Commit Graph

30 Commits

Author SHA1 Message Date
CTO
8172872329 fix: coerce empty FormData strings to null for UUID columns (AIIA-59)
Some checks failed
Deploy to VPS / deploy (push) Has been cancelled
Document upload failed with "invalid input syntax for type uuid" when
decision_id or norm_instrument_id were sent as empty strings from
FormData. The ?? operator only catches null/undefined, not "".

Added emptyToUndefined() to sanitize all optional UUID fields at the
API boundary before they reach the DB insert.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-10 07:43:43 +00:00
CTO (LegalAI)
23a66f92fc fix: resolve upload EACCES and analysis start failure
Some checks failed
Deploy to VPS / deploy (push) Has been cancelled
- Dockerfile: create /app/uploads with correct ownership before switching
  to the non-root nextjs user, fixing EACCES: permission denied on mkdir
- analyse-form.tsx: send 'title' and 'query' fields (not 'question') to
  match the /api/analyses endpoint contract, fixing 400 rejection that
  showed "Analyse konnte nicht gestartet werden"

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-09 22:01:45 +00:00
CTO (LegalAI)
d7ab827b74 fix: rename middleware.ts to proxy.ts for Next.js 16 compatibility
Some checks failed
Deploy to VPS / deploy (push) Has been cancelled
Next.js 16 deprecated the "middleware" file convention in favor of "proxy".
This fixes the build warning reported during manual deploy.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-09 21:03:19 +00:00
CTO (LegalAI)
6f80cadbd4 feat: add build hash to sidebar footer and Gitea CI/CD deploy workflow
Some checks failed
Deploy to VPS / deploy (push) Has been cancelled
- Inject git commit short hash at build time via NEXT_PUBLIC_BUILD_HASH
- Display build hash in sidebar footer for version tracking
- Add Gitea Actions workflow to auto-deploy on push to master (SSH → pull → rebuild)

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-09 20:58:50 +00:00
CTO (LegalAI)
2509b907ae fix: chunk large law texts to prevent truncated AI JSON output
Texts >10k chars are now split at § boundaries and parsed in separate
AI calls, then merged.  This prevents maxOutputTokens truncation that
caused "AI returned invalid JSON" on large imports (~50k+ chars).

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-09 16:20:35 +00:00
CTO (LegalAI)
1493b84787 fix: extract tenantId from session auth instead of request body/headers
AI routes now use requirePermission() + ctx.tenantId to get the tenant,
ensuring getModelForTenant() is always called with the correct tenant ID
so that stored API keys are used. Fixes norms/parse (was falling back to
getModel()) and analyses/structured (was trusting x-tenant-id header).

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-09 14:55:20 +00:00
CTO (LegalAI)
73cd71b1f6 fix: make entrypoint migration non-fatal so app starts even if migrate.mjs fails
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-09 14:48:50 +00:00
CTO (LegalAI)
09b0022b02 fix: include drizzle-orm and pg in serverExternalPackages for standalone migration
The entrypoint.sh migration script (migrate.mjs) imports
drizzle-orm/node-postgres/migrator which is never imported by app code.
Next.js standalone trace therefore omits it from node_modules, causing
the container to crash on startup before server.js runs.

Adding drizzle-orm and pg to serverExternalPackages ensures the full
packages are copied into the standalone output, fixing the migration
crash.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-09 14:41:18 +00:00
CTO (LegalAI)
b22bdd8425 fix: API key save network error — add ENCRYPTION_KEY env and auto-migrate
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>
2026-04-09 14:28:19 +00:00
CTO (LegalAI)
2a7db07d46 fix: add API key input field to AI provider settings form
When selecting Anthropic or OpenAI as provider, the form now shows
an inline API key input field that creates or replaces the key via
the existing CRUD API. Includes key hint display and status indicator.

Resolves AIIA-49

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-09 13:42:57 +00:00
CTO (LegalAI)
4473e32f9c fix: API-Key Status-Anzeige fuer Anthropic/OpenAI im AI-Provider Bereich
Zeigt im AI-Provider Formular einen Status-Indikator an, ob ein API-Schluessel
fuer den gewaehlten Provider (Anthropic/OpenAI) hinterlegt ist. Entfernt Ollama
aus dem API-Key Dropdown, da Ollama keine API-Keys benoetigt.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-09 13:18:38 +00:00
CTO (LegalAI)
362627981d feat: implement per-tenant API key management with AES-256-GCM encryption
Add encrypted API key storage for AI providers (Anthropic, OpenAI, Ollama)
with admin-only CRUD endpoints, tenant isolation, and audit logging.

