Photos & annotations
Photos are the backbone of a defensible defect record. IssuesId treats them as first-class objects — captured on site, marked up in the moment, dictated rather than typed, and anchored to the exact spot that matters.
Capture
Photos can be captured directly from the camera in-app, or imported from the device's camera roll. Each photo:
- →Attaches to a defect (or directly to a drawing for context).
- →Is uploaded to S3-compatible storage with a presigned upload URL — no file ever touches the app server, which keeps uploads fast and lets the platform sign per-tenant access policies.
- →Carries metadata for the upload time, the capturing user, and the original device timestamp where available.
When you're offline, photos queue locally and upload the moment you reconnect. The defect record is created immediately, even before the photo finishes uploading — the photo lands on the record once the queue drains.
Annotations
Photos and drawings support freeform markup powered by Fabric.js. The toolset includes:
- →Pins — numbered markers placed at a specific point on the image. The most common annotation.
- →Rectangles, circles, arrows, free-form lines — call out an area, draw an arrow at the problem.
- →Text — type or dictate a label.
The markup is saved as JSON against the attachment, so it's editable later and rendered consistently anywhere the photo is shown — in the app, in PDF reports, in handover packs.
Pins are coordinate-stable
Each pin carries:
- →Coordinates as ratios (0–1 of the image dimensions), not pixels. This means a pin placed on a 4032×3024 phone photo renders in the right spot when the image is displayed at 800×600 or rendered into a PDF at 2480×1860. Ratios are server-validated; out-of-bounds coordinates are rejected.
- →A state — one of
open,pending,in_dispute,closed— used to colour the pin so a foreman can scan a marked-up drawing and see open work at a glance. - →A caption — the text label shown next to the pin.
- →An optional pin number — for ordered captions ("1: chip in tile", "2: hairline crack").
Voice captions
Pins and attachments support voice captions — dictated audio transcribed into the caption field. Speak instead of typing on a phone in the rain. The transcription is held in a text field on the attachment, capped at 5,000 characters, with ASCII control characters stripped before storage to keep the data safe to render in PDFs and emails downstream.
You can edit the transcribed text after dictation — useful for fixing the inevitable "deck" → "duck" misrecognition.
Drawings vs photos
Both are attachments with markup, but they behave a little differently:
- →Photos are tied to a single defect or inspection.
- →Drawings are tied to the project's drawing register, with their own revision history. Markup on a drawing lives on a specific revision — it's preserved if you scroll back to look at rev B later, and a new revision starts a fresh markup canvas. See Documents & drawings for the full revision model.
In PDF reports
When a report renders a defect, every photo and its pins are embedded. The pins draw at their ratio-based coordinates, scaled to the report's image size. The voice caption renders as text below the photo. The handover pack a client receives is the same evidence the field team captured, presented for print.
What to read next
- →Defects — photos are usually captured against a defect.
- →Documents & drawings — the revision model that drawing markup lives in.
- →Offline & PWA — capture and annotate without a signal, sync later.