Ent Schema Implementer
Convert an approved database design into concrete Ent schema changes for go-sphere projects — step by step, with explicit checkpoints before writing code.
This skill starts after the data model is stable enough to code. Its focus is Ent schema files, entproto compliance, generation impact, and downstream integration checkpoints. It confirms the implementation plan first, then implements, rather than writing code immediately and hoping the assumptions were right.
Entry Gate
Use this skill only when at least one of these is true:
- The user explicitly says the database design is approved.
- There is an accepted review brief or spec that defines the entities.
- The task is clearly to implement or update Ent schema code rather than debate data modeling.
If requirements are still fluid, stop and return to db-schema-designer.
Required Reading
Read these files before starting any implementation work:
- references/implementation-rules.md
- references/ent-schema-examples.md
Read this when integration work is in scope:
- references/go-ent-service-patterns.md
Checklist
Work through these in order. Create a task for each item.
- Read approved design — extract confirmed entities, fields, relations, indexes
- Identify affected files — existing schema files to modify, new ones to create
- Ask clarifying questions — one at a time, for any ambiguity that would change code shape
- Present implementation plan — entity-by-field mapping, entproto annotations, index plan; get approval
- Implement schema files — entity by entity, following implementation-rules.md
- Add entproto compliance — Message(), Field(n), Enum() annotations
- Address integration impact — bind registration, ignored fields, render, service touchpoints
- List generation commands — ordered list of commands the user must run
- Confirm handoff — summarize what was done, flag follow-up work
Process Flow
digraph ent_schema_implementer {
"Read approved design" [shape=box];
"Identify affected files" [shape=box];
"Any ambiguities?" [shape=diamond];
"Ask clarifying question\n(one at a time)" [shape=box];
"Present implementation plan" [shape=box];
"Plan approved?" [shape=diamond];
"Implement schema entity by entity" [shape=box];
"Add entproto compliance" [shape=box];
"Address integration impact" [shape=box];
"List generation commands" [shape=box];
"Confirm handoff" [shape=doublecircle];
"Read approved design" -> "Identify affected files";
"Identify affected files" -> "Any ambiguities?";
"Any ambiguities?" -> "Ask clarifying question\n(one at a time)" [label="yes"];
"Ask clarifying question\n(one at a time)" -> "Any ambiguities?";
"Any ambiguities?" -> "Present implementation plan" [label="no"];
"Present implementation plan" -> "Plan approved?";
"Plan approved?" -> "Present implementation plan" [label="revise"];
"Plan approved?" -> "Implement schema entity by entity" [label="yes"];
"Implement schema entity by entity" -> "Add entproto compliance";
"Add entproto compliance" -> "Address integration impact";
"Address integration impact" -> "List generation commands";
"List generation commands" -> "Confirm handoff";
}
Phase 1: Read and Clarify
Read the approved design or spec. Extract:
- Confirmed entities and their purposes
- Field list with types, nullability, defaults, and mutability
- Relation shapes (one-to-many, many-to-many)
- Index plan tied to query patterns
- Any open questions still marked in the design
If anything is missing or ambiguous in a way that would affect the code shape, ask one question at a time before proceeding. Don't guess at field types, enum values, or relation ownership — those choices are hard to change after generation.
Good question to ask: "The design mentions an order_items relationship but doesn't specify whether OrderItem should be its own entity with attributes or a simple join. Which do you need?"
Do not ask questions about things already clearly specified in the design.
Phase 2: Implementation Plan
Before writing any code, present a structured plan. This surfaces mismatches between the design doc and the actual file layout before they become coding mistakes.
Include:
- Affected files — list each schema file with whether it's new or modified
- Entity mapping summary — one row per entity: entity name → field count, relation count, index count
- Entproto field numbering strategy — confirm field order for ID=1 assignment (especially important for modified schemas where existing numbers must not shift)
- JSON field plan — for every JSON field the brief approved: which canonical name (
extra/metadata/settings/payload/attrs), typed struct orjson.RawMessage, and which domain package will hold the struct (see references/implementation-rules.md section 5) - Deprecation plan — for any field marked deprecated in the brief, which stage to implement now and which proto field number stays reserved
- Integration scope — which bind, render, or service files will need manual follow-up
- Migration plan — versioned migration command to generate after
go generate, plus whether any large-table change needs online DDL (see references/implementation-rules.md section 10) - Assumptions — any design gap you filled with a default choice
Ask explicitly: "Does this plan look right before I start writing?"
The plan can be brief for small schemas (one entity, a few fields). Scale it to the complexity of the work.
Phase 3: Implement Schema Files
Work through entities one at a time, following references/implementation-rules.md and references/ent-schema-examples.md.
For each entity:
- Write the schema struct, Fields(), Edges(), and Indexes().
- Apply field policies: required, optional, default, unique, immutable.
- For approved JSON fields, define (or reuse) the typed struct in the domain package and reference it from
field.JSON(...). See examples 3, 4, 6 in references/ent-schema-examples.md. - For approved deprecated fields, keep them in the schema with a
deprecated:comment until a later migration drops them — see example 5. - Implement relations using project conventions. Extension entities use
edge.To(...).Unique()plus a back-edge — see example 4. - Add indexes tied to approved query patterns only — no speculative indexes.
Never invent unapproved entities or fields. If you notice something missing that seems clearly needed (e.g., a standard created_at timestamp), label it as // Assumption: added standard audit timestamp in a comment.
Phase 4: EntProto Compliance
Add entproto annotations to every schema:
entproto.Message()on every schema struct.- Sequential
entproto.Field(n)on every field, starting with ID at1. entproto.Enum(...)mappings for enum fields with values starting from1(not0— proto3 default value convention).- For modified schemas: preserve existing field numbers exactly. Shifting numbers breaks proto compatibility.
If a field number conflict exists (e.g., extending a schema where some numbers are already taken), flag it before writing rather than picking a number silently.
Phase 5: Integration and Verification
After the schema files are done:
- Bind registration — note which entities need to be registered and where.
- Ignored fields — flag any fields that should be excluded from proto generation.
- Render impacts — identify any render layer files that reference the changed schema.
- Service touchpoints — list any service files that will need updates after generation.
For each item, specify whether it is: (a) handled by generation, (b) requires manual follow-up, or (c) requires a separate skill invocation.
Then list the required generation and verification commands in the order they must be run:
# Example order — adapt to actual project setup
go generate ./ent/...
buf generate
# When the change is destined for a real database, generate a versioned migration:
atlas migrate diff <name> --env local
go build ./...
If the project still runs client.Schema.Create(ctx) against production in a startup path, flag it in the handoff. New columns should ship as reviewed migrations, not as application-side auto-migrate.
Handoff Message
Close with a structured summary:
Done. Implemented
Nentities acrossMfiles.Run these commands:
......Manual follow-up needed:
...Next skill: If you need service implementations from the generated interfaces, use
proto-service-generator.
This makes it easy to hand the work off without the user having to reconstruct what happened.