| Requirement | Version |
|---|---|
| Node.js | ≥ 18.0 |
| npm | ≥ 9.0 |
| TypeScript | ~5.8 |
| Package | Version | Purpose |
|---|---|---|
next |
^16.0.0 | React framework (App Router) |
react |
^19.0.0 | UI library |
react-dom |
^19.0.0 | React DOM renderer |
zustand |
^5.0.0 | State management |
@astryxdesign/core |
^0.1.8 | UI component library (153 components) |
@astryxdesign/theme-neutral |
^0.1.8 | Astryx theme |
@phosphor-icons/react |
^2.1.10 | Icon set |
@prisma/client |
^7.8.0 | Database ORM |
@prisma/adapter-neon |
^7.8.0 | Postgres driver adapter (Neon) |
@neondatabase/serverless |
^1.1.0 | Neon serverless Postgres driver |
prisma |
^7.8.0 | Prisma CLI (also listed as a runtime dep; used by postinstall) |
next-auth |
^5.0.0-beta.31 | Authentication |
bcryptjs |
^3.0.3 | Password hashing |
motion |
^12.42.2 | Animation library |
| Package | Version | Purpose |
|---|---|---|
@astryxdesign/cli |
^0.1.8 | Astryx component/token discovery CLI |
@types/node |
^22.0.0 | Node.js type definitions |
@types/react |
^19.0.0 | React type definitions |
@types/react-dom |
^19.0.0 | ReactDOM type definitions |
@types/bcryptjs |
^2.4.6 | bcryptjs type definitions |
typescript |
~5.8.0 | TypeScript compiler |
dotenv |
^17.4.2 | Loads .env for prisma.config.ts |
vitest |
^4.1.10 | Test runner |
@vitest/coverage-v8 |
^4.1.10 | Code coverage |
@playwright/test |
^1.61.1 | E2E testing |
@testing-library/react |
^16.3.2 | React testing utilities |
@testing-library/user-event |
^14.6.1 | User interaction simulation |
jsdom |
^29.1.1 | DOM implementation for tests |
See package.json for the authoritative, exact version list — this table is a point-in-time summary and will drift as dependencies are bumped.
{
"compilerOptions": {
"target": "ES2022",
"lib": ["dom", "dom.iterable", "esnext"],
"strict": true,
"module": "esnext",
"moduleResolution": "bundler",
"jsx": "preserve",
"incremental": true,
"paths": { "@/*": ["./src/*"] }
}
}Key settings:
- strict mode: All strict type-checking options enabled
- ES2022 target: Modern JavaScript output
- Bundler resolution: Compatible with Next.js bundler
- Path alias:
@/*maps to./src/*
const nextConfig: NextConfig = {
reactStrictMode: true,
};Minimal configuration. No custom webpack, no env files, no middleware.
generator client {
provider = "prisma-client"
output = "../src/generated/prisma"
}
datasource db {
provider = "postgresql"
}(The connection itself — DATABASE_URL plus the @prisma/adapter-neon driver adapter — is wired up in prisma.config.ts / src/lib/prisma.ts, not the url field here; Prisma 7's driver-adapter pattern moved that out of schema.prisma.)
# Prisma (Postgres — e.g. from Vercel Storage → Postgres, or Neon directly)
DATABASE_URL="postgresql://user:password@host/dbname?sslmode=require"
# NextAuth/Auth.js session secret — generate with: openssl rand -base64 32
AUTH_SECRET="your-secret-key-here"# Local development
npx prisma migrate dev --name init
npx prisma generate
npx prisma db push
# Production deployment (CI/deploy pipelines — non-interactive, no schema drift prompts)
npx prisma migrate deployPoint-in-time snapshot as of 2026-08-03 (v3.6.0) — expect drift; re-run the find/wc -l commands below rather than trusting these numbers long-term.
| Directory | Files | Total Lines |
|---|---|---|
src/engine/ad-console/core/ (incl. engine/, slices/) |
25 | ~2,330 |
src/engine/ad-console/features/ |
21 | ~1,180 |
src/engine/ad-console/ (root: index.ts, store.ts, scenarios.ts, types.ts) |
4 | ~180 |
src/components/AdConsole/ |
44 | ~3,930 |
src/components/ (root) |
3 | ~160 |
src/app/ (top-level, incl. globals.css) |
5 | ~4,530 |
src/lib/ |
7 | ~260 |
| Total src/ | — | ~20,700 |
Note: core/ was originally a 3-file module (types.ts, a single engine.ts, scenarios.ts); it's since been split into core/engine/ (one file per domain concern — campaign.ts, target.ts, adgroup.ts, negative.ts, budget.ts, portfolio.ts, draft.ts, id.ts, metrics.ts, responsive.ts, search-term-generator.ts), core/simulation.ts, and core/slices/ (the Zustand-dependent wrappers) — see CLAUDE.md for the current breakdown.
| File | Responsibility |
|---|---|
globals.css |
Design system tokens + responsive styles (largest single file in the repo) |
store.ts |
Zustand root store composition |
core/types.ts |
Domain interfaces |
core/scenarios.ts |
Training data & product catalog |
CampaignManager.tsx |
Campaign list + filters |
CampaignDetail.tsx |
Single campaign deep-dive |
wizard/CreateCampaignWizard.tsx + wizard/steps/** |
6-step, per-ad-type creation flow |
MobileNav.tsx |
Mobile/tablet hamburger drawer navigation |
auth.ts |
NextAuth configuration |
prisma.ts |
Prisma client singleton |
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
environment: 'jsdom',
globals: true,
setupFiles: ['./vitest.setup.ts'],
},
});npm test # Run all tests
npm run test:watch # Watch mode
npm run test:e2e # Playwright E2E tests| Metric | Target |
|---|---|
| First Contentful Paint | < 1.5s |
| Largest Contentful Paint | < 2.5s |
| Time to Interactive | < 3.5s |
| Cumulative Layout Shift | < 0.1 |
| Total Bundle Size | < 500KB |
- Password hashing: bcrypt (10 salt rounds)
- Session strategy: JWT
- Cookie flags: HTTP-only, Secure, SameSite=Lax
- User data isolation via userId foreign key
- Cascade deletes for user data
- Unique constraints on user email and campaign IDs
- Session validation on all protected routes
- Input validation on all endpoints
- Rate limiting (planned)
npm install -g vercel
vercelFROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npx prisma generate
RUN npm run build
EXPOSE 3000
CMD ["npm", "start"]DATABASE_URL="postgresql://user:password@host:5432/db"
AUTH_SECRET="strong-random-secret"