Commit graph

2231 commits

Author SHA1 Message Date
Till JS
a02dceb51c feat(guides): ImportModal, share button, CLAUDE.md, server dev scripts
- ImportModal: 3-tab (URL/Text/AI) import UI with preview before saving
- Guide detail: share button → generates 7-day shareable link with copy-to-clipboard
- App layout: Import button in sidebar + dynamic ImportModal mount
- Library page: Import button in header (desktop), openImportGuide context
- Port corrected to 3027 (was 3025, conflict with CityCorners)
- CLAUDE.md: full project docs (routes, collections, env vars, phase status)
- Root package.json: dev:guides:server, updated dev:guides:app/local/full

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 21:42:26 +02:00
Till JS
ec0af64fd2 fix(memoro/web): fix broken authService.forgotPassword reference + add auth URL to env example
- login page: replace authService.forgotPassword (never imported) with authStore.resetPassword
- .env.example: add PUBLIC_MANA_CORE_AUTH_URL entries

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 21:41:25 +02:00
Till JS
c6448a63bc fix(mana-auth): avoid error.body access in login catch — triggers async stream read
Accessing (error as any)?.body?.code on a Better Auth APIError triggers an internal
async stream read. When the request body contains special chars like '!', the deferred
JSON parse fails as an unhandled rejection that races with the response, causing 500.

Use only error.status === 'FORBIDDEN' which is a simple string property.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 21:41:06 +02:00
Till JS
e624756d66 feat(guides): Phase 3 — Hono/Bun server for web import and guide sharing
- POST /api/v1/import/url — extract URL via mana-search, generate guide with mana-llm
- POST /api/v1/import/text — convert raw text/markdown to structured guide
- POST /api/v1/import/ai — generate guide from AI prompt
- POST /api/v1/share + GET /api/v1/share/:token — shareable guide links (7-day TTL, in-memory MVP)
- Uses Claude Haiku via mana-llm for structured JSON guide generation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 21:29:59 +02:00
Till JS
7f1c83f8b6 feat(guides): collection selector in guide modal, quick inline step add
GuideEditModal:
- Live collection list loaded from IndexedDB
- Select dropdown to assign guide to a collection (or none)
- Collection persisted on save

Guide detail — quick step add (no modal needed):
- Click "+ Schritt hinzufügen" → inline input appears
- Enter to save, Esc to cancel, ⋯ to open full StepEditorModal
- Works in both sections and unsectioned step list
- Input stays open after adding (for rapid multi-step entry)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 21:26:07 +02:00
Till JS
1a999f8cca feat(guides): Phase 2 — step editor, edit mode, collection management
Guide detail page:
- Edit mode toggle (✏ Bearbeiten / ✓ Fertig)
- StepEditorModal: 5 step types, title, markdown content, checkable toggle
- Per-step controls in edit mode: edit, delete, reorder ↑↓ (on hover)
- Section management: add / delete sections in edit mode
- Unsectioned + sectioned steps both editable
- Empty state with CTA to enter edit mode
- Guide delete with confirmation dialog
- Run history shows mode icon (📜 scroll / 🎯 focus)

