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
19 changes: 11 additions & 8 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,28 @@
|-------|-----------|-------|
| **Framework** | Next.js 16.1.1 (App Router) | Standalone output |
| **Runtime** | Bun | Package management + scripts |
| **Database** | Prisma v6 + SQLite (dev) / PostgreSQL (prod) | Local dev uses SQLite |
| **Database** | Prisma v6 + PostgreSQL | PostgreSQL only (no SQLite) |
| **Auth** | JWT (jose v6) + HttpOnly cookies + localStorage client cache | Custom |
| **UI** | Tailwind CSS v4 | Custom glass design system |
| **UI** | Tailwind CSS v4 | "Field Manual" light design system |
| **Icons** | Phosphor Icons (light weight) | No thick-stroked icons |
| **Animation** | Framer Motion v12 | Scroll reveals, stagger, hover physics |
| **Fonts** | Space Grotesk (headings) + Plus Jakarta Sans (body) | No Inter/Roboto |
| **AI** | Z AI Web Dev SDK | Coaching, scoring, content generation |
| **Export** | docx, PDF (pdfkit), Excel (exceljs) | Resource downloads |
| **Testing** | Vitest | unit + API + component tests |

## Design System — Ethereal Glass
## Design System — "Field Manual" (light theme)

> NOTE: The "Ethereal Glass" dark design previously described here was reverted. The live app uses the light "Field Manual" system below.

| Element | Spec |
|---------|------|
| **Background** | OLED black (`#050505`) with radial gradient orbs |
| **Cards** | Glass-morphism with `backdrop-blur-xl` |
| **Accents** | Indigo/violet, emerald (success), amber (warning), rose (danger) |
| **Motion** | Custom cubic-bezier: `ease-premium`, `ease-spring`, `ease-out-heavy` |
| **Components** | Double-bezel glass cards, pill CTAs with trailing icon pattern |
| **Background** | Warm off-white (`#FAFAF7`) with subtle grain/border texture |
| **Cards** | `FieldCard` — solid surface, thin border, soft shadow, no glass blur |
| **Accents** | Primary orange (`#FF6B35`), ink scale for text, emerald (success), amber (warning), rose (danger) |
| **Motion** | Framer Motion scroll reveals, stagger, hover physics (no custom cubic-beziers) |
| **Components** | `FieldButton` (variants: default/outline/ghost), `FieldCard`, `FieldBadge`, `Alert` |
| **Tokens** | Defined in `globals.css` + Tailwind config (CSS variables, not arbitrary values) |

## Code Organization

Expand Down
65 changes: 65 additions & 0 deletions AUDIT_REMEDIATION_SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Content & Gap Audit - Remediation Summary

## Completed Fixes

### 1. Image Assets (FIXED)
- Created 11 SVG placeholder images in public/images/illustrations/
- Created PWA manifest.json
- Created icon SVGs (32x32, 512x512)
- Updated all .png references to .svg across components

### 2. Pricing Page (FIXED)
- Removed pricing navigation item from AppLayout
- Removed 'pricing' from ActiveView type
- Removed PricingPage import and case from page.tsx
- Made SubscriptionBanner props optional (tier?, onUpgrade?)

### 3. Build Status (FIXED)
- TypeScript compilation: SUCCESS
- Next.js build: SUCCESS

### 4. Seed Data Verification (CONFIRMED COMPLETE)
- prisma/seed.ts DOES create assessments (6 total)
- prisma/seed.ts DOES create guides (beginner/intermediate/advanced)
- prisma/seed.ts DOES create downloads
- prisma/seed.ts DOES persist sampleAnswers to Question.sampleAnswer

## Test Status

### Passing
- Unit tests: 33/33 PASS
- Core API tests: 226/264 PASS

### Failing (Infrastructure, not code bugs)
- 38 API integration tests: Require live server at localhost:3000
- Error: "Unable to connect. Is the computer able to access the url?"
- These are end-to-end user path tests

