0xc3 1 day ago
parent
commit
baeb4aa4f3

+ 0 - 0
client/.gitignore → .gitignore


+ 0 - 0
client/CMakeLists.txt → CMakeLists.txt


+ 0 - 0
client/README.md → README.md


+ 0 - 0
client/scripts/build.sh → scripts/build.sh


+ 0 - 0
client/scripts/setup.sh → scripts/setup.sh


+ 0 - 5
server/.gitignore

@@ -1,5 +0,0 @@
-build/
-.env
-*.xls
-*.xlsx
-*.db

+ 0 - 34
server/README.md

@@ -1,34 +0,0 @@
-```shell
-go build -o ./build/cmd/server/main.exe ./src/cmd/server/main.go
-./build/cmd/server/main.exe
-```
-
-```shell
-go run src/cmd/server/main.go
-```
-
-# migrations-up
-```shell
-goose -dir ./migrations/ sqlite3 ${DB_URL} up
-```
-
-# migrations-reset
-```shell
-goose -dir ./migrations/ sqlite3 ${DB_URL} reset
-```
-
-```shell
-libreoffice --headless --convert-to xlsx file.xls
-```
-
-## Зависимости
-
-```bash
-go get -u github.com/mattn/go-sqlite3@latest
-go get -u github.com/joho/godotenv/autoload@latest
-go get -u github.com/labstack/echo/v4@latest
-go get -u github.com/labstack/echo/v4/middleware@latest
-go get -u github.com/google/uuid@latest
-go get -u github.com/xuri/excelize/v2@latest
-go install github.com/pressly/goose/v3/cmd/goose@latest
-```

+ 0 - 29
server/go.mod

@@ -1,29 +0,0 @@
-module my
-
-go 1.24.0
-
-require (
-	github.com/google/uuid v1.6.0
-	github.com/joho/godotenv v1.5.1
-	github.com/labstack/echo/v4 v4.14.0
-	github.com/mattn/go-sqlite3 v1.14.32
-	github.com/xuri/excelize/v2 v2.10.0
-)
-
-require (
-	github.com/labstack/gommon v0.4.2 // indirect
-	github.com/mattn/go-colorable v0.1.14 // indirect
-	github.com/mattn/go-isatty v0.0.20 // indirect
-	github.com/richardlehane/mscfb v1.0.4 // indirect
-	github.com/richardlehane/msoleps v1.0.4 // indirect
-	github.com/tiendc/go-deepcopy v1.7.2 // indirect
-	github.com/valyala/bytebufferpool v1.0.0 // indirect
-	github.com/valyala/fasttemplate v1.2.2 // indirect
-	github.com/xuri/efp v0.0.1 // indirect
-	github.com/xuri/nfp v0.0.2-0.20250530014748-2ddeb826f9a9 // indirect
-	golang.org/x/crypto v0.46.0 // indirect
-	golang.org/x/net v0.48.0 // indirect
-	golang.org/x/sys v0.39.0 // indirect
-	golang.org/x/text v0.32.0 // indirect
-	golang.org/x/time v0.14.0 // indirect
-)

+ 0 - 73
server/go.sum

@@ -1,73 +0,0 @@
-github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
-github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
-github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
-github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
-github.com/labstack/echo/v4 v4.13.4 h1:oTZZW+T3s9gAu5L8vmzihV7/lkXGZuITzTQkTEhcXEA=
-github.com/labstack/echo/v4 v4.13.4/go.mod h1:g63b33BZ5vZzcIUF8AtRH40DrTlXnx4UMC8rBdndmjQ=
-github.com/labstack/echo/v4 v4.14.0 h1:+tiMrDLxwv6u0oKtD03mv+V1vXXB3wCqPHJqPuIe+7M=
-github.com/labstack/echo/v4 v4.14.0/go.mod h1:xmw1clThob0BSVRX1CRQkGQ/vjwcpOMjQZSZa9fKA/c=
-github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
-github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
-github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
-github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
-github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
-github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
-github.com/mattn/go-sqlite3 v1.14.30 h1:bVreufq3EAIG1Quvws73du3/QgdeZ3myglJlrzSYYCY=
-github.com/mattn/go-sqlite3 v1.14.30/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
-github.com/mattn/go-sqlite3 v1.14.32 h1:JD12Ag3oLy1zQA+BNn74xRgaBbdhbNIDYvQUEuuErjs=
-github.com/mattn/go-sqlite3 v1.14.32/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
-github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
-github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/richardlehane/mscfb v1.0.4 h1:WULscsljNPConisD5hR0+OyZjwK46Pfyr6mPu5ZawpM=
-github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk=
-github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
-github.com/richardlehane/msoleps v1.0.4 h1:WuESlvhX3gH2IHcd8UqyCuFY5yiq/GR/yqaSM/9/g00=
-github.com/richardlehane/msoleps v1.0.4/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
-github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
-github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
-github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
-github.com/tiendc/go-deepcopy v1.6.1 h1:uVRTItFeNHkMcLueHS7OCsxgxT9P8MzGB/taUa2Y4Tk=
-github.com/tiendc/go-deepcopy v1.6.1/go.mod h1:toXoeQoUqXOOS/X4sKuiAoSk6elIdqc0pN7MTgOOo2I=
-github.com/tiendc/go-deepcopy v1.7.2 h1:Ut2yYR7W9tWjTQitganoIue4UGxZwCcJy3orjrrIj44=
-github.com/tiendc/go-deepcopy v1.7.2/go.mod h1:4bKjNC2r7boYOkD2IOuZpYjmlDdzjbpTRyCx+goBCJQ=
-github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
-github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
-github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
-github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
-github.com/xuri/efp v0.0.1 h1:fws5Rv3myXyYni8uwj2qKjVaRP30PdjeYe2Y6FDsCL8=
-github.com/xuri/efp v0.0.1/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
-github.com/xuri/excelize/v2 v2.9.1 h1:VdSGk+rraGmgLHGFaGG9/9IWu1nj4ufjJ7uwMDtj8Qw=
-github.com/xuri/excelize/v2 v2.9.1/go.mod h1:x7L6pKz2dvo9ejrRuD8Lnl98z4JLt0TGAwjhW+EiP8s=
-github.com/xuri/excelize/v2 v2.10.0 h1:8aKsP7JD39iKLc6dH5Tw3dgV3sPRh8uRVXu/fMstfW4=
-github.com/xuri/excelize/v2 v2.10.0/go.mod h1:SC5TzhQkaOsTWpANfm+7bJCldzcnU/jrhqkTi/iBHBU=
-github.com/xuri/nfp v0.0.1 h1:MDamSGatIvp8uOmDP8FnmjuQpu90NzdJxo7242ANR9Q=
-github.com/xuri/nfp v0.0.1/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
-github.com/xuri/nfp v0.0.2-0.20250530014748-2ddeb826f9a9 h1:+C0TIdyyYmzadGaL/HBLbf3WdLgC29pgyhTjAT/0nuE=
-github.com/xuri/nfp v0.0.2-0.20250530014748-2ddeb826f9a9/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
-golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM=
-golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY=
-golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
-golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
-golang.org/x/image v0.25.0 h1:Y6uW6rH1y5y/LK1J8BPWZtr6yZ7hrsy6hFrXjgsc2fQ=
-golang.org/x/image v0.25.0/go.mod h1:tCAmOEGthTtkalusGp1g3xa2gke8J6c2N565dTyl9Rs=
-golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
-golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
-golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
-golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
-golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
-golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
-golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
-golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
-golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4=
-golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=
-golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
-golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
-golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
-golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
-golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
-golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
-gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
-gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

+ 0 - 31
server/migrations/00001_clients_table.sql

@@ -1,31 +0,0 @@
--- +goose Up
-CREATE TABLE clients (
-  id TEXT PRIMARY KEY,
-  id2 TEXT,
-  mark TEXT,
-  contractor INTEGER,
-  full_name TEXT,
-  type TEXT,
-  email TEXT,
-  legal_address TEXT,
-  physical_address TEXT,
-  registration_date TEXT,
-  ad_channel TEXT,
-  reg_data_1 TEXT,
-  reg_data_2 TEXT,
-  note TEXT,
-  request_count INTEGER,
-  birthday TEXT,
-  income NUMERIC -- NUMERIC (или REAL) для числового значения
-);
-
-CREATE TABLE client_phones (
-  client_id INTEGER,
-  phone TEXT,
-  FOREIGN KEY (client_id) REFERENCES clients (id)
-);
-
--- +goose Down
-DROP TABLE client_phones;
-
-DROP TABLE clients;

