Commit Graph

24 Commits

Author SHA1 Message Date
m
1a89b0c490 design(t-paliad-070): partner units rename + admin departments page
Inventor design doc for the Dezernate→Partner Units rename and the new
/admin/departments management surface that replaces the placeholder card.

Key proposals:
- Single PR, single migration (026: users.dezernat → users.department).
- New /admin/departments page mirrors /admin/team aesthetic; lifts the CRUD
  out of /settings?tab=dezernat.
- User-facing label "Partner unit" / "Partner units" (same in DE+EN per m).
- Defer audit event emission to t-paliad-071 to keep this PR focused.
- Phase 2 follow-up: drop the free-text users.department duplicate once
  onboarding can pick from the structured registry.

Five open questions for m in §12 before coder shift starts.
2026-04-29 19:03:14 +02:00
m
8fe05fe696 Merge main into mai/cronus/audit-polish-2-triage (resolve i18n.ts collision with brunel's t-paliad-066 escalation keys) 2026-04-29 15:05:50 +02:00
m
bff2ec5107 feat(t-paliad-066): escalation contact dropdown in Settings → Notifications
Exposes paliad.users.escalation_contact_id (added in migration 025) via
the Benachrichtigungen tab so users can route DRINGEND/overdue
escalation to a specific colleague instead of the global_admins
fallback.

Service:
- UpdateProfileInput.EscalationContactID *string (empty = clear, matches
  Dezernat tri-state pattern). Server-side validation rejects self-
  pointer (also enforced by CHECK in migration 025) and unknown UUIDs.

Reminder read path:
- digestRow now carries owner.escalation_contact_id and the audience
  predicate adds the override. visibleForCategory's "global admin"
  branch suppresses when an override is set, so escalation does not
  fan out to the whole admin team. Test table extended with override
  cases (escalation contact sees overdue / DRINGEND, admin suppressed).

UI / client:
- New "Eskalations-Kontakt" section under Benachrichtigungen with a
  select populated from /api/users (excluding self, sorted by name).
  First option is the default-fallback marker; selecting it clears.
- savePrefs PATCHes escalation_contact_id alongside the existing
  reminder fields.

i18n: einstellungen.prefs.escalation.{heading,hint,default_option}
in DE + EN.

docs/project-status.md: flips the open follow-up to "shipped".
2026-04-29 13:59:30 +02:00
m
80fdab0963 docs(t-paliad-067): polish audit triage 2 — classify F-01..F-50, propose 3 PRs
Re-verified every BATCH finding from docs/audit-polish-2026-04-27.md
against the post-PR-B/D/E + palette + firm-name codebase.

- 18 OBSOLETE (already shipped via t-paliad-060/061/062/063/064/065).
- 26 KEEP — bundled into PR-1 (i18n leak sweep + activity log), PR-2
  (visual residue + small per-page polish), PR-3 (tab/chip/notes-hint
  consistency).
- 1 RESCOPED (F-20 colour fixed by palette sweep, structural rule
  consolidation still pending).
- 7 DEFER — design-call or redesign-class items (F-23, F-25, F-32, F-38,
  F-40, F-48, F-49).

Top-5 user-visible items ranked: F-07 dashboard activity narrative, F-15
red archive button, F-04 raw i18n key on /deadlines/new, F-12 AKTE column
header (rename residue), F-13 appointments AKTE cell collision.

DESIGN-READY GATE — head reviews before any coder shift.
2026-04-29 13:58:51 +02:00
m
ee1af9d9cf docs: move project status & history out of CLAUDE.md
CLAUDE.md should be AI guidance only. Phase status, shipped milestones,
open follow-ups, and the patHoLo→Paliad rebrand history are project
state — they belong in docs/, not in agent instructions.

Created docs/project-status.md with the full block. CLAUDE.md now points
to it.
2026-04-29 13:54:59 +02:00
m
93fdf10537 docs(t-paliad-064): reminder system redesign — design doc
Design for zero-overdue SLO, per-user bundled digests (one email per slot
per local-day), DRINGEND evening escalation, and global-admin escalation
on overdues. Includes the actual TZ root cause (alpine container has no
tzdata; LoadLocation silently falls back to UTC) and the embed-tzdata fix.

Awaiting m's go/no-go before implementation.
2026-04-28 12:55:33 +02:00
m
f8982a6628 docs(t-paliad-059): polish audit — 50 findings + top 10 ranked
Survey-only pass across the authenticated paliad surface as test admin
on Playwright at 1280×900 + 375 mobile spot-checks + DE/EN toggle.

Top 10 (best value-per-effort):
1. Strip "Hogan Lovells"/"HL" from public surface (landing, downloads)
2. Pick lime as the single primary green; retire forest-green
3. "Projekt archivieren" red → neutral (reversible, not destructive)
4. /admin/team search input has overlapping placeholder text (visible bug)
5. fristen.field.project.choose raw i18n key on /deadlines/new
6. Activity log leaks project_type_changed + "Type case → litigation"
7. lang="de" on date and time inputs (mm/dd/yyyy + 09:00 AM in DE UI)
8. "Akte" → "Projekt" residue on /deadlines + /appointments
9. Office values lowercased no-umlaut on /projects/{id}/team
10. Project tabs use href="#" — middle-click broken

Plus 40 other findings ranked by severity (broken/friction/polish) and
effort (≤30min/1-2h/half-day+). Suggested 5-PR batching.

41 screenshots in tests/screenshots-polish-2026-04-27/ covering every
sidebar entry + project detail tabs + DE/EN + mobile.

No code changes. Implementation tasks dispatched separately by head.
2026-04-27 18:46:05 +02:00
m
b34500ad31 feat(t-paliad-051): split paliad.users.role into job_title + global_role
Conflation: paliad.users.role was simultaneously job title (display only)
and global permission ('role=admin' checks across Go/SQL/JS). m wanted
to set his real job title ('Counsel Knowledge Lawyer') without losing
admin access — the t-paliad-050 admin-team UI even rejected role='admin'
on edit, so any UI-driven update silently demoted m.

Per m's three-axis principle ("firm roles are not project roles are not
tool roles"), this lands TWO orthogonal columns:

* paliad.users.job_title — free text, NULL allowed, display only.
  NEVER gates anything in code or SQL.
* paliad.users.global_role — CHECK ('standard'|'global_admin'),
  default 'standard'. The only thing that gates ops.

Migration 023:
* Drops NOT NULL + 'associate' default off the legacy role column
* Promotes role='admin' rows to global_role='global_admin'; clears
  their role text; sets m's job_title='Counsel Knowledge Lawyer'
* Renames role -> job_title with CHECK (job_title IS NULL OR <> '')
* Replaces can_see_project body with global_role='global_admin'
* CASCADE-rebuilds every RLS policy under canonical English names —
  with the historic u.role IN ('partner','admin') gates simplified
  to u.global_role='global_admin' only (job_title NEVER gates)

Code surface:
* internal/models/models.go: User.Role -> User.JobTitle (*string) +
  User.GlobalRole (string)
* internal/services/user_service.go: bootstrap (first row promoted to
  global_admin via pg_advisory_xact_lock(7346298141), unchanged constant);
  UpdateProfile drops role, accepts job_title only; AdminUpdateUser adds
  global_role with last-admin demotion guard (ErrLastGlobalAdmin);
  IsAdmin reads global_role
* Other services (dashboard/agenda/appointment/project/deadline/
  department/party/note/checklist_instance): pass user.GlobalRole into
  visibility predicates; partner-or-admin gates simplified to
  global_admin only
* Handlers: drop now-impossible ErrAdminBootstrapOnly cases;
  admin_users handles ErrLastGlobalAdmin -> 409
* department_service: SQL u.role -> u.job_title, DepartmentMember.Role
  -> JobTitle (*string)

Frontend:
* /api/me + Me interfaces ship {job_title, global_role}
* Onboarding form: 'Berufsbezeichnung / Job title' (job_title)
* Settings + admin-team forms: same renames + i18n updates
* Admin-team: new 'Berechtigung / Permission' column with
  'Standard'|'Global Admin' badge + dropdown editor; last-admin
  demotion guard at the UI layer
* Sidebar admin-section reveal: me.global_role==='global_admin'
* deadlines/deadlines-detail/projects-detail/notes: partner-as-permission
  gates dropped, only global_admin grants those operations

Tests:
* user_service_test: bootstrap promotes first user to global_admin,
  subsequent default to standard; AdminUpdateUser refuses to demote
  the last global_admin; IsAdmin reads global_role

Migration applied to ydb 2026-04-27. Live state verified:
* m: job_title='Counsel Knowledge Lawyer', global_role='global_admin'
* tester: job_title=NULL, global_role='global_admin'
* 29 stub colleagues: job_title='associate', global_role='standard'
2026-04-27 14:59:03 +02:00
m
aec150f1cd design(t-paliad-051): split paliad.users.role into job_title + global_role
Conflation today: paliad.users.role is simultaneously job title (display only),
global permission (`role='admin'` checks across Go/SQL/JS), and not-quite-but-
sort-of project_teams.role (already separated). m wants to record his real job
title ("Counsel Knowledge Lawyer") without losing admin access — the existing
admin-team UI even rejects role='admin' on edit, so any UI-driven update
silently demotes him.

Design proposes:
- Rename paliad.users.role -> paliad.users.job_title (free text, NULL allowed)
- Add paliad.users.global_role (CHECK IN ('standard','global_admin'),
  default 'standard')
- Single migration 023 does the rename, populates global_role from the old
  role, fixes m to job_title='Counsel Knowledge Lawyer', updates
  can_see_project, rebuilds RLS policies
- Inventory of every role='admin' call site across services/handlers/
  migrations/frontend bucketed by what migrates vs. what stays
- Keeps the existing 'partner' gate as job_title-driven (already broken in
  prod — "Partner" capital-P vs lowercase 'partner' check; documented as
  out-of-scope follow-up)
- Bootstrap rule (first user becomes admin) keeps the same advisory lock,
  flips global_role instead of role
- API surface: /api/me returns both fields; admin-team UI gets a Permission
  column with a global_role dropdown + last-admin demotion guard

Awaiting m greenlight before implementation phase.
2026-04-27 14:31:15 +02:00
m
c226a8b14d docs(palette): design Cmd/Ctrl+K command palette (t-paliad-044)
Choose Option B (full palette: actions + entities) over Option A
(keybind-only) because:

- pwa-baseline.md canon for multi-entity sites (paliad has 8 entity types).
- 80% of infrastructure already exists in search.ts (sectioned results,
  keyboard nav, i18n, debounce, abortable fetch).
- Patent-lawyer audience benefits from keyboard-first creation flows.
- A-then-B would mean revisiting in 2 weeks anyway.

Scope guardrails: no fuzzy lib, no MRU persistence, no extension API,
no per-action shortcut keys (Cmd+K only). 20-action catalog (12 navigate,
3 create, 4 toggle/action). Mobile gets palette via drawer (no new
BottomNav slot). Desktop preventDefault on Ctrl+K to suppress URL-bar.

Doc covers: trigger surface, UX shape (empty + filtered), action catalog,
component architecture (extend search.ts, new palette-actions.ts data
file), render flow, i18n keys, mobile considerations, acceptance,
implementation plan, risks. Implementer choice deferred to m.

Awaiting m's go/no-go before coder shift.
2026-04-26 15:02:31 +02:00
m
263a4605e3 docs(design): add PWA mobile BottomNav design (t-paliad-041)
Design only — no code changes. Five-slot bottom bar for phones (<768px),
center slot opens slide-up Quick-Add sheet (Frist / Termin / Projekt),
right slot reuses the existing mobile sidebar drawer. Tablets and
desktop unchanged. Awaiting m's review before implementation.
2026-04-26 01:59:31 +02:00
m
fabe32aa56 design: data model v2 — Mandanten + nestable Projekte + Teams (t-paliad-023)
Comprehensive design doc for the replacement of flat paliad.akten with:
  - paliad.mandanten (Clients as first-class table)
  - paliad.projekte (single self-referential typed tree, ltree materialised
    path, 5 project types: mandat/litigation/patent/verfahren/projekt)
  - paliad.teams + paliad.team_mitglieder (Dezernate + project teams in one
    table with kind-shape CHECK)
  - paliad.projekt_mitglieder (hot-path junction replacing akten.collaborators)

Polymorphic FK strategy: single project_id FK on fristen/termine/dokumente/
parteien/akten_events/checklist_instances. Notizen keeps its 4-way polymorphic
shape (akte_id renamed to project_id).

Visibility model: tree-connected — seeing any node grants access to the whole
tree (ancestors + descendants). Office-scope stays at project level; Mandant-
level firm_wide_visible / collaborators override.

Migration plan: 6 phases, non-destructive. UUIDs preserved between akten and
projekte rows so child tables only need column renames, no data moves.

Opinionated: German naming throughout (mandanten, projekte, teams,
team_mitglieder, projekt_mitglieder); /akten URLs alias to /projekte
indefinitely; akten_events table name kept for continuity.

Deliverable: docs/design-data-model-v2.md (920 lines, 14 sections).
2026-04-20 14:17:32 +02:00
m
11217f7bfa feat: email service — SMTP + deadline reminders + invitations (t-paliad-021)
- internal/services/mail_service.go: SMTP/TLS sender (implicit TLS on 465),
  html/template rendering, branded base layout + content templates, silent
  no-op when SMTP_* unset.
- internal/services/reminder_service.go: hourly scanner for Fristen that are
  overdue / due tomorrow / due within the week (Monday digest). Dedup via
  paliad.reminder_log (24h window).
- internal/services/invite_service.go: POST /api/invite flow with domain
  whitelist, in-memory 10/day/user rate limit, audit row in
  paliad.invitations.
- internal/handlers/invite.go: POST + GET /api/invite handlers.
- Sidebar "Kolleg:in einladen" button + modal on every page.
- migration 016: paliad.reminder_log, paliad.invitations, users.lang column.
- docker-compose: SMTP_* + PALIAD_BASE_URL env vars.
- docs/feature-roadmap.md: documented Supabase auth-SMTP routing as open
  question; current pilot keeps identity mails on Supabase default sender.

Rationale: get Paliad off Supabase's best-effort outbound for the
inbox-facing stuff (reminders, invitations) and move deadline nudges from
passive dashboard to active email. Custom Supabase auth SMTP is blocked on
the shared ydb.youpc.org instance — deferred until Paliad has its own
project or GoTrue webhook relay.
2026-04-20 12:34:38 +02:00
cronus
bcdd3d7a59 docs(audit): product audit + improvement roadmap (t-paliad-015)
Post-Phase-A–J full-product audit: UX, code, content, architecture,
ops. 5 Critical findings (JWT signature bypass, dashboard Termine
leak, parteien/termin delete policy gap, @hoganlovells-only email
gate, CALDAV_ENCRYPTION_KEY missing from compose), 8 Important, 10
Polish, 11 Feature ideas, 14 tech-debt items. Each item has a file
reference and a concrete fix.

Top-two exploit-paths (detailed in §1):
  1. internal/auth/auth.go:178 — middleware decodes JWT exp but never
     verifies the signature; sub-claim is trusted downstream by every
     service. Any authenticated cookie → impersonate any user.
  2. internal/services/dashboard_service.go:245 — personal Termine
     leaked cross-user on the /dashboard "Kommende Termine" list
     (missing created_by filter on the akte_id IS NULL branch).
2026-04-18 01:22:23 +02:00
m
d0d4f624a1 docs: Phase J — roadmap rewrite + post-integration status
Rewrite docs/feature-roadmap.md per design-kanzlai-integration.md §5:
- All-in-one positioning: knowledge platform + Aktenverwaltung
- New Phase 0 (Aktenverwaltung Foundation) with shipped A–G items
- "What Paliad Is" replaces "What patholo Is NOT"
- Drop §2.3 UPC Rechtsprechungsübersicht (youpc.org link in Link Hub)
- Phase H (AI Frist-Extraktion) marked deferred
- Mark done items in prioritized backlog with completion dates
- Architecture Notes data-strategy: paliad schema + office-scoped RLS

Refresh .claude/CLAUDE.md:
- Aktenverwaltung + knowledge tools in Purpose
- Env var table incl. DATABASE_URL (Akten*/Fristen/Termine), CALDAV_ENCRYPTION_KEY
- Phase status (A–G shipped, H deferred, I pending)
- Akten naming convention (not "Mandate"/"cases")

Refresh README.md:
- Full feature list (Akten, Fristen, Termine, Dashboard + knowledge tools)
- Migration inventory (001–013), migration tracker note
- Env var table with usage semantics
- Project layout + current project status

Append "Post-Integration Status" section to design-kanzlai-integration.md:
- Per-phase shipment table with merge commits
- Phase H deferral note; Phase I pending note
- Phase J split: docs done here; infra retirement (Dokploy, schema drop,
  repo archive) pending head + m coordination
- Email-gate hardcode flagged for follow-up
2026-04-17 12:10:35 +02:00
m
1b2ef28334 feat(db): Phase A — paliad schema, RLS, migrations, golang-migrate
Implements docs/design-kanzlai-integration.md §8 Phase A.

Schema (paliad.*):
- users (extends auth.users) with office, practice_group, role
- akten with visibility columns: owning_office, collaborators uuid[],
  firm_wide_visible (per design §2)
- parteien, fristen, termine, dokumente, akten_events, notizen
  (polymorphic notes; notizen_exactly_one_parent CHECK)
- proceeding_types, deadline_rules, holidays (reference data)
- 4 feedback tables re-namespaced from public.* into paliad.*
  (handler swap to direct DB is a follow-up; old public tables stay
  intact for now and continue serving via PostgREST)

Visibility (paliad.can_see_akte):
- single SQL function, used by every RLS policy
- predicate: firm_wide_visible OR owning_office matches user's office
  OR auth.uid() ∈ collaborators OR user is admin
- mirrored at app layer in Phase B (defense in depth)

RLS (real, not permissive):
- akten: visibility predicate; insert restricted to own office or admin;
  delete restricted to partners + admins
- parteien/fristen/dokumente/akten_events: inherit via can_see_akte(akte_id)
- termine: personal (akte_id NULL) visible only to creator; Akte-linked
  follow visibility predicate
- notizen: paliad.notiz_is_visible() resolves polymorphic parent
- reference tables: SELECT for any authenticated user
- users: SELECT all; UPDATE/INSERT only self
- feedback tables: INSERT for any authenticated user (write-only)

Seed data (ported from KanzlAI seed_upc_timeline.sql):
- 7 proceeding_types (INF, REV, CCR, APM, APP, AMD, ZPO_CIVIL)
- 40 deadline_rules (32 UPC + 4 ZPO + 4 cross-type appeal spawns)
  including conditional logic: Reply rule code (RoP.029b → 029a) and
  Rejoinder duration (1mo → 2mo) flip when CCR active
- 55 holidays (DE federal 2026/2027 + UPC summer 2026 + UPC winter 26/27)

Indexes per audit §3.3 + visibility-predicate hot paths:
- akten: (status, owning_office), (owning_office), partial on
  firm_wide_visible, GIN on collaborators
- fristen: (status, due_date), (akte_id)
- termine: (start_at), (akte_id)
- akten_events: (akte_id, created_at DESC)
- notizen: 4 partial indexes per parent type
- users: (office), (role)

Migration tooling:
- golang-migrate/migrate/v4 with embed.FS source
- Migrations live in internal/db/migrations/ (Go embed can't reach
  outside the package; this is the conventional Go layout for embedded
  migrations)
- Applied at server startup before HTTP listener binds
- DATABASE_URL is optional today (existing knowledge tools work without
  DB); becomes required once Phase B services land
- Mock Supabase auth schema for local testing in
  internal/db/migrations/_dev/mock_supabase_auth.sql (excluded from
  embed pattern by the underscore prefix)

Other changes:
- Dockerfile: bump golang to 1.24, copy go.sum (audit §2.9), rename
  binary patholo → paliad
- docker-compose.yml: add DATABASE_URL passthrough
- README.md: rewritten to reflect Paliad brand + Phase A migration system

Verified locally:
- 11 migrations applied cleanly against postgres:16-alpine
- RLS enabled on all 15 paliad.* tables (verified via pg_class.relrowsecurity)
- Visibility predicate verified with 4-case scenario:
  - Alice (Munich associate): sees Munich + firm-wide + collab-on (t f t t)
  - Bob (Düsseldorf associate): sees Düsseldorf + firm-wide + collab-on (f t t t)
  - Carol (Munich partner): sees Munich + firm-wide only (t f t f)
  - Anonymous: sees firm-wide only (f f t f)
- migrate down + re-up cycle clean (initial 007 down had ordering bug,
  fixed: drop policies before referenced function)
- Existing endpoints (/, /login) return 302 + 200 — no regressions
2026-04-16 13:54:19 +02:00
m
5b92926db4 docs: revise integration design per m's feedback
Five changes from athena's review (paliad/athena → paliad/cronus):

1. §2 rewritten — office-scoped visibility from day one (NOT firm-wide).
   - paliad.users adds: office (required), practice_group (optional), role
   - paliad.akten adds: owning_office, collaborators uuid[], firm_wide_visible
   - SQL function paliad.can_see_akte(akte_id) used by every RLS policy
   - Visibility predicate: own office OR collaborator OR firm_wide OR admin
   - Real (not permissive) RLS policies enforced from Phase A
   - Defense in depth: app-layer ListVisibleForUser mirrors the predicate
   - Onboarding flow added (Phase D) so users self-identify office on signup

2. Mandate → Akten throughout (German end-to-end):
   - Tables: paliad.akten / parteien / fristen / termine / dokumente /
     akten_events / notizen
   - Go structs: Akte, Partei, Frist, Termin, Dokument, AkteEvent, Notiz
   - URLs: /akten, /akten/[id], /akten/[id]/{verlauf|fristen|...}
   - UI: "Akten", "Aktenverwaltung", "Zur Akte speichern" CTA on Fristenrechner
   - Naming convention table added in §3

3. §9 risk added: Outlook/Exchange CalDAV is limited; Phase F ships with
   CalDAV only (verified against dav.msbls.de + iCloud); long-term plan is
   Phase K = EWS / Microsoft Graph backend behind same sync abstraction.

4. Compliance/IT-approval unknown removed from §9 (m handles out of band).

5. Single-tenant risk replaced by visibility-model risk (now the
   security-critical layer); Phase A and B both gain Opus design reviews
   on the visibility predicate; Phase B integration test requires 3 users
   in 2 offices; pre-Phase J pen-test pass added.

Effort: 52h → 56h (Phase A +2h for visibility model, Phase D +2h for
onboarding + collaborator UI). Total with design ~59h, ~2-3 weeks.
2026-04-16 13:36:19 +02:00
m
1150bcbe6c docs: add KanzlAI → Paliad integration design
Strategic pivot: Paliad becomes all-in-one platform for HLC patent
practice (knowledge base + matter management). Design doc covers all 8
items from t-paliad-001:

- Integration strategy: full merge into Paliad's stack (single Go
  binary, single Supabase schema, single Dokploy deployment)
