LastVet iOS Architecture Notes¶
API client¶
The veteran app talks to Configuration.apiBaseURL using Bearer JWT session exchange. Networking lives in LastVet/Core/Networking/LastVetAPIClient.swift.
| Build | LastVetAPIEnvironment |
API base URL |
|---|---|---|
| Debug | production |
https://api.last.vet/api |
| Release | production |
https://api.last.vet/api |
LASTVET_API_ENVIRONMENT is set in checked-in Configuration/Debug.xcconfig and Configuration/Release.xcconfig. Session exchange secrets are per-environment in gitignored Secrets.xcconfig (VETERAN_SESSION_EXCHANGE_SECRET_STAGING / _PRODUCTION).
Imaging storage (envelope encryption)¶
As of the envelope encryption integration, veteran imaging uploads use Pattern B (API-mediated):
| Flow | Endpoint | Client behavior |
|---|---|---|
| Upload | POST /veteran/me/documents/imaging/upload |
Multipart form (file, title, documentType, optional description / documentDate). Plaintext over TLS. Server encrypts with AES-256-GCM + wrapped DEK. |
| Download | GET /veteran/me/documents/:id/download |
Inline decrypted stream from API (minio_envelope). No client-side object-store URLs. |
Implementation:
ImagingEnvelopeUpload.swift— multipart temp file +URLSessionUploadTaskprogress/cancelLastVetAPIClient.uploadImagingDocument— Wi‑Fi guard (>50 MB), envelope POST, error mappingLastVetAPIClient.downloadDocument— inline stream from API (envelope decrypt on server)
Backend requirement¶
Staging and production API hosts must run with:
When envelope mode is active, retired presigned endpoints (/imaging/upload/init, /complete, abandon DELETE) return 410 Gone. The iOS client treats 410 on abandon as success (local dismiss of stale pending-upload banners).
Caddy on lastvet-edge uses 20 minute read/write timeouts to support 512 MiB uploads over slow uplinks.
Limits and UX¶
- Server max object size: 512 MiB per imaging study
- Client Wi‑Fi gate: 50 MiB on cellular (see
UploadConnectivity.swift) - Upload progress: real percentage via
URLSessionUploadTask; user can cancel mid-upload
Further reading¶
- Design plan:
docs/ENVELOPE_ENCRYPTION_INTEGRATION_PLAN.md(Session 1) - Canonical crypto spec:
lastvet-gates/docs/security/IMAGING_ENVELOPE_ENCRYPTION.md - R940 platform topology (API hosts, env lanes, deploy gates):
lastvet-gates/docs/deployment/R940_ENVIRONMENT_TOPOLOGY.md
Provider portal (separate repo)¶
last.vet-provider downloads veteran documents via GET /provider/:id/veteran/:veteranId/documents/:documentId/download and expects an inline Blob. It does not implement the retired veteran presigned multipart upload flow. Envelope streaming downloads should work without provider changes; provider-originated uploads use the standard document POST (non-imaging types only in UI today).
Tests¶
LastVetTests/NetworkingTests/ImagingEnvelopeUploadTests.swift covers multipart temp-file writing, imaging error mapping, and 410 abandon dismiss behavior.