refactor(types): single source for GraphQL type mapping (type-mapping convergence ③) - #144
Merged
Merged
Conversation
…13 plan) The Python → GraphQL type mapping had 4 parallel implementations and 3 scalar tables (full-project orthogonality review, pattern 1): - SCALAR_TYPE_MAP is now a module-level constant in type_converter and the ONLY table; compose_type_mapper imports it (the specs/001 R2 fork keeps its SQLModel-free behavior — the fork covers behavior, not data) - compose_schema.type_ref_to_sdl is the public single TypeRef renderer; the compose MCP server's verbatim copy (_type_ref_to_str) is deleted - introspector._type_to_sdl_name is a thin shell over ComposeTypeMapper + type_ref_to_sdl: its private 4-entry table described datetime as "datetime" (class-name fallback — never a registered scalar) and invented a "JSON" scalar no schema defined; UUID matched only by luck. A FRESH mapper per call — the shared instance leaked registrations across describes (test isolation proven). Lenient fallbacks (bare list, general unions) keep the former conventions; dict keeps its descriptive "JSON" name since compose rejects dict outright - federation._type_expr untouched by design: it renders lossless Python expressions for the machine contract, not GraphQL SDL, and has no scalar table of its own Behavior change: describe signatures now carry nullability markers consistent with the compose schema (int → "Int!", datetime → "DateTime!", Optional[list[T]] → "[T!]!" instead of the falsely-non-null "[T!]!"). 12 assertions updated to the corrected semantics; 5 regression tests added (single-sourcing + the datetime/UUID/dict fixes). Co-Authored-By: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Lands the type-mapping convergence plan from the full-project orthogonality review (mindmap node #13 / 收敛路线③): the Python → GraphQL type mapping had 4 parallel implementations and 3 scalar tables, and they had already drifted apart.
Measured before this PR — the same annotation fed to two exits:
rpc.describedatetimeDateTime(registered scalar)datetime(class-name fallback — never a valid scalar)dictUnsupportedTypeError)JSON(a scalar no schema ever defined)UUIDUUIDUUID— by luck: the class-name fallback happened to matchChanges
SCALAR_TYPE_MAP→ module-leveltype_converterbecomes THE single table;compose_type_mapperimports it instead of maintaining an identical copy. The specs/001 R2 fork (SQLModel-free compose) is preserved — the fork covers behavior, not data.type_ref_to_sdlpubliccompose_schemaexports the TypeRef renderer; the compose MCP server's verbatim copy (_type_ref_to_str) is deleted.introspector._type_to_sdl_name→ thin shellComposeTypeMapper+type_ref_to_sdl. Its private 4-entry table, class-name fallback, and inventedJSONscalar are gone.dictkeeps the descriptiveJSONname (describe is informational; compose rejects dict outright). A fresh mapper per call — a shared instance leaked registrations across describes (test isolation caught it: id reuse after GC made behavior order-dependent).federation._type_expruntouchedBehavior change
describe_servicesignatures now carry nullability markers consistent with the compose schema:int→Int!,datetime→DateTime!,Optional[list[T]]→[T!](was the falsely-non-null[T!]!). Lenient fallbacks (barelist, general unions) keep the former conventions so describe never crashes.12 existing assertions updated to the corrected semantics; 5 regression tests added (single-sourcing identity, datetime/UUID/dict fixes, public renderer).
Verification
Full suite 1677 passed / 0 failed;
ruff check src/clean.🤖 Generated with Claude Code