database-repository-patternlisted
Install: claude install-skill dbtinoy-/lexigram-framework-skills
# Database Repository Pattern
## Overview
Async SQL with protocol-based repositories. Domain models are plain dataclasses (not ORM entities). Infrastructure-layer implementations handle ORM mapping — domain code never sees it.
## Repository Pattern
```python
# Domain layer — pure protocol (in contracts)
class UserRepositoryProtocol(Protocol):
async def find(self, user_id: str) -> Result[User, NotFoundError]: ...
async def save(self, user: User) -> Result[User, DomainError]: ...
async def delete(self, user_id: str) -> Result[None, DomainError]: ...
# Infrastructure layer — concrete implementation
class SqlUserRepository:
def __init__(self, db: DatabaseProviderProtocol):
self.db = db
async def find(self, user_id: str) -> Result[User, NotFoundError]:
async with self.db.scoped_context() as conn:
row = await conn.fetch_row("SELECT * FROM users WHERE id = $1", user_id)
if not row:
return Err(UserNotFoundError(user_id))
return Ok(User(id=row["id"], name=row["name"], email=row["email"]))
# DI binding
container.singleton(UserRepositoryProtocol, SqlUserRepository)
```
## Domain Models
```python
from lexigram.domain import DomainModel
@dataclass(frozen=True)
class User(DomainModel):
id: str
name: str
email: str
```
`DomainModel` is a mixin providing serialization helpers; it applies `@dataclass(init=False)` automatically when a subclass lacks one (frozen only if you declare it)