69 lines
3.1 KiB
Plaintext
69 lines
3.1 KiB
Plaintext
JQC WEB — phase44: scheduled inspection End Date
|
|
================================================
|
|
Repo: lt_janitorial_quality_control
|
|
Deploy root: /home/jqc/janitorial_qc/
|
|
WEB ONLY. No iOS changes, no iPad rebuild.
|
|
|
|
NEW FILE
|
|
migrations/versions/phase44_scheduled_end_date.py
|
|
revision = 'phase44_sched_end_date'
|
|
down_revision = 'phase43_sched_recurrence' <- verified current HEAD
|
|
|
|
OVERWRITE
|
|
app/models/scheduled_inspection.py end_date column; is_within_end_date();
|
|
is_expired; expire_if_past_end_date();
|
|
fulfill() deactivates past the boundary
|
|
app/utils/forms.py end_date DateField + validate() rules
|
|
app/routes/scheduled_inspections.py _apply_recurrence() sets/clears end_date;
|
|
_reject_if_past_end_date() guard;
|
|
per-context next_due_date label;
|
|
run_reminders() expiry sweep; audit detail
|
|
app/api/scheduled.py 'end_date' in _scheduled_payload
|
|
app/templates/scheduled_inspections/form.html End Date field + JS toggle
|
|
app/templates/scheduled_inspections/list.html "Ends" column + "Ended" badge
|
|
CLAUDE.md
|
|
|
|
DEPLOY (migration step first, then code)
|
|
cd /home/jqc/janitorial_qc
|
|
git pull
|
|
|
|
# 1. MIGRATION
|
|
source venv/bin/activate
|
|
flask db current # expect phase43_sched_recurrence
|
|
flask db upgrade
|
|
flask db current # expect phase44_sched_end_date
|
|
|
|
# 2. CODE
|
|
sudo systemctl restart janitorial_qc
|
|
sudo systemctl status janitorial_qc --no-pager
|
|
|
|
ROLLBACK
|
|
flask db downgrade phase43_sched_recurrence # drops end_date, nothing else
|
|
|
|
VERIFY
|
|
1. New Schedule -> frequency "One-time": End Date row is HIDDEN,
|
|
date field reads "Start Date"
|
|
2. Switch frequency to Weekly: End Date row appears
|
|
3. Edit an existing schedule: date field reads "Next Due Date"
|
|
4. Validation:
|
|
- end date before the due date -> rejected
|
|
- end date on a one-time schedule (via curl/devtools) -> rejected
|
|
- Mon/Wed/Fri, pick a Tuesday, end date that same Tuesday
|
|
-> rejected, message names the Wednesday
|
|
5. List: "Ends" column shows the date, "No end" when blank, "—" for one-time
|
|
6. Existing schedules: unchanged, "No end", still Active, cadence identical
|
|
7. Boundary: set end date = next due date, complete the inspection
|
|
-> schedule goes Inactive, badge reads "Ended"
|
|
8. Cron sweep:
|
|
curl -X POST "https://jqc.ltservicesinc.com/scheduled-inspections/run?token=$DIGEST_SECRET"
|
|
-> JSON now includes "expired": N
|
|
-> a schedule past its end date that was never completed goes Inactive
|
|
and stops generating overdue alerts
|
|
|
|
NOTES
|
|
- Migration follows the phase42/phase43 idiom in this repo
|
|
(op.get_bind() + sa.text() + INFORMATION_SCHEMA). Flag if you want the
|
|
stricter plain-string-only form instead; 62 existing migrations use this one.
|
|
- api/scheduled.py now returns "end_date". Additive and safe: the iPad
|
|
decodes explicit CodingKeys, so current builds ignore the new key.
|