refactor(statistics): resolve review follow-ups across statistics domain #132
No reviewers
Labels
No labels
blocked
bug
enhancement
high-priority
low-priority
needs-info
needs-triage
ready-for-agent
ready-for-human
referenced
research
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gabogg/hikcentral!132
Loading…
Reference in a new issue
No description provided.
Delete branch "refactor/statistics-follow-ups"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem Statement
Multiple P3 review follow-ups across the statistics and occupancy domains accumulated from recent PRs (#89, #90, #92, #110, #116, #122, #126). These tasks addressed overlapping concerns around facility schedule abstractions, usual-weekday baseline rules, database seeding constants, controller error handling DRYing, period quality CTE optimizations, and comparison coverage boundaries.
Resolving these items individually would lead to repetitive merge conflicts across the shared statistics and occupancy service layers.
Architectural Approach
Schedule Abstraction Decoupling (
app/facility_time.py):ScheduleCalendar,ScheduleException,WeekdaySchedule,is_open_by_schedule,opening_hours_by_schedule, andconfigured_holiday_hoursout ofoccupancy_service.pyintoapp/facility_time.py.ScheduleCalendarto a frozen dataclass withexceptionskeyed bydatetime.dateholding typedScheduleExceptioninstances.active_business_day(epoch, reset_time)helper function.Repository & Schema Typing (
app/db/occupancy_repository.py,app/schemas/):CountedDayFlow(NamedTuple)andCountedCycleQualityRecord(TypedDict).database.pywithDEFAULT_HOLIDAY_HOURSandDEFAULT_WEEKDAY_HOURSschema constants.superseded_byandis_currentcolumns inrecord_calibration_log_async.get_counted_cycle_quality_range_asyncusingmin(dates)andmax(dates).update_config_fields_async.BaselineFailureReason = Literal["INSUFFICIENT_USUAL_WEEKDAYS", "BUCKET_COUNT_MISMATCH", "UNSUPPORTED_BUCKET_SIZE"].Controller & Service Refinement (
app/services/analytics_service.py,app/controllers/statistics_controller.py):_GRANULARITY_STRATEGIES.handle_controller_errors()context manager instatistics_controller.pyto unifyValueError -> 422andLookupError -> 404handling.previous_qualityinget_statistics_summary_asyncto eliminate redundant database reads.PeriodVisitors.per_day()andcompare_visitorsagainst zero covered business days and division-by-zero.previous_row,previous_comparison).Scope & Addressed Issues
CountedCycleQualityRecord, config field validation tests, and descending cycle range tests.PeriodVisitorsand comparisons, and clamped comparison coverage test.ScheduleCalendarand schedule evaluation tofacility_time, keyed exceptions by date, converted to frozen dataclass, and cleaned up test fixtures.handle_controller_errorscontext manager instatistics_controller, reusedprevious_qualityin summary calculation, typedBaselineFailureReason, and typed comparison reasons.active_business_dayhelper, simplified usual-weekday candidate selection, preserved calibration log columns, and fixed endpoint parameters._GRANULARITY_STRATEGIESstrategy map, definedCountedDayFlowNamedTuple, and added tests for period pickergap_estimated_daysand daily seriesis_holiday.Closes #128, #124, #120, #111, #99, #97, #96.
Verification Evidence
ruff check .andruff format --check ..pytest.WIP: refactor(statistics): resolve review follow-ups across statistics domainto refactor(statistics): resolve review follow-ups across statistics domainStandards
Hard Violations (Documented Standards)
Missing Return Type Annotation —
statistics_controller.py:22docs/standards/code-standards.md§2.2 &AGENTS.md§2 (Type Annotations): "All function definitions (parameters and return types) must include explicit type hints."def handle_controller_errors():lacks an explicit return type hint (e.g.-> Iterator[None]).Non-Standard HTTP Status Literals —
statistics_controller.py:27-32docs/standards/code-standards.md§3.1 (HTTP Exception Uniformity): requiresfastapi.statusconstants (status.HTTP_...).status_code=422andstatus_code=404directly instead ofstatus.HTTP_422_UNPROCESSABLE_ENTITYandstatus.HTTP_404_NOT_FOUND(statuswas removed from imports).Untyped Dictionaries Across Layers —
facility_time.py:309-354docs/standards/code-standards.md§2.3 (Pydantic Schemas): "Avoid passing untyped, raw dictionaries between service layers when structured schemas are available."is_open_by_schedule,opening_hours_by_schedule, andconfigured_holiday_hoursacceptdict[str, Any]alongside domain dataclasses to accommodate unmapped DB rows fromoccupancy_service.py.Domain Types Defined in Persistence Layer —
occupancy_repository.py:186-204AGENTS.md§2 &docs/standards/code-standards.md§2.3: "Define domain request/response contracts in app/schemas/."CountedDayFlow(NamedTuple) andCountedCycleQualityRecord(TypedDict) are defined in the repository file rather thanapp/schemas/occupancy_models.py.Judgement Calls (Baseline Smells)
Primitive Obsession —
facility_time.py:309-322Smell: Type-branching on
isinstancevs.get()to handle raw dictionaries. Upstream callers should instantiateScheduleException/WeekdaySchedulebefore passing.Divergent Change —
facility_time.py:291-379Smell:
facility_time.py(authoritative for civil time and cycle boundary math) now hosts facility schedule entities and open/closed evaluation logic.Middle Man —
analytics_service.py:584-587Smell: 4 top-level functions delegate entirely to
_GRANULARITY_STRATEGIES. Acceptable trade-off: eliminates the prior Repeated Switches smell while preserving the module's public API.Spec
Missing or Partial Requirements
Scope Creep (Unasked Behaviour)
In
occupancy_repository.py,_CALIBRATION_LOG_INSERT_SQLand_prepare_calibration_log_paramswere modified to insertsuperseded_byandis_current. No spec requested schema/insert extensions on this repository method.test_update_config_fields_rejects_unknown_keys:Added to
test_occupancy_config_api.pywithout being specified in #124.Incorrectly Implemented Requirements
compare_visitors:Summary: Standards: 7 findings (worst: untyped dictionaries and missing return type annotation breaking documented type safety standards). Spec: 10 findings (worst: #128 single ranked verdict decision missing from cycle quality queries and #120 incorrect
PARTIAL_PERIODfallback on zero covered days).