-
Notifications
You must be signed in to change notification settings - Fork 1
Closed
Labels
documentationImprovements or additions to documentationImprovements or additions to documentation
Description
Architecture Decision: src/core and src/domain Separation
Context
NodeSpec needs a clear organization for its business logic in the src/ directory. We need to decide between:
- Pure DDD (Domain-Driven Design) approach
- Pure technical layering approach
- Hybrid approach
Decision
We will use a hybrid architecture with both core/ and domain/ subdirectories under src/:
src/
├── package.json # @deepracticex/nodespec-core
├── index.ts # Unified exports
├── core/ # Technical layer
│ ├── template/ # Template generation engine
│ ├── guide/ # Documentation service
│ └── executor/ # Task execution
└── domain/ # Domain layer (for future DDD modules)
Rationale
Why Not Pure DDD?
NodeSpec is primarily a technical product (CLI tool, template engine, task orchestrator), not a business-heavy system:
- No complex business rules that change frequently
- No need for domain experts (product managers)
- Focus on "how to implement" (algorithms) rather than "what to do" (business rules)
DDD is better suited for:
- Business rule-intensive systems (e-commerce, CRM, finance)
- Frequent business logic changes
- Systems requiring domain expert collaboration
Why Not Pure Technical Layering?
While NodeSpec is currently technical, we want flexibility for future expansion:
- May add user management (authentication, authorization)
- May add licensing/subscription logic
- May add complex workflow orchestration
Why Hybrid?
The hybrid approach provides:
-
Clear Separation of Concerns
core/: Algorithms, engines, technical services (stable)domain/: Business rules, policies (when needed)
-
Flexibility
- Start with
core/only - Add
domain/modules as business complexity grows
- Start with
-
Unified API
// Users don't need to know internal structure import { ProjectGenerator } from '@deepracticex/nodespec-core';
-
Open-Closed Principle
- Open for extension (can add domain modules)
- Closed for modification (doesn't affect existing code)
Implementation
Package Structure
src/package.json:
{
"name": "@deepracticex/nodespec-core",
"exports": {
".": "./index.ts",
"./core/template": "./core/template/index.ts",
"./core/guide": "./core/guide/index.ts",
"./core/executor": "./core/executor/index.ts"
}
}src/index.ts:
// Export from core modules
export * from './core/template/index.js';
export * from './core/guide/index.js';
export * from './core/executor/index.js';
// Export from domain modules (when needed)
// export * from './domain/user/index.js';Usage in Apps
// apps/cli/package.json
{
"dependencies": {
"@deepracticex/nodespec-core": "workspace:*"
}
}
// apps/cli/src/commands/project/init.ts
import { ProjectGenerator } from '@deepracticex/nodespec-core';Examples
Current: Technical Module (core/)
// src/core/template/TemplateEngine.ts
export class TemplateEngine {
render(template: string, data: object): string {
return template.replace(/\{\{(\w+)\}\}/g, (_, key) => data[key]);
}
}
// src/core/template/ProjectGenerator.ts
export class ProjectGenerator {
async generate(targetDir: string, name: string): Promise<void> {
await this.copyTemplate(targetDir);
await this.replaceVariables(targetDir, { name });
await this.initGit(targetDir);
}
}Future: Domain Module (domain/)
If we add user management with complex business rules:
// src/domain/user/User.ts
export class User extends AggregateRoot {
canAccessFeature(feature: Feature): boolean {
// Complex business rules
if (this.subscription.isExpired()) return false;
if (!this.subscription.plan.includes(feature)) return false;
return true;
}
}Decision Criteria
Use core/ when:
- ✅ Technical implementation (algorithms, data processing)
- ✅ Logic is relatively stable
- ✅ Developers make technical decisions
Use domain/ when:
- ✅ Business rules from product/business team
- ✅ Rules change frequently
- ✅ Need to model real-world concepts (entities, value objects)
Related Issues
- Architecture Decision: Use
src/(core) instead ofdomains/for NodeSpec #3 - Architecture Decision: domain vs core - Build NodeSpec CLI with real-world project: DeepracticeAccount #1 - Build NodeSpec CLI with DeepracticeAccount
Status
✅ Decided and being implemented
Metadata
Metadata
Assignees
Labels
documentationImprovements or additions to documentationImprovements or additions to documentation