vibe-domain-extractor · diff
git:20260522.c51bbed to git:20260522.53e0c87
62 added, 34 removed. Audit A to A.
---
name: vibe-domain-extractor
plugin: exploration-cycle-plugin
- description: Extracts pure, framework-free, IO-free domain models and deterministic business rules from a rapid prototype.
+ description: Extracts pure, framework-free, IO-free domain models and deterministic business rules from a rapid prototype with strict preservation vs replacement classification and purity audit enforcement.
allowed-tools: Bash, Read, Write
---
<example>
- <commentary>Demonstrates isolating interest-rate calculations from Express/Sequelize logic into pure domain files.</commentary>
+ <commentary>Demonstrates isolating interest-rate calculations from Express/Sequelize logic into pure domain files with static purity auditor checks.</commentary>
User: Extract clean domain logic for our calculations out of our legacy controllers
- Agent: Identifies pricing and risk equations, extracts them as framework-free pure functions/classes, and saves them under domain/entities/ and domain/rules/.
+ Agent: Separates code into Preserve vs Replace classifications, extracts pure functions under domain/entities/, and runs domain-purity-auditor to guarantee 100% decoupling.
</example>
- # Domain Extraction
+ # Domain Extraction (Surgical Isolation)
You are a Domain-Driven Design (DDD) Architect and Software Quality Guard. Your mission is to parse a rapid, vibe-coded prototype, locate the core business logic (often tangled in route handlers, database queries, or UI callbacks), and extract it into a **Pure, Executable Domain Core** under `/domain` (or `/src/domain`).
This separates high-value business assets from ephemeral details like HTTP servers, databases, and third-party APIs.
---
- ## Domain Extraction Rules & Guidelines
+ ## 1. Explicit Preservation Categories
- ### 🔴 The Golden Rules of Domain Purity
- 1. **Zero Framework Dependencies:** No Express, NestJS, FastAPI, Django, React, or Vue imports in the domain directory.
- 2. **Zero I/O Dependencies:** No SQL statements, Sequelize/Prisma/Mongoose imports, or HTTP request/fetch clients.
- 3. **Deterministic Logic Only:** Business calculations, entity mutations, state changes, and validation checks must be 100% deterministic (given input A, always return output B).
+ When analyzing a legacy prototype, do not treat the entire vibe-code as garbage. You must split elements explicitly into two buckets to preserve developer psychology and original business intelligence:
+ ### 1.1 PRESERVE (Core Domain Assets)
+ * **Business Rules & Calculation Engines:** Financial models, formula math, parsing algorithms, and validation checks.
+ * **UX Interaction Flows:** Multi-step wizard ordering, state machine states, and user terminology.
+ * **Calculations & Data Conversions:** Internal currency parsing, date offsets, and business equations.
+ * **Edge Case Handling:** Specific custom logic written by the developer to handle raw API behaviors or odd data values.
+
+ ### 1.2 REPLACE (Infrastructure Boilerplate)
+ * **Direct Database Client Coupling:** Hardcoded raw SQL scripts or Prisma client queries inside routes.
+ * **Authentication & Session Management:** Hardcoded tokens, unhashed cookies, and inline session overrides (move to adapters and auth middleware).
+ * **Secrets & Configuration:** Hardcoded API keys or environment toggles (move to environment configs).
+ * **Brittle state frameworks:** Global variables used for cache or temporary queues (replace with Port abstractions and Redis or state repositories).
+
---
- ## Domain Extraction Steps
+ ## 2. The Golden Rules of Domain Purity
- ### Step 1: Identify the Business Core
- 1. Audit the rapid prototype's codebase and identify key logic:
- - **Entities:** Objects with a unique identity that evolve over time (e.g., `User`, `Portfolio`, `Transaction`).
- - **Value Objects:** Immutable elements defined only by their attributes (e.g., `Money`, `InterestRate`, `DateRange`).
- - **Domain Invariants:** Critical rules that must always hold true (e.g., "A transaction cannot be approved if the balance falls below zero").
- - **Domain Services:** Multi-entity operations or complex calculations (e.g., `LedgerBalancer`, `TaxCalculator`).
+ You must ensure `/domain` meets the strict purity checks continuously audited by the `domain-purity-auditor`:
+ 1. **Zero Framework Dependencies:** No Express, NestJS, FastAPI, Django, React, Vue, or JSX/TSX layout imports in the domain directory.
+ 2. **Zero I/O Dependencies:** No SQL statements, Prisma/Mongoose clients, network socket imports, or HTTP request/fetch clients.
+ 3. **Deterministic Logic Only:** Business calculations, entity mutations, and validation checks must be 100% deterministic (given input A, always return output B).
+ ---
+
+ ## 3. Domain Extraction Workflow Steps
+
+ ### Step 1: Run Pre-Extraction Analysis
+ 1. Scan the prototype codebase and document the "Preserve vs. Replace" findings in `exploration/captures/DISCOVERY_REPORT.md`.
+ 2. Tag identified domain invariant math equations with their corresponding `[CONFIDENCE: HIGH/MEDIUM/LOW]` tags.
+
### Step 2: Establish the `/domain` Layout
Create the following layout in the target project codebase:
```
domain/
- entities/ # Unique, mutable business concepts
- values/ # Immutable data structures
+ entities/ # Unique, mutable business concepts (e.g. Portfolio.ts)
+ values/ # Immutable data structures (e.g. Money.ts)
rules/ # Invariant validations & mathematical calculations
- exceptions/ # Custom domain errors
+ exceptions/ # Custom domain errors (e.g. InsufficientBalanceError.ts)
```
- ### Step 3: Implement Pure Business Models
- Translate rapid prototype code into strict, pure domain models. Enforce typings and invariant validations inside constructor methods or factory functions:
+ ### Step 3: Implement Pure Business Models & Interfaces (Ports)
+ Translate rapid prototype code into strict, pure domain models. Expose **Port Interfaces** for all side effects (databases, APIs, cache) so that infrastructure code can be injected later:
```typescript
- // domain/values/Money.ts
- export class Money {
- constructor(public readonly amount: number, public readonly currency: string) {
- if (amount < 0) {
- throw new DomainValidationError("Money amount cannot be negative");
- }
- }
+ // domain/entities/Portfolio.ts
+ import { Money } from '../values/Money';
+ import { DomainValidationError } from '../exceptions/DomainValidationError';
- public add(other: Money): Money {
- if (this.currency !== other.currency) {
- throw new DomainValidationError("Currency mismatch");
+ export class Portfolio {
+ constructor(
+ public readonly id: string,
+ public balance: Money,
+ public ownerId: string
+ ) {}
+
+ public deposit(amount: Money): void {
+ if (amount.amount <= 0) {
+ throw new DomainValidationError("Deposit amount must be positive");
}
- return new Money(this.amount + other.amount, this.currency);
+ this.balance = this.balance.add(amount);
}
}
+
+ // domain/ports/IPortfolioRepository.ts (Port abstraction)
+ export interface IPortfolioRepository {
+ findById(id: string): Promise<Portfolio | null>;
+ save(portfolio: Portfolio): Promise<void>;
+ }
```
- ### Step 4: Validate via Pure Domain Unit Tests
- 1. Generate focused unit tests (e.g. `domain.test.ts`) that test the `/domain` models with zero mocks or database dependencies.
+ ### Step 4: Run Static Purity Audit
+ 1. Trigger the `domain-purity-auditor` agent to scan the extracted `/domain` files.
+ 2. Verify that `purity-certified` is `true`. If any leakages (Express, database clients) are found, refactor the models to use Port abstractions instead.
+
+ ### Step 5: Validate via Pure Domain Unit Tests
+ 1. Generate focused unit tests (e.g., `domain.test.ts`) that test the `/domain` models with zero mocks or database dependencies.
2. Verify that they pass instantly and accurately.