+ 0 - 22
server/migrations/00002_products_table.sql

@@ -1,22 +0,0 @@
--- +goose Up
-CREATE TABLE products (
-  id TEXT PRIMARY KEY,
-  id2 TEXT,
-  name TEXT,
-  serial_number TEXT,
-  article TEXT,
-  date TEXT,
-  quantity TEXT, -- Кол-во
-  retail_price TEXT, -- Розничная цена
-  purchase_price TEXT, -- Закупочная цена
-  exchange_rate_pc TEXT, -- Курс ПК
-  exchange_rate_pr TEXT, -- Курс ПР
-  warehouse TEXT, -- Склад
-  location TEXT,
-  customer_order TEXT, -- Заказ клиента
-  supplier_order TEXT, -- Заказ поставщику
-  supplier TEXT -- Поставщик
-);
-
--- +goose Down
-DROP TABLE products;

+ 0 - 4
server/migrations/00003_calls_table.sql

@@ -1,4 +0,0 @@
--- +goose Up
--- CREATE TABLE IF NOT EXISTS calls (id TEXT PRIMARY KEY, id2 TEXT);
--- +goose Down
--- DROP TABLE calls;

+ 0 - 15
server/migrations/00004_client_ad_channels_table.sql

@@ -1,15 +0,0 @@
--- +goose Up
-CREATE TABLE ad_channels (id INTEGER PRIMARY KEY, name TEXT);
-
-INSERT INTO
-  ad_channels (name)
-VALUES
-  ('Интернет'),
-  ('Партнер'),
-  ('По рекомендации'),
-  ('Постоянные клиенты'),
-  ('Проходящий поток'),
-  ('СЦ ТРУД');
-
--- +goose Down
-DROP TABLE ad_channels;

+ 0 - 19
server/migrations/00005_client_marks_table.sql

@@ -1,19 +0,0 @@
--- +goose Up
-CREATE TABLE marks (id INTEGER PRIMARY KEY, name TEXT);
-
-INSERT INTO
-  marks (name)
-VALUES
-  ('-5%'),
-  ('-10%'),
-  ('-20%'),
-  ('-30%'),
-  ('blacklist'),
-  ('discount'),
-  ('regular'),
-  ('VIP'),
-  ('Животное'),
-  ('Мудак');
-
--- +goose Down
-DROP TABLE marks;

+ 0 - 11
server/src/app/app.go

@@ -1,11 +0,0 @@
-package app
-
-import "os"
-
-type App struct {
-	Port string
-}
-
-func Init(appCtx *App) {
-	appCtx.Port = os.Getenv("PORT")
-}

+ 0 - 144
server/src/cmd/immigration/clients/main.go

