Commit graph

1024 commits

Author SHA1 Message Date
Till JS
336cfedd0b refactor(auth): centralize appReady pattern into AuthGate component
Replace copy-pasted appReady/loading/redirect logic in all 13 layouts
with a shared AuthGate component. Supports guest mode, onReady callback
for app-specific data loading, and configurable login redirect.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 08:30:31 +01:00
Till JS
31af413b77 fix(manacore): add missing shared packages to Dockerfile
Add shared-feedback-types, shared-help-content, shared-help-types,
and shared-help-ui to Docker COPY statements.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 08:26:48 +01:00
Till JS
80beef252c feat(observatory): add tabbed gallery views for plants and lakes
Three tabs on the observatory page:
- Seenplatte: the main interactive landscape (existing)
- Pflanzen: horizontal scroll gallery of all 20 apps as plant cards,
  grouped by status (Mature/Production/Beta/Alpha), each with SVG
  preview, score, type label, trend indicator. Click opens detail panel.
- Seen: horizontal scroll of all 6 infrastructure lakes with gradient
  preview, description, clarity and fill level stats.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 08:24:29 +01:00
Till JS
a432c77286 docs: add devlog for evening session 2026-03-24
41 commits: PWA icons for all apps, Mac Mini port exhaustion fix,
Todo UX overhaul (inline edit, drag fix, long press), Dashboard
widget shows all tasks, Dockerfile validator, auth improvements.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 08:20:44 +01:00
Till JS
42dd7d2a7a fix(shared-help): harden help system with XSS protection, i18n, type safety, and reference implementation
- Add HTML sanitization via isomorphic-dompurify in parser layer to prevent XSS
- Replace all hardcoded English strings with translations (FAQSection, KeyboardShortcuts, ChangelogEntry/Section)
- Remove unsafe `as` type casting in loader.ts, use Zod-inferred generics instead
- Add error logging in content loader (replaces silent catch blocks)
- Fix HelpSearch blur handling (mousedown+preventDefault instead of setTimeout hack)
- Add ARIA attributes to HelpSearch for accessibility
- Derive FAQ categories from items instead of hardcoding all 6
- Fix null-safety in GettingStartedGuide.svelte
- Fix unused appId variable in HelpPage.svelte, add scroll-reset on tab switch
- Rebuild Contacts help page as reference implementation using shared HelpPage component
- Add README with quick-start guide, props docs, and translations template

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 22:38:46 +01:00
Till JS
f2488f86fe feat(infra): add workspace dependency audit script
New script scans source imports vs package.json deps to catch missing
workspace dependencies that work locally but break in Docker.
Fixed: manadeck-web and presi-web missing shared-stores.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 22:36:11 +01:00
Till JS
bf7517d24d feat(auth): add SessionExpiredBanner to all remaining web apps
Added to: clock, photos, storage, mukke, planta, picture, skilltree,
nutriphi, chat. Now all 13 web apps show a re-login banner when
token refresh permanently fails.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 22:35:13 +01:00
Till JS
90c438e267 feat(infra): auto-generate Dockerfile COPY statements from package.json
New script generates COPY blocks between marker comments, eliminating
manual maintenance. All 17 web Dockerfiles updated with markers.
Supports --check flag for CI validation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 22:33:07 +01:00
Till JS
23dac3272e feat(observatory): add tooltips, detail panel, radar chart, and atmosphere
Phase 5 - Interactivity:
- Hover tooltip with score, status, category bars on every plant
- Click opens slide-in detail panel with 8-axis radar chart
- Panel shows all category scores, app links, ManaScore link
- Escape key and backdrop click close the panel
- Pan vs click distinction (no panel on drag)

