Commit graph

1530 commits

Author SHA1 Message Date
Till JS
72ee82e516 docs(calendar): update complexity audit — all items resolved
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 21:11:55 +01:00
Till JS
3bace08b7a feat(calendar): add calendar sharing UI and service error boundaries
Calendar Sharing:
- Add shares store with full lifecycle (share, accept/decline, remove, permissions)
- Add missing API methods (getInvitations, getSharedWithMe)
- Create /settings/sharing page with:
  - Pending invitations section with accept/decline
  - "Shared with me" section
  - Per-calendar share management (expandable list, add/remove shares)
  - Share modal with email, permission selection
- Add link from main settings page

Error Boundaries:
- Create ServiceStatusBanner component for graceful degradation
- Integrate into main calendar page for Todo and Birthday services
- Shows warning when service unavailable with retry button
- Uses existing serviceAvailable flags from stores

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 21:11:15 +01:00
Till JS
9df908d838 refactor(calendar): simplify UnifiedBar and extract ViewCarousel gestures
UnifiedBar (633→559 LOC):
- Remove 3 duplicate DateStrip blocks (4→1) and 1 duplicate TagStrip block (2→1)
- Remove deprecated createEventDispatcher (Svelte 4→5)
- Remove unused component imports (DateStrip, TagStrip, CalendarToolbar, DateStripFab)

ViewCarousel (402→162 LOC, -60%):
- Extract all gesture handling (touch, wheel, velocity, snap, animation,
  chain navigation) into useSwipeNavigation composable (260 LOC)
- ViewCarousel now only handles layout, date calculation, and view rendering
- Composable is reusable for any carousel/swipe navigation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 21:04:25 +01:00
Till JS
e57b64590d fix(picture): add missing PUBLIC_GOOGLE/APPLE_CLIENT_ID build args to Dockerfile
SvelteKit $env/static/public requires these vars at build time even if empty.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 20:59:34 +01:00
Till JS
e64c298cec refactor(auth,planta): optimize storage usage
mana-core-auth:
- Replace manual key generation (Date.now) with generateUserFileKey()
- Replace manual validateFileSize with maxSizeBytes in upload()
- Remove OnModuleInit — init storage directly in constructor
- Add upload hooks for structured logging
- Remove redundant getPublicUrl() fallback chain (presigned URL for 1 year)
- Add deleteAllUserAvatars() for account deletion
- Simplify getAvatarUploadUrl() using storage.getPublicUrl()

planta:
- Replace createStorageClient() with manual config by createPlantaStorage()
- Replace manual uuid + path construction with generateUserFileKey()
- Remove uuid dependency for key generation
- Add maxSizeBytes validation (20MB)
- Add cacheControl header (immutable, 1 year)
- Add upload hooks for structured logging
- Add error handling in deletePhoto()
- Add deleteAllUserPhotos() for account deletion
- Make getPhotoUrl() synchronous (was async unnecessarily)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 20:59:14 +01:00
Till JS
6476521fd1 fix(picture): add patches directory to web Dockerfile
pnpm install fails without the patches/ directory since pnpm-lock.yaml
references patch files.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 20:57:38 +01:00
Till JS
e5ba591680 refactor(storage): optimize cloud drive storage service
- Replace manual validateFileSize() with maxSizeBytes in upload()
- Add upload hooks for structured logging
- Add deleteFiles() for bulk deletion via deleteMany()
- Add deleteAllUserFiles() for account deletion via deleteByPrefix()
- Remove unused validateFileSize import

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 20:57:18 +01:00
Till JS
69eac206fa refactor(picture): optimize storage service
- Replace manual key generation (Date.now + Math.random) with
  generateUserFileKey() for UUID-based collision-free keys
