Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
b450ffe
refactor domain entities
Moomien Jun 13, 2026
6987a32
mock test for transfer handler
Moomien Jun 13, 2026
3d8b51d
fix: исправил кэш рейтлимитинг с fixed window на sliding window, испр…
Moomien Jun 14, 2026
fae7bba
new accounts service
Moomien Jun 14, 2026
5b85c0c
улучшил check constraint в миграции для защиты бд. переписал transact…
Moomien Jun 16, 2026
924becf
эндпоинт для аккаунтов готов
Moomien Jun 16, 2026
64b003b
написал юнит тесты для хендлеров транзакций
Moomien Jun 17, 2026
649d6da
добавлена jwt аутентификация вокруг трех слоев(usecase, storage, deli…
Moomien Jun 18, 2026
24b18e8
написал эндпоинты аутентификации
Moomien Jun 18, 2026
e297af2
написал миддлвейр аутентификации + исправления
Moomien Jun 18, 2026
f7639a6
поправил main.go
Moomien Jun 18, 2026
e0fd3f2
юнит тесты для хендлеров
Moomien Jun 18, 2026
f2e3491
проверка actions
Moomien Jun 20, 2026
351d18b
ci
Moomien Jun 20, 2026
8a68993
test lint des
Moomien Jun 20, 2026
2a1ab6e
test lint des
Moomien Jun 20, 2026
abe5172
ci fix
Moomien Jun 20, 2026
8fd9987
ci fix
Moomien Jun 20, 2026
5dd3ed8
ci fix
Moomien Jun 20, 2026
d60adac
ci fix
Moomien Jun 20, 2026
a915f7a
last ci fix
Moomien Jun 20, 2026
958cced
реализовал паттерн config. поправил логи в usecase и infrastructure
Moomien Jun 20, 2026
e6dfd95
масс рефактор + e2e тесты
Moomien Jun 20, 2026
8460517
теперь тесты проходят
Moomien Jun 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Check
on: push
jobs:
golangci-lint:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Setup Go
uses: actions/setup-go@v6
with:
go-version: "1.26"
- name: install deps
run: go mod download
- name: Lint
run: go vet ./...
test:
needs: [golangci-lint]
runs-on: ubuntu-latest
strategy:
matrix:
go-version: ['1.25', '1.26']
os: ['ubuntu-latest', 'windows-latest']
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Setup GO
uses: actions/setup-go@v6
with:
go-version: ${{ matrix.go-version }}
- name: install deps
run: go mod download
- name: Run tests
run: go test -coverprofile=coverage.out ./internal/...
- name: Check coverage threshold
run: |
COVERAGE=$(go tool cover -func=coverage.out | grep total | awk '{print $3}' | tr -d '%')
echo "Coverage: $COVERAGE%"
if (( $(echo "$COVERAGE < 25" | bc -l) )); then
echo "Coverage is below 25%"
exit 1
fi
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#todo dockerfile....
14 changes: 14 additions & 0 deletions cmd/server/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
ENVIRONMENT=
LOG_LEVEL=

POSTGRES_HOST=
POSTGRES_PORT=
POSTGRES_DB=
POSTGRES_USER=
POSTGRES_PASSWORD=
POSTGRES_SSL=

REDIS_HOST=
REDIS_PORT=
REDIS_USER=
REDIS_PASSWORD=
1 change: 1 addition & 0 deletions cmd/server/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.env
161 changes: 85 additions & 76 deletions cmd/server/main.go
Original file line number Diff line number Diff line change
@@ -1,76 +1,85 @@
package main

import (
"database/sql"
"io"
"log/slog"
"net/http"
"os"
"path/filepath"

handlers "processing/internal/delivery/http"
"processing/internal/infrastructure/cache"
"processing/internal/infrastructure/storage"
"processing/internal/usecase"

_ "github.com/jackc/pgx/v5/stdlib"
)

const (
db_url = "postgres://admin:secret@localhost:5432/postgres_bd"
redis_url = "localhost:6379"
)

func main() {
if err := run(); err != nil {
os.Exit(1)
}
}

func run() error {
app, err := os.OpenFile("app.log", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
if err != nil {
panic(err)
}
defer app.Close()

stor, err := os.OpenFile("storage.log", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
if err != nil {
panic(err)
}
defer stor.Close()

redis, err := os.OpenFile("redis.log", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
if err != nil {
panic(err)
}
defer redis.Close()

applog := slog.New(slog.NewJSONHandler(io.MultiWriter(os.Stdout, app), nil))
storagelog := slog.New(slog.NewJSONHandler(io.MultiWriter(os.Stdout, stor), nil))
redislog := slog.New(slog.NewJSONHandler(io.MultiWriter(os.Stdout, redis), nil))

db, err := sql.Open("pgx", db_url)
if err != nil {
applog.Error("не получилось подключиться к бд", "err", err)
return err
}
if err := db.Ping(); err != nil {
applog.Error("не получилось пингануть бд", "err", err)
return err
}
slog.Info("Успешное подключение к бд!")
tx := storage.NewUoWFactory(db, storagelog)
cache := cache.NewRedis(redis_url, redislog)
path := filepath.Join("service.log") // возможно нужно по другому
transferService := usecase.NewService(tx, cache, path)
handler := handlers.NewHandler(transferService)

mux := http.NewServeMux()
mux.HandleFunc("POST /transactions", handler.Transfer)
mux.HandleFunc("GET /transactions/{id}", handler.GetTransaction)
slog.Info("сервер запущен на :8080")
http.ListenAndServe(":8080", mux)

return nil
}
package main

import (
"database/sql"
"log"
"log/slog"
"net/http"
"os"

handlers "processing/internal/delivery/http"
"processing/internal/delivery/http/middleware"
"processing/internal/infrastructure/cache"
"processing/internal/infrastructure/config"
"processing/internal/infrastructure/logger"
"processing/internal/infrastructure/storage"
"processing/internal/usecase"

_ "github.com/jackc/pgx/v5/stdlib"
)

func main() {
if err := run(); err != nil {
os.Exit(1)
}
}

func run() error {
cfg, err := config.Load()
if err != nil {
panic(err)
}

logger, err := logger.NewLogger(cfg.LogLevel, cfg.Environment)
if err != nil {
panic(err)
}

postgres_url := cfg.Postgres.PostgresDSN()
db, err := sql.Open("pgx", postgres_url)
if err != nil {
logger.Debug("не получилось подключиться к бд", "err", err)
return err
}
if err := db.Ping(); err != nil {
logger.Debug("не получилось пингануть бд", "err", err)
return err
}
slog.Info("Успешное подключение к бд!")

redis_url := cfg.Redis.RedisDSN()
cache := cache.NewRedis(cache.NewRedisOptions{
Addr: redis_url,
RateLimitMin: cfg.Redis.RateLimitMin,
RateLimitHour: cfg.Redis.RateLimitHour,
RateLimitDay: cfg.Redis.RateLimitDay,
})
//kafka
////
////

tx := storage.NewUoWFactory(db)
transactionService := usecase.NewTransactionsService(tx, cache, logger)
accountsService := usecase.NewAccountService(tx, cache, logger)
authService := usecase.NewAuthService(tx, cache, logger)

handler := handlers.NewHandler(transactionService, accountsService, authService, logger)

router := http.NewServeMux()

router.HandleFunc("POST /auth/register", handler.Register)
router.HandleFunc("POST /auth/login", handler.Login)
router.HandleFunc("POST /auth/refresh", handler.Refresh)

router.Handle("POST /auth/logout", middleware.AuthMiddleware(http.HandlerFunc(handler.Logout)))
router.Handle("POST /auth/logout-all", middleware.AuthMiddleware(http.HandlerFunc(handler.LogoutAll)))
router.Handle("GET /accounts/{id}", middleware.AuthMiddleware(http.HandlerFunc(handler.GetAccount)))
router.Handle("GET /accounts/{id}/transactions", middleware.AuthMiddleware(http.HandlerFunc(handler.AccountTransactions)))
router.Handle("POST /transactions", middleware.AuthMiddleware(http.HandlerFunc(handler.Transfer)))
router.Handle("GET /transactions/{id}", middleware.AuthMiddleware(http.HandlerFunc(handler.GetTransaction)))

log.Println("сервер запущен на :8080!")
http.ListenAndServe(":8080", router)

return nil
}
Loading