Files
WebForm-mw/app/api/staff/report
Joel Brock 63e73e7fe6 Staff report: pass Civi-signed file URLs through to clicks
Civi serves uploaded files at /civicrm/file?id=X&eid=Y&fcs=<JWT>; the fcs
is a JWT signed with the site key. Without it, Civi's file handler crashes
on a null JWT decode (Firebase\JWT\JWT::decode argument null). We don't
have the site key on the Next.js side, so let Civi mint the URLs for us.

Backend (/api/staff/report):
- Add file_name selects for org-side file fields (Certificate of
  Incorporation and friends) so org files have names alongside URLs.
- Collect every file id referenced by activity and org custom fields.
- Call APIv4 Attachment.get with select: ["id", "url"] to fetch signed
  URLs in one round trip. Build a urlByFileId map.
- Org-side file values are now wrapped in { id, file_name, url } shape
  matching the activity-side files (previously bare file ids that the
  frontend couldn't render).
- Activity-side file values gain a url property from the map.
- If Attachment.get doesn't expose url on this Civi version, the call is
  caught and we fall through to bare URLs without fcs (no regression).

Frontend (FieldValue):
- Prefer v.url when present, normalizing absolute and relative shapes
  against CIVI_BASE_URL.
- Fall back to /civicrm/file?reset=1&id=X if url wasn't provided.
2026-06-10 09:29:42 -07:00
..