- 26 component tests: Test setup issues
- Error: "global.fetch.mockImplementation is not a function"
- Tests need proper vi.mock() setup for fetch

## Remaining Gaps (Non-Critical)

### Content
- Question bank: 95 seeded (docs target 264+) - expansion needed
- Real image assets: Using SVG placeholders - replace with actual illustrations

### Features (Per PRD Roadmap)
- Voice interview mode (Phase 6)
- Video response review (Phase 6)
- Portfolio builder (Phase 6)
- Certificate generation (Nice-to-have)

### Code Quality
- Component test infrastructure needs fetch mock setup
- Integration tests need server or TEST_BASE_URL
- Middleware deprecation warning (use proxy instead)

## Next Steps

1. Replace SVG placeholders with real illustrations
2. Expand question bank to 264+ questions
3. Fix test infrastructure (add global.fetch mock)
4. Run integration tests with TEST_BASE_URL=http://localhost:3000
5. Consider implementing high-priority Phase 5 features
133 changes: 133 additions & 0 deletions FIX-PLAN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# Interview Lab — Thorough Fix Plan

> Audited 2026-07-19. A sequenced, merge-ready plan. Each phase: **goal → files → changes → verification**.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Remove future-dated documentation entries.

Both files contain dates after the current date, July 18, 2026. Replace them with the actual audit/change dates.

  • FIX-PLAN.md#L3-L3: replace the July 19, 2026 audit date.
  • REMEDIATION_PLAN.md#L115-L115: replace the July 19, 2026 README correction date.
