Skip to content

Architecture Decision: src/core and src/domain separation #4

@deepracticexs

Description

@deepracticexs

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:

  1. Clear Separation of Concerns

    • core/: Algorithms, engines, technical services (stable)
    • domain/: Business rules, policies (when needed)
  2. Flexibility

    • Start with core/ only
    • Add domain/ modules as business complexity grows
  3. Unified API

    // Users don't need to know internal structure
    import { ProjectGenerator } from '@deepracticex/nodespec-core';
  4. 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

Status

✅ Decided and being implemented

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions