Commit graph

2513 commits

Author SHA1 Message Date
Till JS
47d893794e chore: rename mukke to music in infra, scripts, and CI/CD
Update remaining mukke references in root package.json scripts,
docker-compose files, Grafana dashboards, Prometheus config,
CD pipeline, cloudflared config, deploy scripts, load tests,
and mana-auth user-data service.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 16:47:57 +02:00
Till JS
7afc1620aa feat(dashboard): update CalendarEventsWidget for timeBlocks, add i18n for day-timeline
- CalendarEventsWidget now shows all timeBlock types with type icons
  and live indicators (was only showing calendar events before)
- Added day_timeline i18n keys in all 5 languages (de/en/es/fr/it)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 15:28:54 +02:00
Till JS
d4700a07f9 feat: rename mukke to music, add cover art upload via mana-media
Rename the music module from "Mukke" to "Music" across the entire
codebase: API routes, web app module, shared packages, search provider,
dashboard widgets, i18n keys, app registry, and route paths.

Add POST /api/v1/music/cover/upload endpoint that uploads cover art
images through mana-media for deduplication, thumbnails, and Photos
gallery visibility.

Dexie table names (mukkePlaylists, mukkeProjects) kept unchanged to
preserve existing IndexedDB data.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 15:25:34 +02:00
Till JS
ee7ff7d5e8 feat(dashboard): add "Mein Tag" timeline widget using timeBlocks
Chronological day timeline showing all timeBlocks for today across all
modules (events, tasks, habits, time entries). Shows summary stats
(total time, counts per type), live indicators for running timers,
and habit icons. Links to calendar for full view.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 15:19:53 +02:00
Till JS
2502d6241d feat(calendar): type-specific styling, filter UI, cross-module navigation
- EventCard: visual differentiation per blockType (task=checkbox, habit=icon,
  timeEntry=striped+clock, focus=dashed, live=pulse animation)
- CalendarHeader: filter toggle with chips for event/task/habit/timeEntry types
- Calendar page: clicking external items navigates to source module

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 14:47:12 +02:00
Till JS
8c8b3f80da fix(calendar): remove duplicate calendarViewStore import in WeekView
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 14:40:41 +02:00
Till JS
0aa0d7b135 feat(manacore/web): unified time model — timeBlocks for all time data
Introduces a central `timeBlocks` table that owns the time dimension
(start, end, recurrence, live status) for all modules. Calendar, times,
habits, and todo modules keep only domain-specific data with a
timeBlockId reference. The calendar becomes a universal time view
showing events, tasks, habits, and time entries from all modules.

Key changes:
- New `$lib/data/time-blocks/` module (types, service, queries, collections)
- Dexie schema v3 with timeBlocks table + migration from existing data
- Calendar events store creates TimeBlock + LocalEvent pairs
- Times timer uses TimeBlock.isLive instead of LocalTimeEntry.isRunning
- Habits logHabit creates point-event TimeBlocks (with optional duration)
- Todo scheduled tasks create TimeBlock via scheduledBlockId
- Calendar views filter by blockType, show items from all modules
- All calendar views use getItemColor() for cross-module color support

Also includes mukke → music module rename.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 14:39:00 +02:00
Till JS
5fd9c1d11e fix(manacore/web): resolve effect_update_depth_exceeded and Dexie transaction errors
- Replace $effect + liveQuery().subscribe() with useLiveQueryWithDefault
  in 6 dashboard modules (todo, calendar, contacts, habits, notes, finance)
  to prevent cascading $state writes exceeding Svelte 5 effect depth limit
- Defer checkInlineSuggestion in Dexie hooks via setTimeout to avoid
  cross-table reads within a single-table transaction scope
- Add 5s timeout to trySSO fetch calls so app loads in guest mode when
  mana-auth is unreachable
