Files
Matt 8cc86bae20 docs: map existing codebase
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 23:14:08 +01:00

5.9 KiB

Technology Stack

Analysis Date: 2026-02-26

Languages

Primary:

  • TypeScript 5.7 - All application code (strict mode, noEmit, ES2022 target)

Secondary:

  • CSS (Tailwind utility classes only, no custom CSS files)

Runtime

Environment:

  • Node.js >=20.0.0 (engines field in package.json)

Package Manager:

  • npm (standard)
  • Lockfile: package-lock.json present

Frameworks

Core:

  • Next.js 15.1 - App Router, standalone output, Turbopack dev mode
  • React 19.0 - Server Components by default; 'use client' only where needed

API Layer:

  • tRPC 11 (RC build 11.0.0-rc.678) - End-to-end typed RPC, superjson transformer
  • @trpc/server, @trpc/client, @trpc/react-query - All at same version

Data:

  • Prisma 6.19 - ORM and schema-first migrations; binary targets: native, windows, linux-musl-openssl-3.0.x
  • @prisma/client 6.19 - Generated client with connection pool (limit=20, timeout=10)

Auth:

  • NextAuth v5 (Beta 25) - JWT strategy, 24-hour sessions; Prisma adapter via @auth/prisma-adapter

Forms & Validation:

  • Zod 3.24 - Input validation for all tRPC procedures
  • React Hook Form 7.54 - Client-side form state; @hookform/resolvers for Zod integration

UI Components:

  • shadcn/ui (configured via components.json) - Radix UI primitives styled with Tailwind
  • Radix UI primitives: alert-dialog, avatar, checkbox, collapsible, dialog, dropdown-menu, label, popover, progress, radio-group, scroll-area, select, separator, slider, slot, switch, tabs, toggle, tooltip (all ^1.x or ^2.x)
  • Tailwind CSS 4.1 - Utility-first, @tailwindcss/postcss plugin
  • Lucide React 0.563 - Icon library (import-optimized via next.config.ts)
  • Framer Motion 11 (motion package) - Animation
  • Tremor 3.18 - Data visualization / chart components
  • @blocknote/react, @blocknote/core, @blocknote/shadcn 0.46 - Rich text block editor
  • next-themes 0.4 - Dark/light mode switching
  • Sonner 2.0 - Toast notifications

Testing:

  • Vitest 4.0 - Test runner, fileParallelism: false, pool: 'forks'
  • @playwright/test 1.49 - E2E test runner

Build/Dev:

  • Turbopack (built into Next.js 15) - Dev server via next dev --turbopack
  • tsx 4.19 - Direct TypeScript execution for scripts and seeds
  • ESLint 9.17 + eslint-config-next 15.1 - Linting
  • Prettier 3.4 + prettier-plugin-tailwindcss 0.7 - Formatting

Key Dependencies

Critical:

  • superjson 2.2 - tRPC transformer; enables Date, Map, Set serialization over the wire
  • bcryptjs 3.0 - Password hashing (no native bcrypt — pure JS for portability)
  • minio 8.0 - S3-compatible object storage client
  • nodemailer 7.0 - SMTP email delivery
  • openai 6.16 - OpenAI SDK for AI features
  • @anthropic-ai/sdk 0.78 - Anthropic Claude SDK; wrapped in adapter matching OpenAI interface
  • @notionhq/client 2.3 - Notion API for project import
  • csv-parse 6.1 - CSV import for candidatures seed

Infrastructure:

  • date-fns 4.1 - Date manipulation
  • use-debounce 10.0 - Input debouncing
  • @tanstack/react-query 5.62 - Server state caching (used via tRPC)
  • @dnd-kit/core, @dnd-kit/sortable - Drag-and-drop ordering UI
  • leaflet 1.9 + react-leaflet 5.0 - Map rendering
  • mammoth 1.11 - DOCX to HTML conversion for file content extraction
  • pdf-parse 2.4, unpdf 1.4 - PDF text extraction
  • html2canvas 1.4, jspdf 4.1, jspdf-autotable 5.0 - PDF export for reports
  • franc 6.2 - Language detection for multilingual project content
  • papaparse 5.4 - CSV parsing in browser
  • cmdk 1.0 - Command palette component
  • react-easy-crop 5.5 - Avatar image cropping
  • react-phone-number-input 3.4 - International phone number input
  • react-day-picker 9.13 - Date picker calendar

Configuration

TypeScript:

  • src/tsconfig.json: strict mode, ES2022 target, path alias @/*./src/*, bundler module resolution
  • Config file: tsconfig.json

Next.js:

  • Config file: next.config.ts
  • output: 'standalone' for Docker deployment
  • typedRoutes: true for compile-time route safety
  • serverExternalPackages: ['@prisma/client', 'minio'] — not bundled

Tailwind:

  • Config file: tailwind.config.ts
  • PostCSS via postcss.config.mjs + @tailwindcss/postcss
  • Brand palette: Primary Red #de0f1e, Dark Blue #053d57, White #fefefe, Teal #557f8c

Vitest:

  • Config file: vitest.config.ts
  • environment: 'node', testTimeout: 30000, sequential execution
  • Path alias mirrors tsconfig

Environment:

  • Required vars: DATABASE_URL, NEXTAUTH_URL, NEXTAUTH_SECRET, MINIO_ENDPOINT, MINIO_ACCESS_KEY, MINIO_SECRET_KEY, MINIO_BUCKET, SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS, EMAIL_FROM, OPENAI_API_KEY, CRON_SECRET
  • Optional vars: MINIO_PUBLIC_ENDPOINT, OPENAI_MODEL (default: gpt-4o), OPENAI_BASE_URL, ANTHROPIC_API_KEY, SESSION_MAX_AGE (default: 86400), MAX_FILE_SIZE (default: 524288000), LOG_LEVEL, MAGIC_LINK_EXPIRY (default: 900)
  • All settings also configurable via SystemSettings DB table (DB takes priority over env vars)

Build:

  • npm run buildnext build → produces .next/standalone/ output
  • npm run typechecktsc --noEmit (no emit, type checking only)

Platform Requirements

Development:

  • Node.js >=20.0.0
  • PostgreSQL 16 (via Docker or local)
  • MinIO instance (optional in dev, defaults to localhost:9000)

Production:

  • Docker (compose file: docker/docker-compose.yml)
  • PostgreSQL 16 (postgres:16-alpine image) in Docker network
  • Next.js app runs as standalone Node.js server on port 7600
  • MinIO and Poste.io are external pre-existing services on VPS
  • Nginx reverse proxy with SSL (external, not in compose)
  • CI/CD: Gitea Actions (image pushed to container registry, pull_policy: always)
  • App entrypoint (docker/docker-entrypoint.sh): runs prisma migrate deployprisma generate → auto-seeds if DB empty → node server.js

Stack analysis: 2026-02-26