- Add maxSizeBytes validation (50MB images, 5MB thumbnails)
- Add cacheControl headers (immutable for images, 7d for thumbnails)
- Add upload hooks for structured logging
- Simplify constructor (remove OnModuleInit, init storage directly)
- Remove unused StorageMode type and getStorageMode()
- Add deleteAllUserFiles() for account deletion
- Consistent error handling in deleteFile() (warn + swallow)
- Board thumbnails use stable path (no timestamp) for overwrite

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 20:56:44 +01:00
Till JS
887b60c8c1 fix(picture): fix health endpoint and port consistency for Docker deployment
Exclude /health from global prefix so healthchecks hit /health instead of
/api/v1/health. Update Dockerfile EXPOSE and healthcheck to use port 3040
matching docker-compose config.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 20:54:27 +01:00
Till JS
15cde622e4 refactor(mukke): optimize storage usage in song and beat services
SongService:
- Use deleteMany() for batch deletion of audio + cover (was sequential)
- Add maxSizeBytes validation on cover art (10MB) and tag writing (500MB)
- Add cacheControl header on cover art uploads (immutable, 1 year)
- Add upload hooks for structured logging
- Use 'songs' subfolder for audio, 'covers' for cover art (was flat)
- Add deleteAllUserFiles() for account deletion via deleteByPrefix()
- Log storage errors instead of silently swallowing

BeatService:
- Add upload:error hook for structured logging
- Use 'beats' subfolder for organized key structure
- Log storage deletion errors instead of swallowing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 20:53:23 +01:00
Till JS
56c3086ec6 test(calendar): add reminders API client tests
- 4 tests: getReminders (success + error), createReminder with body
  validation, deleteReminder endpoint
- All 120 tests passing across 13 test files

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 20:52:23 +01:00
Till JS
b38e5aecf9 fix(contacts): clean up orphaned photos on duplicate merge
DuplicatesService.mergeContacts() now deletes S3 photos of merged
contacts before removing them from the DB. Photos that were adopted
by the primary contact (via mergeContactData) are preserved.

- Import PhotoModule in DuplicatesModule
- Inject PhotoService into DuplicatesService
- Add photo cleanup loop before DB deletion
- Update test mock

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 20:50:44 +01:00
Till JS
3ac976f600 feat(picture): migrate web app from Netlify to Docker/Mac Mini deployment
Switch from adapter-netlify to adapter-node for self-hosted Docker deployment.
Add missing Button and Card UI components, remove Netlify config files,
and add picture-backend + picture-web services to docker-compose and
Cloudflare tunnel routing (picture.mana.how).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 20:50:12 +01:00
Till JS
1ffcfa0e5c docs(calendar): mark reminders as implemented in complexity audit
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 20:48:44 +01:00
Till JS
6806ef8bde feat(calendar): add reminder UI for creating and managing event reminders
- Create ReminderSelector component with two modes:
  - Draft mode (new events): configure reminders before save with preset
    dropdown, push/email toggles, add/remove multiple reminders
  - Saved mode (existing events): view reminders with status (pending/sent/
    failed), add via preset dropdown, delete individual reminders
- Integrate into EventForm: default reminder pre-configured from settings,
  drafts passed to parent via onSave callback for creation after event save
- Integrate into EventDetailModal: load and display reminders for existing
  events, add/remove reminders directly via API, auto-refresh on change
- German UI labels for all reminder presets (Zum Zeitpunkt, 5/10/15/30 Min.,
  1/2 Stunden, 1/2 Tage, 1 Woche vorher)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 20:48:26 +01:00
Till JS
ecec3d56fe fix(contacts): optimize storage usage and fix photo orphan bug
Bug fix:
- ContactService.delete() now cleans up S3 photo before DB deletion
  (previously left orphaned files in storage)
- ContactModule imports PhotoModule for dependency injection

PhotoService improvements:
- Use maxSizeBytes in upload() instead of manual validateFileSize()
- Use getPublicUrl()/result.url instead of manual URL construction
  via getStorageConfig() + BUCKETS concatenation
- Add cacheControl header for immutable photo assets (1 year)
- Add upload hooks for structured logging via Logger
- Add deletePhotoByUrl() for contact deletion cleanup
- Add deleteAllUserPhotos() for account deletion via deleteByPrefix()
- Store photos in 'photos' subfolder for cleaner key structure
- Remove unused getStorageConfig/BUCKETS imports