- Fix guestMode reactivity by declaring with $state()

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 10:38:57 +02:00
Till JS
502813f49c feat(api): route all image uploads through mana-media for CAS, thumbnails & Photos gallery
Picture, Contacts, Planta, Storage, and NutriPhi image uploads now go
through mana-media instead of directly to S3. This enables SHA-256
deduplication, automatic thumbnail generation, EXIF extraction, and
makes all images visible in the Photos gallery. Non-image files (PDFs,
audio, docs) continue to use shared-storage directly. SVG avatars in
Contacts also stay on shared-storage since Sharp can't process SVGs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 10:38:30 +02:00
Till JS
46dae20fa3 feat(manacore/web): localize app names with i18n (5 languages)
Add `apps` locale namespace (de/en/fr/it/es) with localized display
names for all 29 app modules. Workbench card titles, app picker, and
overlay headers now resolve names via $_('apps.{id}') with fallback
to AppDescriptor.name.

Key renames (de): Todo→Aufgaben, Habits→Routinen, Notes→Notizen,
Finance→Finanzen, Places→Orte, Mukke→Musik, Context→Dokumente,
Times→Zeiten, Cards→Karten, Picture→Bilder, Photos→Fotos,
Storage→Ablage, Questions→Recherche, CityCorners→Stadtführer,
Calc→Rechner.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 21:39:31 +02:00
Till JS
8218037841 feat: add shared Phosphor IconPicker, migrate habits from emoji to icons, add photos upload
- Add curated icon registry (73 Phosphor icons, 8 categories) in shared-icons
- Add DynamicIcon atom and IconPicker molecule in shared-ui
- Migrate habits module from emoji strings to Phosphor icon names
- Add Dexie version(2) migration for emoji→icon field rename
- Replace inline SVGs in habits with Phosphor components
- Add drag-and-drop photo upload to Photos workbench ListView
- Add blob: to CSP img-src for upload previews
- Add dev:media script and include mana-media in dev:manacore:servers
- Add ./toast export to shared-ui package.json

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 21:37:01 +02:00
Till JS
ebfc2facaa fix(manacore/web): redesign automations ListView for better readability
- Card-based layout for each automation with clear visual hierarchy
- Colored flow chips (WENN=blue, FILTER=amber, DANN=green) replacing
  hard-to-read inline text
- Clearer step-based create form with badge labels per section
- Better suggestion cards with icon, accept/dismiss buttons
- Toggle switch, name, and flow on separate lines
- Delete button only visible on hover
- Consistent spacing and typography

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 21:22:28 +02:00
Till JS
2f87cf9d9a feat(manacore/web): add unified context menu system for workbench and app pages
Adds right-click context menus to workbench cards, minimized tabs, PillNavigation,
and item-level context menus for todo, calendar, contacts, habits, notes, places,
and moodlit modules. Uses a shared builder pattern with app-specific actions
registered via AppDescriptor.contextMenuActions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 21:18:05 +02:00
Till JS
2dd0812757 feat(manacore/web): proactive automation suggestions (discovery + inline)
Two suggestion systems for cross-module automations:

1. Discovery: Automations ListView shows suggestion cards when it
   detects name overlaps between modules (e.g. "Basketball" habit +
   calendar events containing "Basketball"). Accept or dismiss.

2. Inline: When creating an event/task whose title matches a habit name,
   a toast appears: "Log habit 'Basketball' automatically?" with
   one-click activation. Auto-dismisses after 8s.

Both use simple case-insensitive string matching (min 4 chars).
Dismissed suggestions are persisted in localStorage.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 21:00:23 +02:00
Till JS
0f38a567fe feat(manacore/web): add automations module with UI for trigger rules
New workbench module for creating and managing cross-module automations.
Users can configure rules like "when calendar event with title containing
'Basketball' is created, log habit 'Basketball'".

UI includes: source picker (app/collection/op), condition builder
(field/op/value), action picker with dynamic params (e.g. habit select
dropdown), toggle enable/disable, delete.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 20:44:20 +02:00
Till JS
ee03782fde feat(manacore/web): add cross-module trigger registry for automations
New trigger system that listens to Dexie write operations and fires
configurable actions in other modules. Automations are stored in
IndexedDB and loaded at app startup.

