Skip to content

Commit a1f9ad1

Browse files
phase1: server auth, ESLint cleanup, AI adapter, free-tier cleanup
P1.1 — Server AI adapter: - Replaced BrowserLLMIntegration in 3 AI routes (cover-letter, resume-review, assessment-score) with z-ai-web-dev-sdk - Removed fake fallback data that fabricated experience claims - Added input length limits and JSON schema validation P1.2 — Client auth from server session: - Added GET /api/auth/session endpoint (validates JWT cookie against DB) - AuthProvider now validates session via server on mount instead of trusting localStorage blindly - localStorage kept as write-through cache with server re-validation P1.3 — ESLint fixes & rule re-enablement: - Fixed 4 ESLint errors (impure render calls, unescaped entities) - Re-enabled no-unused-vars, prefer-const, no-debugger, no-empty, no-fallthrough, no-unreachable - Cleaned up unused imports in 5 modified files Free companion cleanup: - Subscription-guard returns allowed: true unconditionally - All subscription API endpoints removed - PricingPage, UpgradeModal, SubscriptionBanner stubbed as no-ops - README pricing table replaced with Free Companion notice
1 parent 20e4886 commit a1f9ad1

28 files changed

Lines changed: 396 additions & 2175 deletions

File tree

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: 39 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,34 @@
55

66
---
77

8-
## ✅ Completed in PR #4
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)
915

1016
| Finding | Fix |
1117
|---|---|
1218
| FieldButton missing `outline` variant | Added outline variant to `fieldButtonVariants` |
13-
| Subscription checkout bypass | Returns 503 "Paid plans not available" |
14-
| Subscription manage `change` action | Blocked for paid tier upgrades |
19+
| Subscription checkout bypass | Removed subscription API endpoints entirely |
20+
| Subscription manage `change` action | Removed subscription API endpoints entirely |
1521
| JWT fallback secret | Requires 32+ char `JWT_SECRET` at startup |
1622
| Questions API unauthenticated | Server-side auth + tier checks; strips premium fields for free tier |
1723
| Guides API unauthenticated | Server-side auth + tier checks; locks content behind entitlement |
1824
| Verification token logged | Removed `console.log`; async/await DB calls |
1925
| Rate limiter non-atomic | Wrapped in `db.$transaction`; fail-closed |
2026
| Fabricated aggregate rating | Removed from structured data |
2127
| 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 |
2232

2333
---
2434

25-
## 🔴 Phase 1 — Must fix before paid launch
35+
## 🔴 Phase 1 — Must fix before public launch
2636

2737
### P1.1 — Server AI adapter
2838
**Files:** `src/lib/browser-llm-integration.ts`, `src/app/api/ai/*/route.ts` (4 routes)
@@ -38,27 +48,16 @@
3848
- Replace all `BrowserLLMIntegration` imports in API routes
3949
- Add privacy/provider disclosure to UI
4050

41-
### P1.2 — Real payment integration
42-
**Files:** `src/app/api/subscription/webhook/route.ts`, `src/app/api/subscription/checkout/route.ts`
43-
**Problem:** Webhook is a placeholder (no signature verification, no subscription sync). Price IDs are empty strings.
44-
**Fix:**
45-
- Configure Stripe price IDs in environment
46-
- Implement signed webhook handler
47-
- Add `checkout.session.completed`, `customer.subscription.updated`, `customer.subscription.deleted` events
48-
- Use webhook as the sole subscription activation path
49-
- Add `idempotencyKey` to payment records
50-
- Wrap billing mutations in `db.$transaction`
51-
52-
### P1.3 — Subscription record consistency
53-
**Files:** `src/lib/pricing.ts`, `prisma/schema.prisma`
54-
**Problem:** `User.subscriptionTier` and `Subscription.tier` are dual sources of truth; mutations aren't transactional.
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.
5554
**Fix:**
56-
- Designate `Subscription.tier` as the single source of truth
57-
- Derive `User.subscriptionTier` via a view or computed field
58-
- Wrap all billing mutations in `db.$transaction`
59-
- Add Prisma enums for `tier`, `status`, `billingPeriod`
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
6059

61-
### P1.4 — ESLint fixes & re-enablement
60+
### P1.3 — ESLint fixes & re-enablement
6261
**Files:** `eslint.config.mjs`, `src/app/page.tsx`, `src/components/interview-lab/AdminPanel.tsx`, `PricingPage.tsx`, `QuestionBank.tsx`
6362
**Problem:** 35 rules disabled; 9 pre-existing ESLint errors block CI.
6463
**Fix:**
@@ -67,15 +66,6 @@
6766
- Remove blanket `off` overrides
6867
- Add `lint-staged` pre-commit hook
6968