- DB migration: tenant_api_keys table with RLS policy
- AES-256-GCM encryption utility (ENCRYPTION_KEY env var)
- CRUD API: GET/POST /api/settings/api-keys, PATCH/DELETE /api/settings/api-keys/[id]
- Provider integration: getModelForTenant() checks tenant keys before env fallback
- Frontend: API key management section in Einstellungen page
- Audit logging on all key CRUD operations (DSGVO)

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-09 12:08:40 +00:00
CTO (LegalAI)
34047739cf feat: add PDF upload support to Fliesstext-Import
The import page now accepts PDF files in addition to TXT.
Backend uses pdf-parse to extract text from uploaded PDFs
before sending to AI for paragraph parsing.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-09 11:52:58 +00:00
CTO (LegalAI)
c86ff8d151 feat: Fliesstext-Import fuer Gesetze mit KI-Parsing
Neuer /normen/import Bildschirm: Gesetzestext als Fliesstext einfuegen
oder TXT-Datei hochladen, KI zerlegt automatisch in Paragraphen,
Vorschau mit Bearbeitungsmoeglichkeit, dann Import ins Regelwerk.

- POST /api/norms/parse: AI-gestuetztes Parsing von Gesetzestexten
- /normen/import: Mehrstufiges Frontend (Eingabe -> Vorschau -> Import)
- Link zum Fliesstext-Import auf der Normen-Uebersichtsseite

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-09 11:46:44 +00:00
CTO (LegalAI)
58d96864cc feat: Frontend-Formulare fuer Entscheidungen und Normen anlegen
- /entscheidungen/new: Formular fuer neue Entscheidungen (Typ, Gericht, Aktenzeichen, Datum, Leitsatz, Tenor, Sachverhalt, Gruende, Volltext, Rechtsgebiete, Schlagwoerter)
- /normen/new: Formular fuer neue Regelwerke mit optionalen Paragraphen inline
- POST /api/norms: Neue API-Route fuer normInstrument-Erstellung
- Buttons auf den Listenseiten /entscheidungen und /normen

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-09 11:31:11 +00:00
CTO (LegalAI)
7b1407268b feat: Generisches Dokument-Upload-System fuer Entscheidungen, Normen und Falldokumente
- Neues documents-Schema mit Mandantentrennung (tenantId), Kategorien (entscheidung/norm/falldokument/sonstiges) und optionaler Verknuepfung zu cases/decisions/normInstruments
- Upload-Library (src/lib/documents/) mit Datei-Upload, PDF/DOCX-Textextraktion und gefilterten Listen
- API-Route POST/GET /api/documents mit RBAC, Audit-Logging und asynchroner Textextraktion
- Wiederverwendbare DokumentUpload-Komponente mit Drag-and-Drop, Fortschrittsanzeige und Dateiliste
- Integration in Fall-Detailseite, Entscheidungs-Detailseite und Normen-Detailseite
- Drizzle-Migration fuer documents-Tabelle mit RLS-konformer Mandantentrennung
- DSGVO: 90-Tage Aufbewahrungsfrist fuer hochgeladene Dokumente

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-09 10:18:56 +00:00
CTO (LegalAI)
a8124fa6b9 fix: use set_config() instead of SET LOCAL for tenant RLS context
PostgreSQL SET commands do not support parameterized queries ($1),
causing "syntax error at or near $1" on all tenant-scoped operations.
Replaced with set_config('app.tenant_id', $1, true) which supports
parameters safely. Also added BEGIN/COMMIT transaction wrapping since
set_config(..., true) requires a transaction for LOCAL scope.

Fixed SQL injection vulnerability in tenant.ts which used unescaped
string interpolation.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-09 09:05:02 +00:00
CTO (LegalAI)
517184bbae fix: add /cases/new route to prevent dynamic [id] catch
The static "new" segment was missing, so Next.js treated "new" as a
UUID parameter for [id]/page.tsx, causing a Postgres "invalid input
syntax for type uuid" error. Adding cases/new/page.tsx with a create
form resolves the server error.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-09 08:48:09 +00:00
CTO (LegalAI)
f0c87d9332 feat: implement case management (Fallverwaltung) UI and API
- API routes: GET/POST /api/cases (list + create), GET/PATCH/DELETE /api/cases/[id]
- Cases list page with search, status filter, and pagination
- Case detail page showing linked analyses and proceedings
- Sidebar navigation: added "Fälle" link after Dashboard
- Tenant isolation via withTenantDb + requirePermission on all API routes
- Audit logging on all case operations

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-09 08:38:21 +00:00
CTO (LegalAI)
07a057bf79 feat: add /api/auth/register route for user registration
Creates tenant and admin user with bcrypt-hashed password.
Fixes registration page JSON parse error caused by missing endpoint.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-09 08:14:22 +00:00
CTO (LegalAI)
ffdab093ff feat: add Ollama/local LLM provider support
Add Ollama as a third AI provider option alongside Anthropic and OpenAI.
Uses the OpenAI-compatible API endpoint that Ollama exposes, configured
via OLLAMA_URL and OLLAMA_MODEL env vars. Provider selection is now
tenant-aware via DB settings, with env var fallback.