Example: calendar event "Basketball" created → habit "Basketball" logged.

Architecture: Dexie hooks → fire() → registry → condition check → action
Actions are async fire-and-forget with loop prevention.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 20:38:41 +02:00
Till JS
2241663823 docs: add Stalwart mail server documentation
Complete documentation for the self-hosted email infrastructure:
architecture, Stalwart config, DNS records, account management,
Fritz!Box port forwarding TODO, troubleshooting, and Brevo fallback.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 20:04:09 +02:00
Till JS
7797930ed4 fix(mana-notify): add Message-ID and Date headers to outgoing emails
Gmail rejects emails without a valid Message-ID header (RFC 5322).
Add Message-ID and Date headers to all outgoing emails.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 17:03:46 +02:00
Till JS
3b4dfb1bdf fix(docker): use noreply account with user role for Stalwart SMTP
Stalwart requires username without domain for auth and the 'user' role
for SMTP access. Update SMTP_USER from admin to noreply.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 16:59:45 +02:00
Till JS
7efe542dd1 chore: remove legacy migration and compat code (no users yet)
- traces: remove migrateLegacyLocationData() and legacy timestamp field
- context: remove legacy @[Title](ID) mention format support

No live users exist, so backwards compatibility is unnecessary.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 16:45:49 +02:00
Till JS
504a686e9b fix(docker): use Stalwart admin account for SMTP sending
The noreply account lacks SMTP auth permissions in Stalwart. Use the
admin account for now — SMTP_FROM still sends as noreply@mana.how.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 16:33:04 +02:00
Till JS
de910946dc chore(manacore): remove legacy per-app IndexedDB migration
No live users exist yet, so migrating from old per-app databases
(manacore-todo, manacore-calendar, etc.) to the unified DB is
unnecessary. Removes legacy-migration.ts and its invocation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 16:29:59 +02:00
Till JS
7ac4e09b04 fix(mana-notify): rewrite SMTP sender with LOGIN auth and better error logging
Go's smtp.PlainAuth refuses to send credentials when the hostname
doesn't match the TLS cert (internal Docker hostname 'stalwart' vs
cert CN 'localhost'). Replace with custom LOGIN auth that works with
any SMTP server. Add detailed error logging at each SMTP stage.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 16:27:26 +02:00
Till JS
f592464f61 fix(analytics): update Umami website ID after database reset
The Umami database was re-initialized with empty website table. Created
new ManaCore Web website in Umami and updated the ID in docker-compose
and .env.development. Fixes stats.mana.how 400 errors.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 16:23:09 +02:00
Till JS
6a75f3fca1 fix(workbench): make page width responsive on mobile
Pages now adapt to the available screen width on mobile (<640px) instead
of overflowing at the fixed 480px default. Resize handle remains functional.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 16:18:08 +02:00
Till JS
3714b3ae67 fix(mana-notify): support insecure TLS for internal SMTP (Stalwart)
Add SMTP_INSECURE_TLS env var to skip certificate verification for
internal Docker-network SMTP connections. Stalwart's self-signed cert
uses 'localhost' as CN which doesn't match the 'stalwart' hostname.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 16:17:57 +02:00
Till JS
d5b76bd646 feat(docker): connect mana-notify to Stalwart SMTP
Set SMTP defaults to use internal Stalwart server (stalwart:587) with
noreply@mana.how credentials. Add stalwart as dependency for mana-notify.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 16:08:33 +02:00
Till JS
4825aef262 feat(mana-auth): add /api/v1/settings endpoint for user settings sync
The unified web app calls auth.mana.how/api/v1/settings to sync theme,
nav, locale, and device settings — but the endpoint was missing, causing
404 errors in production. Implements all 7 CRUD routes against the
existing auth.user_settings table.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 16:06:11 +02:00
Till JS
f070d022c1 fix(docker): correct Stalwart port mapping and healthcheck
Map host 8443 to container 8080 (HTTP admin UI). Use wget for
healthcheck since curl is not available in the Stalwart image.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 15:23:16 +02:00
Till JS
ed78c345c6 fix(docker): correct Stalwart image name to stalwartlabs/stalwart
The old image name stalwartlabs/mail-server doesn't exist on Docker Hub.
The correct image is stalwartlabs/stalwart.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 15:21:55 +02:00
Till JS
0a6fe57a80 feat(infra): add Stalwart mail server, route mana-notify SMTP through it
Add self-hosted Stalwart mail server (Rust, ~50MB RAM) to replace Brevo
as SMTP provider. mana-notify now sends via stalwart:587 internally.

