Skip to content

Commit e4a6078

Browse files
Phase 1: server auth, ESLint cleanup, AI adapter, free-tier cleanup
Merging Phase 1 — 3 blockers resolved: P1.1 — Server AI adapter: Replaced BrowserLLMIntegration with z-ai-web-dev-sdk in 3 routes. Removed fake fallback data. P1.2 — Client auth from server session: Added /api/auth/session endpoint. AuthProvider validates via server on mount. P1.3 — ESLint cleanup: 0 errors (was 9). Re-enabled 6 important rules. TypeScript: 0 errors. Tests: 251 passed, 0 failed.
2 parents 556f8ff + 8699ee8 commit e4a6078

32 files changed

Lines changed: 572 additions & 2138 deletions

File tree

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
--health-retries 5
2828
2929
env:
30-
JWT_SECRET: ci-only-do-not-use-in-prod
30+
JWT_SECRET: ci-only-do-not-use-in-prod-abcdef1234567890
3131
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/interviewlab_test
3232
# Auth/API rate limits are tuned tight for production; the live-server
3333
# integration suite below makes far more requests per minute than a

README.md

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,12 @@ for aspiring Amazon Virtual Assistants.
2525
| **Cover Letter Studio** | Generate role-targeted cover letters with multiple tones |
2626
| **Practice Tests** | Timed assessments with AI-scored results |
2727
| **Learning Paths** | Beginner → Intermediate → Advanced guides per role |
28-
| **Download Center** | Templates, checklists, worksheets (tier-gated) |
28+
| **Download Center** | Templates, checklists, worksheets |
2929
| **Admin Panel** | Analytics dashboard and question management |
3030

31-
## 💰 Pricing Tiers
31+
## 💰 Pricing
3232

