{
  "openapi": "3.0.3",
  "info": {
    "title": "TradeLoop DPP API",
    "version": "1.0.0",
    "description": "\nDigital Product Passport (DPP) API for ISO 20435 compliant DID documents.\n\n## Overview\n\nThis API provides two paths to create Digital Product Passports for physical assets:\n\n### Simple Path (CSV Upload)\nUpload a CSV file and let the system handle hash computation and DID registration automatically.\n\n### Advanced Path (Direct API)\nClient computes hashes and registers DIDs directly for full control over DPP data.\n\n## Authentication\n\nCurrently, the API is open for development purposes. Authentication will be added in future releases.\n\n## ISO 20435 Compliance\n\nAll DID documents created through this API comply with ISO 20435 standards for Digital Product Passports.\n      ",
    "contact": {
      "name": "TradeLoop API Support",
      "url": "https://tradeloop.io"
    },
    "license": {
      "name": "Proprietary"
    }
  },
  "servers": [
    {
      "url": "https://inventory-csv-agent.vercel.app",
      "description": "Production Server"
    },
    {
      "url": "http://localhost:3000",
      "description": "Development Server"
    }
  ],
  "tags": [
    {
      "name": "DID Management",
      "description": "Register, resolve, update, and deactivate DID documents"
    },
    {
      "name": "Hash Operations",
      "description": "Compute and verify hash trees for data integrity"
    },
    {
      "name": "CSV Processing",
      "description": "Upload and process CSV files for bulk DPP creation"
    },
    {
      "name": "Storage",
      "description": "File upload and storage operations"
    },
    {
      "name": "QA",
      "description": "Quality assurance and testing endpoints"
    }
  ],
  "components": {
    "schemas": {
      "SuccessResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "message": {
            "type": "string"
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": false
          },
          "error": {
            "type": "string"
          },
          "details": {
            "type": "string"
          }
        }
      },
      "PhysicalAssetIdentifiers": {
        "type": "object",
        "required": [
          "dataObjectType",
          "manufacturer",
          "partNumber",
          "serialNumber",
          "hashingAlgorithm"
        ],
        "properties": {
          "dataObjectType": {
            "type": "string",
            "example": "physicalAssetIdentifiers"
          },
          "manufacturer": {
            "type": "string",
            "example": "Dell"
          },
          "partNumber": {
            "type": "string",
            "example": "R640"
          },
          "serialNumber": {
            "type": "string",
            "example": "SN-12345678"
          },
          "hashingAlgorithm": {
            "type": "string",
            "example": "SHA-256"
          },
          "identifierSource": {
            "type": "string",
            "example": "manufacturer-label"
          }
        }
      },
      "HashTree": {
        "type": "object",
        "required": [
          "dataObjectType",
          "rootHash",
          "algorithm",
          "version",
          "individualHashes"
        ],
        "properties": {
          "dataObjectType": {
            "type": "string",
            "example": "hashTree"
          },
          "rootHash": {
            "type": "string",
            "example": "abc123..."
          },
          "algorithm": {
            "type": "string",
            "example": "SHA-256"
          },
          "version": {
            "type": "integer",
            "example": 1
          },
          "priorRootHash": {
            "type": "string",
            "nullable": true
          },
          "individualHashes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "DIDDocument": {
        "type": "object",
        "properties": {
          "@context": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              "https://www.w3.org/ns/did/v1"
            ]
          },
          "id": {
            "type": "string",
            "description": "The DID (hash only, no namespace prefix)",
            "example": "abc123def456..."
          },
          "usn": {
            "type": "string",
            "description": "Universal Serial Number"
          },
          "dataObjects": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "created": {
            "type": "string",
            "format": "date-time"
          },
          "updated": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "RegisterDIDRequest": {
        "type": "object",
        "required": [
          "dataObjects"
        ],
        "properties": {
          "did": {
            "type": "string",
            "description": "Optional: Server generates if not provided"
          },
          "usn": {
            "type": "string",
            "description": "Optional: Universal Serial Number"
          },
          "dataObjects": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "dataObjectType"
              ],
              "properties": {
                "dataObjectType": {
                  "type": "string"
                }
              }
            },
            "description": "Array of data objects including physicalAssetIdentifiers and optionally hashTree"
          }
        }
      },
      "UpdateDIDRequest": {
        "type": "object",
        "required": [
          "did",
          "dataObjects"
        ],
        "properties": {
          "did": {
            "type": "string",
            "description": "The DID to update"
          },
          "operation": {
            "type": "string",
            "enum": [
              "merge",
              "replace"
            ],
            "default": "merge"
          },
          "dataObjects": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Array of data objects including updated hashTree"
          }
        }
      },
      "ComputeHashTreeRequest": {
        "type": "object",
        "required": [
          "manufacturer",
          "partNumber",
          "serialNumber",
          "dataObjects"
        ],
        "properties": {
          "manufacturer": {
            "type": "string",
            "example": "Dell"
          },
          "partNumber": {
            "type": "string",
            "example": "R640"
          },
          "serialNumber": {
            "type": "string",
            "example": "SN-12345678"
          },
          "dataObjects": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "priorRootHash": {
            "type": "string",
            "nullable": true
          },
          "version": {
            "type": "integer",
            "default": 1
          },
          "hashingAlgorithm": {
            "type": "string",
            "default": "SHA-256"
          }
        }
      },
      "VerifyHashTreeRequest": {
        "type": "object",
        "required": [
          "hashTree",
          "dataObjects"
        ],
        "properties": {
          "hashTree": {
            "$ref": "#/components/schemas/HashTree"
          },
          "dataObjects": {
            "type": "array",
            "items": {
              "type": "object"
            }
          }
        }
      },
      "StagingStatusResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "message": {
            "type": "string"
          },
          "stagingId": {
            "type": "string",
            "format": "uuid"
          },
          "fileName": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "processing",
              "completed",
              "failed"
            ]
          },
          "processing": {
            "type": "object",
            "properties": {
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "completedAt": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "durationMs": {
                "type": "integer",
                "nullable": true
              }
            }
          },
          "results": {
            "type": "object",
            "properties": {
              "recordsProcessed": {
                "type": "integer",
                "nullable": true
              },
              "recordsSucceeded": {
                "type": "integer",
                "nullable": true
              },
              "recordsFailed": {
                "type": "integer",
                "nullable": true
              }
            }
          }
        }
      }
    }
  },
  "paths": {
    "/api/compute-hash-tree": {
      "post": {
        "summary": "Compute hash tree",
        "description": "Server-side endpoint for computing DID, USN, and hash tree.\nSimplifies integration for clients who don't want to implement crypto locally.\n\n**Returns:**\n- Generated DID from physical asset identifiers\n- Generated USN from DID\n- Complete hash tree with individual hashes and root hash\n",
        "tags": [
          "Hash Operations"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ComputeHashTreeRequest"
              },
              "example": {
                "manufacturer": "Dell",
                "partNumber": "R640",
                "serialNumber": "SN-12345678",
                "dataObjects": [
                  {
                    "dataObjectType": "physicalAssetIdentifiers",
                    "manufacturer": "Dell",
                    "partNumber": "R640",
                    "serialNumber": "SN-12345678",
                    "hashingAlgorithm": "SHA-256"
                  }
                ],
                "version": 1,
                "hashingAlgorithm": "SHA-256"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Hash tree computed successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "did": {
                      "type": "string",
                      "description": "Generated DID"
                    },
                    "usn": {
                      "type": "string",
                      "description": "Generated Universal Serial Number"
                    },
                    "hashTree": {
                      "$ref": "#/components/schemas/HashTree"
                    },
                    "metadata": {
                      "type": "object",
                      "properties": {
                        "algorithm": {
                          "type": "string"
                        },
                        "version": {
                          "type": "integer"
                        },
                        "dataObjectCount": {
                          "type": "integer"
                        },
                        "computed": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "500": {
            "description": "Internal server error"
          }
        }
      }
    },
    "/api/did/{did}": {
      "get": {
        "summary": "Resolve a DID",
        "description": "Retrieves the DID Document for a given DID identifier.\n\nReturns the complete DID document including all data objects,\nmetadata about the asset, and timestamps.\n",
        "tags": [
          "DID Management"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "did",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The DID to resolve (hash only, no namespace prefix)",
            "example": "abc123def456789..."
          }
        ],
        "responses": {
          "200": {
            "description": "DID Document found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "didDocument": {
                      "$ref": "#/components/schemas/DIDDocument"
                    },
                    "metadata": {
                      "type": "object",
                      "properties": {
                        "manufacturer": {
                          "type": "string"
                        },
                        "partNumber": {
                          "type": "string"
                        },
                        "serialNumber": {
                          "type": "string"
                        },
                        "hashTreeVersion": {
                          "type": "integer"
                        },
                        "resolvedAt": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid DID parameter"
          },
          "404": {
            "description": "DID not found"
          },
          "410": {
            "description": "DID has been deactivated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "string",
                      "example": "DID has been deactivated"
                    },
                    "did": {
                      "type": "string"
                    },
                    "deactivatedAt": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error"
          }
        }
      }
    },
    "/api/did/deactivate": {
      "post": {
        "summary": "Deactivate a DID",
        "description": "Deactivates a DID, making it inactive for future use.\n\n**Important:**\n- Per ISO 20435: No \"reason\" field is required\n- Soft delete (sets is_active = false)\n- History is preserved for audit trail\n- Deactivated DIDs return 410 Gone on resolve\n",
        "tags": [
          "DID Management"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "did"
                ],
                "properties": {
                  "did": {
                    "type": "string",
                    "description": "The DID to deactivate"
                  }
                }
              },
              "example": {
                "did": "abc123def456..."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "DID deactivated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string",
                      "example": "DID deactivated successfully"
                    },
                    "did": {
                      "type": "string"
                    },
                    "deactivatedAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "note": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error or DID already deactivated"
          },
          "404": {
            "description": "DID not found"
          },
          "500": {
            "description": "Internal server error"
          }
        }
      }
    },
    "/api/did/list": {
      "get": {
        "summary": "List DID documents",
        "description": "Lists all DID documents with optional filters for manufacturer,\nactive status, and pagination.\n",
        "tags": [
          "DID Management"
        ],
        "parameters": [
          {
            "in": "query",
            "name": "manufacturer",
            "schema": {
              "type": "string"
            },
            "description": "Filter by manufacturer name"
          },
          {
            "in": "query",
            "name": "isActive",
            "schema": {
              "type": "boolean"
            },
            "description": "Filter by active status (true/false)"
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer",
              "default": 50
            },
            "description": "Maximum number of results to return"
          },
          {
            "in": "query",
            "name": "offset",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Number of results to skip for pagination"
          }
        ],
        "responses": {
          "200": {
            "description": "List of DID documents",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "count": {
                      "type": "integer"
                    },
                    "didDocuments": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/DIDDocument"
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error"
          }
        }
      }
    },
    "/api/did/register": {
      "post": {
        "summary": "Register a new DID",
        "description": "Registers a new DID Document for a physical asset per ISO 20435.\n\n**Key Features:**\n- DID parameter is OPTIONAL (server generates if not provided)\n- Supports both JSON and CSV file uploads\n- Complete hash verification with logging\n- Batch registration support via CSV\n",
        "tags": [
          "DID Management"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RegisterDIDRequest"
              },
              "example": {
                "dataObjects": [
                  {
                    "dataObjectType": "physicalAssetIdentifiers",
                    "manufacturer": "Dell",
                    "partNumber": "R640",
                    "serialNumber": "SN-12345678",
                    "hashingAlgorithm": "SHA-256"
                  }
                ]
              }
            },
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "csv": {
                    "type": "string",
                    "format": "binary",
                    "description": "CSV file with asset data"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "DID(s) registered successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    },
                    "summary": {
                      "type": "object",
                      "properties": {
                        "total": {
                          "type": "integer"
                        },
                        "successful": {
                          "type": "integer"
                        },
                        "failed": {
                          "type": "integer"
                        }
                      }
                    },
                    "didDocuments": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/DIDDocument"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error or all registrations failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "415": {
            "description": "Unsupported content type"
          },
          "500": {
            "description": "Internal server error"
          }
        }
      }
    },
    "/api/did/update": {
      "post": {
        "summary": "Update a DID Document",
        "description": "Updates an existing DID Document with new data objects.\n\n**Client Requirements:**\n1. Retrieve current DID document\n2. Modify/add data objects\n3. Compute new individualHashes for ALL data objects\n4. Compute new rootHash including priorRootHash\n5. Increment version number\n6. Set priorRootHash to current rootHash\n\nThe server verifies that priorRootHash matches the current rootHash\nand that the version has been incremented.\n",
        "tags": [
          "DID Management"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateDIDRequest"
              },
              "example": {
                "did": "abc123def456...",
                "operation": "merge",
                "dataObjects": [
                  {
                    "dataObjectType": "physicalAssetIdentifiers",
                    "manufacturer": "Dell",
                    "partNumber": "R640",
                    "serialNumber": "SN-12345678",
                    "hashingAlgorithm": "SHA-256"
                  },
                  {
                    "dataObjectType": "hashTree",
                    "rootHash": "newRootHash...",
                    "priorRootHash": "previousRootHash...",
                    "version": 2,
                    "algorithm": "SHA-256",
                    "individualHashes": [
                      "hash1",
                      "hash2"
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "DID updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    },
                    "did": {
                      "type": "string"
                    },
                    "hashTreeVersion": {
                      "type": "integer"
                    },
                    "previousVersion": {
                      "type": "integer"
                    },
                    "rootHash": {
                      "type": "string"
                    },
                    "priorRootHash": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error, priorRootHash mismatch, or version not incremented"
          },
          "404": {
            "description": "DID not found"
          },
          "500": {
            "description": "Internal server error"
          }
        }
      }
    },
    "/api/process-and-upload": {
      "post": {
        "summary": "Process CSV and upload to database",
        "description": "Combines CSV processing and Supabase upload into one endpoint:\n1. Accepts a CSV file\n2. Transforms it to ISO 20435 format\n3. Uploads the data to Supabase inventory table\n\n**Required CSV columns:**\n- manufacturer\n- partNumber\n- serialNumber\n",
        "tags": [
          "CSV Processing"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "csv"
                ],
                "properties": {
                  "csv": {
                    "type": "string",
                    "format": "binary",
                    "description": "CSV file with asset data"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "CSV processed and uploaded successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    },
                    "summary": {
                      "type": "object",
                      "properties": {
                        "totalRows": {
                          "type": "integer"
                        },
                        "processed": {
                          "type": "integer"
                        },
                        "processingErrors": {
                          "type": "integer"
                        },
                        "uploaded": {
                          "type": "integer"
                        }
                      }
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid CSV file or validation errors"
          },
          "500": {
            "description": "Internal server error or upload failed"
          }
        }
      }
    },
    "/api/process-csv": {
      "post": {
        "summary": "Process CSV to ISO 20435 format",
        "description": "Transforms a CSV file into ISO 20435 compliant data objects.\nDoes not persist the data - returns the transformed results.\n\n**Required CSV columns:**\n- manufacturer\n- partNumber\n- serialNumber\n\n**Optional columns:**\n- did (if not provided, will be generated)\n- hashingAlgorithm (default: SHA-256)\n- Plus any ISO 20435 optional fields\n",
        "tags": [
          "CSV Processing"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "csv"
                ],
                "properties": {
                  "csv": {
                    "type": "string",
                    "format": "binary",
                    "description": "CSV file with asset data"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "CSV processed successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "summary": {
                      "type": "object",
                      "properties": {
                        "totalRows": {
                          "type": "integer"
                        },
                        "successful": {
                          "type": "integer"
                        },
                        "failed": {
                          "type": "integer"
                        }
                      }
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    },
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "rowIndex": {
                            "type": "integer"
                          },
                          "error": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid CSV file or all rows failed"
          },
          "500": {
            "description": "Internal server error"
          }
        }
      }
    },
    "/api/process-queue": {
      "post": {
        "summary": "Process pending staging records",
        "description": "Queue worker endpoint that processes pending staging records.\nCan be called manually or via cron job.\n\n**Processing:**\n- Fetches up to 10 pending records at a time\n- Updates status to 'processing' during work\n- Retries failed records up to max_retries\n- Records final status (completed/failed)\n",
        "tags": [
          "CSV Processing"
        ],
        "responses": {
          "200": {
            "description": "Queue processing completed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    },
                    "summary": {
                      "type": "object",
                      "properties": {
                        "processed": {
                          "type": "integer"
                        },
                        "succeeded": {
                          "type": "integer"
                        },
                        "failed": {
                          "type": "integer"
                        },
                        "retried": {
                          "type": "integer"
                        },
                        "duration_ms": {
                          "type": "integer"
                        }
                      }
                    },
                    "details": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Queue processing failed"
          }
        }
      }
    },
    "/api/qa/dpp": {
      "get": {
        "summary": "Get QA test information",
        "description": "Returns information about available QA tests for the DPP API.",
        "tags": [
          "QA"
        ],
        "responses": {
          "200": {
            "description": "QA test information",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "description": {
                      "type": "string"
                    },
                    "implementation": {
                      "type": "string"
                    },
                    "targetApi": {
                      "type": "string"
                    },
                    "endpoints": {
                      "type": "object"
                    },
                    "tests": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Run DPP QA tests",
        "description": "Runs comprehensive QA tests against the DPP API endpoints.\n\n**Tests include:**\n- Hash tree computation and verification\n- DID registration (single and batch)\n- DID resolution and deactivation\n- File uploads\n- Error handling\n",
        "tags": [
          "QA"
        ],
        "responses": {
          "200": {
            "description": "QA tests completed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "summary": {
                      "type": "object",
                      "properties": {
                        "total": {
                          "type": "integer"
                        },
                        "passed": {
                          "type": "integer"
                        },
                        "failed": {
                          "type": "integer"
                        },
                        "skipped": {
                          "type": "integer"
                        }
                      }
                    },
                    "tests": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    },
                    "devjockTask": {
                      "type": "string"
                    },
                    "duration": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "QA test execution failed"
          }
        }
      }
    },
    "/api/staging-status/{id}": {
      "get": {
        "summary": "Check staging record status",
        "description": "Check the processing status of an uploaded CSV file.\nReturns detailed information about processing state, results, and errors.\n",
        "tags": [
          "CSV Processing"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "The staging record ID (returned from upload-to-staging)"
          }
        ],
        "responses": {
          "200": {
            "description": "Staging status retrieved",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StagingStatusResponse"
                }
              }
            }
          },
          "404": {
            "description": "Staging record not found"
          },
          "500": {
            "description": "Internal server error"
          }
        }
      }
    },
    "/api/storage/upload": {
      "post": {
        "summary": "Upload file to storage",
        "description": "Uploads files to Supabase Storage bucket 'dpp-attachments'.\nFiles are organized by DID and support public/private access control.\n\n**Features:**\n- Files organized by DID\n- Unique filename generation to prevent collisions\n- Public URLs for easy access\n",
        "tags": [
          "Storage"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file",
                  "did"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "The file to upload"
                  },
                  "did": {
                    "type": "string",
                    "description": "The DID to organize the file under"
                  },
                  "isPublic": {
                    "type": "boolean",
                    "default": true,
                    "description": "Whether the file should be publicly accessible"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "File uploaded successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "url": {
                          "type": "string",
                          "format": "uri"
                        },
                        "path": {
                          "type": "string"
                        },
                        "metadata": {
                          "type": "object",
                          "properties": {
                            "filename": {
                              "type": "string"
                            },
                            "size": {
                              "type": "integer"
                            },
                            "mimeType": {
                              "type": "string"
                            },
                            "uploadedAt": {
                              "type": "string",
                              "format": "date-time"
                            },
                            "did": {
                              "type": "string"
                            },
                            "isPublic": {
                              "type": "boolean"
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing required parameters"
          },
          "500": {
            "description": "Upload failed"
          }
        }
      }
    },
    "/api/upload-to-staging": {
      "post": {
        "summary": "Upload CSV to staging for async processing",
        "description": "Uploads a CSV file to the staging table for asynchronous processing.\nReturns immediately without blocking on transformation.\n\n**Workflow:**\n1. Upload CSV file\n2. File is stored in staging_dpp_uploads table\n3. Background worker processes the file\n4. Check status via /api/staging-status/{id}\n",
        "tags": [
          "CSV Processing"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "csv"
                ],
                "properties": {
                  "csv": {
                    "type": "string",
                    "format": "binary",
                    "description": "CSV file with asset data"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "CSV uploaded and queued for processing",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    },
                    "stagingId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "fileName": {
                      "type": "string"
                    },
                    "rowCount": {
                      "type": "integer"
                    },
                    "status": {
                      "type": "string",
                      "example": "pending"
                    },
                    "statusUrl": {
                      "type": "string",
                      "example": "/api/staging-status/{id}"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid CSV file"
          },
          "500": {
            "description": "Internal server error"
          }
        }
      }
    },
    "/api/upload-to-supabase": {
      "post": {
        "summary": "Upload ISO 20435 data to inventory",
        "description": "Uploads ISO 20435 compliant data to the Supabase 'inventory' table.\nAccepts single objects or arrays of objects.\n\n**Required fields in physicalAssetIdentifiers:**\n- manufacturer\n- partNumber\n- serialNumber\n",
        "tags": [
          "Storage"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "object",
                    "description": "Single ISO 20435 data object"
                  },
                  {
                    "type": "array",
                    "items": {
                      "type": "object"
                    },
                    "description": "Array of ISO 20435 data objects"
                  }
                ]
              },
              "example": {
                "dataObjectId": "QmXyz...",
                "physicalAssetIdentifiers": {
                  "manufacturer": "Dell",
                  "partNumber": "R640",
                  "serialNumber": "SN-12345678"
                },
                "did": "abc123..."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Data uploaded successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    },
                    "summary": {
                      "type": "object",
                      "properties": {
                        "totalRecords": {
                          "type": "integer"
                        },
                        "uploaded": {
                          "type": "integer"
                        }
                      }
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation failed or missing required fields"
          },
          "500": {
            "description": "Upload to Supabase failed"
          }
        }
      }
    },
    "/api/verify-hash-tree": {
      "post": {
        "summary": "Verify hash tree",
        "description": "Server-side endpoint for verifying client-computed hash trees.\nValidates cryptographic integrity of data objects.\n\n**Verification checks:**\n- Individual hashes match computed values from data objects\n- Root hash matches computed value from individual hashes\n",
        "tags": [
          "Hash Operations"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VerifyHashTreeRequest"
              },
              "example": {
                "hashTree": {
                  "dataObjectType": "hashTree",
                  "rootHash": "abc123...",
                  "algorithm": "SHA-256",
                  "version": 1,
                  "individualHashes": [
                    "hash1",
                    "hash2"
                  ]
                },
                "dataObjects": [
                  {
                    "dataObjectType": "physicalAssetIdentifiers",
                    "manufacturer": "Dell",
                    "partNumber": "R640",
                    "serialNumber": "SN-12345678"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Hash tree verification passed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": true
                    },
                    "valid": {
                      "type": "boolean",
                      "example": true
                    },
                    "message": {
                      "type": "string"
                    },
                    "verification": {
                      "type": "object",
                      "properties": {
                        "individualHashesMatch": {
                          "type": "boolean"
                        },
                        "rootHashMatch": {
                          "type": "boolean"
                        },
                        "hashTreeVersion": {
                          "type": "integer"
                        },
                        "algorithm": {
                          "type": "string"
                        },
                        "dataObjectCount": {
                          "type": "integer"
                        }
                      }
                    },
                    "details": {
                      "type": "object",
                      "properties": {
                        "sent": {
                          "type": "object"
                        },
                        "computed": {
                          "type": "object"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error or verification failed"
          },
          "500": {
            "description": "Internal server error"
          }
        }
      }
    }
  }
}