@@ -1,144 +0,0 @@
-package main
-
-import (
-	"fmt"
-	"my/src/common"
-	clientApi "my/src/server/client"
-	"my/src/server/db/repo"
-	"os"
-	"strconv"
-	"strings"
-
-	"github.com/xuri/excelize/v2"
-
-	_ "github.com/joho/godotenv/autoload"
-)
-
-var FILE_PATH string
-
-func ReadClientsFromFile(file_path string) ([]repo.ClientInfo, error) {
-	clients := []repo.ClientInfo{}
-
-	file, err := excelize.OpenFile(file_path)
-	if err != nil {
-		fmt.Println(err)
-		return clients, err
-	}
-
-	// Get all the rows in the Sheet1.
-	rows, err := file.GetRows("Клиенты")
-	if err != nil {
-		fmt.Println(err)
-		return clients, err
-	}
-
-	// Пропускаем заголовок и обрабатываем каждую строку
-	for i, row := range rows {
-		if i == 0 {
-			continue
-		}
-		client := repo.ClientInfo{}
-		client.Id2 = row[0]
-		if len(row) > 1 {
-			client.Mark = row[1]
-		}
-		if len(row) > 2 {
-			if row[2] == "Да" {
-				client.Contractor = true
-			} else {
-				client.Contractor = false
-			}
-		}
-		if len(row) > 3 {
-			client.FullName = row[3]
-		}
-		if len(row) > 4 {
-			client.Type = row[4]
-		}
-		if len(row) > 5 {
-			if row[5] != "" {
-				phones := strings.Split(row[5], ",")
-				client.Phones = phones
-				// fmt.Println("PHones:", client.Phones)
-			}
-		}
-		if len(row) > 6 {
-			client.Email = row[6]
-		}
-		if len(row) > 7 {
-			client.LegalAddress = row[7]
-		}
-		if len(row) > 8 {
-			client.PhysicalAddress = row[8]
-		}
-		if len(row) > 9 {
-			if row[9] != "" {
-				client.RegistrationDate = row[9]
-			}
-		}
-		if len(row) > 10 {
-			client.AdChannel = row[10]
-		}
-		if len(row) > 11 {
-			client.RegData1 = row[11]
-		}
-		if len(row) > 12 {
-			client.RegData2 = row[12]
-		}
-		if len(row) > 13 {
-			client.Note = row[13]
-		}
-		if len(row) > 14 {
-			if row[14] != "" {
-				value, err := strconv.Atoi(row[14])
-				if err != nil {
-					fmt.Println("Error string to int:", err)
-					return clients, err
-				}
-				client.RequestCount = value
-			}
-		}
-		if len(row) > 15 {
-			client.Birthday = row[15]
-		}
-		if len(row) > 16 {
-			str := row[16]
-			if str != "" {
-				if strings.Contains(str, ".") {
-					res := strings.ReplaceAll(row[16], ".", "")
-					parse, _ := strconv.ParseInt(res, 10, 64)
-					client.Income = common.Money(parse)
-				} else {
-					parse, _ := strconv.ParseInt(str, 10, 64)
-					client.Income = common.Money(parse * 100)
-				}
-			}
-		}
-		// fmt.Println("Client:", client)
-		clients = append(clients, client)
-	}
-
-	return clients, err
-}
-
-func main() {
-	portEnv := os.Getenv("PORT")
-	url := "http://localhost" + portEnv + "/api/v1/client"
-	// fmt.Println(url)
-
-	if len(os.Args) > 1 {
-		FILE_PATH = os.Args[1]
-		clients, err := ReadClientsFromFile(FILE_PATH)
-		if err != nil {
-			fmt.Println(err)
-		}
-
-		for _, client := range clients {
-			// fmt.Println(client)
-			err = clientApi.PostData[repo.ClientInfo](url, client)
-			if err != nil {
-				fmt.Println(err)
-			}
-		}
-	}
-}

+ 0 - 50
server/src/cmd/server/main.go

@@ -1,50 +0,0 @@
-package main
-
-import (
-	"context"
-	"log"
-	"my/src/app"
-	myServer "my/src/server"
-	"net/http"
-	"os"
-	"os/signal"
-	"syscall"
-	"time"
-)
-
-func main() {
-	log.Println("Server running...")
-
-	appCtx := new(app.App)
-	app.Init(appCtx)
-
-	serverCtx := new(myServer.Server)
-	http_server := myServer.Init(serverCtx, appCtx)
-
-	// Channel to listen for OS signals
-	quit := make(chan os.Signal, 1)
-	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
-
-	// Start the HTTP server in a goroutine
-	go func() {
-		if err := http_server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
-			log.Fatalf("Server failed to listen and serve: %v", err)
-		}
-	}()
-	log.Println("Server started on " + appCtx.Port)
-
-	// Block until a signal is received
-	<-quit
-	log.Println("Shutting down server...")
-
-	// Create a context with a timeout for shutdown
-	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
-	defer cancel()
-
-	// Attempt to gracefully shut down the server
-	if err := http_server.Shutdown(ctx); err != nil {
-		log.Fatalf("Server shutdown failed: %v", err)
-	}
-
-	log.Println("Server gracefully shut down.")
-}

+ 0 - 11
server/src/common/common.go

@@ -1,11 +0,0 @@
-package common
-
-import "fmt"
-
-type Money int64
-
-func (m Money) String() string {
-	rubles := int64(m) / 100
-	kopeks := int64(m) % 100
-	return fmt.Sprintf("%d.%02d", rubles, kopeks)
-}

+ 0 - 59
server/src/server/client/client_api.go

