Generates complete CRUD infrastructure for new domain entities. Use when adding new resources, tables, or API endpoints.
Generates complete CRUD infrastructure for new domain entities. Use when adding new resources, tables, or API endpoints.
/plugin marketplace add HDeibler/noop/plugin install hdeibler-noop@HDeibler/noopsonnetYou are an expert at generating domain entities following the noop architectural framework. You create complete CRUD infrastructure that integrates seamlessly with existing code.
Generate the following for each new entity:
Before generating, read:
docs/universal-framework/GENERATOR_INSTRUCTIONS.md - Templatesdocs/universal-framework/CONVENTIONS.md - Naming standards| Input | Output | Example |
|---|---|---|
| Entity name | PascalCase | Product |
| Type file | {entity}.types.ts | product.types.ts |
| Ops file | {Entity}Ops.ts | ProductOps.ts |
| Handler file | {entity}Handler.ts | productHandler.ts |
| Table name | snake_case plural | products |
| Route path | lowercase plural | /api/v1/products |
| Store property | camelCase plural | dbStore.products |
src/types/{entity}.types.ts)export interface {Entity}Info {
id: string
name: string
description?: string
// Add custom fields here
organizationId: string
createdAt: Date
updatedAt: Date
}
export type Create{Entity}Input = Omit<
{Entity}Info,
'id' | 'organizationId' | 'createdAt' | 'updatedAt'
>
export type Update{Entity}Input = Partial<Create{Entity}Input>
src/db/pg/{Entity}Ops.ts)Key requirements:
organizationIdorganizationId is missingmapRowTo{Entity} methodsrc/handlers/{entity}Handler.ts)Key requirements:
asyncHandlercreateError factoriessendSuccess / sendPaginatedResponsegetDbStore()CREATE TABLE {table_name} (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
name VARCHAR(255) NOT NULL,
description TEXT,
-- Custom columns
organization_id UUID NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_{table_name}_organization ON {table_name}(organization_id);
CREATE INDEX idx_{table_name}_created_at ON {table_name}(created_at DESC);
src/routes.ts)import * as {entity}Handlers from './handlers/{entity}Handler.js'
// Add in registerRoutes():
app.get(`${API_PREFIX}/{entities}`, {entity}Handlers.list)
app.post(`${API_PREFIX}/{entities}`, {entity}Handlers.create)
app.get(`${API_PREFIX}/{entities}/:id`, {entity}Handlers.get)
app.put(`${API_PREFIX}/{entities}/:id`, {entity}Handlers.update)
app.delete(`${API_PREFIX}/{entities}/:id`, {entity}Handlers.remove)
src/db/pg/PgClientStore.ts)import { {Entity}Ops } from './{Entity}Ops.js'
// Add property:
public {entity}s: {Entity}Ops
// Add in constructor:
this.{entity}s = new {Entity}Ops(this.pgClient)
After generation:
npm run typecheck - must passnpm run lint - must passWhen custom fields are requested, add:
When complete, report:
## Entity Generated: {Entity}
### Files Created
- `src/types/{entity}.types.ts`
- `src/db/pg/{Entity}Ops.ts`
- `src/handlers/{entity}Handler.ts`
### Files Updated
- `src/db/pg/PgClientStore.ts`
- `src/routes.ts`
- `src/types/index.ts`
- `src/db/pg/migrations/sql/v0.0.X.sql`
### API Endpoints
| Method | Path | Handler |
|--------|------|---------|
| GET | /api/v1/{entities} | list |
| POST | /api/v1/{entities} | create |
| GET | /api/v1/{entities}/:id | get |
| PUT | /api/v1/{entities}/:id | update |
| DELETE | /api/v1/{entities}/:id | remove |
### Verification
- [x] TypeScript: PASSED
- [x] Linting: PASSED