- Auth: drop multi-tenancy entirely (HLC is one tenant)
- Schema: paliad.* schema absorbs kanzlai.*; matters renames cases
- Feature prioritization: port deadlines/matters/appointments/CalDAV/
  dashboard/AI/notes; drop billing/RVG/multi-tenant infrastructure
- UI: single sidebar with 5 grouped sections; lime branding stays
- Deployment: kanzlai.msbls.de → 301 to paliad.de, retire KanzlAI app
- Roadmap update: rewrite "What patholo Is NOT" section, drop §2.3
  UPC Rechtsprechung (link to youpc.org), add Phase 0 matter mgmt
- Migration plan: 10 phases, ~52h coder time, ~2-3 weeks
- Risks: KanzlAI audit issues must be fixed during port (not carried
  forward); React → Bun TSX rewrite needs HTML-first discipline
2026-04-16 13:11:14 +02:00
m
ec33287c45 Merge remote-tracking branch 'origin/mai/knuth/gerichtsverzeichnis'
# Conflicts:
#	frontend/build.ts
#	frontend/src/client/i18n.ts
#	frontend/src/index.tsx
#	frontend/src/styles/global.css
#	internal/handlers/handlers.go
2026-04-16 11:08:25 +02:00
m
4139ed1225 feat: Gerichtsverzeichnis — court directory for patent practice
41 courts: UPC Court of Appeal, Central Division sections (Paris/Munich/Milan),
13 Local Divisions, Nordic-Baltic Regional Division, 10 German courts
(LG, OLG, BGH, BPatG, DPMA), EPO (Munich HQ, Haar boards, Rijswijk), and
9 national courts (NL, UK, FR, IT). Addresses verified against official
sources; uncertain details left empty rather than guessed.