Collections page:
- CollectionEditModal: emoji, color, path vs library type
- Create collection from empty state and header button
- Edit/delete existing collections

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 21:23:47 +02:00
Till JS
8e496ff417 fix(memoro): migrate web services + add credits balance endpoint
- server: add GET /api/v1/credits/balance (proxies to mana-credits via getBalance)
- web/creditService: rewrite to new paths (pricing, balance, retry-transcription, retry-headline)
- web/questionService: use authStore.getAccessToken() + new /api/v1/memos/:id/question path
- web/audioUploadService: fix accessToken param name for triggerTranscription

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 21:20:52 +02:00
Till JS
a893b07b70 feat(guides): complete Phase 1 — auth routes, i18n, collection detail, import fixes
- Add auth routes: login, register, forgot-password, reset-password (teal branding)
- Add i18n setup with de/en locales
- Add version.ts and theme store
- Add collections/[id] detail page with path progress and per-guide actions
- Fix import naming conflict (guidesStore → dbStore alias in app layout)
- Fix BaseRecord inline imports → top-level imports in stores and components
- Fix authStore.getAccessToken() → getValidToken()
- Fix theme import to use local store wrapper
- Update plan doc: Phase 1 complete

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 21:16:16 +02:00
Till JS
6d2509c258 feat(memoro): add deployment infrastructure and migrate web services to new Hono server
- Dockerfile for audio-server (Bun + ffmpeg)
- docker-compose.macmini.yml entries for memoro-server (3015) and memoro-audio-server (3016)
- Dev commands: dev:memoro:server, dev:memoro:audio-server, dev:memoro:app, dev:memoro:full
- MEMORO_* env vars in .env.development
- web: add PUBLIC_MEMORO_SERVER_URL env var to env.ts and .env.example
- web: rewrite transcriptionService → POST /api/v1/memos (new server path)
- web: rewrite spaceService → /api/v1/spaces/* (aligned with actual Hono routes)
- server: fix callAudioServer param name audioPath (was filePath) in memos.ts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 20:16:54 +02:00
Till JS
6e0dd0c065 docs(devlog): add 2026-03-31 entry — Memoro, status.mana.how, Todo polish, infra 2026-03-31 20:15:56 +02:00
Till JS
0a9c38161b feat(guides): add mana guides app — step-by-step playbook app
New app at apps/guides/ with local-first architecture (Dexie.js + mana-sync).

- 5 collections: guides, sections, steps, collections, runs
- Library view: card grid with search, category & difficulty filters
- Guide detail: sections/steps overview, start-run buttons
- Run mode: scroll (all steps) + focus (one step at a time) with note support
- Collections view: learning paths with progress bars
- History view: all runs with timestamps and duration
- Guest seed: 3 demo guides (dev setup, pasta recipe, git basics)
- GuideCard with run-status indicator (○◑●⟳)
- GuideEditModal with emoji, color, difficulty, tags
- Registered in shared-branding: port 5200, teal #0d9488, guides.mana.how
- Plan doc: .claude/plans/mana-guides.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 20:12:36 +02:00
Till JS
5e4518b418 refactor(ui): unify LanguageSelector, ConfirmDialog, and AppSlider across apps
- contacts, zitare: migrate LanguageSelector to shared PillDropdown pattern
- context, times: replace local ConfirmDialog with ConfirmationModal from @manacore/shared-ui
  - delete local ConfirmDialog.svelte in both apps
  - map open→visible, onCancel→onClose, remove destructive prop (default in shared-ui)
- calendar, chat, contacts, presi, todo: switch AppSlider from static MANA_APPS
  to getActiveManaApps() to filter inactive apps consistently

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 19:10:55 +02:00
Till JS
3ea2c03ab2 feat(todo): inline title editing + detail modal button on task items
- Title already had contenteditable; now shows clear focus ring (primary tint)
  when active so it's obvious the title is being edited
- Added ArrowsOutSimple icon button at the right end of each task row
  (appears on hover) that opens the full TaskEditModal
- Modal wired up with save/delete/close handlers
- Fixed all remaining hardcoded colors in TaskItem to use CSS vars
  (checkbox checked/animating, drag handle, due date, meta, form inputs,
  expanded wrapper border, btn-danger, assignee dot)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 19:06:55 +02:00
Till JS
29515e7c4d feat(memoro): add Hono/Bun server + audio-server (replaces NestJS)
Two new services replacing the NestJS backend + audio-backend:

- apps/memoro/apps/server/ (port 3015): main business logic
  - Memo creation, transcription orchestration, AI headline/Q&A
  - Space + invite management, credits, settings, cleanup
  - Uses @manacore/shared-hono authMiddleware (mana-auth JWT)
  - Service-role Supabase client with explicit user_id filters

- apps/memoro/apps/audio-server/ (port 3016): audio processing
  - 4-tier Azure Speech fallback (fast → retry → convert → batch)
  - FFmpeg conversion (PCM 16kHz mono WAV) via fluent-ffmpeg
  - Load balancing across up to 4 Azure Speech keys
  - Internal-only (X-Service-Key auth)

Auth proxy, space sync, and NestJS services not yet removed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 19:03:31 +02:00
Till JS
a0caa1f21d fix(manacore-web): fix login redirect flow
- Root +page.svelte: use authStore instead of data.session (always undefined)
  → after email verification auto-sign-in, redirects to /home not /login
- (auth)/+layout.svelte: remove racing $effect, keep only onMount redirect check
  → no more double goto() race condition after login
- login/+page.svelte: successRedirect /dashboard → /home (consistent with root)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 19:02:04 +02:00
Till JS
838b4c13de refactor(ui): apply elevation system across todo, contacts, calendar, clock apps
Replace all hardcoded hex/rgba colors with CSS custom properties throughout
the todo web app and fix modal backgrounds in contacts, calendar, and clock.
Removes all redundant :global(.dark) overrides — CSS vars handle both modes.

- todo: TaskEditModal, SubtaskList, TagStrip, TagStripModal, SyncIndicator
- todo: FokusLayout, GridLayout, KanbanLayout, ViewColumn (drop targets, add-column cards)
- todo: ViewSelector, ViewColumnHeader, ViewEditorModal, TodoToolbarContent
- todo: QuickAddTask, TagSelector, KanbanTaskCard, +layout (FAB)
- todo: DurationPicker, StorypointsSelector, FunRatingPicker, PrioritySelector
- contacts: NewContactModal background + remove Schnelleingabe quick input
- calendar: EventDetailModal, VoiceRecordingModal backgrounds
- clock: AuthGateModal background

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 19:00:24 +02:00
Till JS
e3355191d5 docs(auth): add Auth UX Patterns section with email verification rules
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 18:51:04 +02:00
Till JS
a6560a3227 fix(status-json): strip /health path before .mana.how suffix for correct service keys
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 18:49:18 +02:00
Till JS
bf49b95319 fix(clock-web): fix mangled import in stopwatch page
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 18:49:04 +02:00
Till JS
08032c004b feat(manascore): add live uptime badges from status.mana.how
- generate-status-page.sh now also writes status.json alongside index.html
  Format: { updated, summary: {up, total}, services: { appName: bool } }
- nginx status.mana.how serves status.json with CORS headers (public read)
  and explicit location block to avoid rewrite to index.html
- ManaScore index page fetches status.json client-side on load and
  injects green ● LIVE / red ● DOWN badge next to each app's status chip

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 18:47:55 +02:00
Till JS
259253e7b3 feat(auth): show resend verification panel when registering with existing unverified email
- auth.ts: catch USER_ALREADY_EXISTS and return EMAIL_ALREADY_REGISTERED (409)
- authService: map 409 with EMAIL_ALREADY_REGISTERED code to typed error
- RegisterPage: show amber warning panel + resend + go-to-login for existing emails
- translations: add emailAlreadyRegistered, emailAlreadyRegisteredMessage, goToLogin (en/de)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 18:44:01 +02:00
Till JS
c736dd52f2 docs: add Memoro backend Hono/Bun migration plan
Full migration plan for both NestJS services (backend + audio-backend)
to Hono/Bun, including endpoint inventory, auth pattern change
(Supabase RLS → service role), and phased implementation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 18:43:44 +02:00
Till JS
af33b1cead fix(cloudflared): sync config with actual container ports and add missing apps
- Fix ports: zitare 5018→5026, mukke 5180→5024, calc 5026→5031, element 4080→4010, playground 5090→5050
- Add missing routes: citycorners, inventar, times, uload, arcade, status, whopxl
- Comment out planta (container not deployed) and manavoxel (no port expose)
- Remove duplicate citycorners from landing pages block
- Reorder and document all services consistently

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 18:40:26 +02:00
Till JS
d23ef52839 fix(mana-auth): set callbackURL instead of redirectTo for email verification redirect
Better Auth uses callbackURL to determine the post-verification redirect target.
Setting only redirectTo left callbackURL=/ which resolved to auth.mana.how/ (404).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 18:34:56 +02:00
Till JS
8e1601076f fix(presi-web): export auth alias from auth store for existing imports
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 18:32:03 +02:00
Till JS
5871283d60 docs: add Mana Bundle Format plan
Cross-app data bundle format (.mana / .manapkg) for onboarding flows,
templates, and sequential content release. Implementation deferred.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 18:31:45 +02:00
Till JS
f79ad1773a refactor(todo): simplify to single Fokus view, remove Übersicht/Matrix tabs
- Remove Fokus/Übersicht/Matrix view tab group from PillNavigation
- Remove /kanban redirect and activeLayoutMode switching logic
- Hardcode layoutOverride to 'fokus' in +page.svelte
- Fix currentPath reference error after redirect block removal

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 18:29:24 +02:00
Till JS
fa8b2cdf0e feat(infra): migrate chat-web, clock-web, presi-web, nutriphi-web from GHCR to local builds
All 4 apps now use the same local build pattern as the other 33 apps.
Only umami (external project) keeps its GHCR image.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 18:28:31 +02:00
Till JS
58e03e7e26 docs: warn about dual cloudflared config (repo vs server file)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 18:22:59 +02:00
Till JS
5b11f4bd11 fix(uload-web): add health endpoint for Docker healthcheck
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 18:20:42 +02:00
Till JS
86c2abb00d fix(landings-nginx): mkdir snippets before copy, add status.mana.how vhost
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 18:17:22 +02:00
Till JS
cc242d9e00 fix(inventar-web): use browser error tracking import in hooks.client.ts
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 18:15:12 +02:00
Till JS
6801ba9fe8 fix(status-page): increase mem_limit to 64m for apk add
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 18:12:46 +02:00
Till JS
0500fb7a0a fix(prerender): suppress favicon.png 404 during prerender in skilltree and nutriphi
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 18:11:53 +02:00
Till JS
f4713ec831 fix(status-page): use host network so container reaches VictoriaMetrics on localhost:9090
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 18:11:30 +02:00
Till JS
bdf76cb24d fix(mana-auth): remove debug log, finalize EMAIL_NOT_VERIFIED detection
APIError.status is string 'FORBIDDEN', body.code is 'EMAIL_NOT_VERIFIED'.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 18:07:57 +02:00
Till JS
d044afec2f feat(status-page): add public status page at status.mana.how
- scripts/generate-status-page.sh: Shell-Script das VictoriaMetrics abfragt
  und eine statische HTML-Statusseite generiert (probe_success + response times)
- docker-compose.macmini.yml: mana-status-gen Container (Alpine, jq, curl)
  schreibt alle 60s nach /Volumes/ManaData/landings/status/
- docker/nginx/landings.conf: status.mana.how vHost mit Cache-Control: no-store
- cloudflared-config.yml: status.mana.how → localhost:4400

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 18:07:07 +02:00
Till JS
504f77a60c debug: log login error shape 2026-03-31 18:05:41 +02:00
Till JS
36922cc946 fix(mana-auth): robust email-not-verified detection
Better Auth throws APIError.from(FORBIDDEN, EMAIL_NOT_VERIFIED).
Check status 403, body.code, and lowercased message.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 18:01:24 +02:00
Till JS
38135ca8b9 fix(uload-web): add missing @tailwindcss/typography dependency
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 17:59:59 +02:00
Till JS
b1af506b99 fix(auth): surface email-not-verified error and detect needsVerification on signup
- mana-auth login route: catch Better Auth's email verification error and
  return 403 EMAIL_NOT_VERIFIED instead of 401 Invalid credentials
- shared-auth signUp: detect emailVerified:false in register response and
  return needsVerification:true so the UI shows the verification prompt
- shared-auth-ui LoginPage: map INVALID_CREDENTIALS error code to friendly message
- shared-i18n: add invalidCredentials translation (de/en)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 17:52:47 +02:00
Till JS
999c54a5a1 fix(todo): scrollable sheet body + subtasks animate complete with parent
FokusLayout:
- Wrap DnD zone, footer, and completed-today in .sheet-body
- .sheet-body is the scroll container (flex:1, overflow-y:auto)
- .sheet-content no longer manages scroll — allows scrolling to
  the "Heute erledigt" section below the main task list

KanbanTaskCard:
- Inline subtasks all appear as done (checked + strikethrough) during
  the parent's completing animation via isAnimatingComplete flag
- Subtask clicks blocked during animation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 17:50:22 +02:00
Till JS
23aa5e26ab fix(uload-web): add missing @tailwindcss/forms dependency
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 17:48:43 +02:00
Till JS
31d661cc61 docs(mac-mini): document uptime monitoring tools and Grafana dashboard
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 17:46:10 +02:00
Till JS
a22f1de6d0 feat(todo): complete animation + "Heute erledigt" section on focus pages
KanbanTaskCard:
- Checkbox click animates first (checkPop 300ms, fade to 50% opacity)
- After 500ms the actual onToggleComplete fires and task moves
- Modal cannot open during animation (pointer-events: none)

FokusLayout:
- Derives completedToday from tasks context (isCompleted + completedAt today)
- Shows "Heute erledigt" section at bottom of every sheet
- New items slide in from above (slideDown 350ms animation)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 17:45:22 +02:00
Till JS
402baf7c7f feat(monitoring): add uptime monitoring via Blackbox Exporter
- scripts/check-status.sh: parallel HTTP check aller mana.how Domains aus cloudflared-config.yml
- docker/blackbox/blackbox.yml: Blackbox Exporter Config (http_2xx, http_health Module)
- docker-compose.macmini.yml: blackbox-exporter Container (Port 9115, 32MB RAM)
- docker/prometheus/prometheus.yml: 4 Scrape-Jobs (blackbox-web, blackbox-api, blackbox-infra, blackbox-gpu)
- docker/prometheus/alerts.yml: 5 Alert-Regeln (WebAppDown, APIDown, InfraToolDown, GPUServiceDown, SlowHTTPResponse)
- docker/grafana/dashboards/uptime.json: Grafana Uptime-Dashboard mit Status-Tables und Verlauf
- package.json: check:status Script

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 17:43:25 +02:00
Till JS
bce533ca8b fix(uload-web): add missing svelte-i18n dependency
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 17:38:12 +02:00
Till JS
420bf07520 design(todo): wrap task and subtask titles instead of truncating
- Remove white-space: nowrap / overflow: hidden / text-overflow: ellipsis
- Titles wrap to multiple lines so all content is always readable
- align-items: flex-start on card and subtask rows so checkbox
  and priority dot stay aligned to the first text line (margin-top: 0.2rem)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 17:36:31 +02:00
Till JS
adfcc7dcee design(todo): paper-style task cards — no border/bg, text-proportional checkboxes
- Remove card border, background, shadow, backdrop-filter, border-radius
- Tasks render as plain text directly on the page background
- Priority dot: slim 3px left accent instead of round dot
- Main checkbox: 1.1rem circle matching title font size
- Title: 0.9375rem regular weight, uses CSS var for theme color
- Subtasks: same size as title (0.9375rem), same checkbox size
- Subtask indent calculated from priority-dot + gaps + checkbox width
- Vertical connecting line aligned to checkbox center

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 17:34:21 +02:00
Till JS
2a00310273 fix(todo): use \$state.snapshot() for subtask toggle to avoid DataCloneError
Svelte 5 \$state creates deep reactive Proxy objects. IndexedDB can't
serialize Proxies via structured clone algorithm. Using \$state.snapshot()
produces plain objects that IndexedDB can store.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 17:31:35 +02:00