From noop
Generate new domain entities with full CRUD infrastructure in noop-based projects. Use when adding new resources, tables, or API endpoints to an existing project.
How this skill is triggered — by the user, by Claude, or both
Slash command
/noop:entity-generatorThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
This skill generates complete CRUD infrastructure for new domain entities.
This skill generates complete CRUD infrastructure for new domain entities.
Automatically use this skill when the user wants to:
@docs/universal-framework/GENERATOR_INSTRUCTIONS.md
@docs/universal-framework/CONVENTIONS.md
@docs/universal-framework/ARCHITECTURE_SPEC.md
For entity Product:
| File | Purpose |
|---|---|
src/types/product.types.ts | Type definitions |
src/db/pg/ProductOps.ts | Database operations |
src/handlers/productHandler.ts | HTTP handlers |
| Migration SQL | Table creation |
| File | Changes |
|---|---|
src/db/pg/PgClientStore.ts | Register ProductOps |
src/routes.ts | Add CRUD routes |
src/types/index.ts | Export types |
| Input | Output | Example |
|---|---|---|
| Entity | PascalCase | Product |
| Type file | {entity}.types.ts | product.types.ts |
| Ops file | {Entity}Ops.ts | ProductOps.ts |
| Handler | {entity}Handler.ts | productHandler.ts |
| Table | snake_case plural | products |
| Routes | lowercase plural | /api/v1/products |
| Store prop | camelCase plural | dbStore.products |
export interface ProductInfo {
id: string
name: string
description?: string
organizationId: string
createdAt: Date
updatedAt: Date
}
export type CreateProductInput = Omit<ProductInfo, 'id' | 'organizationId' | 'createdAt' | 'updatedAt'>
export class ProductOps {
async create(data: CreateProductInput, organizationId: string): Promise<ProductInfo> {
if (!organizationId) throw new Error('organization_id is required')
// parameterized INSERT
}
async getById(id: string, organizationId: string): Promise<ProductInfo | undefined> {
if (!organizationId) throw new Error('organization_id is required')
// SELECT with org filter
}
private mapRowToProduct(row: DbProductRow): ProductInfo { }
}
export const create = asyncHandler(async (req, res) => {
const { name, description } = req.body
if (!name) throw createError.requiredField('name')
const dbStore = getDbStore()
const item = await dbStore.products.create(
{ name, description },
req.user.organizationId
)
return sendSuccess(res, item, 'Product created', 201)
})
CREATE TABLE products (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
name VARCHAR(255) NOT NULL,
description TEXT,
organization_id UUID NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_products_organization ON products(organization_id);
app.get(`${API_PREFIX}/products`, productHandlers.list)
app.post(`${API_PREFIX}/products`, productHandlers.create)
app.get(`${API_PREFIX}/products/:id`, productHandlers.get)
app.put(`${API_PREFIX}/products/:id`, productHandlers.update)
app.delete(`${API_PREFIX}/products/:id`, productHandlers.remove)
npm run typecheck passesnpm run lint passesGuides reception of code review feedback: verify before implementing, avoid performative agreement, push back with technical reasoning when needed.
Design banners for social media, ads, website heroes, and print with multiple art direction options and AI-generated visuals.
npx claudepluginhub joshuarweaver/cascade-code-general-misc-4 --plugin hdeibler-noop