Test fix:
- Add PhotoService mock to ContactService spec

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 20:01:43 +01:00
Till JS
d9ccb5e31b feat(games): add whopixels hosting at whopxl.mana.how
Dockerfile, docker-compose service (port 5100), Caddy and cloudflared
routing for the WhoPixels game. PORT is now configurable via env var.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 19:57:50 +01:00
Till JS
2eb280cc07 test(calendar): add composable unit tests and WeekView E2E interaction tests
Unit tests (vitest):
- useEventDragDrop.test.ts: 7 tests (idle state, drag start, resize start,
  cancel, hasMoved reset, getResizePreviewTime, preview positions)
- useTaskDragDrop.test.ts: 5 tests (idle state, drag start, resize start,
  cancel, preview position calculation)
- useDragToCreate.test.ts: 4 tests (idle state, guard when other op active,
  cancel, preview time format)

E2E tests (playwright):
- week-view-interactions.spec.ts: 7 tests covering drag-to-create (click,
  drag with time range, escape cancel), event card positioning, current time
  indicator, day headers, and today highlighting

All 116 unit tests passing across 12 test files.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 19:51:23 +01:00
Till JS
5832326010 docs(storage): update README with complete API documentation
Cover all features added in recent commits: hooks, metrics,
Prometheus collector, presigned multipart, move, copy,
deleteByPrefix, getMetadata, stream size validation, CDN URLs.
Update bucket table to match current state.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 19:49:16 +01:00
Till JS
8511c2ca4c feat(cd): add Matrix notification on deploy failure
Sends a message to a Matrix room when a deploy fails, including
the failing services, commit, deployer, and a link to the logs.

Requires two GitHub Actions secrets:
- DEPLOY_NOTIFY_ROOM_ID: Matrix room ID
- DEPLOY_NOTIFY_BOT_TOKEN: Matrix bot access token

Skips silently if secrets are not configured.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 19:47:53 +01:00
Till JS
8c2aa261e8 perf(auth): replace bcrypt with bcryptjs (pure JS, no native build tools)
- Switch from bcrypt (native C++ addon) to bcryptjs (pure JavaScript)
- Remove python3/make/g++ build tools from Dockerfile builder stage
- bcryptjs is 100% hash-compatible with bcrypt
- Smaller builder image and faster Docker builds

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 19:46:16 +01:00
Till JS
aeabdcaf8e refactor(calendar): extract WeekView inline logic into composables (1600→903 LOC)
Replace 697 lines of inline drag/drop/resize/create/keyboard handlers
in WeekView.svelte with existing composables:

- useEventDragDrop: event drag & resize (was ~220 LOC inline)
- useTaskDragDrop: task drag & resize (was ~180 LOC inline)
- useSidebarDrop: sidebar task drop (was ~70 LOC inline)
- useDragToCreate: new composable for click-drag event creation (was ~105 LOC)
- useCalendarKeyboard: Escape key cancel (was ~50 LOC inline)

Also adds getResizePreviewTime() to useEventDragDrop return value
so WeekView doesn't need access to internal resize state.

WeekView.svelte: 1600 → 903 lines (-44%)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 19:43:19 +01:00
Till JS
70671e2b2b perf(docker): prune devDeps and cleanup node_modules in all backend Dockerfiles
Add pnpm prune --prod and remove .ts/.map/test/docs files from
node_modules in the builder stage for chat, todo, calendar, clock,
and contacts backends. Same approach as mana-core-auth optimization.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 19:42:01 +01:00
Till JS
152fa5fe08 feat(storage): add deleteByPrefix, copy, getMetadata and prod lifecycle rules
- Add deleteByPrefix(prefix) for bulk user data deletion (account cleanup)
- Add copy(sourceKey, destKey) via CopyObjectCommand for file duplication
- Add getMetadata(key) via HeadObjectCommand for content-type/size/metadata
- Add FileMetadata type for structured metadata responses
- Add minio-init container to docker-compose.macmini.yml with bucket creation,
  public access policies, and lifecycle rules (matching dev compose)
