Skip to content

Commit 2dcd2bd

Browse files
soorqmaksberegovoi
andauthored
feat: implement core modules (Auth, User), S3 integration, and CI/CD infra
* feat: add users module and standardized API error responses * feat: core domain entity type / add service and repository * chore: add auth module arch * feat(shared): add ApiBaseController decorator for global swagger responses * feat(swagger): add reusable swagger error decorators * docs(users): describe user api endpoints in swagger * feat(auth): scaffold auth controller with route stubs * feat(auth): scaffold auth service with dependencies * feat(auth): add zod-based dtos for authentication and 2fa * refactor(swagger): rename ApiRequireAuth to ApiUnauthorized for better reuse * docs(auth): describe auth api endpoints in swagger * chore: feat libs per auth flow / rename endpoints * chore: feat per auth module libs and redis * feat(auth): intergrate with jwt module and update config module * feat(redis):chore(infra): integrate redis and setup correct infra * feat(auth):chore(ua-parser): integrate logic per register flow #1 * feat(auth): integrate logic per sign flow #2 * feat(mail): add mail module and Handlebars templates * feat(user): implement user controller with facade integration * feat(auth): integrate logic per reset password flow #3 / bug with otplib always code apply * fix(auth): fix OTP verification bypass in AuthService * fix(auth): correct session expiration time in signIn and verify * fix(email): fix verification code copy formatting * fix(infra): specify postgres user and db for healthcheck * fix(cors): normalize origins to hostname to resolve local blocks * fix(compose): resolve error with depends and correct output per users * feat(s3):chore(aws): add s3 module at libs and env file * refactor(auth): fix type inconsistencies in user models * feat(infra): setup migrations, optimize pg pool, and add ghcr workflow * chore(auth): add password reset and sign-up confirmation Swagger documentation * feat(user): implement avatar upload functionality with S3 integration * chore(auth): add password reset and sign-up confirmation Swagger documentation --------- Co-authored-by: Maksym Berehovyi <108676512+maksberegovoi@users.noreply.github.com> Co-authored-by: Maxim <darlinggbm@gmail.com>
1 parent 4fb50b5 commit 2dcd2bd

103 files changed

Lines changed: 5968 additions & 284 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.env.example

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# --- APP ---
22
PORT=3000
33
NODE_ENV=development
4-
CORS_ALLOWED_ORIGINS=http://localhost:3000
4+
CORS_ALLOWED_ORIGINS=http://localhost:3000,http://127.0.0.1:3000
55

66
# --- POSTGRES ---
77
DB_USERNAME=admin
@@ -18,6 +18,30 @@ DB_SCHEMA=base
1818
DATABASE_URL=postgres://${DB_USERNAME}:${DB_PASSWORD}@localhost:${DB_PORT}/${DB_DATABASE}
1919

2020
# --- REDIS ---
21-
REDIS_HOST=redis
22-
REDIS_PORT=6379
23-
REDIS_EXTERNAL_PORT=6380
21+
# in the docker network will be, not show port redis, at prod env
22+
# REDIS_HOST=redis
23+
# at development mode
24+
REDIS_HOST=127.0.0.1
25+
REDIS_PORT=7000
26+
27+
JWT_ACCESS_SECRET=same-same-same-same-same
28+
JWT_ACCESS_EXPIRES_IN=15m
29+
30+
JWT_REFRESH_SECRET=same-same-same-same-same
31+
JWT_REFRESH_EXPIRES_IN=15m
32+
33+
# --- MAIL SETTINGS ---
34+
MAIL_HOST=smtp.gmail.com
35+
MAIL_PORT=465
36+
MAIL_USER=example@gmail.com
37+
38+
# 16x password
39+
MAIL_PASSWORD=xxxxxxxxyyyyyyyy
40+
MAIL_FROM_NAME="Task Tracker"
41+
MAIL_FROM_EMAIL=example@gmail.com
42+
43+
S3_BUCKET_NAME=''
44+
S3_ENDPOINT=''
45+
S3_REGION=''
46+
S3_ACCESS_KEY=''
47+
S3_SECRET_KEY=''

.github/workflows/build.yml

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: Build and Push
22

