Skip to content

Asset Management Architecture

This document describes the asset management and license system architecture in Diskover.

Overview

The asset system enables sellers to upload digital files to their organization's storage, link them to products, and allow buyers to download them after purchase. Access is controlled through entitlements created on purchase completion.

Key Components

License System

Organizations have licenses that define usage limits:

Field Description Default (Free Tier)
max_upload_size_mb Maximum single file upload size 100 MB
max_total_storage_mb Total storage quota 1000 MB (1 GB)
max_assets_count Maximum number of assets 100
max_products_count Maximum number of products 50
max_members_count Maximum organization members 5

Licenses are assigned to organizations via the org_licenses table. New organizations automatically receive the default "free" license.

Asset Storage

Assets are stored in S3-compatible storage (Railway Object Storage, AWS S3, MinIO, etc.).

Storage Key Format: {org_id}/{asset_id}/{filename}

Presigned URLs: - Upload URLs: 15-minute expiration - Download URLs: 1-hour expiration

Entitlements

Entitlements grant users access to specific assets: - Created automatically when a transaction completes - For digital products: expires_at is NULL (lifetime access) - For memberships: expires_at matches subscription period end


System Architecture Diagram

                              FRONTEND (React)
  +---------------------------------------------------------------------------+
  |  Dashboard UI       Product Pages        Asset Upload (S3)                |
  |  - Org Mgmt         - List/Detail        - Direct upload via              |
  |  - Asset Mgmt       - Checkout             presigned URL                  |
  |  - Purchases        - Downloads                                           |
  +----------+----------------+------------------------+----------------------+
             |                |                        |
             | HTTP + JWT     |                        | S3 Presigned URL
             v                v                        v
  +---------------------------------------------------------------------------+
  |                          BACKEND (Go + Chi)                               |
  |  +---------------------------------------------------------------------+  |
  |  |                    Clerk Auth Middleware                            |  |
  |  |                   (JWT validation, user sync)                       |  |
  |  +---------------------------------------------------------------------+  |
  |                                    |                                      |
  |  +-------------+ +-------------+ +-------------+ +-------------------+    |
  |  |User Handler | |Org Handler  | |Asset Handler| |Transaction Handler|    |
  |  +------+------+ +------+------+ +------+------+ +--------+----------+    |
  |         |               |               |                 |               |
  |  +------v------+ +------v------+ +------v------+ +--------v----------+    |
  |  |User Service | |Org Service  | |Asset Service| |Transaction Service|    |
  |  +------+------+ +------+------+ +------+------+ +--------+----------+    |
  |         |               |               |                 |               |
  |         |               |        +------v------+          |               |
  |         |               |        |Storage Svc  |----------+------------+  |
  |         |               |        |(S3 presign) |          |            |  |
  |         |               |        +-------------+          |            |  |
  |  +------v---------------v---------------+-----------------v---------+  |  |
  |  |                        Repository Layer                          |  |  |
  |  |  UserRepo | OrgRepo | AssetRepo | ProductRepo | TransactionRepo  |  |  |
  |  |                    | EntitlementRepo | SubscriptionRepo          |  |  |
  |  +----------------------------------------+-------------------------+  |  |
  +--------------------------------------------|----------------------------+  |
                                               |                               |
                                               v                               v
                           +------------------------+          +-------------------+
                           |      PostgreSQL        |          |   Railway S3      |
                           |  +--------+ +--------+ |          |  (Object Storage) |
                           |  | users  | |  orgs  | |          |                   |
                           |  |products| | assets | |          |  {org_id}/        |
                           |  |trans-  | |entitle-| |          |   {asset_id}/     |
                           |  |actions | |ments   | |          |    {filename}     |
                           |  +--------+ +--------+ |          +-------------------+
                           +------------------------+

Data Flow Diagrams

Purchase & Download Flow

PURCHASE FLOW

    Buyer                Frontend              Backend                 DB
      |                     |                     |                     |
      |  1. Add to cart     |                     |                     |
      |-------------------->|                     |                     |
      |                     |                     |                     |
      |  2. Checkout        |                     |                     |
      |-------------------->|                     |                     |
      |                     |  3. POST /transactions                    |
      |                     |-------------------->|                     |
      |                     |                     |  4. Create          |
      |                     |                     |     transaction     |
      |                     |                     |-------------------->|
      |                     |                     |                     |
      |                     |                     |  5. Get product     |
      |                     |                     |     assets          |
      |                     |                     |-------------------->|
      |                     |                     |                     |
      |                     |                     |  6. Create          |
      |                     |                     |     entitlements    |
      |                     |                     |-------------------->|
      |                     |                     |                     |
      |                     |  7. Success         |                     |
      |                     |<--------------------|                     |
      |  8. Show confirm    |                     |                     |
      |<--------------------|                     |                     |


