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
50 lines
2.4 KiB
Go
50 lines
2.4 KiB
Go
package litigationplanner
|
|
|
|
import "context"
|
|
|
|
// Catalog supplies proceeding-type metadata + rules for the calculator.
|
|
//
|
|
// Implementations:
|
|
// - paliad: reads paliad.deadline_rules + paliad.proceeding_types,
|
|
// filtered to lifecycle_state='published' AND is_active=true.
|
|
// ProjectHint scopes future per-project rule merges.
|
|
// - embedded/upc (Slice C): in-memory map keyed by code, populated
|
|
// once at init from the embedded JSON snapshot.
|
|
//
|
|
// All methods return ErrUnknownProceedingType / ErrUnknownRule when the
|
|
// caller asks for a code/id that doesn't exist in the catalog.
|
|
type Catalog interface {
|
|
// LoadProceeding returns the proceeding-type metadata + the full
|
|
// rule list (sorted by sequence_order). Caller passes the user-
|
|
// facing proceeding code (e.g. "upc.inf.cfi"). The hint scopes a
|
|
// future per-project rule merge — implementations that don't
|
|
// support projects ignore it.
|
|
LoadProceeding(ctx context.Context, code string, hint ProjectHint) (*ProceedingType, []Rule, error)
|
|
|
|
// LoadProceedingByID is the resolver used by CalculateRule when it
|
|
// has a rule + needs the rule's parent proceeding metadata.
|
|
LoadProceedingByID(ctx context.Context, id int) (*ProceedingType, error)
|
|
|
|
// LoadRuleByID resolves a rule UUID to the rule row. Used by
|
|
// CalculateRule when the caller supplies CalcRuleParams.RuleID.
|
|
LoadRuleByID(ctx context.Context, ruleID string) (*Rule, error)
|
|
|
|
// LoadRuleByCode resolves a rule by (proceedingCode, submissionCode)
|
|
// + returns the parent proceeding for use in the response identity.
|
|
// Used by CalculateRule when the caller supplies the (code, local)
|
|
// pair from a concept-card pill.
|
|
LoadRuleByCode(ctx context.Context, proceedingCode, submissionCode string) (*Rule, *ProceedingType, error)
|
|
|
|
// LoadRulesByTriggerEvent lists Pipeline-C trigger-event-rooted
|
|
// rules (rules whose trigger_event_id matches). Used by
|
|
// EventDeadlineService → Calculate via CalcOptions.TriggerEventIDFilter.
|
|
LoadRulesByTriggerEvent(ctx context.Context, triggerEventID int64) ([]Rule, error)
|
|
|
|
// LoadTriggerEventsByIDs bulk-loads paliad.trigger_events rows
|
|
// for the conditional-label override (t-paliad-294 /
|
|
// m/paliad#126). Returns a map keyed by event id; missing ids
|
|
// are simply absent (caller treats absence as "no override").
|
|
// Empty input returns an empty map without a DB roundtrip.
|
|
LoadTriggerEventsByIDs(ctx context.Context, ids []int64) (map[int64]TriggerEvent, error)
|
|
}
|