4 Commits

Author SHA1 Message Date
rayhpeng
597a11372e fix(feedback): remove order-dependent import and stale layout pointers
model.py imported its exceptions from the package __init__, which itself
imports model -- a cycle that only resolved because __init__ happens to
import exceptions first. Import them from the exceptions submodule
directly, matching service.py, so reordering __init__ can never break
collection.

Also update the two module docstrings that still pointed readers at the
deleted app/infra/ layout and the old deps.py wiring: adapters live in
app/adapters/{context}/ and wiring happens in the composition root,
app/composition.py::build_domain_services.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-30 11:12:31 +08:00
rayhpeng
793169529c refactor(feedback): align the slice with the hexagonal spec
- command-ify the write use cases (RateRun / RetractRunRating; queries
  keep plain parameters, commands stay dumb data)
- split the domain errors into exceptions.py, a peer of model.py
  (PEP 8 Error suffixes, AWS-style module name)
- unify the aggregate->row mapping as _apply(row, feedback) so one
  explicit field list serves both the insert and the update path
- drop the unused feedback.message_id column (migration 0011): feedback
  is bound to a run, nothing ever wrote or read the field
- pin remove_for_run's equality semantics for user_id=None in the
  contract suite and fix the port docstring that contradicted both
  implementations
2026-07-29 18:28:54 +08:00
rayhpeng
02117a4d77 style(feedback): give domain errors docstrings instead of ... bodies
The single-line `class X: ...` exception stubs tripped
github-code-quality's "Statement has no effect" rule: a bare `...` is a
discarded expression statement. Replace each with a one-line docstring,
matching the empty-error convention used elsewhere (GoalWriteConflict,
ConflictError) and silencing the false positive. No behavior change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 15:54:08 +08:00
rayhpeng
44cb9fd375 feat(harness): add feedback domain slice (model, ports, service)
Hexagonal inner ring for the feedback bounded context: frozen aggregate
with construct-time invariants (rating, reason-tag slugs), technology-
neutral ports (typing.Protocol), and the application service with
explicit user_id. Guarded by an AST purity test that keeps domain/ free
of infrastructure imports.
2026-07-23 15:30:33 +08:00