Phase 6 - Atmosphere:
- Dynamic sky that follows real time of day (sunrise/noon/sunset/night)
- Stars with twinkling animation at night
- Sun glow during golden hour
- Birds flying across the scene (daytime)
- Dragonflies circling over lakes
- Butterflies near plants
- Fireflies at night (glowing, drifting)
- Time updates every minute

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 22:21:04 +01:00
Till JS
5286404129 feat(parsers): add intelligent quick-create parsers for 6 apps with multilingual support
- Base parser: multilingual (DE/EN/FR/ES/IT) date, time, weekday, month parsing
- Base parser: fuzzy/typo tolerance (Levenshtein), recurrence (RRULE), relative time
- Base parser: timezone extraction, date ranges, ordinal dates, confidence scoring
- Base parser: past dates (gestern/yesterday), this/next week distinction
- Base parser: compose helper (createAppParser), multiple @references
- Calendar: event-parser with duration, time ranges, location, all-day, calendar ref
- Calendar: wire up UnifiedBar with onCreate/onParseCreate for quick event creation
- Todo: task-parser multilingual priority keywords (urgent/important/normal/later)
- Planta: plant-parser with acquisition keywords (gekauft/bought/acheté)
- Mukke: song-parser with Artist-Title format, BPM, genre, playlist/project creation
- NutriPhi: meal-parser with meal type detection, add QuickInputBar to layout
- All parsers: 210 tests across 7 test suites, all passing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 22:18:05 +01:00
Till JS
5c2a8d07e3 fix(manacore): add date-fns to package.json for Docker build
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 21:28:54 +01:00
Till JS
d6440664ac feat(auth): add session expired banner when token refresh fails
Users now see an amber banner with a re-login button instead of a
broken empty page when their session expires. Uses pub/sub events
from tokenManager, integrated in todo, calendar, zitare, contacts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 21:24:28 +01:00
Till JS
02db49175a fix(observatory): use inline styles to ensure SVG renders correctly
Replaced Tailwind utility classes with inline styles for the container
and SVG element to prevent CSS purging issues in production build.
Added explicit preserveAspectRatio and xmlns attributes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 21:24:25 +01:00
Till JS
47dbe00d3d fix(manacore): show all open tasks in dashboard widget, not just today
The tasks widget only showed tasks with dueDate=today, so tasks without
a date appeared as "no tasks". Now fetches all open tasks via GET /tasks,
sorted by due date (today/overdue first, then future, then no date).

- Add getAllOpenTasks() to todo service
- Update widget to use getAllOpenTasks()
- Show due date label next to task title (with overdue highlighting)
- Update i18n: "Aufgaben heute" → "Aufgaben"

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 21:22:36 +01:00
Till JS
04f5afe671 feat(landing): replace simple footer with rich mega footer
4-column categorized footer showcasing the entire Mana ecosystem:
- Ecosystem: All 15 apps with status dots and expandable list
- Platform: Dashboard, Observatory, Playground, monitoring, community
- Insights: Devlog, ManaScore, Release Plan, Blueprints, landing pages
- Legal: Privacy, DSGVO, AI models, Impressum

Responsive: 4 cols desktop, 2 cols tablet, 1 col mobile.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 21:13:46 +01:00
Till JS
a2605e8816 feat(infra): add Dockerfile dependency validator + fix 16 missing COPYs
New script validates that all workspace deps in package.json have
matching COPY statements in Dockerfiles. Fixed missing shared-pwa,
shared-vite-config, patches/, and project-specific package COPYs
across 7 web app Dockerfiles.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 20:25:54 +01:00
Till JS
10df359fdb fix(todo): simplify section headers - remove chevron, count, and collapse
Sections are now always open with clean minimal headers:
- Remove chevron toggle icon
- Remove task count from section headers
- Remove collapsible behavior (sections always visible)
- Reduce icon size from 20 to 18
- Remove count from upcoming day subheaders

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 20:05:06 +01:00
Till JS
6c4fd392cc fix(zitare): add spiral-db to web Dockerfile
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 20:04:21 +01:00
Till JS
764843772a feat(manacore): add Seenplatte ecosystem observatory visualization
Interactive SVG lake landscape that visualizes all ManaCore apps as plants
around interconnected lakes. Plant type and health reflects ManaScore:
- Oaks/Birches for mature/production apps (85+)
- Young trees and reeds for beta apps
- Sprouts for alpha/prototype apps
- Animated water (waves, river flow particles)
- Pan & zoom navigation
- 6 lakes representing infrastructure (Auth, Redis, MinIO, 3x PostgreSQL)
- 20 apps with real ManaScore data

