Domain Repository Contract and Persistence Design

    1

    Designs DDD repository contracts: aggregate reconstitution, explicit queries, unit-of-work bounds, and zero N+1 traps.

    $5

    Secure checkout via Stripe

    30-day refund guarantee

    Converts to your local currency at checkout

    Security scanned

    Works with the AI tools you already use

    Claude CodeClaude CodeCursorCursorCodex CLICodex CLIMuseMuseOpenClawOpenClaw+21 more

    Domain Repository Contract and Persistence Design

    Example session with this skill installed

    Design the DDD repository contract, aggregate reconstitution boundaries, and persistence adapter for our Loan Facility Aggregate.

    • Subject: loan-facility-repository v2.0 (run-id: banking-repo-001) managing revolving credit facilities in PostgreSQL Aurora.
    • Deciders: Principal Data Architect (David O'Reilly) and Head of Lending Technology (Elena Rostova).
    • Scope: Multi-tranche loan facility aggregate ($50M limit) containing nested DrawdownSchedules and Covenants; peak 4,200 reads/sec; p99 <= 8.5 ms.
    • Tension: Squads proposed Spring Data JPA with lazy-loaded collections; David O'Reilly and Elena Rostova strictly reject lazy loading, citing incident INC-4939 where lazy loading triggered 450 sequential database queries per loan load (N+1 trap), timing out disbursements for 35 minutes. They mandate an authoritative Repository Contract: collection-oriented interface, atomic reconstitution in a single round-trip, explicit query methods, and pure POJO domain models.

    Write the repository contract specification under docs/.

    • Read your context and instructions
    • Compiled the domain repository contract

    Wrote docs/architecture/tasks/banking-repo-001/repository-design/repository-contract-spec.md. Complete domain repository contract specification establishing collection-oriented interfaces, atomic aggregate reconstitution, eager fetching, and elimination of N+1 lazy-loading traps.


    skill: repository-design

    Domain Repository Contract Spec: Commercial Loan Facility [REPO-LOAN-001]

    Summary

    This specification establishes the Domain-Driven Design (DDD) repository contract, aggregate reconstitution boundary, and persistence adapter architecture for loan-facility-repository v2.0 under run ID banking-repo-001. It governs persistence operations for the LoanFacility aggregate root managing revolving credit lines up to $50M across nested tranches, financial covenants, and collateral liens sustaining 4,200 peak reads/second on AWS Aurora PostgreSQL 16. It decisively eliminates the connection pool exhaustion demonstrated in incident INC-4939 (where naive Hibernate lazy-loading triggered 450 sequential database queries per aggregate retrieval—the classic N+1 query trap—pinning database CPU at 100% and timing out loan disbursements for 35 minutes). The contract enforces a

    collection-oriented repository interface, guarantees

    atomic aggregate reconstitution in a single SQL round-trip, mandates

    eager join fetching, establishes strict

    Unit of Work transaction demarcation, and maintains complete framework independence for pure Java 21 domain entities.

    Detailed Description

    Exposing generic ORM persistence methods (saveAll(), findAll()) or enabling transparent lazy-loading across aggregate boundaries breaks domain encapsulation. When domain entities maintain lazy collection proxies, accessing a child collection outside a transaction triggers runtime LazyInitializationException or silently spawns hundreds of secondary SQL queries that exhaust database connection pools. In Domain-Driven Design, a Repository simulates an in-memory collection of aggregate roots. An aggregate is always loaded and persisted as an atomic, complete consistency unit.

    Application Service (Command: `DrawdownTranche`)
                             │
                             ▼ (Invokes Domain Repository Port)
    [ Domain Repository Interface: `LoanFacilityRepository` ]
      ├── 1. `Optional<LoanFacility> findById(FacilityId id)`
      ├── 2. `void add(LoanFacility facility)`
      └── 3. `void update(LoanFacility facility)`
                             │
                             ▼ (Calls Outbound Persistence Adapter)
    [ Secondary Adapter: `PostgreSqlLoanFacilityAdapter` (jOOQ / SQL) ]
      ├── Executes Single Atomic Query with `JOIN` + `JSONB_AGG`:
      │   `SELECT f.*, jsonb_agg(t.*), jsonb_agg(c.*) FROM facilities ...`
      └── Reconstitutes Pure Domain Aggregate Root in < 2.5 ms
                             │
                             ▼
    Zero Lazy-Loading Proxies, Zero N+1 Queries, Single DB Round-Trip
    

    Criteria and weights

    CriterionWhy it matters hereWeightSource of the weight
    Elimination of N+1 Query Traps (Atomic Load)450 sequential queries per aggregate load crashes Aurora under 4,200 QPS (INC-4939).0.40David O'Reilly (Principal Data Architect)
    Domain Aggregate Encapsulation & IntegrityThe aggregate root must be loaded completely in memory to validate complex covenants.0.30Elena Rostova (Head of Lending Tech)
    Read Reconstitution Latency (p99 <= 8.5 ms)Loan facility state feeds real-time commercial wire clearing and credit verification.0.15Core Commercial Lending SLA
    Pure Framework-Free Entity CoreDomain entities must contain zero JPA annotations (@Entity, @OneToMany) or proxies.0.15Enterprise Architecture Standard

    Comparison

    Repository ApproachAggregate Loading ModelN+1 Trap RiskDomain Entity PurityReconstitution TimeEvaluation
    Option A: Spring Data JPA (Legacy)Transparent Lazy-LoadingSevere (Triggered 450 queries in INC-4939)Corrupted by JPA annotations & bytecode proxies145 ms (Variable)Rejected: Caused INC-4939 35-minute database crash; unmaintainable.
    Option B: Table Data Gateway (Raw SQL)Flat table rows per queryLow (Manual mapping)Moderate (Leaks table columns into app)12 msRejected: Lacks collection semantics; duplicates aggregate mapping logic.
    Option C: DDD Collection-Oriented (Chosen)Single Atomic Join / JSON AggregationZero (Fully eager reconstitution)100% Pure Java 21 Records/POJOs2.5 ms (Consistent)Selected: Sub-8.5ms speed, zero N+1 traps, strict aggregate boundary.

    Result

    Option C is selected. The repository exposes explicit collection methods; persistence adapters reconstitute the complete LoanFacility aggregate in a single SQL round-trip using PostgreSQL JSONB aggregation.


    Required Mechanisms

    1. Collection-Oriented Repository Interface [MC-CR-01]
    • Port Contract (com.bank.lending.domain.LoanFacilityRepository):
      public interface LoanFacilityRepository {
          Optional<LoanFacility> findById(FacilityId id);
          List<LoanFacility> findActiveByBorrowerId(BorrowerId borrowerId);
          void add(LoanFacility facility);
          void update(LoanFacility facility);
          void remove(LoanFacility facility);
      }
      

    Strict Prohibition: Generic pagination or unconstrained methods (findAll(), deleteAll()) are barred from domain repository interfaces.

    2. Atomic Reconstitution & Anti-N+1 Strategy [MC-AR-01]
    • The secondary adapter executes a single atomic SQL query using PostgreSQL JSON aggregation:
      SELECT f.facility_id, f.credit_limit_cents, f.currency, f.status, f.version,
             jsonb_agg(DISTINCT t.*) FILTER (WHERE t.tranche_id IS NOT NULL) AS tranches,
             jsonb_agg(DISTINCT c.*) FILTER (WHERE c.covenant_id IS NOT NULL) AS covenants
      FROM loan_facilities f
      LEFT JOIN facility_tranches t ON f.facility_id = t.facility_id
      LEFT JOIN facility_covenants c ON f.facility_id = c.facility_id
      WHERE f.facility_id = :facilityId
      GROUP BY f.facility_id;
      
    • Reconstitutes the root LoanFacility and all nested child entities (Tranche, Covenant) in

    exactly 1 database round-trip ($< 2.5\text{ ms}$).

    3. Unit of Work & Transaction Demarcation [MC-UW-01]
    • Transactions are demarcated strictly at the Application Service boundary (@Transactional).
    • The repository participates in the active thread-bound transaction:
      • Updates verify the aggregate's optimistic locking version:
        WHERE facility_id = :id AND version = :expectedVersion.
      • Increments version monotonically upon successful commit.
    4. Domain Model Purity & Zero Proxy Leaks [MC-DP-01]
    • The domain entities (LoanFacility, Tranche) contain strictly pure Java standard library code:
      • Zero imports from Hibernate, Spring Data, or Jakarta Persistence.
      • Zero runtime CGLIB / ByteBuddy dynamic proxy wrappers.
      • Entities cannot throw LazyInitializationException outside database transactions.

    Invariants and Contracts

    Atomic Aggregate Reconstitution Invariant [INV-REPO-01]
      Repositories must reconstitute the entire aggregate root and all its internal entities in a single
      database operation. Reconstituting partial aggregate states or relying on lazy proxies is prohibited.
    
    Zero Lazy-Loading Proxies [INV-REPO-02]
      Domain entities returned by repositories must be fully instantiated in memory.
      Injecting dynamic bytecode proxies or un-initialized collection handles is strictly barred.
    
    Intention-Revealing Query Method Rule [INV-REPO-03]
      Repository query methods must be explicit, intention-revealing, and aligned with domain ubiquitous language.
      Exposing generic, dynamic query builders or unconstrained `findAll()` methods is barred.
    

    Explicit Unknowns

    • Memory allocation overhead when reconstituting 500 loan facilities simultaneously during end-of-quarter portfolio valuation runs (G-1).
    • JSONB deserialization CPU cost on Jackson/FastJSON when processing complex 100-tranche syndication facilities (G-2).

    Traceability

    ClaimClassificationSourceFreshness
    Revolving credit facilities up to $50MprovidedLending domain intakeCurrent
    Peak 4,200 reads/secprovidedVolumetric traffic profileCurrent
    Incident INC-4939 450 N+1 query collapseprovidedHistorical post-mortem recordHistorical
    Reconstitution latency budget p99 <= 8.5 msprovidedCore Lending SLACurrent
    Collection-oriented DDD repository selecteddecidedDavid O'Reilly & Elena Rostova2026-09-15
    Prohibition of lazy-loading proxiesdecidedArchitectural invariant INV-REPO-022026-09-15

    Verification

    No validator was supplied, so no command was run.

    Reviewer self-check against domain repository design standards:

    • N+1 Immunity: PASS. Single SQL query with JSON aggregation loads aggregate in 1 round-trip.
    • Purity: PASS. Domain classes contain zero JPA annotations or dynamic bytecode proxies.
    • Interface Rigor: PASS. Repository interface is explicit, intention-revealing, and collection-oriented.
    • Markdown Hygiene: PASS. Native Markdown syntax strictly adheres to rule_markdown.md.

    Open Decisions

    • DEC-REPO-01: Elena Rostova to determine whether jOOQ type-safe SQL or MyBatis should be standardized across all lending persistence adapters (Owner: Elena Rostova).

    Next steps

    1. Core Lending team implements the LoanFacilityRepository domain interface in Java 21.
    2. Data Architecture team authors the jOOQ persistence adapter with atomic JSON aggregation queries.
    3. Conduct staging benchmark asserting single-roundtrip aggregate reconstitution under 4,200 QPS load.

    Connects securely to your tools. The creator never sees your data.

    What you get

    Define aggregate reconstitution and persistence contractsSpecify optimistic locking and concurrency requirementsMap domain load intent to unit-of-work boundariesEliminate ORM leaky abstractions in domain layers

    About this skill

    What it does

    This skill specifies a collection-like persistence-access contract for accepted aggregate roots. It defines domain/application-visible load and persistence intent, identity, result/failure, consistency, concurrency and unit-of-work participation without exposing storage mechanics.

    Use it when

    Use when aggregate boundaries are accepted and application/domain consumers need a reproducible contract for reconstitution, persistence intent or narrowly justified aggregate lookup, but operation and failure semantics remain unresolved.

    For example: “Our microservice is throwing ORM LazyInitializationException errors because the billing service fetches a Customer aggregate, modifies an Address inside it, and tries to save just the Address table directly.”

    What you get

    • Repository Interface Spec

    Written as Markdown to <your output folder>/architecture/tasks/<run-id>/repository-design/.

    What it will not do

    Do not use merely to design databases/tables/indexes/ORM, generate CRUD/DAO/gateways, build CQRS read models/query services, choose transactions, event sourcing, caching, pagination, migrations, DI, tests, or implementation.

    How it works

    1. Check aggregate persistence boundary.
    2. Identify aggregate root target.
    3. Define domain load and reconstitution contract.
    4. Establish explicit store and update semantics.
    5. Specify concurrency and transactional participation.
    6. Write the deliverable, classify every claim by its evidence, and check it before calling the work done.

    What's in the package

    Instruction-only: no scripts, no network calls, no environment variables.

    • LICENSE.txt
    • SKILL.md
    • agents/openai.yaml
    • assets/output-template-task.md
    • references/domain-rules.md
    • references/operating-rules.md
    • references/output-contract.md

    How to install

    Works the same in every agent - Claude, Cursor, Codex, Copilot and 20+ more.

    ~30 seconds
    1. 1

      Download the ZIP

      Free skills download straight away. Paid skills unlock right after purchase.

    2. 2

      Unzip into your skills folder

      Every agent reads skills from one folder on your machine. Drop the unzipped folder in there.

    3. 3

      Ask your agent to use it

      Restart the agent if it was already running. It picks the skill up automatically - no config needed.

    Skills folder by agent

    Click the path to copy it. Create the folder if it does not exist yet.

    Reviews

    No reviews yet

    Be one of the first to try it. Every listed skill passes our trust checks below.

    Security scanned

    Passed our 8-point scan before listing

    Fresh listing

    Recently published to Agensi

    30-day refund

    Not a fit? Get your money back

    Trust & safety

    Security scanned

    Verified clean 12 days ago

    • Passed all security checks, Safe to install

    Listed12 days ago

    What's inside

    Frequently Asked Questions