Verfahrensablauf: sort post-trigger optional events by duration ascending (14d → 1mo → 2mo …) #128

Open
opened 2026-05-26 09:11:48 +00:00 by mAi · 1 comment
Collaborator

m's report (2026-05-26 11:11)

In the post-decision optional-events section, the four R.118.4 / R.151 / R.353 / R.220.1 rows render in catalog order, not by duration. m's expectation:

Optional events following other events (like here the appeals after a decision) should be sorted by their duration because that defines the likely sequence. So if there is a 14days deadline, it must be before the 1 month which must be before 2 months

Expected order (post-Entscheidung, ascending duration):

  1. (any 14-day rules here, e.g. R.262.2 if anchored on the decision)
  2. 1-month: R.151 Antrag auf Kostenentscheidung
  3. 1-month: R.353 Antrag auf Berichtigung
  4. 2-month: R.118.4 Antrag auf Folgeentscheidungen
  5. 2-month: R.220.1 Berufung gegen Endentscheidung

Currently they're interleaved (Folgeentscheidungen first even though 2-month).

What to do

  1. In internal/services/projection_service.go (or the rendering path in frontend/src/client/views/verfahrensablauf-core.ts), sort the rules WITHIN the same trigger-event group by:
    • duration_unit weight: days < weeks < months
    • duration_value ascending within same unit
    • then by submission_code ASC as a stable secondary sort
  2. Only apply within rules that share the same parent_id / trigger_event_id. Don't reorder across different trigger groups.
  3. Court-set / conditional rules (knuth #121) without a duration value sort LAST in their group (their date is unknown — they don't fit the duration ladder).
  4. Verify against m's example: the four post-decision rules render with R.151 + R.353 first (1-month), then R.118.4 + R.220.1 (2-month).

Files most likely touched

  • internal/services/fristenrechner.go (or projection_service.go) — sorting in the projection result
  • internal/services/fristenrechner_test.go — regression test with the post-decision group
  • Possibly frontend/src/client/views/verfahrensablauf-core.ts if sorting happens client-side

Hard rules

  • Don't change the trigger-event grouping — same set of rules render under same trigger, just reordered within.
  • Don't change durations — read-only sort.
  • Conditional rows (no concrete date) sort LAST within their group.
  • go build ./... && go test ./internal/... && cd frontend && bun run build clean.
  • Branch: mai/<worker>/sort-rules-by-duration.

Out of scope

  • Sorting across trigger groups (those keep their proceeding-sequence order).
  • Adding new sort options to the UI (this is the canonical sort).
  • Reordering main-track rules (those follow proceeding sequence).

Reporting

mai report completed with branch + SHAs + UX path: open the example UPC inf project with a decision date → confirm the post-decision optional events render 1-month rules (R.151, R.353) before 2-month rules (R.118.4, R.220.1).

## m's report (2026-05-26 11:11) In the post-decision optional-events section, the four R.118.4 / R.151 / R.353 / R.220.1 rows render in catalog order, not by duration. m's expectation: > Optional events following other events (like here the appeals after a decision) should be sorted by their duration because that defines the likely sequence. So if there is a 14days deadline, it must be before the 1 month which must be before 2 months Expected order (post-Entscheidung, ascending duration): 1. (any 14-day rules here, e.g. R.262.2 if anchored on the decision) 2. **1-month**: R.151 Antrag auf Kostenentscheidung 3. **1-month**: R.353 Antrag auf Berichtigung 4. **2-month**: R.118.4 Antrag auf Folgeentscheidungen 5. **2-month**: R.220.1 Berufung gegen Endentscheidung Currently they're interleaved (Folgeentscheidungen first even though 2-month). ## What to do 1. In `internal/services/projection_service.go` (or the rendering path in `frontend/src/client/views/verfahrensablauf-core.ts`), sort the rules WITHIN the same trigger-event group by: - `duration_unit` weight: days < weeks < months - `duration_value` ascending within same unit - then by `submission_code` ASC as a stable secondary sort 2. Only apply within rules that share the same `parent_id` / `trigger_event_id`. Don't reorder across different trigger groups. 3. Court-set / conditional rules (knuth #121) without a duration value sort LAST in their group (their date is unknown — they don't fit the duration ladder). 4. Verify against m's example: the four post-decision rules render with R.151 + R.353 first (1-month), then R.118.4 + R.220.1 (2-month). ## Files most likely touched - `internal/services/fristenrechner.go` (or `projection_service.go`) — sorting in the projection result - `internal/services/fristenrechner_test.go` — regression test with the post-decision group - Possibly `frontend/src/client/views/verfahrensablauf-core.ts` if sorting happens client-side ## Hard rules - **Don't change the trigger-event grouping** — same set of rules render under same trigger, just reordered within. - **Don't change durations** — read-only sort. - Conditional rows (no concrete date) sort LAST within their group. - `go build ./... && go test ./internal/... && cd frontend && bun run build` clean. - Branch: `mai/<worker>/sort-rules-by-duration`. ## Out of scope - Sorting across trigger groups (those keep their proceeding-sequence order). - Adding new sort options to the UI (this is the canonical sort). - Reordering main-track rules (those follow proceeding sequence). ## Reporting `mai report completed` with branch + SHAs + UX path: open the example UPC inf project with a decision date → confirm the post-decision optional events render 1-month rules (R.151, R.353) before 2-month rules (R.118.4, R.220.1).
mAi self-assigned this 2026-05-26 09:11:48 +00:00
Author
Collaborator

ritchie shift-1 progress (2026-05-26)

Branch: mai/ritchie/coder-sort-post-trigger
Commit: 49ddaa4

What landed

  • internal/services/fristenrechner.go — new sortDeadlinesByDurationWithinTriggerGroup step in Calculate() right after the rule-evaluation loop. Walks consecutive runs of deadlines whose underlying rule shares the same (parent_id, trigger_event_id) and reorders each run in place by duration ASC.
    • Sort key: court-set / conditional LAST → duration_unit weight (days/working_days=0, weeks=1, months=2, years=3) → duration_value ASC → submission_code ASC.
    • Root rules (no parent, no trigger_event_id) are explicitly skipped from sort — they're distinct anchor points whose proceeding-sequence order is non-negotiable.
    • Different trigger groups keep their original position; the chunk walk only ever permutes adjacent same-group rows.
  • internal/services/fristenrechner_sort_test.go — 5 pure-function tests:
    1. PostDecision — canonical four-rule scenario from m's report: cost_app + rectification (1mo) before appeal_spawn + cons_orders (2mo).
    2. UnitWeight — days < weeks < months < years tier ordering.
    3. NoCrossGroupReorder — interleaved groups stay interleaved.
    4. ConditionalLastIsConditional / IsCourtSet rows pinned to the bottom of their group.
    5. RootsNotMerged — top-level rules never sort against each other.

Verification

  • go build ./... clean.
  • go test ./internal/... all green (180+ tests).
  • bun test 181/181 pass.
  • bun run build produces dist/ without errors.

Note on within-tier tiebreak

The spec called for submission_code ASC as the secondary sort, which puts appeal_spawn before cons_orders within the 2-month tier (a < c). m's expected listing in the issue body has them in rule-code order (R.118 before R.220). Tier-level intent (1-month tier before 2-month tier) is met either way; flagged here in case m wants rule_code ordering instead — would be a one-line tiebreak swap.

UX path to confirm in browser

Open any UPC inf project with a decision date set, scroll to the post-decision optional-events block, verify 1-month rules (R.151 Antrag auf Kostenentscheidung, R.353 Antrag auf Berichtigung) render before 2-month rules (R.118.4 Folgeentscheidungen, R.220.1 Berufung gegen Endentscheidung).

Commit: 49ddaa4eb8

## ritchie shift-1 progress (2026-05-26) **Branch:** `mai/ritchie/coder-sort-post-trigger` **Commit:** 49ddaa4 ### What landed - `internal/services/fristenrechner.go` — new `sortDeadlinesByDurationWithinTriggerGroup` step in `Calculate()` right after the rule-evaluation loop. Walks consecutive runs of deadlines whose underlying rule shares the same `(parent_id, trigger_event_id)` and reorders each run in place by duration ASC. - Sort key: court-set / conditional LAST → duration_unit weight (days/working_days=0, weeks=1, months=2, years=3) → duration_value ASC → submission_code ASC. - Root rules (no parent, no trigger_event_id) are explicitly skipped from sort — they're distinct anchor points whose proceeding-sequence order is non-negotiable. - Different trigger groups keep their original position; the chunk walk only ever permutes adjacent same-group rows. - `internal/services/fristenrechner_sort_test.go` — 5 pure-function tests: 1. `PostDecision` — canonical four-rule scenario from m's report: cost_app + rectification (1mo) before appeal_spawn + cons_orders (2mo). 2. `UnitWeight` — days < weeks < months < years tier ordering. 3. `NoCrossGroupReorder` — interleaved groups stay interleaved. 4. `ConditionalLast` — `IsConditional` / `IsCourtSet` rows pinned to the bottom of their group. 5. `RootsNotMerged` — top-level rules never sort against each other. ### Verification - `go build ./...` clean. - `go test ./internal/...` all green (180+ tests). - `bun test` 181/181 pass. - `bun run build` produces dist/ without errors. ### Note on within-tier tiebreak The spec called for `submission_code` ASC as the secondary sort, which puts `appeal_spawn` before `cons_orders` within the 2-month tier (a < c). m's expected listing in the issue body has them in rule-code order (R.118 before R.220). Tier-level intent (1-month tier before 2-month tier) is met either way; flagged here in case m wants rule_code ordering instead — would be a one-line tiebreak swap. ### UX path to confirm in browser Open any UPC inf project with a decision date set, scroll to the post-decision optional-events block, verify 1-month rules (R.151 Antrag auf Kostenentscheidung, R.353 Antrag auf Berichtigung) render before 2-month rules (R.118.4 Folgeentscheidungen, R.220.1 Berufung gegen Endentscheidung). Commit: https://mgit.msbls.de/m/paliad/commit/49ddaa4eb8127062fdbb9ad982dd048798be6b78
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: m/paliad#128
No description provided.