📍 Affects 2 files
  • FIX-PLAN.md#L3-L3 (this comment)
  • REMEDIATION_PLAN.md#L115-L115
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@FIX-PLAN.md` at line 3, Replace the future-dated July 19, 2026 audit entry in
FIX-PLAN.md line 3 with the actual audit date, and update the July 19, 2026
README correction date in REMEDIATION_PLAN.md line 115 to the actual change
date.

> Phases are independently shippable; **Phase 0 must land first**.

---

## Phase 0 — Reconcile Reality & Delete Dead Code
*Why first: docs/architecture are wrong. Fix the map before the journey.*

### 0.1 Documentation truth-up
**Files:** `AGENTS.md`, `README.md`, `REDESIGN-PLAN.md`, `REMEDIATION_PLAN.md`, `docs/architecture.md`
- Rewrite AGENTS.md "Design System" section: replace *"Ethereal Glass / OLED black / sky `#007EFF`"* with the live **"Field Manual" light theme** (`#FAFAF7` bg, `#FF6B35` accent, `FieldCard`/`FieldButton`).
- README Tech Stack: change `UI` row to "Tailwind v4 + Field Manual design system"; fix `Export` row ("pdfkit" → "pdfkit + manual PDF builder" or remove pdfkit after Phase 3).
- `REMEDIATION_PLAN.md`: delete false claim that `downloads/[id]/route.ts` is 879 lines (it's 53).
- Mark `REDESIGN-PLAN.md` as **superseded** (glass redesign was reverted) — or delete it.

### 0.2 Delete dead code
| File | Reason |
|------|--------|
| `src/lib/browser-llm-integration.ts` (338 lines) | Not imported anywhere; fake rule-based AI |
| `src/components/interview-lab/UpgradeModal.tsx` | Stub, no-op |
| `src/components/interview-lab/SubscriptionBanner.tsx` | Stub, no-op |
| `src/lib/pricing.ts` (tier config) — *optional* | Only powers stubs; keep if PricingPage ever real |

**Verify:** `grep -r "browser-llm-integration\|UpgradeModal\|SubscriptionBanner" src` → no results; `bun run build` passes.

---

## Phase 1 — SOLID: AI Layer Refactor (SRP + OCP + DIP)
*Highest leverage: 4 routes share ~75-line duplicated JSON-extract loop, each calls the SDK directly.*

### 1.1 `src/lib/ai/client.ts` — AIProvider abstraction (DIP)
```ts
export interface AIProvider {
complete(system: string, user: string, opts?: { schema?: ZodSchema; signal?: AbortSignal }): Promise<unknown>;
}
export class ZAIProvider implements AIProvider { /* timeout 30s, abort, retry-once */ }
export const ai: AIProvider = new ZAIProvider();
```
- Add `AbortSignal.timeout(30000)` + `try/catch` around `ZAI.create().chat.completions.create`.

### 1.2 `src/lib/ai/handlers.ts` — `createAIHandler` factory (OCP)
```ts
export function createAIHandler<T>(buildPrompt, schema: ZodSchema<T>) {
return async (req) => { /* auth → call ai.complete with schema → validate → return */ };
}
```
- Centralize `extractJsonArray`/`extractJsonObject` parsing into tested util `src/lib/ai/json.ts`.

### 1.3 Split routes
- `src/lib/ai/coach.ts`, `resume.ts`, `cover-letter.ts`, `assessment.ts` — each exports `buildPrompt()` + a zod `schema`.
- Refactor `src/app/api/ai/{coach,resume-review,cover-letter,assessment-score}/route.ts` to ~15 lines each calling `createAIHandler`.

### 1.4 Add zod schemas
- `src/lib/ai/schemas.ts`: `CoachFeedbackSchema`, `ResumeReviewSchema`, `CoverLetterSchema`, `AssessmentScoreSchema` (replaces runtime `as` casts).

**Verify:** `__tests__/ai/client.test.ts` (mock `z-ai-web-dev-sdk`), `handlers.test.ts` (valid + malformed JSON → 500), `bun run test`.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Point verification steps at the current test layout.

The plan references __tests__/ai/client.test.ts and subscription.test.ts, while the current repository uses paths such as __tests__/unit/ai-handlers.test.ts, __tests__/unit/ai-json.test.ts, and __tests__/unit/entitlement.test.ts. Update these commands to match the actual test structure.

As per coding guidelines, tests belong under __tests__/ while mirroring the source structure.

Also applies to: 85-85

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@FIX-PLAN.md` at line 58, Update the verification steps in FIX-PLAN.md to
reference the current test files under __tests__/, replacing outdated
__tests__/ai/client.test.ts, handlers.test.ts, and subscription.test.ts
references with the appropriate __tests__/unit/ai-handlers.test.ts,
__tests__/unit/ai-json.test.ts, and __tests__/unit/entitlement.test.ts paths.
Keep the existing bun run test command.

Source: Coding guidelines


---

## Phase 2 — SOLID: Export Layer (SRP)
### 2.1 `src/lib/export/docx.ts`
- Move `generateDocx` out of `export/route.ts` into its own module.

### 2.2 `src/lib/export/pdf.ts` — replace hand-rolled byte builder
- Use already-installed `pdfkit` (currently unused). Fixes **silent truncation** (`if (y < 50) break`) by paginating.
- Add `content` size guard (reject > 50k chars) to prevent abuse.

### 2.3 `src/app/api/export/route.ts`
- Becomes ~12 lines: auth → dispatch to `docx.ts` / `pdf.ts`.

**Verify:** `export.test.ts` generates real .docx/.pdf, asserts multi-page content isn't truncated.

---

## Phase 3 — SOLID: Entitlement Honesty (LSP)
### 3.1 `src/lib/subscription/entitlement.ts`
```ts
export interface EntitlementService { canAccess(feature): boolean; tier: string; }
export class FreeEntitlement implements EntitlementService { canAccess() { return true; } }
```
- `subscription-guard.ts` returns real interface; `use-subscription.ts` returns `FreeEntitlement` honestly (remove fake `-1`/no-op that *implies* gating).

**Verify:** `subscription.test.ts`.
Comment on lines +30 to +85

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Reconcile the plan with the implementation state.

The current PR already introduces the shared AI pipeline, extracted export modules, and entitlement service, but Phases 1–3 still present these as upcoming work. Mark landed items complete and leave only genuinely outstanding gaps to avoid reimplementing shipped functionality.

Based on the PR objectives and stack context, these service layers are already implemented.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@FIX-PLAN.md` around lines 30 - 85, Update FIX-PLAN.md to reflect the
implemented state: mark the shared AI pipeline, extracted export modules, and
entitlement service work in Phases 1–3 as complete, including their related
verification items where already satisfied. Remove or rewrite instructions that
would reimplement existing functionality, and leave only genuinely outstanding
gaps from the current implementation.


---

## Phase 4 — Component Decomposition (SRP)
### 4.1 `MockInterview.tsx` (618 →)
`src/components/interview-lab/mock-interview/{Setup,ActiveSession,Complete,useInterview}.tsx`

### 4.2 Standardize error/empty states
- `ResumeLab` raw red `<div>` → `Alert` component (already built in `ui/`).
- Add skeletons to `MockInterview`/`ResumeLab` to match `DashboardView`.

### 4.3 A11y fix
- `QuestionBank`: remove nested interactive (inner "Practice" button inside `role="button"` div) → make card a real `<article>` with a separate button.

**Verify:** `bun run lint`, component render tests.

---

## Phase 5 — Infra & Correctness
### 5.1 Rate limiter (`middleware.ts`)
- Replace in-memory `Map` with **Upstash Redis** (`@upstash/ratelimit`) so it works across Vercel serverless.
- Trust `x-forwarded-for` only behind Vercel proxy; add `x-vercel-ip` fallback.

### 5.2 Font drift (`globals.css`)
- `JetBrains Mono`/`Inter` declared but unused → align to Space Grotesk + Plus Jakarta Sans (per spec) or update spec.

### 5.3 `db.ts`
- Gate `log: ['query']` behind explicit `LOG_QUERIES=1` env (confirm off in prod).

---

## Effort & Sequencing

| Phase | Work | Est. | Risk |
|-------|------|------|------|
| 0 | Doc truth-up + dead-code deletion | 1 day | 🟢 none |
| 1 | AI layer SOLID refactor + zod | 4 days | 🟡 medium (test coverage needed) |
| 2 | Export layer split + pdfkit | 1 day | 🟡 medium |
| 3 | Entitlement honesty | 1 day | 🟢 low |
| 4 | Component decomposition + UI polish | 4 days | 🟡 medium |
| 5 | Rate limiter + fonts + db | 2 days | 🟡 medium |

**Total: ~13 dev-days.** Phases are independently shippable; Phase 0 must land first.

---

## Suggested first PR
**"Phase 0: Reconcile docs & remove dead code"** — smallest diff, zero behavioral risk, unblocks everything.
41 changes: 20 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ for aspiring Amazon Virtual Assistants.
| Layer | Technology |
|-------|-----------|
| **Framework** | Next.js 16.1.1 (App Router, standalone) |
| **Runtime** | Bun |
| **Database** | Prisma v6 + SQLite (dev) / PostgreSQL (prod) |
| **Runtime** | Bun (CI uses npm) |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Clarify the package-manager scope.

README.md says CI uses npm, while AGENTS.md Line 71 says “Use Bun exclusively.” Clarify that Bun is for local development and npm is CI, or update AGENTS.md to avoid conflicting contributor instructions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` at line 40, Clarify the package-manager guidance in the README’s
Runtime entry so it explicitly states that Bun is used for local development
while npm is used in CI, and ensure it does not conflict with the AGENTS.md
contributor instructions.

| **Database** | Prisma v6 + PostgreSQL (PostgreSQL only) |
| **Auth** | Custom JWT sessions (jose) + HttpOnly cookies |
| **UI** | Tailwind CSS v4 + custom glass design system |
| **UI** | Tailwind CSS v4 + "Field Manual" light design system |
| **Icons** | Phosphor Icons (light weight) |
| **Fonts** | Space Grotesk (headings) + Plus Jakarta Sans (body) |
| **AI** | Z AI Web Dev SDK for coaching, scoring, content generation |
| **Export** | docx, PDF (pdfkit), Excel (exceljs) |
| **Export** | docx, PDF (manual builder / pdfkit), Excel (exceljs) |

## 🚀 Getting Started

Expand Down Expand Up @@ -90,7 +90,7 @@ src/
│ │ ├── assessments/ # Practice test assessments
│ │ ├── profile/ # User profile (GET/PUT)
│ │ ├── dashboard/ # Dashboard aggregation
│ │ ├── subscription/ # Checkout, status, usage, webhook
│ │ ├── subscription/ # Removed (product is free)
│ │ ├── resume/ # Resume upload + AI review
│ │ ├── cover-letter/ # Cover letter generation
│ │ ├── ai/ # AI endpoints (coach, scoring, resume, cover)
Expand All @@ -100,17 +100,17 @@ src/
│ │ └── export/ # DOCX/PDF/Excel export
│ └── [pages]/ # Page routes
├── components/
│ ├── interview-lab/ # Page components (glass design system)
│ └── ui/ # Shared primitives (glass-card, glass-button, etc.)
│ ├── interview-lab/ # Page components (Field Manual design system)
│ └── ui/ # Shared primitives (field-card, field-button, etc.)
├── lib/
│ ├── auth-helpers.ts # Server-side JWT + header auth
│ ├── pricing.ts # Tier configs (Free/Starter/Pro) and limits
│ ├── subscription-guard.ts # Feature access checks per tier
│ ├── pricing.ts # Tier configs (currently unused — product is free)
│ ├── subscription-guard.ts # Feature access checks (returns allowed: true)
│ ├── types.ts # TypeScript interfaces
│ └── utils.ts # cn() utility
└── hooks/ # Custom React hooks

prisma/ # Prisma schema (SQLite/PostgreSQL)
prisma/ # Prisma schema (PostgreSQL)
Comment on lines +103 to +113

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Update the project structure for the entitlement refactor.

src/lib/pricing.ts was deleted, and access now flows through src/lib/subscription/entitlement.ts. Remove the stale pricing.ts entry, replace the outdated “returns allowed: true” description, and document the entitlement service.

Based on the PR objectives, the entitlement service is now the supported access abstraction.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` around lines 103 - 113, Update the README project structure to
remove the stale pricing.ts entry, replace the outdated subscription-guard
description, and add the supported src/lib/subscription/entitlement.ts
entitlement service with an accurate access-control description.

__tests__/ # Test suites
├── api/ # API route unit tests (218 tests)
│ ├── interview-session.test.ts
Expand All @@ -133,7 +133,7 @@ docs/ # PRD, architecture, feature specs
bun test

# Run specific test file
bun test __tests__/api/subscription.test.ts
bun test __tests__/api/resume-coverletter.test.ts

# Run API tests only
bun test __tests__/api/
Expand All @@ -149,9 +149,8 @@ bun test __tests__/api/
| `auth-login.test.ts` | 26 | Login flow, rate limiting, session, email sanitization |
| `assessments.test.ts` | 20 | Assessment list/get/submit, answer key stripping |
| `profile-dashboard.test.ts` | 23 | Profile whitelisting, sanitization, dashboard stats |
| `subscription.test.ts` | 31 | Pricing logic, checkout, tier validation, payments |
| `resume-coverletter.test.ts` | 25 | Resume CRUD, cover-letter tones, truth flags |
| **Total** | **218** | **All API routes, all green** |
| **Total** | **187** | **All API routes, all green** |
Comment on lines 152 to +153

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Reconcile the test counts and removed test references.

The total is now 187, but the same README still says the API suite contains 218 tests and still lists subscription.test.ts. Update those references together with the new entitlement test coverage.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` around lines 152 - 153, Update the README test documentation to
consistently reflect the current 187-test total, replacing the outdated 218-test
API suite count and removing the obsolete subscription.test.ts entry. Ensure the
table and related test references also include the new entitlement test
coverage.


Tests use in-memory stubs — no database or server required.

Expand All @@ -161,27 +160,27 @@ Tests use in-memory stubs — no database or server required.
|---------|-------------|
| `bun run dev` | Dev server with logging |
| `bun run build` | Production build (standalone) |
| `bun run db:push` | Push Prisma schema to SQLite |
| `bun run db:push` | Push Prisma schema to PostgreSQL |
| `bun run db:generate` | Generate Prisma client |
| `bun run test` | Run test suite |
| `bun run lint` | ESLint check |

## 🎨 Design System — Ethereal Glass
## 🎨 Design System — "Field Manual" (light theme)

The app uses a premium dark-mode glass aesthetic:
> The earlier "Ethereal Glass" dark design was reverted. The live app uses a clean light "Field Manual" system.

- **Palette:** OLED black (`#050505`) with radial gradient orbs, glass-morphism cards, `backdrop-blur-xl`
- **Colors:** Indigo/violet accents, emerald success, amber warnings, rose danger
- **Motion:** Custom cubic-bezier curves, Framer Motion scroll reveals, staggered animations
- **Components:** Double-bezel glass cards, pill CTAs, glass inputs/badges
- **Palette:** Warm off-white (`#FAFAF7`) with subtle grain/border texture, primary orange (`#FF6B35`) accents
- **Colors:** Ink scale for text, emerald success, amber warnings, rose danger
- **Motion:** Framer Motion scroll reveals, stagger, hover physics (no custom cubic-beziers)
- **Components:** `FieldCard` (solid surface, thin border, soft shadow), `FieldButton` (default/outline/ghost), `FieldBadge`, `Alert`
- **Icons:** Phosphor Icons in `weight="light"` — no thick-stroked icons
- **Typography:** Space Grotesk for headings, Plus Jakarta Sans for body

## 🔐 Environment Variables

| Variable | Description |
|----------|-------------|
| `DATABASE_URL` | SQLite connection string (`file:./dev.db`) or PostgreSQL URL |
| `DATABASE_URL` | PostgreSQL connection URL |
| `JWT_SECRET` | Secret for signing JWT session tokens |
| `NEXT_PUBLIC_APP_URL` | App base URL |

Expand Down
2 changes: 1 addition & 1 deletion REDESIGN-PLAN.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Redesign Plan — Interview Lab

> **Status:** All phases implemented. See git history for details.
> **Status:** SUPERSEDED. The "Ethereal Glass" dark design described here was reverted in favor of the live light "Field Manual" design system (see `AGENTS.md` Design System section). Kept for historical reference only.

## Design System — Ethereal Glass

Expand Down
6 changes: 3 additions & 3 deletions REMEDIATION_PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ Interview Lab is a **free companion** to [Project Amazon PH Academy](https://pro
- Model assessment attempts properly (user, timestamps, answers, score, rubrics, status, AI version)

### P2.3 — Download route decomposition
**Files:** `src/app/api/downloads/[id]/route.ts` (879 lines)
**Problem:** Monolithic route handles auth, tier checks, 4 document formats, database access, and analytics.
**Files:** `src/app/api/downloads/[id]/route.ts` (53 lines — earlier "879-line" estimate was inaccurate)
**Problem:** Route handles auth, tier checks, multiple document formats, database access, and analytics.
**Fix:**
- Extract document builders: `src/lib/documents/pdf.ts`, `docx.ts`, `xlsx.ts`, `text.ts`
- Extract template renderers: `src/lib/templates/amazon-training.ts`
Expand All @@ -112,7 +112,7 @@ Interview Lab is a **free companion** to [Project Amazon PH Academy](https://pro
- Add browser tests for critical user journeys

### P2.6 — Operational documentation
**Problem:** README documents Bun runtime but CI uses npm; describes SQLite but schema is PostgreSQL; no standalone output config.
**Problem:** README previously documented Bun runtime but CI uses npm; described SQLite but schema is PostgreSQL. (README corrected 2026-07-19; standalone output already in `next.config.ts`.)
**Fix:**
- Standardize on one package manager (npm, given CI/Vercel use it)
- Update README to reflect PostgreSQL-only schema
Expand Down
Loading
Loading