mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 20:01:09 +02:00
- Add migrate.ts script with PostgreSQL advisory locks to prevent concurrent migrations - Add retry logic with exponential backoff for transient connection errors - Update CI/CD workflows to run migrations before deployment with health polling - Create comprehensive DATABASE_MIGRATIONS.md documentation covering: - Drizzle ORM internals (push vs generate/migrate modes) - Migration tracking (journal files, __drizzle_migrations table) - Advisory lock architecture and timeout handling - Zero-downtime migration patterns (expand-contract) - Troubleshooting guide - Update .claude/guidelines/database.md with migration quick reference - Remove stale migration files that caused schema conflicts
6.1 KiB
6.1 KiB
Mana Core Auth - Claude Code Guidelines
Project Overview
Mana Core Auth is the central authentication service for the Mana Universe ecosystem. It uses Better Auth for all authentication functionality.
⚠️ CRITICAL RULES FOR CLAUDE CODE
1. ALWAYS USE BETTER AUTH - NO EXCEPTIONS
DO NOT implement custom authentication logic. Better Auth handles:
- User registration and sign-in
- JWT token generation (EdDSA algorithm)
- JWT token verification (via JWKS)
- Session management
- Organization/multi-tenant support
- Password hashing
- Token refresh
2. JWT Rules
| DO | DON'T |
|---|---|
Use jose library for JWT operations |
Use jsonwebtoken library |
| Use Better Auth's JWKS endpoint | Configure RSA keys in .env |
| Use EdDSA algorithm (Better Auth default) | Use RS256 or HS256 |
Fetch JWKS from /api/v1/auth/jwks |
Hardcode public keys |
| Keep JWT claims minimal | Add credit_balance, org data to JWT |
3. Before Making Auth Changes
- Read the docs first:
docs/AUTHENTICATION_ARCHITECTURE.md - Check Better Auth docs: https://www.better-auth.com/docs
- Ask: "Does Better Auth already provide this?" - Usually YES
- Use Context7: Fetch Better Auth documentation before implementing
4. Token Validation Pattern
// CORRECT - Use jose with JWKS
import { jwtVerify, createRemoteJWKSet } from 'jose';
const JWKS = createRemoteJWKSet(new URL('/api/v1/auth/jwks', baseUrl));
const { payload } = await jwtVerify(token, JWKS, { issuer, audience });
// WRONG - Never do this
import * as jwt from 'jsonwebtoken';
jwt.verify(token, publicKey, { algorithms: ['RS256'] });
Tech Stack
- Framework: NestJS 10
- Auth: Better Auth with JWT + Organization plugins
- Database: PostgreSQL with Drizzle ORM
- JWT Library:
jose(NOTjsonwebtoken)
Commands
# Development
pnpm start:dev # Start with hot reload
# Build
pnpm build # Production build
# Database
pnpm db:push # Push schema to database
pnpm db:generate # Generate migrations
pnpm db:migrate # Run migrations
# Testing
pnpm test # Unit tests
pnpm test:e2e # E2E tests
Project Structure
services/mana-core-auth/
├── src/
│ ├── auth/
│ │ ├── better-auth.config.ts # Better Auth setup
│ │ ├── services/
│ │ │ └── better-auth.service.ts # Auth service
│ │ ├── auth.controller.ts # Auth endpoints
│ │ └── dto/ # Request DTOs
│ ├── credits/ # Credit system
│ ├── db/
│ │ ├── schema/ # Drizzle schemas
│ │ ├── migrations/ # Generated migration files
│ │ ├── connection.ts # DB connection
│ │ └── migrate.ts # Migration script with advisory locks
│ └── config/
│ └── configuration.ts # App config
├── docs/
│ └── AUTHENTICATION_ARCHITECTURE.md # READ THIS FIRST
└── test/
Database Migrations
For comprehensive migration documentation, see docs/DATABASE_MIGRATIONS.md.
Key points:
- Use
db:pushfor development (fast iteration) - Use
db:generate+db:migratefor production (tracked migrations) - Migrations use advisory locks to prevent concurrent execution
- CI/CD runs migrations automatically before code deployment
Key Files
| File | Purpose |
|---|---|
src/auth/better-auth.config.ts |
Better Auth configuration with JWT + Org plugins |
src/auth/services/better-auth.service.ts |
Main auth service - ALL auth logic here |
src/db/schema/auth.schema.ts |
User, session, account, jwks tables |
docs/AUTHENTICATION_ARCHITECTURE.md |
Comprehensive auth documentation |
Environment Variables
# Required
DATABASE_URL=postgresql://...
JWT_ISSUER=manacore
JWT_AUDIENCE=manacore
# NOT required for Better Auth JWT (auto-generates EdDSA keys)
# JWT_PRIVATE_KEY=... # DON'T USE - Better Auth uses jwks table
# JWT_PUBLIC_KEY=... # DON'T USE - Better Auth uses jwks table
Common Tasks
Adding a new auth endpoint
- Check if Better Auth already provides it
- If yes, wrap it in
better-auth.service.ts - Expose via
auth.controller.ts - Add DTO validation
Validating tokens from other services
Other services call POST /api/v1/auth/validate with the JWT. The validation uses Better Auth's JWKS (EdDSA keys from auth.jwks table).
Adding JWT claims
DON'T add dynamic data to JWT claims. Keep them minimal:
sub(user ID)emailrolesid(session ID)
For dynamic data (credits, org info), create API endpoints instead.
Debugging
Token not validating?
- Check algorithm:
echo $TOKEN | cut -d'.' -f1 | base64 -d- Should be
EdDSA, NOTRS256
- Should be
- Check JWKS endpoint:
curl localhost:3001/api/v1/auth/jwks - Check issuer/audience match between signing and validation
User can't sign in?
- Check database connection
- Check
auth.userstable exists - Check
auth.accountstable for credential record
Testing Auth Flow
# Register
curl -X POST http://localhost:3001/api/v1/auth/register \
-H "Content-Type: application/json" \
-d '{"email": "test@example.com", "password": "password123", "name": "Test"}'
# Login
curl -X POST http://localhost:3001/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"email": "test@example.com", "password": "password123"}'
# Validate token
curl -X POST http://localhost:3001/api/v1/auth/validate \
-H "Content-Type: application/json" \
-d '{"token": "eyJhbGciOiJFZERTQSIs..."}'