Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/CRISTIANCAMACH34/Zippi/llms.txt

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

Zippi uses a port/adapter pattern for file storage: the domain and application layers depend on a storage interface, and the concrete driver is selected at runtime via STORAGE_DRIVER. This means switching from local filesystem storage in development to AWS S3 in production requires only a configuration change — no application code is modified.

Storage Drivers

Two drivers are available:
DriverSTORAGE_DRIVER valueBest for
LocalStoragelocalLocal development, single-server deployments
S3Storages3Production, multi-instance, durable object storage

Use Cases

The storage layer handles three main categories of files:
  • Product images — catalog photos uploaded through the business portal
  • Delivery evidence photos — photos taken by couriers upon delivery
  • Export files — CSV/XLSX reports generated by finance and operations modules

Configuration

# .env
STORAGE_DRIVER=local
UPLOAD_FOLDER=storage/uploads      # Relative to the backend working directory
MAX_CONTENT_LENGTH_MB=10           # Maximum upload size in megabytes
The LocalStorage driver stores files under UPLOAD_FOLDER, organized by subfolder. Each file is saved with a UUID-based name to avoid collisions:
# app/infrastructure/external/storage/local_storage.py
class LocalStorage:
    def __init__(self, base_path: Path) -> None:
        self._base = ensure_dir(base_path)

    def save_bytes(self, folder: str, data: bytes, suffix: str = "") -> str:
        d = ensure_dir(self._base / folder)
        name = f"{uuid4().hex}{suffix}"
        path = d / name
        path.write_bytes(data)
        return str(path.relative_to(self._base))
Uploaded files are served directly by the Flask application from the UPLOAD_FOLDER path. This is suitable for local development but should not be used in multi-instance deployments because files are not shared across processes or servers.

Switching Between Drivers

To move from local development storage to S3:
  1. Set STORAGE_DRIVER=s3 in your production .env.
  2. Fill in all AWS_* variables.
  3. Restart the backend — no code change required.
To revert to local storage for debugging:
STORAGE_DRIVER=local
UPLOAD_FOLDER=storage/uploads

The Port/Adapter Pattern

Both drivers implement the same internal interface. Application code calls the storage port without knowing which driver is active:
Application layer
    └── calls StoragePort.save(folder, data, suffix)


Infrastructure layer resolves the driver:
    STORAGE_DRIVER=local  →  LocalStorage.save_bytes(...)
    STORAGE_DRIVER=s3     →  S3Storage.put_object(...)
This design means you can add a new driver (e.g. Google Cloud Storage, Cloudflare R2) by writing a new adapter class that satisfies the interface — the rest of the application does not change.

File Size Limits

MAX_CONTENT_LENGTH_MB controls the maximum allowed upload size, enforced at the Flask request layer before the file reaches the storage driver. The default is 10 MB. For larger delivery evidence videos, increase this value and ensure your reverse proxy (nginx, ALB) allows the corresponding body size.

Build docs developers (and LLMs) love