diff --git a/app/api/issues.py b/app/api/issues.py index eded629..45f9f56 100644 --- a/app/api/issues.py +++ b/app/api/issues.py @@ -58,10 +58,12 @@ def _issue_payload(issue): 'reported_at': issue.reported_at.isoformat() if issue.reported_at else None, 'resolved_at': issue.resolved_at.isoformat() if issue.resolved_at else None, 'mobile_local_id': issue.mobile_local_id, - # photo_path is the primary issue photo; result_photos are resolution photos. - # Both are relative paths from the server static root. - 'photo_path': issue.photo_path or None, - 'result_photos': issue.result_photos or [], + # photo_path: primary evidence photo (first iPad photo). + # mobile_photo_paths: extra evidence photos from iPad (shown under Photo Evidence). + # result_photos: resolution photos added via the web update form. + 'photo_path': issue.photo_path or None, + 'mobile_photo_paths': issue.mobile_photo_paths or [], + 'result_photos': issue.result_photos or [], } @@ -204,26 +206,24 @@ def create_issue(): inspection = None # ── Create ──────────────────────────────────────────────────────────── - # result_photos may be supplied by the mobile app as a list of paths that - # were already uploaded via /api/v1/photos/upload (one call per photo). - # Validate that it is a list of non-empty strings; silently drop bad entries. - raw_result_photos = data.get('result_photos') - if isinstance(raw_result_photos, list): - result_photos = [p for p in raw_result_photos if isinstance(p, str) and p.strip()] - else: - result_photos = [] + # result_photos in the POST body = extra evidence photos from the iPad. + # Store in mobile_photo_paths (not result_photos) so they appear under + # "Photo Evidence" on the web, not "Resolution Details". + raw_mobile = data.get('result_photos') + mobile_photo_paths = [p for p in raw_mobile if isinstance(p, str) and p.strip()] \ + if isinstance(raw_mobile, list) else [] issue = Issue( - inspection_id = inspection_id, - facility_id = facility_id, - severity = severity, - description = description, - photo_path = data.get('photo_path') or None, - result_photos = result_photos or None, - status = 'open', - reported_at = now_eastern(), - reported_by = user.id, - mobile_local_id = mobile_local_id, + inspection_id = inspection_id, + facility_id = facility_id, + severity = severity, + description = description, + photo_path = data.get('photo_path') or None, + mobile_photo_paths = mobile_photo_paths or None, + status = 'open', + reported_at = now_eastern(), + reported_by = user.id, + mobile_local_id = mobile_local_id, ) db.session.add(issue) db.session.flush() # get issue.id @@ -352,17 +352,16 @@ def update_issue_status(issue_id): @jwt_required def update_issue_photos(issue_id): """ - Attach additional photos to an existing issue created from the mobile app. + Attach additional evidence photos to an issue created from the mobile app. - Called by the iOS app immediately after create_issue when the inspector - attached more than one photo. The photos are already uploaded to the server - via /api/v1/photos/upload; this endpoint stores their paths in result_photos. + Called by the iOS app after create_issue when the inspector attached more + than one photo. Photos are already uploaded via /api/v1/photos/upload. + Stored in mobile_photo_paths so they display under "Photo Evidence" on the + web, not "Resolution Details". Request JSON ------------ - { - "result_photos": ["uploads/issue_photos/a.jpg", "uploads/issue_photos/b.jpg"] - } + { "result_photos": ["uploads/issue_photos/a.jpg", "uploads/issue_photos/b.jpg"] } Response 200 ------------ @@ -376,12 +375,11 @@ def update_issue_photos(issue_id): if issue is None: return api_error('Issue not found', 404) - # Inspectors may only update issues they reported or are assigned to if user.role == 'inspector' and issue.assigned_to != user.id and issue.reported_by != user.id: return api_error('Access denied', 403) data = request.get_json(silent=True) or {} - raw = data.get('result_photos') + raw = data.get('result_photos') if not isinstance(raw, list): return api_error('result_photos must be a list of path strings', 400) @@ -390,19 +388,18 @@ def update_issue_photos(issue_id): if not new_photos: return api_error('result_photos must contain at least one valid path', 400) - # Merge with any existing result_photos rather than overwriting, - # so multiple PATCH calls (e.g. retry) are idempotent. - existing = issue.result_photos or [] + # Merge idempotently with any existing mobile_photo_paths + existing = issue.mobile_photo_paths or [] merged = existing + [p for p in new_photos if p not in existing] - issue.result_photos = merged + issue.mobile_photo_paths = merged db.session.commit() log_action(ACTION_UPDATE, 'Issue', issue.id, - f'result_photos updated (+{len(new_photos)} photos)', + f'mobile_photo_paths updated (+{len(new_photos)} photos)', f'source=mobile; updated_by={user.username}') logger.info('API ISSUES | photos_updated | issue_id=%d | added=%d | user=%s', issue.id, len(new_photos), user.username) - return api_ok({'issue_id': issue.id, 'result_photos_count': len(merged)}) \ No newline at end of file + return api_ok({'issue_id': issue.id, 'result_photos_count': len(merged)}) diff --git a/app/models/issue.py b/app/models/issue.py index 153080d..e06c2cb 100644 --- a/app/models/issue.py +++ b/app/models/issue.py @@ -63,6 +63,10 @@ class Issue(db.Model): resolved_at = db.Column(db.DateTime) result_notes = db.Column(db.Text) result_photos = db.Column(db.JSON) # list of relative paths e.g. ["uploads/issue_photos/abc.jpg"] + # Extra evidence photos submitted from the iPad at issue-creation time. + # Stored separately from result_photos (resolution photos added via web) + # so they display under "Photo Evidence" rather than "Resolution Details". + mobile_photo_paths = db.Column(db.JSON, nullable=True) # ── Resolution verification ────────────────────────────────────────── verified_by = db.Column(db.Integer, db.ForeignKey('users.id', ondelete='SET NULL'), nullable=True) diff --git a/app/templates/issues/issues_view.html b/app/templates/issues/issues_view.html index 1490c21..52b22f8 100644 --- a/app/templates/issues/issues_view.html +++ b/app/templates/issues/issues_view.html @@ -54,12 +54,23 @@
{{ issue.description }}
- {% if issue.photo_path %} + {% if issue.photo_path or issue.mobile_photo_paths %}{{ issue.description }}
- {% if issue.photo_path %} + {% if issue.photo_path or issue.mobile_photo_paths %}