PR-1 of the Unified Fristenrechner. Purely additive: new search-grouping layer + per-rule date override capability. No coverage changes yet (those land in PR-2 = Phase B1 UPC counterclaim cross-flows). Migrations: - 037: paliad.deadline_concepts (id, slug, name_de/en, aliases text[], party, category, sort_order). Trigram + GIN indexes for the search bar. - 038: deadline_rules.concept_id (uuid FK), legal_source (text); event_deadlines.legal_source; trigger_events.concept_id (text slug, soft-link — youpc imports keep their bigint PK). - 039: deadline_rules.condition_flag text → text[] (USING ARRAY[old]). Semantic: rule renders iff every element is in CalcOptions.Flags. Single-element arrays preserve the legacy with_ccr swap exactly. - 040: seed 30 concept rows + backfill all 74 fristenrechner deadline_rules with concept_id; backfill legal_source from existing rule_code (e.g. 'RoP.023' → 'UPC.RoP.23.1', '§ 276 ZPO' → 'DE.ZPO.276.1', 'Art. 108 EPÜ' → 'EU.EPÜ.108', 'R. 79(1) EPÜ' → 'EU.EPC-R.79.1'). Calculator (services/fristenrechner.go): - ConditionFlag is now pq.StringArray (matches text[] schema). New allFlagsSet() helper gates rule rendering; rules with multi-element flags require ALL of them set (prep for Phase B1 with_amend ∧ with_cci). - CalcOptions.AnchorOverrides map[string]string (rule_code → YYYY-MM-DD). The tree-walk consults overrideDates[parent.code] before reading the computed-date map; lets a downstream rule re-anchor on a user-set date. - IsCourtSet rows that get an override stop being placeholder and emit the user's date as a real anchor (so downstream cost_app etc. compute off it). New IsOverridden flag in UIDeadline so the UI can highlight user-edited rows. - LegalSource surfaced on UIDeadline for future search-card display. UI (frontend/src/client/fristenrechner.ts + global.css + i18n): - Each timeline / column rule date is click-to-edit. Click → inline date input → blur or Enter → POST with anchorOverrides → re-render. Empty value clears the override. Escape cancels. Root-event rows (the trigger anchor) stay non-editable — that's the trigger-date input. - Override map cleared on proceeding switch / reset; persists across trigger-date / flag toggle changes within the same proceeding. - New CSS: subtle hover underline on .frist-date-edit; lime border on .timeline-date--overridden + .frist-date-edit-input. - New i18n key deadlines.date.edit.hint (DE + EN). Handler (handlers/fristenrechner.go): - POST body gains optional anchorOverrides map<string,string>; passed through to CalcOptions. Tests: - TestAllFlagsSet covers single-flag legacy semantic, two-flag AND semantic, empty-required unconditional, extra-flags-no-effect. - Existing TestIsCourtDeterminedRule unchanged. Phase A ships standalone — Phase B1 (UPC counterclaim cross-flows) and Phase C/D (search backend + concept-card UI) follow.
31 lines
1.5 KiB
SQL
31 lines
1.5 KiB
SQL
-- t-paliad-131 Phase A3: condition_flag text → text[].
|
|
--
|
|
-- The current scalar column supports "rule renders only if ONE flag is
|
|
-- set". The Phase B1 UPC counterclaim cross-flows need conditional rules
|
|
-- that depend on TWO flags simultaneously (e.g. UPC_INF Application to
|
|
-- amend requires both `with_ccr` AND `with_amend`; UPC_REV chains require
|
|
-- with_amend AND/OR with_cci as independent gates).
|
|
--
|
|
-- New semantic: rule renders iff condition_flag is NULL/empty OR every
|
|
-- element of condition_flag is present in the caller's flag set.
|
|
-- Single-element arrays preserve the old behaviour exactly — the existing
|
|
-- two `with_ccr` rules on UPC_INF migrate cleanly via ARRAY['with_ccr'].
|
|
--
|
|
-- The matching code change in internal/services/fristenrechner.go ships
|
|
-- in the same PR; both must land together.
|
|
|
|
ALTER TABLE paliad.deadline_rules
|
|
ALTER COLUMN condition_flag TYPE text[]
|
|
USING (CASE WHEN condition_flag IS NULL THEN NULL
|
|
ELSE ARRAY[condition_flag]
|
|
END);
|
|
|
|
COMMENT ON COLUMN paliad.deadline_rules.condition_flag IS
|
|
'Flag-conditioned rule. Array of flag codes; rule renders iff every '
|
|
'element is present in CalcOptions.Flags. NULL/empty = unconditional. '
|
|
'When set + all flags satisfied AND alt_duration_value is non-NULL, '
|
|
'the calculator swaps to alt_duration_value/alt_duration_unit/'
|
|
'alt_rule_code (existing semantic preserved). When set + flags not '
|
|
'satisfied, the rule is suppressed entirely (new semantic for Phase '
|
|
'B1 cross-flow rules that should not appear without their flag).';
|