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>
- 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>
- 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>
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>
- 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>
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>
- 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>
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>
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>
- 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>
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>
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>
- 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>
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>
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>
74 commits covering cross-app SSO fix, audit logging service,
account lockout, API key rate limiting, GlitchTip integration
for all 15 backends, and production readiness audits for all 20 apps.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add 7 database indexes on all query paths (userId, deckId, order, themeId)
- Add timestamps with timezone for all tables
- Enable Swagger/OpenAPI documentation at /api/docs
- Add ApiTags and ApiBearerAuth to all controllers
- Add ParseUUIDPipe on all ID parameters
- Harden DTO validation: string length limits, @IsIn for enums,
@IsUrl for URLs, @ArrayMaxSize for arrays, @Min(0) for order fields
- Update audit to reflect improvements
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace GHCR images with local Docker builds for consistency.
All 13 deployed backends now use the same build pattern:
build: context: . / dockerfile: apps/*/apps/backend/Dockerfile
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add 10 test files covering all 5 services and 5 controllers
- Add global ThrottlerGuard (100 req/min) via APP_GUARD
- Add SvelteKit +error.svelte error boundary
- Add Jest config and test dependencies
- Update audit to reflect improvements
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. SecurityEventsService: Centralized audit logging for all auth events
(login, register, logout, password changes, API key operations, SSO
token exchange, etc.). Fire-and-forget pattern ensures auth flows
are never blocked by logging failures.
2. AccountLockoutService: Locks accounts after 5 failed login attempts
within 15 minutes. 30-minute lockout duration. Fails open on DB
errors. Clears attempts on successful login. Email-not-verified
does not count as a failed attempt.
3. API Key validation endpoint secured with rate limiting (10 req/min
per IP via ThrottlerGuard) and audit logging. Key prefixes logged
for forensics, never full keys.
New schema: auth.login_attempts table for tracking failed logins.
174 tests passing across all auth and security modules.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add import './instrument' to 15 remaining backend main.ts files
- Add GLITCHTIP_DSN to 10 additional backends in docker-compose.macmini.yml
- Total: 13/13 deployed backends have DSNs configured
- Total: 18/18 backends have instrument.ts + import
Backends with live error tracking after next rebuild:
chat, todo, calendar, clock, contacts, storage, presi, nutriphi,
skilltree, photos, zitare, mukke, planta
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adding a new app to cross-app SSO requires updating trustedOrigins,
CORS_ORIGINS, and running SSO contract tests. Documented in both
root CLAUDE.md and mana-core-auth CLAUDE.md to prevent future regressions.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add Quick Access section to MONITORING.md with all public URLs
- Add Umami public share links for all 15 web apps
- Add Grafana dashboard list
- Update ERROR_TRACKING.md with guest + admin credentials
- All tools publicly accessible (Grafana: anonymous, Umami: share links,
GlitchTip: guest account)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Enable share_id on all 15 Umami websites. Link directly to the ManaCore
dashboard share URL - no login required.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Several apps (mukke, photos, planta, questions, todo, traces, context,
docs, manadeck, zitare) were missing from Better Auth's trustedOrigins,
causing SSO session cookie exchange to fail for those apps. Also synced
CORS_ORIGINS in docker-compose.macmini.yml.
Added 47 SSO contract tests to prevent regressions.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add PostgreSQL datasource pointing to GlitchTip database
- Add Error Tracking dashboard with 7 panels:
- Total Open Issues (stat)
- Issues by Project (pie chart)
- Total Events (stat)
- Projects Tracked (stat)
- Resolved vs Unresolved (stat)
- New Issues Over Time (stacked bar chart, 30 days)
- Recent Issues (table with 50 latest, color-coded levels)
- Dashboard links to GlitchTip UI for detailed investigation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Added 9 missing icons to PillNavigation phosphorIcons map: music-notes,
playlist, waveform, file-text, sparkle, sparkles, share, trash, filter.
These were previously rendering as empty SVGs due to missing mappings.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Shows GlitchTip (error tracking), Grafana (metrics), and Umami (analytics)
links with guest login credentials directly on the audits page.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Feedback is now a sub-item under the Konto (user) dropdown in PillNavigation
instead of a standalone pill in the nav bar. Added feedbackHref prop to
PillNavigation (defaults to /feedback) and removed feedback from nav items
in all 11 apps and shared app-routes config.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add batch cover-url endpoint (POST /library/cover-urls) to efficiently
resolve multiple cover art presigned URLs in a single request. Integrate
cover art display across all UI surfaces: album grid, album detail header,
song list thumbnails, playlist grid, and playlist detail song list.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
GlitchTip is publicly accessible like other monitoring tools (Grafana, Umami).
No login restriction needed for internal dev tooling.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Create instrument.ts for: chat, clock, context, manadeck, mukke,
nutriphi, photos, picture, planta, presi, questions, skilltree,
storage, traces, zitare
- Add import './instrument' as first line in all main.ts files
- Add @manacore/shared-error-tracking dependency to all package.json files
- Create 10 new GlitchTip projects (mukke→18, total: 18 projects)
- All 18 backends now have error tracking (active when GLITCHTIP_DSN is set)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Uses shared components: ThemePage from shared-theme-ui, SettingsPage/
SettingsSection/SettingsCard/SettingsRow from shared-ui, FeedbackPage
from shared-feedback-ui. Adds feedback and help nav items.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Assign version numbers based on app maturity: Calendar/Contacts/Todo (1.0.0),
Chat/Picture (0.3.0), 11 beta apps (0.2.0), Context/Planta/Questions (0.1.0),
Traces (0.0.1). Set up @changesets/cli for future version management.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sentry SDK v9 rejects UUID-formatted keys with hyphens. Use the compact
hex format returned by GlitchTip's get_dsn() method.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>