Short answer: for a logistics receipt system, use a backend-authorized direct browser upload with short-lived signed URLs, immutable object keys, and a storage policy that treats tenant isolation as the first constraint. React and Next.js can send the bytes directly to S3-compatible storage; the application server should decide who may create, read, replace, or delete a receipt. CORS is part of that boundary, not a substitute for authorization.
The easiest architecture is the one that leaves the fewest dangerous decisions in the browser. A browser upload should carry a file and a temporary capability. It should not carry a cloud master key, choose an unrestricted object path, or decide that a receipt belongs to tenant A because a form field said so.
That sounds strict because audit storage is strict.…