Atomic extraction of the deadline-rule compute engine + types from
internal/services into a new pkg/litigationplanner package that paliad
+ youpc.org can both import. No behaviour change — every existing test
passes against the post-move shape.
Package contents (~1850 LoC):
- doc.go package docstring + reuse manifesto
- types.go Rule, ProceedingType, NullableJSON, AdjustmentReason,
HolidayDTO, CalcOptions, CalcRuleParams, Timeline,
TimelineEntry, RuleCalculation*, FristenrechnerType,
ProjectHint, sentinel errors
- catalog.go Catalog interface (proceeding + rule lookups)
- holidays.go HolidayCalendar interface
- courts.go CourtRegistry interface + DefaultsForJurisdiction +
country/regime constants
- expr.go EvalConditionExpr + HasConditionExpr +
ExtractFlagsFromExpr (jsonb gate evaluator)
- durations.go ApplyDuration + AddWorkingDays (pure compute)
- subtrack.go SubTrackRouting + LookupSubTrackRouting registry
- legal_source.go FormatLegalSourceDisplay + BuildLegalSourceURL
- proceeding_mapping.go MapLitigationToFristenrechner + code constants
(CodeUPCInfringement, CodeDEInfringementLG, ...)
- engine.go Calculate + CalculateRule + the trigger-event
branch + applyRuleOverrides (the big move)
paliad side (~1900 LoC net deletion):
- internal/services/fristenrechner.go shrinks from 1505 → ~290 lines
(thin paliad Catalog adapter + type aliases for back-compat).
- internal/models/models.go: DeadlineRule, ProceedingType, NullableJSON
become type aliases to litigationplanner.* — every sqlx scan and
every projection_service caller compiles unchanged.
- internal/services/holidays.go: AdjustmentReason + HolidayDTO become
aliases to lp.* (canonical definitions now in the package).
- internal/services/proceeding_mapping.go: rewritten as thin re-exports
of lp constants + helpers.
- internal/services/deadline_search_service.go: FormatLegalSourceDisplay
+ BuildLegalSourceURL replaced with delegating wrappers to lp.
Catalog interface satisfaction:
- DeadlineRuleService → paliadCatalog adapter (wraps the existing
service, replicates the original SELECT shapes).
- HolidayService → satisfies lp.HolidayCalendar directly (compile-
time assertion at end of fristenrechner.go).
- CourtService → satisfies lp.CourtRegistry directly.
Wire shape is byte-identical. JSON tags on Rule / ProceedingType /
Timeline / TimelineEntry / RuleCalculation match the historical
UIResponse / UIDeadline shape; the frontend reads the same bytes.
Slice B (Catalog interface + paliad loader cleanup) is folded into
this commit since Slice A already needs the interfaces to call
Calculate across the boundary. Slice C (embedded UPC snapshot +
generator) is the next coder shift; the Berufung unification m
called out lands in Slice B/C per head's brief.
Refs: docs/design-litigation-planner-2026-05-26.md
54 lines
2.7 KiB
Go
54 lines
2.7 KiB
Go
package litigationplanner
|
|
|
|
// SubTrackRouting describes a proceeding type that has no native rules
|
|
// of its own and is normally rendered inside a parent proceeding's flow
|
|
// with one or more condition flags enabled. The Procedure Roadmap
|
|
// (verfahrensablauf) routes calc requests for these codes to the parent
|
|
// proceeding + default flags, but preserves the user-picked code/name
|
|
// in the response identity and surfaces a contextual note explaining
|
|
// the framing — see m/paliad#58 and the design doc cited above.
|
|
//
|
|
// Adding a new sub-track is a data-only change here: extend
|
|
// SubTrackRoutings with the (code, parent, flags, note) tuple and the
|
|
// renderer picks it up automatically. The note copy lives in this file
|
|
// because it's semantic to the routing, not UI chrome.
|
|
type SubTrackRouting struct {
|
|
// Code is the user-picked proceeding code (e.g. "upc.ccr.cfi").
|
|
Code string
|
|
// ParentCode is the proceeding whose rules to use (e.g. "upc.inf.cfi").
|
|
ParentCode string
|
|
// DefaultFlags are merged into the user's flag set so the
|
|
// gated rules render. Order is preserved.
|
|
DefaultFlags []string
|
|
// NoteDE / NoteEN are the contextual banner above the timeline,
|
|
// explaining that the proceeding type is normally a sub-track.
|
|
// Plain text — the frontend renders them as a banner.
|
|
NoteDE string
|
|
NoteEN string
|
|
}
|
|
|
|
// SubTrackRoutings — single-source-of-truth registry. Today: just CCR.
|
|
// The pattern generalises to other "sub-track" proceeding types (e.g.
|
|
// R.30 application to amend the patent as a standalone roadmap, R.46
|
|
// preliminary objection) once they have a proceeding-type code of their
|
|
// own. New entries here are picked up by the spawn-as-standalone
|
|
// renderer in Calculate without further wiring.
|
|
var SubTrackRoutings = map[string]SubTrackRouting{
|
|
CodeUPCCounterclaim: {
|
|
Code: CodeUPCCounterclaim,
|
|
ParentCode: CodeUPCInfringement,
|
|
DefaultFlags: []string{"with_ccr"},
|
|
NoteDE: "Die Nichtigkeitswiderklage läuft normalerweise innerhalb eines UPC-Verletzungsverfahrens mit aktiver Nichtigkeitswiderklage. Diese Zeitleiste zeigt das Verletzungsverfahren mit gesetztem with_ccr-Flag.",
|
|
NoteEN: "The counterclaim for revocation normally runs inside a UPC infringement action with the counterclaim flag set. This timeline shows the infringement action with with_ccr automatically enabled.",
|
|
},
|
|
}
|
|
|
|
// LookupSubTrackRouting returns the sub-track routing for a proceeding
|
|
// code, or (zero, false) if the code is not a sub-track. Used by the
|
|
// fristenrechner Calculate path to spawn the parent flow with the sub-
|
|
// track's default flags.
|
|
func LookupSubTrackRouting(code string) (SubTrackRouting, bool) {
|
|
r, ok := SubTrackRoutings[code]
|
|
return r, ok
|
|
}
|