fix(schedule): call dated overrides schedule exceptions #175
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!175
Loading…
Reference in a new issue
No description provided.
Delete branch "chore/schedule-exception-naming"
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?
Summary
Implements #108: call dated schedule overrides Schedule Exceptions in the admin UI and documentation, with English and Spanish wording for holiday hours, special hours, and exceptional closures. The existing
/api/occupancy/holidaysroute and storage names remain compatible.This is a prerequisite of #170 (historical-flow curation, #163). #161's draft builds on this branch and handles holiday identity, events, and analytics separately.
Architectural impact
CONTEXT.md. Updated Swagger summaries, descriptions, and schema field descriptions while preserving the legacy API names.Verification
python3 scripts/check_docs.pypassed (38 Markdown files, 76 HTTP operations).pytest -qpassed: 452 tests after first-pass fixes.fdfad26).Review status
fdfad26; details in the follow-up comment.Checklist
5322763), resolve themasterconflict (4034c42), and push both commits.docs/standards/git-and-workflow.md.Issues closed on merge
Closes #108
gabogg referenced this pull request2026-09-28 10:28:14 +00:00
WIP: chore(schedule): call dated overrides schedule exceptionsto chore(schedule): call dated overrides schedule exceptionsReview pass 1: Standards + Spec
Diff reviewed:
origin/master...HEAD(basefb89880). The spec is #108, specifically its Confirmed triage resolution — 2026-09-27. The main findings were checked against the code. Under the first-pass policy, every item below should be fixed in this PR.Standards
Hard violations
docs/standards/ui-design-guidelines.md§3.2 says labels and states use standard uppercase.app/static/js/i18n.js:2289),el.textContent = t(key)replaces the uppercase fallback in the HTML with a mixed-case string. The parent.multiplier-step-btnsets notext-transform.app/static/index.html:758renders as[ Schedule Exceptions ]/[ Excepciones de Horario ], next to the hardcoded[ SCHEDULES ]and[ CAMERAS ].app/static/index.html:812renders as[ + Add Exception ]/Agregar Excepción.uppercaseclass), and line 689 is fine (the strings are already all caps).uppercaseto these spans or buttons, or make the strings all caps.docs/standards/git-and-workflow.md§1 limitschore/to dependency updates, CI workflows and tool configs. This PR changes user-visible UI text and the glossary, sofix/orrefactor/fits better. This is minor; at least use the right type in the merge title.Judgement calls (code smells)
occupancy.subtabHolidays,addHolidayBtn,holidaysCountBadge,scheduledHolidaysTitle,defaultHolidayHoursTitle.common.holidaynow means "Schedule Exception" (i18n.js:583/1675), andapp.js:1867reads it. The routes andholiday_*fields have a compatibility reason to keep their names. These keys are internal to the frontend and don't, anddocs/agents/domain.mdasks code to use the glossary's terms.exceptionMinEntriesLabel(i18n.js:127/1218) uses the new term, while its siblingsholidayOpenLabel/holidayCloseLabelkeep the old one.index.html:681-700), are translated. The panel is now partly English and partly Spanish when switched to Spanish.Bugs and nits
scheduledHolidaysTitle: "Scheduled Exceptions"(i18n.js:1249) drops "Schedule", while Spanish says "Excepciones de Horario Programadas". The Spanish matches the glossary term.docs/api/README.md, only the Occupancy table's header changes from "OpenAPI summary" to "Description". The other tables (:19, :102, …) keep "OpenAPI summary". See Spec (a)1.tests/test_i18n.pydoesn't check that the translated labels still render uppercase, which is why finding 1 wasn't caught.index.html:804shows[ NAME ]until translations load, then mixed case. This existed before this PR.Spec
Nothing blocks the spec.
CONTEXT.md:116-121) match the resolution.(a) Missing or partial
The spec line is: "Rename admin UI wording and documentation to Schedule exceptions".
/docsbuilds its operation summaries from the function names: "Get Holidays Calendar", "Add Or Update Holiday", "Delete Holiday" (app/controllers/occupancy_controller.py:199-245).app/schemas/occupancy_models.py:327, 337, 340).summary=/description=and updating the docstrings changes no route. Thedocs/api/README.mdOccupancy header can then go back to "OpenAPI summary".schedule_labelbuilt inapp/services/occupancy_service.py:298asf"🎉 {h_name} (Cerrado)", with the default name"Feriado"(:289; alsoapp/db/occupancy_repository.py:775). A renovation or emergency closure still gets a party emoji, even though this PR removed the emoji from the card title and badge. At minimum drop the emoji and use a neutral default name. The Spanish-only backend label overlaps with #73; defer that part to #73 if needed.(b) Scope creep
app.js:1867and from thecarousel.holidayOpen/holidayClosedstrings follows from the rename, so it is in scope.tests/test_i18n.pyassertsstatisticsDeck...legend.holiday === 'FERIADO'. This locks in a marker that #161 owns. It is harmless, but #161 may need to relax it.(c) Implemented but questionable
CONTEXT.md:113(Usual Weekday Baseline) still says a day counts only if it "is not a holiday or Closed Day". The code excludes every dated exception (is_holiday=Trueon every row,occupancy_service.py:302). Under the new definitions a holiday and a schedule exception are different things, so the sentence no longer describes the code. Change it to "schedule exception", or keep it and add a pointer to #161, which owns baseline eligibility.index.htmlorapp.js:generalParamsAndHolidaysTitle,defaultHolidayHoursTitle,schedulesHolidaysAndCamerasTitle,scheduledHolidaysTitle,workingHoursTitle. The edits are consistent but change nothing on screen. Wire them up or leave them, but don't count them as coverage.Summary:
🎉 … (Cerrado)label still present exceptions as holidays.🤖 Generated with Claude Code
chore(schedule): call dated overrides schedule exceptionsto fix(schedule): call dated overrides schedule exceptionsFirst-pass findings addressed —
fdfad26Standards
fix(schedule): ...so the merge title uses the correct change type. The existingchore/branch remains because #161's stacked draft uses it as its base.Spec
/holidaysOpenAPI operations and their relevant schema fields. The API guide again uses the “OpenAPI summary” header and matches those summaries.Verification: Ruff lint and format checks, docs check (38 Markdown files / 76 HTTP operations), focused tests (24 passed), full pytest (452 passed), and commit-time hooks all passed. The branch is pushed and ready for review pass 2.
Code review, pass 2 (
origin/master...fdfad26)Result: no P1 or P2 findings. Both axes confirm every first-pass finding is fixed. Of the 8 P3s (5 Standards, 3 Spec), 7 are deferred to #184, following docs/standards/git-and-workflow.md ("Second pass, ordinary PR"). The harmless scope-creep note is not tracked.
Verification on master (
fb89880) merged with this PR: 451 pytest passed, 1 skipped. The skip is the tailwind binary, which is untracked in a clean checkout. 242 frontend tests passed andruff checkis clean. CI on the branch is green.Standards
First-pass findings
uppercase(index.html:754-761,794,810), andswitchAdminOccSubtabadds it back after a tab switch (app.js:2319,2321).fix(schedule). Thechore/branch stays because the stacked #161 draft uses it as its base.exceptionMinEntriesLabelvsholidayOpenLabel: fixed. They are nowexceptionOpenLabelandexceptionCloseLabel.scheduledHolidaysTitle: fixed. The key was unused and is deleted.New findings (all P3, judgement calls, all in #184)
index.html:672,678).class="uppercase" data-i18n=…. It also forces a redundantuppercaseonto inner<span>s.exceptionMinEntriesLabeldoes not match thetrust*Labelprefix of its neighbours."Excepción de horario"is duplicated in the repository and the service.FERIADOnow has only an indirect guard (test_statistics_deck_day.test.js:235).Spec
First-pass findings
docs/api/README.md:82-84matches the OpenAPI summaries.test_occupancy.py:139-156).FERIADOassertion: removed. The deck strings are untouched, which fits the spec line "keep this issue naming-only and non-blocking for the statistics deck".No route, field, table or ID was renamed, which satisfies "Preserve existing API routes and storage names for compatibility." Nothing is missing.
P3 findings (in #184)
name: ""is now stored as the default name, while the POST response still echoes""(occupancy_repository.py:775,occupancy_controller.py:241).Summary
Merging.
🤖 Generated with Claude Code