Replace local MetricsService implementations with @manacore/shared-nestjs-metrics:
- chat, calendar, todo, clock, contacts, skilltree
Removes ~350 LOC of duplicated metrics code:
- Delete local metrics directories (service, module, controller)
- Remove manual metrics middleware from main.ts
- Use MetricsModule.register({ prefix: 'app_' }) pattern
Part of consolidation effort - see docs/CONSOLIDATION_OPPORTUNITIES.md
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Extract setupGlobalErrorHandler() utility from contacts app and add to
@manacore/shared-ui. Migrate 7 apps to use the shared implementation:
calendar, chat, clock, contacts, matrix, picture, storage.
Features:
- Catches unhandled promise rejections with error classification
- Handles offline/online network status changes
- Built-in i18n (DE + EN) with customizable translations
- Optional onAuthError callback for redirect handling
- Returns cleanup function for proper unmounting
- Create shared AuthGateModal component in @manacore/shared-auth-ui
- Migrate 4 apps to use shared component: chat, todo, contacts, calendar
- Remove duplicate local AuthGateModal components
- Support for 'save', 'sync', 'feature', 'ai' actions
- Built-in i18n (DE + EN) with custom translation support
- Optional migration info display for session data
- Uses Phosphor icons from @manacore/shared-icons
- Update CONSISTENCY_REPORT.md
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add ability to resend verification email when login fails with
"Email not verified" error. Implemented across all 14 apps using
Mana Core Auth.
Changes:
- Add POST /api/v1/auth/resend-verification endpoint to mana-core-auth
- Add resendVerificationEmail method to shared-auth client
- Update LoginPage component with resend UI and translations
- Add resendVerificationEmail to all app auth stores
- Add translations for de, en, fr, es, it
- Add PlantaLogo to shared-branding
- Migrate planta login to shared LoginPage component
Update all 15 web apps to consistent dependency versions:
- @sveltejs/kit: ^2.47.1 (was mixed ^2.0.0 to ^2.47.1)
- svelte: ^5.41.0 (was mixed ^5.0.0 to ^5.41.0)
- svelte-check: ^4.3.3 (was mixed ^4.0.0 to ^4.3.3)
- typescript: ^5.9.3 (was mixed ^5.0.0 to ^5.9.3)
Benefits:
- Consistent type checking behavior across apps
- All apps benefit from latest Svelte 5 features
- Easier maintenance with unified versions
Migrate 4 web apps from @tailwindcss/postcss to @tailwindcss/vite:
- chat
- manadeck
- manacore
- presi
Changes per app:
- Replace @tailwindcss/postcss with @tailwindcss/vite in package.json
- Add tailwindcss() to vite.config.ts plugins array
- Delete postcss.config.js (no longer needed)
Benefits:
- Faster builds with native Vite integration
- Consistent build pipeline across all 14 web apps
- Simplified configuration (no separate PostCSS config)
- Add dev credentials pre-fill on login page (dev@manacore.local)
- Add initialPassword prop to LoginPage component
- Add seed script for dev user (pnpm db:seed:dev in mana-core-auth)
- Add OLLAMA_URL to .env.development for Mac Mini connection
Add /compare route to test prompts against multiple Ollama models:
- CompareInput: prompt textarea with temperature/max tokens controls
- ModelResponseCard: displays response with status, metrics, markdown
- ModelResponseGrid: responsive grid layout for side-by-side comparison
- CompareProgress: progress bar with cancel functionality
- Svelte 5 runes-based store for state management
- Add Scales icon to shared-ui navigation
Add a unified welcome modal for guest mode that displays:
- App icon, name, and description from shared-branding
- Feature list of what guests can do (localized DE/EN)
- Warning about local-only data storage
- Login, Register, Help, and "Continue as Guest" buttons
New files:
- GuestWelcomeModal.svelte - The modal component
- guestWelcome.ts - localStorage utilities for tracking seen state
Integrated into: contacts, chat, todo, calendar, and clock apps
Add verified banner and email pre-fill to LoginPage component when
users are redirected after email verification. Updates all app login
pages to pass verification params from URL query string.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add sourceAppUrl tracking during registration to redirect users back
to the app they registered from after email verification. Includes
URL validation for security (only *.mana.how, mana.how, localhost).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add OllamaService for local model inference via Ollama API
- Update ChatService to route requests based on model provider
- Support both 'ollama' (local) and 'openrouter' (cloud) providers
- Add Gemma 3 4B as default model (free, runs on Mac Mini)
- Add SQL migration script for existing databases
- Update CLAUDE.md with Ollama configuration docs
Environment variables:
- OLLAMA_URL: Ollama server URL (default: http://localhost:11434)
- OLLAMA_TIMEOUT: Request timeout in ms (default: 120000)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add metrics module to calendar, chat, clock, contacts backends
- Add metrics module to mana-core-auth service
- Expose /metrics endpoint for Prometheus scraping
- Track HTTP requests, response times, and custom business metrics
Co-Authored-By: Claude <noreply@anthropic.com>
- Clock: Replace local user-settings store with shared theme store
from @manacore/shared-theme to support nav settings properly
- All apps: Add optional chaining and fallback values when accessing
userSettings.nav.desktopPosition and userSettings.nav.hiddenNavItems
to prevent TypeError when user is not authenticated
Apps fixed: calendar, chat, clock, contacts, manacore, manadeck,
picture, todo
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Users can now use Calendar, Chat, Clock, and Todo without signing in.
Data is stored in sessionStorage (lost when tab closes).
Changes per app:
- Add session storage stores for temporary data
- Add AuthGateModal for login prompts
- Remove auth redirect from app layouts
- Add guest mode banner with item count
- Add sessionStorage return URL handling
When users sign in, session data is migrated to their cloud account.
Add unified pricing components for the Mana credit system:
- Central pricing data with plans, packages, and translations
- ManaPricingSection component with billing toggle and trust indicators
- Pricing pages for Chat and ManaDeck landings
- Footer links updated to /pricing pages
Update all tracking script URLs and admin dashboard links to use the
new stats.mana.how subdomain for Umami web analytics.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add new reusable components to shared-landing-ui package:
- AppScrollerSection, TimelineSection, MasonryGridSection, PrinciplesSection
- LegalPageTemplate for privacy/terms/cookies/imprint pages
- Navigation component with mobile menu and language switcher
- GradientText and LanguageSwitcher atoms
- i18n system with getLangFromUrl, useTranslations, localizePath
- Theme files for picture (indigo), chat (blue), zitare (teal)
Add legal pages to ManaDeck and Chat landing pages:
- privacy, terms, cookies, imprint pages using shared template
- Updated footers with cookies link
The prepare script only runs during local pnpm install, not during
workspace-level installation in Docker. Adding explicit svelte-kit sync
step before vite build to generate SvelteKit entry points.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add drizzle.config.ts to clock-backend
- Add missing shared-types package to all web app Dockerfiles
- Add shared-splitscreen to todo-web Dockerfile
These packages were missing from the Docker build context,
causing TypeScript compilation errors during image builds.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add backendUrl parameter to initializeWebAuth() for interceptor config
- Expand isTokenExpiredResponse() to match more error patterns:
- "invalid token", "token validation failed", "claim" (jose errors)
- ERR_JWT_EXPIRED error code
- Update all web apps to pass backendUrl for automatic refresh:
- picture (3006), chat (3002), zitare (3007), contacts (3015)
- calendar (3014), clock (3017), todo (3018)
- Fix API client default port in picture web app
This prevents users from being randomly signed out when JWT expires.
The interceptor now catches 401 responses and automatically refreshes
the token before retrying the request.
- Rename route /labels to /tags and /label/[id] to /tag/[id]
- Rename LabelSelector component to TagSelector
- Update all UI texts from "Labels" to "Tags"
- Update navigation items and references
- Align terminology with Calendar and Contacts apps
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Users were getting signed out after ~15 minutes because API clients were
reading tokens directly from localStorage without triggering the refresh
logic. The tokenManager exists with proper refresh capability but was
never being used.
Changes:
- Add getValidToken() method to auth stores in 9 web apps
- Update API clients to use authStore.getValidToken() instead of localStorage
- Token refresh now happens proactively before requests fail
Apps updated: chat, calendar, picture, zitare, contacts, todo, clock, manacore, manadeck
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Chat:
- Add OpenRouter as primary AI provider with multiple models
- Update chat service with new model configurations
- Add model seed data for Llama, DeepSeek, Mistral, Claude, GPT-4o
Picture:
- Integrate @mana-core/nestjs-integration for credit system
- Implement freemium model (3 free generations, then 10 credits)
- Migrate storage to @manacore/shared-storage
- Add comprehensive project documentation
The chat-backend build failed because the storage module imports from
@manacore/shared-storage which was not being copied into the Docker build
context.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
## Runtime Environment Fix
- Updated all web app hooks.server.ts to use $env/dynamic/private
- This allows Docker containers to inject env vars at runtime
- Updated docker-compose.staging.yml with HTTPS staging domains
- Fixes Mixed Content errors when accessing staging via domains
## New Features
- Added email service to mana-core-auth for sending emails
- Added storage module to chat backend
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Updated all web app hooks.server.ts to use $env/dynamic/private
instead of process.env for reading environment variables
- This allows Docker containers to inject env vars at runtime
- Updated docker-compose.staging.yml with HTTPS staging domains
- Fixes Mixed Content errors when accessing staging via domains
Affected apps: clock, chat, calendar, todo, manacore
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Replace custom settings implementations with GlobalSettingsSection
- Add appId prop to all GlobalSettingsSection instances
- Remove duplicate local theme/language controls
- Standardize settings across Chat, Picture, and Manacore apps
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The production stage was copying node_modules to /app, but pnpm creates
symlinks pointing to ../../../../../node_modules/.pnpm/ (relative to the
app's node_modules location). When the directory structure changed, these
symlinks broke, causing "Cannot find package" errors.
Fix:
- Keep same directory structure in production (/app/apps/*/apps/web)
- Copy the root .pnpm store that symlinks point to
- Copy the app's node_modules which contains the symlinks
Affected apps: todo, manacore, chat, calendar, clock
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
npm doesn't understand pnpm's workspace:* protocol. Copy node_modules
from the builder stage to get all dependencies including workspace packages.
Affected: todo, manacore, chat, calendar, clock web apps.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The production stage was silently ignoring npm install failures with
`|| true`, causing dependencies to be missing at runtime.
Affected: clock, manacore, chat, calendar web apps.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Problem: Browser was calling localhost:3001 instead of staging server IP
because environment variables from Docker aren't available client-side.
Solution:
1. Add PUBLIC_*_CLIENT env vars to docker-compose.staging.yml for browser URLs
2. Inject these into window.__PUBLIC_*__ via hooks.server.ts transformPageChunk
3. Auth store reads from window variable for client-side requests
This pattern properly handles:
- SSR: Uses Docker internal URLs (http://mana-core-auth:3001)
- Client: Uses public URLs (http://46.224.108.214:3001)
- Local dev: Falls back to localhost
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changed PUBLIC_MANA_CORE_AUTH_URL from $env/static/public to runtime
environment variables so the Docker build doesn't fail.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add @sveltejs/adapter-node for server-side rendering
- Create Dockerfile for chat web SvelteKit app
- Add /health endpoint for container health checks
- Add chat-web service to docker-compose.staging.yml
- Update CI/CD workflow with chat-web health check
The chat app now deploys with both backend and web frontend:
- mana-core-auth (port 3001) - central auth
- chat-backend (port 3002) - API
- chat-web (port 3000) - web frontend
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed NestJS dependency injection error in ChatService by converting type-only import to regular import.
Root cause: Type-only imports are erased at compile time, causing NestJS to fail dependency injection at runtime.
Error: "Nest can't resolve dependencies of the ChatService (?, DATABASE_CONNECTION)"
This was the same issue we fixed in mana-core-auth services.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add GeneralSettings types (startPages, weekStartsOn, soundsEnabled)
- Create app-routes.ts with available routes for 12 apps
- Extend UserSettingsStore with general settings support
- Update GlobalSettingsSection with start page selector UI
- Add start page redirect logic to all app layouts:
- Clock, Calendar, Todo, Zitare, Picture
- Manadeck, Presi, Chat, Manacore
- Create user-settings stores for Clock and Todo apps
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Copy packages/shared-nestjs-auth in build stage
- Build shared-nestjs-auth before backend
- Resolves TS2307 errors in Docker build CI
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>