← スキル一覧に戻る

crud-routes-builder
by RedBoardDev
⭐ 0🍴 0📅 2026年1月19日
SKILL.md
name: crud-routes-builder description: Generate base HTTP CRUD routes (create, list, get, delete) for a domain entity in apps/api/src/interfaces/http/routes, using existing domain fields/schemas and repositories; handles nested sub-entities via Fastify prefixes. Use when asked to scaffold CRUD routes for an entity (e.g., "Crée les routes CRUD pour Recipe", "Génère le CRUD de l'entité Ingredient", "Fais les routes CRUD de Member dans Collection").
CRUD Routes Builder
Create the four base routes under apps/api/src/interfaces/http/routes/{entities}/ following the collections example already in the repo. Domain + repository must already exist; leave imports unresolved if missing. No update route.
Inputs to confirm
- Singular + plural names (kebab case), especially irregular plurals.
- Whether this is a sub-entity and its parent (parent folder +
parentIdparam name). - Tag/summary/description strings (PascalCase plural tags; e.g.,
["Collections"],["Collection Members"]).
Naming & placement
- Folder: lower kebab plural (e.g.,
collections). - Files:
create-{entity},list-{entities},get-{entity},delete-{entity}. - Parent index registers routes; sub-entity routes live in
{parent-entities}/{sub-entities}/and are registered from the parent withprefix: "/:parentId/sub-entities".
Route registration (index.ts)
import type { FastifyInstance } from "fastify";
import { createEntityRoute } from "./create-entity";
import { listEntitiesRoute } from "./list-entities";
import { getEntityRoute } from "./get-entity";
import { deleteEntityRoute } from "./delete-entity";
// import { subRoutes } from "./sub-entities";
export async function entitiesRoutes(app: FastifyInstance) {
await app.register(listEntitiesRoute);
await app.register(getEntityRoute);
await app.register(createEntityRoute);
await app.register(deleteEntityRoute);
// await app.register(subRoutes, { prefix: "/:parentId/sub-entities" });
}
Create route (create-{entity}/)
index.ts:route().post().auth().meta({ tags, summary, description }).schemas(schemas).handle(createEntityHandler).schema.ts: body from domain fields ({ ...entityFields.foo }),response{ 201: entitySnapshotSchema }, exportschemas.handler.ts:RouteHandler<typeof schemas>, grabctx.user/ctx.body, runcreateEntityErrorsif needed, callcreateEntityfromdb-access, return{ status: HttpStatus.Created, data: entity.toSnapshot() }.db-access.ts: importgetPrisma,handleError,{ Entity }from@cookmate/domain/{entity}; build entity (set timestamps/owner fields), persist with prisma (map domain names to Prisma columns like ownerId -> userId), wrap withhandleError.
List route (list-{entities}/)
select.ts: define Prismaselect,responseSchema(usuallyz.array(...)), andtransform; exportselectConfig(useSelectConfigtype from@/shared/types/select-config).where.ts: exportlistEntitiesWhereConfigsviadefineWhereConfigs.order-by.ts: exportlistEntitiesSortConfigviadefineSortConfig.schema.ts:queryusesdefineListQuerySchema({ where, sort });responseusesselectConfig.schema; exportschemas. For sub-entities includeparamswith parentId.handler.ts: parse query withparsePagination,parseWhereParams,parseSortParams, buildwherewithcombineWhere, then calllistEntitiesSelectandcountEntities. Return{ status: HttpStatus.OK, data: selectConfig.transform(...), metadata: { pagination } }.
Get route (get-{entity}/)
select.ts: same pattern, butresponseSchemais a single object (not array).transformmay accept extra options (e.g.,isOwner).schema.ts:paramsz.object({ {entityId}: z.uuid() }),response{ 200: selectConfig.schema }.handler.ts: fetch via repositorygetEntitySelectwithselectConfig.select; rungetEntityErrorsif needed; return{ status: HttpStatus.OK, data: selectConfig.transform(result, options) }.
Delete route (delete-{entity}/)
index.ts:route().delete("/:{entityId}").schema.ts:paramsUUID,response{ 204: z.null() }.handler.ts: rundeleteEntityErrors, call localdeleteEntity(db-access), return{ status: HttpStatus.NoContent }.db-access.ts:deleteEntity = handleError(async (id) => { await getPrisma().entity.delete({ where: { id } }); }).
Sub-entities
- Folder:
{parent-entities}/{sub-entities}/, with its ownindex.tsregistering subroutes. - Parent
index.tsregisters subroutes withprefix: "/:parentId/{sub-entities}"and parent params include{ parentId: z.uuid() }. - Tags: PascalCase plural with parent context (e.g.,
["Collection Members"]).
References
- apps/api/src/interfaces/http/routes/collections/**
- apps/api/src/interfaces/http/routes/collections/members/**
スコア
総合スコア
50/100
リポジトリの品質指標に基づく評価
✓SKILL.md
SKILL.mdファイルが含まれている
+20
○LICENSE
ライセンスが設定されている
0/10
○説明文
100文字以上の説明がある
0/10
○人気
GitHub Stars 100以上
0/15
○最近の活動
3ヶ月以内に更新がある
0/10
○フォーク
10回以上フォークされている
0/5
✓Issue管理
オープンIssueが50未満
+5
✓言語
プログラミング言語が設定されている
+5
○タグ
1つ以上のタグが設定されている
0/5
レビュー
💬
レビュー機能は近日公開予定です