Plan: Store Parameter-Struct Refactor

On this page

Status

Filed by platform-stabilization Step 14. Implementation completed 2026-05-03.

Step Description Status

1

File this plan + nav entry; survey the ~40+ affected store fns; group by service.

Done (pre-ADR-030) — filed 2026-05-01; survey produced verified count of 80 sites — 24 craig-cases + 14 craig-placement + 12 craig-exchange + 8 craig-financial + 17 craig-security + 3 craig-reporting + 1 craig-rules + 0 craig-intake

2

Conversion in craig-cases (largest set).

Done (2026-05-03) — MR !188

3

Conversion in craig-placement / craig-financial / craig-reporting / craig-security / craig-exchange / craig-rules.

Done (2026-05-03) — MR !189

4

Drop the now-redundant #[allow(clippy::too_many_arguments, reason = "deferred mechanical refactor — see …​")] annotations.

Done (pre-ADR-030) — inline with Steps 2 + 3 — annotations dropped at the same time the param structs were introduced

5

Plan completion audit + archive.

Done (pre-ADR-030)

Issue: #272 (closed by !189)
MRs: !188 (Step 2 — pilot, 21 fns) / !189 (Step 3 — bundle, 55 fns)

Context

Across the stateful CRAIG services, ~40+ store fns currently use 7-13 positional &str/Option<&str>/Uuid arguments. They’re silenced with #[allow(clippy::too_many_arguments, reason = "deferred mechanical refactor …​")] annotations that point at this plan.

The platform-stabilization plan (Steps 8 + 12) added executor-generic signatures (<'e, E: sqlx::PgExecutor<'e>>) to many of these fns when wiring up the transactional outbox. The signatures are now even longer, making the parameter-struct refactor more valuable — but also more mechanical.

Scope

In scope:

  • Replace each long-parameter-list store fn with a typed parameter struct (Create<Resource>Params, Update<Resource>Params).

  • Update every caller (services + tests) to construct the struct.

  • Drop the #[allow(clippy::too_many_arguments)] annotations.

  • Preserve executor-generic signatures from Steps 8/12.

Out of scope:

  • Schema changes.

  • Behavior changes.

  • New endpoints or features.

Risks

  • High touch-count — every caller of every refactored store fn updates. Type system enforces completeness, but the diff is large.

  • Test fixture builders need updating where they construct param tuples directly. craig-test-lib’s PersonBuilder etc. already use struct shapes; no change needed there.

Open questions

  1. Naming convention: CreatePersonParams vs CreatePersonInput vs CreatePersonRow. Pick one and stick with it across the workspace.

  2. Lifetime-parameter shape: structs with &str borrows tie the struct lifetime to the caller stack frame. Acceptable for the common pattern; review if any store fn currently holds the param tuple across an .await boundary that would block ownership.

  3. Migration cadence: one MR per service vs one bundle. Steps 8 and 12 of platform-stabilization showed the pattern works either way; reviewer-tractability is the deciding factor.

After this plan lands

The #[allow(clippy::too_many_arguments, reason = "deferred mechanical refactor …​")] annotations across the workspace go to zero, closing the citation chain that pointed at data-integrity-hardening.adoc § Deferred (Store Parameter Structs).

Edit this page · latest