File storage
S3-compatible adapters, presigned uploads, avatars, and organization logos.
Adapter pattern
Storage lives under lib/storage with a provider toggle in simulacrum.config.ts:
typescript
storage: {
provider: "s3" | "r2" | "supabase" | "minio" | "local",
bucket: process.env.STORAGE_BUCKET,
},
Presigned URLs
Clients request a short-lived upload URL from a server action, PUT the file directly to object storage, then confirm metadata in your database.
Avatars and logos
Profile settings use the same pipeline for user avatars. Organization settings upload logos to a dedicated prefix with public read or CDN in front.
Enforce file size and MIME allowlists server-side before issuing presigned URLs.