Accessible at /observatory in the ManaCore web dashboard.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 20:01:49 +01:00
Till JS
caa126f8de fix(zitare): add missing shared-utils dependency to web package
hooks.server.ts imports @manacore/shared-utils/analytics-server but
shared-utils wasn't listed as a dependency. pnpm doesn't create the
symlink without it, causing Rollup to fail during Docker builds.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 20:01:34 +01:00
Till JS
ea37288f8e feat(todo): long press to open expanded edit form on mobile
500ms long press on a task item opens the expanded form with all fields.
Touch move or release before 500ms cancels the long press.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 19:56:04 +01:00
Till JS
4b4cdd8cd8 feat(todo): inline title editing on click
Click on task title to edit it directly inline instead of opening the
expanded form. Enter to save, Escape to cancel, blur to save.
Title shows subtle hover background to indicate editability.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 19:49:39 +01:00
Till JS
f42f9ce818 fix(todo): swap checkbox/priority order, enlarge priority dot, remove chevron
- Swap positions: checkbox now before priority indicator (drag → check → prio → content)
- Increase priority dot size from 0.5rem to 0.625rem
- Remove expand/collapse chevron icon on the right side

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 19:46:33 +01:00
Till JS
c96447981f fix(todo): improve drag-and-drop handles and fix reorder persistence
- Replace hamburger icon with standard 6-dot grip icon for drag handles
- Increase drag handle icon size (1rem → 1.25rem) and hit area
- Fix reorder bug: handleDndFinalize was not calling reorderTasks(),
  so reordered items were never persisted and would revert on refresh
- Add optimistic update with rollback on error in reorderTasks store

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 19:43:30 +01:00
Till JS
233a3c0732 docs: add devlog for morning session 2026-03-24
Credits cost tab, dashboard grid fix, PostgreSQL backup, port exhaustion
debugging, SkillTree achievements, Calendar i18n, CityCorners features.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 19:28:31 +01:00
Till JS
c8686506ca fix(zitare): add shared-pwa to web Dockerfile
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 19:22:43 +01:00
Till JS
91daba062f fix(storage): add PWA icons and meta tags to fix build and enable install
The prerendered /offline page referenced /favicon.png which didn't exist,
causing Docker build failure. Added favicon.svg, generated all PWA icons,
and added proper PWA meta tags to app.html.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 19:22:16 +01:00
Till JS
994abf3ece fix(zitare): add missing patches/ COPY to web Dockerfile
The pnpm lockfile references patches (e.g., react-native-reanimated)
which need to be present for --frozen-lockfile to succeed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 19:20:44 +01:00
Till JS
9431af656d docs(manascore): update scores for storage, todo, and calendar
- Storage: 82 → 84 (Dockerfile fix, offline prerender)
- Todo: PWA icons + offline prerender documented
- Calendar: PWA icons + offline prerender documented

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 19:18:53 +01:00
Till JS
6d231ee8bf docs: document ManaScore extended metrics and add to root CLAUDE.md
Update about page with Score Trend, Lighthouse, Dependency Health,
API Conformity, and Cross-App Consistency documentation. Add
ManaScore section to root CLAUDE.md for discoverability.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 12:30:58 +01:00
Till JS
94d7e2bd02 feat(citycorners): add slugs, contacts, collections, clustering, rate limiting, soft deletes
1. SEO Slugs: Auto-generated from name (ä→ae, ö→oe, etc.), unique with
   -2/-3 suffix. Routes accept both UUID and slug. Seed data includes slugs.

2. Opening Hours + Contact: website, phone, openingHours fields in schema.
   Displayed on detail page, editable in add/edit forms.

3. Landing Page with API: Fetches locations from backend at build time,
   falls back to hardcoded JSON if API unreachable.

4. Frontend Tests: Vitest setup with api.test.ts (50 backend + web tests).

5. Marker Clustering: leaflet.markercluster for 10+ locations on map,
   direct markers for fewer.

6. Favorite Collections: New collections table with CRUD endpoints.
   Favorites page has tabs for favorites vs collections. Create, view,
   delete collections with location management.

7. Rate Limiting: In-memory guard (10 req/min) on write endpoints.
   Returns 429 with retryAfter.

8. Soft Deletes: deletedAt field, all reads filter deleted records.
   POST /locations/:id/restore endpoint for owners.