DOWNLOAD FLOW

    Buyer                Frontend              Backend                 DB                    S3
      |                     |                     |                     |                     |
      |  1. View purchases  |                     |                     |                     |
      |-------------------->|                     |                     |                     |
      |                     |  2. GET /assets/{id}/download             |                     |
      |                     |-------------------->|                     |                     |
      |                     |                     |  3. Check           |                     |
      |                     |                     |     entitlement     |                     |
      |                     |                     |-------------------->|                     |
      |                     |                     |  4. Valid           |                     |
      |                     |                     |<--------------------|                     |
      |                     |                     |                     |                     |
      |                     |                     |  5. Generate presigned URL               |
      |                     |                     |------------------------------------------->|
      |                     |                     |  6. Presigned URL                        |
      |                     |                     |<-------------------------------------------|
      |                     |                     |                     |                     |
      |                     |  7. Download URL    |                     |                     |
      |                     |<--------------------|                     |                     |
      |                     |                                                                 |
      |                     |  8. Download file directly from S3                              |
      |                     |---------------------------------------------------------------->|
      |  9. File download   |                                                                 |
      |<--------------------|                                                                 |

Asset Upload Flow

UPLOAD FLOW

    Seller               Frontend              Backend                 DB                    S3
      |                     |                     |                     |                     |
      |  1. Select file     |                     |                     |                     |
      |-------------------->|                     |                     |                     |
      |                     |                     |                     |                     |
      |                     |  2. POST /orgs/{id}/assets                |                     |
      |                     |     (name, type, size)                    |                     |
      |                     |-------------------->|                     |                     |
      |                     |                     |                     |                     |
      |                     |                     |  3. Check license   |                     |
      |                     |                     |     limits          |                     |
      |                     |                     |-------------------->|                     |
      |                     |                     |                     |                     |
      |                     |                     |  4. Create asset    |                     |
      |                     |                     |     record          |                     |
      |                     |                     |-------------------->|                     |
      |                     |                     |                     |                     |
      |                     |                     |  5. Generate upload presigned URL         |
      |                     |                     |------------------------------------------->|
      |                     |                     |  6. Presigned URL                        |
      |                     |                     |<-------------------------------------------|
      |                     |                     |                     |                     |
      |                     |  7. Asset + URL     |                     |                     |
      |                     |<--------------------|                     |                     |
      |                     |                                                                 |
      |                     |  8. PUT file to S3 (direct upload)                              |
      |                     |---------------------------------------------------------------->|
      |                     |  9. Upload complete                                             |
      |                     |<----------------------------------------------------------------|
      |  10. Success        |                     |                     |                     |
      |<--------------------|                     |                     |                     |

Entity Relationship Diagram

+------------------+       +------------------+       +------------------+
|      users       |       |       orgs       |       |     products     |
+------------------+       +------------------+       +------------------+
| id               |   +-->| id               |<--+   | id               |
| clerk_id         |   |   | name             |   |   | org_id ----------+---+
| email            |   |   | slug             |   |   | name             |   |
| name             |   |   | is_personal      |   |   | type             |   |
| personal_org_id -+---+   +------------------+   |   | price            |   |
+------------------+              |               |   | subscription_days|   |
       |                          |               |   +------------------+   |
       |              +-----------+---------+     |          |               |
       |              |      org_members    |     |   +------+--------+      |
       |              +---------------------+     |   | product_assets |      |
       |              | org_id              |     |   +---------------+      |
       +------------->| user_id             |     |   | product_id    |      |
                      | role                |     |   | asset_id -----+---+  |
                      +---------------------+     |   +---------------+   |  |
                                                  |                       |  |
