Inspiration

Skincare social media has an honesty problem. Every product is a miracle, every before/after is real, and nobody tells you that a single selfie under bathroom lighting proves nothing. We wanted to build the opposite: a skincare companion that would rather say "we don't know yet" than flatter you.

What it does

BaddieGuide answers one question — "is my skincare routine actually working?" — with guided AI face scans and an honesty-first trend engine.

  • Guided scans run through Perfect Corp's AI Skin Analysis API (SD), scoring 12 concerns with focus on redness, acne, texture and oiliness.
  • A noise-aware trend engine refuses to call a trend before 3 scans, shades a per-concern noise band on every chart, and labels changes inside the band "normal fluctuation" — never progress, never regression.
  • Quality-flagged scans stay visible but are excluded from the math — never silently averaged.
  • Deterministic verdicts come from a human-reviewed rules file (no AI improvisation at runtime), personalized by skin tone using Perfect Corp's AI Fitzpatrick Scale Analyzer — deeper skin tones get more conservative, marks-aware phrasing. We store the Fitzpatrick type only, for calibration, never as an ethnicity label.
  • Routine correlation callouts always carry "(correlation, not proof)".
  • Escalation guardrail: a worsening, high-severity acne pattern overrides all other messaging with one banner — show this to a dermatologist.
  • Baddie Score ❤ rates your consistency (scan streak + routine logging). It never rates your face — its inputs are dates, so it structurally can't.
  • Then vs Now is strictly opt-in: at most 2 stored photos, deletable anytime.

How we built it

Java 21 / Spring Boot 3 backend (PostgreSQL + Flyway), React + Tailwind frontend served from the same container, single Dockerfile, deployed on Railway. The two YouCam APIs sit behind a fail-closed budget guard: every billable call must first commit a credit reservation in a ledger — if budget state can't be proven, the call is denied, so the app can never overrun its API budget. Trend math runs exclusively on raw vendor scores; display normalizes once to 0–100 higher-is-better and says so in the UI. The consent flow (18+ → notice → two explicit consents) hard-gates every camera endpoint server-side with 403s.

Challenges we ran into

Building trust without runtime AI meant encoding every message in a reviewable rules file with a forbidden-vocabulary guard that fails the build if medical claims sneak in. Separating signal from noise was the core product problem: phone-camera scores wobble, so we compute and display the noise band instead of hiding it — which meant designing for "no verdict yet" as a first-class state. Our build environment had no package-registry access, so we made the frontend build fully hermetic (vendored React, single-binary bundler and CSS tools). And deploy day taught us the classics: ignore-rules silently dropping a vendored dependency, and environment variables landing on the wrong service.

Accomplishments that we're proud of

The honesty invariants are executable tests, not slogans — a table of "honesty cases" asserts that the engine refuses premature verdicts, excludes flagged scans, and calls in-band changes fluctuation. The fail-closed credit ledger means the demo can't bankrupt itself during judging. Skin-tone-aware confidence phrasing treats measurement uncertainty on deeper skin tones as something to say out loud, not hide. And it's a complete product — consent flow, guided scan, trends, escalation, delete-my-data — not a proof-of-concept.

What we learned

Honesty is a visible feature: users trust a chart more when the noise band is drawn on it. The hardest UX is the empty state — telling someone "come back after 3 scans" kindly. API credits deserve production-grade budget engineering from day one. And Fitzpatrick typing is genuinely useful when framed as calibration and genuinely dangerous when framed as anything else.

What's next for BaddieGuide

Real accounts via magic links, HD analysis mode, scan reminders, measured per-user noise calibration over longer histories, and an edge/WAF layer for a true public launch.

Built With

Share this project:

Updates

Submission history