70-
### P1.5 — Client auth from server session
71-
**Files:** `src/lib/auth-context.tsx`
72-
**Problem:** Auth state restored from `localStorage` (modifiable); no server validation on startup.
73-
**Fix:**
74-
- Add `GET /api/auth/session` endpoint returning authenticated user from cookie
75-
- On app mount, validate session via server endpoint instead of reading localStorage
76-
- Keep localStorage as a cache layer with server re-validation
77-
- Ensure logout clears both cookie and localStorage atomically
78-
7969
---
8070

8171
## 🟡 Phase 2 — Required within next development cycle
@@ -108,7 +98,7 @@
10898
**Files:** `src/app/api/export/route.ts`
10999
**Problem:** No input size validation; PDF silently truncates at page bottom.
110100
**Fix:**
111-
- Add content length limits matching subscription tier
101+
- Add content length limits
112102
- Replace handcrafted PDF with proper pagination (e.g., `pdf-lib` or `pdfkit` with page break support)
113103
- Add request body size validation middleware
114104

@@ -118,7 +108,7 @@
118108
**Fix:**
119109
- Set per-file coverage thresholds (e.g., 60% lines, 50% branches)
120110
- Remove blanket excludes for components
121-
- Add integration tests for auth flows, onboarding, interviews, resume gen, admin, and plan enforcement
111+
- Add integration tests for auth flows, onboarding, interviews, resume gen, admin
122112
- Add browser tests for critical user journeys
123113

124114
### P2.6 — Operational documentation
@@ -132,7 +122,7 @@
132122

133123
---
134124

135-
## ⚪ Phase 3 — Before paid launch gate
125+
## ⚪ Phase 3 — Before public launch gate
136126

137127
### P3.1 — Privacy & legal
138128
- Add privacy policy page with data retention and account deletion
@@ -141,9 +131,8 @@
141131
- Add cookie consent banner
142132
- Add terms of service page
143133

144-
### P3.2 — Honest metadata
145-
- Remove `offers.price: "0"` from structured data if paid tiers exist
146-
- Add proper pricing schema if billing is active
134+
### P3.2 — Honest structured data
135+
- Remove `offers.price: "0"` from structured data if product is truly free (or add proper "Free" offer)
147136
- Add real user review/rating system before claiming ratings
148137

149138
### P3.3 — Security hardening
@@ -167,7 +156,7 @@
167156

168157
| Phase | Items | Estimated effort |
169158
|---|---|---|
170-
| 🔴 Phase 1 (blockers) | 5 items | 3–4 sprints |
159+
| 🔴 Phase 1 (blockers) | 3 items | 2–3 sprints |
171160
| 🟡 Phase 2 (cycle) | 6 items | 4–6 sprints |
172161
| ⚪ Phase 3 (launch gate) | 4 items | 2–3 sprints |
173162

@@ -177,22 +166,24 @@
177166

178167
### Current branch state
179168
- `main` at commit `190b3be` with PR #4 merged
180-
- The PR branch `fix/critical-security-and-build-issues` can be deleted
181-
182-
### Known CI state
183-
- ESLint: 9 pre-existing errors (4 files untouched by PR #4)
184-
- Vercel: fails on pre-existing analytics route runtime error
185-
- Neither is a regression from PR #4
169+
- Subscription system stubbed (not removed) to keep imports compiling
170+
- 3 stub files created: `PricingPage.tsx`, `UpgradeModal.tsx`, `SubscriptionBanner.tsx`
186171

187172
### Key architecture decisions to carry forward
188173
1. **Auth:** JWT in HttpOnly cookies with DB re-verification on every request (keep this pattern)
189-
2. **Tier enforcement:** Server-side `subscription-guard.ts` helpers are the right pattern — extend them, don't duplicate
174+
2. **Tier enforcement:** All subscription guard functions return `allowed: true` — product is free
190175
3. **Rate limiting:** The `db.$transaction` pattern is correct for persistent storage; middleware needs Redis/Upstash for serverless
191176
4. **AI:** Build a proper server adapter rather than trying to fix the client-side `BrowserLLMIntegration`
192177

193178
### Files most likely to conflict with future work
194179
- `src/lib/browser-llm-integration.ts` — will be replaced entirely by P1.1
195180
- `src/app/api/downloads/[id]/route.ts` — needs full decomposition (P2.3)
196181
- `prisma/schema.prisma` — needs migration (P2.2)
197-
- `eslint.config.mjs` — needs rules re-enabled (P1.4)
198-
- `src/lib/auth-context.tsx` — needs session endpoint (P1.5)
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)