Ports exposed: 25 (SMTP), 587 (submission), 465 (SMTPS), 993 (IMAPS),
8443 (web admin). Requires DNS setup (MX, SPF, DKIM, DMARC) and router
port-forwarding to complete the migration.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 15:20:23 +02:00
Till JS
18d4f84718 fix(docker): add Brevo SMTP_USER default for mana-notify
SMTP_USER was empty because it wasn't in .env and had no default.
Add the Brevo account as default (was previously hardcoded in mana-auth).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 15:07:24 +02:00
Till JS
c7908e9f69 fix(infra): prevent race condition in status-page-gen script execution
Copy the volume-mounted generate.sh to /tmp before executing, so a
concurrent git pull doesn't corrupt the file mid-read.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 15:06:13 +02:00
Till JS
0bac7e127f fix(docker): align mana-notify service key with mana-auth
mana-notify was using NOTIFY_SERVICE_KEY (defaulting to dev-service-key)
while mana-auth sends MANA_CORE_SERVICE_KEY. Use the same env var so
mana-auth can authenticate with mana-notify.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 15:05:03 +02:00
Till JS
b2adaaa30e refactor(mana-auth): route emails through mana-notify instead of Nodemailer
Replace direct Brevo SMTP sending with HTTP calls to mana-notify's
notification API. This centralizes all email configuration in one
service (mana-notify) and removes the nodemailer dependency from
mana-auth. SMTP provider is now swappable via a single env var.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 15:01:27 +02:00
Till JS
62d9eb1f2b fix(infra): update status page, prometheus, and cloudflared for unified app
All web app subdomains (chat.mana.how, todo.mana.how, etc.) were removed
when the unified app launched, but monitoring configs still referenced them.
Update blackbox targets to use mana.how/route URLs, remove stale API backend
routes from cloudflared, clean up CORS origins, and fix status page generator
to handle route-based URLs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 14:59:15 +02:00
Till JS
543e7055b9 feat(manacore/web): add undo toasts to all 14 DetailViews + task completion
Extend undo toast coverage to all modules:
- Delete undo in cards, storage, presi, planta, inventar, skilltree,
  memoro, questions, uload, mukke, citycorners DetailViews
- Task completion toggle in todo ListView shows undo toast

All deletions can now be reversed within 5 seconds via "Rückgängig".

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 14:55:30 +02:00
Till JS
81716725f2 feat(manacore/web): add undo toasts for delete and tag removal
Extend toast system with action buttons and toastStore.undo() helper.
After deleting a task/event/contact or removing a tag, a toast with
"Rückgängig" button appears for 5 seconds. Clicking it restores the
item (clears deletedAt) or re-adds the tag.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 14:50:32 +02:00
Till JS
a673a69972 feat(manacore/web): add overlay close animation + Escape key support
- Overlay fades out + scales down on close (150ms) instead of vanishing
- Escape key closes overlay (pops cross-detail, or closes all)
- All close paths use closeAllOverlays() for consistent animation
- Overlay stays visible during closing animation via `closing` state

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 14:42:02 +02:00
Till JS
4e5709a033 fix(docker): add shared-logger to sveltekit-base Dockerfile
shared-hono depends on @manacore/shared-logger but it was missing from
the base image COPY list, causing pnpm install to fail.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 14:41:17 +02:00
Till JS
3fa7073597 fix(docker): remove stale clock/packages/shared COPY from mana-web Dockerfile
Clock was archived/consolidated into Times but the Dockerfile still
referenced its shared package, breaking the Docker build.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 14:36:11 +02:00
Till JS
8f5727fd51 feat(manacore/web): add places module with GPS location tracking
New local-first places module for the workbench: browser Geolocation API
tracking, place management (CRUD, favorites, tags, categories), OSM map
preview in detail view, and proximity-based visit detection.

