From 56fb6be4b133c5ef1dc488f47e50a2fb506179e1 Mon Sep 17 00:00:00 2001 From: pyr0ball Date: Sun, 12 Apr 2026 22:24:13 -0700 Subject: [PATCH] fix(community): use __post_init__ coercion, source_product store arg, add package-data for SQL files --- circuitforge_core/community/models.py | 25 +++++++++++-------------- circuitforge_core/community/store.py | 5 +++-- pyproject.toml | 3 +++ 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/circuitforge_core/community/models.py b/circuitforge_core/community/models.py index 45c2eb7..63b681b 100644 --- a/circuitforge_core/community/models.py +++ b/circuitforge_core/community/models.py @@ -66,25 +66,22 @@ class CommunityPost: protein_pct: float | None moisture_pct: float | None - def __init__(self, **kwargs): - # 1. Coerce list fields to tuples + def __post_init__(self) -> None: + # Coerce list fields to tuples (frozen dataclass: use object.__setattr__) for key in ("slots", "dietary_tags", "allergen_flags", "flavor_molecules"): - if key in kwargs and isinstance(kwargs[key], list): - kwargs[key] = tuple(kwargs[key]) + val = getattr(self, key) + if isinstance(val, list): + object.__setattr__(self, key, tuple(val)) - # 2. Validate BEFORE assignment - post_type = kwargs.get("post_type") - if post_type not in _VALID_POST_TYPES: + # Validate post_type + if self.post_type not in _VALID_POST_TYPES: raise ValueError( - f"post_type must be one of {sorted(_VALID_POST_TYPES)}, got {post_type!r}" + f"post_type must be one of {sorted(_VALID_POST_TYPES)}, got {self.post_type!r}" ) + + # Validate scores for score_name in ( "seasoning_score", "richness_score", "brightness_score", "depth_score", "aroma_score", "structure_score", ): - if score_name in kwargs: - _validate_score(score_name, kwargs[score_name]) - - # 3. Assign all fields - for f in self.__dataclass_fields__: - object.__setattr__(self, f, kwargs[f]) + _validate_score(score_name, getattr(self, score_name)) diff --git a/circuitforge_core/community/store.py b/circuitforge_core/community/store.py index 6b23415..648316c 100644 --- a/circuitforge_core/community/store.py +++ b/circuitforge_core/community/store.py @@ -66,8 +66,9 @@ class SharedStore: All methods return new objects (immutable pattern). Never mutate rows in-place. """ - def __init__(self, db: "CommunityDB") -> None: + def __init__(self, db: "CommunityDB", source_product: str = "kiwi") -> None: self._db = db + self._source_product = source_product # ------------------------------------------------------------------ # Reads @@ -176,7 +177,7 @@ class SharedStore: json.dumps(list(post.allergen_flags)), json.dumps(list(post.flavor_molecules)), post.fat_pct, post.protein_pct, post.moisture_pct, - "kiwi", + self._source_product, ), ) conn.commit() diff --git a/pyproject.toml b/pyproject.toml index 138dee6..94771fb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -84,6 +84,9 @@ cf-manage = "circuitforge_core.manage.cli:app" where = ["."] include = ["circuitforge_core*"] +[tool.setuptools.package-data] +"circuitforge_core.community.migrations" = ["*.sql"] + [tool.pytest.ini_options] testpaths = ["tests"] asyncio_mode = "auto"