Jul 17 - Fill the gaps between Single-tenant mode and Multi-tenant mode - MT7

This commit is contained in:
2026-07-17 12:54:07 -04:00
parent 8d9730e3df
commit c706489480
8 changed files with 178 additions and 16 deletions
+4 -4
View File
@@ -9,11 +9,11 @@ addition: per-tenant object-key prefixing. See "Tenant isolation" below.
One interface, backend selected by config ``STORAGE_BACKEND``:
- ``local`` (default): files under ``app/static/uploads``, served via
``url_for('static', ...)``. **Byte-for-byte identical** to the behavior
before this abstraction existed — MT-2 is a no-op.
before this abstraction existed — introducing this seam is a no-op.
- ``s3``: Cloudflare R2 / any S3-compatible store. Private bucket; browser/API
URLs are short-lived presigned GETs. Requires ``boto3`` and the ``R2_*``
config keys. boto3 is imported lazily, so a ``local`` deploy needs neither.
Inert until MT-8 flips STORAGE_BACKEND per tenant.
Inert until STORAGE_BACKEND is flipped to s3 per tenant at R2 cutover.
The stored **key** is always the relative path ``uploads/<subfolder>/<file>`` —
the exact string persisted in the DB (`Issue.photo_path`, `result_photos[]`,
@@ -34,9 +34,9 @@ payload. Callers stay tenant-agnostic; the DB stays portable.
The **local** backend deliberately does NOT prefix: its layout is the existing
on-disk tree, and prefixing would relocate every existing file (that is not a
no-op, and MT-2 must be one). Local mode therefore keeps today's shared
no-op, and this seam must be one). Local mode therefore keeps today's shared
``app/static/uploads`` directory across tenants — an isolation weakness that
predates this module and is retired when a tenant moves to ``s3`` in MT-8.
predates this module and is retired when a tenant moves to ``s3`` at cutover.
Public module-level API (delegates to the active backend):