ワンクリックで
scaffold
Create a new entity with its full stack including domain, database, API, frontend, and E2E tests.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Create a new entity with its full stack including domain, database, API, frontend, and E2E tests.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Implement a backlog story following the layer order (Domain, Database, API, Frontend, E2E) with TDD.
Review the backlog to determine what to work on next by checking epic and story statuses in docs/backlog/.
Automates pre-commit workflow: lint, test, review changes, then commit with conventional commit format.
Verify a story is complete by checking acceptance criteria, running all tests, and updating status.
Add end-to-end Playwright tests for a feature using data-testid selectors, with API and UI test patterns.
Add unit tests for domain logic, database adapters, API endpoints, or frontend components using Vitest patterns.
| name | scaffold |
| description | Create a new entity with its full stack including domain, database, API, frontend, and E2E tests. |
| disable-model-invocation | true |
// packages/domain/src/entities/MyEntity.ts
export interface MyEntity {
id: string;
name: string;
userId: string;
createdAt: Date;
updatedAt: Date;
}
export interface CreateMyEntityDTO {
name: string;
userId: string;
}
export interface UpdateMyEntityDTO {
name?: string;
}
// packages/domain/src/ports/MyEntityRepository.ts
import type { MyEntity, CreateMyEntityDTO, UpdateMyEntityDTO } from '../entities/MyEntity';
export interface MyEntityRepository {
create(dto: CreateMyEntityDTO): Promise<MyEntity>;
findById(id: string): Promise<MyEntity | null>;
findByUserId(userId: string): Promise<MyEntity[]>;
update(id: string, data: UpdateMyEntityDTO): Promise<MyEntity>;
delete(id: string): Promise<void>;
}
// Add to packages/database/src/schema.sqlite.ts
export const myEntities = sqliteTable('my_entities', {
id: text('id').primaryKey(),
name: text('name').notNull(),
userId: text('user_id').notNull().references(() => users.id, { onDelete: 'cascade' }),
createdAt: integer('created_at', { mode: 'timestamp_ms' }).notNull(),
updatedAt: integer('updated_at', { mode: 'timestamp_ms' }).notNull(),
});
// packages/api/src/controllers/my-entities.controller.ts
@Controller('my-entities')
export class MyEntitiesController {
constructor(
@Inject(CreateMyEntity) private readonly createMyEntity: CreateMyEntity,
@Inject(ListMyEntities) private readonly listMyEntities: ListMyEntities,
) {}
@Get()
async list(@CurrentUser() user: JwtPayload) {
const items = await this.listMyEntities.execute(user.sub);
return { items };
}
@Post()
@HttpCode(HttpStatus.CREATED)
async create(
@SimpleValidatedBody(CreateMyEntityDto) dto: CreateMyEntityDto,
@CurrentUser() user: JwtPayload,
) {
const item = await this.createMyEntity.execute({ ...dto, userId: user.sub });
return { item };
}
}
// packages/mobile/src/features/my-entity/api.ts
import { api } from '@/lib/api';
export interface MyEntity { id: string; name: string; userId: string; createdAt: string; updatedAt: string; }
export const myEntityApi = {
list: () => api.get<{ items: MyEntity[] }>('/my-entities').then(r => r.items),
get: (id: string) => api.get<{ item: MyEntity }>(`/my-entities/${id}`).then(r => r.item),
create: (data: { name: string }) => api.post<{ item: MyEntity }>('/my-entities', data).then(r => r.item),
update: (id: string, data: { name?: string }) => api.patch<{ item: MyEntity }>(`/my-entities/${id}`, data).then(r => r.item),
delete: (id: string) => api.delete(`/my-entities/${id}`),
};