Contributing Guide
Developer5 min read
Contributing to nyxCore
Prerequisites
- Node.js >= 18
- Docker (for PostgreSQL + Redis)
- npm (package manager)
Environment Setup
- Clone the repo and install dependencies:
git clone <repo-url>
cd nyxcore-systems
npm install
- Copy
.env.exampleand fill in required values:
cp .env.example .env
Environment Variables
| Variable | Required | Description |
|---|---|---|
DATABASE_URL |
Yes | PostgreSQL connection string. Default: postgresql://nyxcore:nyxcore_dev@localhost:5432/nyxcore?schema=public |
REDIS_URL |
Yes | Redis connection string for rate limiting. Default: redis://localhost:6379 |
AUTH_SECRET |
Yes | NextAuth session secret. Generate with openssl rand -base64 32 |
AUTH_URL |
Yes | NextAuth base URL. Default: http://localhost:3000 |
ENCRYPTION_KEY |
Yes | 32-byte base64 key for AES-256-GCM API key encryption. Generate with openssl rand -base64 32 |
RESEND_API_KEY |
No | Resend API key for transactional emails |
EMAIL_FROM |
No | Sender address for emails. Format: Name <email@domain.com> |
NODE_ENV |
No | development (default), production, or test |
GITHUB_CLIENT_ID |
No | GitHub OAuth app client ID |
GITHUB_CLIENT_SECRET |
No | GitHub OAuth app client secret |
KIMI_BASE_URL |
No | Override base URL for Kimi K2 / Moonshot AI provider |
GRAFANA_ADMIN_PASSWORD |
No | Grafana admin password (production monitoring) |
HETZNER_API_KEY |
No | Hetzner DNS API token for Traefik ACME TLS |
STRIPE_SECRET_KEY |
No | Stripe API secret key for billing |
STRIPE_WEBHOOK_SECRET |
No | Stripe webhook signing secret |
NEXT_PUBLIC_APP_URL |
No | Public app URL for Stripe redirects. Default: http://localhost:3000 |
- Start infrastructure and database:
npm run docker:up # Start PostgreSQL 16 (pgvector) + Redis 7
npm run db:push # Apply Prisma schema to database
npm run db:generate # Generate Prisma client
npm run db:seed # Seed default tenant + personas
- Apply Row-Level Security policies:
psql $DATABASE_URL -f prisma/rls.sql
- Start the dev server:
npm run dev
# Or use the all-in-one script:
./scripts/dev-start.sh # Starts docker + dev server together
Available Scripts
| Script | Command | Description |
|---|---|---|
dev |
next dev |
Start Next.js development server with hot reload |
build |
next build |
Create optimized production build |
start |
next start |
Start production server (requires build first) |
lint |
next lint |
Run ESLint on the codebase |
typecheck |
tsc --noEmit |
TypeScript type checking without emit |
test |
vitest run |
Run all unit tests (Vitest) |
test:watch |
vitest |
Run tests in watch mode |
test:e2e |
playwright test |
Run end-to-end tests (Chromium + Mobile) |
db:generate |
prisma generate |
Regenerate Prisma client after schema changes |
db:push |
prisma db push |
Push schema changes to DB (no migration file) |
db:migrate |
prisma migrate dev |
Create and apply a named migration |
db:seed |
prisma db seed |
Seed database with default tenant and personas |
db:seed:init |
tsx prisma/seed-init.ts |
Initial seed (default tenant only) |
db:studio |
prisma studio |
Open Prisma Studio GUI at localhost:5555 |
docker:up |
docker compose up -d |
Start PostgreSQL + Redis containers |
docker:down |
docker compose down |
Stop containers (data persisted in volumes) |
Helper Scripts
| Script | Description |
|---|---|
scripts/dev-start.sh |
Start docker + dev server in one command |
scripts/deploy.sh |
Production deployment script |
scripts/db-backup.sh |
Database backup utility |
scripts/db-migrate-safe.sh |
Safe production migration (filters destructive DDL) |
scripts/memory-pull.sh |
Pull .memory/ letter files from GitHub |
scripts/run-analysis.ts |
Run code analysis pipeline via CLI |
scripts/copy-to-ckb-nyx.ts |
Copy files to CKB container |
scripts/md2pdf.py |
Convert Markdown files to PDF |
scripts/run-persona-eval.ts |
Run persona evaluation pipeline |
scripts/analyze-persona-results.ts |
Analyze persona evaluation results |
scripts/harden-persona-prompts.ts |
Harden persona system prompts |
Development Workflow
Schema Changes
After editing prisma/schema.prisma:
npm run db:push # Apply schema to DB
npm run db:generate # Regenerate Prisma client types
For production-tracked changes, use npm run db:migrate instead of db:push.
Adding a New tRPC Router
- Create router in
src/server/trpc/routers/<name>.ts - Register in
src/server/trpc/router.ts - Use
protectedProcedure(auth + tenant) orllmProtectedProcedure(+ LLM rate limit) - Access via
trpc.<router>.<procedure>in client components
Adding a New Dashboard Page
- Create
src/app/(dashboard)/dashboard/<feature>/page.tsxwith"use client" - Use tRPC hooks:
const { data } = trpc.<router>.<method>.useQuery() - Follow spacing/header conventions:
space-y-6, uppercase tracking-wider titles
Testing
Unit Tests
npm run test # All tests
npx vitest run tests/unit/crypto.test.ts # Single file
npm run test:watch # Watch mode
- Location:
tests/unit/*.test.ts - Framework: Vitest with globals enabled
- Setup:
tests/setup.ts(mocks env vars) - Path alias:
@/maps to./src/
E2E Tests
npx playwright install # Install browsers (first time)
npm run test:e2e # Run all E2E tests
- Location:
tests/e2e/*.spec.ts - Framework: Playwright (Chromium + Mobile viewports)
Pre-Commit Checks
Before committing, run:
npm run typecheck && npm run lint && npm run test
Infrastructure
| Service | Image | Port | Purpose |
|---|---|---|---|
| PostgreSQL | pgvector/pgvector:pg16 |
5432 | Primary database with vector extension |
| Redis | redis:7-alpine |
6379 | Rate limiting (fail-open) |
| CKB | ghcr.io/simplyliz/ckb:latest |
— | Code Knowledge Base (repository analysis) |
Data is persisted in Docker volumes (postgres_data, redis_data). docker:down stops containers but preserves data.
Code Style
- TypeScript strict mode
- Radix UI primitives + CVA variants in
src/components/ui/ - CSS variables with
nyx-*namespace, dark mode via.darkclass - Utility:
cn()(clsx + tailwind-merge) - LLM providers use BYOK pattern — tenant API keys encrypted at rest (AES-256-GCM)
