feat: add generic Value[T] base class for value objects
- Create Value[T] (frozen dataclass + ABC + Generic) in domain/framework/ - Migrate ClassifiedAdTitle and ClassifiedAdText to inherit Value[str] - Standardize all value access via .value instead of type-specific fields
This commit is contained in:
@@ -1,18 +1,45 @@
|
||||
# Plan: Add FastAPI to the Project
|
||||
# Plan: Value Object Base Class
|
||||
|
||||
## Goal
|
||||
Add FastAPI as the web framework with a minimal health check endpoint.
|
||||
Create a generic `Value[T]` base class in the framework layer. All value objects standardize on `.value` access via inheritance.
|
||||
|
||||
## Changes
|
||||
## Design
|
||||
|
||||
### 1. Dependencies
|
||||
- Add `fastapi` and `uvicorn[standard]` to `pyproject.toml` under `[project.dependencies]`
|
||||
- Install dependencies into the virtual environment
|
||||
### `Value[T]` base class (`domain/framework/value.py`)
|
||||
```python
|
||||
@dataclass(frozen=True)
|
||||
class Value(ABC, Generic[T]):
|
||||
value: T
|
||||
```
|
||||
|
||||
### 2. Application Entry Point
|
||||
- Create `main.py` with a FastAPI app instance
|
||||
- Add a health check endpoint (`GET /`) that returns `{"status": "ok"}`
|
||||
- Frozen dataclass → immutability + structural equality (core Value Object semantics)
|
||||
- `Generic[T]` → type-safe `.value` access in subclasses (e.g., `Value[str]`)
|
||||
- `ABC` → mirrors the `Entity` pattern
|
||||
|
||||
### Subclasses
|
||||
- `ClassifiedAdTitle(Value[str])` — drops `title: str`, inherits `value: T` bound to `str`
|
||||
- `ClassifiedAdText(Value[str])` — drops `text: str`, inherits `value: T` bound to `str`
|
||||
|
||||
### Ripple effects
|
||||
Every `.title` / `.text` reference on these objects becomes `.value`:
|
||||
- `classified_ad.py` — `self.title.title` → `self.title.value`, construction calls, method bodies
|
||||
- Tests — assertions, constructions, equality checks
|
||||
|
||||
## Files changed
|
||||
| File | Change |
|
||||
|------|--------|
|
||||
| `domain/framework/value.py` | New — `Value[T]` base class |
|
||||
| `domain/framework/__init__.py` | Add `Value` re-export |
|
||||
| `domain/marketplace/classified_ad_title.py` | Inherit `Value[str]`, rename field |
|
||||
| `domain/marketplace/classified_ad_text.py` | Inherit `Value[str]`, rename field |
|
||||
| `domain/marketplace/classified_ad.py` | Update `.title`/`.text` refs → `.value` |
|
||||
| `tests/test_classified_ad_title.py` | Update refs |
|
||||
| `tests/test_classified_ad_text.py` | Update refs |
|
||||
| `tests/test_classified_ad.py` | Update refs |
|
||||
|
||||
## Not in scope
|
||||
`ClassifiedAdId`, `UserId`, `Money`, `Price` — stay as-is.
|
||||
|
||||
## Verification
|
||||
- `pytest tests/` — all tests pass
|
||||
- `uvicorn main:app --reload` — server starts and health endpoint responds
|
||||
- `pytest tests/` — all 63 tests pass
|
||||
- `ruff check .` && `ruff format --check .` — clean
|
||||
|
||||
Reference in New Issue
Block a user