managarten/apps
Till JS d56ad396d8 feat(wardrobe,picture): try-on integration — outfit → OpenAI edit (M4)
M4 of docs/plans/wardrobe-module.md — the loop closes. A user with at
least a face-ref in the active space can click "Anprobieren" on an
outfit detail page; the client composes a reference call against the
existing M3 `/generate-with-reference` endpoint, persists the result
into the Picture gallery with a `wardrobeOutfitId` back-reference,
and pins a `lastTryOn` snapshot on the outfit so its card instantly
shows the AI preview next time.

Server side — picture/routes.ts:
- verifyMediaOwnership now accepts `apps: string | readonly string[]`.
  Under the hood it runs one list() per app-tag and unions the owned
  set before the missing-id check. Preserves the 500-row per-app
  sanity cap. Single-tag callers unchanged — it's an additive widen.
- Picture /generate-with-reference passes `['me', 'wardrobe']` so
  face/body portraits (me-images) and garment photos (wardrobe) can
  ride in the same referenceMediaIds array. Anything outside those
  two tags still 404s — no expansion of the trust surface.

Client side — wardrobe/api/try-on.ts:
- `runOutfitTryOn({ outfit, garments, faceRefMediaId, bodyRefMediaId?, ... })`
  composes the ref list (face → body → up to 6 garments, respecting
  the 8-slot server cap), picks portrait 1024x1536 by default (or
  1024x1024 in accessory-only mode), and POSTs with
  `model='openai/gpt-image-2'`, `quality='medium'`, `n=1`. One render
  per click; multi-variant is a future Generator-style extension.
- Default prompts are composed in DE from the outfit meta (name +
  occasion); callers can override via `prompt`. Accessory-only mode
  uses a tighter studio-portrait phrasing since the fullbody ref is
  dropped there.
- `isAccessoryOnlyOutfit()` helper — iff every garment is in
  FACE_ONLY_CATEGORIES, skip body-ref and render square. Covers the
  Brille-Try-On headline use case.
- On success: inserts a `picture.images` row with generationMode=
  'reference', referenceImageIds, and wardrobeOutfitId set; then
  calls wardrobeOutfitsStore.setLastTryOn() with imageId + imageUrl
  so OutfitCard + DetailOutfitView immediately flip to the AI cover.

TryOnButton — wardrobe/components/TryOnButton.svelte:
- Three states: ready (click to render), missing-references (shows
  UserCircle + link to /profile/me-images, with the right hint for
  accessory-only vs. fullbody), loading (spinner).
- Credit estimate on the button (10c medium quality).
- Hints: accessory-only, too-many-garments (>6, over server cap),
  and non-personal-space disclosure — the family-space case gets its
  own sentence since "Try-On rendert dich, nicht dein Kind" is
  non-obvious.
- Reads face-ref/body-ref via useImageByPrimary (space-scoped after
  the v40 meImages migration — brand/club/family spaces need their
  own references uploaded).

UI wiring:
- DetailOutfitView replaces the M3 stub button with <TryOnButton/>.
  The existing "Try-On Verlauf"-Strip already reads
  `useOutfitTryOns(outfit.id)` which filters `picture.images` by
  wardrobeOutfitId — it lights up automatically on first render.

Not in M4 (punted to follow-ups):
- Solo-garment try-on on DetailGarmentView ("nur diese Brille auf
  mein Gesicht"). Plan called it out as optional; the outfit flow
  already covers it when the outfit contains only that one garment.
- Multi-variant rendering (n=2/4). Usable "show me 3 looks" needs a
  picker UI on top, not just a param bump.
- Quality + prompt override in the button. A power-user panel can
  come later; default medium + auto-prompt keeps M4's click-to-try-on
  one-tap.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 18:52:57 +02:00
..
api feat(wardrobe,picture): try-on integration — outfit → OpenAI edit (M4) 2026-04-23 18:52:57 +02:00
calc/packages/shared chore: delete 25 web-archived directories, remove stale stubs, clean workspace config 2026-04-03 13:03:49 +02:00
calendar refactor(shared-tailwind): rewrite themes.css to single-layer shadcn convention 2026-04-09 01:13:06 +02:00
cards chore(mobile): remove 6 of 7 mobile apps — keep only memoro 2026-04-20 15:31:47 +02:00
chat chore(mobile): remove 6 of 7 mobile apps — keep only memoro 2026-04-20 15:31:47 +02:00
citycorners chore: complete ManaCore → Mana rename (docs, go modules, plists, images) 2026-04-07 12:26:10 +02:00
contacts refactor(shared-tailwind): rewrite themes.css to single-layer shadcn convention 2026-04-09 01:13:06 +02:00
context chore(mobile): remove 6 of 7 mobile apps — keep only memoro 2026-04-20 15:31:47 +02:00
docs feat(ai): Mission Grant rollout gating — flag, alerts, runbook, user docs 2026-04-15 14:02:47 +02:00
food refactor: rename nutriphi module to food (Essen) 2026-04-14 15:30:07 +02:00
guides refactor(shared-tailwind): rewrite themes.css to single-layer shadcn convention 2026-04-09 01:13:06 +02:00
inventory refactor(mana): rename inventar → inventory across the codebase 2026-04-09 15:50:24 +02:00
mana feat(wardrobe,picture): try-on integration — outfit → OpenAI edit (M4) 2026-04-23 18:52:57 +02:00
manavoxel fix(type-check): clear the last five failures — monorepo type-check is now 76/76 green 2026-04-20 15:53:07 +02:00
memoro chore: remove abandoned per-product workspace artifacts 2026-04-09 11:56:51 +02:00
moodlit refactor(shared-tailwind): rewrite themes.css to single-layer shadcn convention 2026-04-09 01:13:06 +02:00
mukke feat: rename ManaCore to Mana across entire codebase 2026-04-05 20:00:13 +02:00
news refactor(shared-tailwind): rewrite themes.css to single-layer shadcn convention 2026-04-09 01:13:06 +02:00
photos refactor: rename nutriphi module to food (Essen) 2026-04-14 15:30:07 +02:00
picture chore(mobile): remove 6 of 7 mobile apps — keep only memoro 2026-04-20 15:31:47 +02:00
plants refactor: rename planta → plants, clean up codebase 2026-04-12 18:59:44 +02:00
presi fix(presi): wire up db:push for presi schema via @mana/api 2026-04-12 14:32:44 +02:00
questions refactor(shared-tailwind): rewrite themes.css to single-layer shadcn convention 2026-04-09 01:13:06 +02:00
quotes/packages/content fix(mana-llm): google-genai v1.73 keyword-only Part.from_text() 2026-04-16 12:47:23 +02:00
skilltree chore: delete 25 web-archived directories, remove stale stubs, clean workspace config 2026-04-03 13:03:49 +02:00
storage refactor(shared-tailwind): rewrite themes.css to single-layer shadcn convention 2026-04-09 01:13:06 +02:00
times chore: complete ManaCore → Mana rename (docs, go modules, plists, images) 2026-04-07 12:26:10 +02:00
todo fix(tsconfig): unblock shared-types consumers 2026-04-21 18:53:55 +02:00
traces chore(mobile): remove 6 of 7 mobile apps — keep only memoro 2026-04-20 15:31:47 +02:00
uload fix(type-check): clear the last five failures — monorepo type-check is now 76/76 green 2026-04-20 15:53:07 +02:00