One resource family
Task and Category are enough to prove CRUD, filtering, validation, and ownership.
Domain sliceUse OpenAPI 3.1 to bind request validation, handlers, controllers, SDK clients, and documentation.

export class TaskController {
constructor(private readonly createTask: CreateTaskUseCase) {}
async create(input: CreateTaskInput): Promise<TaskOutput> {
return this.createTask.execute(input);
}
}From zero to first MVP
Use this path when the first MVP must expose predictable CRUD or integration behavior that another system, admin screen, or frontend can call immediately.
Model one resource such as Task with Category ownership, required fields, validation, and the first create/list operations.
MVP output: a tiny OpenAPI surface with one command and one query.
type Category = { id: string; name: string };
type Task = { id: string; title: string; categoryId: string; completed: boolean };
const categories = new Map<string, Category>([
['work', { id: 'work', name: 'Work' }]
]);
const tasks = new Map<string, Task>();MVP scope
Task and Category are enough to prove CRUD, filtering, validation, and ownership.
Domain sliceCreate, list, update status, and fetch by id before adding reporting or bulk operations.
API sliceStart with in-memory or local SQL, then swap the repository adapter after feedback.
Runtime slice| Proof area | Question to answer | Jumentix mechanism | MVP evidence |
|---|---|---|---|
| Contract | Can another client understand the API without reading source code? | OpenAPI 3.1, route check, schema examples. | Docs and route metadata match the handler. |
| Behavior | Does the first workflow enforce validation and domain rules? | Controller/use-case tests and error contract checks. | Invalid input fails before persistence; domain errors stay explicit. |
| Adoption | Can a frontend or partner call it today? | Generated REST client and copyable request example. | A first consumer can create and list records. |
Practical implementation
These examples keep Category and Task as the product vocabulary and show the controller, contract, client, worker, or state layer needed to reach a runnable MVP.
type Category = { id: string; name: string };
type Task = { id: string; title: string; categoryId: string; completed: boolean };
const categories = new Map<string, Category>([
['work', { id: 'work', name: 'Work' }]
]);
const tasks = new Map<string, Task>();
class CreateTaskUseCase {
async execute(input: { title: string; categoryId: string }) {
if (!input.title.trim()) return { status: 400, body: { error: 'title is required' } };
if (!categories.has(input.categoryId)) return { status: 404, body: { error: 'category not found' } };
const task: Task = {
id: crypto.randomUUID(),
title: input.title,
categoryId: input.categoryId,
completed: false
};
tasks.set(task.id, task);
return { status: 201, body: task };
}
}
class TaskController {
constructor(private readonly createTask: CreateTaskUseCase) {}
async create(request: Request) {
const input = await request.json() as { title: string; categoryId: string };
const response = await this.createTask.execute(input);
return Response.json(response.body, { status: response.status });
}
async list() {
return Response.json([...tasks.values()]);
}
}
const controller = new TaskController(new CreateTaskUseCase());
export async function handleRequest(request: Request) {
const url = new URL(request.url);
if (request.method === 'POST' && url.pathname === '/tasks') return controller.create(request);
if (request.method === 'GET' && url.pathname === '/tasks') return controller.list();
return Response.json({ error: 'not found' }, { status: 404 });
}Keep exploring
Ship OpenAPI 3.1 services with interchangeable native HTTP adapters.
Explore the blueprintRun Socket.IO or gRPC beside a REST fallback and AsyncAPI documentation.
Explore the blueprintLaunch one deployable with domain boundaries ready to become services.
Explore the blueprintKeep service communication contract-based with the Message Mediator.
Explore the blueprintBuild frontend products that share generated SDKs and work offline.
Explore the blueprintExplore the source, run the factory locally, and turn your next Node.js service into a repeatable platform capability.