The 0004_add_openrouter_provider.sql migration existed but was never
registered in _journal.json, so the 'openrouter' value was missing from
the api_key_provider PostgreSQL enum. Inserting an OpenRouter key threw
a DB error that was unhandled, causing Next.js to return an HTML 500;
the frontend's res.json() then threw, showing "Netzwerkfehler".
Fixes:
- Add 0004_add_openrouter_provider to _journal.json (idx 7) so the
migration runs on next deploy and registers 'openrouter' in the enum
- Fix null-label duplicate check: use isNull() instead of passing
undefined to and(), which incorrectly matched all provider keys
- Wrap DB insert in try/catch to return a proper JSON error instead of
crashing with an unhandled exception
Co-Authored-By: Paperclip <noreply@paperclip.ing>
The CROSS JOIN referenced s.system_prompt which didn't exist in the
VALUES alias, causing the entire migration transaction to fail.
This prevented the skills table from being created at all.
Seed is now handled entirely by migration 0006.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
All skills API routes were using `db` directly instead of `withTenantDb`,
causing RLS to block all operations since `app.tenant_id` was never set.
This caused "Netzwerkfehler" when creating/reading skills.
Also fixes the broken seed migration (0005) which referenced a non-existent
column in the CROSS JOIN, preventing default system skills from being inserted.
New migration 0006 properly seeds the 4 default skills with full system prompts.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Replace hardcoded ANALYSIS_MODES lookups with database-driven skill loading:
- Add skills table to Drizzle schema with tenant-scoped, configurable skills
- Add analyses.skill_id FK and structured_result JSONB column
- Refactor runAnalysis()/runAnalysisSync() to resolve skills from DB
- Support skillId, skillSlug, or legacy mode enum (with fallback)
- Add structured data output via generateObject() + jsonSchema() for
skills with output_type = structured_data
- Update /api/analyses POST to accept skillId/skillSlug alongside mode
- Migration 0005: creates skills table, seeds system skills, backfills
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Integrate OpenRouter via its OpenAI-compatible API so users can select
and use OpenRouter models alongside existing Anthropic/OpenAI/Ollama
providers. Adds provider to type system, DB enum, API validation,
buildModel switch, and settings UI.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
The migration file was added by feat/aiia-66-source-selection but was not
registered in _journal.json, so it never runs on deploy. This caused
'source_scope' column-missing errors on document insert.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Add source scope (case/global) to documents, enabling users to select
which uploaded documents the AI considers during analysis. Includes
schema migration, API support, reusable source selection UI component,
and integration into the analyse form.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
The "Netzwerkfehler beim Speichern des Schlüssels" was caused by two issues:
1. ENCRYPTION_KEY env var was not passed to the Docker container, so
AES-256-GCM encrypt() threw at runtime on every POST/PATCH.
2. The 0003_tenant_api_keys migration was not in the drizzle journal
and no migration runner existed in the Docker image.
Changes:
- docker-compose.yml: pass ENCRYPTION_KEY to app container
- .env.example: document ENCRYPTION_KEY with generation command
- .gitignore: allow .env.example to be tracked
- Dockerfile: include drizzle/ migrations and entrypoint script
- entrypoint.sh: run migrations before starting the app
- migrate.mjs: runtime migration script using drizzle-orm migrator
- drizzle journal: register 0003_tenant_api_keys migration
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Implement § 61 NV Bühne non-renewal deadline calculation with tiered
protection (standard 31.10., extended 31.07. for 15+ years, special
protection for over-55), tariff-based compensation calculation with
Gagenklassen and Dienstalterszulage, and Spielzeit seasonal logic
(1.8.–31.7. with Probenzeit). Includes DB schema (contracts,
compensationRules, nonRenewalDeadlines), migration, and three API
endpoints under /api/nv-buehne/.
Co-Authored-By: Paperclip <noreply@paperclip.ing>