Commit graph

359 commits

Author SHA1 Message Date
Till JS
1052469397 feat(infra): extend Dockerfile validator to backends and services
Validator now checks 52 Dockerfiles (web + backend + service).
Fixed 10 missing COPYs across backends, services, and nestjs-base.
Generator also supports backend/service Dockerfiles with markers.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 08:57:10 +01:00
Till JS
8356ac634a test(auth): add unit tests for local JWKS cache
15 tests covering: happy path, caching with TTL, empty DB, connection
failures, key rotation, and cache clearing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 22:36:22 +01:00
Till JS
5b5849eaa4 perf(auth): cache JWKS locally instead of HTTP self-call
Replace createRemoteJWKSet (HTTP to localhost) with local DB-backed
JWKS cache. Keys are read from auth.jwks table and cached in memory
with 5-minute TTL. Eliminates HTTP roundtrip per token validation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 20:26:16 +01:00
Till JS
46925dec90 fix(project-doc-bot): restore shared-llm dependency in package.json
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 12:40:58 +01:00
Till JS
e060884881 fix(infra): add healthcheck start_period, restore shared-llm dep in project-doc-bot
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 11:48:13 +01:00
Till JS
cc55ca5578 fix(mana-core-auth): add shared-llm package to Dockerfile
The auth service now depends on @manacore/shared-llm but it was missing
from the Docker build context, causing build failures.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 11:13:28 +01:00
Till JS
62c5dddab0 feat(project-doc-bot): migrate to shared-llm, remove OpenAI dependency
Migrate matrix-project-doc-bot from raw fetch to @manacore/shared-llm
and remove the unused openai npm package. The bot was already using
mana-llm and mana-stt (not OpenAI directly), but the code still had
raw fetch calls and the openai package installed.

Changes:
- generation.service.ts: raw fetch → llm.chat() via LlmClientService
- app.module.ts: add LlmModule.forRootAsync()
- Remove openai dependency (was unused in code)
- Update CLAUDE.md: document actual AI stack (mana-llm + mana-stt)
- Update TECH_STACK_INDEPENDENCE.md: mark Prio 1-3 as completed
  - Prio 1: Picture App → mana-image-gen 
  - Prio 2: Project Doc Bot → Ollama + mana-stt 
  - Prio 3: All LLM calls via mana-llm 
  - Self-hosted percentage: 75% → ~80%

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 10:44:56 +01:00
Till JS
6cab9a3c24 fix(infra): remove n8n and increase health check intervals to fix port exhaustion
Mac Mini had 25k+ TIME_WAIT sockets exhausting the 16k ephemeral port range,
blocking all outgoing TCP connections. Root cause: ~50 health checks at 30s
intervals + n8n automation creating excessive short-lived connections.

- Remove n8n service and volume (no longer needed)
- Increase health check intervals: 30s → 120s (app services), 10s → 30s (infra)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 10:35:45 +01:00
Till JS
fea6a8e64b feat: add it.mana.how landing page for European tech sovereignty
New Astro landing page at services/it-landing/ targeting European
organizations that need independent, GDPR-compliant IT infrastructure.

10 sections:
- Hero: "Technologische Souveränität für Europa" with 75% self-hosted stat
- Problem: US Cloud Act, vendor lock-in, GDPR conflicts, Schrems II
- Solution: IndependenceBar (animated 75% progress) + 3 principles
- Infrastructure Grid: 21 components color-coded (green/amber/red)
- GDPR: 6 compliance cards (all rights, breach notification, AI safety)
- Open Source Stack: 8 comparisons (PostgreSQL vs DynamoDB, etc.)
- Target Audiences: Government, healthcare, education, SMBs
- Roadmap: Timeline from current state to 90%+ independence (2027)
- FAQ: 8 questions about sovereignty, Cloud Act, local AI, costs
- CTA: Contact for consultation

