Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/S4nti4goCoder/cloudsyncpro/llms.txt

Use this file to discover all available pages before exploring further.

CloudSyncPro routes file bytes directly from the browser to Cloudflare R2 using presigned URLs, bypassing Supabase entirely for the binary transfer. This design avoids Supabase’s egress bandwidth costs, removes a single point of congestion for large uploads, and keeps the Edge Function payload small — it only handles URL generation and permission checks, not streaming bytes.

Upload flow

1

Request a presigned URL from the Edge Function

The client calls the upload-file Edge Function with the file name, MIME type, size, workspace_id, and optional folder_id. The request is authenticated via a Bearer access token in the Authorization header.The Edge Function validates that the user has edit permission in the workspace (using has_workspace_edit_permission), generates a presigned PUT URL for R2, and returns it along with the r2Key and the public URL of the object.
2

PUT the file directly to R2

The client uses XMLHttpRequest to PUT the raw file bytes to the presigned URL. The Content-Type header is set to the file’s MIME type. Progress events from xhr.upload are forwarded to the optional onProgress callback so the UI can render an upload progress bar.Because the upload goes straight to R2, no Supabase bandwidth is consumed and upload throughput is limited only by the user’s connection and R2’s ingestion capacity.
3

Register file metadata in Postgres

After the PUT succeeds, the client calls supabase.from('files').insert(...) to create a row in the files table. The insert includes name, original_name, size, mime_type, extension, r2_key, workspace_id, folder_id, uploaded_by, and defaults status to active and version to 1.
4

Log the activity

Finally, activityService.logActivity writes an upload entry to activity_logs with the resource ID, name, size, and MIME type. This entry appears in the workspace activity timeline.

Auto-purge flow

Trashed files are hard-deleted automatically after 30 days. The purge is orchestrated by a Supabase pg_cron job that calls an Edge Function — no external cron infrastructure is needed.
1

pg_cron job triggers at 03:15 UTC

A pg_cron job scheduled to run daily at 03:15 UTC fires inside Postgres. It issues an HTTP request to the purge-files Edge Function.
2

Edge Function receives the purge request

The request includes mode: auto_purge in the JSON body and an X-Cron-Secret header containing the CRON_SECRET secret. The Edge Function verifies the header value against the stored secret before proceeding.
3

R2 blobs and Postgres rows are deleted

The function queries for all files rows where status = 'deleted' and updated_at < now() - interval '30 days'. For each matching file it deletes the R2 object using the stored r2_key, then removes the Postgres row. This ensures no orphaned blobs remain in the bucket.
The X-Cron-Secret header is the only authentication mechanism protecting the purge-files endpoint from unauthenticated invocations. Set a strong, randomly generated value for CRON_SECRET in Supabase Dashboard → Edge Functions → Secrets, and never expose it in client-side code or version control.

Build docs developers (and LLMs) love