-
Notifications
You must be signed in to change notification settings - Fork 1
Description
Context
During the design phase, we discussed whether to use domains/ (DDD approach) or src/ (core/technical layering) for the product's business logic.
Key Insight
One monorepo = One product = One bounded context
The repository boundary itself defines the domain boundary. There's no need for an additional domains/ directory when:
- Each monorepo represents a single product
- Future products will have their own repositories (e.g., DeepracticeAccount, DeepracticeCI)
Architecture Philosophy
The Nature of src/
src/ contains product-specific business logic that:
- Is highly specialized for this product
- Is NOT intended for sharing across projects
- Serves only this product's needs
Naming Semantics: domain vs core
When to use domain/ (DDD approach)
- Business-heavy products: Complex business rules, frequent changes
- Modeling approach: Entities, Aggregates, Domain Services, Value Objects
- Thinking mode: Business concepts first (Order, User, Payment)
- Advantage: Express business rules without deep technical details
- Examples: E-commerce, CRM, Financial systems
```typescript
// domain style
class Order extends AggregateRoot {
items: OrderItem[];
addItem(product: Product, quantity: number) {
if (this.items.length >= 100) {
throw new BusinessRuleError('Max 100 items per order');
}
}
}
```
When to use core/ (Technical layering)
- Tech-heavy products: Algorithm-intensive, clear technical logic
- Modeling approach: Modules, Services, Utility functions
- Thinking mode: Technical implementation first (Template Engine, Parser, Executor)
- Advantage: Clear technical details, optimization-friendly
- Examples: CLI tools, Compilers, Frameworks
```typescript
// core style
class TemplateEngine {
parse(template: string): AST { }
compile(ast: AST): Function { }
render(compiled: Function, data: object): string { }
}
```
Decision for NodeSpec
NodeSpec is a technical product, characterized by:
- Template generation = technical logic
- File operations = technical logic
- Command orchestration = technical logic
- Performance-sensitive (CLI startup speed)
Therefore: Use src/ (core approach)
Final Architecture
```
DeepracticeNodeSpec/
├── src/ # Product core (technical layering)
│ ├── template/ # Template engine
│ ├── guide/ # Documentation lookup
│ └── executor/ # Task executor
│
├── packages/ # Ecosystem - Reusable capabilities
│ ├── logger/ # Used internally and externally
│ └── error-handling/
│
├── configs/ # Ecosystem - Reusable standards
│ ├── eslint-config/
│ └── prettier-config/
│
└── apps/ # Product interfaces
└── cli/ # Command-line interface (depends on src/)
```
Product as Ecosystem
The monorepo serves dual purposes:
- Product: NodeSpec itself
- Ecosystem: packages/ and configs/ become independently usable
Evolution path:
- Build the product → Polish the tools
- Good tools → External adoption
- External usage → Tool improvement
This is the "sharpening stone" strategy - building a product naturally creates an ecosystem.
Decision Rationale
✅ Simple and clear: src/ = business logic, obvious meaning
✅ Scalable: packages naturally become ecosystem
✅ Clear responsibilities: Each directory has obvious purpose
✅ Occam's Razor: Simplest solution that works
Next Steps
- Remove
domains/directory - Create
src/directory with appropriate structure - Update architecture documentation
- Begin CLI implementation using this structure
Core principle: Repository boundary = Domain boundary. Use domain/ for business complexity, core/ (src/) for technical products.
🤖 Generated via github-issue-manager agent