- 96 tests passing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 19:40:17 +01:00
Till JS
b0e5a9c5ff feat(storage): add upload hooks, metrics integration, and presigned multipart
Upload hooks:
- StorageHooks class with fire-and-forget event emitter pattern
- Events: upload, upload:error, delete, delete:error, download
- All StorageClient operations now emit appropriate events
- Unsubscribe functions for cleanup

Metrics:
- StorageMetricsCollector interface (decoupled from prom-client)
- InMemoryMetrics for testing and local dev
- attachMetrics() wires hooks to any collector automatically
- Backends can create a Prometheus collector via MetricsService

Presigned multipart upload (browser direct-upload):
- createMultipartUpload() initiates and returns uploadId
- getMultipartUploadUrls() generates presigned PUT URLs per part
- completeMultipartUpload() finalizes with part ETags
- abortMultipartUpload() for cleanup on abandoned uploads

90 tests passing across 5 test files.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 19:36:46 +01:00
Till JS
822e75368a feat(shared): add DevBuildBadge component and getBuildDefines() helper
- shared-vite-config: getBuildDefines() injects __BUILD_HASH__ and
  __BUILD_TIME__ as compile-time constants via Vite define
- shared-ui: DevBuildBadge component shows git hash + build timestamp
  in a small fixed badge at bottom-right (click to expand)
- Integrated into mukke-web for deployment verification

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 19:34:21 +01:00
Till JS
511b51e372 test(calendar): add tests for CalDAV sync API, external calendars store, and recurrence
- sync.test.ts: 8 tests for API client (CRUD, sync, discovery, OAuth, export URL)
- external-calendars.test.ts: 8 tests for store (fetch, connect, disconnect,
  update, triggerSync success/error, getById)
- events-recurrence.test.ts: 9 tests for recurrence expansion (daily, weekly,
  exceptions, non-recurring passthrough, helpers, delete occurrence/series)

All 100 tests passing across 9 test files.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 19:31:34 +01:00
Till JS
01c4d3a9d1 feat(storage): cleanup buckets, add file-size validation and bulk delete
- Remove archived LIGHTWRITE and NUTRIPHI from BUCKETS
- Add missing PLANTA and PROJECTDOC buckets (were in Docker init but not in code)
- Add maxSizeBytes option to upload() and uploadMultipart() for size enforcement
- Add deleteMany() with automatic batching (1000 keys per S3 request)
- Add factories for createPlantaStorage() and createProjectDocStorage()
- Update tests (62 passing)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 19:27:42 +01:00
Till JS
720602343e fix(shared-auth): set SSO session cookie on login
The signIn() method only called the custom /api/v1/auth/login endpoint
which returns JWT tokens but doesn't set a session cookie. Without the
cookie, cross-subdomain SSO (trySSO) can never find an active session.

Now also calls Better Auth's native /api/auth/sign-in/email with
credentials:'include' after successful login, which sets the session
cookie with Domain=.mana.how for cross-subdomain SSO.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 19:27:33 +01:00
Till JS
5c9e16f634 fix(calendar): integrate recurrence dialog and external calendars into UI
- Wire RecurrenceEditDialog into EventDetailModal and QuickEventOverlay
  so deleting recurring events shows "this/all/future" options
- Add external calendars section to CalendarSidebar with visibility
  toggle and sync error indicator
- Update COMPLEXITY_AUDIT.md to mark sync and recurrence as implemented

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 19:22:28 +01:00
Till JS
eb859c18bc fix(auth): use SameSite=None for cross-subdomain SSO
SameSite=Lax only sends cookies on top-level navigations (link clicks),
not on programmatic fetch() requests. SSO relies on fetch() with
credentials:'include' from app subdomains to auth.mana.how, so
SameSite=None is required when COOKIE_DOMAIN is set.