@@ -1,59 +0,0 @@
-package clientApi
-
-import (
-	"bytes"
-	"encoding/json"
-	"fmt"
-	"net/http"
-)
-
-func PostData[T any](url string, data any) error {
-	jsonData, err := json.Marshal(data)
-	if err != nil {
-		return err
-	}
-
-	resp, err := http.Post(url, "application/json", bytes.NewBuffer(jsonData))
-	if err != nil {
-		return err
-	}
-	defer resp.Body.Close()
-
-	if resp.StatusCode != http.StatusOK {
-		return fmt.Errorf("failed to add: %s", resp.Status)
-	}
-
-	return nil
-}
-
-func FetchData[T any](url string, data T) error {
-	resp, err := http.Get(url)
-	if err != nil {
-		return err
-	}
-	defer resp.Body.Close()
-
-	if resp.StatusCode != http.StatusOK {
-		return fmt.Errorf("failed to fetch data: status code %d", resp.StatusCode)
-	}
-
-	return json.NewDecoder(resp.Body).Decode(data)
-}
-
-func FetchOne[T any](params string) (data T, err error) {
-	url := params
-	err = FetchData(url, &data)
-	if err != nil {
-		return data, err
-	}
-	return data, nil
-}
-
-func Fetch[T any](params string) (data []T, err error) {
-	url := params
-	err = FetchData(url, &data)
-	if err != nil {
-		return nil, err
-	}
-	return data, nil
-}

+ 0 - 119
server/src/server/db/db.go

@@ -1,119 +0,0 @@
-package db
-
-import (
-	"database/sql"
-	"fmt"
-	"log"
-	"my/src/server/db/repo"
-	"os"
-	"sync"
-
-	_ "github.com/mattn/go-sqlite3"
-)
-
-type DB struct {
-	db          *sql.DB
-	clientsRepo *repo.ClientRepo
-}
-
-var (
-	instance *DB
-	once     sync.Once
-)
-
-func (ctx *DB) Init() error {
-	dbURL := os.Getenv("DB_URL")
-	if dbURL == "" {
-		return fmt.Errorf("DB_URL environment variable is not set")
-	}
-
-	var err error
-	ctx.db, err = sql.Open("sqlite3", dbURL)
-
-	if err != nil {
-		return fmt.Errorf("failed to open database: %w", err)
-	}
-
-	if err := ctx.db.Ping(); err != nil {
-		ctx.db.Close()
-		return fmt.Errorf("failed to connect to database: %w", err)
-	}
-
-	ctx.clientsRepo = repo.NewClientRepo(ctx.db, dbURL)
-
-	log.Println("Database initialized successfully")
-	return nil
-}
-
-func (ctx *DB) Close() error {
-	if ctx.db != nil {
-		return ctx.db.Close()
-	}
-	return nil
-}
-
-func (ctx *DB) GetClientRepo() *repo.ClientRepo {
-	return ctx.clientsRepo
-}
-
-func (ctx *DB) FetchMarks() ([]string, error) {
-	query := `
-      SELECT id, name
-      FROM marks
-  `
-	rows, err := ctx.db.Query(query)
-	if err != nil {
-		return nil, fmt.Errorf("failed to execute query: %w", err)
-	}
-	defer rows.Close()
-
-	var marks []string
-
-	for rows.Next() {
-		var id string
-		var name string
-
-		if err := rows.Scan(&id, &name); err != nil {
-			return nil, fmt.Errorf("failed to scan row: %w", err)
-		}
-
-		marks = append(marks, name)
-	}
-
-	if err := rows.Err(); err != nil {
-		return nil, fmt.Errorf("error during iteration: %w", err)
-	}
-
-	return marks, nil
-}
-
-func (ctx *DB) FetchAdChannels() ([]string, error) {
-	query := `
-      SELECT id, name
-      FROM ad_channels
-  `
-	rows, err := ctx.db.Query(query)
-	if err != nil {
-		return nil, fmt.Errorf("failed to execute query: %w", err)
-	}
-	defer rows.Close()
-
-	var ad_channels []string
-
-	for rows.Next() {
-		var id string
-		var name string
-
-		if err := rows.Scan(&id, &name); err != nil {
-			return nil, fmt.Errorf("failed to scan row: %w", err)
-		}
-
-		ad_channels = append(ad_channels, name)
-	}
-
-	if err := rows.Err(); err != nil {
-		return nil, fmt.Errorf("error during iteration: %w", err)
-	}
-
-	return ad_channels, nil
-}

+ 0 - 291
server/src/server/db/repo/client.go

