diff --git a/CLAUDE.md b/CLAUDE.md index 39d5f74..ac1b55b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -425,6 +425,7 @@ inspections.scheduled_inspection_id FK→scheduled_inspections SET NULL ← P - **Assignment notification** (immediate): on **create**, the assigned inspector gets an in-app + email "assigned to you" notification; on **edit**, only when the inspector actually changes (a "reassigned to you" notification to the new assignee). Via `_notify_assignee()` in the blueprint using `event_type=EVENT_SCHEDULED_INSPECTION`. - **Reminders** are dispatched by the cron endpoint (see §11): advance (1 day before) + due-date to the inspector, overdue to admin/director — each fires at most once per occurrence via the `*_notified` flags. Uses `notify()` with `event_type=EVENT_SCHEDULED_INSPECTION`. - Dashboard shows an **upcoming (next 7 days) / overdue** panel for non-customers (inspectors see only their own). +- **"Scheduled" badge:** an inspection started from a schedule carries `scheduled_inspection_id`. `Inspection.scheduled_inspection` (relationship, foreign_keys on that column) resolves the source schedule (None if ad-hoc or the schedule was later deleted). The inspection **detail** view header shows a `bi-calendar-check` "Scheduled · " badge, and the inspection **list** shows a compact "Scheduled" pill next to the template name — both gated on `scheduled_inspection_id` being set. Management (`/scheduled-inspections/new|edit|delete`) is `@project_manager_required`; **Start** is the **assigned inspector ONLY** (`sched.inspector_id == current_user.id`) — managers do NOT get a Start button and `GET //start` 403s for anyone who isn't the assignee (the inspection is theirs to do; a manager who must run it assigns it to themselves). The Start button is hidden for non-assignees on both the scheduled-inspections list and the dashboard panel. Inspectors' list/dashboard views are scoped to their own `inspector_id`. diff --git a/app/models/inspection.py b/app/models/inspection.py index 15f5912..474d7c7 100644 --- a/app/models/inspection.py +++ b/app/models/inspection.py @@ -84,6 +84,10 @@ class Inspection(db.Model): results = db.relationship('InspectionResult', backref='inspection', lazy='dynamic', cascade='all, delete-orphan') issues = db.relationship('Issue', backref='inspection', lazy='dynamic', cascade='all, delete-orphan') + # The ScheduledInspection this inspection was started from (phase36), if any. + # None for ad-hoc/manual inspections or if the schedule was later deleted. + scheduled_inspection = db.relationship('ScheduledInspection', + foreign_keys=[scheduled_inspection_id]) follow_ups = db.relationship('Inspection', backref=db.backref('parent', remote_side='Inspection.id'), lazy='dynamic', foreign_keys='Inspection.parent_inspection_id') diff --git a/app/templates/inspections/list.html b/app/templates/inspections/list.html index e2837b7..cb70baa 100644 --- a/app/templates/inspections/list.html +++ b/app/templates/inspections/list.html @@ -123,7 +123,14 @@ {{ ins.facility.project.name if ins.facility and ins.facility.project else '—' }} {{ ins.facility.name }} {% if ins.area %}{{ ins.area.name }}{% else %}{% endif %} - {{ ins.template.name }} + + {{ ins.template.name }} + {% if ins.scheduled_inspection_id %} + + Scheduled + + {% endif %} + {{ ins.inspector.display_name }} {% if ins.overall_score %} diff --git a/app/templates/inspections/view.html b/app/templates/inspections/view.html index ae407f5..4a7c9f5 100644 --- a/app/templates/inspections/view.html +++ b/app/templates/inspections/view.html @@ -475,6 +475,11 @@
+ {% if inspection.scheduled_inspection_id %} + + Scheduled{% if inspection.scheduled_inspection %} · {{ inspection.scheduled_inspection.frequency_label }}{% endif %} + + {% endif %} {{ inspection.status|replace('_',' ')|title }}