Commit graph

4 commits

Author SHA1 Message Date
Till JS
e0820331b0 feat(wardrobe): solo-garment try-on + plan-doc status updates (M4.1)
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>
2026-04-23 21:14:35 +02:00
Till JS
638f9c34d6 docs(plans): me-images M1-M5 status + new wardrobe plan
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>
2026-04-23 15:08:45 +02:00
Till JS
a64a7e39cf feat(profile): UI for me-images management at /profile/me-images (M2)
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>
2026-04-23 14:01:40 +02:00
Till JS
89258eb451 feat(profile,api): meImages foundation for AI reference generation (M1)
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>
2026-04-23 13:50:53 +02:00