proto-service-skeleton
Proto Service Skeleton
Turn generated *ServiceHTTPServer interfaces into compilable service files under internal/service/<module>/.
Required Reading
Read before generating:
Companion Skill Policy
When sphere-layout-feature-workflow is available in the current session, use it together with this skill.
Collaboration rules:
- Let
sphere-layout-feature-workflowdrive framework-native feature assembly (middleware, auth, errors, routing, wiring flow). - Let
proto-service-skeletonfocus on per-service file generation/completion from*ServiceHTTPServer. - Prefer shared framework capabilities over custom implementation.
- Avoid implementing duplicate functionality when an equivalent capability already exists in this repository or the Sphere stack.
If sphere-layout-feature-workflow is unavailable, continue with this skill and enforce the Reuse-First Checklist below.
Scope
- Handle only
*ServiceHTTPServerinterfaces. - Cover all modules (such as
api,dash,shared). - Do not handle
BotServeror other non-HTTP interfaces.
Repository Conventions
- Keep one
Servicestruct per proto module. - Keep one Go file per proto service.
- File naming: remove the
Servicesuffix and convert tosnake_case. - Every service file must include an interface assertion:
var _ <pkg>.<ServiceName>HTTPServer = (*Service)(nil)
Workflow
- Discover modules and interfaces:
Use
type XxxServiceHTTPServer interfacefromapi/<module>/v1/*.sphere.pb.goas the single source of truth. - Run Reuse-First Checklist: Before adding new code, check whether existing Sphere/repository capabilities already solve the need.
- Map target files:
XxxService -> internal/service/<module>/xxx.go. - Check target file state: If the file does not exist, create it. If it exists, only append missing methods/assertions/imports.
- Generate method signatures:
Signatures must exactly match the interface; receiver is always
func (s *Service). - Fill method bodies using strategy:
Prefer the simple CRUD fast path; otherwise generate stubs.
Reuse templates from
references/service-implementation-best-practices.mdwhen needed. - Return change summary and validation result: Follow this skill's Output Contract.
Reuse-First Checklist
Before implementing new logic, verify these in order:
- Existing service implementation in the same module (
internal/service/<module>/*.go). - Existing generated converters and binders (
internal/pkg/render/entbind,internal/pkg/render/entmap). - Existing shared helpers (
internal/pkg/*,internal/service/shared/*). - Existing dependency wiring (
internal/service/wire.go,internal/wire.go,cmd/app/wire.go). - Existing Sphere-native middleware/auth/error flow already used by sibling services.
If a capability already exists, reuse it. Do not re-implement equivalent behavior.
Implementation Strategy
A) Simple CRUD Fast Path (Direct Ent)
For methods classified as simple CRUD, call Ent directly inside Service without adding an extra DAO business layer.
Classification rules:
- Method name is
Create*,Get*,List*,Update*, orDelete*. - It operates on a single entity.
- It does not require complex cross-domain orchestration or complex transactions.
Implementation style:
Create*/Update*: preferentbind.CreateXxx/entbind.UpdateOneXxx.Get*/Delete*: calls.db.<Entity>.Get/DeleteOneIDdirectly.List*: usequery.Clone().Count,conv.Page, andLimit/Offset/Order(sql.OrderDesc()).- Response mapping: use
s.render.<Entity>(...)orconv.Map(..., s.render.<Entity>).
Prohibited:
- Do not add a new
internal/pkg/daobusiness wrapper for simple CRUD.
B) Unknown or Complex Logic
When business logic cannot be safely inferred, generate a compilable stub first:
return nil, errors.New("not implemented: <Method>")
When logic is clearly complex (cross-entity transactions, long flows, reusable orchestration), split it into:
internal/usecase/<module>/<service>/
Rules after split:
- Service methods keep orchestration only.
- Update
type Service structdependencies ininternal/service/<module>/service.gowhen needed. - Update
NewService(...)parameters and assignments when needed. - Update wire providers when needed so dependency injection remains compilable.
Safe Update Policy
- Append missing methods only; do not rewrite existing method bodies.
- Append missing assertions only; do not delete existing assertions.
- Add only required imports; avoid unrelated reordering.
- Do not modify generated files under
api/*. - Do not change existing business semantics.
Output Contract
Output in this exact order:
Scaffold PlanFiles To Create/UpdateInterface Coverage CheckStub Methods AddedUsecase Split DecisionValidation Result
Minimal Validation Checklist
go test ./internal/service/...go test ./cmd/app/...- If dependency injection signatures change, run
make gen/wireand rerun the tests above.
Acceptance Checklist
- New-file scenario: file exists, assertion exists, all interface methods exist, and code compiles.
- Existing-file scenario: only missing methods are appended; existing implementations are unchanged.
- Simple CRUD scenario: direct Ent via
s.db, matching thekeyvaluestorestyle. - Complex-logic scenario: split into
internal/usecase/...as needed and complete the injection chain.