Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

- **Framework**: Next.js 16, React 19, TypeScript ~5.8
- **State**: Zustand 5
- **Database**: Prisma 7 (SQLite dev)
- **Database**: Prisma 7 + Postgres (via `@prisma/adapter-neon`)
- **Auth**: NextAuth 5 (beta)
- **Testing**: Vitest 4, Playwright 1.61
- **Styling**: Tailwind CSS
- **Styling**: `@astryxdesign/core` components + CSS custom-property tokens (no Tailwind compiler wired up despite the name appearing in some older docs)

## Build & Test

Expand Down
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ These come from `AGENTS.md`, `LOOP.md`, `loop-constraints.md`, and `gate.yaml`
- `docs/` has deeper reference material: `ARCHITECTURE.md`, `API.md` (full engine function signatures), `SCHEMA.md`, `FEATURES.md`, `INTEGRATION.md` (porting guide), `AUTH.md`, `AUDIT-FOLLOWUPS.md`.
- `CHANGELOG.md` (repo root) tracks notable changes per release starting at 3.6.0; bump `version` in `package.json` (and the unused-but-should-stay-in-sync `coreState.version` in `core/slices/core.ts`) together with a new entry when cutting a release.
- `skills/`, `patterns/`, `gate.yaml`, `STATE.md`, `loop-*.md` support an autonomous triage/fix loop tool used against this repo — not part of the app runtime.
- `.claude/`, `.agents/`, `.codex/` (added via the `ecc-tools` bot PR #56) are an auto-generated agent-tooling bundle: a repo skill, Codex config/agent roles, workflow command scaffolds, and "continuous learning instincts" derived from git-history analysis — not part of the app runtime either. Treat `.claude/skills/Amazon-ad-console/SKILL.md` as unverified: it was generated from commit-history heuristics and contains at least one claim that doesn't match this repo (it says filenames use `camelCase` with invented examples like `adEngine.ts`; the real convention is PascalCase for components (`CampaignManager.tsx`) and lowercase-per-domain-concern for engine modules (`core/engine/campaign.ts`), per the Architecture section above). This file (`CLAUDE.md`) is the authoritative guide — prefer it over the generated skill wherever they disagree.

## Porting the engine

Expand Down
38 changes: 25 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Open [http://localhost:3000](http://localhost:3000) — the simulator loads with
|---|---|---|---|
| 1 | SP | Auto \| Coffee Filter \| Discovery | Automatic |
| 2 | SP | Manual \| Coffee Filter \| Exact Winners | Manual keyword |
| 3 | SB | Video \| Coffee Brand Awareness | Video creative |
| 3 | SB | Video \| Coffee Brand Awareness | Keyword (Video ad format) |
| 4 | SD | Views Remarketing \| 30 Day | Audience |
| 5 | SB | Product Collection \| Coffee Variety | Product targeting |
| 6 | SD | Contextual \| Coffee Accessories | Contextual |
Expand Down Expand Up @@ -75,11 +75,12 @@ Open [http://localhost:3000](http://localhost:3000) — the simulator loads with
|-------|-----------|
| Framework | Next.js 16 (App Router) |
| UI | React 19 |
| State | Zustand 5 (single store, 8 slices) |
| State | Zustand 5 (single store, 8 core slices + 7 feature slices) |
| Language | TypeScript 5.8 (strict mode) |
| Styling | Global CSS (premium design system with Amazon-faithful tokens) |
| UI components | `@astryxdesign/core` (153 components, theme via `@astryxdesign/theme-neutral`) |
| Styling | Global CSS tokens bridging Astryx to the Amazon-faithful visual identity |
| Engine | Pure TypeScript — zero React/UI dependencies |
| Database | Prisma + SQLite (local development) |
| Database | Prisma 7 + Postgres (via `@prisma/adapter-neon`) |
| Authentication | NextAuth v5 (credentials provider) |
| Password Hashing | bcryptjs |

Expand Down Expand Up @@ -131,9 +132,12 @@ Amazon-ad-console/
│ │ └── ad-console/
│ │ ├── core/ # Zero-dep engine
│ │ │ ├── types.ts # All domain interfaces
│ │ │ ├── engine.ts # Pure stateless functions
│ │ │ ├── engine/ # Pure stateless functions, one module per domain concern
│ │ │ │ └── (campaign, target, adgroup, negative, budget, portfolio, draft, id, metrics, responsive, search-term-generator).ts
│ │ │ ├── simulation.ts # 7-day performance simulator
│ │ │ ├── slices/ # Zustand StateCreator slices wrapping the engine
│ │ │ └── scenarios.ts # Training data & product catalog
│ │ ├── features/ # 7 SOLID feature modules
│ │ ├── features/ # 7 self-contained feature modules
│ │ │ ├── drills/ # Navigation coaching
│ │ │ ├── profiles/ # Multi-user profiles
│ │ │ ├── trainer/ # Certification & grading
Expand All @@ -143,26 +147,27 @@ Amazon-ad-console/
│ │ │ └── integrity/ # Data quality checks
│ │ ├── store.ts # Composed root Zustand store
│ │ ├── index.ts # Public API re-exports
│ │ ├── engine.ts # Backward-compat re-export
│ │ └── types.ts # Backward-compat re-export
│ │ ├── types.ts # Backward-compat re-export of core/types.ts
│ │ └── scenarios.ts # Backward-compat re-export of core/scenarios.ts
│ ├── components/
│ │ ├── AdConsole/ # React UI layer
│ │ │ ├── AdConsole.tsx # Root view router
│ │ │ ├── Dashboard.tsx # Aggregate metrics
│ │ │ ├── CampaignManager.tsx # Campaign list + filters
│ │ │ ├── CampaignDetail.tsx # Single campaign deep-dive
│ │ │ ├── CreateCampaignWizard.tsx # Multi-step creation flow
│ │ │ ├── PortfolioOverview.tsx # Portfolio grouping
│ │ │ ├── wizard/ # 6-step campaign creation flow (per SP/SB/SD)
│ │ │ │ └── CreateCampaignWizard.tsx
│ │ │ ├── layout/
│ │ │ │ ├── Sidebar.tsx # Navigation rail
│ │ │ │ ├── Sidebar.tsx # Desktop navigation rail
│ │ │ │ └── Topbar.tsx # Header with actions + UserMenu
│ │ │ ├── mobile/
│ │ │ │ └── MobileNav.tsx # Mobile drawer navigation
│ │ │ │ └── MobileNav.tsx # Mobile/tablet hamburger drawer navigation
│ │ │ ├── nav/
│ │ │ │ └── consoleNav.ts # Amazon console nav model
│ │ │ ├── metrics/
│ │ │ │ └── MetricCard.tsx # Reusable metric display
│ │ │ ├── details/ # Tab components
│ │ │ ├── details/ # Tab components + shared EmptyState
│ │ │ └── features/ # Feature-specific pages
│ │ │ ├── drills/DrillsPage.tsx
│ │ │ ├── missions/MissionsPage.tsx
Expand Down Expand Up @@ -190,7 +195,12 @@ Amazon-ad-console/
│ ├── INTEGRATION.md
│ ├── TECH-SPECS.md
│ ├── MOBILE_REDESIGN_PLAN.md
│ └── AUTH.md # Multi-user authentication guide
│ ├── AUTH.md # Multi-user authentication guide
│ ├── DEPLOYMENT.md # Vercel project setup and deploy process
│ └── AUDIT-FOLLOWUPS.md # Status of each audit finding, with PR links
├── CLAUDE.md # Architecture + conventions guide for Claude Code
├── CHANGELOG.md # Notable changes per release
├── .env.example # DATABASE_URL / AUTH_SECRET template
├── package.json
├── tsconfig.json
├── next.config.ts
Expand Down Expand Up @@ -232,7 +242,9 @@ See [docs/INTEGRATION.md](docs/INTEGRATION.md) for the full porting guide.
- [Tech Specs](docs/TECH-SPECS.md) — Dependencies, configuration, performance
- [Mobile Redesign Plan](docs/MOBILE_REDESIGN_PLAN.md) — Mobile-first redesign strategy
- [Authentication Guide](docs/AUTH.md) — Multi-user access setup and configuration
- [Deployment](docs/DEPLOYMENT.md) — Vercel project setup and deploy process
- [Audit Follow-Ups](docs/AUDIT-FOLLOWUPS.md) — Status of each finding from the 2026-07-21 audit, with PR links
- [Changelog](CHANGELOG.md) — Notable changes per release, starting at 3.6.0
Comment thread
projectamazonph marked this conversation as resolved.

## License

Expand Down
7 changes: 3 additions & 4 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ User Action → Component → Store Slice → Engine Function → New State →

### Server-Side Data Flow
```
Component → API Route → Prisma Client → SQLite Database
Component → API Route → Prisma Client (Neon adapter) → Postgres Database
Component ← API Response ← Prisma Query Result
```
Expand All @@ -123,7 +123,7 @@ Component ← API Response ← Prisma Query Result
- **Provider**: Credentials (email/password)
- **Session Strategy**: JWT
- **Password Hashing**: bcryptjs
- **Database**: SQLite via Prisma
- **Database**: Postgres via Prisma (`@prisma/adapter-neon`)

### API Route Protection
All `/api/*` routes check for valid session:
Expand Down Expand Up @@ -246,8 +246,7 @@ model Campaign {
### Environment Variables
```env
DATABASE_URL="postgresql://..."
NEXTAUTH_SECRET="your-secret-here"
NEXTAUTH_URL="http://localhost:3000"
AUTH_SECRET="your-secret-here"
```

### Production Considerations
Expand Down
40 changes: 17 additions & 23 deletions docs/AUTH.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ The application supports multiple users with isolated campaign data. Each user c

1. **NextAuth v5** — Authentication provider
2. **Prisma** — Database ORM
3. **SQLite** — Local development database
3. **Postgres** — Database (via `@prisma/adapter-neon`), used in every environment
4. **JWT Sessions** — Stateless session management

### Database Schema
Expand Down Expand Up @@ -54,27 +54,26 @@ model Campaign {
### 1. Install Dependencies

```bash
npm install prisma @prisma/client next-auth bcryptjs
npm install prisma @prisma/client @prisma/adapter-neon @neondatabase/serverless next-auth bcryptjs
npm install -D @types/bcryptjs
```

### 2. Initialize Prisma

```bash
npx prisma init --datasource-provider sqlite
npx prisma init --datasource-provider postgresql
```

### 3. Configure Environment Variables

Create `.env` file:

```env
# Prisma
DATABASE_URL="file:./dev.db"
# Prisma (Postgres — e.g. from Vercel Storage → Postgres, or Neon directly)
DATABASE_URL="postgresql://user:password@host/dbname?sslmode=require"

# NextAuth
NEXTAUTH_SECRET="your-secret-key-here"
NEXTAUTH_URL="http://localhost:3000"
# NextAuth/Auth.js session secret — generate with: openssl rand -base64 32
AUTH_SECRET="your-secret-key-here"
Comment thread
coderabbitai[bot] marked this conversation as resolved.
```

### 4. Run Migrations
Expand Down Expand Up @@ -295,25 +294,20 @@ export function SyncButton() {
## Production Deployment

### Database
Replace SQLite with a production database:
`prisma/schema.prisma` declares the `postgresql` datasource provider, used in every environment, not just production. The runtime connection (`DATABASE_URL` plus the `@prisma/adapter-neon` driver adapter) is wired up separately in `prisma.config.ts` / `src/lib/prisma.ts`, not in the schema itself — see `.env.example`:

```env
# PostgreSQL
DATABASE_URL="postgresql://user:password@localhost:5432/adconsole"

# MySQL
DATABASE_URL="mysql://user:password@localhost:3306/adconsole"
DATABASE_URL="postgresql://user:password@host/dbname?sslmode=require"
```

### Environment Variables
```env
DATABASE_URL="your-production-db-url"
NEXTAUTH_SECRET="strong-random-secret"
NEXTAUTH_URL="https://your-domain.com"
DATABASE_URL="your-postgres-connection-string"
AUTH_SECRET="strong-random-secret" # generate with: openssl rand -base64 32
```

### Security Checklist
- [ ] Use strong NEXTAUTH_SECRET (32+ characters)
- [ ] Use strong AUTH_SECRET (32+ characters)
- [ ] Enable HTTPS in production
- [ ] Set secure cookie flags
- [ ] Add rate limiting to auth endpoints
Expand All @@ -333,18 +327,18 @@ NEXTAUTH_URL="https://your-domain.com"
**"Unauthorized" error**
- Ensure user is logged in
- Check JWT token expiration
- Verify NEXTAUTH_SECRET is set
- Verify AUTH_SECRET is set

**Database connection errors**
- Run `npx prisma migrate dev`
- Check DATABASE_URL in .env
- Verify SQLite file exists
- Local development: run `npx prisma migrate dev` to apply pending migrations
- Production: run `npx prisma migrate deploy` instead (`migrate dev` is dev-only — it can prompt interactively and isn't safe for CI/deploy pipelines)
- Check DATABASE_URL in .env points at a reachable Postgres instance
Comment thread
coderabbitai[bot] marked this conversation as resolved.

### Debug Mode
Enable NextAuth debug logging:

```env
NEXTAUTH_DEBUG=true
AUTH_DEBUG=true
```

## Future Enhancements
Expand Down
2 changes: 1 addition & 1 deletion docs/FEATURES.md
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,7 @@ When clicking a tab-mapped item:
## 15. Multi-User Authentication

**Auth Provider**: NextAuth v5
**Database**: Prisma + SQLite
**Database**: Prisma + Postgres (via `@prisma/adapter-neon`)
**Components**: `SessionProvider.tsx`, `UserMenu.tsx`, `SyncButton.tsx`
**Pages**: `/auth/login`, `/auth/register`, `/landing`

Expand Down
91 changes: 51 additions & 40 deletions docs/TECH-SPECS.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,36 @@
| `react` | ^19.0.0 | UI library |
| `react-dom` | ^19.0.0 | React DOM renderer |
| `zustand` | ^5.0.0 | State management |
| `@prisma/client` | ^5.0.0 | Database ORM |
| `@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` | ^2.4.3 | Password hashing |
| `motion` | ^11.0.0 | Animation library |
| `bcryptjs` | ^3.0.3 | Password hashing |
| `motion` | ^12.42.2 | Animation library |

### Development

| 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.0 | bcryptjs type definitions |
| `@types/bcryptjs` | ^2.4.6 | bcryptjs type definitions |
| `typescript` | ~5.8.0 | TypeScript compiler |
| `prisma` | ^5.0.0 | Prisma CLI |
| `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 |

**Total runtime dependency count: 8** (next, react, react-dom, zustand, @prisma/client, next-auth, bcryptjs, motion)
See `package.json` for the authoritative, exact version list — this table is a point-in-time summary and will drift as dependencies are bumped.

## TypeScript Configuration

Expand Down Expand Up @@ -85,57 +92,62 @@ generator client {
}

datasource db {
provider = "sqlite"
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`.)

### Environment Variables
```env
# Prisma
DATABASE_URL="file:./dev.db"
# Prisma (Postgres — e.g. from Vercel Storage → Postgres, or Neon directly)
DATABASE_URL="postgresql://user:password@host/dbname?sslmode=require"

# NextAuth
NEXTAUTH_SECRET="your-secret-key-here"
NEXTAUTH_URL="http://localhost:3000"
# NextAuth/Auth.js session secret — generate with: openssl rand -base64 32
AUTH_SECRET="your-secret-key-here"
```

### Database Commands
```bash
npx prisma init --datasource-provider sqlite
# 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 deploy
```

## File Statistics

*Point-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/` | 3 | ~800 |
| `src/engine/ad-console/features/` | 21 | ~1,800 |
| `src/engine/ad-console/` (root) | 4 | ~220 |
| `src/components/AdConsole/` | 15 | ~1,800 |
| `src/components/` (root) | 3 | ~200 |
| `src/app/` | 8 | ~1,200 |
| `src/lib/` | 4 | ~300 |
| `prisma/` | 2 | ~100 |
| **Total src/** | **60+** | **~7,500** |

### Source File Breakdown

| File | Lines | Responsibility |
|------|-------|---------------|
| `globals.css` | 1,377 | Design system tokens + responsive styles |
| `store.ts` | 250 | Zustand root store composition |
| `engine.ts` | 600 | Core business logic functions |
| `types.ts` | 200 | Domain interfaces |
| `scenarios.ts` | 400 | Training data & product catalog |
| `CampaignManager.tsx` | 300 | Campaign list + filters |
| `CampaignDetail.tsx` | 550 | Single campaign deep-dive |
| `CreateCampaignWizard.tsx` | 200 | Multi-step creation flow |
| `MobileNav.tsx` | 133 | Mobile drawer navigation |
| `auth.ts` | 80 | NextAuth configuration |
| `prisma.ts` | 15 | Prisma client singleton |
| `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.

### Selected File Sizes

| 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 |

## Testing Configuration

Expand Down Expand Up @@ -210,6 +222,5 @@ CMD ["npm", "start"]
### Environment Variables for Production
```env
DATABASE_URL="postgresql://user:password@host:5432/db"
NEXTAUTH_SECRET="strong-random-secret"
NEXTAUTH_URL="https://your-domain.com"
AUTH_SECRET="strong-random-secret"
```
Loading