3c39ed7b

By: Michael Lynch <git@mtlynch.io>

Upload imported media to S3-compatible bucket

The importer now uploads media files directly to an S3-compatible bucket
(e.g. Backblaze B2) instead of writing them to a local directory. The
server reads an S3 config to construct public media URLs, replacing the
temporary /dev-files/ local file server route.

New --s3-config flag (required) on both the server and importer points to
a JSON file with endpoint, region, bucket, credentials, and an optional
mediaBaseURL. If mediaBaseURL is omitted it defaults to {endpoint}/{bucket}.

The importer writes each media file to a temp file, uploads it via the
AWS SDK v2 S3 client (UsePathStyle=true for B2 compatibility), then
deletes the temp file. The metadata.json output continues to be written
locally via the existing --metadata flag.

A pre-generated testdata/metadata.json is committed so the Nix e2e test
sandbox can start the server without running the importer against a real
S3 bucket (Nix build sandboxes have no network access).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Suite timing

Time to Start Worker time Duration Time to finish
Config 0s 1s 1s 2s
Eval 2s 39s 39s 42s
Build 49s 3m38s 1m09s 1m59s
Test - - - -
Deploy - - - -
Suite 0s 4m19s 1m58s 1m59s

Timeline

0s10s20s30s40s50s1m1m10s1m20s1m30s1m40s1m50s