Summary
Lets the S3 client target an S3-compatible endpoint, so staging uploads go to LocalStack instead of real AWS (item B2 of the Terraform plan).
-
AWS_S3_ENDPOINT— custom endpoint; unset means real AWS (prod). -
AWS_S3_FORCE_PATH_STYLE=true— path-style addressing, required by LocalStack. - When an endpoint is set, the returned URL is
<endpoint>/<bucket>/<key>; without one it is the same AWS URL as before.
Prod leaves both variables unset, so its behaviour is unchanged.
After merge (staging, S10)
Add AWS_S3_ENDPOINT=http://localstack:4566 and AWS_S3_FORCE_PATH_STYLE=true to the moanapay/staging/app-env secret, redeploy, and smoke-test an upload.
Not in scope
Returned URLs are not client-readable (the bucket is private on every env). A stable /storage/files/:key endpoint that redirects to a presigned URL is B3.
Verification
-
jest src/modules/storage: new tests cover both the AWS default and the custom endpoint; mutation-checked (dropping the endpoint wiring fails the test). -
eslintclean,nest buildok, no newtscerrors. - Codex adversarial review: 2 rounds, APPROVED (both round-1 findings answered: private bucket → B3; staging vars come from the app-env secret).