Skip to content

feat(storage): scaffold Caliber.Webhooks.EntityFrameworkCore (DbContext + schema) (S1 of #37)#57

Merged
williamdewitt merged 1 commit into
mainfrom
feat/m45-efcore-scaffold
Jun 27, 2026
Merged

feat(storage): scaffold Caliber.Webhooks.EntityFrameworkCore (DbContext + schema) (S1 of #37)#57
williamdewitt merged 1 commit into
mainfrom
feat/m45-efcore-scaffold

Conversation

@williamdewitt

Copy link
Copy Markdown
Owner

What

Foundation for the durable SQLite store — sub-task 1 of 3 for #37, under the M2 epic (#8). A new multi-target provider project, Caliber.Webhooks.EntityFrameworkCore, maps the M1 domain (WebhookMessage/Endpoint) to the messages/endpoints schema via EF Core and creates it with ensure-created. No store logic yet — no IMessageStore/IEndpointStore implementations (those are #46 and #47).

Highlights

  • New project src/Caliber.Webhooks.EntityFrameworkCore (net8.0;net10.0), in the solution. The core package stays dependency-free — EF deps are isolated to the provider.
  • Durable snake_case schema contract locked by a test: UNIQUE (event_id, endpoint_id) for idempotent fan-out, (status, next_attempt_at) for the due-message claim query, subscribed_event_types stored as JSON (null = subscribe-all).
  • Schema-contract smoke test — creates the schema on a real SQLite file, asserts the column set and the unique index. The EF project is intentionally outside Stryker's scope (core-only) for now; mutation coverage of the store logic follows with feat(storage): EfMessageStore — SQL claim (UPDATE … RETURNING) + idempotent fan-out #46/feat(storage): EfEndpointStore + UseSqlite() opt-in + docs #47.

Dependency decisions (the non-obvious bits)

  • EF Core Sqlite pinned to 8.0.28 via CPM — the net8 floor, same policy as the Extensions packages. Its transitive Microsoft.Extensions.* sit at 8.0.x, so CentralPackageTransitivePinningEnabled stays conflict-free. EF Core 10 would drag those transitives to 10.x and trip NU1109 against the 8.0.0 pins.
  • Raised *.Abstractions floor to 8.0.2 — the graph's real transitive minimum (Http 8.0.0 → Logging 8.0.1 → *.Abstractions >= 8.0.2). The core project masked this by referencing them directly (authoritative); a provider that pulls them only transitively trips NU1109 without this.
  • Pinned SQLitePCLRaw.bundle_e_sqlite3 to 2.1.11 and accepted CVE-2025-6965 (GHSA-2m69-gcr7-jv3q, High) via a documented, narrow NuGetAuditSuppress. It's a native-SQLite bug (< 3.50.2) with no fixed SQLitePCLRaw release, reachable only via attacker-controlled SQL — which this store never runs (EF-generated SQL, bound parameters only). Rationale + a "remove when upstream patches" trigger are in Directory.Build.props.

Verification

  • dotnet build -c Release — green on net8.0 + net10.0, zero warnings (warnings-as-errors + Meziantou + analyzers).
  • dotnet test155 passed on both TFMs.
  • dotnet pack.nupkg + .snupkg produced.

risk:core — for human review + merge.

Closes #45.

…xt + schema)

Foundation for the durable SQLite store: sub-task 1 of 3 for #37, under M2 epic #8.
A new multi-target (net8.0;net10.0) provider project maps the M1 domain
(WebhookMessage/Endpoint) to the messages/endpoints schema via EF Core, created
with ensure-created. No store logic yet — no IMessageStore/IEndpointStore impls
(those are #46 and #47).

- New src/Caliber.Webhooks.EntityFrameworkCore wired into the solution; the core
  package stays dependency-free (EF deps isolated to the provider).
- Durable snake_case schema contract: a UNIQUE (event_id, endpoint_id) index for
  idempotent fan-out, a (status, next_attempt_at) index for the due-message claim
  query, and EventTypes stored as JSON (null = subscribe-all).
- EF Core Sqlite pinned via CPM to 8.0.28 — the net8 floor, same policy as the
  Extensions packages; its transitive Microsoft.Extensions.* stay at 8.0.x so
  CentralPackageTransitivePinningEnabled stays conflict-free (EF 10 would drag
  them to 10.x and trip NU1109).
- Fix two latent CPM issues the provider surfaced: raise the *.Abstractions floor
  to 8.0.2 (the graph's real transitive minimum via Http; the core masked it with
  direct references) and pin SQLitePCLRaw.bundle_e_sqlite3 to 2.1.11.
- Accept CVE-2025-6965 (GHSA-2m69-gcr7-jv3q) via a documented, narrow NuGet audit
  suppression: a native-SQLite bug with no fixed release, reachable only via
  attacker-controlled SQL — which this store never runs (EF-generated SQL, bound
  parameters only).
- Schema-contract smoke test creates the schema on a real SQLite file and pins the
  column + unique-index contract. 155 tests green on net8.0 + net10.0, zero warnings.

Closes #45.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions github-actions Bot added the risk:low tests/samples; CI green + light approval label Jun 27, 2026
@williamdewitt williamdewitt added risk:core src/Caliber.Webhooks; code-owner review (Opus, high effort) and removed risk:low tests/samples; CI green + light approval labels Jun 27, 2026
@williamdewitt williamdewitt merged commit 6197283 into main Jun 27, 2026
9 checks passed
@williamdewitt williamdewitt deleted the feat/m45-efcore-scaffold branch June 27, 2026 08:35
williamdewitt added a commit that referenced this pull request Jun 27, 2026
…#58)

isCore only matched `src/Caliber.Webhooks/` (trailing slash), so sibling provider
projects (e.g. src/Caliber.Webhooks.EntityFrameworkCore/, added in #57) and the root
build infra (Directory.Build.props/Directory.Packages.props — repo-wide deps and
analyzers) fell through to risk:low. PR #57 had to be relabelled core by hand, and
every M2 storage-provider PR would mis-classify the same way.

Broaden isCore to the whole src/ tree plus the root build-props files. Critical still
wins by precedence (public API / migrations / security source), and .github/workflows/**
stays core. No behaviour change for the existing core lib or trivial-docs auto-merge.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:core src/Caliber.Webhooks; code-owner review (Opus, high effort)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(storage): scaffold Caliber.Webhooks.EntityFrameworkCore (DbContext + schema, ensure-created)

1 participant