Roadmap · Reflection · Phase 1 PR Plan

Lenci — Phased Roadmap

From V0.2.4 public beta to V1.0 — stabilization, surface parity, scale.

Owner Kareem · Siyada Tech Branch V0.2.4 → V0.3.0 Date 2026-04-27 Codebase ~/siyaida/dev-lenci

Reflection on the project

What Lenci is

A six-studio AI content platform (Apparel, Product, Video, Models, Brand, Location) that replaces traditional photoshoots — built Saudi-first with full Arabic/RTL support, modest-fashion native, and PDPL-compliant infrastructure. Public beta is live and producing revenue.

The honest state

The product is shipping faster than the engineering can keep up with it. Three signals tell the same story:

  • Surface inconsistency. Three of the six studios (Models, Brand, Location) were added later, but the surrounding surfaces — dashboard, landing page, usage analytics, credit breakdown — still show the original three. Users discover features by accident.
  • Trust-critical bugs in the most-used flow. Apparel Studio (the headline studio) ships two critical defects: face/body preservation is too weak (the output looks like a different person) and uploaded images persist across sessions (users perceive their photos are stored without consent). Either one is enough to lose a user on day one.
  • Engineering debt is compounding. server.ts grew from 8,876 lines (March plan) to 9,468 lines (April) — modularization hasn't started while feature work continues. TypeScript baseline is dirty (~169 errors). 93 tests fail. Five exploitable security holes are live in production, including an endpoint that grants 1000 free credits to any signed-in user.

What this implies

The next two months should be stabilization, not features. The roadmap below front-loads security, trust, and structure before resuming the published forward roadmap (mobile Q2, social Q3, API/enterprise Q4). Skipping this is cheaper today and very expensive later — the modularization-coverage-gates loop is the prerequisite for safely shipping a mobile app, an API, or enterprise contracts.

The defensible wedge

External research confirms there is no Saudi-native, Arabic-first, modest-fashion-native AI content platform. Generic competitors (Claid, Photoroom, Flair, Pebblely, Dreamshot, SellerPic) compete on tooling features. Lenci's moat is regional, cultural, and bundled (six studios + brand identity + Arabic + KSA data residency). Protect that wedge — don't dilute it chasing feature parity with general-purpose tools.

Roadmap — eight phases

Phases 1–5 are stabilization (the V0.3.0 release). Phases 6–8 are the post-V0.3 forward roadmap from the pitch deck. Sequencing is strict: each phase removes a blocker for the next.

Phase 1 · stabilize
Stop the bleeding — security & trust
~2 weeks · 7 PRs

Close exploitable security holes, fix the two critical Apparel bugs, and delete dead Next.js code. Nothing in this phase is a feature — it's all triage.

Scope

  • Phase 0 of V0.3 plan (5 security items)
  • Apparel Issue #5 — face/body preservation crit
  • Apparel Issue #9 — stale upload state crit
  • V0.3 Phase 1 — delete dead Next.js code

Exit criteria

  • 0 unauthenticated AI endpoints
  • 0 secrets in logs
  • Apparel signin → empty state, every time
  • Face identity preserved on user-uploaded models
  • TS errors drop ≥ 70
Phase 2 · type-safe
Compile clean, test green
~2–3 weeks

Drive TypeScript and tests to a green baseline so subsequent refactoring is safe.

Scope

  • V0.3 Phase 2 — fix all 169 active TS errors (ProductControlPanel 33, ErrorBoundary 25, geminiService 31, PerformanceDashboard 15, sharedStore 8, promptService 8)
  • V0.3 Phase 3 — fix 93 failing tests (security, watermarking, webhook, money, sanitization, costs, plans, subscriptionService, usageService)

Exit criteria

  • tsc --noEmit exits 0
  • vitest run 100% pass
  • vite build succeeds
  • Test scripts in package.json reflect categories
Phase 3 · modularize
Break up server.ts & cover the money paths
~3–4 weeks

Extract the 9,468-line monolith into ~12 testable route modules; write tests for every financial and security-critical path.