- New provider type 'ollama' in AIProvider union
- Tenant-aware getModelForTenant() reads AI config from tenant settings jsonb
- Admin settings UI on /einstellungen for provider/model selection
- API route GET/PATCH /api/settings/ai for tenant AI config
- Updated all AI call sites (analysis, structured-analysis, contracts)

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-09 08:11:31 +00:00
CEO
bd132315b4 fix: port mappings (3002 for app, 5434 for postgres) to avoid conflicts
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-09 08:05:19 +00:00
CTO (LegalAI)
38973f2d63 feat: add deployment script and project README
- deploy.sh: pulls from Gitea, rebuilds and restarts Docker containers
- README.md: setup instructions, env vars, deployment guide

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-09 07:57:00 +00:00
CTO (LegalAI)
7dfbc42b8c feat: contract analysis API improvements and DSGVO compliance updates
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-09 07:56:01 +00:00
CTO (LegalAI)
0daf65ce91 fix(decisions): enforce DSGVO tenant isolation and RBAC on decisions API
- GET /api/decisions: Add requirePermission('decisions:read'), use
  withTenantDb() for RLS enforcement, add application-level tenant
  filter (own tenant OR published+anonymized)
- POST /api/decisions: Add requirePermission('decisions:write'), use
  withTenantDb(), set tenantId from authenticated session context
  instead of accepting it from request body (prevents tenant spoofing)

Addresses DSGVO Art. 32 (security of processing) and Art. 5(1)(f)
(integrity and confidentiality).

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-09 00:45:55 +00:00
CTO (LegalAI)
b837f4a71e feat: Phase 4.4 — Human-in-the-Loop APIs (AIIA-27)
- POST /api/analyses/:id/feedback — correction/approval/rejection workflow
- GET /api/headnotes — Leitsatz-Vorschlags-Workflow (pending headnote review)

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-09 00:24:34 +00:00
CTO (LegalAI)
78ccf64948 feat: Phase 4 — WebApp-Frontend für Bühnenrecht (AIIA-27)
Complete frontend implementation with Next.js App Router:

- Dashboard with case/analysis/proceeding stats and quick actions
- Normen-Browser with Quellenrang hierarchy and instrument detail
- Entscheidungssuche with full-text search and detail view
- Analysemodus with streaming AI analysis (4 modes: Gutachten, Entscheidung, Vergleich, Risiko)
- Vertragsanalyse with file upload (PDF/DOCX)
- Verfahren overview (BSchGO/ArbGG)
- Auth pages (Login/Register)
- Mandantenfähigkeit: tenant switcher, RBAC-based settings
- Responsive sidebar navigation with Tailwind CSS
- Dashboard layout with session-based auth guard
- Installed missing runtime deps (pdf-parse, mammoth, devDependencies)

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-09 00:23:09 +00:00
CTO (LegalAI)
3c16fdc30f feat: add NV Bühne non-renewal & compensation module (Phase 3.2)
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>
2026-04-08 23:25:54 +00:00
CTO (LegalAI)
a7245001ad feat: vollständiges Datenmodell für Normen und Entscheidungen (AIIA-15)
Replaces placeholder schema with full legal data model:
- Normen with temporal versioning (valid_from/valid_to), source rank hierarchy,
  immutable version chains, and norm-to-norm cross-references
- Entscheidungen with structured metadata (Aktenzeichen, Gremium, Leitsatz,
  Tenor, Tatbestand, Entscheidungsgründe), decision-norm links with Stichtag
- NV Bühne Fachgruppen and BSchGO Arbitration Tribunals
- Cases, Analyses, and DSGVO Audit Log
- Mandantentrennung via tenant_id + PostgreSQL Row-Level Security policies
- Initial Drizzle migration and RLS migration

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-08 21:16:40 +00:00
CTO (LegalAI)
1d61b2ad8a Initial project structure: Next.js 15 + TypeScript + Drizzle ORM
- Next.js 15 with App Router, TypeScript, Tailwind CSS
- Directory structure per LegalAI architecture plan
- Docker Compose setup (PostgreSQL 16, Meilisearch, App)
- Drizzle ORM with base schema (tenants, users, norms, decisions)
- AI abstraction layer structure (Vercel AI SDK)
- Normen-Engine with Quellenrang hierarchy
- Search abstraction layer
- Auth placeholder (NextAuth.js)

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-08 21:07:22 +00:00