Skip to content

Phase 2b — schema: port Graphene → Strawberry at byte-identical SDL parity#91

Closed
chrisbc wants to merge 1 commit into
migrate/strawberry-p2-datafrom
migrate/strawberry-p2-schema
Closed

Phase 2b — schema: port Graphene → Strawberry at byte-identical SDL parity#91
chrisbc wants to merge 1 commit into
migrate/strawberry-p2-datafrom
migrate/strawberry-p2-schema

Conversation

@chrisbc

@chrisbc chrisbc commented Jun 24, 2026

Copy link
Copy Markdown
Member

Stacked migration — PR 4 of N. Base = migrate/strawberry-p2-data (Phase 2a, #90).
Epic: GNS-Science/nshm-toshi-api#359 · Tracking: #86 · Log: docs/MIGRATION_LOG.md

The schema port — the largest piece. strawberry_schema.py reproduces all 29 types; tools/schema_parity.py proves it byte-identical to schema.legacy.graphql.

What's here

  • SDL byte-parity (the gate passes). Custom Node interface (id: ID!, not strawberry.relay/GlobalID — Model C1); root type QueryRoot; auto_camel_case=False with relay PageInfo fields kept camelCase.
  • Parity traps cleared: nullable-with-default fields (X | None), strawberry.UNSET vs = null args (Model T3), and the legacy partial 3-key style-arg default reproduced via an input instance with fill_* UNSET.
  • Resolvers reuse the existing Graphene-free compute (cached.*, color_scale, apply_geojson_style, get_location_detail_list). Light query-root resolvers verified against legacy output (about, locations, radii, colour-scale, location lists).
  • tools/schema_parity.py gate + corpus replay re-pointed at the Strawberry schema.
  • Added the strawberry.ext.mypy_plugin; new code is mypy-clean.

Scope boundary

Archive-dependent runtime resolvers (rupture field computes, pagination, sections geojson/MFD/colour, node() dispatch) are stubbed → Phase 3, where they're implemented with the tiny-archive fixtures + the converted test suite that verify them. The schema shape is complete and parity-locked now.

Verification

  • schema_paritybyte-identical to the legacy SDL
  • corpus replay (14 queries) validates against the Strawberry schema — 15 pass
  • full legacy suite 77 passed / 10 skipped; ruff clean; new code mypy-clean
  • cli / cli_ab_test still import (graphene path untouched)

Note: 29 mypy errors remain in the legacy graphene modules (pre-existing follow_untyped_imports config; deleted at cutover) — not from this PR, and mypy isn't the PR test gate.

…rity

- strawberry_schema.py: full 29-type schema; tools/schema_parity.py gate confirms
  byte-identical vs schema.legacy.graphql
- custom Node interface (id: ID!, not strawberry.relay/GlobalID); QueryRoot root
  type; auto_camel_case=False; relay PageInfo camelCase via name=
- nullability (X|None for nullable-with-default), UNSET vs =null args, and the
  partial 3-key style-arg default all matched
- resolvers reuse the graphene-free compute helpers; light query-root resolvers
  verified vs legacy output
- corpus replay re-pointed at the Strawberry schema (15 pass); add strawberry
  mypy plugin (new code mypy-clean)
- archive-dependent runtime resolvers stubbed -> Phase 3 (need fixtures + tests)

Refs #86
@chrisbc

chrisbc commented Jun 24, 2026

Copy link
Copy Markdown
Member Author

Landed via the combined PR #95 (one merge → one test-stage deploy, per runbook G7). Per-phase detail preserved here.

@chrisbc chrisbc closed this Jun 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant