feat: add ClassifiedAd domain entity
This commit is contained in:
35
.agent/current-plan.md
Normal file
35
.agent/current-plan.md
Normal 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
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
env/
|
||||
__pycache__/
|
||||
*.pyc
|
||||
.pytest_cache/
|
||||
*.egg-info/
|
||||
33
AGENTS.md
Normal file
33
AGENTS.md
Normal 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
1
domain/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from .marketplace import classified_ad
|
||||
1
domain/marketplace/__init__.py
Normal file
1
domain/marketplace/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from .classified_ad import ClassifiedAd
|
||||
12
domain/marketplace/classified_ad.py
Normal file
12
domain/marketplace/classified_ad.py
Normal 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
11
pyproject.toml
Normal 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 = ["."]
|
||||
61
tests/test_classified_ad.py
Normal file
61
tests/test_classified_ad.py
Normal 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
|
||||
Reference in New Issue
Block a user