Easy-to-manage touch screens
무료 오픈소스 터치스크린으로 USB 설정 가이드, 드래그‑드롭 편집기, 로컬 제어를 제공하며 Home Assistant용으로 제작되었습니다
피부에 관한 7가지 질문에 답하면 맞춤형 아침·저녁 스킨케어 루틴, 적합한 성분, 예산별 제품을 제안받음
Answer seven questions about your skin and get a personalised morning and evening skincare routine, the ingredients that suit you, and products at every budget.
라이프스타일TypeScript · HTMLGitHub @NadiaSakovich온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
Personalized skincare routine builder — staged quiz + AI (Gemini) routine engine. Next.js 16, React 19, Tailwind v4.
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
A web service that builds a personalized skincare routine. You take a staged quiz
(skin type → concerns → preferences), get a skin analysis, and receive an AM/PM
routine plus example product picks sourced from live web results.
Content is heuristic and for general guidance only — it is not medical advice, and
the product names shown are examples rather than endorsements.README 전문 보기 ↗A web service that builds a personalized skincare routine. You take a staged quiz (skin type → concerns → preferences), get a skin analysis, and receive an AM/PM routine plus example product picks sourced from live web results.
Live: https://sealedskin.vercel.app
Content is heuristic and for general guidance only — it is not medical advice, and the product names shown are examples rather than endorsements.
@theme block in src/app/globals.cssnpm install
cp .env.example .env.local # then fill in the values (see below)
npm run dev # http://localhost:3000
The app runs without any credentials — it just degrades. Without GEMINI_API_KEY
you always get the offline routine logic (labelled "Standard routine · AI
unavailable"), and without the Firebase keys sign-in and saved routines are
unavailable. Everything else works.
| Script | What it does |
|---|---|
npm run dev | Dev server on port 3000 |
npm run build | Production build |
npm start | Serve a production build |
npm run lint | ESLint |
npx tsc --noEmit | Typecheck (strict; unused locals fail the build) |
Copy .env.example → .env.local (git-ignored) and fill in:
| Variable | Required for | Where to get it |
|---|---|---|
AI_PROVIDER | AI routines | gemini (the only provider today) |
AI_MODEL | AI routines | Default model, e.g. gemini-3.5-flash-lite |
GEMINI_API_KEY | AI routines + grounding | https://aistudio.google.com/apikey |
NEXT_PUBLIC_FIREBASE_API_KEY | Sign-in | Firebase console → Project settings → Web app |
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN | Sign-in | ” |
NEXT_PUBLIC_FIREBASE_PROJECT_ID | Sign-in | ” |
NEXT_PUBLIC_FIREBASE_APP_ID | Sign-in | ” |
FIREBASE_PROJECT_ID | Saved routines | Project settings → Service accounts → generate key |
FIREBASE_CLIENT_EMAIL | Saved routines | ” |
FIREBASE_PRIVATE_KEY | Saved routines | ” — one line, in quotes, keeping the literal \n escapes |
The NEXT_PUBLIC_* values are browser-visible identifiers and safe to expose. The
FIREBASE_CLIENT_EMAIL / FIREBASE_PRIVATE_KEY pair is a service-account secret —
keep it out of the client and out of git.
The quiz (src/components/SkinQuiz.tsx) is a client-side step machine: skin type
(7 diagnostic questions) → concerns and priorities → preferences (commitment level,
region, pregnancy) → a review screen → results.
Skin-type analysis is local and deterministic (src/lib/analysis.ts) — it scores
answers rather than asking a model, since the result is shown mid-quiz.
The routine is built by an AI agent (src/lib/ai/agent.ts) in two steps, because
Gemini cannot reliably combine Google Search grounding with structured JSON output in a
single call — with search enabled the JSON comes back corrupted:
The AI is called first; the local engine is the fallback. On any failure — missing
key, network error, malformed response — the quiz silently falls back to the offline
logic in src/data/actives.ts, so a user is never stuck. Which path ran is tagged on
RoutineResult.source.
When a grounded answer is shown, the source links and the Google Search Suggestions chip are displayed. That is required by Google's grounding terms — don't remove them.
src/app/ routes: / (quiz), /about, /how-it-works, /profile, /api/*
src/components/ layout, quiz, results, profile, ui
src/data/ quiz content: questions, concerns, actives, products
src/lib/ai/ provider interface, Gemini provider, agent, result assembly
src/lib/firebase/ client sign-in + Admin SDK
Deployed on Vercel; pushes to main deploy to production and branches get preview
URLs, via the Vercel GitHub App. Set the same environment variables in the Vercel
project — note that NEXT_PUBLIC_* values are inlined at build time, so changing
one requires a redeploy, not just a restart.
Two things that are easy to miss:
/api/routine sets maxDuration = 60. The grounded pipeline takes 9–18s. If that
budget is lost the failure is silent — routines just quietly become offline ones.jose overridepackage.json pins jose to ^5.10.0 through overrides. firebase-admin depends on
jwks-rsa, which does a CommonJS require('jose'), but jose 6 is ESM-only; since
firebase-admin is in Next's default serverExternalPackages list it is loaded with
native require, which throws ERR_REQUIRE_ESM inside a serverless bundle and 500s
every /api/users request.
This is not reproducible locally — next dev and next build && next start both
serve the route correctly. Verify anything touching firebase-admin, jose, or the
externals config on a preview deployment. Remove the override once jwks-rsa switches
to a dynamic import().
Server-side events are logged as structured JSON to both the console (so
Vercel's own runtime logs are unchanged) and Better Stack, via
src/lib/logger.ts. Without BETTER_STACK_SOURCE_TOKEN the logger silently
degrades to console-only, so local development needs no setup.
여기까지가 README 앞부분입니다. 나머지는 원문에서 읽을 수 있습니다. README 전문 보기 ↗