Aug 4 - Update code to follow up - MT13b
This commit is contained in:
@@ -81,11 +81,33 @@ class Inspection(db.Model):
|
||||
)
|
||||
follow_up_required = db.Column(db.Boolean, nullable=False, default=False)
|
||||
follow_up_note = db.Column(db.Text, nullable=True)
|
||||
# phase49 — WHO asked for the follow-up and when. `follow_up_required` alone
|
||||
# cannot distinguish a client request from an internal one, and staff need to
|
||||
# know who is waiting. Set by flag_followup(), nulled by clear_followup().
|
||||
# NULL on every pre-phase49 row, which the UI renders as an unattributed
|
||||
# follow-up exactly as before.
|
||||
follow_up_requested_by = db.Column(
|
||||
db.Integer,
|
||||
db.ForeignKey('users.id', ondelete='SET NULL',
|
||||
name='fk_inspections_follow_up_requested_by'),
|
||||
nullable=True,
|
||||
)
|
||||
follow_up_requested_at = db.Column(db.DateTime, nullable=True)
|
||||
|
||||
results = db.relationship('InspectionResult', backref='inspection', lazy='dynamic', cascade='all, delete-orphan')
|
||||
issues = db.relationship('Issue', backref='inspection', lazy='dynamic', cascade='all, delete-orphan')
|
||||
follow_ups = db.relationship('Inspection', backref=db.backref('parent', remote_side='Inspection.id'),
|
||||
lazy='dynamic', foreign_keys='Inspection.parent_inspection_id')
|
||||
# phase49. Explicit foreign_keys is required: inspector_id also points at
|
||||
# users.id, so SQLAlchemy cannot infer which column this relationship uses.
|
||||
follow_up_requester = db.relationship('User',
|
||||
foreign_keys=[follow_up_requested_by])
|
||||
# The schedule this inspection was started from / materialised by, so the
|
||||
# detail view can show the cadence and who set it up. Explicit foreign_keys
|
||||
# again: inspection_schedules.parent_inspection_id points back here (phase48),
|
||||
# so neither side's join is inferable.
|
||||
inspection_schedule = db.relationship(
|
||||
'InspectionSchedule', foreign_keys=[inspection_schedule_id])
|
||||
|
||||
def __repr__(self):
|
||||
return f'<Inspection {self.id} - {self.inspection_date}>'
|
||||
|
||||
@@ -37,6 +37,12 @@ EVENT_INSPECTION_SCHEDULED = 'inspection_scheduled'
|
||||
# order via the tokenized public link (phase36).
|
||||
EVENT_WORK_ORDER = 'work_order_update'
|
||||
|
||||
# Fired when a follow-up re-inspection is requested — by a manager, or (phase49)
|
||||
# by a customer against their own facility. Routed through notify_by_matrix so
|
||||
# recipients stay admin-configurable; the inspection's own inspector is notified
|
||||
# directly by the route rather than through the matrix.
|
||||
EVENT_FOLLOWUP_REQUESTED = 'followup_requested'
|
||||
|
||||
ALL_EVENT_TYPES = {
|
||||
EVENT_ISSUE_ASSIGNED: 'Issue assigned to me',
|
||||
EVENT_ISSUE_STATUS: 'Issue status changed',
|
||||
@@ -48,6 +54,7 @@ ALL_EVENT_TYPES = {
|
||||
EVENT_ADMIN_BROADCAST: 'Admin broadcast (system announcements)',
|
||||
EVENT_INSPECTION_SCHEDULED: 'Scheduled inspection due (assigned to me)',
|
||||
EVENT_WORK_ORDER: 'Contractor updated a work order',
|
||||
EVENT_FOLLOWUP_REQUESTED: 'Follow-up re-inspection requested',
|
||||
# Customer-facing — only relevant for customer role accounts
|
||||
EVENT_CUSTOMER_INSPECTION_DONE: 'Inspection completed at my facility (portal)',
|
||||
EVENT_CUSTOMER_ISSUE_UPDATED: 'Issue created or updated at my facility (portal)',
|
||||
|
||||
@@ -27,6 +27,7 @@ issue_flagged : admin ✓ director ✓ inspector ✗ pm ✗ cust
|
||||
issue_created : admin ✗ director ✗ inspector ✗ pm ✗ customer ✓ (assignee implicit)
|
||||
issue_updated_customer : admin ✗ director ✗ inspector ✗ pm ✗ customer ✓
|
||||
verification_requested : admin ✓ director ✓ inspector ✗ pm ✗ customer ✗
|
||||
followup_requested : admin ✓ director ✓ inspector ✗ pm ✓ customer ✗ (inspection's own inspector implicit)
|
||||
sla_alert : admin ✓ director ✗ inspector ✗ pm ✗ customer ✗ (assignee + followers implicit)
|
||||
score_alert : admin ✓ director ✓ inspector ✗ pm ✗ customer ✗ (facility score drop cron)
|
||||
"""
|
||||
@@ -59,6 +60,7 @@ MATRIX_EVENTS = {
|
||||
'issue_created': 'Issue created (standalone)',
|
||||
'issue_updated_customer': 'Issue updated (customer)',
|
||||
'verification_requested': 'Verification requested',
|
||||
'followup_requested': 'Follow-up requested (incl. by customer)',
|
||||
'sla_alert': 'SLA at-risk / breached',
|
||||
'score_alert': 'Facility score trend alert (significant drop)',
|
||||
}
|
||||
@@ -143,6 +145,16 @@ MATRIX_DEFAULTS = {
|
||||
('verification_requested', 'project_manager'): False,
|
||||
('verification_requested', 'customer'): False,
|
||||
('verification_requested', 'custom'): False,
|
||||
# followup_requested (phase49) — a customer (or manager) asks for a
|
||||
# re-inspection. On for the roles who action it; the inspection's own
|
||||
# inspector is notified directly by the route, so the inspector column stays
|
||||
# off to avoid alerting the whole inspector pool.
|
||||
('followup_requested', 'admin'): True,
|
||||
('followup_requested', 'director'): True,
|
||||
('followup_requested', 'inspector'): False,
|
||||
('followup_requested', 'project_manager'): True,
|
||||
('followup_requested', 'customer'): False,
|
||||
('followup_requested', 'custom'): False,
|
||||
# sla_alert (assignee + followers always notified implicitly)
|
||||
('sla_alert', 'admin'): True,
|
||||
('sla_alert', 'director'): False,
|
||||
|
||||
+7
-1
@@ -43,7 +43,13 @@ class User(UserMixin, db.Model):
|
||||
mfa_recovery_codes = db.Column(db.JSON, nullable=True)
|
||||
|
||||
# Relationships
|
||||
inspections = db.relationship('Inspection', backref='inspector', lazy='dynamic')
|
||||
# phase49: inspections now has TWO foreign keys to users.id — inspector_id
|
||||
# and follow_up_requested_by — so the join is otherwise ambiguous and every
|
||||
# mapper configuration fails with AmbiguousForeignKeysError. This
|
||||
# relationship means "inspections I performed": inspector_id only.
|
||||
inspections = db.relationship('Inspection', backref='inspector',
|
||||
lazy='dynamic',
|
||||
foreign_keys='Inspection.inspector_id')
|
||||
|
||||
# ── Flask-Login integration ────────────────────────────────────────────
|
||||
# Override UserMixin.is_active so that disabled accounts are rejected
|
||||
|
||||
Reference in New Issue
Block a user