diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index d388d30..0000000 --- a/.dockerignore +++ /dev/null @@ -1,11 +0,0 @@ -node_modules -npm-debug.log -dist -.env -.git -.gitignore -README.md -.nyc_output -coverage -.coverage -.coverage.* \ No newline at end of file diff --git a/README.ja.md b/README.ja.md index fa168b1..d8431ef 100644 --- a/README.ja.md +++ b/README.ja.md @@ -23,9 +23,8 @@ 7. [プロジェクト構成](#-プロジェクト構成) 8. [開発コマンド](#-開発コマンド) 9. [開発ルールと品質保証](#-開発ルールと品質保証) -10. [アーキテクチャ](#-アーキテクチャ) -11. [多言語対応](#-多言語対応) -12. [よくある質問](#-よくある質問) +10. [多言語対応](#-多言語対応) +11. [よくある質問](#-よくある質問) > **どちらを使うべき?** > - **このボイラープレート**を使う → **Claude Code**で**TypeScript**アプリを**サブエージェント**環境で開発したい場合 @@ -185,18 +184,6 @@ npm run check:deps # 循環依存チェック 手動での確認: `npm run check:all` -## 🏗️ アーキテクチャ - -AIコーディングに適した3つのアーキテクチャパターン: - -| パターン | 適している用途 | 特徴 | -|---------|--------------|------| -| **レイヤード** | エンタープライズアプリケーション | 責務が明確に分離される | -| **垂直スライス** | 機能単位での開発 | 機能ごとにコンテキストが完結 | -| **ハイブリッド進化型** | 段階的に成長するプロジェクト | 小規模から大規模へ柔軟に対応 | - -詳細は`docs/rules/architecture/`をご覧ください - ## 🌐 多言語対応 日本語と英語に対応しています: diff --git a/README.md b/README.md index 1cb62d9..d039518 100644 --- a/README.md +++ b/README.md @@ -23,9 +23,8 @@ 7. [Project Structure](#-project-structure) 8. [Development Commands](#-development-commands) 9. [Rules & Quality Assurance](#-development-rules--quality-assurance) -10. [Architecture Patterns](#-architecture) -11. [Multilingual Support](#-multilingual-support) -12. [FAQ](#-faq) +10. [Multilingual Support](#-multilingual-support) +11. [FAQ](#-faq) > **Which should you use?** > - **Use this Boilerplate** if you're on **Claude Code** and building **TypeScript** apps with a rich **sub-agent** setup. @@ -192,18 +191,6 @@ Sub agents handle quality automatically: Manual verification: `npm run check:all` -## 🏗️ Architecture - -Three proven patterns optimized for AI coding: - -| Pattern | Best For | Key Benefit | -|---------|----------|-------------| -| **Layered** | Enterprise apps | Clear separation of concerns | -| **Vertical Slice** | Features-first development | Minimal context per feature | -| **Hybrid Progressive** | Growing projects | Scales from MVP to enterprise | - -Details in `docs/rules/architecture/` - ## 🌐 Multilingual Support Full support for English and Japanese: diff --git a/docs/rules-en/architecture/hybrid-progressive/rules.md b/docs/rules-en/architecture/hybrid-progressive/rules.md deleted file mode 100644 index 83048a6..0000000 --- a/docs/rules-en/architecture/hybrid-progressive/rules.md +++ /dev/null @@ -1,355 +0,0 @@ -# Hybrid Progressive Architecture - Implementation Rules - -This document defines implementation rules and stage-specific checklists for LLMs when adopting Hybrid Progressive Architecture. - -## Basic Principles - -### 1. Principle of Progressive Evolution -- **Be clear about current Stage**: Always be aware of which stage the project is in -- **Allow coexistence**: Accept coexistence of different structures -- **Flexibility in structural changes**: Bold structural changes are possible according to project requirements - -### 2. Consistency in Decision Making -- **New features**: Implement with current Stage's recommended pattern -- **Modifying existing features**: Respect existing structure -- **Refactoring**: Implement based on clear criteria - -## Stage-Specific Implementation Rules - -### Stage 1: Simple Vertical Slicing - -#### Directory Structure -``` -src/ -├── features/ -│ └── [action-name].ts # e.g., create-todo.ts -└── lib/ - └── [utility].ts # e.g., database.ts -``` - -#### Implementation Rules -- **Single file completion**: Write all processing in one file -- **Duplication allowed**: OK to have same code in multiple files -- **Minimal consolidation**: Only DB connection level goes to lib/ - -#### Code Example -```typescript -// features/create-todo.ts -import { db } from '../lib/database' - -// Type definitions also in this file -interface Todo { - id: string - title: string - completed: boolean -} - -// Validation included -function validateTitle(title: string): void { - if (!title || title.length > 100) { - throw new Error('Invalid title') - } -} - -// Main function -export async function createTodo(title: string, userId: string): Promise { - validateTitle(title) - - const todo = await db.insert('todos', { - title, - userId, - completed: false, - createdAt: new Date(), - }) - - return todo -} -``` - -### Stage 2: Feature Grouping - -#### Directory Structure -``` -src/ -├── features/ -│ └── [feature]/ -│ ├── [action].ts # e.g., create.ts -│ └── shared/ -│ ├── types.ts -│ └── utils.ts -└── lib/ -``` - -#### Implementation Rules -- **Consolidation within feature**: Duplication within same feature goes to `shared/` -- **Feature independence**: Don't reference other feature folders -- **Interface definition**: Consolidate type definitions in `shared/types.ts` - -#### Code Example -```typescript -// features/todo/shared/types.ts -export interface Todo { - id: string - title: string - completed: boolean - userId: string - createdAt: Date -} - -export interface CreateTodoInput { - title: string - userId: string -} - -// features/todo/shared/validation.ts -export function validateTodoTitle(title: string): void { - if (!title || title.length > 100) { - throw new Error('Invalid title') - } -} - -// features/todo/create.ts -import { db } from '../../lib/database' -import { validateTodoTitle } from './shared/validation' -import type { Todo, CreateTodoInput } from './shared/types' - -export async function createTodo(input: CreateTodoInput): Promise { - validateTodoTitle(input.title) - - return db.insert('todos', { - ...input, - completed: false, - createdAt: new Date(), - }) -} -``` - -### Stage 3: Partial Layer Introduction - -#### Directory Structure -``` -src/ -├── features/ # By feature (maintain vertical slicing) -├── shared/ -│ ├── domain/ # Common domain -│ │ ├── entities/ -│ │ └── value-objects/ -│ └── infrastructure/ -│ └── repositories/ -└── lib/ -``` - -#### Implementation Rules -- **Common domain models**: Entities used by multiple features go to `shared/domain` -- **Repository pattern**: DB operations go to `shared/infrastructure` -- **Maintain feature-specific logic**: Business logic stays in each feature - -#### Code Example -```typescript -// shared/domain/entities/Todo.ts -export class Todo { - constructor( - public readonly id: string, - public readonly title: string, - public readonly userId: string, - public readonly completed: boolean, - public readonly createdAt: Date, - ) {} - - static create(params: { - title: string - userId: string - }): Todo { - return new Todo( - generateId(), - params.title, - params.userId, - false, - new Date(), - ) - } -} - -// shared/infrastructure/repositories/TodoRepository.ts -import { Todo } from '../../domain/entities/Todo' -import { db } from '../../../lib/database' - -export class TodoRepository { - async save(todo: Todo): Promise { - await db.insert('todos', { - id: todo.id, - title: todo.title, - userId: todo.userId, - completed: todo.completed, - createdAt: todo.createdAt, - }) - return todo - } -} - -// features/todo/create.ts -import { Todo } from '../../shared/domain/entities/Todo' -import { TodoRepository } from '../../shared/infrastructure/repositories/TodoRepository' - -const todoRepository = new TodoRepository() - -export async function createTodo(title: string, userId: string): Promise { - // Business rules remain within feature - if (title.includes('forbidden')) { - throw new Error('Forbidden word in title') - } - - const todo = Todo.create({ title, userId }) - return todoRepository.save(todo) -} -``` - -### Stage 4: Hybrid Structure - -#### Directory Structure -``` -src/ -├── features/ # New/experimental features -├── modules/ # Mature features (layered) -│ └── [module]/ -│ ├── application/ -│ ├── domain/ -│ └── infrastructure/ -└── shared/ # Project-wide common -``` - -#### Implementation Rules -- **New features**: Vertical slicing implementation in `features/` -- **Stable features**: Layered implementation in `modules/` -- **Migration criteria**: Stable for 3+ months or touched by 5+ people - -## Migration Rules - -### Migration Steps Between Stages - -#### Stage 1 → Stage 2 -1. Identify related features (e.g., todo-related) -2. Create feature directory -3. Move files (e.g., `create-todo.ts` → `todo/create.ts`) -4. Extract common code to `shared/` -5. Update import paths - -#### Stage 2 → Stage 3 -1. Identify common entities -2. Move to `shared/domain/entities/` -3. Introduce repository pattern -4. Reference entities from each feature - -#### Stage 3 → Stage 4 -1. Identify stable feature modules -2. Create `modules/[module]/` directory -3. Reorganize code by layers -4. Migrate tests simultaneously - -### Migration Considerations - -#### ✅ What to Do -- **Migrate one feature at a time**: Don't change everything at once -- **Write tests first**: Ensure behavior before migration -- **Commit units**: 1 migration = 1 commit - -#### ❌ What Not to Do -- **Partial migration**: Making only part of the new structure -- **Excessive abstraction**: Don't add features during migration -- **Structural consistency**: Minimize mixing old and new structures during migration - -## Decision Flowchart - -``` -Decision when writing new code: - -1. Are there existing related features? - ├─ Yes → Match that feature's structure - └─ No → Go to 2 - -2. What is the current project Stage? - ├─ Stage 1 → Single file directly under features/ - ├─ Stage 2 → Under features/[feature-name]/ - ├─ Stage 3 → Use shared/ for common parts - └─ Stage 4 → features/ if experimental, modules/ if stable - -3. After implementation, check migration criteria - └─ Criteria met → Plan migration to next Stage -``` - -## Coding Standards - -### Naming Conventions -- **Stage 1-2**: Kebab case (`create-todo.ts`) -- **Stage 3-4**: Camel case (`createTodo.ts`) -- **During migration**: Unify to new naming convention - -### Import Order -```typescript -// 1. External libraries -import { z } from 'zod' - -// 2. Imports from shared/ -import { Todo } from '../../shared/domain/entities/Todo' - -// 3. Imports from same feature -import { validateInput } from './shared/validation' - -// 4. Imports from lib/ -import { logger } from '../../lib/logger' -``` - -## Quality Management - -### Quality Criteria for Each Stage - -#### Stage 1 -- [ ] Each file works independently -- [ ] Basic error handling exists -- [ ] Minimal validation exists - -#### Stage 2 -- [ ] Clear type definitions -- [ ] Consistency within feature -- [ ] Basic tests exist - -#### Stage 3 -- [ ] Appropriate domain models -- [ ] Repository pattern correctly implemented -- [ ] Integration tests exist - -#### Stage 4 -- [ ] Clear responsibilities for each layer -- [ ] Dependency injection utilized -- [ ] Coverage 70% or higher - -## LLM Implementation Guidelines - -### Basic Flow for Implementation -1. **Stage identification**: Confirm current Stage -2. **Pattern confirmation**: Match existing structure -3. **Progressive implementation**: Follow current Stage's rules -4. **Quality check**: Confirm by Stage-specific criteria - -### Decision Criteria (Priority when in doubt) -1. **Respect existing patterns** - Maintain project consistency -2. **Match current Stage** - Don't prematurely advance -3. **Progressive improvement** - Don't make large changes at once - -### Escalation Criteria -Confirm with user in the following cases: -- When considering Stage migration -- Clear exceeding of initially assumed scope -- Architecture-level changes -- Adding new dependencies - -## Summary - -Hybrid Progressive Architecture is an approach that can flexibly evolve with project growth. Important points for LLMs: - -1. **Clearly recognize current Stage** - Always confirm before implementation -2. **Consistent decision making** - Respect existing patterns -3. **Progressive migration** - Avoid drastic changes -4. **Continue quality checks** - Meet criteria at each Stage - -**One phrase to remember: "When in doubt, follow the current Stage's rules"** \ No newline at end of file diff --git a/docs/rules-en/architecture/vertical-slice/rules.md b/docs/rules-en/architecture/vertical-slice/rules.md deleted file mode 100644 index 831a89a..0000000 --- a/docs/rules-en/architecture/vertical-slice/rules.md +++ /dev/null @@ -1,240 +0,0 @@ -# Vertical Slice Architecture - Implementation Rules - -This document defines implementation rules and checklists for LLMs when adopting Vertical Slice Architecture. - -## Core Implementation Rules - -### 1. File Organization Principles - -#### ✅ Mandatory Rules -- **1 Feature 1 File**: Each feature is implemented in an independent file -- **Self-containment**: Minimize dependencies on external files -- **Clear Naming**: Filenames clearly express the feature (e.g., `create-todo.ts`, `send-email.ts`) - -#### ❌ Prohibited -- Don't mix multiple features in one file -- Don't create unnecessary abstraction layers -- Don't pre-design for future extensibility - -### 2. Directory Structure - -``` -src/ -├── features/ # Feature-based code -│ └── [feature-name]/ # Feature group -│ ├── [action].ts # Each action -│ └── shared/ # Common code within feature -└── lib/ # Pure function libraries -``` - -### 3. File Internal Structure - -Each feature file should be structured in the following order: - -```typescript -// 1. Imports -import { z } from 'zod' -import { database } from '../../lib/database' - -// 2. Type definitions/schemas -const InputSchema = z.object({...}) -type Output = {...} - -// 3. Internal helper functions -function validateBusinessRule(...) {...} - -// 4. Main processing function (export) -export async function mainFunction(input: unknown): Promise { - // Implementation -} - -// 5. HTTP handlers etc. (if needed) -export async function httpHandler(req: Request): Promise { - // Implementation -} -``` - -## Implementation Guidelines - -### When Adding New Features - -1. **Determine Feature Granularity** - - 1 business action = 1 file - - Example: "Create Todo" = `create-todo.ts` - -2. **Create Directory** - ```bash - mkdir -p src/features/[feature-name] - ``` - -3. **Create File** - - Use clear action-based filename - - Use kebab-case - -### Error Handling - -```typescript -// Self-contained error handling within file -export async function createTodo(input: unknown): Promise { - try { - // Validation - const validated = Schema.parse(input) - - // Business logic - // ... - - return result - } catch (error) { - // Handle appropriately within this file - if (error instanceof z.ZodError) { - throw new ValidationError('Invalid input', error.errors) - } - throw error - } -} -``` - -### Test Placement - -``` -features/ -└── todo/ - ├── create-todo.ts - ├── create-todo.test.ts # Place in same directory - └── shared/ -``` - -## Consolidation Decision Criteria - -### What to Consolidate (place in lib/) -- **Pure Functions**: Generic functions without side effects -- **Generic Utilities**: Date formatting, string processing, etc. -- **Constants**: Configuration values used across the application - -### What Not to Consolidate -- **Logic Dependent on Specific Features**: Keep within feature directory -- **Code Used in Only 2-3 Places**: Allow duplication -- **Business Logic**: Implement directly in each feature file - -### Progressive Consolidation - -```typescript -// Step 1: First write working code (duplication OK) -// features/todo/create-todo.ts -function formatDate(date: Date): string { - return date.toISOString().split('T')[0] -} - -// Step 2: Consider after 3+ duplications -// features/[feature]/shared/format.ts -export function formatDate(date: Date): string { - return date.toISOString().split('T')[0] -} - -// Step 3: Move to lib/ after 5+ usages -// lib/date-utils.ts -export function formatDate(date: Date): string { - return date.toISOString().split('T')[0] -} -``` - -## LLM Implementation Checklist - -### Pre-implementation Checks -- [ ] Feature scope is limited to one business action -- [ ] Filename clearly expresses the feature -- [ ] Existing related feature patterns have been reviewed -- [ ] Test file placement has been determined - -### Implementation Checkpoints -- [ ] All processing is contained within one file -- [ ] Dependencies on external files are minimal -- [ ] Error handling is self-contained within file -- [ ] Validation logic is embedded - -### Post-implementation Checks -- [ ] Test coverage is 70% or higher -- [ ] Tests don't depend on other tests -- [ ] Feature works completely -- [ ] Code has an understandable structure - -## Anti-patterns - -### ❌ Patterns to Avoid - -1. **Excessive Abstraction** - ```typescript - // Bad example: Unnecessary interfaces - interface TodoService { - create(dto: CreateTodoDto): Promise - } - - class TodoServiceImpl implements TodoService { - constructor(private repository: TodoRepository) {} - } - ``` - -2. **Layer Separation** - ```typescript - // Bad example: Split into layers - // controllers/todo.controller.ts - // services/todo.service.ts - // repositories/todo.repository.ts - ``` - -3. **Premature Optimization** - ```typescript - // Bad example: Design anticipating future expansion - abstract class BaseHandler { - abstract validate(input: T): void - abstract execute(input: T): Promise - } - ``` - -## Best Practices - -### 1. Keep It Simple -- Write everything in the file first -- Consolidate only when needed -- Thoroughly apply YAGNI principle - -### 2. Prioritize Readability -- Even a 1000-line file is OK if logically organized -- Use comments to clarify sections -- Keep functions small - -### 3. Test First -- Write tests before implementing features -- Manage tests with same file structure -- Minimize mocks - -## LLM Implementation Guidelines - -### Flow for New Feature Implementation -1. **Check Feature Directory**: Confirm directory for relevant feature -2. **Pattern Check**: Follow existing patterns if code exists -3. **Self-contained Implementation**: Implement to complete in 1 file -4. **Test Creation**: Create test file in same directory - -### Refactoring Priority -1. **In-file Improvements**: Prioritize improvements within one file -2. **Minimal Cross-file Changes**: Minimize changes across files -3. **Rule of Three**: Consider consolidation only after 3+ actual duplications - -### Decision Criteria (Priority when in doubt) -1. **Choose Simplicity** - Simple solutions over complex design -2. **Choose Independence** - Self-containment over inter-file dependencies -3. **Choose 1 File Completion** - Integration over splitting - -### Escalation Criteria -Confirm with user in the following cases: -- Clear exceeding of initially assumed scope -- Architecture-level changes -- Adding new dependencies -- Changes with significant performance impact - -## Summary - -This architecture is designed for LLMs to work most efficiently. While it may seem redundant to humans, it's the most understandable and modifiable structure for LLMs. - -**One phrase to remember: "When in doubt, don't split, write in 1 file"** \ No newline at end of file diff --git a/docs/rules-en/rules-index.yaml b/docs/rules-en/rules-index.yaml index 65ade00..7d1956f 100644 --- a/docs/rules-en/rules-index.yaml +++ b/docs/rules-en/rules-index.yaml @@ -118,42 +118,6 @@ rules: - "Diagram Requirements" - "Common ADR Relationships" - vertical-slice-architecture: - file: "architecture/vertical-slice/rules.md" - tags: [architecture, vertical-slice, llm-optimized, single-file, implementation] - typical-use: "When adopting Vertical Slice Architecture, feature implementation" - size: medium - key-references: - - "Vertical Slice Architecture - Jimmy Bogard" - - "Anthropic LLM Research" - sections: - - "Core Implementation Rules" - - "Implementation Guidelines" - - "Consolidation Decision Criteria" - - "LLM Implementation Checklist" - - "Anti-patterns" - - "Best Practices" - - "LLM Implementation Guidelines" - - "Summary" - - hybrid-progressive-architecture: - file: "architecture/hybrid-progressive/rules.md" - tags: [architecture, scalable, progressive, layered, implementation] - typical-use: "Progressively growing projects, implementation rule application" - size: medium - key-references: - - "Evolutionary Architecture - Neal Ford" - - "Building Microservices - Sam Newman" - sections: - - "Basic Principles" - - "Stage-specific Implementation Rules" - - "Migration Rules" - - "Decision Flowchart" - - "Coding Conventions" - - "Quality Management" - - "LLM Implementation Guidelines" - - "Summary" - implementation-approach: file: "architecture/implementation-approach.md" tags: [architecture, implementation, task-decomposition, strategy-patterns, strangler-pattern, facade-pattern, design, planning, confirmation-levels] diff --git a/docs/rules-ja/architecture/hybrid-progressive/rules.md b/docs/rules-ja/architecture/hybrid-progressive/rules.md deleted file mode 100644 index 300c5e5..0000000 --- a/docs/rules-ja/architecture/hybrid-progressive/rules.md +++ /dev/null @@ -1,355 +0,0 @@ -# Hybrid Progressive Architecture - 実装ルール - -このドキュメントは、Hybrid Progressive Architectureを採用した場合のLLM向け実装ルールとStage別チェックリストを定義します。 - -## 基本原則 - -### 1. 段階的進化の原則 -- **現在のStageを明確に**: プロジェクトがどの段階にあるかを常に意識 -- **混在を許容**: 異なる構造の共存を認める -- **構造変更の柔軟性**: プロジェクトの要件に応じて、大胆な構造変更も可能 - -### 2. 判断の一貫性 -- **新機能**: 現在のStageの推奨パターンで実装 -- **既存機能の修正**: 既存の構造を尊重 -- **リファクタリング**: 明確な基準に基づいて実施 - -## Stage別実装ルール - -### Stage 1: シンプル垂直分割 - -#### ディレクトリ構造 -``` -src/ -├── features/ -│ └── [action-name].ts # 例: create-todo.ts -└── lib/ - └── [utility].ts # 例: database.ts -``` - -#### 実装ルール -- **1ファイル完結**: 全ての処理を1つのファイルに記述 -- **重複許容**: 同じコードが複数ファイルにあってもOK -- **最小限の共通化**: DBコネクション程度のみlib/へ - -#### コード例 -```typescript -// features/create-todo.ts -import { db } from '../lib/database' - -// 型定義もこのファイル内に -interface Todo { - id: string - title: string - completed: boolean -} - -// バリデーションも内包 -function validateTitle(title: string): void { - if (!title || title.length > 100) { - throw new Error('Invalid title') - } -} - -// メイン関数 -export async function createTodo(title: string, userId: string): Promise { - validateTitle(title) - - const todo = await db.insert('todos', { - title, - userId, - completed: false, - createdAt: new Date(), - }) - - return todo -} -``` - -### Stage 2: 機能グループ化 - -#### ディレクトリ構造 -``` -src/ -├── features/ -│ └── [feature]/ -│ ├── [action].ts # 例: create.ts -│ └── shared/ -│ ├── types.ts -│ └── utils.ts -└── lib/ -``` - -#### 実装ルール -- **機能内共通化**: 同一機能内の重複は`shared/`へ -- **機能間独立**: 他の機能フォルダを参照しない -- **インターフェース定義**: 型定義は`shared/types.ts`に集約 - -#### コード例 -```typescript -// features/todo/shared/types.ts -export interface Todo { - id: string - title: string - completed: boolean - userId: string - createdAt: Date -} - -export interface CreateTodoInput { - title: string - userId: string -} - -// features/todo/shared/validation.ts -export function validateTodoTitle(title: string): void { - if (!title || title.length > 100) { - throw new Error('Invalid title') - } -} - -// features/todo/create.ts -import { db } from '../../lib/database' -import { validateTodoTitle } from './shared/validation' -import type { Todo, CreateTodoInput } from './shared/types' - -export async function createTodo(input: CreateTodoInput): Promise { - validateTodoTitle(input.title) - - return db.insert('todos', { - ...input, - completed: false, - createdAt: new Date(), - }) -} -``` - -### Stage 3: 部分的レイヤー導入 - -#### ディレクトリ構造 -``` -src/ -├── features/ # 機能別(垂直分割維持) -├── shared/ -│ ├── domain/ # 共通ドメイン -│ │ ├── entities/ -│ │ └── value-objects/ -│ └── infrastructure/ -│ └── repositories/ -└── lib/ -``` - -#### 実装ルール -- **共通ドメインモデル**: 複数機能で使うエンティティは`shared/domain`へ -- **リポジトリパターン**: DB操作は`shared/infrastructure`へ -- **機能特有ロジックは維持**: ビジネスロジックは各機能に残す - -#### コード例 -```typescript -// shared/domain/entities/Todo.ts -export class Todo { - constructor( - public readonly id: string, - public readonly title: string, - public readonly userId: string, - public readonly completed: boolean, - public readonly createdAt: Date, - ) {} - - static create(params: { - title: string - userId: string - }): Todo { - return new Todo( - generateId(), - params.title, - params.userId, - false, - new Date(), - ) - } -} - -// shared/infrastructure/repositories/TodoRepository.ts -import { Todo } from '../../domain/entities/Todo' -import { db } from '../../../lib/database' - -export class TodoRepository { - async save(todo: Todo): Promise { - await db.insert('todos', { - id: todo.id, - title: todo.title, - userId: todo.userId, - completed: todo.completed, - createdAt: todo.createdAt, - }) - return todo - } -} - -// features/todo/create.ts -import { Todo } from '../../shared/domain/entities/Todo' -import { TodoRepository } from '../../shared/infrastructure/repositories/TodoRepository' - -const todoRepository = new TodoRepository() - -export async function createTodo(title: string, userId: string): Promise { - // ビジネスルールは機能内に残す - if (title.includes('forbidden')) { - throw new Error('Forbidden word in title') - } - - const todo = Todo.create({ title, userId }) - return todoRepository.save(todo) -} -``` - -### Stage 4: ハイブリッド構造 - -#### ディレクトリ構造 -``` -src/ -├── features/ # 新機能・実験的機能 -├── modules/ # 成熟した機能(レイヤード) -│ └── [module]/ -│ ├── application/ -│ ├── domain/ -│ └── infrastructure/ -└── shared/ # 全体共通 -``` - -#### 実装ルール -- **新機能**: `features/`で垂直分割実装 -- **安定機能**: `modules/`でレイヤード実装 -- **移行基準**: 3ヶ月以上安定 or 5人以上が触る - -## 移行ルール - -### Stage間の移行手順 - -#### Stage 1 → Stage 2 -1. 関連機能を特定(例: todo関連) -2. 機能ディレクトリを作成 -3. ファイルを移動(例: `create-todo.ts` → `todo/create.ts`) -4. 共通コードを`shared/`に抽出 -5. インポートパスを更新 - -#### Stage 2 → Stage 3 -1. 共通エンティティを特定 -2. `shared/domain/entities/`に移動 -3. リポジトリパターンを導入 -4. 各機能からエンティティを参照 - -#### Stage 3 → Stage 4 -1. 安定した機能モジュールを特定 -2. `modules/[module]/`ディレクトリを作成 -3. レイヤー別にコードを再編成 -4. テストも同時に移行 - -### 移行時の注意点 - -#### ✅ やるべきこと -- **一機能ずつ移行**: 全体を一度に変えない -- **テストを先に書く**: 移行前に動作を保証 -- **コミット単位**: 1つの移行 = 1コミット - -#### ❌ やってはいけないこと -- **中途半端な移行**: 一部だけ新構造にする -- **過度な抽象化**: 移行時に機能追加しない -- **構造の一貫性**: 移行時は新旧構造の混在を最小限に - -## 判断フローチャート - -``` -新しいコードを書く時の判断: - -1. 既存の関連機能があるか? - ├─ Yes → その機能の構造に合わせる - └─ No → 2へ - -2. 現在のプロジェクトStageは? - ├─ Stage 1 → features/直下に単一ファイル - ├─ Stage 2 → features/[機能名]/配下 - ├─ Stage 3 → 共通部分はshared/を使用 - └─ Stage 4 → 実験的ならfeatures/、安定ならmodules/ - -3. 実装後、移行基準を確認 - └─ 基準を満たす → 次Stageへの移行を計画 -``` - -## コーディング規約 - -### 命名規則 -- **Stage 1-2**: ケバブケース(`create-todo.ts`) -- **Stage 3-4**: キャメルケース(`createTodo.ts`) -- **移行時**: 新しい命名規則に統一 - -### インポート順序 -```typescript -// 1. 外部ライブラリ -import { z } from 'zod' - -// 2. shared/からのインポート -import { Todo } from '../../shared/domain/entities/Todo' - -// 3. 同一機能内からのインポート -import { validateInput } from './shared/validation' - -// 4. lib/からのインポート -import { logger } from '../../lib/logger' -``` - -## 品質管理 - -### 各Stageの品質基準 - -#### Stage 1 -- [ ] 各ファイルが独立して動作する -- [ ] 基本的なエラーハンドリングがある -- [ ] 最低限のバリデーションがある - -#### Stage 2 -- [ ] 型定義が明確 -- [ ] 機能内で一貫性がある -- [ ] 基本的なテストがある - -#### Stage 3 -- [ ] ドメインモデルが適切 -- [ ] リポジトリパターンが正しく実装 -- [ ] 統合テストがある - -#### Stage 4 -- [ ] 各レイヤーの責務が明確 -- [ ] 依存性注入が活用されている -- [ ] カバレッジ70%以上 - -## LLM向け実装指針 - -### 実装時の基本フロー -1. **Stage特定**: 現在のStageを確認 -2. **パターン確認**: 既存の構造に合わせる -3. **段階的実装**: 現在のStageのルールに従う -4. **品質チェック**: Stage別基準で確認 - -### 判断基準(迷った時の優先順位) -1. **既存パターンを尊重** - プロジェクトの一貫性を保つ -2. **現在のStageに合わせる** - 無理な先取りをしない -3. **段階的改善** - 一度に大きな変更をしない - -### エスカレーション基準 -以下の場合はユーザーに確認: -- Stageの移行を検討する時 -- 当初想定範囲の明らかな超過 -- アーキテクチャレベルの変更 -- 新しい依存関係の追加 - -## まとめ - -Hybrid Progressive Architectureは、プロジェクトの成長に合わせて柔軟に進化できるアプローチです。LLMとしての重要なポイント: - -1. **現在のStageを明確に認識** - 実装前に必ず確認 -2. **一貫性のある判断** - 既存パターンを尊重 -3. **段階的な移行** - 急激な変更を避ける -4. **品質チェックの継続** - 各Stageで基準を満たす - -**覚えておくべき一言:「迷ったら現在のStageのルールに従う」** \ No newline at end of file diff --git a/docs/rules-ja/architecture/vertical-slice/rules.md b/docs/rules-ja/architecture/vertical-slice/rules.md deleted file mode 100644 index 93f336e..0000000 --- a/docs/rules-ja/architecture/vertical-slice/rules.md +++ /dev/null @@ -1,240 +0,0 @@ -# Vertical Slice Architecture - 実装ルール - -このドキュメントは、Vertical Slice Architectureを採用した場合のLLM向け実装ルールとチェックリストを定義します。 - -## コア実装ルール - -### 1. ファイル構成の原則 - -#### ✅ 必須ルール -- **1機能1ファイル**: 各機能は独立したファイルに実装する -- **自己完結性**: 外部ファイルへの依存は最小限に抑える -- **明確な命名**: ファイル名は機能を明確に表現する(例: `create-todo.ts`, `send-email.ts`) - -#### ❌ 禁止事項 -- 複数の機能を1つのファイルに混在させない -- 不必要な抽象化レイヤーを作らない -- 将来の拡張性のための事前設計をしない - -### 2. ディレクトリ構造 - -``` -src/ -├── features/ # 機能別のコード -│ └── [feature-name]/ # 機能グループ -│ ├── [action].ts # 各アクション -│ └── shared/ # 機能内共通コード -└── lib/ # 純粋関数ライブラリ -``` - -### 3. ファイル内の構造 - -各機能ファイルは以下の順序で構成する: - -```typescript -// 1. インポート -import { z } from 'zod' -import { database } from '../../lib/database' - -// 2. 型定義・スキーマ -const InputSchema = z.object({...}) -type Output = {...} - -// 3. 内部ヘルパー関数 -function validateBusinessRule(...) {...} - -// 4. メイン処理関数(エクスポート) -export async function mainFunction(input: unknown): Promise { - // 実装 -} - -// 5. HTTPハンドラー等(必要な場合) -export async function httpHandler(req: Request): Promise { - // 実装 -} -``` - -## 実装ガイドライン - -### 新機能を追加する時 - -1. **機能の粒度を決定** - - 1つのビジネスアクション = 1ファイル - - 例: "Todoを作成する" = `create-todo.ts` - -2. **ディレクトリを作成** - ```bash - mkdir -p src/features/[feature-name] - ``` - -3. **ファイルを作成** - - アクション名を明確にしたファイル名を使用 - - ケバブケース(kebab-case)を使用 - -### エラーハンドリング - -```typescript -// ファイル内で完結したエラーハンドリング -export async function createTodo(input: unknown): Promise { - try { - // バリデーション - const validated = Schema.parse(input) - - // ビジネスロジック - // ... - - return result - } catch (error) { - // このファイル内で適切にハンドリング - if (error instanceof z.ZodError) { - throw new ValidationError('Invalid input', error.errors) - } - throw error - } -} -``` - -### テストの配置 - -``` -features/ -└── todo/ - ├── create-todo.ts - ├── create-todo.test.ts # 同じディレクトリに配置 - └── shared/ -``` - -## 共通化の判断基準 - -### 共通化すべきもの(lib/に配置) -- **純粋関数**: 副作用のない汎用的な関数 -- **汎用ユーティリティ**: 日付フォーマット、文字列処理等 -- **定数**: アプリケーション全体で使用する設定値 - -### 共通化すべきでないもの -- **特定機能に依存するロジック**: その機能のディレクトリ内に留める -- **2-3箇所でしか使わないコード**: 重複を許容 -- **ビジネスロジック**: 各機能ファイルに直接実装 - -### 段階的な共通化 - -```typescript -// Step 1: まず動作するコードを書く(重複OK) -// features/todo/create-todo.ts -function formatDate(date: Date): string { - return date.toISOString().split('T')[0] -} - -// Step 2: 3回以上重複したら検討 -// features/[feature]/shared/format.ts -export function formatDate(date: Date): string { - return date.toISOString().split('T')[0] -} - -// Step 3: 5箇所以上で使用されたらlib/へ -// lib/date-utils.ts -export function formatDate(date: Date): string { - return date.toISOString().split('T')[0] -} -``` - -## LLM向け実装チェックリスト - -### 実装前の確認事項 -- [ ] 機能の範囲が1つのビジネスアクションに限定されている -- [ ] ファイル名が機能を明確に表現している -- [ ] 既存の関連機能のパターンを確認済み -- [ ] テストファイルの配置場所を決定済み - -### 実装中のチェックポイント -- [ ] 全ての処理が1ファイル内で完結している -- [ ] 外部ファイルへの依存が最小限 -- [ ] エラーハンドリングがファイル内で完結 -- [ ] バリデーションロジックが組み込まれている - -### 実装後の確認事項 -- [ ] テストカバレッジが70%以上 -- [ ] テストが他のテストに依存していない -- [ ] 機能が完全に動作する -- [ ] コードが理解しやすい構造になっている - -## アンチパターン - -### ❌ 避けるべきパターン - -1. **過度な抽象化** - ```typescript - // 悪い例: 不必要なインターフェース - interface TodoService { - create(dto: CreateTodoDto): Promise - } - - class TodoServiceImpl implements TodoService { - constructor(private repository: TodoRepository) {} - } - ``` - -2. **レイヤー分割** - ```typescript - // 悪い例: レイヤーに分割 - // controllers/todo.controller.ts - // services/todo.service.ts - // repositories/todo.repository.ts - ``` - -3. **早すぎる最適化** - ```typescript - // 悪い例: 将来の拡張を見越した設計 - abstract class BaseHandler { - abstract validate(input: T): void - abstract execute(input: T): Promise - } - ``` - -## ベストプラクティス - -### 1. シンプルさを保つ -- 最初は全てをファイル内に書く -- 必要になってから共通化する -- YAGNIの原則を徹底する - -### 2. 読みやすさを優先 -- 1000行のファイルでも、論理的に整理されていればOK -- コメントで区切りを明確にする -- 関数は小さく保つ - -### 3. テストファースト -- 機能を実装する前にテストを書く -- テストも同じファイル構造で管理 -- モックは最小限に - -## LLM向け実装指針 - -### 新機能実装時のフロー -1. **機能ディレクトリ確認**: 該当する機能のディレクトリを確認 -2. **パターン確認**: 既存コードがある場合はそのパターンに従う -3. **自己完結実装**: 1ファイルで完結するよう実装 -4. **テスト作成**: 同じディレクトリにテストファイルを作成 - -### リファクタリング時の優先順位 -1. **ファイル内改善**: 1つのファイル内での改善を優先 -2. **最小限のファイル間変更**: ファイルを跨いだ変更は最小限に -3. **3回ルール**: 共通化は実際に3回以上重複してから検討 - -### 判断基準(迷った時の優先順位) -1. **シンプルさを選ぶ** - 複雑な設計より単純な解決策 -2. **独立性を選ぶ** - ファイル間依存より自己完結 -3. **1ファイル完結を選ぶ** - 分割より統合 - -### エスカレーション基準 -以下の場合はユーザーに確認: -- 当初想定範囲の明らかな超過 -- アーキテクチャレベルの変更 -- 新しい依存関係の追加 -- パフォーマンスに大きな影響を与える変更 - -## まとめ - -このアーキテクチャは、LLMが最も効率的に作業できるよう設計されています。人間にとっては冗長に見えるかもしれませんが、LLMにとっては最も理解しやすく、修正しやすい構造です。 - -**覚えておくべき一言:「迷ったら分割せず、1ファイルに書く」** \ No newline at end of file diff --git a/docs/rules-ja/rules-index.yaml b/docs/rules-ja/rules-index.yaml index 3bf041c..3644c86 100644 --- a/docs/rules-ja/rules-index.yaml +++ b/docs/rules-ja/rules-index.yaml @@ -118,42 +118,6 @@ rules: - "図表作成要件" - "共通ADRとの関係性" - vertical-slice-architecture: - file: "architecture/vertical-slice/rules.md" - tags: [architecture, vertical-slice, llm-optimized, single-file, implementation] - typical-use: "Vertical Slice Architecture採用時、機能実装" - size: medium - key-references: - - "Vertical Slice Architecture - Jimmy Bogard" - - "Anthropic LLM Research" - sections: - - "コア実装ルール" - - "実装ガイドライン" - - "共通化の判断基準" - - "LLM向け実装チェックリスト" - - "アンチパターン" - - "ベストプラクティス" - - "LLM向け実装指針" - - "まとめ" - - hybrid-progressive-architecture: - file: "architecture/hybrid-progressive/rules.md" - tags: [architecture, scalable, progressive, layered, implementation] - typical-use: "段階的に成長するプロジェクト、実装ルール適用" - size: medium - key-references: - - "Evolutionary Architecture - Neal Ford" - - "Building Microservices - Sam Newman" - sections: - - "基本原則" - - "Stage別実装ルール" - - "移行ルール" - - "判断フローチャート" - - "コーディング規約" - - "品質管理" - - "LLM向け実装指針" - - "まとめ" - implementation-approach: file: "architecture/implementation-approach.md" tags: [architecture, implementation, task-decomposition, strategy-patterns, strangler-pattern, facade-pattern, design, planning, confirmation-levels] diff --git a/package-lock.json b/package-lock.json index 9e12122..51a61af 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ai-coding-project-boilerplate", - "version": "1.7.12", + "version": "1.7.13", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ai-coding-project-boilerplate", - "version": "1.7.12", + "version": "1.7.13", "hasInstallScript": true, "license": "MIT", "bin": { diff --git a/package.json b/package.json index f79b9da..ada38a3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ai-coding-project-boilerplate", - "version": "1.7.12", + "version": "1.7.13", "description": "TypeScript project boilerplate optimized for Claude Code development with comprehensive development rules, architecture patterns, and quality assurance tools", "main": "dist/index.js", "keywords": [