controller

Create HTTP API controllers with Zod or Go struct validation across TypeScript and Go backends.

4|Updated Jul 30, 2026
One-click install
npx skills add https://github.com/gabriellst/codm --skill controller-gabriellst
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: controller
Source: https://github.com/gabriellst/codm/tree/main/.claude/skills/controller
Command: npx skills add https://github.com/gabriellst/codm --skill controller-gabriellst

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? Adding a new REST endpoint in this polyglot DDD codebase requires following strict, language-specific conventions — schema validation, middleware composition, DI registration, and OpenAPI metadata — and getting any of them wrong produces silent failures like unregistered routes or missing SDK types. ## Core Features & Use Cases - Language dispatch hub: Routes to the TypeScript or Go playbook based on file extension, so the correct idioms (Zod schemas vs. types.Controller structs) are always applied. - TypeScript controllers: Generates @injectable() Controller classes with InputSchema/OutputSchema, .example() annotations, ctx.session auth injection, middleware overrides, and MCP tool exposure via static mcpScopes. - Go controllers: Scaffolds structs implementing types.Controller with Metadata() + Handle(), auto-registered through fx group:"controllers", using httputil.DecodeRequest and validator/v10 tags. - Pattern registries: Ships registry.yaml files per language encoding mandatory patterns (CTRL-01…CTRL-GO-11) and detectable bad practices for automated review. - Use Case: Ask to add POST /channels/whatsapp and receive a complete controller — request struct or Zod schema, use case wiring, middleware declaration, and module registration — that passes the project's review checks. ## Quick Start Ask the agent to create a new HTTP endpoint such as "add a GET /products/:id controller to the product context" and it will scaffold the controller following the matching language playbook.

Frequently Asked Questions about controller

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I create a new REST API endpoint in this project?

Run the controller scaffolder or ask for the endpoint by name and path. The skill generates the controller with input/output schemas, validation, use case wiring, and registration — TypeScript controllers extend a base Controller class, Go controllers implement types.Controller with Metadata and Handle methods.

How do I add validation to HTTP request schemas with Zod?

Define an InputSchema with body, query, or params keys using Zod, and attach .example() for OpenAPI generation. Query params need z.stringToNumber() or z.stringToBoolean() converters since they arrive as strings; body fields use native Zod types.

How are Go controllers registered with the HTTP router?

Go controllers auto-register via fx dependency injection: annotate the constructor with fx.As(new(types.Controller)) and fx.ResultTags group:"controllers" in module.go. The router reads Metadata() from each tagged controller to build routes and apply middleware.

Should list endpoint filters go in the shared contracts package?

No. Filters, sortBy, or groupBy literals used by a single list endpoint belong inline on that controller's query schema. Promote a value to packages/contracts only when another service or a persisted database column must agree on it.

Why is my controller not reachable after creating it?

In TypeScript, the controller must be exported from controllers/index.ts or it is silently never registered. In Go, the constructor must be annotated with fx.As and the group:"controllers" result tag in module.go, otherwise the router never sees it.

When should a controller be public without authentication middleware?

Only for callers that structurally cannot hold a session, such as process health checks. TypeScript requires a docblock justifying the empty middleware chain; Go uses Metadata().Public set to true, never a route registered directly on the mux.