33-
| Tier | Price | Interviews | Resumes | Cover Letters | Practice Tests |
34-
|------|-------|-----------|---------|--------------|----------------|
35-
| **Free** | ₱0 | 1/week | 1/month | 1/month | 2/month |
36-
| **Starter** | ₱499/mo | 5/week | Unlimited | Unlimited | 5/month |
37-
| **Pro** | ₱999/mo | Unlimited | Unlimited | Unlimited | Unlimited |
33+
**Free, always.** Interview Lab is a free companion to [Project Amazon PH Academy](https://projectamazon.ph). All features are available to all users — no paid tiers.
3834

3935
## 🛠 Tech Stack
4036

REMEDIATION_PLAN.md

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
# Interview Lab — Remediation Plan & Handoff
2+
3+
**Date:** 2026-07-17
4+
**PR #4 merged at:** 2026-07-17T05:33:17Z (commit `190b3be`)
5+
6+
---
7+
8+
## Product context
9+
10+
Interview Lab is a **free companion** to [Project Amazon PH Academy](https://projectamazon.ph). All features are available to all users — no paid tiers, no subscription gating.
11+
12+
---
13+
14+
## ✅ Completed (PR #4 + follow-up)
15+
16+
| Finding | Fix |
17+
|---|---|
18+
| FieldButton missing `outline` variant | Added outline variant to `fieldButtonVariants` |
19+
| Subscription checkout bypass | Removed subscription API endpoints entirely |
20+
| Subscription manage `change` action | Removed subscription API endpoints entirely |
21+
| JWT fallback secret | Requires 32+ char `JWT_SECRET` at startup |
22+
| Questions API unauthenticated | Server-side auth + tier checks; strips premium fields for free tier |
23+
| Guides API unauthenticated | Server-side auth + tier checks; locks content behind entitlement |
24+
| Verification token logged | Removed `console.log`; async/await DB calls |
25+
| Rate limiter non-atomic | Wrapped in `db.$transaction`; fail-closed |
26+
| Fabricated aggregate rating | Removed from structured data |
27+
| Pre-existing FieldBadge/Button type errors | Added missing variants |
28+
| Subscription tier gating | `subscription-guard.ts` always returns `allowed: true` |
29+
| Subscription endpoints | Removed `src/app/api/subscription/` entirely |
30+
| Pricing page / UpgradeModal / SubscriptionBanner | Stubbed to no-op (kept imports compiling) |
31+
| README pricing table | Replaced with "Free, always" notice |
32+
33+
---
34+
35+
## 🔴 Phase 1 — Must fix before public launch
36+
37+
### P1.1 — Server AI adapter
38+
**Files:** `src/lib/browser-llm-integration.ts`, `src/app/api/ai/*/route.ts` (4 routes)
39+
**Problem:** The `BrowserLLMIntegration` module is marked `"use client"` and depends on `window.ai`. Server routes import it and silently fall back to rule-based templates that fabricate experience claims.
40+
**Fix:**
41+
- Create `src/lib/server-ai.ts` with:
42+
- Schema-validated structured output (zod)
43+
- Explicit provider configuration (OpenAI/Anthropic)
44+
- Timeouts and abort handling
45+
- Input length limits
46+
- Per-user quota enforcement
47+
- Truthfulness checks
48+
- Replace all `BrowserLLMIntegration` imports in API routes
49+
- Add privacy/provider disclosure to UI
50+
51+
### P1.2 — Client auth from server session
52+
**Files:** `src/lib/auth-context.tsx`
53+
**Problem:** Auth state restored from `localStorage` (modifiable); no server validation on startup.
54+
**Fix:**
55+
- Add `GET /api/auth/session` endpoint returning authenticated user from cookie
56+
- On app mount, validate session via server endpoint instead of reading localStorage
57+
- Keep localStorage as a cache layer with server re-validation
58+
- Ensure logout clears both cookie and localStorage atomically
59+
60+
### P1.3 — ESLint fixes & re-enablement
61+
**Files:** `eslint.config.mjs`, `src/app/page.tsx`, `src/components/interview-lab/AdminPanel.tsx`, `PricingPage.tsx`, `QuestionBank.tsx`
62+
**Problem:** 35 rules disabled; 9 pre-existing ESLint errors block CI.
63+
**Fix:**
64+
- Fix the 9 ESLint errors across 4 files (setState in effects, hoisting, const reassignment)
65+
- Re-enable important rules incrementally: `no-unused-vars`, `no-console`, `react-hooks/exhaustive-deps`, `no-fallthrough`
66+
- Remove blanket `off` overrides
67+
- Add `lint-staged` pre-commit hook
68+
69+
---
70+
71+
## 🟡 Phase 2 — Required within next development cycle
72+
73+
### P2.1 — Rate limiter upgrade
74+
**Files:** `src/middleware.ts`, `src/lib/rate-limit.ts`
75+
**Problem:** In-memory `Map` in middleware doesn't persist across serverless instances; IP parsing trusts unvalidated `x-forwarded-for`.
76+
**Fix:**
77+
- Replace in-memory Map with Upstash/Redis for middleware rate limiting
78+
- Add trusted proxy chain configuration
79+
- Add `Retry-After` header with actual reset timestamp
80+
81+
### P2.2 — Prisma schema hardening
82+
**Files:** `prisma/schema.prisma`
83+
**Changes needed:**
84+
- Convert string fields to enums: `role`, `difficulty`, `status`, `tier`, `billingPeriod`, `currency`, `fileType`, `subscriptionStatus`, `paymentStatus`
85+
- Add Prisma `Json` fields for: `toolsKnown`, `weakAreas`, `transcript`, `rubricBreakdown`, `truthFlags`, `answerKey`, `metadata`
86+
- Add indexes on: `userId`, `sessionId`, `questionId`, `expiresAt`, `resetTime`, `createdAt`
87+
- Model assessment attempts properly (user, timestamps, answers, score, rubrics, status, AI version)
88+
89+
### P2.3 — Download route decomposition
90+
**Files:** `src/app/api/downloads/[id]/route.ts` (879 lines)
91+
**Problem:** Monolithic route handles auth, tier checks, 4 document formats, database access, and analytics.
92+
**Fix:**
93+
- Extract document builders: `src/lib/documents/pdf.ts`, `docx.ts`, `xlsx.ts`, `text.ts`
94+
- Extract template renderers: `src/lib/templates/amazon-training.ts`
95+
- Keep route focused on auth, routing, and response
96+
97+
### P2.4 — Export endpoint size limits
98+
**Files:** `src/app/api/export/route.ts`
99+
**Problem:** No input size validation; PDF silently truncates at page bottom.
100+
**Fix:**
101+
- Add content length limits
102+
- Replace handcrafted PDF with proper pagination (e.g., `pdf-lib` or `pdfkit` with page break support)
103+
- Add request body size validation middleware
104+
105+
### P2.5 — Add test coverage thresholds
106+
**Files:** `vitest.config.ts`, `__tests__/`
107+
**Problem:** Coverage configuration exists but has no minimum thresholds; excludes pages, layouts, and shared UI.
108+
**Fix:**
109+
- Set per-file coverage thresholds (e.g., 60% lines, 50% branches)
110+
- Remove blanket excludes for components
111+
- Add integration tests for auth flows, onboarding, interviews, resume gen, admin
112+
- Add browser tests for critical user journeys
113+
114+
### P2.6 — Operational documentation
115+
**Problem:** README documents Bun runtime but CI uses npm; describes SQLite but schema is PostgreSQL; no standalone output config.
116+
**Fix:**
117+
- Standardize on one package manager (npm, given CI/Vercel use it)
118+
- Update README to reflect PostgreSQL-only schema
119+
- Add `output: "standalone"` to `next.config.ts`
120+
- Document required env vars with descriptions
121+
- Add setup/teardown scripts for development
122+
123+
---
124+
125+
## ⚪ Phase 3 — Before public launch gate
126+
127+
### P3.1 — Privacy & legal
128+
- Add privacy policy page with data retention and account deletion
129+
- Add AI provider disclosure (what data is sent to third-party APIs)
130+
- Resolve license contradiction (GPL v3 vs "Private, all rights reserved")
131+
- Add cookie consent banner
132+
- Add terms of service page
133+
134+
### P3.2 — Honest structured data
135+
- Remove `offers.price: "0"` from structured data if product is truly free (or add proper "Free" offer)
136+
- Add real user review/rating system before claiming ratings
137+
138+
### P3.3 — Security hardening
139+
- Session penetration tests
140+
- Authorization penetration tests on all API routes
141+
- Add `helmet`-style security headers
142+
- Rate limit all API endpoints consistently
143+
- Add input validation middleware for all POST/PUT routes
144+
145+
### P3.4 — Operational readiness
146+
- Error monitoring (Sentry or similar)
147+
- Load tests on AI, export, and download endpoints
148+
- Accessibility audit (WCAG 2.1 AA)
149+
- Add health check endpoint (`GET /api/health`)
150+
- Add structured logging (not just `console.log`)
151+
- Database backup and restore procedure
152+
153+
---
154+
155+
## 📊 Summary of remaining work
156+
157+
| Phase | Items | Estimated effort |
158+
|---|---|---|
159+
| 🔴 Phase 1 (blockers) | 3 items | 2–3 sprints |
160+
| 🟡 Phase 2 (cycle) | 6 items | 4–6 sprints |
161+
| ⚪ Phase 3 (launch gate) | 4 items | 2–3 sprints |
162+
163+
---
164+
165+
## 📝 Handoff notes
166+
167+
### Current branch state
168+
- `main` at commit `190b3be` with PR #4 merged
169+
- Subscription system stubbed (not removed) to keep imports compiling
170+
- 3 stub files created: `PricingPage.tsx`, `UpgradeModal.tsx`, `SubscriptionBanner.tsx`
171+
172+
### Key architecture decisions to carry forward
173+
1. **Auth:** JWT in HttpOnly cookies with DB re-verification on every request (keep this pattern)
174+
2. **Tier enforcement:** All subscription guard functions return `allowed: true` — product is free
175+
3. **Rate limiting:** The `db.$transaction` pattern is correct for persistent storage; middleware needs Redis/Upstash for serverless
176+
4. **AI:** Build a proper server adapter rather than trying to fix the client-side `BrowserLLMIntegration`
177+
178+
### Files most likely to conflict with future work
179+
- `src/lib/browser-llm-integration.ts` — will be replaced entirely by P1.1
180+
- `src/app/api/downloads/[id]/route.ts` — needs full decomposition (P2.3)
181+
- `prisma/schema.prisma` — needs migration (P2.2)
182+
- `eslint.config.mjs` — needs rules re-enabled (P1.3)
183+
- `src/lib/auth-context.tsx` — needs session endpoint (P1.2)
184+
185+
### Stub files (to be removed when components are refactored)
186+
- `src/components/interview-lab/PricingPage.tsx`
187+
- `src/components/interview-lab/UpgradeModal.tsx`
188+
- `src/components/interview-lab/SubscriptionBanner.tsx`
189+
- `src/lib/use-subscription.ts`

0 commit comments

Comments
 (0)