Skinova — System Architecture

YouCam API Skin AI & Apparel VTO Hackathon · Track 1 — Skin AI · Consumer skincare intelligence from selfie scan to routine, coach, and progress

Next.js 15 + React 19 Vercel Serverless Neon Postgres + pgvector YouCam Skin AI (5 APIs) Qwen Cloud DashScope skinova-ai.vercel.app Demo video ↗
Frontend (Browser) Backend (Next.js API) YouCam API Qwen Cloud Database

1 · Frontend — Next.js 15 + React 19 (Vercel CDN)

Public site

Landing at / with Live status (demo vs live scan) · Privacy /privacy · Terms /terms

Authentication

Sign up /signup · Log in /login · JWT session cookie (HTTP-only, 7-day TTL)

App shell (auth-gated)
  • Dashboard — metrics & navigation hub
  • Skin Scan — upload / samples + 6-step live stepper
  • Results · Routine · Progress
  • Skin Coach — grounded Q&A (Live AI / Guided)
  • Settings — clear scan & coach history
Client state

sessionStorage caches the latest scan for fast UI; Neon is the source of truth via GET /api/skinova/scans. Middleware blocks unauthenticated routes.

POST /api/auth/* POST /api/skinova/scan GET /api/skinova/scan-status/[id] POST /api/skinova/simulation GET /api/skinova/simulation-status/[id] POST /api/skinova/coach GET /api/skinova/health JSON ↑

2 · Backend — Next.js API Routes + Server Libraries (Vercel Functions)

Auth API

/api/auth/signup · login · logout · session — bcrypt passwords, JWT cookies via jose

Skin Scan pipeline

run-skin-scan.tsyoucam.ts · validate image · file metadata · presigned upload · task create · poll · normalize ui_scoreAnalysisResult

Skin Coach pipeline

coach-scope guard → rag.ts hybrid retrieval → coach-llm.ts Qwen call → coach-validator · conversation history from Neon

Personalization + simulation

run-personalization.ts (Fitzpatrick, skin tone, face analyzer) · run-skin-simulation.ts → poll · save to user_simulation_results

Product routes

/api/skinova/scan · scan-status · simulation · simulation-status · coach · routine · scans · health · reset

Knowledge ingest

scripts/ingest-knowledge.mjs embeds content/knowledge/skincare.json (38 chunks) into pgvector via DashScope text-embedding-v4

Security boundary

API_KEY, QWEN_API_KEY, DATABASE_URL server-only · never exposed to browser bundles · middleware.ts protects app routes

↓     ↓     ↓
Backend talks to YouCam, Qwen Cloud, and Neon in parallel

3 · YouCam API (Perfect Corp.) — 5 integrated

AI Skin Analysis

Primary scan flow — file metadata, presigned upload, task create, poll, ui_score normalization

Personalization APIs

Fitzpatrick Scale · Skin Tone · Face Analyzer — post-scan enrichment on Results

AI Skin Simulation

Progress page before/after preview — POST /api/skinova/simulation → poll → Neon user_simulation_results

Modes

Live when API_KEY set & SKINOVA_DEMO_MODE=false · Demo mock when credentials absent

4 · Qwen Cloud (DashScope)

qwen3-max

Skin Coach replies — grounded system prompt (skinova-coach-qwen-v2) · temperature 0.2 · scan + RAG context in prompt

text-embedding-v4

1536-dim embeddings for knowledge chunk retrieval and ingest (npm run knowledge:ingest)

Coach modes

Live AI when QWEN_API_KEY configured · Guided rule-based fallback if API unavailable

5 · Neon Postgres + pgvector

users

Account records — name, email, bcrypt password hash · created via signup

knowledge_chunks · coach_messages

Skinova curated skincare knowledge (38 chunks) · vector(1536) hybrid RAG · per-user coach thread history

user_scans · user_routine_plans

Scan history (preview_image_url, sample_id, analysis JSON) and AI/template routines — hydrated into session on return

user_simulation_results · scan_task_context

Simulation preview URLs per scan · in-flight YouCam file IDs for re-simulation

Live scan mode

Real YouCam tasks — file metadata, presigned upload, async poll, live ui_score normalization.

Demo scan mode

Representative mock analysis when SKINOVA_DEMO_MODE=true or no API_KEY — no units consumed.

Live Skin Coach

Scope guard → hybrid RAG (vector + topic boost) → Qwen → validator. Answers cite knowledge + scan context only.

Guided coach fallback

Deterministic education templates when Qwen is not configured or API errors occur.

Scan session (browser)

Latest analysis in sessionStorage — powers Results, Routine, Coach personalization, Progress trends.

Static assets

public/samples/ YouCam playground selfies · public/screenshots/ submission captures · brand assets.

Primary data flows

  1. Auth: Browser POST /api/auth/signup|login → Neon users → HTTP-only JWT session cookie → middleware allows /dashboard, /scan, etc.
  2. Skin scan (live): Browser uploads selfie → POST /api/skinova/scan → YouCam file API + presigned PUT + task create → client polls GET /api/skinova/scan-status/[taskId] → Fitzpatrick + skin tone + face analyzer enrichment → AnalysisResult saved to Neon user_scans (with preview_image_url / sample_id) + sessionStorage → Results / Routine / Coach / Progress.
  3. Skin Simulation: Progress page POST /api/skinova/simulation → YouCam simulation task → poll GET /api/skinova/simulation-status/[taskId] → before/after preview saved to user_simulation_results.
  4. Skin Coach (live): Browser POST /api/skinova/coach with message + scan context → scope guard → embed query (Qwen) → retrieve knowledge_chunks (pgvector + topic boost) → Qwen chat completion with grounded prompt → validate → store in coach_messages → JSON answer to UI.
  5. Health / status: Landing GET /api/skinova/health reports mode (live/demo), scanReady, and coachReady without exposing secrets.
  6. Knowledge maintenance: Edit content/knowledge/skincare.jsonnpm run knowledge:ingest -- --force → re-embed all chunks into Neon.
  7. Deploy: GitHub → Vercel build → serverless functions for all API routes · env vars for DATABASE_URL, AUTH_SECRET, API_KEY, QWEN_API_KEY.

Module map (repository)

  1. UI: app/components/*scan-experience, results-experience, progress-experience, skin-simulation-panel, coach-experience, landing-live-status, app-shell
  2. Scan core: app/lib/youcam.ts · run-skin-scan.ts · run-personalization.ts · scan-session.ts · scan-steps.ts
  3. Simulation: run-skin-simulation.ts · simulation-db.ts · use-skin-simulation.ts
  4. Coach core: coach-service.ts · coach-llm.ts · coach-contract.ts · coach-scope.ts · rag.ts · embeddings.ts
  5. Data: db.ts · auth.ts · scan-db.ts · simulation-db.ts · routine-db.ts · knowledge-db.ts
  6. Ops: scripts/setup-and-run.sh · youcam-smoke-test.mjs · coach-smoke-test.mjs · ingest-knowledge.mjs