Scope

  • V0.3 Phase 4 — extract routes/{auth,billing,credits,subscriptions,generation,video,admin,webhooks,support,website,studios,health}.ts
  • V0.3 Phase 5 — Tier 1 tests: credits, Stripe webhooks, auth middleware, validation, rate limiting

Exit criteria

  • server.ts < 1,000 lines
  • No file in src/server/ > 1,000 lines
  • Coverage ≥ 30% overall
  • Every route module has auth + happy-path tests
Phase 4 · polish & surface parity
Production polish + show all six studios everywhere
~2–3 weeks

Close the surface gaps that hide Models/Brand/Location from users, restore theme parity, and ship the production-polish items.

Scope

  • V0.3 Phase 6 — structured logger, CSP without unsafe-eval, env-only creds, bundle code-splitting (target < 1.5 MB main chunk), remove 600+ console.log
  • Issue #3 — dashboard cards for all 6 studios high
  • Issue #6 — landing page sections for Models, Brand, Location
  • Issue #7 — usage dashboard by studio name (not internal events)
  • Issue #8 — credit breakdown lists all 6 studios individually
  • Issue #1 — restore light theme & toggle
  • Issue #2 — dark email templates
  • Issue #4 — improve Video Studio AI concept uniqueness high

Exit criteria

  • 0 console.log in production build
  • Main bundle < 1,500 KB
  • All 6 studios visible on dashboard, landing, usage, billing
  • Theme toggle works (EN+AR, light+dark)
  • Email rendering verified in light + dark clients
Phase 5 · gates · ship V0.3.0
Quality gates & release
~1–2 weeks

Make bad code hard to merge, then cut V0.3.0.

Scope

  • V0.3 Phase 7 — Husky pre-commit (tsc --noEmit, unit tests, eslint)
  • GitHub Actions CI on every push/PR
  • Documented QA checklist + manual smoke per release
  • Test quality standards documented
  • Cut V0.3.0 tag

Exit criteria

  • Pre-commit hooks installed
  • CI pipeline green on main
  • QA checklist signed off
  • V0.3.0 deployed to production
Phase 6 · mobile
Native apps (iOS & Android)
Q2 2026

Expo / React Native shell over the existing API. Reuses Phase 3's modular route boundaries.

Scope

  • Auth, dashboard, all 6 studios feature parity
  • Camera/photo-library upload flows
  • Push notifications for generation completion
  • App Store + Google Play submissions

Prerequisites

  • Phases 1–5 complete (modular API + green tests)
  • API stability — no breaking changes during mobile dev
Phase 7 · social
Autoposting & AI copywriting
Q3 2026

Generated content reaches social channels without leaving Lenci. Closes the last gap between "I made a photo" and "I posted it."

Scope

  • Instagram, TikTok, Pinterest, Snapchat OAuth
  • Scheduling & campaign calendar
  • AI caption + hashtag generation (Arabic + English)
  • Per-platform format presets (already exist as Product Studio packages)

Open questions

  • API access cost on each platform
  • Approval/review flow before auto-post
  • Analytics ingestion (engagement loop back into Lenci)
Phase 8 · API & enterprise
Public API + enterprise tier + marketplaces
Q4 2026

Open the platform to third-party integrators (Noon, Salla, Zid) and large-brand contracts.

Scope

  • Public REST API with API-key auth + per-key rate limits
  • Marketplace integrations: Noon, Amazon KSA, Salla, Zid
  • Enterprise tier: dedicated support, custom models, SLA
  • Custom-model fine-tuning service (brand-specific models)

Prerequisites

  • Modular routes (Phase 3) — required for clean API surface
  • 30%+ test coverage — required for SLA-backed contracts
  • Structured logging (Phase 4) — required for audit/debug at enterprise scale

Phase 1 — PR sequence with QA gates

Seven PRs, sequenced. Each PR has a single owner, single concern, and a dedicated QA gate before the next PR is opened. PRs 1–5 are independent and can ship in parallel; PRs 6–7 depend on cleaner state and ship sequentially after the security batch.

