persona-community-3/CLAUDE.md
jordan f53b908499
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
ci/woodpecker/manual/woodpecker Pipeline was successful
Initialize project from skeleton template
2026-02-23 11:10:35 +00:00

6.3 KiB

persona-community-3

AI Persona Generation Community

Find Your Guide

If you need to... Read this
Set up local dev local/setup.md
Build a feature feature-development.md
Backend API patterns backend/api-patterns.md
Frontend design system frontend/design-system.md
Auth & user management auth.md
Event channels events.md
Media pipeline media.md
Album generation album.md
Generate personas personagen.md
Deploy ops/deploying.md

Quick Reference

# Start local dev
./scripts/dev.sh

# Run quality checks
./scripts/quality.sh

# List all components
./scripts/discover.sh

Critical Rules

  • Handler pattern: All handlers return error, wrapped with app.Wrap(). HTTPErrors map to status codes; raw errors become 500.
  • Request binding: Always use app.Bind() or app.BindAndValidate(). Never use raw json.NewDecoder.
  • URL parameters: Use brace syntax {param} for chi URL parameters. NEVER use colon syntax :param - it won't work and will cause 404s. Extract with chi.URLParam(r, "param").
  • Error types: Use httperror.BadRequest, httperror.NotFound, etc. Never bare http.Error().
  • Response envelope: Use httpresponse.OK, httpresponse.Created, httpresponse.NoContent. All responses use {data, meta} envelope.
  • Auth middleware: Auth is opt-in. Use auth.Middleware() in route groups for protected endpoints.
  • OpenAPI first: Document endpoints in spec.go using openapi.* helpers. Mount with application.EnableDocs(spec).
  • CSS variables: All UI components use CSS custom properties (var(--background), var(--accent), etc.). Never hardcode colors.
  • Monorepo imports: Go packages from git.threesix.ai/jordan/persona-community-3/pkg/*, TypeScript from @persona-community-3/*.
  • Database: Production uses CockroachDB (provisioned by the platform). Local dev uses PostgreSQL via docker-compose. Both are wire-compatible via lib/pq. Write SQL compatible with both — avoid PostgreSQL-only features (advisory locks, listen/notify, tsvector).
  • NO WEBSOCKETS. EVER. All real-time communication uses HTTP2 + SSE. User → server is HTTP2 POST. Server → user is SSE. This includes chat, notifications, progress, everything.
  • Event flow: POST → Service (enqueue) → Queue → Worker (generate) → Redis pub/sub → Service SSE subscriber → User. Service is thin, worker does AI work.
  • Channel naming: user:<id> = events for a specific user. channel:<id> = events for a topic/room/resource. Document all channels in ./docs/channels.md.
  • Media uploads: POST returns job ID immediately. Progress and result come via SSE events. Never wait synchronously.
  • Media generation: Same pattern - POST queues job, returns ID, results via SSE. Video takes 2-5 min; never block HTTP. Text generation streams ai_chat_chunk events token-by-token.
  • Media storage: Backend returns complete URLs. Never construct storage paths in frontend. Variants (thumbnail, optimized) auto-generated.
  • No fake progress: Never simulate progress with timers. Real progress comes from real events.
  • Auth tokens: 15-minute access tokens with embedded session ID (sid). Refresh via POST /auth/refresh. Session revocation invalidates all tokens for that session.
  • Passwords: Bcrypt cost 12, min 8 chars, max 72. Hashing lives in pkg/auth/password.go. Never store plaintext.
  • Auth codes: OTP/magic link/reset codes are single-use and time-limited. In standalone dev mode (no DATABASE_URL), the code is always logged to stdout as [DEV] auth code created — use this code to log in code=XXXXXX — check the server terminal to get it. This works even when NOTIFY_URL is set. In production (with DATABASE_URL), emails go through the notify service (NOTIFY_URL/NOTIFY_API_KEY/NOTIFY_HOST/NOTIFY_FROM).
  • Dev user: Set DEV_USER_EMAIL=you@example.com (and optionally DEV_USER_PASSWORD) to seed your account into the in-memory store on startup so it survives restarts without re-registering.

Architecture

persona-community-3/
├── services/     # Go API services (port 8001+)
├── workers/      # Background workers (no port)
├── apps/         # Frontend applications (port 3001+)
├── cli/          # CLI tools (no port)
├── packages/     # Shared TypeScript packages
│   ├── ui/       # UI components (@persona-community-3/ui)
│   ├── layout/   # Dashboard layout (@persona-community-3/layout)
│   ├── auth/     # Auth provider (@persona-community-3/auth)
│   ├── api-client/ # Typed API client (@persona-community-3/api-client)
│   └── logger/   # HTTP/console logger (@persona-community-3/logger)
├── pkg/          # Shared Go packages
│   ├── app/      # Service bootstrapper (Wrap, Bind, Health)
│   ├── chassis/  # Facade re-exporting app types
│   ├── openapi/  # OpenAPI 3.0 spec builder + Scalar docs
│   ├── httperror/ # Typed HTTP errors
│   ├── httpresponse/ # Response envelope helpers
│   ├── httpvalidation/ # Struct validation
│   ├── middleware/ # RequestID, CORS, Recovery, Logger
│   ├── auth/     # JWT, API key, middleware
│   ├── config/   # Viper-based configuration
│   ├── httpclient/ # Resilient HTTP client
│   └── logging/  # slog wrapper
└── scripts/      # Development & CI scripts
Slot Language Port Range Purpose
services/ Go 8001+ REST APIs, backend services
workers/ Go none Background jobs, queue consumers
apps/ TypeScript 3001+ React, Next.js, Astro frontends
cli/ Go none CLI tools, scripts
packages/ TypeScript none Shared frontend packages
pkg/ Go none Shared backend packages

Components