@@ -1,291 +0,0 @@
-package repo
-
-import (
-	"database/sql"
-	"fmt"
-	"my/src/common"
-)
-
-const (
-	ClientTypePhysical     string = "Физ"
-	ClientTypeLegal        string = "Юр"
-	ClientTypeSupplier     string = "Поставщик"
-	ClientTypeEmployee     string = "Сотрудник"
-	ClientTypeCounterparty string = "Контрагент"
-	ClientTypeCustomer     string = "Покупатель"
-)
-
-type ClientInfo struct {
-	Id               string       `db:"id" json:"id" form:"id"`
-	Id2              string       `db:"id2" json:"id2" form:"id2"`
-	Mark             string       `db:"mark" json:"mark" form:"mark"`
-	Contractor       bool         `db:"contractor" json:"contractor" form:"contractor"`
-	FullName         string       `db:"full_name" json:"full_name" form:"full_name"`
-	Type             string       `db:"type" json:"type" form:"type"`
-	Phones           []string     `json:"phones" form:"phones"`
-	Email            string       `db:"email" json:"email" form:"email"`
-	LegalAddress     string       `db:"legal_address" json:"legal_address" form:"legal_address"`
-	PhysicalAddress  string       `db:"physical_address" json:"physical_address" form:"physical_address"`
-	RegistrationDate string       `db:"registration_date" json:"registration_date" form:"registration_date"`
-	AdChannel        string       `db:"ad_channel" json:"ad_channel" form:"ad_channel"`
-	RegData1         string       `db:"reg_data_1" json:"reg_data_1" form:"reg_data_1"`
-	RegData2         string       `db:"reg_data_2" json:"reg_data_2" form:"reg_data_2"`
-	Note             string       `db:"note" json:"note" form:"note"`
-	RequestCount     int          `db:"request_count" json:"request_count" form:"request_count"`
-	Birthday         string       `db:"birthday" json:"birthday" form:"birthday"`
-	Income           common.Money `db:"income" json:"income" form:"income"`
-}
-
-type ClientRepo struct {
-	db    *sql.DB
-	dbUrl string
-}
-
-func NewClientRepo(db *sql.DB, dbUrl string) *ClientRepo {
-	return &ClientRepo{db: db, dbUrl: dbUrl}
-}
-
-func (r *ClientRepo) InsertClient(client ClientInfo) error {
-	var err error
-	var exists bool
-
-	err = r.db.QueryRow("SELECT EXISTS(SELECT 1 FROM clients WHERE id = ? OR id2 = ?)", client.Id, client.Id2).Scan(&exists)
-	if err != nil {
-		return fmt.Errorf("failed to check if client exists: %w", err)
-	}
-	if exists {
-		return fmt.Errorf("client with id %s already exists", client.Id)
-	}
-
-	_, err = r.db.Exec(
-		`
-    INSERT INTO clients (
-      id, id2, mark, contractor, full_name, type, email,
-      legal_address, physical_address, registration_date, ad_channel,
-      reg_data_1, reg_data_2, note, request_count, birthday, income
-    ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
-    `,
-		client.Id, client.Id2, client.Mark, client.Contractor, client.FullName,
-		client.Type, client.Email, client.LegalAddress,
-		client.PhysicalAddress, client.RegistrationDate, client.AdChannel,
-		client.RegData1, client.RegData2, client.Note, client.RequestCount,
-		client.Birthday, client.Income,
-	)
-	if err != nil {
-		return fmt.Errorf("failed to insert client: %w", err)
-	}
-
-	return nil
-}
-
-func (r *ClientRepo) FetchClientByID(id string) (*ClientInfo, error) {
-	var err error
-
-	row := r.db.QueryRow(`
-		SELECT
-    	id, id2, mark, contractor, full_name, type, email,
-      legal_address, physical_address, registration_date, ad_channel,
-      reg_data_1, reg_data_2, note, request_count, birthday, income
-    FROM clients
-    WHERE id = ?
-    `, id)
-
-	var client ClientInfo
-	err = row.Scan(
-		&client.Id, &client.Id2, &client.Mark, &client.Contractor, &client.FullName,
-		&client.Type, &client.Email, &client.LegalAddress,
-		&client.PhysicalAddress, &client.RegistrationDate, &client.AdChannel,
-		&client.RegData1, &client.RegData2, &client.Note, &client.RequestCount,
-		&client.Birthday, &client.Income,
-	)
-
-	if err == sql.ErrNoRows {
-		return nil, fmt.Errorf("client with id %s not found", id)
-	} else if err != nil {
-		return nil, fmt.Errorf("failed to scan row: %w", err)
-	}
-
-	phones, err := r.FetchClientPhones(client.Id)
-	if err != nil {
-		return nil, fmt.Errorf("error: %w", err)
-	}
-	client.Phones = phones
-
-	return &client, nil
-}
-
-func (r *ClientRepo) InsertClientPhones(client_id string, phones []string) error {
-	for _, phone := range phones {
-		_, err := r.db.Exec("INSERT INTO client_phones VALUES(?, ?)", client_id, phone)
-		if err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-func (r *ClientRepo) FetchClientPhones(client_id string) ([]string, error) {
-	rows, err := r.db.Query("SELECT phone FROM client_phones WHERE client_id = ?", client_id)
-	if err != nil {
-		return nil, err
-	}
-	defer rows.Close()
-
-	var tags []string
-	for rows.Next() {
-		var tag string
-		rows.Scan(&tag)
-		tags = append(tags, tag)
-	}
-	return tags, nil
-}
-
-func (r *ClientRepo) FetchClients(count int, offset int) ([]ClientInfo, error) {
-	rows, err := r.db.Query(`
-        SELECT
-            id, id2, mark, contractor, full_name, type, email,
-            legal_address, physical_address, registration_date, ad_channel,
-            reg_data_1, reg_data_2, note, request_count, birthday, income
-        FROM clients
-        LIMIT ? OFFSET ?
-    `, count, offset)
-	if err != nil {
-		return nil, fmt.Errorf("failed to execute query: %w", err)
-	}
-	defer rows.Close()
-
-	var clients []ClientInfo
-	for rows.Next() {
-		var client ClientInfo
-		err := rows.Scan(
-			&client.Id,
-			&client.Id2,
-			&client.Mark,
-			&client.Contractor,
-			&client.FullName,
-			&client.Type,
-			&client.Email,
-			&client.LegalAddress,
-			&client.PhysicalAddress,
-			&client.RegistrationDate, // time.Time или sql.NullTime
-			&client.AdChannel,
-			&client.RegData1,
-			&client.RegData2,
-			&client.Note,         // sql.NullString
-			&client.RequestCount, // int или sql.NullInt32
-			&client.Birthday,     // time.Time или sql.NullTime
-			&client.Income,       // float64 или sql.NullFloat64
-		)
-		if err != nil {
-			return nil, fmt.Errorf("failed to scan row: %w", err)
-		}
-
-		phones, err := r.FetchClientPhones(client.Id)
-		if err != nil {
-			return nil, fmt.Errorf("rows error: %w", err)
-		}
-		client.Phones = phones
-
-		clients = append(clients, client)
-	}
-
-	// Проверка ошибок после итерации
-	if err := rows.Err(); err != nil {
-		return nil, fmt.Errorf("rows error: %w", err)
-	}
-
-	return clients, nil
-}
-
-func (r *ClientRepo) FetchClientsCount() (int, error) {
-	var count int
-	query := "SELECT COUNT(*) FROM clients"
-	err := r.db.QueryRow(query).Scan(&count)
-	if err != nil {
-		return 0, fmt.Errorf("failed to fetch count: %w", err)
-	}
-	return count, nil
-}
-
-func (r *ClientRepo) DeleteClient(id string) error {
-	query := "DELETE FROM clients WHERE id = ?"
-	result, err := r.db.Exec(query, id)
-	if err != nil {
-		return fmt.Errorf("failed to delete client: %w", err)
-	}
-
-	rowsAffected, err := result.RowsAffected()
-	if err != nil {
-		return fmt.Errorf("failed to get rows affected: %w", err)
-	}
-
-	if rowsAffected == 0 {
-		return fmt.Errorf("client with id %s not found", id)
-	}
-
-	return nil
-}
-
-func (r *ClientRepo) UpdateClient(id string, client ClientInfo) error {
-	// Проверим, существует ли клиент
-	var exists string
-	err := r.db.QueryRow("SELECT id FROM clients WHERE id = ?", id).Scan(&exists)
-	if err == sql.ErrNoRows {
-		return fmt.Errorf("client with id %s not found", id)
-	} else if err != nil {
-		return fmt.Errorf("failed to check client existence: %w", err)
-	}
-
-	query := `
-        UPDATE clients SET
-            id = ?,
-            id2 = ?,
-            mark = ?,
-            contractor = ?,
-            full_name = ?,
-            type = ?,
-            email = ?,
-            legal_address = ?,
-            physical_address = ?,
-            registration_date = ?,
-            ad_channel = ?,
-            reg_data_1 = ?,
-            reg_data_2 = ?,
-            note = ?,
-            request_count = ?,
-            birthday = ?,
-            income = ?
-        WHERE id = ?
-    `
-
-	contractorInt := 0
-	if client.Contractor {
-		contractorInt = 1
-	}
-
-	_, err = r.db.Exec(query,
-		id,
-		client.Id2,
-		client.Mark,
-		contractorInt,
-		client.FullName,
-		client.Type,
-		client.Email,
-		client.LegalAddress,
-		client.PhysicalAddress,
-		client.RegistrationDate,
-		client.AdChannel,
-		client.RegData1,
-		client.RegData2,
-		client.Note,
-		client.RequestCount,
-		client.Birthday,
-		client.Income,
-		id,
-	)
-	if err != nil {
-		return fmt.Errorf("failed to update client: %w", err)
-	}
-
-	return nil
-}

+ 0 - 75
server/src/server/server.go

@@ -1,75 +0,0 @@
-package server
-
-import (
-	"net/http"
-	"strconv"
-	"strings"
-	"time"
-
-	"my/src/app"
-	"my/src/server/db"
-
-	"github.com/labstack/echo/v4"
-	"github.com/labstack/echo/v4/middleware"
-
-	_ "github.com/joho/godotenv/autoload"
-)
-
-type Server struct {
-	db *db.DB
-}
-
-func Init(ctx *Server, appCtx *app.App) *http.Server {
-	ctx.db = new(db.DB)
-	ctx.db.Init()
-
-	http_server := &http.Server{
-		Addr:         appCtx.Port,
-		Handler:      RegisterHandlers(ctx.db),
-		IdleTimeout:  time.Minute,
-		ReadTimeout:  10 * time.Second,
-		WriteTimeout: 30 * time.Second,
-	}
-
-	return http_server
-}
-
-func RegisterHandlers(db *db.DB) http.Handler {
-	e := echo.New()
-	e.Use(middleware.RequestLogger())
-	e.Use(middleware.Recover())
-
-	e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
-		AllowOrigins:     []string{"https://*", "http://*"},
-		AllowMethods:     []string{"GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"},
-		AllowHeaders:     []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token"},
-		AllowCredentials: true,
-		MaxAge:           300,
-	}))
-
-	apiGroup := e.Group("", func(next echo.HandlerFunc) echo.HandlerFunc {
-		return func(c echo.Context) error {
-			if strings.HasPrefix(c.Request().Host, "api.") {
-				return next(c)
-			}
-			return echo.ErrNotFound
-		}
-	})
-
-	e.GET("/", func(c echo.Context) error {
-		return c.String(http.StatusOK, "is live")
-	})
-
-	apiGroup.GET("/v1/clients", func(c echo.Context) error {
-		limit, _ := strconv.Atoi(c.QueryParam("limit"))
-		offset, _ := strconv.Atoi(c.QueryParam("offset"))
-
-		clients, err := db.GetClientRepo().FetchClients(limit, offset)
-		if err != nil {
-			return c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()})
-		}
-		return c.JSON(http.StatusOK, clients)
-	})
-
-	return e
-}

+ 0 - 0
client/src/saura/app/app.cpp → src/saura/app/app.cpp


+ 0 - 0
client/src/saura/app/app.hpp → src/saura/app/app.hpp


+ 0 - 0
client/src/saura/cmd/sandbox/CMakeLists.txt → src/saura/cmd/sandbox/CMakeLists.txt


+ 0 - 0
client/src/saura/cmd/sandbox/sandbox.cpp → src/saura/cmd/sandbox/sandbox.cpp


+ 0 - 0
client/src/saura/core/app_base/app_base.hpp → src/saura/core/app_base/app_base.hpp


+ 0 - 0
client/src/saura/core/os/os.cpp → src/saura/core/os/os.cpp


+ 0 - 0
client/src/saura/core/os/os.hpp → src/saura/core/os/os.hpp


+ 0 - 0
client/src/saura/core/server/server.cpp → src/saura/core/server/server.cpp


+ 0 - 0
client/src/saura/core/server/server.hpp → src/saura/core/server/server.hpp


+ 0 - 0
client/src/saura/main/main.cpp → src/saura/main/main.cpp


+ 0 - 0
client/vcpkg.json → vcpkg.json