All checks were successful
ci/woodpecker/push/deploy Pipeline was successful
Set up local dev workflow: SSH tunnel to dev DB, Next.js API proxy via rewrites, Docker or native backend on port 5000. Update and restructure project documentation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
178 lines
6.2 KiB
Markdown
178 lines
6.2 KiB
Markdown
# GoodBrick Site
|
||
|
||
Сайт производителя фасадной плитки GoodBrick с каталогом продукции.
|
||
|
||
## Stack
|
||
|
||
- **Frontend:** Next.js 16 + shadcn/ui + Tailwind CSS 4 (TypeScript)
|
||
- **Backend:** .NET 9 Web API (C#)
|
||
- **Database:** PostgreSQL 16
|
||
- **Proxy:** Caddy 2 (auto-SSL)
|
||
- **CI/CD:** Woodpecker CI (Gitea OAuth)
|
||
- **Git:** Gitea (self-hosted)
|
||
|
||
## Project Structure
|
||
|
||
```
|
||
GBSite/
|
||
├── frontend/ # Next.js app
|
||
│ ├── src/app/ # App Router pages
|
||
│ ├── src/lib/ # Utilities
|
||
│ ├── Dockerfile # Multi-stage: node:20-alpine
|
||
│ └── package.json
|
||
├── backend/ # .NET 9 Web API
|
||
│ ├── src/GBSite.Api/ # Main API project
|
||
│ │ ├── Controllers/
|
||
│ │ └── Program.cs
|
||
│ ├── GBSite.Api.sln
|
||
│ └── Dockerfile # Multi-stage: dotnet sdk → aspnet runtime
|
||
├── deploy/
|
||
│ ├── docker-compose.prod.yml
|
||
│ ├── docker-compose.dev.yml
|
||
│ └── docker-compose.local.yml # Local backend (Docker mode)
|
||
├── scripts/
|
||
│ ├── local-tunnel.ps1 # SSH tunnel to dev DB
|
||
│ ├── local-backend-docker.ps1 # Start Docker backend
|
||
│ ├── local-backend-dotnet.ps1 # Start native backend
|
||
│ └── local-frontend.ps1 # Start frontend dev server
|
||
├── .woodpecker/
|
||
│ └── deploy.yml # CI/CD pipeline
|
||
└── CLAUDE.md # This file
|
||
```
|
||
|
||
## Environments
|
||
|
||
| Env | Frontend URL | API URL | DB |
|
||
|-----|-------------|---------|-----|
|
||
| **Prod** | https://new.goodbrick.com.ua | https://new.goodbrick.com.ua/api/* | prod_db |
|
||
| **Dev** | https://dev.goodbrick.com.ua | https://dev.goodbrick.com.ua/api/* | dev_db |
|
||
| **Local** | http://localhost:3000 | http://localhost:5000/api/* | dev_db (via SSH tunnel) |
|
||
|
||
## Docker Containers (Server)
|
||
|
||
| Container | Internal Port | Host Port | Network |
|
||
|-----------|--------------|-----------|---------|
|
||
| gb-prod-frontend | 3000 | 127.0.0.1:3100 | app-network |
|
||
| gb-prod-backend | 5000 | 127.0.0.1:5100 | app-network |
|
||
| gb-dev-frontend | 3000 | 127.0.0.1:3200 | app-network |
|
||
| gb-dev-backend | 5000 | 127.0.0.1:5200 | app-network |
|
||
|
||
## Routing (Caddy)
|
||
|
||
Path-based routing — один домен для фронта и API:
|
||
- `domain.com/*` → frontend container (port 3000)
|
||
- `domain.com/api/*` → backend container (port 5000)
|
||
|
||
Backend получает запросы с prefix `/api/` (Caddy использует `handle`, не `handle_path`).
|
||
|
||
## Local Development
|
||
|
||
### Quick Start (3 терминала)
|
||
|
||
**Terminal 1 — SSH Tunnel (всегда нужен):**
|
||
```powershell
|
||
.\scripts\local-tunnel.ps1
|
||
```
|
||
|
||
**Terminal 2 — Backend (выбрать один):**
|
||
```powershell
|
||
# Работа с фронтом — бэкенд в Docker:
|
||
.\scripts\local-backend-docker.ps1
|
||
|
||
# Работа с бэком — dotnet run с hot-reload:
|
||
.\scripts\local-backend-dotnet.ps1
|
||
```
|
||
|
||
**Terminal 3 — Frontend:**
|
||
```powershell
|
||
.\scripts\local-frontend.ps1
|
||
```
|
||
|
||
### Как это работает
|
||
|
||
- **SSH Tunnel:** `localhost:5433` → сервер `31.131.18.254:5432` (dev_db)
|
||
- **Backend:** слушает на `localhost:5000`, подключается к БД через туннель
|
||
- **Frontend:** `npm run dev` на `:3000`, Next.js rewrites проксируют `/api/*` → `localhost:5000`
|
||
- **Переключение режимов:** Ctrl+C в терминале с бэком, запустить другой скрипт. Фронт перезапускать не нужно.
|
||
|
||
### Конфигурация
|
||
|
||
- `backend/src/GBSite.Api/appsettings.Local.json` — connection string к dev_db (gitignored)
|
||
- `frontend/.env.local` — `LOCAL_API_URL` и `INTERNAL_API_URL` для локального проксирования
|
||
- `deploy/docker-compose.local.yml` — Docker backend с `host.docker.internal:5433`
|
||
|
||
### URLs
|
||
- Frontend: http://localhost:3000
|
||
- Backend API: http://localhost:5000/api/health
|
||
- DB: localhost:5433 (через SSH tunnel к dev_db)
|
||
|
||
## Development (manual)
|
||
|
||
### Frontend
|
||
```bash
|
||
cd frontend && npm install && npm run dev
|
||
```
|
||
|
||
### Backend
|
||
```bash
|
||
cd backend && dotnet run --project src/GBSite.Api
|
||
```
|
||
|
||
### Build locally
|
||
```bash
|
||
cd frontend && npm run build
|
||
cd backend && dotnet build
|
||
```
|
||
|
||
## API Conventions
|
||
|
||
- All API routes start with `/api/`
|
||
- Controllers use attribute routing: `[Route("api/[controller]")]`
|
||
- Health check: `GET /api/health` — returns `{ status, database, environment }`
|
||
- Health ping: `GET /api/health/ping` — returns `{ status: "pong" }`
|
||
|
||
## Frontend Conventions
|
||
|
||
- App Router (not Pages Router)
|
||
- `src/app/` — pages and API routes
|
||
- `src/lib/` — shared utilities
|
||
- `src/components/` — React components (create when needed)
|
||
- shadcn/ui components via `npx shadcn@latest add <component>`
|
||
- Server-side calls to backend use `INTERNAL_API_URL` env var
|
||
- Client-side calls use relative paths (`/api/...`) — Caddy proxies them on server, Next.js rewrites locally
|
||
|
||
## Git & CI/CD
|
||
|
||
- **Repo:** https://git.goodbrick.com.ua/admin/gb-site
|
||
- **Branches:** `main` → prod deploy, `dev` → dev deploy
|
||
- **CI:** Woodpecker auto-deploys on push (SSH to server, git pull, docker compose build & up)
|
||
- **Commit style:** conventional, short descriptions in English
|
||
|
||
## Server
|
||
|
||
- **Host:** 31.131.18.254
|
||
- **SSH:** `ssh deploy@31.131.18.254` (key-based)
|
||
- **App location:** `/srv/apps/gb-site` (main), `/srv/apps/gb-site-dev` (dev worktree)
|
||
- **Caddy config:** `/srv/proxy/Caddyfile`
|
||
- **All services docs:** see SERVER.md
|
||
|
||
## Database
|
||
|
||
PostgreSQL доступен только внутри Docker network (container name: `postgres`).
|
||
|
||
Connection string format:
|
||
```
|
||
Host=postgres;Port=5432;Database={db};Username={user};Password={pass}
|
||
```
|
||
|
||
Configured via env var `ConnectionStrings__Default` in docker-compose files.
|
||
Locally via `appsettings.Local.json` with SSH tunnel (`localhost:5433`).
|
||
|
||
## Key Rules
|
||
|
||
- Never commit `.env` files or secrets — credentials are in docker-compose env vars on server
|
||
- Frontend standalone output (`output: "standalone"` in next.config.ts) — required for Docker
|
||
- Backend listens on port 5000 (`ASPNETCORE_URLS=http://+:5000`)
|
||
- All containers must be in `app-network` (external Docker network)
|
||
- `appsettings.Local.json` is gitignored — local dev overrides only
|