Full-Stack Monorepo with Next.js Frontend and Go Backend.
IMPORTANT: LLM-friendly documentation for the entire tech stack can be found in .docs/:
.docs/
├── nextjs.md # Next.js 16 App Router
├── tanstack-query.md # TanStack Query
├── better-auth.md # Better Auth
├── gorm.md # GORM ORM
├── goca.md # Goca CLI
├── orval.md # Orval API Generator
├── river.md # River Job Queue
├── background-jobs.md # Background Job Integration
├── shadcn.md # shadcn/ui
├── tailwind.md # Tailwind CSS 4
├── kamal-deploy.md # Kamal Deployment
├── logging.md # Logging (zerolog + Pino)
└── disaster-recovery.md # Database Backups & Recovery
Always check
.docs/first before searching the internet!
| Component | Technology |
|---|---|
| Frontend | Next.js 16, TypeScript, Tailwind CSS, shadcn/ui |
| Frontend Architecture | Feature-Sliced Design (FSD) |
| Backend | Go, Gorilla Mux, Clean Architecture, GORM |
| Code Generator | Goca CLI (Go Clean Architecture) |
| Database | PostgreSQL 16 |
| Auth | Better Auth (Magic Link, JWT) |
| Background Jobs | River (PostgreSQL-native, ~66k jobs/sec) |
| Real-time | Server-Sent Events (SSE) |
| API | Swagger/swag → Orval |
| Logging | zerolog (Go) + Pino (Next.js) |
| Log Aggregation | Grafana + Loki + Promtail |
| Database Backups | postgres-backup-s3 + RustFS (S3-compatible) |
| Linting | Biome + Steiger (FSD) |
# Goca (Backend Code Generation)
go install github.com/sazardev/goca@latest
# Gitleaks (Security Scanning)
brew install gitleaks
# Sitefetch (Documentation Fetching)
bun install -g sitefetch# Clone repository
git clone <repo-url>
cd next-go-pg
# Install dependencies
make install
# Start database
make db-up
# Create Better Auth tables
cd frontend && DATABASE_URL="postgres://postgres:postgres@localhost:5432/nextgopg" bunx @better-auth/cli migrate -y
# Start development
make devOpen:
- Frontend: http://localhost:3000
- Backend: http://localhost:8080
next-go-pg/
├── backend/ # Go Backend (Clean Architecture)
│ ├── cmd/server/ # Entrypoint
│ ├── internal/
│ │ ├── domain/ # Entities (goca make entity)
│ │ ├── usecase/ # Business Logic (goca make usecase)
│ │ ├── repository/ # Data Access (goca make repository)
│ │ ├── handler/ # HTTP Handler (goca make handler)
│ │ ├── middleware/ # Auth (JWT + Better Auth), CORS, Logging
│ │ ├── jobs/ # River Background Jobs
│ │ └── sse/ # Server-Sent Events Broker
│ ├── pkg/logger/ # zerolog Logger
│ └── docs/ # Swagger (generated)
├── frontend/ # Next.js Frontend (FSD Architecture)
│ ├── src/
│ │ ├── app/ # Next.js App Router
│ │ ├── widgets/ # Composite UI (Header)
│ │ ├── features/ # User Interactions (Auth, Stats, Data Export)
│ │ ├── entities/ # Business Objects (User)
│ │ └── shared/ # Reusable (UI, API, Lib, Logger)
│ └── orval.config.ts # API Generator Config
├── docker-compose.dev.yml # Dev Database + Mailpit
├── docker-compose.logging.yml # Logging Stack (Grafana + Loki)
├── docker-compose.backup.yml # Backup Stack (postgres-backup-s3 + RustFS)
├── deploy/
│ ├── loki/ # Loki & Promtail Config
│ └── grafana/ # Grafana Provisioning
├── Makefile # Build Commands
└── README.md
This project uses GitHub Actions for continuous integration and automatic releases.
| Check | Tool | Description |
|---|---|---|
| Backend Lint | golangci-lint | Go code quality |
| Backend Security | gosec | Security vulnerabilities |
| Backend Test | go test | Unit tests with race detection |
| Frontend Lint | Biome + Steiger | Code style + FSD architecture |
| Frontend Typecheck | TypeScript | Type safety |
| Dependency Review | GitHub | CVE scanning |
| Secret Scan | Gitleaks | Prevent leaked secrets |
Releases are automated based on Conventional Commits:
| Commit Type | Version Bump | Example |
|---|---|---|
fix: |
Patch (0.0.X) | fix: resolve login bug |
feat: |
Minor (0.X.0) | feat: add dark mode |
feat!: |
Major (X.0.0) | feat!: redesign API |
When you merge to main:
- Release Please creates a "Release PR" with updated CHANGELOG
- You review and merge the Release PR
- GitHub Release is created automatically
- Go binaries + Docker images are built
Commits are validated by commitlint:
# Format
<type>(<scope>): <description>
# Examples
feat: add user authentication
fix(api): resolve timeout issue
docs: update READMETypes: feat, fix, docs, style, refactor, perf, test, build, ci, chore
This project uses gitleaks to prevent committing secrets and sensitive data.
# Install gitleaks
brew install gitleaks # macOS
# or
go install github.com/gitleaks/gitleaks/v8@latest
# Setup git hooks (runs automatically with make install)
make setup-hooks- API keys, tokens, and passwords
- Absolute paths with usernames
- Database URLs with embedded credentials
- Private keys and certificates
- AWS/GCP/Azure credentials
make security-scan # Scan entire codebasegit commit --no-verifymake dev # Start DB + Frontend + Backend
make dev-frontend # Frontend only (localhost:3000)
make dev-backend # Backend only (localhost:8080)make db-up # Start PostgreSQL
make db-down # Stop PostgreSQL
make db-reset # Reset databasemake api # Generate TypeScript client from OpenAPImake lint # Biome + Steiger (FSD) Linting
make lint-fix # Auto-fix
make typecheck # TypeScript Check
make test # Run tests
make security-scan # Scan for secretsmake build # Frontend + Backend
make build-frontend # Next.js Production Build
make build-backend # Go Binarymake search-docs q="query" # Search docs with semantic search
make search-docs q="query" n=10 # Search with custom result count
make fetch-docs url=<url> # Fetch LLM-friendly docs
make fetch-docs url=<url> name=<n> # With custom filenamemake logs-up # Start Grafana + Loki + Promtail
make logs-down # Stop logging stack
make logs-open # Open Grafana (localhost:3001)
make logs-query q='{level="error"}' # Query logs via CLIFully automatic PostgreSQL backups to S3-compatible storage (RustFS).
make backup-up # Start automatic backup system
make backup-down # Stop backup stack
make backup-now # Create backup immediately
make backup-list # List all backups in S3
make backup-restore # Restore from latest backup- Schedule: Daily (configurable via
BACKUP_SCHEDULE) - Retention: 7 days (configurable via
BACKUP_KEEP_DAYS) - Storage: RustFS Console at http://localhost:9001
See Disaster Recovery for details.
- Add Swagger comments to Go handler
- Generate TypeScript client:
make api - Use generated hooks:
import { useGetStats } from "@shared/api/endpoints/users/users"
function MyComponent() {
const { data, isLoading } = useGetStats()
// ...
}PostgreSQL-native job queue with ~66k jobs/sec throughput.
| Job | Description | Trigger |
|---|---|---|
send_magic_link |
Magic Link email | Login request |
send_verification_email |
Email verification | New user |
send_2fa_otp |
2FA code | 2FA enabled |
send_login_notification |
Login alert | New device/IP |
data_export |
CSV/JSON export | User request |
Export user data with real-time progress via SSE:
// Frontend: Start export
const { mutate: startExport } = usePostExportStart()
startExport({ data: { format: "csv", dataType: "all" } })
// Listen for progress via SSE
useEffect(() => {
const es = new EventSource("/api/v1/events")
es.addEventListener("export-progress", (e) => {
const progress = JSON.parse(e.data)
// { jobId, status, progress: 0-100, downloadId }
})
}, [])User Request → Handler → Enqueue Job → PostgreSQL → River Worker → Process
↓
SSE Broadcast ← Progress Events
Better Auth with Magic Link (passwordless) authentication.
- User enters email on
/login - Backend sends Magic Link email
- User clicks link → Token verified → Logged in
/login- Magic Link login/magic-link/verify- Link verification UI/verify-email- Email verification for new users/settings- Session management (view/revoke sessions)/dashboard- Protected area
- Passwordless: Magic Link authentication
- Rate Limiting: 3 requests per minute
- Session Management: View and revoke sessions
- Login Notifications: Email on new device/IP
- Cross-Tab Sync: Logout syncs across tabs
import { signIn, signOut, authClient } from "@shared/lib/auth-client"
// Request Magic Link
await signIn.magicLink({
email,
callbackURL: "/dashboard",
})
// Sign out
await signOut()
// List sessions
const { data: sessions } = await authClient.listSessions()
// Revoke session
await authClient.revokeSession({ token })Mailpit is included for local email testing:
make dev # Starts Mailpit on port 8025Open http://localhost:8025 to view emails.
DATABASE_URL=postgres://postgres:postgres@localhost:5432/nextgopg
NEXT_PUBLIC_APP_URL=http://localhost:3000
NEXT_PUBLIC_API_URL=http://localhost:8080
BETTER_AUTH_SECRET=<at-least-32-characters>
DATABASE_URL=postgres://postgres:postgres@localhost:5432/nextgopg
PORT=8080
make db-up # PostgreSQL onlymake docker-build # Build images
make docker-up # Start containers
make docker-down # Stop containerscd backend
# New feature with all layers
goca feature Product --fields "name:string,price:float64,stock:int"
# Entity only
goca make entity Product
# Repository only
goca make repository Product
# Swagger + Orval (one command from root!)
cd ..
make apimake api automatically runs:
- swag init → Generates Swagger from Go comments
- orval → Generates TypeScript React Query Hooks
- Technical Docs (.docs) - LLM-friendly Tech Stack Docs
- Frontend README
- Backend README
- Goca Documentation