# Development Guidelines
Development guidelines and best practices for this project.
---
## Core Principles
This project follows industry-standard software engineering principles:
### ๐ฏ Validation First (์ต์ฐ์ ์์น)
> **"๊ฒ์ฆ์ ์ด๋ป๊ฒ ํ ๊ฒ์ธ๊ฐ?"๋ฅผ ๋จผ์ ์ ์ํฉ๋๋ค.**
- **Before Writing Code**: ์ฝ๋ ์์ฑ ์ ์ ๊ฒ์ฆ ๋ฐฉ๋ฒ๋ถํฐ ์ ์
- **No Validation, No Code**: ๊ฒ์ฆ ๋ฐฉ๋ฒ์ด ์์ผ๋ฉด ์ฝ๋๋ฅผ ์์ฑํ์ง ์์
- **Test-Driven Development**: ํ
์คํธ๋ฅผ ๋จผ์ ์์ฑ (Red-Green-Refactor)
- **Automated Verification**: ๋ชจ๋ ๊ฒ์ฆ์ ์๋ํ (CI/CD)
- **Never Skip Validation**: ๊ฒ์ฆ ์คํจ ์ ์ฐํํ์ง ์๊ณ ์ฆ์ ์์
๐ **See**: [VALIDATION_STRATEGY.md](./VALIDATION_STRATEGY.md) for complete validation methodology
---
### Other Engineering Principles
- **SOLID Principles**: Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation, Dependency Inversion
- **DRY (Don't Repeat Yourself)**: Extract repeated patterns into reusable components
- **KISS (Keep It Simple)**: Favor simple solutions over complex ones
- **YAGNI (You Aren't Gonna Need It)**: Implement only what's needed now
For detailed explanations, TypeScript examples, code review checklists, and refactoring patterns, see the [development-guidelines skill](../.claude/skills/development-guidelines/SKILL.md).
---
## SDD + TDD Integration
Specification-Driven Development (SDD) combined with Test-Driven Development (TDD) for high-quality code.
### Workflow: Spec โ Test โ Code (STC)
SDD extends TDD by adding a specification phase before testing:
```
1. [Spec] Write RFC/ADR โ Define what to build and why
2. [Test] Define test cases from spec โ Clarify acceptance criteria
3. [Code] TDD Cycle (Red-Green-Refactor) โ Implement with tests
4. [Review] Validate against spec โ Ensure compliance
5. [Iterate] Update spec if needed โ Keep docs synchronized
```
### When to Write RFC vs ADR
**RFC (Request for Comments)**: Use for new features
- New functionality or modules
- API/interface changes
- Complex refactoring plans
- User-facing changes
**ADR (Architecture Decision Record)**: Use for technical decisions
- Technology stack choices (libraries, frameworks)
- Architecture pattern selections
- Data format decisions (JSON, TOML, YAML)
- Trade-off decisions
### Integration with TDD
SDD and TDD work together seamlessly:
1. **Spec First**: RFC/ADR defines requirements and design
2. **Test From Spec**: Derive test cases from specification
3. **TDD Cycle**: Implement using Red-Green-Refactor
4. **Validate Against Spec**: Ensure implementation matches spec
5. **Update Spec**: Document any deviations or lessons learned
### Benefits
- **Clear Requirements**: RFC/ADR provides concrete specification
- **Testable Design**: Specs include test strategy
- **Documentation**: Code and docs stay synchronized
- **AI Collaboration**: Enables effective work with AI agents (Claude Code, etc.)
- **Traceability**: Link decisions to implementation
### Example Workflow
```typescript
// 1. RFC defines the interface
// docs/specs/rfcs/0001-search-interface.md:
//
// ```typescript
// interface SearchQuery {
// query: string;
// filter?: { category?: string; tags?: string[] };
// }
// interface SearchEngine {
// search(query: SearchQuery): Promise<SearchResult[]>;
// }
// ```
// 2. Write failing test (Red)
describe('SearchEngine', () => {
it('should search and return results', async () => {
const engine = new SearchEngine(mockIndex);
const results = await engine.search({ query: 'test' });
expect(results).toHaveLength(1); // Fails - not implemented
});
});
// 3. Minimal implementation (Green)
class SearchEngine implements SearchEngine {
async search(query: SearchQuery): Promise<SearchResult[]> {
return []; // Test passes (after adjusting assertion)
}
}
// 4. Refactor with actual logic
class SearchEngine implements SearchEngine {
constructor(private index: FTSIndex) {}
async search(query: SearchQuery): Promise<SearchResult[]> {
const results = await this.index.query(query.query);
return this.applyFilters(results, query.filter);
}
private applyFilters(results: RawResult[], filter?: Filter): SearchResult[] {
// Apply filtering logic
return results.filter(r => this.matchesFilter(r, filter));
}
}
```
### When NOT to Write Specs
Keep it simple - not every task needs a spec:
- โ
**Complex feature**: Write RFC
- โ
**Technology choice**: Write ADR
- โ ๏ธ **Simple function**: TDD only, no spec
- โ ๏ธ **Bug fix**: TDD only, no spec
- โ ๏ธ **Minor refactoring**: TDD only, no spec
**KISS Principle**: Only write specs when complexity or decision impact justifies the documentation effort.
### Resources
- [Specifications Guide](./docs/specs/README.md) - How to write RFC/ADR
- [SDD+TDD Workflow](./docs/workflows/SDD_TDD_WORKFLOW.md) - Detailed process
- [RFC Examples](./docs/specs/rfcs/) - Sample feature RFCs
- [ADR Examples](./docs/specs/adrs/) - Sample decision records
---
## Summary
Following these principles results in:
- Maintainable, extendable code
- Fewer bugs and faster debugging
- Better team collaboration
- Professional quality standards
- Clear documentation and decision tracking
**Remember: Good code is simple, clear, and purposeful.**