Closes the one checklist item M4 left for later — "TryOnButton auf
DetailGarmentView (mit impliziten 'Solo-Outfit')". A user can now open
a single garment's detail page, see "An mir anprobieren · 10 Credits",
and get an inline preview of themselves wearing just that one item
(or just that accessory, for glasses/jewelry/hat/accessory).
Client:
- api/try-on.ts: extracts a shared callGenerateWithReference() helper
and a dimsForSize() utility from runOutfitTryOn so the new
runGarmentTryOn can share the HTTP-error matrix + picture.images
row shape without a refactor of the outfit path.
- runGarmentTryOn({ garment, faceRefMediaId, bodyRefMediaId?, prompt?,
quality? }): auto-detects accessoryOnly from the garment's category
(FACE_ONLY_CATEGORIES), composes the DE default prompt ("im/in
<Name>", "mit <Name>" für Accessoires), writes a picture.images row
with wardrobeOutfitId=null so it doesn't pollute any outfit's
try-on history. Does NOT update any outfit.lastTryOn — it's a
standalone preview, on purpose.
- GarmentTryOnButton.svelte: thinner sibling of TryOnButton. Same
three states (ready / missing-refs / loading), same non-personal-
space disclaimer. Extra: inline preview panel showing the last
rendered result, with a link to the Picture gallery ("Gefunden in
der Picture-Galerie als normale Generierung.").
- DetailGarmentView now puts the try-on action above the existing
wear-tracking button. Try-on is the more engaging action for this
page; demoting "heute getragen" to a secondary-styled button
respects that without removing it.
Plan docs:
- docs/plans/wardrobe-module.md — rewrites the Status block to M1-M5
with actual commit hashes, and checks off the per-milestone task
lists. Adds a new M4.1 block for solo-garment try-on.
- docs/plans/me-images-and-reference-generation.md — adds the v40
space-scope migration (cb9a9bb42) as its own row in the commit
table, with a pointer to the sub-plan.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two plan updates as a set:
- me-images-and-reference-generation.md: rewrites the "Status" block
to reflect what actually shipped (M1 89258eb45, M2 a64a7e39c, M2.5
e2b5ac38c, M3 in 38dc80654, M4 in d087b4744, M5 fc635f983) and
adds an "Offen" section listing the small follow-ups that didn't
make the M1-M5 cut — global aiUsesReferenceImages kill-switch,
kind-editor on existing tiles, reference-display in picture
detail view, legacy-avatar re-upload hint — plus the three
optional later tracks (M6 local FLUX+PuLID, M7 inpainting masks,
M8 zero-knowledge blobs). Milestones checklist is now
✅-annotated per shipped item with actual decisions (Dexie v38
instead of v27, no me-storage bucket after all, generation_log
deferred, etc.).
- wardrobe-module.md: new plan. Data layer sketch (two tables:
wardrobeGarments + wardrobeOutfits, reuses me-images + picture
as dependencies), UI breakdown (/wardrobe, /wardrobe/compose,
garment + outfit detail routes), Try-On as a thin wrapper over
the M3 endpoint (with the cap bumped from 4 → 8 references, so
face + body + up-to-6 garments fits one call), four MCP tools
in a new wardrobe.ts module, and two optional later tracks
(Persona Stil-Coach template, context-driven outfit suggestion
mission). The explicit non-goals block keeps the scope tight:
no product DB, no replacement for inventory, no shopping, no
style-coaching that feels judgmental.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
M2 of docs/plans/me-images-and-reference-generation.md — the Settings
surface that sits on top of the M1 data layer. Users can now upload
a Face and a Fullbody reference into two primary slots, toss extra
references into a grid, and toggle each image's "KI darf nutzen" flag
individually.
Route placement: /profile/me-images (not /settings/me-images as the
plan originally proposed). The repo convention is per-module subroutes
(/todo/settings, /invoices/settings, …) — there is no global /settings
namespace to hang this off. Plan doc updated accordingly.
- MeImageUploadZone: drag-and-drop + file-picker, pattern from
picture/ListView but refactored into a reusable component. Fires
onFiles(File[]) so the parent decides kind + slot.
- MeImageSlotCard: large card for Face / Fullbody primary slots.
When filled it shows the portrait + the image's AI-toggle + delete
+ a compact "Neues Bild setzen" replacement zone. When empty it
collapses into a large drop-zone.
- MeImageTile: grid tile for everything that isn't currently holding
a primary slot — thumbnail, kind badge, Robot-AI-toggle, Star
primary-promotion (only enabled for kinds that map to a slot),
Trash delete.
- MeImagesView: orchestrates queries (useImageByPrimary for each
slot + useAllMeImages for the rest), upload flow (readDimensions →
uploadMeImageFile → store.createMeImage → optional setPrimary in
the same tick), and the three write actions (toggleAi, togglePrimary,
delete). Dropping a file on a slot drop-zone both uploads and claims
the slot, so the old holder automatically falls into the grid.
- Client: profile/api/me-images.ts wraps the M1 endpoint with
authStore.getValidToken() → Bearer header and a small
readImageDimensions helper that exposes natural width/height
synchronously (mana-media reports them later but we want them for
the Dexie row's first write).
- Discoverability: profile ListView "Konto" tab gains a "Meine Bilder"
action button that navigates to the new route with a one-line hint.
Still open (later commits): the hard-migration that rewrites
auth.users.image → meImages(primaryFor='avatar'), the global
aiUsesReferenceImages kill-switch (lives on profile singleton), and
the Picture-generator's Reference picker (M4, rides on top of M3's
backend endpoint).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
M1 of docs/plans/me-images-and-reference-generation.md — a user-owned
pool of reference images (face, fullbody, hands, …) that will back
image generation where the user appears as themselves (outfit try-on,
glasses, portraits) via OpenAI /v1/images/edits. Data layer only in
this commit; UI lands in M2, the edits endpoint in M3.
- Dexie v38: meImages table with id/kind/primaryFor/createdAt indices.
Added to USER_LEVEL_TABLES so the hook stamps userId and skips the
spaceId/authorId/visibility trio (one human = one face across every
Space, not per-Space).
- Encryption registry: label + tags encrypted; kind/primaryFor/usage
stay plaintext because they drive the indexed queries and the
Reference picker's filtering. mediaId/URLs/dimensions are structural.
- Profile module store: createMeImage, updateMeImage,
setAiReferenceEnabled (per-image KI opt-in — plan decision #5),
setPrimary (transactional slot swap — only one row per primary slot),
deleteMeImage. Emits MeImage* domain events.
- Queries: useAllMeImages, useMeImagesByKind, useReferenceImages
(only the rows the user opted in for KI), useImageByPrimary.
- POST /api/v1/profile/me-images/upload: thin wrapper over mana-media
with app='me' as the reference tag. No new MinIO bucket — plan
decision #1 revised after verifying mana-media uses one bucket and
only tags references by app.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>