#PR titleSeverityDepends on~LOC
PR-1Remove /api/test/grant-creditscrit−30
PR-2Authenticate 4 public AI endpointscrit~+40
PR-3Remove credential / token logginghigh−20
PR-4Remove cursor agent debug fs.appendFileSyncmed−40
PR-5Delete dead Next.js code (src/app/api/, middleware.ts, ProtectedRoute.tsx)med−2,000
PR-6Apparel Studio: clear stale state on session boundary (Issue #9)critPR-1..5 merged~+80
PR-7Apparel Studio: harden face/body preservation (Issue #5)critPR-6~+150
PR-1Remove the test grant-credits endpointcrit
Why

Any signed-in user can POST /api/test/grant-credits and receive 1000 free credits. Direct revenue loss vector.

Change
  • Delete the route handler in src/server/http/server.ts (was line 836–862; re-grep — file has grown)
  • Search for any client-side caller and remove if found
QA gate
  • curl -X POST .../api/test/grant-credits with valid auth returns 404
  • vitest run baseline still passes (no test depended on this endpoint)
  • Manual: existing user balances unchanged after deploy
PR-2Authenticate four public AI endpointscrit
Why

Anonymous traffic can call expensive AI endpoints today: /api/studios/video/analyze (OpenAI Vision), /api/support/chat + /api/support/chat/stream (AI chat), /api/website-scrape (Puppeteer). Cost-of-abuse + denial-of-wallet risk.

Change
  • Add const user = await getSessionUser(req, res); if (!user) return; at the top of each handler (4 sites)
  • Add an integration test per endpoint: unauth → 401
QA gate
  • 4× new tests assert 401 on unauth requests
  • Smoke: each endpoint still works for a logged-in user
  • Anonymous load test (curl burst) returns 401, not 200
PR-3Remove credential / token logginghigh
Why

API keys, auth tokens, and SMTP credentials are partially logged today. Even truncated values aid attackers.

Change
  • Delete log lines in src/services/geminiService.ts (lines 16–18, 31)
  • Delete log lines in src/server/auth.ts (lines 35–38)
  • Delete log line in src/server/config/smtpEmail.ts (line 15)
  • Note: line numbers from the V0.3 plan; re-grep — files have shifted.
QA gate
  • Grep production logs for first/last 10 chars of any active API key, token, or SMTP user — zero matches in last 24h post-deploy
  • vitest run baseline passes
PR-4Remove cursor-agent debug fs.appendFileSyncmed
Why

Synchronous file writes inside hot request paths block the event loop and inflate p99 latency.

Change
  • Delete the four #region agent log blocks in server.ts (search for the region marker — line numbers stale)
QA gate
  • p99 latency on top 5 routes ≤ pre-merge baseline
  • No new cursor-agent related entries in any log file
PR-5Delete dead Next.js codemed
Why

Lenci is a Vite/Express app, but a leftover Next.js skeleton (src/app/api/, src/middleware.ts, ProtectedRoute.tsx) is still in the tree, contributing ~70 of the 169 TypeScript errors.

Change
  • Audit src/app/ first — keep any pages actively imported by App.tsx
  • Delete only files that import from next/server, next/navigation, or react-router-dom
  • Rename or delete watch-before.jpg.jpg double-extension file
QA gate
  • tsc --noEmit error count drops by ≥ 70
  • App boots, all 6 studios load, no console errors on first paint
  • No remaining import of next/server, next/navigation, react-router-dom (grep)
PR-6Apparel Studio: clear stale state on session boundarycrit
Why

Issue #9 — privacy-critical. Users see previously uploaded model and apparel images on fresh sign-in. Perceived as Lenci storing personal photos without consent. Trust violation, retention risk.

Change
  • In the apparel Zustand store: add resetStudioState() action that clears uploads, previews, and any blob URLs
  • Wire to: logout, fresh sign-in, app launch (when no active session)
  • Audit localStorage + sessionStorage for persisted apparel keys; drop them
  • Verify object URLs created with URL.createObjectURL are revoked
QA gate
  • E2E: sign in, upload, sign out, sign in → Apparel inputs are empty
  • E2E: sign in, upload, close tab, reopen → Apparel inputs are empty
  • E2E: sign in as user A, upload, sign out, sign in as user B → user B sees nothing
  • DevTools: no blob: URLs leaked after logout (memory + Application tab)
  • New unit tests on the store covering reset actions
PR-7Apparel Studio: harden face / body preservationcrit
Why

Issue #5 — trust-critical. Users uploading their own model photos see outputs with altered facial identity, skin tone, and body proportions. Breaks the core promise of "see yourself wearing it."

Change
  • Prompt: add explicit identity-lock directives: "Preserve facial features, skin tone, and body proportions of the reference image exactly. The person in the output must be visually identical to the reference."
  • Reference quality enforcement: reject reference uploads < 1024×1024; warn if < 3 angles available; offer multi-angle upload (front + side) per current SOTA guidance
  • Pipeline: evaluate adding an IP-Adapter or ControlNet pass for face lock if Gemini 3 Pro alone can't hold identity; treat as a follow-up if scope creeps
  • Eval harness: a test set of 10 diverse reference images + the AdaFace identity score as the regression metric
QA gate
  • Identity score (AdaFace cosine similarity, ref vs output) ≥ 0.5 on the eval set median (define a baseline + improvement target)
  • Side-by-side review of 10 generations: 9/10 judged "same person" by 3 internal reviewers
  • No regression in non-Apparel studios (Models, Location can use the same code path)
  • Reference-quality rejection covered by component test

QA gate definitions (apply between every PR)

GateCommand / checkPass condition
Type checktsc --noEmitError count ≤ pre-PR baseline (PR may not introduce new TS errors; reductions encouraged)
Testsvitest runPass rate ≥ pre-PR baseline; new code paths covered
Buildvite buildSucceeds; main chunk size delta ≤ +50 KB without justification
Linteslint src/0 new warnings in changed files
SmokeLogin + dashboard + each studio happy path (EN + AR)No console errors, no broken layouts, RTL intact
i18nnpm run i18n:check0 missing translations
SecurityManual: grep for new secrets, hardcoded URLs, console.log with PII0 hits on changed files

Success metrics

MetricTodayEnd of Phase 1End of Phase 5 (V0.3.0)
TS errors (active)169≤ 990
Test pass rate90.5% (921/1017)≥ 90.5%100%
Coverage6%6%+≥ 30%
server.ts LOC9,468≤ 9,500< 1,000
Bundle (main)3,674 KB≤ 3,674 KB< 1,500 KB
Unauthenticated AI endpoints400
Free-credit exploit endpoints100
Apparel face identity scorebaseline TBD≥ +20% vs baseline≥ +30% vs baseline
Studios surfaced on dashboard3 of 63 of 66 of 6

Risks & mitigations

RiskLikelihoodImpactMitigation
Phase 1 PR-7 (face preservation) needs an IP-Adapter pipeline change, not just prompt tuning — scope explosionMediumHighTime-box the prompt-only attempt to 3 days; if metric target not met, ship the prompt change as PR-7a and create a follow-up PR-7b for pipeline work in Phase 3
Modularization (Phase 3) regresses an undocumented API contractMediumHighPhase 2 must finish first (green tests as safety net); modularize one route at a time, ship behind a feature flag if needed, smoke-test each merge
Feature requests during stabilization (Phases 1–5)HighMediumHard freeze on non-critical features for 8–10 weeks; only Phase-listed work merges. Roadmap doc shared with stakeholders.
Saudi market traction stalls during freezeLowMediumPhase 4 includes the user-visible wins (theme, surface parity, video uniqueness). Communicate the V0.3 release publicly as a quality push.
Live exploit of /api/test/grant-credits before PR-1 landsLow (obscurity), High (impact)CriticalPR-1 is day 1, hour 1. Until merged, monitor credit balance anomalies and pull the route at server startup if needed.
Gemini 3 Pro pricing changes mid-roadmapMediumMediumMargins are 85–135% — there's room. Keep pricing config behind a single source of truth so a re-price is a one-file change.