Skip to content

feat: _meta plumbing + ManyToManyRelation junction key fields + Clean* rename#863

Merged
pyramation merged 3 commits intomainfrom
devin/1774048082-meta-schema-m2m
Mar 20, 2026
Merged

feat: _meta plumbing + ManyToManyRelation junction key fields + Clean* rename#863
pyramation merged 3 commits intomainfrom
devin/1774048082-meta-schema-m2m

Conversation

@pyramation
Copy link
Contributor

@pyramation pyramation commented Mar 20, 2026

Summary

Two changes:

1. Rename Clean* types → drop prefix (57 files, zero logic changes)

All 12 Clean* interfaces in graphql/codegen and graphql/query renamed to plain names:
CleanTableTable, CleanFieldField, CleanManyToManyRelationManyToManyRelation, etc.

Mechanical find-and-replace. The Clean prefix was meaningless — these types are already scoped to the codegen/query context.

2. _meta table metadata plumbing for M:N junction key fields

After buildSchemaSDL() runs, the MetaSchemaPlugin has already populated _cachedTablesMeta with M:N relation metadata. We just snapshot it:

  • graphile-schema/src/index.ts — re-exports _cachedTablesMeta from graphile-settings (1 line)
  • database.ts — snapshots [..._cachedTablesMeta] after buildSchemaSDL() and returns it as tablesMeta
  • source/types.ts — adds MetaTableInfo type + optional tablesMeta field on SchemaSourceResult
  • ManyToManyRelation — extended with junctionLeftKeyFields, junctionRightKeyFields, leftKeyFields, rightKeyFields

No new functions. No HTTP code. Just uses what's already there. PR 3 will consume these fields for ORM add/remove junction methods.

Review & Testing Checklist for Human

  • Breaking change: Clean* type names are exported from @constructive-io/graphql-codegen and @constructive-io/graphql-query. Any external consumers importing CleanTable, CleanField, etc. will break. Consider whether type aliases are needed for backward compat.
  • unknown[]MetaTableInfo[] cast in database.ts: Structurally compatible (subset), but skips runtime validation. Verify junctionLeftKeyAttributes etc. exist on the cached objects.
  • Internal function names: Functions like transformFieldToCleanOperation still reference "Clean" in their names. Minor inconsistency — they're private, but worth a follow-up cleanup.

Test plan: Run codegen in database mode against a schema with M:N relations. Verify tablesMeta is populated on SchemaSourceResult.

Notes

  • endpoint.ts, file.ts, pgpm-module.ts sources unchanged — they return { introspection } without tablesMeta (field is optional)
  • No code reads tablesMeta or the new key fields yet — plumbing only. PR 3 adds consumers.
  • Depends on constructive-db#642 (merged)

Link to Devin session: https://app.devin.ai/sessions/745d2d10b699452091e24131ba5edef2
Requested by: @pyramation


Open with Devin

- Extend CleanManyToManyRelation with junctionLeftKeyFields,
  junctionRightKeyFields, leftKeyFields, rightKeyFields (both codegen
  and query packages)
- Add MetaTableInfo type to SchemaSourceResult for _meta data flow
- Add fetchGraphqlQuery() helper for arbitrary GraphQL queries
- Endpoint source now fetches _meta in parallel with introspection
  (graceful fallback if endpoint lacks MetaSchemaPlugin)
- Add buildSchemaWithMeta() to graphile-schema that returns SDL +
  cached tablesMeta from MetaSchemaPlugin
- Database source now returns tablesMeta via buildSchemaWithMeta()

Sets up the plumbing for PR 3 (ORM add/remove junction methods).
@devin-ai-integration
Copy link
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

…ablesMeta directly

Reverted all HTTP plumbing (fetchGraphqlQuery, parallel _meta fetch in endpoint.ts)
and the buildSchemaWithMeta refactor. Instead, database.ts just snapshots
_cachedTablesMeta (already populated by MetaSchemaPlugin during buildSchemaSDL).
…Relation, etc.)

Mechanical rename across 57 files. The Clean* prefix was meaningless noise —
these types are already scoped to the codegen/query context.

CleanTable → Table, CleanField → Field, CleanFieldType → FieldType,
CleanRelations → Relations, CleanBelongsToRelation → BelongsToRelation,
CleanHasOneRelation → HasOneRelation, CleanHasManyRelation → HasManyRelation,
CleanManyToManyRelation → ManyToManyRelation, CleanOperation → Operation,
CleanArgument → Argument, CleanTypeRef → TypeRef, CleanObjectField → ObjectField
@devin-ai-integration devin-ai-integration bot changed the title feat: _meta plumbing + CleanManyToManyRelation junction key fields feat: _meta plumbing + ManyToManyRelation junction key fields + Clean* rename Mar 20, 2026
@pyramation pyramation merged commit 6a4ebd5 into main Mar 20, 2026
44 checks passed
@pyramation pyramation deleted the devin/1774048082-meta-schema-m2m branch March 20, 2026 23:52
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

View 5 additional findings in Devin Review.

Open in Devin Review

Comment on lines +134 to +137
return {
introspection,
tablesMeta: [..._cachedTablesMeta] as MetaTableInfo[],
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 tablesMeta collected from _cachedTablesMeta but never consumed by the pipeline

The DatabaseSchemaSource.fetch() now collects tablesMeta from the _cachedTablesMeta global (line 136) and returns it in SchemaSourceResult. However, the only consumer of source.fetch() is runCodegenPipeline() at graphql/codegen/src/core/pipeline/index.ts:115, which destructures only { introspection }, completely discarding tablesMeta. This means the new ManyToManyRelation junction key fields (junctionLeftKeyFields, junctionRightKeyFields, leftKeyFields, rightKeyFields) added to graphql/codegen/src/types/schema.ts:195-202 and graphql/query/src/types/schema.ts:195-202 will never be populated on the inferred tables. The entire _cachedTablesMeta integration is dead code — the data is collected, returned, and silently dropped.

Prompt for agents
The tablesMeta is returned from DatabaseSchemaSource.fetch() but never consumed. In graphql/codegen/src/core/pipeline/index.ts at line 115, change the destructuring from `const { introspection } = await source.fetch()` to `const { introspection, tablesMeta } = await source.fetch()`, then pass tablesMeta into inferTablesFromIntrospection or add a post-processing step that enriches the inferred ManyToManyRelation entries with the junction key field information from tablesMeta. Without this wiring, the new junctionLeftKeyFields/junctionRightKeyFields/leftKeyFields/rightKeyFields on ManyToManyRelation will always be undefined.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

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