REST API v1

Cách gọi các endpoint TMS File — method, path, mẫu request/response và curl copy được. Đặt BASE_URL là origin dịch vụ (ví dụ http://localhost:3000).

Placeholder: $BASE_URL

  • GET/api/v1/health-checks

    Kiểm tra dịch vụ TMS File đang phản hồi.

    Response

    Mẫu
    {
      "message": "TMS-FILE is running"
    }

    cURL

    curl
    curl -sS "$BASE_URL/api/v1/health-checks"
  • POST/api/v1/files/uploadmultipart/form-data

    Upload một file: tạo metadata và ghi bytes theo binding lưu trữ đang hoạt động của tổ chức.

    Request

    Các field multipart/form-data bên dưới.

    Mẫu
    file                (binary, required)
    organization_id     (string, required)
    sub_system          (string, required)
    original_name       (string, optional — defaults to file name)
    mime_type           (string, optional)
    upload_temp         (boolean, optional — TEMP local-only file)

    Response

    Mẫu
    {
      "file_id": "01HZX…",
      "original_name": "sample.pdf",
      "mime_type": "application/pdf",
      "file_size": 12345,
      "ext": "pdf",
      "file_path": "1/oms/2026/09/26/…",
      "sync_status": "PENDING",
      "updated_at": "2026-09-26T10:00:00.000Z"
    }

    cURL

    curl
    curl -sS -X POST "$BASE_URL/api/v1/files/upload" \
      -F "file=@./sample.pdf" \
      -F "organization_id=1" \
      -F "sub_system=oms" \
      -F "original_name=sample.pdf" \
      -F "mime_type=application/pdf"
  • PUT/api/v1/files/uploadmultipart/form-data

    Thay đổi vòng đời theo file_id có sẵn: TEMP → THUMBNAIL, promote sẵn sàng, hoặc thay binary.

    Request

    multipart/form-data. make_as_thumbnail và make_as_ready loại trừ lẫn nhau.

    Mẫu
    file_id             (string, required)
    make_as_thumbnail   (boolean — TEMP → THUMBNAIL; no binary)
    make_as_ready       (boolean — promote without or with binary)
    file                (binary — replace blob when status allows)
    original_name / mime_type  (optional with file)
    
    Flags make_as_thumbnail and make_as_ready are mutually exclusive.

    Response

    Mẫu
    {
      "file_id": "01HZX…",
      "sync_status": "NONE",
      "updated_at": "2026-09-26T10:05:00.000Z"
    }

    cURL

    curl
    curl -sS -X PUT "$BASE_URL/api/v1/files/upload" \
      -F "file_id=01HZX…" \
      -F "make_as_ready=true"
  • POST/api/v1/files/batchmultipart/form-data

    Upload hàng loạt (multipart items[]). All-or-nothing: ghi DB trong transaction rồi ghi disk tuần tự.

    Request

    Field gốc kèm items[N].*.

    Mẫu
    organization_id     (string, required)
    sub_system          (string, required)
    items[N].file       (binary, required)
    items[N].original_name / mime_type  (optional)
    
    All-or-nothing: DB transaction then sequential disk writes.

    Response

    Mẫu
    [
      { "file_id": "…", "original_name": "a.pdf", "…": "…" },
      { "file_id": "…", "original_name": "b.png", "…": "…" }
    ]

    cURL

    curl
    curl -sS -X POST "$BASE_URL/api/v1/files/batch" \
      -F "organization_id=1" \
      -F "sub_system=oms" \
      -F "items[0].file=@./a.pdf" \
      -F "items[0].original_name=a.pdf" \
      -F "items[0].mime_type=application/pdf" \
      -F "items[1].file=@./b.png" \
      -F "items[1].original_name=b.png" \
      -F "items[1].mime_type=image/png"
  • GET/api/v1/files/{fileId}

    Đọc file: LOCAL stream bytes; CLOUD redirect tới presigned URL. Dùng disposition=attachment để tải xuống.

    Request

    Path và query tùy chọn bên dưới.

    Mẫu
    Path: fileId (ULID)
    Query: disposition=attachment (optional)

    Response

    Mẫu
    LOCAL  → 200 stream (file bytes)
    CLOUD  → 302 redirect to presigned URL

    cURL

    curl
    curl -sS -L -o out.bin "$BASE_URL/api/v1/files/{fileId}"
    # Download as attachment:
    curl -sS -L -o out.bin "$BASE_URL/api/v1/files/{fileId}?disposition=attachment"
  • GET/api/v1/files/{fileId}/{width}/{height}

    Gallery variant vuông: width === height và thuộc whitelist. Stream WebP từ cache hoặc resize on-the-fly.

    Request

    Quy tắc path bên dưới. Không vuông hoặc ngoài whitelist → 400.

    Mẫu
    Path: fileId, width, height
    Rules: width === height; size in whitelist: 200, 250, 300, 400, 500, 700, 1000
    Outside whitelist or non-square → 400
    Always streamed via tms-file (no R2 redirect)

    Response

    Mẫu
    200 image/webp (cached or resized on the fly)
    Passthrough original when max edge ≤ requested size

    cURL

    curl
    curl -sS -o thumb.webp "$BASE_URL/api/v1/files/{fileId}/500/500"
  • DELETE/api/v1/files/{fileId}

    Soft purge: đặt purge_status = SYSTEM_PURGE. Job nền xóa bytes trên storage rồi xóa bản ghi DB.

    Request

    Chỉ path parameter.

    Mẫu
    Path: fileId (ULID)

    Response

    Mẫu
    {
      "fileId": "01HZX…",
      "deleted": true,
      "storageLocation": "LOCAL",
      "purgePending": true
    }

    cURL

    curl
    curl -sS -X DELETE "$BASE_URL/api/v1/files/{fileId}"
  • GET/api/v1/storage-providers

    Danh sách storage provider đang hoạt động — mảng { providerCode, providerName }.

    Response

    Mẫu
    [
      { "providerCode": "R2", "providerName": "Cloudflare R2" }
    ]

    cURL

    curl
    curl -sS "$BASE_URL/api/v1/storage-providers"
  • POST/api/v1/organization-storage-bindings/createapplication/json

    Tạo binding lưu trữ file cho tổ chức (một binding hoạt động cho mỗi tổ chức).

    Request

    JSON body.

    Mẫu
    {
      "organizationId": 1,
      "organizationName": "Demo Org",
      "storageProvider": "R2",
      "syncEnabled": true
    }

    Response

    Mẫu
    {
      "id": 10,
      "organizationId": 1,
      "organizationName": "Demo Org",
      "isActive": true,
      "syncEnabled": true,
      "storageProvider": "R2",
      "effectiveFrom": "2026-09-26T10:00:00.000Z",
      "effectiveTo": null
    }

    cURL

    curl
    curl -sS -X POST "$BASE_URL/api/v1/organization-storage-bindings/create" \
      -H "Content-Type: application/json" \
      -d '{
        "organizationId": 1,
        "organizationName": "Demo Org",
        "storageProvider": "R2",
        "syncEnabled": true
      }'
  • PUT/api/v1/organization-storage-bindings/updateapplication/json

    Cập nhật binding đang hoạt động của tổ chức (kể cả isActive để ngưng hoặc mở lại).

    Request

    JSON body.

    Mẫu
    {
      "organizationId": 1,
      "organizationName": "Demo Org",
      "storageProvider": "R2",
      "syncEnabled": true,
      "isActive": true
    }

    Response

    Mẫu
    {
      "id": 10,
      "organizationId": 1,
      "isActive": true,
      "syncEnabled": true,
      "storageProvider": "R2"
    }

    cURL

    curl
    curl -sS -X PUT "$BASE_URL/api/v1/organization-storage-bindings/update" \
      -H "Content-Type: application/json" \
      -d '{
        "organizationId": 1,
        "organizationName": "Demo Org",
        "storageProvider": "R2",
        "syncEnabled": true,
        "isActive": true
      }'