33
on:
44
push:
5-
branches: [dev, main]
5+
branches: [dev, main, feat/**]
66

77
env:
88
REGISTRY: ghcr.io
@@ -13,20 +13,20 @@ jobs:
1313
runs-on: ubuntu-latest
1414
permissions:
1515
contents: read
16-
# packages: write
16+
packages: write
1717

1818
steps:
1919
- uses: actions/checkout@v4
2020

2121
- name: Set up Docker Buildx
2222
uses: docker/setup-buildx-action@v3
2323

24-
# - name: Log in to the Container registry
25-
# uses: docker/login-action@v3
26-
# with:
27-
# registry: ${{ env.REGISTRY }}
28-
# username: ${{ github.actor }}
29-
# password: ${{ secrets.GITHUB_TOKEN }}
24+
- name: Log in to the Container registry
25+
uses: docker/login-action@v3
26+
with:
27+
registry: ${{ env.REGISTRY }}
28+
username: ${{ github.actor }}
29+
password: ${{ secrets.GITHUB_TOKEN }}
3030

3131
- name: Extract metadata (tags, labels)
3232
id: meta
@@ -36,13 +36,14 @@ jobs:
3636
tags: |
3737
type=ref,event=branch
3838
type=sha,format=short
39+
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }}
3940
4041
- name: Build and push Docker image
4142
uses: docker/build-push-action@v5
4243
with:
4344
context: .
4445
file: ./Dockerfile.prod
45-
push: false # add true, if your setup variables
46+
push: true
4647
tags: ${{ steps.meta.outputs.tags }}
4748
labels: ${{ steps.meta.outputs.labels }}
4849
cache-from: type=gha

.github/workflows/ci.yml

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,37 @@
11
name: CI
22

33
on:
4-
pull_request:
5-
branches: [dev, main]
6-
push:
7-
branches: [dev, main]
4+
pull_request:
5+
branches: [dev, main, "feat/**"]
6+
push:
7+
branches: [dev, main, "feat/**"]
88

99
jobs:
10-
quality-check:
11-
name: Lint & Test
12-
runs-on: ubuntu-latest
10+
quality-check:
11+
name: Lint & Test
12+
runs-on: ubuntu-latest
1313

14-
steps:
15-
- name: Checkout repository
16-
uses: actions/checkout@v4
14+
steps:
15+
- name: Checkout repository
16+
uses: actions/checkout@v4
1717

18-
- name: Install pnpm
19-
uses: pnpm/action-setup@v4
18+
- name: Install pnpm
19+
uses: pnpm/action-setup@v4
2020

21-
- name: Setup Node.js
22-
uses: actions/setup-node@v4
23-
with:
24-
node-version: 20
25-
cache: 'pnpm'
21+
- name: Setup Node.js
22+
uses: actions/setup-node@v4
23+
with:
24+
node-version: 20
25+
cache: "pnpm"
2626

27-
- name: Install dependencies
28-
run: pnpm install --frozen-lockfile
27+
- name: Install dependencies
28+
run: pnpm install --frozen-lockfile
2929

30-
- name: Run Lint
31-
run: pnpm run lint
30+
- name: Run Lint
31+
run: pnpm run lint
3232

33-
- name: Type Check
34-
run: pnpm exec tsc --noEmit
33+
- name: Type Check
34+
run: pnpm exec tsc --noEmit
3535

36-
- name: Run Tests
37-
run: pnpm run test
36+
- name: Run Tests
37+
run: pnpm run test

Dockerfile.prod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ ENV PORT=3000
2828

2929
COPY --from=build /app/dist ./dist
3030
COPY --from=build /app/node_modules ./node_modules
31+
COPY --from=build /app/migrations ./migrations
3132
COPY --from=build /app/package.json ./
33+
COPY --from=build /app/drizzle.config.ts ./drizzle.config.ts
3234

3335
EXPOSE 3000
3436

infra/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Command to run infra at dev mode
2+
3+
Run it by pwd at root! Not include at this dir
4+
5+
```sh
6+
docker compose -f ./infra/dev/compose.dev.yaml --env-file .env --profile infra up --build -d -V
7+
```

infra/compose.dev.yaml

Lines changed: 0 additions & 54 deletions
This file was deleted.

infra/dev/README.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Файл для фронт разрабов
2+
3+
## Описание
4+
5+
Данный конфиг разворачивает полный инстанс бэкенда (API + DB + Redis)
6+
для локальной разработки фронтенда.
7+
8+
## ТРЕБОВАНИЯ:
9+
10+
1. Положить актуальный файл .env в директорию с этим файлом
11+
(путь: ./infra/dev/.env).
12+
2. Наличие Docker Desktop / Docker Engine.
13+
14+
## ЗАПУСК:
15+
16+
Выполните команду из корня проекта:
17+
18+
```sh
19+
docker compose -f ./infra/dev/compose.dev.yaml --profile infra up --pull always --build -d -V
20+
```
21+
22+
## ЧТО ВНУТРИ:
23+
24+
- API: http://localhost:3000
25+
- Postgres: localhost:6000 (пароли и база берутся из .env)
26+
- Redis: localhost:7000
27+
28+
## ОСОБЕННОСТИ:
29+
30+
- Авто-миграции: Приложение само накатит SQL-схему при старте.
31+
- Healthchecks: Контейнер API не поднимется, пока DB и Redis
32+
не станут доступны (status: healthy).
33+
- Изоляция: Используется выделенная сеть 'task-tracker-gateway'.
34+
35+
## RESET:
36+
37+
Если нужно полностью очистить базу и начать с нуля:
38+
39+
```sh
40+
docker compose -f ./infra/dev/compose.dev.yaml --profile infra down -v
41+
```

infra/dev/compose.dev.yaml

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
version: "3.9"
2+
3+
name: task-tracker-api
4+
5+
services:
6+
api:
7+
hostname: api
8+
container_name: api
9+
image: ghcr.io/task-tracker-lab/task-tracker-backend:feat-user
10+
env_file:
11+
- .env
12+
ports:
13+
- "3000:3000"
14+
depends_on:
15+
database:
16+
condition: service_healthy
17+
redis:
18+
condition: service_healthy
19+
networks:
20+
- backend
21+
deploy:
22+
resources:
23+
limits:
24+
cpus: "2.0"
25+
memory: 1024M
26+
reservations:
27+
cpus: "0.5"
28+
memory: 256M
29+
30+
database:
31+
hostname: database
32+
container_name: database
33+
image: postgres:16-alpine
34+
restart: always
35+
env_file:
36+
- .env
37+
environment:
38+
POSTGRES_USER: ${DB_USERNAME}
39+
POSTGRES_PASSWORD: ${DB_PASSWORD}
40+
POSTGRES_DB: ${DB_DATABASE}
41+
ports:
42+
- "6000:5432"
43+
volumes:
44+
- postgres_data:/var/lib/postgresql/data
45+
networks:
46+
- backend
47+
healthcheck:
48+
test:
49+
[
50+
"CMD-SHELL",
51+
'pg_isready -U "$$POSTGRES_USER" -d "$$POSTGRES_DB" -q || exit 1',
52+
]
53+
interval: 5s
54+
timeout: 5s
55+
retries: 5
56+
profiles: ["infra"]
57+
58+
redis:
59+
hostname: redis
60+
container_name: redis
61+
image: redis:7-alpine
62+
restart: always
63+
ports:
64+
- "7000:6379"
65+
command: redis-server --save 60 1 --loglevel notice
66+
volumes:
67+
- redis_data:/data
68+
networks:
69+
- backend
70+
healthcheck:
71+
test: ["CMD", "redis-cli", "ping"]
72+
interval: 5s
73+
timeout: 3s
74+
retries: 5
75+
profiles: ["infra"]
76+
77+
minio:
78+
hostname: minio
79+
container_name: minio
80+
image: minio/minio:latest
81+
restart: always
82+
environment:
83+
MINIO_ROOT_USER: ${S3_ACCESS_KEY}
84+
MINIO_ROOT_PASSWORD: ${S3_SECRET_KEY}
85+
ports:
86+
- "9000:9000" # API
87+
- "9001:9001" # Console (UI)
88+
command: server /data --console-address ":9001"
89+
volumes:
90+
- minio_data:/data
91+
networks:
92+
- backend
93+
profiles: [ "infra" ]
94+
95+
minio-init:
96+
image: minio/mc:latest
97+
depends_on:
98+
- minio
99+
environment:
100+
MINIO_ROOT_USER: ${S3_ACCESS_KEY}
101+
MINIO_ROOT_PASSWORD: ${S3_SECRET_KEY}
102+
networks:
103+
- backend
104+
profiles: [ "infra" ]
105+
entrypoint: >
106+
/bin/sh -c "
107+
sleep 5;
108+
mc alias set myminio http://minio:9000 ${S3_ACCESS_KEY} ${S3_SECRET_KEY};
109+
mc mb myminio/${S3_BUCKET_NAME} --ignore-existing;
110+
mc anonymous set download myminio/${S3_BUCKET_NAME};
111+
exit 0;
112+
"
113+
114+
volumes:
115+
postgres_data:
116+
redis_data:
117+
minio_data:
118+
119+
networks:
120+
backend:
121+
name: task-tracker-gateway

0 commit comments

Comments
 (0)