2.1 KiB
Adding a New Feature — End-to-End Guide
This guide walks through adding a complete feature from entity to UI.
Example: Adding a "Comments" feature
1. Define Entity
Create packages/core/src/entities/models/comment.ts:
import { z } from "zod";
export const commentSchema = z.object({
id: z.string(),
content: z.string().min(1),
articleId: z.string(),
authorId: z.string(),
createdAt: z.date(),
});
export type Comment = z.infer<typeof commentSchema>;
Export from entities/models/index.ts.
2. Define Repository Interface
Create packages/core/src/application/repositories/comments.repository.interface.ts:
import type { Comment } from "@/entities/models/comment.js";
export interface ICommentsRepository {
getCommentsByArticle(articleId: string): Promise<Comment[]>;
createComment(input: Comment): Promise<Comment>;
}
Export from application/repositories/index.ts.
3. Write Use Case (TDD)
Write test first in packages/core/tests/unit/use-cases/content/create-comment.use-case.test.ts, then implement in packages/core/src/application/use-cases/content/create-comment.use-case.ts.
4. Write Controller
Create packages/core/src/interface-adapters/controllers/content/comments.controller.ts — validates input with Zod, calls use case.
5. Write Mock Implementation
Create packages/core/src/infrastructure/repositories/mock-comments.repository.ts with @injectable().
6. Register in DI
Add ICommentsRepository symbol to di/types.ts, create binding in di/modules/content.module.ts, load in di/container.ts.
7. Add tRPC Router
Create packages/api/src/router/comments.router.ts, add to appRouter in router/index.ts.
8. (Optional) Add Payload Collection
If comments are stored in Payload CMS, create packages/cms-core/src/collections/comments/.
9. Build UI
Create component in packages/ui/src/organisms/comment-list/ with co-located .stories.tsx.
10. Wire in App
Use useTRPC() in app pages to fetch and display comments.
11. Write Tests
- Unit: use case + controller tests in
packages/core/tests/ - E2E: Playwright test in
tests/e2e/