Features:
- Light EU Sovereign theme (#003399 EU blue, professional B2B design)
- German (default) + English (/en/) with Astro i18n
- Custom components: InfrastructureGrid, IndependenceBar (scroll animation)
- Data from docs/TECH_STACK_INDEPENDENCE.md (real infrastructure stats)
- Legal pages: Impressum, Datenschutz
- Deploy: pnpm deploy:landing:it → Cloudflare Pages

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 10:04:59 +01:00
Till JS
45063b88be feat(mana-llm): add Google Gemini fallback provider with auto-routing
Add Google Gemini as a fallback provider that activates automatically
when Ollama is overloaded or unavailable, ensuring LLM requests always
succeed even under load.

New provider (src/providers/google.py):
- Full LLMProvider implementation using google-genai SDK
- Chat completions (streaming + non-streaming)
- Vision/multimodal support (base64 images)
- Embeddings via text-embedding-004
- Model mapping: Ollama models → Gemini equivalents
  (gemma3:4b → gemini-2.0-flash, llava:7b → gemini-2.0-flash, etc.)

Auto-fallback routing (src/providers/router.py):
- Concurrent request tracking for Ollama (OLLAMA_MAX_CONCURRENT=3)
- When Ollama concurrent > max: route to Google automatically
- When Ollama fails: retry on Google with model mapping
- Health check caching (5s TTL) to avoid hammering Ollama
- Non-Ollama providers (openrouter, groq, together) are never fallback-routed
- Fallback info included in /health endpoint response

New config (src/config.py):
- GOOGLE_API_KEY: enables Google provider
- GOOGLE_DEFAULT_MODEL: default gemini-2.0-flash
- AUTO_FALLBACK_ENABLED: toggle fallback (default: true)
- OLLAMA_MAX_CONCURRENT: concurrent request threshold (default: 3)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 22:44:09 +01:00
Till JS
e2f144962c feat: add unified @manacore/shared-llm package and migrate all backends
Create a shared LLM client package that provides a unified interface
to the mana-llm service, replacing 9 individual fetch-based integrations
with consistent error handling, retry logic, and JSON extraction.

Package (@manacore/shared-llm):
- LlmModule with forRoot/forRootAsync (NestJS dynamic module)
- LlmClientService: chat, json, vision, visionJson, embed, stream
- LlmClient standalone class for non-NestJS consumers
- extractJson utility (consolidates 3 markdown-stripping implementations)
- retryFetch with exponential backoff (429, 5xx, network errors)
- 44 unit tests (json-extractor, retry, llm-client)

Migrated backends:
- mana-core-auth: raw fetch → llm.json()
- planta: raw fetch + vision → llm.visionJson()
- nutriphi: raw fetch + regex → llm.visionJson() + llm.json()
- chat: custom OllamaService (175 LOC) → llm.chatMessages()
- context: raw fetch → llm.chat() (keeps token tracking)
- traces: 2x raw fetch → llm.chat()
- manadeck: @google/genai SDK → llm.json() + llm.visionJson()
- bot-services: raw Ollama API → LlmClient standalone
- matrix-ollama-bot: raw fetch → llm.chatMessages() + llm.vision()

New credit operations:
- AI_PLANT_ANALYSIS (2 credits, planta)
- AI_GUIDE_GENERATION (5 credits, traces)
- AI_CONTEXT_GENERATION (2 credits, context)
- AI_BOT_CHAT (0.1 credits, matrix)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 22:06:30 +01:00
Till JS
c78809834c fix(landing-builder): rework Dockerfile to copy workspace directly
Replace pnpm deploy with direct workspace copy approach since pnpm
deploy doesn't work well with workspace:* dependencies in partial copies.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 13:50:22 +01:00
Till JS
060eb01de7 fix(landing-builder): simplify Dockerfile COPY steps
Remove non-existent node_modules COPY for hoisted packages.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 13:22:00 +01:00
Till JS
994f03c423 fix(landing-builder): add patches dir to Dockerfile for pnpm install
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 13:21:21 +01:00
Till JS
df0b849408 feat: add org landing page builder service
New service that generates static Astro landing pages for organizations
and deploys them to Cloudflare Pages at {slug}.mana.how.

Components:
- Landing Builder Service (NestJS, port 3030) with Astro template
- Admin UI in Manacore web dashboard at /organizations/[id]/landing
- TeamSection + ContactSection for shared-landing-ui
- Two org themes (classic dark, warm light)
- LandingPageConfig types in shared-types
- Docker + CI/CD integration for Mac Mini deployment

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 13:20:10 +01:00
Till JS
71b9339310 refactor: move llm-playground from services/ to apps/playground/
The LLM playground is a SvelteKit web app (frontend), not a backend
microservice. Moving it to apps/ follows the monorepo convention where
all user-facing apps live under apps/.

- Moved services/llm-playground/ → apps/playground/apps/web/
- Renamed package from @mana-llm/playground to @playground/web
- Updated Dockerfile paths for new location
- Updated docker-compose.macmini.yml build context
- Removed unused concurrently dependency
- Added parent package.json

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 11:25:54 +01:00
Till JS
7910737dd9 fix(mana-media): use prom-client directly instead of shared metrics package
mana-media uses NestJS 11 while shared-nestjs-metrics targets NestJS 10,
causing DynamicModule type incompatibility. Use prom-client directly with
a simple MetricsController to expose /metrics endpoint.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 11:06:09 +01:00
Till JS
734ab8012a fix(docker): add patches directory to mana-media Dockerfile
The pnpm-lock.yaml references patches (react-native-reanimated) which
must be present for pnpm install --frozen-lockfile to succeed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 10:50:52 +01:00
Till JS
143112f77a feat(observability): add mana-search, mana-media, and Synapse to monitoring
- Add Prometheus scraping for mana-search (port 3020, already has metrics)
- Add Prometheus scraping for mana-media (port 3015, MetricsModule added)
- Add Prometheus scraping for Matrix Synapse (port 9002, already enabled)
- Add MetricsModule to mana-media with media_ prefix
- Update Dockerfile for mana-media to include shared-nestjs-metrics
- Replace hardcoded ServiceDown alert list with dynamic regex
  (.*-backend|mana-core-auth|mana-search|mana-media|synapse)
- Replace hardcoded backends.json query with dynamic regex
- Add Search, Media, Synapse to master-overview and system-overview dashboards

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 10:46:59 +01:00
Till JS
7c1e2aca49 chore: remove remaining Hetzner references across codebase
Deleted:
- DOCKER_REGISTRY_SETUP.md, QUICK_START_CICD.md (legacy CI/CD docs)
- docs/ULOAD-DEPLOYMENT.md (Hetzner VPS deployment guide)
- scripts/get-ssh-key.sh, scripts/remove-coolify-references.sh (legacy scripts)

Updated Hetzner → MinIO references in:
- shared-storage (package.json, README, client.ts, types.ts)
- App CLAUDE.md files (mukke, storage, planta, picture)
- .claude/GUIDELINES.md, sveltekit-web.md guideline
- TROUBLESHOOTING.md, SETUP_TEMPLATES.md (replaced IPs with placeholders)
- GIT_WORKFLOW.md, COMMANDS.md
- services/matrix-project-doc-bot/CLAUDE.md

Remaining Hetzner mentions are in historical devlogs/audits and docs
that list Hetzner as a hosting alternative (not as active infrastructure).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 10:30:26 +01:00
Till JS
2c26fce736 fix: replace all manacore.app URLs with mana.how
The production domain is mana.how, not manacore.app. Updated all
references across shared-branding APP_URLS, app configs, landing pages,
docs, help content, calendar iCal UIDs, and deploy scripts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 18:40:37 +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
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
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
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
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
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
f7df8e97aa feat(auth): add audit logging, account lockout, and API key rate limiting
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>
2026-03-19 22:09:58 +01:00
Till JS
322f551b43 docs(auth): document SSO checklist for adding new apps
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>
2026-03-19 21:32:35 +01:00
Till JS
bb69f78e1e fix(auth): add missing trusted origins for cross-app SSO
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>
2026-03-19 21:17:34 +01:00
Till JS
97d5b13a38 feat(versioning): add semantic versioning and changesets to all apps
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>
2026-03-19 16:20:18 +01:00
Till JS
3b8931090f fix(auth): scope pnpm install to auth service in Dockerfile
Use --filter to only install mana-core-auth and shared-storage deps,
avoiding missing workspace package errors from root package.json.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 15:10:08 +01:00
Till JS
baf96cbe03 fix(auth): copy patches dir in Dockerfile to fix pnpm install
pnpm resolves patch references from root package.json even for
partial workspace installs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 15:09:03 +01:00
Till JS
2c21f6c2bc fix(auth): use --no-frozen-lockfile in Dockerfile
The partial workspace copy causes lockfile mismatches since not all
referenced packages are present in the Docker build context.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 15:08:15 +01:00
Till JS
817ccfea31 fix(auth): improve email verification error detection in signIn
Better Auth may return error objects instead of throwing for unverified
emails. Now checks result.error before hasUser(), uses case-insensitive
matching, and re-throws NestJS HTTP exceptions to avoid masking them.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 15:05:04 +01:00
Till JS
6e1af0d889 feat(calendar): add Playwright E2E tests for web app
Add 22 E2E tests across 5 test suites covering auth, calendar views,
settings, event CRUD, and calendar management. Tests that require the
calendar backend gracefully skip when it's not running.

Also fixes: hooks.server.ts env fallbacks, ThrottlerGuard DI error,
and auth metrics service TypeScript error.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 13:08:09 +01:00
Till JS
f922d2c4a1 fix(auth): return proper 403 for unverified email on login
Better Auth throws APIError("FORBIDDEN") when email is not verified,
but the signIn catch block didn't handle this case, causing a 500.
Now returns ForbiddenException with EMAIL_NOT_VERIFIED code so the
client can show the resend verification link.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 12:33:27 +01:00
Till JS
14ca0ae0b5 fix(auth): align reset-password min length to 8 characters
The ResetPasswordDto required 12 characters while registration and
change-password only required 8, causing a mismatch with frontend UI.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 12:22:56 +01:00
Till JS
bd1178edf8 feat(traces): integrate traces app into monorepo with NestJS backend and AI city guides
Restructure standalone traces app into monorepo pattern with mobile + backend + shared types.
Add NestJS backend with Drizzle ORM schema for locations, cities, places, POIs, and AI guides.
Add mobile sync layer, cities tab, and guide generation UI. Fix pre-existing type errors across
mobile codebase, matrix-mana-bot (sendDirectMessage), llm-playground, and all web auth stores
(signUp call signature).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 08:12:42 +01:00
Till-JS
a336cc2381 fix(nutriphi-bot): make I18nService optional to fix DI error
Same fix as planta-bot - I18nService injection was failing because
the service couldn't be resolved in the BotModule context despite
I18nModule having global: true.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-17 14:14:07 +01:00
Till-JS
5c630c3fa4 feat(nutriphi-bot): add smart meal feedback with positive aspects and improvement suggestions
- Generate automatic feedback based on nutritional values
- Show positive aspects (fiber, protein, whole grains, nuts, fruits/vegetables)
- Suggest improvements (portion size, fat content, missing nutrients)
- Detect multiple oils and suggest simplification

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-17 14:09:33 +01:00
Till-JS
1d44f918c5 fix(manacore-web): add missing packages to Dockerfile
Add shared-pwa, qr-export, and wallpaper-generator packages
to the Docker build context for manacore-web.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-17 13:43:08 +01:00
Till-JS
c480231128 fix(planta-bot): make I18nService optional to diagnose DI issue
Also restore @Global() decorator to I18nModule while keeping
global: true in DynamicModule config for consistency with other
modules like CreditModule.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-17 12:51:04 +01:00
Till-JS
9faa1fcc68 debug: add detailed logging to planta bot handleTextMessage 2026-02-17 12:40:57 +01:00
Till-JS
dcf4438804 feat(mana-bot): add daily morning summary feature
Add configurable morning summaries that aggregate data from multiple sources:
- Weather forecast via Open-Meteo API (free, no API key needed)
- Today's calendar events
- Today's tasks + overdue tasks
- Birthdays from contacts
- Plants needing water from Planta

New commands:
- !morning / !morgen - Get summary now
- !morning-on/off - Enable/disable automatic delivery
- !morning-time HH:MM - Set delivery time
- !morning-location [city] - Set weather location
- !morning-timezone [zone] - Set timezone
- !morning-format [kompakt|ausfuehrlich] - Set format
- !morning-settings - Show current settings

New shared services in @manacore/bot-services:
- WeatherService - Open-Meteo integration with geocoding
- ContactsApiService - Birthday fetching
- PlantaApiService - Watering schedule
- MorningSummaryService - Aggregates all sources
- MorningPreferencesService - User preferences storage

Includes scheduler for automatic daily delivery at user-configured time.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-17 11:01:47 +01:00
Till-JS
ceac5444ca fix(planta-bot): rewrite Dockerfile to use pnpm workspace pattern
- Use node:20-slim like other bots
- Copy and build shared packages (bot-services, matrix-bot-common)
- Use pnpm instead of npm
- Add non-root user for security
- Fix healthcheck port to 4022

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-17 10:48:55 +01:00
Till-JS
9704e88e78 feat(planta-bot): add AI plant identification via image upload
- Add handleImageMessage() to BaseMatrixService for image support
- Implement photo upload and Gemini Vision analysis in PlantaService
- Add image handler in MatrixService that downloads, uploads, and analyzes
- Format analysis results with health status, care tips, and confidence
- Update CLAUDE.md documentation with new feature
- Fix type mismatch in onboarding-bot (fullName → displayName)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-17 10:40:08 +01:00
Till-JS
20db01628a fix(auth): remove conflicting JSON body parser middleware
The manual bodyParser.json() middleware conflicts with NestJS rawBody mode.
When rawBody: true is enabled, NestJS consumes the body stream first, then
the manual parser tries to read it again causing "stream is not readable".

NestJS handles JSON parsing internally, so the manual middleware was redundant
and causing 500 errors on login requests.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-16 14:30:06 +01:00
Till-JS
14da5a28ef 📝 docs(auth): update organization endpoint documentation
- Add all new organization management endpoints to API table
- Add new Invitations section for invitation endpoints
- Update controller JSDoc with complete endpoint list
- Update last updated date
2026-02-16 12:57:29 +01:00