Falls back to Lax for local development (no COOKIE_DOMAIN).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 18:55:34 +01:00
Till JS
985872330f perf(auth): optimize Dockerfile from ~740MB to ~320MB
- Use --chown on COPY instead of chown -R (eliminates duplicate layer)
- Remove corepack from production stage (not needed at runtime)
- Prune devDependencies and clean up test/docs/sourcemaps from node_modules
- Tested: container starts and passes health check

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 18:55:24 +01:00
Till JS
41fbd2f035 feat(storage): improve shared-storage robustness, scalability, and DX
- Fix exists() to only catch 404/NotFound, rethrow real errors
- Add downloadStream() for memory-efficient large file downloads
- Add uploadMultipart() using @aws-sdk/lib-storage for large files
- Add automatic pagination to list() via continuation tokens
- Add CDN URL support (cdnUrl in BucketConfig, getCdnUrl() method)
- Reduce factory boilerplate with generic createStorage() function
- Add MinIO lifecycle rules for tmp/ prefixes (chat 90d, calendar 30d, picture 7d)
- Add vitest setup with 56 tests covering client, factory, and utils

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 18:52:34 +01:00
Till JS
ab42c265e1 feat(calendar): add CalDAV/iCal sync UI and recurring events support
CalDAV/iCal Sync:
- Add sync API client (lib/api/sync.ts) for all external calendar endpoints
- Add external calendars store with connect, disconnect, sync operations
- Add /settings/sync page with provider selection (Google, CalDAV, iCal URL, Apple),
  credentials form, CalDAV discovery, sync status display, and manual sync trigger
- Add link to sync settings from main settings page

Recurring Events:
- Add RecurrenceSelector component with preset selection (daily, weekly, monthly,
  yearly, weekdays) and custom configuration (interval, weekday picker, end date)
- Integrate RecurrenceSelector into EventForm between date fields and location
- Expand recurring events into individual occurrences in events store using
  generateOccurrences() from @calendar/shared
- Add recurrence-aware delete: single occurrence (exception), all occurrences,
  or series update via dedicated store methods
- Add RecurrenceEditDialog component for "this/all/this and future" selection

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 18:46:33 +01:00
Till JS
43a2226290 perf(auth): optimize Dockerfile from ~740MB to ~350MB
- Add pnpm prune --prod to remove devDependencies from node_modules
- Use --chown on COPY instead of chown -R (eliminates 1.6GB duplicate layer)
- Remove corepack from production stage (not needed at runtime)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 17:41:05 +01:00
Till JS
1057d6952f ci(cd): add mukke-backend and mukke-web to CD pipeline
Mukke was missing from the automated deployment pipeline, so changes
to the web app were not being deployed to the Mac Mini server.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 17:39:49 +01:00
Till JS
42fe39c6a2 fix(infra): fix deploy tracking dashboard datasource UIDs and instant queries
- Add explicit uid: deploy-tracking to datasource provisioning
- Add instant: true to all Prometheus stat/gauge panel queries
- Pushgateway gauges need instant queries, not range queries

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 17:35:41 +01:00
Till JS
d3a3bc7b77 refactor(calendar): remove tag groups hierarchy and legacy drag-drop composables
Remove unnecessary complexity from the calendar web app:

- Remove tag groups system entirely (store, API client, route, components)
  Tags are now a flat alphabetically-sorted list instead of grouped hierarchy
- Remove unused legacy composables (useDragDrop, useResize) that were never
  imported by any component — useEventDragDrop already consolidates both
- Simplify TagStripModal from 1,452 to ~350 LOC by removing group CRUD,
  drag-drop between groups, and group hierarchy rendering
- Add complexity audit report documenting remaining issues

