business-logic-entry-point-repository-domain-types

Installation
SKILL.md

Repository Domain Types for Business Logic Entry Points

Goal

The types exchanged between business-logic entry points and repositories must be domain-entity types and domain value types.

Repository method signatures — parameters and return types — must use the domain model directly. They must not expose types that depend on or are generated by the concrete persistence technology in use.

This rule keeps the business-logic layer decoupled from persistence-technology details. The entry point works with domain entities and domain values; the repository handles the translation to and from the persistence representation internally.

What Counts as In Scope

Apply this skill to code that does one or more of these things:

  • defines a repository interface or repository method signatures
  • defines repository method parameters or return types
  • passes persistence-technology types between a business-logic entry point and a repository
  • returns ORM entities, database records, row objects, document models, or persistence-generated types from a repository to a business-logic entry point
  • accepts persistence-technology types as input from a business-logic entry point into a repository

The Rule

  1. Repository method signatures must use domain-entity types and domain value types.

    • Parameters must be domain entities, domain value types, or primitive types with domain meaning (e.g., an entity ID).
    • Return types must be domain entities, domain value types, or collections of domain entities.
    • Do not use ORM entity types, database record types, row objects, document model types, schema-generated types, or any type that depends on the persistence technology.
  2. The repository translates between domain types and persistence types internally.

    • The repository implementation converts domain entities to persistence representations before writing.
    • The repository implementation converts persistence representations to domain entities before returning.
    • This translation is an internal concern of the repository and must not leak into its public interface.
  3. Do not share types between the domain model and the persistence layer.

    • Domain-entity types must not carry ORM decorators, database annotations, schema metadata, or persistence-framework markers.
    • Persistence representations must not be used as domain entities.
    • Each layer owns its own types; the repository bridges the two.
  4. Do not introduce intermediate transfer types between entry points and repositories.

    • Do not create DTOs, data-transfer objects, or mapping types that sit between the entry point and the repository.
    • The entry point passes and receives domain types directly; the repository accepts and returns domain types directly.

Detection Workflow

  1. Find repository interfaces and method signatures.

    • Identify repository classes, interfaces, protocols, or modules that business-logic entry points depend on.
  2. Check parameter types.

    • Verify that every parameter is a domain-entity type, domain value type, or a primitive with domain meaning.
    • Flag parameters that use ORM entity types, database record types, persistence model types, or types imported from persistence-technology modules.
  3. Check return types.

    • Verify that every return type is a domain-entity type, a collection of domain entities, or a domain value type.
    • Flag return types that expose ORM entities, database records, document models, or persistence-generated types.
  4. Check for type leakage in entry-point code.

    • Verify that business-logic entry points do not import, reference, or handle persistence-technology types when interacting with repositories.
    • Verify that no mapping between persistence types and domain types occurs in the entry point — that mapping belongs inside the repository.

Writing or Changing Repository Signatures

  1. Start from the domain model.

    • Identify the domain entities and domain value types involved.
    • Express repository operations in terms of those domain types.
  2. Define parameters using domain types.

    • Accept domain entities for save and update operations.
    • Accept domain value types or primitives with domain meaning for query parameters (e.g., entity IDs, email addresses).
  3. Define return types using domain types.

    • Return domain entities for find and get operations.
    • Return collections of domain entities for list operations.
    • Return domain value types when the operation produces a domain result that is not a full entity.
  4. Implement the translation inside the repository.

    • Convert domain entities to persistence representations when writing to storage.
    • Convert persistence representations to domain entities when reading from storage.
    • Keep all persistence-technology imports and type references inside the repository implementation, not in the interface.

Delegation to Execution Context

When the business-logic-entry-point-execution-context skill is active in the project, repository method signatures do not include the transaction parameter. The repository implementation retrieves the transaction from the execution context internally. When the transaction from the execution context is undefined or null, the repository must create a new standalone transaction for that operation. All other rules from this skill still apply: method signatures must use domain-entity types and domain value types exclusively.

Examples

Use this (with execution context):

// Repository interface — domain types only
interface OrderRepository {
  create(order: Order): ResultAsync<Order, RepositoryError>
  findById(orderId: OrderId): ResultAsync<Order, RepositoryError>
  findByCustomerId(customerId: CustomerId): ResultAsync<Order[], RepositoryError>
}

Not this:

// Repository leaking ORM types
interface OrderRepository {
  create(order: OrderEntity): ResultAsync<OrderEntity, RepositoryError>
  findById(orderId: string): ResultAsync<OrderEntity, RepositoryError>
}

Use this (explicit passing, for languages without execution context):

// Repository interface — domain types only
interface OrderRepository {
  save(transaction: Transaction, order: Order): ResultAsync<Order, RepositoryError>
  findById(transaction: Transaction, orderId: OrderId): ResultAsync<Order, RepositoryError>
  findByCustomerId(transaction: Transaction, customerId: CustomerId): ResultAsync<Order[], RepositoryError>
}

Not this:

// Repository leaking ORM types
interface OrderRepository {
  save(transaction: Transaction, order: OrderEntity): ResultAsync<OrderEntity, RepositoryError>
  findById(transaction: Transaction, orderId: string): ResultAsync<OrderEntity, RepositoryError>
}

Use this:

# Repository with domain types
class CustomerRepository(Protocol):
    def find_by_id(self, tx: Transaction, customer_id: CustomerId) -> Customer: ...
    def save(self, tx: Transaction, customer: Customer) -> Customer: ...

Not this:

# Repository leaking SQLAlchemy model
class CustomerRepository(Protocol):
    def find_by_id(self, tx: Transaction, customer_id: str) -> CustomerModel: ...
    def save(self, tx: Transaction, customer: CustomerModel) -> CustomerModel: ...

Use this:

// Repository with domain types
interface SubscriptionRepository {
    fun findById(tx: Transaction, subscriptionId: SubscriptionId): Subscription
    fun save(tx: Transaction, subscription: Subscription): Subscription
}

Not this:

// Repository leaking JPA entity
interface SubscriptionRepository {
    fun findById(tx: Transaction, subscriptionId: Long): SubscriptionEntity
    fun save(tx: Transaction, subscription: SubscriptionEntity): SubscriptionEntity
}

Review Questions

When reading or reviewing code, ask:

  • Do the repository method signatures use domain-entity types and domain value types exclusively?
  • Do any repository parameters or return types depend on the persistence technology?
  • Does the entry point import, reference, or handle persistence-technology types when calling the repository?
  • Does the mapping between domain types and persistence types happen inside the repository, not in the entry point?
  • Are there intermediate DTOs or transfer types between the entry point and the repository that could be eliminated?

If any repository signature exposes persistence-technology types, apply this skill.

Report the Outcome

When finishing the task:

  • state which repository interfaces or signatures were identified or changed
  • state which persistence-technology types were replaced with domain types
  • state which type translations were moved inside the repository implementation
  • state which persistence-technology imports were removed from entry-point or repository-interface files
Related skills

More from code-sherpas/agent-skills

Installs
5
First Seen
Mar 24, 2026