50 backend tests passing, 0 type errors.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 12:27:29 +01:00
Till JS
06694eac19 feat(manascore): add API conformity and cross-app consistency checks
- API Conformity: 7 checks (responses, errors, pagination, versioning,
  docs, health, validation) with checklist UI
- Cross-App Consistency: track shared package usage (auth, ui, theme,
  branding, i18n, error-tracking + optional storage, llm)
- Both shown as compact badges on overview, detailed cards on detail page

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 12:24:45 +01:00
Till JS
61c23d5e79 fix(manacore): improve dashboard layout polish
- Remove unnecessary wrapper div in WidgetContainer
- Increase grid gap from gap-4 to gap-5 for breathing room
- Add auto-rows-fr for equal row heights
- Add min-h on widget content so empty widgets aren't tiny
- Change default layout to 3 equal columns (small)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 12:21:51 +01:00
Till JS
02215dfb12 feat(skilltree): add achievement system with 26 achievements + monetization report
Full-stack achievement system for SkillTree with backend (NestJS) and frontend (SvelteKit):
- 26 achievements across 7 categories (XP, Skills, Levels, Activities, Streak, Branches, Special)
- 5 rarity tiers (Common → Legendary) with distinct styling
- Auto-unlock after XP gain, skill creation, and activity logging
- Celebration animation on unlock with sparkle effects
- Achievements page with category filters and progress tracking
- IndexedDB offline support with local condition evaluation
- Backend seeds achievements on startup, checks conditions after mutations
- Stats overview extended with achievement counter
- i18n translations (DE + EN)

Also adds docs/MONETIZATION_REPORT.md with ranked analysis of all apps.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 12:17:43 +01:00
Till JS
000b74af9f fix(web): add appReady gate to prevent auth race condition in all apps
In Svelte, child onMount fires before parent onMount. Pages that fetch
data in onMount race against the layout's authStore.initialize(). Added
appReady state gate to layouts so children don't mount until auth is
confirmed. Affects: todo, contacts, clock, photos, zitare, planta.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 12:15:35 +01:00
Till JS
e3115b302d feat(infra): add Cloudflare fallback plan + self-hosted landing pages
Two infrastructure improvements for tech independence:

1. Cloudflare Fallback Documentation (docs/CLOUDFLARE_FALLBACK.md):
   - Plan B: WireGuard + Caddy on Hetzner VPS (€3.79/mo)
   - Complete Caddyfile with all 30+ subdomains
   - Step-by-step failover checklist (~15 min to switch)
   - Plan C: Direct IP with ISP

2. Self-Hosted Landing Pages (eliminates Cloudflare Pages dependency):
   - Nginx container (mana-infra-landings) on port 4400
   - Multi-site config: each subdomain → separate dist/ folder
   - Build script: scripts/mac-mini/build-landings.sh
   - Cloudflare Tunnel ingress rules for 10 landing page domains
   - Storage: /Volumes/ManaData/landings/ on external SSD
   - Domains: it, chats, pics, zitares, presis, clocks,
     manadeck, nutriphi, citycorners, docs

Migration path: Build landings locally, set Cloudflare DNS to
tunnel instead of Pages, then decommission CF Pages projects.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 12:07:40 +01:00
Till JS
954b204bac fix(manacore): fix dashboard grid layout - widgets were col-span-1
The animate:flip wrapper div in DashboardGrid was not passing through
the col-span classes, causing all widgets to render at minimum width.
Moved size classes from WidgetContainer to the grid wrapper div.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 11:49:12 +01:00
Till JS
986f168d32 feat(manascore): add Lighthouse score integration
Add optional lighthouse scores (performance, accessibility, best
practices, SEO) to schema. Display as inline badges on overview
and circular gauges on detail page with average score.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 11:46:16 +01:00
Till JS
d3ae3841d9 feat(manascore): add score trend visualization with sparkline charts
Add history array to schema for tracking score changes over time.
Index page shows inline sparkline + delta, detail page shows larger
area chart with score labels on each data point.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 11:35:12 +01:00
Till JS
c21347351a fix(credit-operations): export TypeScript source directly
Allows Vite/SvelteKit to import the package without a prior build step,
matching the pattern used by other shared packages like shared-credit-ui.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 11:31:20 +01:00
Till JS
3c6253a84b fix(manacore): use --ignore-scripts in Dockerfile install step
Prevents postinstall from triggering premature builds before shared
packages are compiled.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 11:28:42 +01:00
Till JS
817ad841c6 fix(manacore): build credit-operations package in web Dockerfile
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 11:26:31 +01:00
Till JS
8e390395fd feat(citycorners): add photo gallery, nearby locations, and search history
1. Photo Gallery:
   - New `images` JSONB array field in locations schema
   - POST /locations/:id/images endpoint to add photos (auth required)
   - Gallery with thumbnail strip and image counter on detail page
   - Any authenticated user can add photos to any location
   - "Add photo" button inline with thumbnails