+------------------+       +------------------+   |                       |  |
|   transactions   |       |      assets      |   |                       |  |
+------------------+       +------------------+   |                       |  |
| id               |       | id               |<--+-----------------------+  |
| user_id ---------+--+    | org_id ----------+---+                          |
| product_id ------+--+----| name             |                              |
| amount           |  |    | storage_key      |<-----------------------------+
| status           |  |    | content_type     |
+------------------+  |    | size_bytes       |
       |              |    +------------------+
       |              |
+------+---------+    |    +------------------+    +------------------+
|  entitlements  |    |    |  subscriptions   |    |     licenses     |
+----------------+    |    +------------------+    +------------------+
| id             |    |    | id               |    | id               |<---------+
| user_id -------+----+    | user_id ---------+->+ | name             |          |
| asset_id       |         | product_id       |  | | max_upload_size  |          |
| product_id     |         | status           |  | | max_total_storage|          |
| transaction_id |         | period_start     |  | | max_assets       |          |
| expires_at     |         | period_end       |  | | max_products     |          |
+----------------+         +------------------+  | | max_members      |          |
                                                 | | monthly_fee      |          |
                                                 | | is_default       |          |
                                                 | +------------------+          |
                                                 |                               |
                                                 | +------------------+          |
                                                 | |   org_licenses   |          |
                                                 | +------------------+          |
                                                 | | org_id ----------+-> orgs   |
                                                 | | license_id ------+----------+
                                                 | | expires_at       |
                                                 | +------------------+

API Endpoint Reference

Asset Management

Method Endpoint Description
GET /orgs/{org_id}/assets List organization assets
POST /orgs/{org_id}/assets Create asset and get upload URL
GET /orgs/{org_id}/assets/{id} Get asset details
PATCH /orgs/{org_id}/assets/{id} Update asset metadata
DELETE /orgs/{org_id}/assets/{id} Delete asset
GET /orgs/{org_id}/assets/usage Get storage usage

Product-Asset Linking

Method Endpoint Description
GET /orgs/{org_id}/products/{id}/assets List product assets
POST /orgs/{org_id}/products/{id}/assets Add asset to product
DELETE /orgs/{org_id}/products/{id}/assets/{asset_id} Remove asset from product

Downloads

Method Endpoint Description
GET /assets/{id}/download Get download URL (validates entitlement)

Organization License

Method Endpoint Description
GET /orgs/{org_id}/license Get organization license info

Organization Role Permissions

Action Owner Admin Member Viewer
View org details Yes Yes Yes Yes
Upload assets Yes Yes Yes No
Delete own assets Yes Yes Yes No
Delete any asset Yes Yes No No
Create products Yes Yes No No
Edit/delete products Yes Yes No No
Link assets to products Yes Yes No No
Invite members Yes Yes No No
Change member roles Yes Yes (not owner) No No
Remove members Yes Yes (not owner) No No
Edit org settings Yes Yes No No
Delete org Yes No No No
Transfer ownership Yes No No No

S3 Storage Configuration

Environment Variables

# Railway Object Storage or S3-compatible provider
S3_ENDPOINT=https://<bucket>.railway.app
S3_REGION=us-east-1
S3_BUCKET=diskover-assets
S3_ACCESS_KEY_ID=your_access_key
S3_SECRET_ACCESS_KEY=your_secret_key
S3_USE_PATH_STYLE=true    # Required for Railway and MinIO

Storage Key Structure

{bucket}/
  {org_id}/
    {asset_id}/
      {original_filename}

Example: diskover-assets/550e8400-e29b-41d4-a716-446655440000/6ba7b810-9dad-11d1-80b4-00c04fd430c8/design-course.zip


License Tiers

Tier Upload Storage Assets Products Members Price
Free 100 MB 1 GB 100 50 5 $0/mo
Starter 500 MB 10 GB 500 100 10 $19/mo
Pro 2 GB 100 GB 2000 500 50 $49/mo
Enterprise 10 GB 1 TB Unlimited Unlimited Unlimited Contact

Note: Only the free tier is implemented. Paid tiers are for future billing integration.


File Upload Validation

Client-Side

  • Check file size against max_upload_size_bytes from usage endpoint
  • Validate content type (frontend can show appropriate icons)
  • Display upload progress during S3 direct upload

Server-Side

  • Verify size_bytes against license max_upload_size_mb
  • Check total storage usage against max_total_storage_mb
  • Verify asset count against max_assets_count
  • Reject uploads that exceed any limit with clear error messages