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!227
Loading…
Reference in a new issue
No description provided.
Delete branch "chore/statistics-p3-followups-219-220"
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?
Resolves deferred P3 findings from the third review passes on PR #167 and PR #168.
Closes #219
Closes #220 (Note: Closing #220 auto-closes the issue; item 3 was migrated and already resolved in #209).
Summary
Issue #167 follow-ups (#219):
_trusted_cycle_multiplierto_plausible_trusted_multiplierinapp/services/analytics_service.pyto prevent confusion with_trusted_cycle_multiplier_async._plausible_trusted_multiplier,_is_trusted_log, and_trusted_multiplierto takeCalibrationLogRecordrather thanMapping[str, Any].CalibrationLogRecordinto a base table rowTypedDictand extended it withBatchCalibrationLogRecordcontainingmatched_cycle_date: strandrank_in_cycle: int.app/db/occupancy_repository.pyinto a shared_window_values_params(windows)helper across all four batch methods.tests/test_statistics_periods.pyinto module-level_assert_indexed_plan(sql, params).tests/test_statistics_baselines.pytotest_hourly_baseline_positional_averaging_for_duplicated_clock_labelsand updateddocs/audit/statistics-baseline-followups-pr-plan.md.Issue #168 follow-ups (#220):
occupancy.zoneLabelfromapp/static/js/i18n.js(EN and ES).occupancy.noCameraGroupto use "No camera group" instead of "General".zone_namewrites are handled in #209 (already merged) to avoid merge conflicts.tests/frontend/test_admin_cameras.test.js) and command deck (tests/frontend/test_command_deck_adapter.test.js) in EN and ES, and cleaned up globals intest_admin_cameras.app/db/occupancy_repository.pyto module constant_SELECT_CAMERAS_WITH_GROUP_SQL.tests/test_occupancy.pywithoccupancy_repo.register_camera_groups_async.docs/api/README.mdto use glossary term "Camera Group" instead of "counting camera group".is_excludedandresource_group_codeindocs/api/README.md.CONTEXT.mdBusiest Day definition to use the brief's exact text with Closed Day and multi-day scope clauses restored.best_dayvariable in summary service and references in documentation tobusiest_day._TandOmittedIfNoneAnnotated alias inapp/schemas/statistics.pyforexclude_if=lambda v: v is Noneand documented wire omission rule indocs/api/README.md(noting deliberate OpenAPI nullability).Architectural Impact
CalibrationLogRecordmatching table schema without false casts, while batch methods returnBatchCalibrationLogRecord.Verification / Test Evidence
rtk ruff check .: clean (0 issues).rtk ruff format --check .: clean (154 files formatted).python3 scripts/check_docs.py: clean (43 Markdown files and 90 HTTP operations verified).node --test tests/frontend/*.test.js: 250 passed, 0 failed.rtk pytest: 602 passed, 0 failed.Checklist
_trusted_cycle_multiplier->_plausible_trusted_multiplierCalibrationLogRecordCalibrationLogRecordtable columns base andBatchCalibrationLogRecordfor batch reads_window_values_paramshelper in repository batch methods_assert_indexed_planhelper in query plan testszoneLabeli18n key_SELECT_CAMERAS_WITH_GROUP_SQLconstantregister_camera_groups_asyncin testis_excludedandresource_group_codecamera response fieldsCONTEXT.mdBusiest Day definition uses exact brief text with restored clausesbest_daytobusiest_dayOmittedIfNoneAnnotated alias in statistics schemas and documented wire omission (OpenAPI nullability deliberate)WIP: chore(statistics): third-pass P3 follow-ups from PRs #167 and #168to chore(statistics): third-pass P3 follow-ups from PRs #167 and #168Please perform code review pass 1 of master...bd835b7 against issues #219 and #220.
Scope:
_trusted_cycle_multiplier->_plausible_trusted_multiplierinapp/services/analytics_service.py._plausible_trusted_multiplier,_is_trusted_log,_trusted_multiplier) to takeCalibrationLogRecordrather thanMapping[str, Any].CalibrationLogRecordinapp/schemas/occupancy_models.pywithrank_in_cycle: intand nullableis_trusted: int | None._cycle_values_params(cycles)inapp/db/occupancy_repository.pyfor cycle parameter flattening across all four batch queries._assert_indexed_plan(sql, params)intests/test_statistics_periods.py.tests/test_statistics_baselines.pytotest_hourly_baseline_positional_averaging_for_duplicated_clock_labelsand update citation indocs/audit/statistics-baseline-followups-pr-plan.md.occupancy.zoneLabelfromapp/static/js/i18n.js(EN/ES).occupancy.noCameraGroupto use "No camera group" inapp/static/js/src/ui/command_deck_adapter.js._SELECT_CAMERAS_WITH_GROUP_SQLconstant inapp/db/occupancy_repository.py.register_camera_groups_asyncintests/test_occupancy.pyinstead of raw SQL insert.docs/api/README.md.is_excludedandresource_group_codecamera response fields indocs/api/README.md.CONTEXT.md.best_daytobusiest_dayin summary service anddocs/architecture/rfc-statistics-deck-display-model.md.OmittedIfNoneAnnotated alias inapp/schemas/statistics.pyand document indocs/api/README.md.Validation passed:
rtk ruff check .: clean (0 issues)rtk ruff format --check .: clean (150 files formatted)python3 scripts/check_docs.py: clean (42 Markdown files, 80 HTTP operations)node --test tests/frontend/*.test.js: 244 passed, 0 failedrtk pytest: 534 passed, 0 failedRecord the completed review as a formal review using
scripts/wt review post 227, headed:Code review, pass 1 (master...bd835b7, spec #219, #220)
This addresses findings from prior reviews (#167 and #168), so the repository's three-pass follow-up review policy applies before merge.
Code review, pass 1 (
origin/master...bd835b7, spec #219 + #220)Result: 1 P2 (raised on both axes) and 15 P3s. Not mergeable yet. This is pass 1, so fix every finding, merge
origin/master(now9a72ff4) and request a second pass.zone_name, so it doesn't clash with #234.9a72ff4(it merges cleanly):Spec
Per-item status
_cycle_values_paramscall sites.P2
CalibrationLogRecordis a false type on the single-row path (occupancy_repository.py~2564/2576 on the merge result; raised on both axes).get_calibration_log_for_cycle_asyncnow returnscast(CalibrationLogRecord, dict(row))from aSELECT *that has neithermatched_cycle_datenorrank_in_cycle, yet the TypedDict marks both as required (occupancy_models.py:82-83). The type checker would acceptlog["rank_in_cycle"]and the code would raiseKeyErrorat runtime. That undercuts #219 item 3 ("the record matches every column the query returns").NotRequiredon those keys also works.P3
#220 item 11 README wording. It points readers at "fields marked
OmittedIfNone", which is a Python-internal name. Describe the rule in wire terms, or list the fields. Also note in the PR that OpenAPI still marks those fields nullable, and that this is deliberate.The
Busiest Daytext in CONTEXT.md lost two clauses by copying the brief verbatim:Default: restore both after the verbatim text, unless the maintainer says otherwise on this PR.
module.exportsexportsrenderCountingCamerasListwith no test using it (app.js:4504-4510). Test it or drop the export. Also add a one-line comment explaining whyapp.jshas thelocalStorageguard and the export block (Node test loading, the same asi18n.js:2372).tests/frontend/test_admin_cameras.test.jsleaks globals (:18-26, 73-77). It setsglobalThis.windowandglobalThis.localStorage, butfinallydeletes onlydocumentandt, and app.js stays in the require cache. Clean up every global it sets.Closes #220will auto-close #220 while item 3 lives on in #209, which is already merged. Fine as is, but say so in the PR body.Standards
P2
P3
chore/is for dependencies, CI and tool config. This PR isrefactor/work. Userefactor(statistics):in the PR title and new commits; the branch name can stay.bd835b7has noCo-Authored-Bytrailer._cycle_values_params(cycles)(occupancy_repository.py:88). It is also called with counting windows (:1738). Rename it, for example to_window_values_params(windows).T = TypeVar("T")inapp/schemas/statistics.py:11. Rename it_T._assert_indexed_planis nested inside the test (tests/test_statistics_periods.py:577). Move it to module level, which fits #219 item 5's "one helper" better.Not raised: keeping
CalibrationLogRecordas a TypedDict is fine, since it predates this PR and holds internal DB rows rather than API payloads.chore(statistics): third-pass P3 follow-ups from PRs #167 and #168to refactor(statistics): third-pass P3 follow-ups from PRs #167 and #168Pass 1 fixes (
a96f6bf)All P2 and P3 findings from review pass 1 (r44) have been resolved.
origin/master(9a72ff4) is merged cleanly into the branch.CalibrationLogRecordrequired query-only keys (matched_cycle_date,rank_in_cycle), making single-row query a false cast.CalibrationLogRecord(table columns) andBatchCalibrationLogRecord(withmatched_cycle_dateandrank_in_cycle). Single-row returns truthfully typedCalibrationLogRecord.OmittedIfNone.docs/api/README.mdand noted that OpenAPI nullability is deliberate.Busiest Daydefinition inCONTEXT.mdlost multi-day scope and closed/unreliable period clauses.CONTEXT.mdfollowing the brief's verbatim text.renderCountingCamerasListexport inapp.js; missing comments on Node-loading guards.renderCountingCamerasListfrommodule.exportsand added explanatory comments on Node test loading forlocalStorageguard and exports.tests/frontend/test_admin_cameras.test.jsleaked globals andapp.jsinrequire.cache.window,localStorage,document,t, and purgedapp.jsfromrequire.cacheinfinally.chore/instead ofrefactor/).refactor(statistics): ...and usedrefactor(statistics):prefix for new commits.Co-Authored-Bytrailer on earlier commit.Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>trailer to fix commit._cycle_values_params(cycles)also used for counting windows._window_values_params(windows)across definition and all four call sites.T = TypeVar("T")inapp/schemas/statistics.py._T = TypeVar("_T")._assert_indexed_planinside test function._assert_indexed_planto module level intests/test_statistics_periods.py.Ready for review pass 2.
Code review, pass 2 (
origin/master...a96f6bf, spec #219 + #220)Result: no P1, no P2 and 4 P3s. Mergeable. The new P3s are filed as #268. A pre-existing boundary mismatch went to #127, and the commit-history items are accepted as they are.
CalibrationLogRecordtypeBatchCalibrationLogRecordadds the two query-only keys, and the single-row path uses the base type.is_trustedis nullable, like the column._window_values_params, P3-10_T, P3-11 module-level helpera96f6bfuserefactor(statistics):, butbd835b7still sayschore(statistics):. Accepted: not worth rewriting history for.Co-Authored-Byonbd835b7New P3 → #268
test_admin_cameras.test.js:20-37sets globals and loads app.js before thetry, so if loading throws, the globals leak.typeof localStorageguard atapp.js:16-17never runs in tests, because the only test stubslocalStoragefirst.previous_month_daily_averageis "always present", but it is omitted when null. This predates the PR.Pre-existing → #127
The single-row calibration-log lookup's window end is inclusive (
<=), while the batched lookup's is exclusive (<). The two disagree on a log stamped exactly at a cycle boundary, and the audit doc claims they match.