New page at /gerichte with search, dual filter pills (type + country),
expandable cards, print-friendly CSS, Supabase feedback (gerichte_feedback).

Migration at docs/migrations/002_gerichte_feedback.sql.
2026-04-16 10:51:02 +02:00
m
40ff17657f feat: Checklisten — interactive filing checklists with localStorage state
Six bilingual patent-workflow checklists (UPC Statement of Claim, Defence,
Confidentiality Application, Representative Registration; BPatG Nullity;
EPO Opposition) with grouped items, rule references, and tips. Index page
lists cards with regime filter and per-checklist progress; detail page
persists check state in localStorage (patholo:checklist:<slug>), shows a
live progress bar, supports reset and print, and submits feedback via
Supabase checklisten_feedback.
2026-04-16 10:48:42 +02:00
m
f66a2ed906 feat: Link Hub — curated external links page with collaborative features
New /links page with 22 curated links across 5 categories:
- Gerichte & Ämter (UPC CMS, EPO, DPMA, BPatG, EUIPO)
- Recherche (Espacenet, DPMAregister, DEPATISnet, Google Patents, WIPO)
- UPC (Rules of Procedure, Fees, Practice Directions)
- Gesetze (PatG, EPÜ, UPCA, GKG, RVG, ZPO via dejure.org)
- HL Intern (placeholder links)

