The m CLI isn't available in Docker containers. Replace exec.Command("m", "mail", "send")
with direct SMTP using crypto/tls + net/smtp (implicit TLS on port 465).
Env vars: SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS, MAIL_FROM
Gracefully skips sending if SMTP is not configured.
Note: mgmt@msbls.de rejected by Hostinger as not owned by mail@msbls.de.
Default from address set to mail@msbls.de until alias is created.
Now that KanzlAI is on the youpc.org Supabase instance, the separate
YouPCDatabaseURL connection is unnecessary. The main database connection
can query mlex.* tables directly since they're on the same Postgres.
- Remove YouPCDatabaseURL from config
- Remove separate sqlx.Connect block in main.go
- Pass main database handle as youpcDB parameter to router
- Update CLAUDE.md: mgmt schema in youpc.org (was kanzlai in flexsiebels)
Backend:
- DraftDocument: Claude generates legal documents from case data + template type
(14 template types: Klageschrift, UPC claims, Abmahnung, etc.)
- CaseStrategy: Opus-powered strategic analysis with next steps, risk assessment,
and timeline optimization (structured tool output)
- FindSimilarCases: queries youpc.org Supabase for UPC cases, Claude ranks by
relevance with explanations and key holdings
Endpoints: POST /api/ai/draft-document, /case-strategy, /similar-cases
All rate-limited (5 req/min) and permission-gated (PermAIExtraction).
YouPC database connection is optional (YOUPC_DATABASE_URL env var).
1. Tenant isolation bypass (CRITICAL): TenantResolver now verifies user
has access to X-Tenant-ID via user_tenants lookup before setting context.
Added VerifyAccess method to TenantLookup interface and TenantService.
2. Consolidated tenant resolution: Removed duplicate resolveTenant() from
helpers.go and tenant resolution from auth middleware. TenantResolver is
now the single source of truth. Deadlines and AI handlers use
auth.TenantFromContext() instead of direct DB queries.
3. CalDAV credential masking: tenant settings responses now mask CalDAV
passwords with "********" via maskSettingsPassword helper. Applied to
GetTenant, ListTenants, and UpdateSettings responses.
4. CORS + security headers: New middleware/security.go with CORS
(restricted to FRONTEND_ORIGIN) and security headers (X-Frame-Options,
X-Content-Type-Options, HSTS, Referrer-Policy, X-XSS-Protection).
5. Internal error leaking: All writeError(w, 500, err.Error()) replaced
with internalError() that logs via slog and returns generic "internal
error" to client. Same for jsonError in tenant handler.
6. Input validation: Max length on title (500), description (10000),
case_number (100), search (200). Pagination clamped to max 100.
Content-Disposition filename sanitized against header injection.
Regression test added for tenant access denial (403 on unauthorized
X-Tenant-ID). All existing tests pass, go vet clean.