File Uploads

Prestarts and activities support file attachments (photos, documents, PDFs). Files are uploaded via multipart form data and stored on the server filesystem.

Upload Flow

  1. User selects a file using the file input
  2. Frontend creates a FormData object with the file
  3. Server action sends POST /prestarts/{prestartId}/files (or .../activities/{activityId}/files)
  4. Go handler:
    • Parses the multipart form (max 32MB)
    • Creates the storage directory: ./uploads/prestarts/{orgId}/{prestartId|activityId}/
    • Writes the file to disk
    • Inserts metadata into prestart_files table
  5. Returns the file record with file_url for display

Delete File

  1. User clicks delete on a file
  2. Server action calls DELETE /files/{fileId}
  3. Go handler soft-deletes the prestart_files row
  4. The physical file remains on disk (can be cleaned up by a future maintenance task)

File Serving

Files are served via the existing static file server in main.go at /uploads/*. The prestart file handler builds the URL as:

/uploads/prestarts/{orgId}/{parentId}/{filename}

Security

  • Only the prestart creator or an admin can upload/delete files
  • Files are associated with org_id for tenant isolation
  • The CHECK constraint ensures every file has at least one parent (prestart_id or activity_id)

Key Files

FilePurpose
backend/db/queries/prestart_files.sql3 file queries
backend/api/internal/prestart/service.goFile upload/delete logic
backend/api/internal/prestart/handler.goFile HTTP handlers
apps/web/src/actions/prestarts.tsuploadPrestartFile, uploadActivityFile, deletePrestartFile