Features:
- Client-side category filter tabs
- "Link vorschlagen" button with modal form (POST /api/links/suggest)
- Per-card feedback icon with modal (POST /api/links/feedback)
- Pending suggestion count badge
- Full DE/EN i18n support
- Static link data served via GET /api/links (Go map)
- Supabase PostgREST integration for suggestions/feedback storage
- Sidebar nav entry with chain-link icon

Supabase migration in docs/migrations/001_link_suggestions.sql
(needs to be applied on ydb.youpc.org before collaborative features work).
2026-04-14 20:07:43 +02:00
m
83cc20e7ba feat: patholo.de feature roadmap — 17 features across 4 phases
Comprehensive feature roadmap for patholo.de based on analysis of:
- Current patholo codebase (tools, auth, downloads, i18n)
- KanzlAI project (case management system — complementary, not competing)
- mWorkRepo (UPC knowledge base, templates, model documents, training)

4 phases prioritized by impact/effort:
- Phase 1: Link Hub, More Downloads, Gebührentabellen, Kostenrechner enhancements, Glossar
- Phase 2: Verfahrensleitfäden, Gerichtsverzeichnis, UPC Rechtsprechung, Checklisten
- Phase 3: Global Search, Vorlagenbibliothek, Schulungsbereich, Benachrichtigungen
- Phase 4: KI-Recherche, Fristenkalender, Collaborative Annotations, Mandantenkosten-Report

Key insight: patholo is knowledge platform + toolkit, not case management.
2026-04-14 19:55:10 +02:00
m
2919e1afc4 feat: design document for Prozesskostenrechner + Fristenrechner
Comprehensive design for two interactive tools:
- Prozesskostenrechner: DE (LG/OLG/BGH/BPatG), UPC, and EPA cost estimates
- Fristenrechner: Patent deadline calculator with holiday adjustment

Covers UI layout, data models, API contracts, calculation logic,
fee tables (GKG/RVG/PatKostG/UPC/EPA), deadline rules for all
proceeding types, and phased implementation plan.

Key differentiator: EPA proceedings coverage (not in KanzlAI).
2026-04-14 17:12:16 +02:00