feat: add ClassifiedAd domain entity

This commit is contained in:
2026-07-26 07:02:30 -04:00
commit 69ab1233e6
8 changed files with 159 additions and 0 deletions

35
.agent/current-plan.md Normal file
View File

@@ -0,0 +1,35 @@
# Plan: ClassifiedAd Domain Entity
## Status: COMPLETED
## Objective
Create the first Domain Entity representing a ClassifiedAd with the specified attributes.
## Decisions Made
- **Location**: `domain/marketplace/classified_ad.py`
- **Class style**: `@dataclass(frozen=True)` for immutability
- **Validation**: No validation, just hold data
- **Tests**: Yes, create unit tests
## Entity Structure
```python
@dataclass(frozen=True)
class ClassifiedAd:
id: UUID
_ownerId: UUID
title: str
text: str
_price: Decimal
```
## Files Created
- `domain/__init__.py`
- `domain/marketplace/__init__.py`
- `domain/marketplace/classified_ad.py`
- `tests/test_classified_ad.py`
- `pyproject.toml`
## Test Results
- `test_classified_ad_creation` - PASSED
- `test_classified_ad_is_immutable` - PASSED
- `test_classified_ad_equality` - PASSED

5
.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
env/
__pycache__/
*.pyc
.pytest_cache/
*.egg-info/

33
AGENTS.md Normal file
View File

@@ -0,0 +1,33 @@
# AGENTS.md
## Project Context
This is a training project to learn functional programming in Python. Both Python and functional programming are relatively new. The learning approach uses an example project based on "Hands-on Domain Driven Design with .NET Core".
## Collaboration Principles
### Communication Style
- Be honest and objective. Evaluate all suggestions, ideas, and feedback on their technical merits.
- Do not be overly complementary or sycophantic.
- If something does not align with best practices or could be improved, say so directly and constructively.
- Technical accuracy and project quality take precedence over being agreeable.
### Command and Code Style
- Prefer simple commands over complex ones.
- Default to simple, single-purpose commands.
- Avoid one-liners that sacrifice clarity for brevity.
### Workflow
- We build production code together.
- User handles implementation details; AI guides architecture and catches complexity early.
- Challenge assumptions and ideas when it's useful. Be critical, not agreeable.
## Core Workflow: Research → Plan → Implement → Validate
Start every feature with: "Let me research the codebase and create a plan before implementing."
Research - Understand existing patterns and architecture
Plan - Propose approach and verify with you
Implement - Build with tests and error handling
Validate - ALWAYS run formatters, linters, and tests after implementation
Whenever working on a feature or issue, let's always come up with a plan first, then save it to a file called /.agent/current-plan.md, before getting started with code changes. Update this file as the work progresses.
Let's use pure functions where possible to improve readability and testing.

1
domain/__init__.py Normal file
View File

@@ -0,0 +1 @@
from .marketplace import classified_ad

View File

@@ -0,0 +1 @@
from .classified_ad import ClassifiedAd

View File

@@ -0,0 +1,12 @@
from dataclasses import dataclass
from decimal import Decimal
from uuid import UUID
@dataclass(frozen=True)
class ClassifiedAd:
id: UUID
_ownerId: UUID
title: str
text: str
_price: Decimal

11
pyproject.toml Normal file
View File

@@ -0,0 +1,11 @@
[build-system]
requires = ["setuptools"]
build-backend = "setuptools.backends._legacy:_Backend"
[project]
name = "python-fun"
version = "0.1.0"
requires-python = ">=3.12"
[tool.pytest.ini_options]
pythonpath = ["."]

View File

@@ -0,0 +1,61 @@
from decimal import Decimal
from uuid import UUID, uuid4
from domain.marketplace.classified_ad import ClassifiedAd
def test_classified_ad_creation():
ad_id = uuid4()
owner_id = uuid4()
ad = ClassifiedAd(
id=ad_id,
_ownerId=owner_id,
title="Test Title",
text="Test text content",
_price=Decimal("99.99"),
)
assert ad.id == ad_id
assert ad._ownerId == owner_id
assert ad.title == "Test Title"
assert ad.text == "Test text content"
assert ad._price == Decimal("99.99")
def test_classified_ad_is_immutable():
ad = ClassifiedAd(
id=uuid4(),
_ownerId=uuid4(),
title="Title",
text="Text",
_price=Decimal("10.00"),
)
try:
ad.title = "New Title" # type: ignore
assert False, "Should have raised FrozenInstanceError"
except AttributeError:
pass
def test_classified_ad_equality():
ad_id = uuid4()
owner_id = uuid4()
ad1 = ClassifiedAd(
id=ad_id,
_ownerId=owner_id,
title="Title",
text="Text",
_price=Decimal("10.00"),
)
ad2 = ClassifiedAd(
id=ad_id,
_ownerId=owner_id,
title="Title",
text="Text",
_price=Decimal("10.00"),
)
assert ad1 == ad2