Also allows geolocation in Permissions-Policy header (self only).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 14:33:56 +02:00
Till JS
e17d6228e4 fix(manacore/web): fix getTagsByIds missing allTags param in zitare, fix TagDragData cast
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 14:20:34 +02:00
Till JS
09eef96ed8 fix(manacore/web): align notes and finance ListViews with workbench design system
Match todo/calendar/contacts patterns: hardcoded colors with dark mode
overrides, consistent button styles (transparent bg, hover states),
same padding/spacing/border-radius as existing ListViews.

Buttons are now clearly recognizable: primary (purple bg), ghost
(transparent with hover), danger (red on hover), filter tabs
(active state with colored bg).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 14:08:01 +02:00
Till JS
b63829ae4c fix(manacore/web): redesign notes workbench — compact input, click-to-edit
Replace bulky compose area with single-line quick-create (Enter to save).
Notes are directly clickable and open as inline editors in-place with
title, content, pin/delete actions, and Escape/Fertig to close.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 14:04:24 +02:00
Till JS
4ec4694f8f fix(manacore/web): make notes and finance workbench panels directly usable
Notes: always-visible compose field at top (title + content), expands
on focus, Cmd+Enter to save. Note list below.

Finance: always-visible quick-add with type toggle, amount + description
inline, category chips. No hidden button — ready to use immediately.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 14:02:00 +02:00
Till JS
c01eccb852 refactor(manacore/web): merge entity + app registries into unified AppDescriptor
Replace the dual registry system (app-registry.ts + entities/) with a
single AppDescriptor that contains identity, views, and entity fields.

- Create $lib/app-registry/ with types.ts, registry.ts, apps.ts, index.ts
- Merge all 27 app entries + 3 entity descriptors into one registry
- Move ViewProps from nav-stack.ts into app-registry/types.ts
- Update all 39 consumer files (ListViews, DetailViews, AppPage, etc.)
- Delete old files: entities/, app-registry.ts, nav-stack.ts, entity.ts

Single source of truth: one AppDescriptor per module, one registry.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 14:01:27 +02:00
Till JS
9abbf9c70d feat(manacore/web): add notes and finance modules
Notes: lightweight markdown notes with search, color tags, pinning,
inline create, auto-save editor, and grid/detail views.

Finance: income/expense tracking with categories, monthly overview,
category breakdown bars, quick-add form, and transaction history.

Both modules include workbench ListView, full-page routes, entity
descriptors for drag/drop, and database/sync registration.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 13:57:37 +02:00
Till JS
a8480f6710 fix(ui): allow multiple detail views open across AppPages
Previously, clicking a detail view in one AppPage would close the
overlay in all other AppPages because the global click handler closed
on ANY click outside the overlay card.

Now the click handler only closes the overlay when the click is
inside the SAME AppPage but outside the overlay card. Clicks in
other AppPages are ignored, allowing multiple detail views to be
open simultaneously side by side.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 13:48:25 +02:00
Till JS
df74029423 fix(manacore/web): fix cross-module drop — sync entity registration, lazy store imports
Entity registration was async (dynamic imports) so acceptedDropTypes
was always empty when $derived first evaluated. Now entities register
synchronously at import time. Store imports (Dexie, etc.) are deferred
to createItem() call time to avoid circular dependencies.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 13:42:31 +02:00