Uploads & R2 — Code Map
Core module
apps/api/src/r2/r2.module.ts— global module.apps/api/src/r2/r2.service.ts— S3 client over R2. Exposesupload,deleteObject,getPresignedUrl(Cached),getPresignedUploadUrl,objectExists,getObjectText,getObjectBytes,getComplianceBucket,invalidatePresignedUrl.
Generic staged-upload pipeline
apps/api/src/uploads/uploads.module.tsapps/api/src/uploads/uploads.controller.ts—POST /organizations/:orgId/uploads/presign.apps/api/src/uploads/uploads.service.ts— policy table,createPresignedUpload,lookupStaged,lookupStagedMany,consumeMany.apps/api/src/uploads/dto/upload.dto.ts— DTO +UPLOAD_OWNER_TYPES.
Consumers (direct or staged)
apps/api/src/progress-photos/progress-photos.service.ts— staged viauploads.lookupStagedMany; thumbnails generated post-write.apps/api/src/workouts/workouts.service.ts— directr2.getPresignedUploadUrlfor workout media.apps/api/src/messages/messages.service.ts— direct presign for message attachments (POST /organizations/:orgId/messages/attachments/upload-url).apps/api/src/messages/messages.controller.ts— controller wiring.apps/api/src/forms/forms.service.ts— signature uploads, including the public token-gated path. Reads + writes compliance bucket viaR2Service.apps/api/src/forms/forms.controller.ts—@Public() POST /forms/by-token/:token/signature-upload.apps/api/src/organizations/organizations.service.ts— logo upload + cached presigned reads.apps/api/src/class-sessions/class-sessions.service.ts— logo presigned reads for class-session display.apps/api/src/export/export.service.ts— uploads generated CSVs, mints download URLs.
Redis
apps/api/src/redis/redis.module.ts— global Redis client.- Keys:
upload:<uploadId>— staged metadata (TTL 900s).r2:geturl:<bucket>:<key>:<expiresIn>— cached presigned GET URLs (TTL =expiresIn - 300).r2:geturl:<key>:<expiresIn>— legacy cache key used byinvalidatePresignedUrl.
Env
R2_ACCOUNT_ID,R2_BUCKET_NAME,R2_ACCESS_KEY_ID,R2_SECRET_ACCESS_KEY— required.R2_COMPLIANCE_BUCKET_NAME— optional; falls back to the default bucket.
Tests
apps/api/src/messages/messages.service.driver.tsmocksgetPresignedUrl(Cached).apps/api/src/forms/forms.service.driver.tsmocksgetPresignedUrl(Cached)andgetPresignedUploadUrl.apps/api/src/class-sessions/class-sessions.service.driver.tsmocks the cached path.