2. Nearby Locations:
   - GET /locations/:id/nearby endpoint with Haversine distance query
   - Configurable radius (default 2km, max 10km)
   - Returns up to 5 nearby locations sorted by distance
   - Horizontal scroll card strip on detail page showing distance

3. Search Suggestions + History:
   - GET /locations/suggestions endpoint (prefix matching, fast)
   - Search history stored in localStorage (max 8 entries)
   - Empty search shows recent history with clock icon
   - Selected locations automatically saved to history
   - Falls back to full-text search if no prefix matches

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 11:25:17 +01:00
Till JS
c4cc8529e3 fix(manacore): add credit-operations package to web Dockerfile
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 11:21:31 +01:00
Till JS
58fb3e8dff feat(citycorners): add owner tracking, edit/delete UI, and pagination
1. Owner tracking (createdBy):
   - Add createdBy field to locations schema
   - Set createdBy to userId on location creation
   - Only owners can edit/delete their own locations
   - Seed/unowned locations remain editable by anyone

2. Edit/Delete UI:
   - Edit button + full edit form at /locations/:id/edit
   - Delete button with confirmation dialog on detail page
   - Both only visible to the location owner
   - ForbiddenException (403) if non-owner tries to modify

3. Pagination:
   - Backend returns paginated results (page, limit, total, totalPages)
   - Frontend "Load more" button for infinite scroll
   - Category filter reloads from API with server-side filtering
   - Default 20 items per page, max 100

Tests updated: 36 tests passing (5 new for ownership + pagination).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 11:19:15 +01:00
Till JS
979564540a fix(manacore): fix @const syntax error in ContextDocsWidget
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 11:17:45 +01:00
Till JS
57a2841168 fix(manacore): fix syntax error in LandingEditor bind:value
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 11:15:39 +01:00
Till JS
5611f3824a feat(citycorners): UX quick wins for web app
- Lazy loading for location card images
- Category filter pills now show count (e.g. "Restaurants (3)")
- Better empty states with category-specific messages and emoji
- Share button on detail page (Web Share API with clipboard fallback)
- "On map" and "Directions" (Google Maps) buttons on detail page
- Geolocation "locate me" button on map page with user marker
- Image URL retry button on add form when image fails to load
- i18n keys for all new features (DE/EN)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 11:07:38 +01:00
Till JS
357fbb3d50 feat(manacore): rename audits to ManaScore + add methodology page
Rename content collection, pages, and routes from "audits" to
"manascore" for clearer branding. Add comprehensive about page
explaining the 8 scoring categories, weights, and methodology.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 10:43:07 +01:00
Till JS
fc7d2942d0 feat(picture): add local image generation via mana-image-gen
Add LocalImageGenService that routes to the self-hosted FLUX.2 klein
model on the Mac Mini, eliminating Replicate API dependency for basic
image generation.

Changes:
- LocalImageGenService: wraps mana-image-gen HTTP API (/generate)
  with health checking, timeout handling, and GenerationResult compat
- GenerateService: routes to local or Replicate based on model config
  (replicateId starting with "local/" → LocalImageGenService)
- Local models always use sync mode (no webhooks needed, ~0.8s)
- Seed: add "FLUX.2 Klein (Lokal)" model with sortOrder -1 (shown first)
  - costPerGeneration: 0 (free, runs locally)
  - estimatedTimeSeconds: 1
- docker-compose: add IMAGE_GEN_SERVICE_URL env var for picture backend

Replicate remains available for premium models (Seedream, Nano Banana).
Local FLUX.2 klein becomes the default free option.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 10:38:30 +01:00