Total: -2,170 LOC across 13 files

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 17:33:57 +01:00
Till JS
e7fb2074b4 fix(docker): add cross-app CORS origins to todo-backend
calendar.mana.how and contacts.mana.how need to call todo-api.mana.how
for cross-app task integration.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 17:30:45 +01:00
Till JS
e124869f6e fix(infra): make deploy tracking Bash 3.x compatible (macOS runner)
- Remove set -euo pipefail from sourced library (breaks caller error handling)
- Replace declare -A associative arrays with string-based lookups
- macOS ships Bash 3.2 which doesn't support declare -A

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 17:27:31 +01:00
Till JS
70b1c4429d test(mukke): add vitest setup and 34 frontend tests for player & library stores
- Set up vitest with jsdom, testing-library/svelte, and SvelteKit mocks
- Player store: 16 tests covering playSong, queue, shuffle, repeat,
  volume, error handling, clearQueue, removeFromQueue
- Library store: 18 tests covering loadSongs, loadCoverUrls (including
  non-image path filtering), albums, artists, genres, stats, favorites,
  tabs, upload, and delete

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 17:16:47 +01:00
Till JS
67326b738a fix(shared-api-client): add useRuntimeUrl flag for cross-app clients
getBaseUrl() always overrides baseUrl with window.__PUBLIC_BACKEND_URL__,
which breaks cross-app API clients (e.g. calendar→todo, calendar→contacts)
by routing all requests to the host app's backend.

Added useRuntimeUrl: false option to skip the runtime override when
the client already resolves its own base URL.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 17:11:31 +01:00
Till JS
dea632c6c7 fix(caddy): update all reverse proxy ports to match docker containers
Many Caddy ports were outdated and pointing to dead services:
- mana.how: 5173→5000
- chat: 3000→5010, chat-api: 3002→3030
- todo: 5188→5011
- calendar: 5186→5012, calendar-api: 3016→3032
- clock: 5187→5013, clock-api: 3017→3033
- contacts: 5184→5014
- grafana: 3100→8000, stats: 3200→8010

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 17:09:09 +01:00
Till JS
3f91c4656a feat(infra): add deploy tracking with PostgreSQL, Pushgateway & Grafana dashboard
Instrument the CD pipeline to record per-deploy and per-service metrics
(build time, image size, startup time, health status) into PostgreSQL and
push gauges to Pushgateway. Adds a Grafana dashboard with 13 panels covering
deploy frequency, build performance, service health, and history.

New files:
- scripts/mac-mini/init-deploy-tracking.sql (idempotent DDL)
- scripts/deploy-metrics.sh (bash library for CI)
- docker/grafana/provisioning/datasources/deploy-tracking.yml
- docker/grafana/dashboards/deploy-tracking.json

Modified:
- docker/prometheus/prometheus.yml (pushgateway scrape job)
- .github/workflows/cd-macmini.yml (build/health instrumentation)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 17:08:03 +01:00
Till JS
a5940abfc2 feat(mukke): clickable songs in library, player error handling & cover fallbacks
- Songs in library are now clickable to play (with full queue support)
- Active song highlighted with primary color and play/pause overlay on cover
- Player store: error state, audio error listener, auto-skip on failure
- MiniPlayer: error toast bar with dismiss button
- Library store: filter non-image paths from cover URL loading
- Cover images: onerror fallback to icon when S3 file is missing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 17:05:07 +01:00
Till JS
26d8eb0898 fix(calendar): add shared-app-onboarding to web Dockerfile
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 16:45:55 +01:00
Till JS
93e1c7de4a refactor(calendar): simplify settings from 41 to 18 persisted preferences
Remove unused header/dateStrip settings (hardcode defaults), move runtime
UI state (sidebar, tags, immersive mode) to non-persisted $state() variables,
and add localStorage migration for existing users.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 16:40:47 +01:00
Till JS
98d1d1cc90 fix(calendar): add shared-pwa package to web Dockerfile
vite.config.ts imports @manacore/shared-pwa for PWA config.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 16:40:24 +01:00
Till JS
58bdf984bc fix(calendar): add patches dir to web Dockerfile
pnpm install fails without the patches directory since the lockfile
references react-native-reanimated patch.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 16:38:47 +01:00
Till JS
a1836407b1 refactor(docker): switch calendar-web to local build
Stale GHCR image didn't include cross-app URL injection for todo/contacts
backends, causing all task/birthday requests to hit calendar-api instead.

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