{
  "openapi": "3.1.0",
  "info": {
    "title": "Budget Analyzer - Unified API",
    "version": "1.0",
    "description": "Unified API documentation for all Budget Analyzer microservices. This specification combines the Transaction Service, Currency Service, and Permission Service into a single document for client code generation.\n\nAll endpoints are served under the `/api` base path.",
    "contact": {
      "name": "Bleu Rubin",
      "email": "contact@budgetanalyzer.org"
    },
    "license": {
      "name": "MIT",
      "url": "https://opensource.org/licenses/MIT"
    }
  },
  "servers": [
    {
      "url": "https://demo.budgetanalyzer.org/api",
      "description": "Production environment"
    }
  ],
  "tags": [
    {
      "name": "Saved Views",
      "description": "Create and manage saved transaction views",
      "x-service": "transaction-service"
    },
    {
      "name": "Statement Formats",
      "description": "Manage statement format configurations for imports",
      "x-service": "transaction-service"
    },
    {
      "name": "Transactions",
      "description": "Import and manipulate transactions",
      "x-service": "transaction-service"
    },
    {
      "name": "Currency Series",
      "description": "Endpoints for querying, creating, and updating currency series",
      "x-service": "currency-service"
    },
    {
      "name": "Exchange Rates",
      "description": "Endpoints for querying and importing exchange rates",
      "x-service": "currency-service"
    },
    {
      "name": "User Administration",
      "description": "User administration operations",
      "x-service": "permission-service"
    }
  ],
  "paths": {
    "/v1/views/{id}": {
      "get": {
        "tags": [
          "Saved Views"
        ],
        "summary": "Get a saved view",
        "description": "Gets a saved view by ID",
        "operationId": "getView",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SavedViewResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "NOT_FOUND",
                  "message": "Not Found"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INTERNAL_ERROR",
                  "message": "Internal Server Error"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "SERVICE_UNAVAILABLE",
                  "message": "Service Unavailable"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "Saved Views"
        ],
        "summary": "Update a saved view",
        "description": "Updates a saved view's name or criteria",
        "operationId": "updateView",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSavedViewRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SavedViewResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "NOT_FOUND",
                  "message": "Not Found"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INVALID_REQUEST",
                  "message": "Bad Request"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INTERNAL_ERROR",
                  "message": "Internal Server Error"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "SERVICE_UNAVAILABLE",
                  "message": "Service Unavailable"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Saved Views"
        ],
        "summary": "Delete a saved view",
        "description": "Deletes a saved view",
        "operationId": "deleteView",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "NOT_FOUND",
                  "message": "Not Found"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INTERNAL_ERROR",
                  "message": "Internal Server Error"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "SERVICE_UNAVAILABLE",
                  "message": "Service Unavailable"
                }
              }
            }
          }
        }
      }
    },
    "/v1/statement-formats/{formatKey}": {
      "get": {
        "tags": [
          "Statement Formats"
        ],
        "summary": "Get statement format details",
        "description": "Returns details of a specific statement format by its format key.",
        "operationId": "getFormat",
        "parameters": [
          {
            "name": "formatKey",
            "in": "path",
            "description": "Unique format identifier",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "capital-one"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StatementFormatResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "NOT_FOUND",
                  "message": "Not Found"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INTERNAL_ERROR",
                  "message": "Internal Server Error"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "SERVICE_UNAVAILABLE",
                  "message": "Service Unavailable"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "Statement Formats"
        ],
        "summary": "Update a statement format",
        "description": "Updates an existing statement format. Only provided fields will be updated. The format key and format type cannot be changed after creation.",
        "operationId": "updateFormat",
        "parameters": [
          {
            "name": "formatKey",
            "in": "path",
            "description": "Unique format identifier",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "capital-one"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateStatementFormatRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StatementFormatResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "NOT_FOUND",
                  "message": "Not Found"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INVALID_REQUEST",
                  "message": "Bad Request"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INTERNAL_ERROR",
                  "message": "Internal Server Error"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "SERVICE_UNAVAILABLE",
                  "message": "Service Unavailable"
                }
              }
            }
          }
        }
      }
    },
    "/v1/views": {
      "get": {
        "tags": [
          "Saved Views"
        ],
        "summary": "List saved views",
        "description": "Gets all saved views for the current user",
        "operationId": "listViews",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/SavedViewResponse"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INTERNAL_ERROR",
                  "message": "Internal Server Error"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "SERVICE_UNAVAILABLE",
                  "message": "Service Unavailable"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Saved Views"
        ],
        "summary": "Create a saved view",
        "description": "Creates a new saved view for the current user",
        "operationId": "createView",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSavedViewRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SavedViewResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INVALID_REQUEST",
                  "message": "Bad Request"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INTERNAL_ERROR",
                  "message": "Internal Server Error"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "SERVICE_UNAVAILABLE",
                  "message": "Service Unavailable"
                }
              }
            }
          }
        }
      }
    },
    "/v1/views/{id}/pin/{txnId}": {
      "post": {
        "tags": [
          "Saved Views"
        ],
        "summary": "Pin a transaction",
        "description": "Pins a transaction to the view",
        "operationId": "pinTransaction",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "txnId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SavedViewResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INVALID_REQUEST",
                  "message": "Bad Request"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INTERNAL_ERROR",
                  "message": "Internal Server Error"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "SERVICE_UNAVAILABLE",
                  "message": "Service Unavailable"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Saved Views"
        ],
        "summary": "Unpin a transaction",
        "description": "Removes a pin from the view",
        "operationId": "unpinTransaction",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "txnId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SavedViewResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "NOT_FOUND",
                  "message": "Not Found"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INTERNAL_ERROR",
                  "message": "Internal Server Error"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "SERVICE_UNAVAILABLE",
                  "message": "Service Unavailable"
                }
              }
            }
          }
        }
      }
    },
    "/v1/views/{id}/exclude/{txnId}": {
      "post": {
        "tags": [
          "Saved Views"
        ],
        "summary": "Exclude a transaction",
        "description": "Excludes a transaction from the view",
        "operationId": "excludeTransaction",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "txnId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SavedViewResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INVALID_REQUEST",
                  "message": "Bad Request"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INTERNAL_ERROR",
                  "message": "Internal Server Error"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "SERVICE_UNAVAILABLE",
                  "message": "Service Unavailable"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Saved Views"
        ],
        "summary": "Remove exclusion",
        "description": "Removes an exclusion, allowing the transaction to appear if it matches criteria",
        "operationId": "unexcludeTransaction",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "txnId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SavedViewResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "NOT_FOUND",
                  "message": "Not Found"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INTERNAL_ERROR",
                  "message": "Internal Server Error"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "SERVICE_UNAVAILABLE",
                  "message": "Service Unavailable"
                }
              }
            }
          }
        }
      }
    },
    "/v1/transactions/preview": {
      "post": {
        "tags": [
          "Transactions"
        ],
        "summary": "Preview transactions from a file before import",
        "description": "Parses a CSV or PDF file and returns the extracted transactions for review and editing before batch import. No data is persisted. The format parameter is required and determines which parser to use. The response includes any parsing warnings.",
        "operationId": "previewTransactions",
        "parameters": [
          {
            "name": "format",
            "in": "query",
            "description": "Format key (e.g., 'capital-one-yearly' for PDF, 'capital-one' for CSV). Use GET /v1/statement-formats to list available formats.",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "capital-one-yearly"
          },
          {
            "name": "accountId",
            "in": "query",
            "description": "Account ID to pre-fill for all transactions",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "checking-12345"
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "CSV or PDF file to preview"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PreviewResponse"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "examples": {
                  "Format Not Supported": {
                    "summary": "Invalid format parameter",
                    "description": "Format Not Supported",
                    "value": {
                      "type": "APPLICATION_ERROR",
                      "message": "Format not supported: fake-bank",
                      "code": "FORMAT_NOT_SUPPORTED"
                    }
                  },
                  "Parsing Error": {
                    "summary": "Missing required column",
                    "description": "Parsing Error",
                    "value": {
                      "type": "APPLICATION_ERROR",
                      "message": "Missing value for required column 'Description' at line 1",
                      "code": "CSV_PARSING_ERROR"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INVALID_REQUEST",
                  "message": "Bad Request"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INTERNAL_ERROR",
                  "message": "Internal Server Error"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "SERVICE_UNAVAILABLE",
                  "message": "Service Unavailable"
                }
              }
            }
          }
        }
      }
    },
    "/v1/transactions/bulk-delete": {
      "post": {
        "tags": [
          "Transactions"
        ],
        "summary": "Bulk delete transactions",
        "description": "Soft-deletes multiple transactions in a single operation. Returns the count of successfully deleted transactions and any IDs that were not found or already deleted.",
        "operationId": "bulkDeleteTransactions",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkDeleteRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Some transactions not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BulkDeleteResponse"
                },
                "examples": {
                  "Partial success": {
                    "summary": "Some IDs not found",
                    "description": "Partial success",
                    "value": {
                      "deletedCount": 2,
                      "notFoundIds": [
                        999,
                        1000
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INVALID_REQUEST",
                  "message": "Bad Request"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INTERNAL_ERROR",
                  "message": "Internal Server Error"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "SERVICE_UNAVAILABLE",
                  "message": "Service Unavailable"
                }
              }
            }
          }
        }
      }
    },
    "/v1/transactions/batch": {
      "post": {
        "tags": [
          "Transactions"
        ],
        "summary": "Import a batch of transactions",
        "description": "Imports transactions from a batch request (typically from the preview endpoint after user edits). Validates all transactions upfront and rejects the entire batch if any fail. Duplicates (matching date + amount + description) are skipped.",
        "operationId": "batchImportTransactions",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BatchImportRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchImportResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INVALID_REQUEST",
                  "message": "Bad Request"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INTERNAL_ERROR",
                  "message": "Internal Server Error"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "SERVICE_UNAVAILABLE",
                  "message": "Service Unavailable"
                }
              }
            }
          }
        }
      }
    },
    "/v1/statement-formats": {
      "get": {
        "tags": [
          "Statement Formats"
        ],
        "summary": "List all statement formats",
        "description": "Returns all configured statement formats (both enabled and disabled).",
        "operationId": "listFormats",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/StatementFormatResponse"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INTERNAL_ERROR",
                  "message": "Internal Server Error"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "SERVICE_UNAVAILABLE",
                  "message": "Service Unavailable"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Statement Formats"
        ],
        "summary": "Create a new statement format",
        "description": "Creates a new statement format configuration. For CSV formats, the column header fields (dateHeader, descriptionHeader, creditHeader) are required.",
        "operationId": "createFormat",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateStatementFormatRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StatementFormatResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INVALID_REQUEST",
                  "message": "Bad Request"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "examples": {
                  "Duplicate Format Key": {
                    "summary": "Format key already exists",
                    "description": "Duplicate Format Key",
                    "value": {
                      "type": "APPLICATION_ERROR",
                      "message": "Format key already exists: capital-one",
                      "code": "FORMAT_KEY_ALREADY_EXISTS"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INTERNAL_ERROR",
                  "message": "Internal Server Error"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "SERVICE_UNAVAILABLE",
                  "message": "Service Unavailable"
                }
              }
            }
          }
        }
      }
    },
    "/v1/transactions/{id}": {
      "get": {
        "tags": [
          "Transactions"
        ],
        "summary": "Get transaction",
        "description": "Get transaction by id",
        "operationId": "getTransaction",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "NOT_FOUND",
                  "message": "Not Found"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INTERNAL_ERROR",
                  "message": "Internal Server Error"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "SERVICE_UNAVAILABLE",
                  "message": "Service Unavailable"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Transactions"
        ],
        "summary": "Delete transaction",
        "description": "Delete transaction by id",
        "operationId": "deleteTransaction",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "NOT_FOUND",
                  "message": "Not Found"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INTERNAL_ERROR",
                  "message": "Internal Server Error"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "SERVICE_UNAVAILABLE",
                  "message": "Service Unavailable"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Transactions"
        ],
        "summary": "Update transaction",
        "description": "Updates mutable fields (description and accountId) of a transaction. All other fields are immutable to preserve financial data integrity.",
        "operationId": "updateTransaction",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransactionUpdateRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "NOT_FOUND",
                  "message": "Not Found"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INVALID_REQUEST",
                  "message": "Bad Request"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INTERNAL_ERROR",
                  "message": "Internal Server Error"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "SERVICE_UNAVAILABLE",
                  "message": "Service Unavailable"
                }
              }
            }
          }
        }
      }
    },
    "/v1/views/{id}/transactions": {
      "get": {
        "tags": [
          "Saved Views"
        ],
        "summary": "Get view transaction IDs",
        "description": "Gets IDs of active transactions in this view, grouped by membership type (matched, pinned, excluded). Soft-deleted transactions are excluded.",
        "operationId": "getViewTransactions",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ViewMembershipResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "NOT_FOUND",
                  "message": "Not Found"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INTERNAL_ERROR",
                  "message": "Internal Server Error"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "SERVICE_UNAVAILABLE",
                  "message": "Service Unavailable"
                }
              }
            }
          }
        }
      }
    },
    "/v1/transactions": {
      "get": {
        "tags": [
          "Transactions"
        ],
        "summary": "Get transactions",
        "description": "Get all transactions",
        "operationId": "getTransactions",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TransactionResponse"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INTERNAL_ERROR",
                  "message": "Internal Server Error"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "SERVICE_UNAVAILABLE",
                  "message": "Service Unavailable"
                }
              }
            }
          }
        }
      }
    },
    "/v1/transactions/search": {
      "get": {
        "tags": [
          "Transactions"
        ],
        "summary": "Search transactions across users",
        "operationId": "searchTransactions",
        "parameters": [
          {
            "name": "id",
            "in": "query",
            "description": "Unique identifier for the transaction",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "description": "Unique identifier for the transaction",
              "example": 1
            },
            "example": 1
          },
          {
            "name": "ownerId",
            "in": "query",
            "description": "ID of the user who owns the transaction. Only effective on admin endpoints; ignored on user-scoped endpoints where the authenticated user is always applied.",
            "required": false,
            "schema": {
              "type": "string",
              "description": "ID of the user who owns the transaction. Only effective on admin endpoints; ignored on user-scoped endpoints where the authenticated user is always applied.",
              "example": "usr_test123"
            },
            "example": "usr_test123"
          },
          {
            "name": "accountId",
            "in": "query",
            "description": "Identifier for the account associated with the transaction",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Identifier for the account associated with the transaction",
              "example": "checking-3223"
            },
            "example": "checking-3223"
          },
          {
            "name": "bankName",
            "in": "query",
            "description": "Name of the bank where the transaction occurred",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Name of the bank where the transaction occurred",
              "example": "Capital One"
            },
            "example": "Capital One"
          },
          {
            "name": "dateFrom",
            "in": "query",
            "description": "Start date for transaction date range",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "Start date for transaction date range",
              "example": "2025-10-01"
            },
            "example": "2025-10-01"
          },
          {
            "name": "dateTo",
            "in": "query",
            "description": "End date for transaction date range",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "End date for transaction date range",
              "example": "2025-10-14"
            },
            "example": "2025-10-14"
          },
          {
            "name": "currencyIsoCode",
            "in": "query",
            "description": "ISO currency code for the transaction",
            "required": false,
            "schema": {
              "type": "string",
              "description": "ISO currency code for the transaction",
              "example": "USD"
            },
            "example": "USD"
          },
          {
            "name": "minAmount",
            "in": "query",
            "description": "Minimum transaction amount",
            "required": false,
            "schema": {
              "type": "number",
              "description": "Minimum transaction amount",
              "example": 10.0
            },
            "example": 10.0
          },
          {
            "name": "maxAmount",
            "in": "query",
            "description": "Maximum transaction amount",
            "required": false,
            "schema": {
              "type": "number",
              "description": "Maximum transaction amount",
              "example": 500.0
            },
            "example": 500.0
          },
          {
            "name": "type",
            "in": "query",
            "description": "Type of the transaction",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Type of the transaction",
              "enum": [
                "CREDIT",
                "DEBIT",
                "CREDIT",
                "DEBIT"
              ],
              "example": "DEBIT"
            },
            "example": "DEBIT"
          },
          {
            "name": "description",
            "in": "query",
            "description": "Text to match in the transaction description",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Text to match in the transaction description",
              "example": "Grocery"
            },
            "example": "Grocery"
          },
          {
            "name": "createdAfter",
            "in": "query",
            "description": "Start of creation timestamp range",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Start of creation timestamp range",
              "example": "2025-10-14T00:00:00Z"
            },
            "example": "2025-10-14T00:00:00Z"
          },
          {
            "name": "createdBefore",
            "in": "query",
            "description": "End of creation timestamp range",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "End of creation timestamp range",
              "example": "2025-10-15T00:00:00Z"
            },
            "example": "2025-10-15T00:00:00Z"
          },
          {
            "name": "updatedAfter",
            "in": "query",
            "description": "Start of last update timestamp range",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Start of last update timestamp range",
              "example": "2025-10-14T00:00:00Z"
            },
            "example": "2025-10-14T00:00:00Z"
          },
          {
            "name": "updatedBefore",
            "in": "query",
            "description": "End of last update timestamp range",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "End of last update timestamp range",
              "example": "2025-10-15T00:00:00Z"
            },
            "example": "2025-10-15T00:00:00Z"
          },
          {
            "name": "page",
            "in": "query",
            "description": "Zero-based page index (0..N)",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            }
          },
          {
            "name": "size",
            "in": "query",
            "description": "The size of the page to be returned",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1
            }
          },
          {
            "name": "sort",
            "in": "query",
            "description": "Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported.",
            "required": false,
            "schema": {
              "type": "array",
              "default": [
                "date,DESC",
                "id,DESC"
              ],
              "items": {
                "type": "string"
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Transactions retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PagedResponseTransactionResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "examples": {
                  "Invalid Sort Field": {
                    "summary": "Unsupported sort field requested",
                    "description": "Invalid Sort Field",
                    "value": {
                      "type": "INVALID_REQUEST",
                      "message": "Unsupported sort field: invalid. Allowed sort fields: id, ownerId, accountId, bankName, date, currencyIsoCode, amount, type, description, createdAt, updatedAt"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INTERNAL_ERROR",
                  "message": "Internal Server Error"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "SERVICE_UNAVAILABLE",
                  "message": "Service Unavailable"
                }
              }
            }
          }
        }
      }
    },
    "/v1/transactions/search/count": {
      "get": {
        "tags": [
          "Transactions"
        ],
        "summary": "Count transactions across users",
        "operationId": "countTransactionsAcrossUsers",
        "parameters": [
          {
            "name": "id",
            "in": "query",
            "description": "Unique identifier for the transaction",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int64",
              "description": "Unique identifier for the transaction",
              "example": 1
            },
            "example": 1
          },
          {
            "name": "ownerId",
            "in": "query",
            "description": "ID of the user who owns the transaction. Only effective on admin endpoints; ignored on user-scoped endpoints where the authenticated user is always applied.",
            "required": false,
            "schema": {
              "type": "string",
              "description": "ID of the user who owns the transaction. Only effective on admin endpoints; ignored on user-scoped endpoints where the authenticated user is always applied.",
              "example": "usr_test123"
            },
            "example": "usr_test123"
          },
          {
            "name": "accountId",
            "in": "query",
            "description": "Identifier for the account associated with the transaction",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Identifier for the account associated with the transaction",
              "example": "checking-3223"
            },
            "example": "checking-3223"
          },
          {
            "name": "bankName",
            "in": "query",
            "description": "Name of the bank where the transaction occurred",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Name of the bank where the transaction occurred",
              "example": "Capital One"
            },
            "example": "Capital One"
          },
          {
            "name": "dateFrom",
            "in": "query",
            "description": "Start date for transaction date range",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "Start date for transaction date range",
              "example": "2025-10-01"
            },
            "example": "2025-10-01"
          },
          {
            "name": "dateTo",
            "in": "query",
            "description": "End date for transaction date range",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "End date for transaction date range",
              "example": "2025-10-14"
            },
            "example": "2025-10-14"
          },
          {
            "name": "currencyIsoCode",
            "in": "query",
            "description": "ISO currency code for the transaction",
            "required": false,
            "schema": {
              "type": "string",
              "description": "ISO currency code for the transaction",
              "example": "USD"
            },
            "example": "USD"
          },
          {
            "name": "minAmount",
            "in": "query",
            "description": "Minimum transaction amount",
            "required": false,
            "schema": {
              "type": "number",
              "description": "Minimum transaction amount",
              "example": 10.0
            },
            "example": 10.0
          },
          {
            "name": "maxAmount",
            "in": "query",
            "description": "Maximum transaction amount",
            "required": false,
            "schema": {
              "type": "number",
              "description": "Maximum transaction amount",
              "example": 500.0
            },
            "example": 500.0
          },
          {
            "name": "type",
            "in": "query",
            "description": "Type of the transaction",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Type of the transaction",
              "enum": [
                "CREDIT",
                "DEBIT",
                "CREDIT",
                "DEBIT"
              ],
              "example": "DEBIT"
            },
            "example": "DEBIT"
          },
          {
            "name": "description",
            "in": "query",
            "description": "Text to match in the transaction description",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Text to match in the transaction description",
              "example": "Grocery"
            },
            "example": "Grocery"
          },
          {
            "name": "createdAfter",
            "in": "query",
            "description": "Start of creation timestamp range",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Start of creation timestamp range",
              "example": "2025-10-14T00:00:00Z"
            },
            "example": "2025-10-14T00:00:00Z"
          },
          {
            "name": "createdBefore",
            "in": "query",
            "description": "End of creation timestamp range",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "End of creation timestamp range",
              "example": "2025-10-15T00:00:00Z"
            },
            "example": "2025-10-15T00:00:00Z"
          },
          {
            "name": "updatedAfter",
            "in": "query",
            "description": "Start of last update timestamp range",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Start of last update timestamp range",
              "example": "2025-10-14T00:00:00Z"
            },
            "example": "2025-10-14T00:00:00Z"
          },
          {
            "name": "updatedBefore",
            "in": "query",
            "description": "End of last update timestamp range",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "End of last update timestamp range",
              "example": "2025-10-15T00:00:00Z"
            },
            "example": "2025-10-15T00:00:00Z"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "integer",
                  "format": "int64"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INTERNAL_ERROR",
                  "message": "Internal Server Error"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "SERVICE_UNAVAILABLE",
                  "message": "Service Unavailable"
                }
              }
            }
          }
        }
      }
    },
    "/v1/transactions/count": {
      "get": {
        "tags": [
          "Transactions"
        ],
        "summary": "Count transactions",
        "description": "Returns the count of active transactions owned by the requesting user and matching the given filter criteria.",
        "operationId": "countTransactions",
        "parameters": [
          {
            "name": "filter",
            "in": "query",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/TransactionFilter"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "integer",
                  "format": "int64"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INTERNAL_ERROR",
                  "message": "Internal Server Error"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "SERVICE_UNAVAILABLE",
                  "message": "Service Unavailable"
                }
              }
            }
          }
        }
      }
    },
    "/v1/currencies/{id}": {
      "get": {
        "tags": [
          "Currency Series"
        ],
        "summary": "Get currency series by ID",
        "description": "Retrieve a currency series by its unique identifier",
        "operationId": "getById",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Currency series retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CurrencySeriesResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "NOT_FOUND",
                  "message": "Not Found"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INTERNAL_ERROR",
                  "message": "Internal Server Error"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "SERVICE_UNAVAILABLE",
                  "message": "Service Unavailable"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "Currency Series"
        ],
        "summary": "Update currency series",
        "description": "Update an existing currency series (currency code and provider series ID are immutable, only enabled status can be changed)",
        "operationId": "update",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CurrencySeriesUpdateRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Currency series updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CurrencySeriesResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INVALID_REQUEST",
                  "message": "Bad Request"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "NOT_FOUND",
                  "message": "Not Found"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INTERNAL_ERROR",
                  "message": "Internal Server Error"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "SERVICE_UNAVAILABLE",
                  "message": "Service Unavailable"
                }
              }
            }
          }
        }
      }
    },
    "/v1/exchange-rates/import": {
      "post": {
        "tags": [
          "Exchange Rates"
        ],
        "summary": "Import latest available rates from FRED",
        "description": "Retrieve latest un-imported exchange rates from FRED for all enabled currencies - manually triggers daily cron job",
        "operationId": "importLatestExchangeRates",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ExchangeRateImportResultResponse"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INVALID_REQUEST",
                  "message": "Bad Request"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INTERNAL_ERROR",
                  "message": "Internal Server Error"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "SERVICE_UNAVAILABLE",
                  "message": "Service Unavailable"
                }
              }
            }
          }
        }
      }
    },
    "/v1/currencies": {
      "get": {
        "tags": [
          "Currency Series"
        ],
        "summary": "Get all currency series",
        "description": "Retrieve all currency series, optionally filtered by enabled status",
        "operationId": "getAll",
        "parameters": [
          {
            "name": "enabledOnly",
            "in": "query",
            "description": "Filter by enabled status (true = enabled only, false = all)",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CurrencySeriesResponse"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INTERNAL_ERROR",
                  "message": "Internal Server Error"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "SERVICE_UNAVAILABLE",
                  "message": "Service Unavailable"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Currency Series"
        ],
        "summary": "Create a new currency series",
        "description": "Create a new currency series. This endpoint is typically used when FRED adds support for new currency pairs. The 23 commonly-used currencies are already pre-populated and can be enabled via the PUT endpoint.",
        "operationId": "create",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CurrencySeriesCreateRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Currency series created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CurrencySeriesResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INVALID_REQUEST",
                  "message": "Bad Request"
                }
              }
            }
          },
          "422": {
            "description": "Business validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "examples": {
                  "Duplicate Currency Code": {
                    "summary": "Currency code already exists",
                    "description": "Duplicate Currency Code",
                    "value": {
                      "type": "APPLICATION_ERROR",
                      "message": "Currency code 'EUR' already exists",
                      "code": "DUPLICATE_CURRENCY_CODE"
                    }
                  },
                  "Invalid ISO 4217 Code": {
                    "summary": "Currency code is not a valid ISO 4217 code",
                    "description": "Invalid ISO 4217 Code",
                    "value": {
                      "type": "APPLICATION_ERROR",
                      "message": "Invalid ISO 4217 currency code: XXX",
                      "code": "INVALID_ISO_4217_CODE"
                    }
                  },
                  "Invalid Provider Series ID": {
                    "summary": "Provider series ID does not exist in FRED",
                    "description": "Invalid Provider Series ID",
                    "value": {
                      "type": "APPLICATION_ERROR",
                      "message": "Provider series ID 'INVALID_SERIES' does not exist in the external provider",
                      "code": "INVALID_PROVIDER_SERIES_ID"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INTERNAL_ERROR",
                  "message": "Internal Server Error"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "SERVICE_UNAVAILABLE",
                  "message": "Service Unavailable"
                }
              }
            }
          }
        }
      }
    },
    "/v1/exchange-rates": {
      "get": {
        "tags": [
          "Exchange Rates"
        ],
        "summary": "Get exchange rates",
        "description": "Get exchange rates for converting USD to the target currency",
        "operationId": "getExchangeRates",
        "parameters": [
          {
            "name": "startDate",
            "in": "query",
            "description": "Start date for exchange rates in ISO format",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "example": "2024-01-01"
          },
          {
            "name": "endDate",
            "in": "query",
            "description": "End date for exchange rates in ISO format",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "example": "2024-12-31"
          },
          {
            "name": "targetCurrency",
            "in": "query",
            "description": "Target currency of exchange rate",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "THB"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ExchangeRateResponse"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ExchangeRateResponse"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Business validation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "examples": {
                  "No Exchange Rate Data Available": {
                    "summary": "No exchange rate data exists for the requested currency",
                    "description": "No Exchange Rate Data Available",
                    "value": {
                      "type": "APPLICATION_ERROR",
                      "message": "No exchange rate data available for currency: EUR",
                      "code": "NO_EXCHANGE_RATE_DATA_AVAILABLE"
                    }
                  },
                  "Start Date Out of Range": {
                    "summary": "Start date is before the earliest available data",
                    "description": "Start Date Out of Range",
                    "value": {
                      "type": "APPLICATION_ERROR",
                      "message": "Exchange rates for THB not available before 2000-01-03",
                      "code": "START_DATE_OUT_OF_RANGE"
                    }
                  },
                  "Currency Not Enabled": {
                    "summary": "Currency not enabled for exchange rate data",
                    "description": "Currency Not Enabled",
                    "value": {
                      "type": "APPLICATION_ERROR",
                      "message": "Currency is not enabled: EUR",
                      "code": "CURRENCY_NOT_ENABLED"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INTERNAL_ERROR",
                  "message": "Internal Server Error"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "SERVICE_UNAVAILABLE",
                  "message": "Service Unavailable"
                }
              }
            }
          }
        }
      }
    },
    "/v1/users/{id}/deactivate": {
      "post": {
        "tags": [
          "User Administration"
        ],
        "summary": "Deactivate a user",
        "description": "Marks a user as deactivated, removes all role assignments, and revokes active sessions. Idempotent — deactivating an already-deactivated user returns 200.",
        "operationId": "deactivateUser",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "User ID",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "usr_abc123"
          }
        ],
        "responses": {
          "200": {
            "description": "User deactivated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserDeactivationResponse"
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "User not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "SERVICE_UNAVAILABLE",
                  "message": "Service Unavailable"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INVALID_REQUEST",
                  "message": "Bad Request"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INTERNAL_ERROR",
                  "message": "Internal Server Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/users": {
      "get": {
        "tags": [
          "User Administration"
        ],
        "summary": "Search users",
        "description": "Lists users with filtering, sorting, and pagination.",
        "operationId": "getUsers",
        "parameters": [
          {
            "name": "id",
            "in": "query",
            "description": "Unique identifier for the user",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Unique identifier for the user",
              "example": "usr_abc123"
            },
            "example": "usr_abc123"
          },
          {
            "name": "email",
            "in": "query",
            "description": "Email address (case-insensitive LIKE, multi-word OR)",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Email address (case-insensitive LIKE, multi-word OR)",
              "example": "admin@example.com"
            },
            "example": "admin@example.com"
          },
          {
            "name": "displayName",
            "in": "query",
            "description": "Display name (case-insensitive LIKE, multi-word OR)",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Display name (case-insensitive LIKE, multi-word OR)",
              "example": "Admin User"
            },
            "example": "Admin User"
          },
          {
            "name": "idpSub",
            "in": "query",
            "description": "Identity provider subject identifier (exact match)",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Identity provider subject identifier (exact match)",
              "example": "auth0|67fd70c38eb9d43f1c93ea44"
            },
            "example": "auth0|67fd70c38eb9d43f1c93ea44"
          },
          {
            "name": "status",
            "in": "query",
            "description": "Current user status",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Current user status",
              "enum": [
                "ACTIVE",
                "DEACTIVATED",
                "ACTIVE",
                "DEACTIVATED"
              ],
              "example": "ACTIVE"
            },
            "example": "ACTIVE"
          },
          {
            "name": "createdAfter",
            "in": "query",
            "description": "Start of creation timestamp range",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Start of creation timestamp range",
              "example": "2026-04-01T00:00:00Z"
            },
            "example": "2026-04-01T00:00:00Z"
          },
          {
            "name": "createdBefore",
            "in": "query",
            "description": "End of creation timestamp range",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "End of creation timestamp range",
              "example": "2026-04-08T00:00:00Z"
            },
            "example": "2026-04-08T00:00:00Z"
          },
          {
            "name": "updatedAfter",
            "in": "query",
            "description": "Start of last update timestamp range",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Start of last update timestamp range",
              "example": "2026-04-01T00:00:00Z"
            },
            "example": "2026-04-01T00:00:00Z"
          },
          {
            "name": "updatedBefore",
            "in": "query",
            "description": "End of last update timestamp range",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "End of last update timestamp range",
              "example": "2026-04-08T00:00:00Z"
            },
            "example": "2026-04-08T00:00:00Z"
          },
          {
            "name": "page",
            "in": "query",
            "description": "Zero-based page index (0..N)",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            }
          },
          {
            "name": "size",
            "in": "query",
            "description": "The size of the page to be returned",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1
            }
          },
          {
            "name": "sort",
            "in": "query",
            "description": "Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported.",
            "required": false,
            "schema": {
              "type": "array",
              "default": [
                "createdAt,DESC",
                "id,DESC"
              ],
              "items": {
                "type": "string"
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Users retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PagedResponseUserSummaryResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INTERNAL_ERROR",
                  "message": "Internal Server Error"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "SERVICE_UNAVAILABLE",
                  "message": "Service Unavailable"
                }
              }
            }
          }
        }
      }
    },
    "/v1/users/{id}": {
      "get": {
        "tags": [
          "User Administration"
        ],
        "summary": "Get user",
        "description": "Returns a single user's details and assigned roles.",
        "operationId": "getUser",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "User ID",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "usr_abc123"
          }
        ],
        "responses": {
          "200": {
            "description": "User retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserDetailResponse"
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "NOT_FOUND",
                  "message": "Not Found"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "INTERNAL_ERROR",
                  "message": "Internal Server Error"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponse"
                },
                "example": {
                  "type": "SERVICE_UNAVAILABLE",
                  "message": "Service Unavailable"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "UpdateSavedViewRequest": {
        "type": "object",
        "description": "Request to update a saved view",
        "properties": {
          "name": {
            "type": "string",
            "description": "New name for the view",
            "example": "SF Trip December 2024",
            "maxLength": 255,
            "minLength": 0
          },
          "criteria": {
            "$ref": "#/components/schemas/ViewCriteriaApi",
            "description": "New filter criteria for the view"
          },
          "openEnded": {
            "type": "boolean",
            "description": "If true, the view includes transactions up to current date"
          }
        }
      },
      "ViewCriteriaApi": {
        "type": "object",
        "description": "Filter criteria for a saved view",
        "properties": {
          "startDate": {
            "type": "string",
            "format": "date",
            "description": "Start date for transaction date range",
            "example": "2024-12-01"
          },
          "endDate": {
            "type": "string",
            "format": "date",
            "description": "End date for transaction date range (null for open-ended views)"
          },
          "accountIds": {
            "type": "array",
            "description": "Account IDs to filter by",
            "items": {
              "type": "string"
            },
            "uniqueItems": true
          },
          "bankNames": {
            "type": "array",
            "description": "Bank names to filter by",
            "example": [
              "Capital One",
              "Truist"
            ],
            "items": {
              "type": "string"
            },
            "uniqueItems": true
          },
          "currencyIsoCodes": {
            "type": "array",
            "description": "Currency ISO codes to filter by",
            "example": [
              "USD",
              "EUR"
            ],
            "items": {
              "type": "string"
            },
            "uniqueItems": true
          },
          "minAmount": {
            "type": "number",
            "description": "Minimum transaction amount",
            "example": 10.0
          },
          "maxAmount": {
            "type": "number",
            "description": "Maximum transaction amount",
            "example": 500.0
          },
          "searchText": {
            "type": "string",
            "description": "Text to match in the transaction description",
            "example": "coffee"
          }
        }
      },
      "SavedViewResponse": {
        "type": "object",
        "description": "Saved view response",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique identifier for the view"
          },
          "name": {
            "type": "string",
            "description": "Name of the view",
            "example": "SF Trip December 2024"
          },
          "criteria": {
            "$ref": "#/components/schemas/ViewCriteriaApi",
            "description": "Filter criteria for the view"
          },
          "openEnded": {
            "type": "boolean",
            "description": "If true, the view includes transactions up to the current date"
          },
          "pinnedCount": {
            "type": "integer",
            "format": "int32",
            "description": "Number of pinned transactions"
          },
          "excludedCount": {
            "type": "integer",
            "format": "int32",
            "description": "Number of excluded transactions"
          },
          "transactionCount": {
            "type": "integer",
            "format": "int64",
            "description": "Total number of transactions matching this view"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp when the view was created"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp when the view was last updated"
          }
        },
        "required": [
          "createdAt",
          "criteria",
          "excludedCount",
          "id",
          "name",
          "openEnded",
          "pinnedCount",
          "transactionCount",
          "updatedAt"
        ]
      },
      "ApiErrorResponse": {
        "description": "Standard API error response format",
        "properties": {
          "type": {
            "type": "string",
            "description": "Error type categorization for API responses",
            "enum": [
              "INVALID_REQUEST",
              "VALIDATION_ERROR",
              "NOT_FOUND",
              "APPLICATION_ERROR",
              "SERVICE_UNAVAILABLE",
              "INTERNAL_ERROR",
              "UNAUTHORIZED",
              "FORBIDDEN"
            ],
            "example": "APPLICATION_ERROR"
          },
          "message": {
            "type": "string",
            "description": "Human-readable message describing the error",
            "example": "CSV format: fake-bank not supported"
          },
          "code": {
            "type": "string",
            "description": "Machine-readable error code for specific application errors (required for APPLICATION_ERROR type)",
            "example": "CSV_PARSING_ERROR"
          },
          "fieldErrors": {
            "type": "array",
            "description": "List of field-level validation errors (populated for VALIDATION_ERROR type)",
            "items": {
              "$ref": "#/components/schemas/FieldError"
            }
          }
        },
        "required": [
          "message",
          "type"
        ]
      },
      "FieldError": {
        "description": "Field-level validation error details",
        "properties": {
          "index": {
            "type": "integer",
            "format": "int32",
            "description": "Zero-based index of the item in a batch/list that caused the error. Null for single-item validation errors.",
            "example": 44
          },
          "field": {
            "type": "string",
            "description": "Field that triggered the error",
            "example": "email"
          },
          "message": {
            "type": "string",
            "description": "Error message",
            "example": "must be a valid email address"
          },
          "rejectedValue": {
            "type": "object",
            "description": "Value that caused the error",
            "example": "invalid@email"
          }
        },
        "required": [
          "field",
          "message"
        ]
      },
      "UpdateStatementFormatRequest": {
        "type": "object",
        "properties": {
          "displayName": {
            "type": "string",
            "maxLength": 100,
            "minLength": 0
          },
          "bankName": {
            "type": "string",
            "maxLength": 100,
            "minLength": 0
          },
          "defaultCurrencyIsoCode": {
            "type": "string",
            "maxLength": 3,
            "minLength": 3
          },
          "dateHeader": {
            "type": "string",
            "maxLength": 50,
            "minLength": 0
          },
          "dateFormat": {
            "type": "string",
            "maxLength": 50,
            "minLength": 0
          },
          "descriptionHeader": {
            "type": "string",
            "maxLength": 50,
            "minLength": 0
          },
          "creditHeader": {
            "type": "string",
            "maxLength": 50,
            "minLength": 0
          },
          "debitHeader": {
            "type": "string",
            "maxLength": 50,
            "minLength": 0
          },
          "typeHeader": {
            "type": "string",
            "maxLength": 50,
            "minLength": 0
          },
          "categoryHeader": {
            "type": "string",
            "maxLength": 50,
            "minLength": 0
          },
          "enabled": {
            "type": "boolean"
          }
        }
      },
      "StatementFormatResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "formatKey": {
            "type": "string"
          },
          "displayName": {
            "type": "string"
          },
          "formatType": {
            "type": "string",
            "enum": [
              "CSV",
              "PDF",
              "XLSX"
            ]
          },
          "bankName": {
            "type": "string"
          },
          "defaultCurrencyIsoCode": {
            "type": "string"
          },
          "dateHeader": {
            "type": "string"
          },
          "dateFormat": {
            "type": "string"
          },
          "descriptionHeader": {
            "type": "string"
          },
          "creditHeader": {
            "type": "string"
          },
          "debitHeader": {
            "type": "string"
          },
          "typeHeader": {
            "type": "string"
          },
          "categoryHeader": {
            "type": "string"
          },
          "enabled": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp when the statement format was created",
            "example": "2026-04-08T10:30:00Z"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp when the statement format was last updated",
            "example": "2026-04-08T10:45:00Z"
          },
          "createdBy": {
            "type": "string",
            "description": "User ID that created this statement format",
            "example": "usr_admin123"
          },
          "updatedBy": {
            "type": "string",
            "description": "User ID that last updated this statement format",
            "example": "usr_admin456"
          }
        },
        "required": [
          "createdAt"
        ]
      },
      "CreateSavedViewRequest": {
        "type": "object",
        "description": "Request to create a new saved view",
        "properties": {
          "name": {
            "type": "string",
            "description": "Name of the saved view",
            "example": "SF Trip December 2024",
            "maxLength": 255,
            "minLength": 0
          },
          "criteria": {
            "$ref": "#/components/schemas/ViewCriteriaApi",
            "description": "Filter criteria for the view"
          },
          "openEnded": {
            "type": "boolean",
            "description": "If true, the view includes transactions up to current date",
            "example": false
          }
        },
        "required": [
          "criteria",
          "name"
        ]
      },
      "PreviewResponse": {
        "type": "object",
        "description": "Response from transaction preview containing extracted transactions",
        "properties": {
          "sourceFile": {
            "type": "string",
            "description": "Original filename of the uploaded file",
            "example": "cap-one-2024.csv"
          },
          "detectedFormat": {
            "type": "string",
            "description": "Detected format key used for parsing (informational)",
            "example": "capital-one-ytd"
          },
          "transactions": {
            "type": "array",
            "description": "List of extracted transactions ready for review",
            "items": {
              "$ref": "#/components/schemas/PreviewTransaction"
            }
          },
          "warnings": {
            "type": "array",
            "description": "List of warnings for fields with potential issues. Empty for CSV extraction; populated for PDF extraction where OCR confidence may be low.",
            "items": {
              "$ref": "#/components/schemas/PreviewWarning"
            }
          }
        }
      },
      "PreviewTransaction": {
        "type": "object",
        "description": "Previewed transaction data before import",
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "description": "Date of the transaction",
            "example": "2024-04-12"
          },
          "description": {
            "type": "string",
            "description": "Description of the transaction",
            "example": "TAQUERIA DEL SOL #3",
            "minLength": 1
          },
          "amount": {
            "type": "number",
            "description": "Amount of the transaction",
            "example": 55.12
          },
          "type": {
            "type": "string",
            "description": "Type of the transaction",
            "enum": [
              "CREDIT",
              "DEBIT"
            ],
            "example": "DEBIT"
          },
          "category": {
            "type": "string",
            "description": "Category extracted from source data",
            "example": "Dining"
          },
          "bankName": {
            "type": "string",
            "description": "Name of the bank",
            "example": "Capital One",
            "minLength": 1
          },
          "currencyIsoCode": {
            "type": "string",
            "description": "ISO currency code",
            "example": "USD",
            "minLength": 1
          },
          "accountId": {
            "type": "string",
            "description": "Account identifier (may be null)",
            "example": "checking-12345"
          }
        },
        "required": [
          "amount",
          "bankName",
          "currencyIsoCode",
          "date",
          "description",
          "type"
        ]
      },
      "PreviewWarning": {
        "type": "object",
        "description": "Warning for a specific field in a previewed transaction",
        "properties": {
          "index": {
            "type": "integer",
            "format": "int32",
            "description": "Zero-based index of the transaction in the preview list",
            "example": 12
          },
          "field": {
            "type": "string",
            "description": "Name of the field with the warning",
            "example": "amount"
          },
          "message": {
            "type": "string",
            "description": "Warning message",
            "example": "OCR confidence low"
          }
        }
      },
      "BulkDeleteRequest": {
        "type": "object",
        "description": "Request to bulk delete multiple transactions",
        "properties": {
          "ids": {
            "type": "array",
            "description": "List of transaction IDs to delete",
            "example": [
              1,
              2,
              3
            ],
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "minItems": 1
          }
        },
        "required": [
          "ids"
        ]
      },
      "BulkDeleteResponse": {
        "type": "object",
        "description": "Response from bulk delete operation",
        "properties": {
          "deletedCount": {
            "type": "integer",
            "format": "int32",
            "description": "Number of transactions successfully deleted",
            "example": 5
          },
          "notFoundIds": {
            "type": "array",
            "description": "List of transaction IDs that were not found or already deleted",
            "example": [
              999,
              1000
            ],
            "items": {
              "type": "integer",
              "format": "int64"
            }
          }
        }
      },
      "BatchImportRequest": {
        "type": "object",
        "description": "Request for batch importing transactions",
        "properties": {
          "transactions": {
            "type": "array",
            "description": "List of transactions to import",
            "items": {
              "$ref": "#/components/schemas/PreviewTransaction"
            },
            "minItems": 1
          }
        },
        "required": [
          "transactions"
        ]
      },
      "BatchImportResponse": {
        "type": "object",
        "description": "Response from batch transaction import",
        "properties": {
          "created": {
            "type": "integer",
            "format": "int32",
            "description": "Number of transactions created",
            "example": 156
          },
          "duplicatesSkipped": {
            "type": "integer",
            "format": "int32",
            "description": "Number of duplicates skipped",
            "example": 3
          },
          "transactions": {
            "type": "array",
            "description": "List of created transactions with IDs",
            "items": {
              "$ref": "#/components/schemas/TransactionResponse"
            }
          }
        }
      },
      "TransactionResponse": {
        "type": "object",
        "description": "Transaction response representing a financial transaction",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64",
            "description": "Unique identifier for the transaction",
            "example": 1
          },
          "ownerId": {
            "type": "string",
            "description": "ID of the user who owns this transaction",
            "example": "usr_test123"
          },
          "accountId": {
            "type": "string",
            "description": "Identifier for the account associated with the transaction",
            "example": "checking-3223"
          },
          "bankName": {
            "type": "string",
            "description": "Name of the bank where the transaction occurred",
            "example": "Capital One"
          },
          "date": {
            "type": "string",
            "format": "date",
            "description": "Date of the transaction",
            "example": "2025-10-14"
          },
          "currencyIsoCode": {
            "type": "string",
            "description": "ISO currency code for the transaction",
            "example": "USD"
          },
          "amount": {
            "type": "number",
            "description": "Amount of the transaction",
            "example": 100.5
          },
          "type": {
            "type": "string",
            "description": "Type of the transaction",
            "enum": [
              "CREDIT",
              "DEBIT"
            ],
            "example": "DEBIT"
          },
          "description": {
            "type": "string",
            "description": "Description of the transaction",
            "example": "Grocery shopping"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp when the transaction was created",
            "example": "2025-10-14T10:30:00Z"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp when the transaction was last updated",
            "example": "2025-10-14T10:30:00Z"
          }
        },
        "required": [
          "amount",
          "bankName",
          "createdAt",
          "currencyIsoCode",
          "date",
          "description",
          "id",
          "ownerId",
          "type",
          "updatedAt"
        ]
      },
      "CreateStatementFormatRequest": {
        "type": "object",
        "properties": {
          "formatKey": {
            "type": "string",
            "maxLength": 50,
            "minLength": 0,
            "pattern": "^[a-z0-9-]+$"
          },
          "displayName": {
            "type": "string",
            "maxLength": 100,
            "minLength": 0
          },
          "formatType": {
            "type": "string",
            "enum": [
              "CSV",
              "PDF",
              "XLSX"
            ]
          },
          "bankName": {
            "type": "string",
            "maxLength": 100,
            "minLength": 0
          },
          "defaultCurrencyIsoCode": {
            "type": "string",
            "maxLength": 3,
            "minLength": 3
          },
          "dateHeader": {
            "type": "string",
            "maxLength": 50,
            "minLength": 0
          },
          "dateFormat": {
            "type": "string",
            "maxLength": 50,
            "minLength": 0
          },
          "descriptionHeader": {
            "type": "string",
            "maxLength": 50,
            "minLength": 0
          },
          "creditHeader": {
            "type": "string",
            "maxLength": 50,
            "minLength": 0
          },
          "debitHeader": {
            "type": "string",
            "maxLength": 50,
            "minLength": 0
          },
          "typeHeader": {
            "type": "string",
            "maxLength": 50,
            "minLength": 0
          },
          "categoryHeader": {
            "type": "string",
            "maxLength": 50,
            "minLength": 0
          }
        },
        "required": [
          "bankName",
          "defaultCurrencyIsoCode",
          "displayName",
          "formatKey",
          "formatType"
        ]
      },
      "TransactionUpdateRequest": {
        "type": "object",
        "description": "Request to update a transaction's mutable fields",
        "properties": {
          "description": {
            "type": "string",
            "description": "Updated description for the transaction",
            "example": "Whole Foods - groceries for dinner party",
            "maxLength": 500,
            "minLength": 0
          },
          "accountId": {
            "type": "string",
            "description": "Updated account ID to associate with the transaction",
            "example": "checking-12345",
            "maxLength": 100,
            "minLength": 0
          }
        }
      },
      "ViewMembershipResponse": {
        "type": "object",
        "description": "Transaction IDs grouped by membership type in a saved view. Only includes active (non-deleted) transactions.",
        "properties": {
          "matched": {
            "type": "array",
            "description": "IDs of active transactions matching view criteria (excluding excluded IDs)",
            "example": [
              123,
              456,
              789
            ],
            "items": {
              "type": "integer",
              "format": "int64"
            }
          },
          "pinned": {
            "type": "array",
            "description": "IDs of active transactions explicitly pinned (excluding those already matched)",
            "example": [
              101,
              102
            ],
            "items": {
              "type": "integer",
              "format": "int64"
            }
          },
          "excluded": {
            "type": "array",
            "description": "IDs of active transactions explicitly excluded from matched set",
            "example": [
              234
            ],
            "items": {
              "type": "integer",
              "format": "int64"
            }
          }
        },
        "required": [
          "excluded",
          "matched",
          "pinned"
        ]
      },
      "PageMetadataResponse": {
        "type": "object",
        "description": "Pagination metadata for a paged API response",
        "properties": {
          "page": {
            "type": "integer",
            "format": "int32",
            "description": "Zero-based current page index",
            "example": 0
          },
          "size": {
            "type": "integer",
            "format": "int32",
            "description": "Requested page size",
            "example": 50
          },
          "numberOfElements": {
            "type": "integer",
            "format": "int32",
            "description": "Number of items included in the current page",
            "example": 50
          },
          "totalElements": {
            "type": "integer",
            "format": "int64",
            "description": "Total number of matching records across all pages",
            "example": 12437
          },
          "totalPages": {
            "type": "integer",
            "format": "int32",
            "description": "Total number of pages for the current query",
            "example": 249
          },
          "first": {
            "type": "boolean",
            "description": "Whether this is the first page",
            "example": true
          },
          "last": {
            "type": "boolean",
            "description": "Whether this is the last page",
            "example": false
          }
        },
        "required": [
          "first",
          "last",
          "numberOfElements",
          "page",
          "size",
          "totalElements",
          "totalPages"
        ]
      },
      "PagedResponseTransactionResponse": {
        "type": "object",
        "description": "Stable paged API response wrapper",
        "properties": {
          "content": {
            "type": "array",
            "description": "Items included in the current page",
            "items": {
              "$ref": "#/components/schemas/TransactionResponse"
            }
          },
          "metadata": {
            "$ref": "#/components/schemas/PageMetadataResponse",
            "description": "Pagination metadata for the current result set"
          }
        },
        "required": [
          "content",
          "metadata"
        ]
      },
      "TransactionFilter": {
        "type": "object",
        "description": "Filter for querying transactions by various fields",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64",
            "description": "Unique identifier for the transaction",
            "example": 1
          },
          "ownerId": {
            "type": "string",
            "description": "ID of the user who owns the transaction. Only effective on admin endpoints; ignored on user-scoped endpoints where the authenticated user is always applied.",
            "example": "usr_test123"
          },
          "accountId": {
            "type": "string",
            "description": "Identifier for the account associated with the transaction",
            "example": "checking-3223"
          },
          "bankName": {
            "type": "string",
            "description": "Name of the bank where the transaction occurred",
            "example": "Capital One"
          },
          "dateFrom": {
            "type": "string",
            "format": "date",
            "description": "Start date for transaction date range",
            "example": "2025-10-01"
          },
          "dateTo": {
            "type": "string",
            "format": "date",
            "description": "End date for transaction date range",
            "example": "2025-10-14"
          },
          "currencyIsoCode": {
            "type": "string",
            "description": "ISO currency code for the transaction",
            "example": "USD"
          },
          "minAmount": {
            "type": "number",
            "description": "Minimum transaction amount",
            "example": 10.0
          },
          "maxAmount": {
            "type": "number",
            "description": "Maximum transaction amount",
            "example": 500.0
          },
          "type": {
            "type": "string",
            "description": "Type of the transaction",
            "enum": [
              "CREDIT",
              "DEBIT"
            ],
            "example": "DEBIT"
          },
          "description": {
            "type": "string",
            "description": "Text to match in the transaction description",
            "example": "Grocery"
          },
          "createdAfter": {
            "type": "string",
            "format": "date-time",
            "description": "Start of creation timestamp range",
            "example": "2025-10-14T00:00:00Z"
          },
          "createdBefore": {
            "type": "string",
            "format": "date-time",
            "description": "End of creation timestamp range",
            "example": "2025-10-15T00:00:00Z"
          },
          "updatedAfter": {
            "type": "string",
            "format": "date-time",
            "description": "Start of last update timestamp range",
            "example": "2025-10-14T00:00:00Z"
          },
          "updatedBefore": {
            "type": "string",
            "format": "date-time",
            "description": "End of last update timestamp range",
            "example": "2025-10-15T00:00:00Z"
          }
        }
      },
      "CurrencySeriesUpdateRequest": {
        "type": "object",
        "description": "Request to update an existing currency series (currency code and provider series ID are immutable)",
        "properties": {
          "enabled": {
            "type": "boolean",
            "description": "Whether this currency is enabled for exchange rate access",
            "example": true
          }
        },
        "required": [
          "enabled"
        ]
      },
      "CurrencySeriesResponse": {
        "type": "object",
        "description": "Currency series response with mapping details",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64",
            "description": "Unique identifier",
            "example": 1
          },
          "currencyCode": {
            "type": "string",
            "description": "ISO 4217 three-letter currency code",
            "example": "EUR"
          },
          "providerSeriesId": {
            "type": "string",
            "description": "Exchange rate provider series identifier",
            "example": "DEXUSEU"
          },
          "enabled": {
            "type": "boolean",
            "description": "Whether this currency is enabled for exchange rate access",
            "example": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp when this currency series was created",
            "example": "2025-01-15T10:30:00Z"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp when this currency series was last updated",
            "example": "2025-01-15T14:45:00Z"
          }
        },
        "required": [
          "createdAt",
          "currencyCode",
          "enabled",
          "id",
          "providerSeriesId",
          "updatedAt"
        ]
      },
      "ExchangeRateImportResultResponse": {
        "type": "object",
        "description": "Exchange rate import result response for a specific currency",
        "properties": {
          "currencyCode": {
            "type": "string",
            "description": "ISO 4217 currency code",
            "example": "EUR"
          },
          "providerSeriesId": {
            "type": "string",
            "description": "Provider series ID used for this import",
            "example": "DEXUSEU"
          },
          "newRecords": {
            "type": "integer",
            "format": "int32",
            "description": "Number of new exchange rates created",
            "example": 10
          },
          "updatedRecords": {
            "type": "integer",
            "format": "int32",
            "description": "Number of exchange rates that were updated due to having a different rate than what we have stored- should never happen, rates shouldn't change",
            "example": 0
          },
          "skippedRecords": {
            "type": "integer",
            "format": "int32",
            "description": "Number of rows in the csv that already had matching exchange rates created in the database",
            "example": 5
          },
          "earliestExchangeRateDate": {
            "type": "string",
            "format": "date",
            "description": "Date of the earliest exchange rate in this import",
            "example": "2025-01-01"
          },
          "latestExchangeRateDate": {
            "type": "string",
            "format": "date",
            "description": "Date of the latest exchange rate in this import",
            "example": "2025-10-31"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp of the import execution",
            "example": "2025-10-31T15:30:00Z"
          }
        },
        "required": [
          "currencyCode",
          "newRecords",
          "providerSeriesId",
          "skippedRecords",
          "timestamp",
          "updatedRecords"
        ]
      },
      "CurrencySeriesCreateRequest": {
        "type": "object",
        "description": "Request to create a new currency series",
        "properties": {
          "currencyCode": {
            "type": "string",
            "description": "ISO 4217 three-letter currency code",
            "example": "EUR",
            "maxLength": 3,
            "minLength": 3,
            "pattern": "^[A-Z]{3}$"
          },
          "providerSeriesId": {
            "type": "string",
            "description": "Exchange rate provider series identifier (e.g., DEXUSEU for EUR/USD). Must be a valid FRED series ID.",
            "example": "DEXUSEU",
            "maxLength": 50,
            "minLength": 0
          },
          "enabled": {
            "type": "boolean",
            "default": true,
            "description": "Whether this currency is enabled for exchange rate access",
            "example": true
          }
        },
        "required": [
          "currencyCode",
          "providerSeriesId"
        ]
      },
      "ExchangeRateResponse": {
        "type": "object",
        "description": "Exchange rate response",
        "properties": {
          "baseCurrency": {
            "type": "string",
            "description": "Base currency (1 unit of base = rate units of target, currently only USD supported)",
            "example": "USD"
          },
          "targetCurrency": {
            "type": "string",
            "description": "Target currency",
            "example": "THB"
          },
          "date": {
            "type": "string",
            "format": "date",
            "description": "Date for the given rate",
            "example": "2025-11-02"
          },
          "rate": {
            "type": "number",
            "description": "Exchange rate for the given date",
            "example": 32.68
          },
          "publishedDate": {
            "type": "string",
            "format": "date",
            "description": "Date the exchange rate was published. FRED doesn't publish rates for weekends and holidays, so we use the nearest previously published rate",
            "example": "2025-10-31"
          }
        },
        "required": [
          "baseCurrency",
          "date",
          "publishedDate",
          "rate",
          "targetCurrency"
        ]
      },
      "UserDeactivationResponse": {
        "type": "object",
        "properties": {
          "userId": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "DEACTIVATED"
            ]
          },
          "rolesRemoved": {
            "type": "integer",
            "format": "int32"
          },
          "sessionsRevoked": {
            "type": "boolean"
          }
        }
      },
      "PagedResponseUserSummaryResponse": {
        "type": "object",
        "description": "Stable paged API response wrapper",
        "properties": {
          "content": {
            "type": "array",
            "description": "Items included in the current page",
            "items": {
              "$ref": "#/components/schemas/UserSummaryResponse"
            }
          },
          "metadata": {
            "$ref": "#/components/schemas/PageMetadataResponse",
            "description": "Pagination metadata for the current result set"
          }
        },
        "required": [
          "content",
          "metadata"
        ]
      },
      "UserSummaryResponse": {
        "type": "object",
        "description": "Summary representation of a user for list views",
        "properties": {
          "id": {
            "type": "string",
            "description": "Internal user ID",
            "example": "usr_abc123"
          },
          "idpSub": {
            "type": "string",
            "description": "Identity provider subject identifier",
            "example": "auth0|67fd70c38eb9d43f1c93ea44"
          },
          "email": {
            "type": "string",
            "description": "User email address",
            "example": "admin@example.com"
          },
          "displayName": {
            "type": "string",
            "description": "Display name",
            "example": "Admin User"
          },
          "status": {
            "type": "string",
            "description": "Current user status",
            "enum": [
              "ACTIVE",
              "DEACTIVATED"
            ],
            "example": "ACTIVE"
          },
          "roleIds": {
            "type": "array",
            "description": "Assigned role IDs",
            "example": [
              "ADMIN"
            ],
            "items": {
              "type": "string"
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Creation timestamp",
            "example": "2026-04-01T12:00:00Z"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Last update timestamp",
            "example": "2026-04-08T12:00:00Z"
          },
          "deactivatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Deactivation timestamp",
            "example": "2026-04-08T12:00:00Z"
          }
        }
      },
      "UserDetailResponse": {
        "type": "object",
        "description": "Detailed representation of a user",
        "properties": {
          "id": {
            "type": "string",
            "description": "Internal user ID",
            "example": "usr_abc123"
          },
          "idpSub": {
            "type": "string",
            "description": "Identity provider subject identifier",
            "example": "auth0|67fd70c38eb9d43f1c93ea44"
          },
          "email": {
            "type": "string",
            "description": "User email address",
            "example": "admin@example.com"
          },
          "displayName": {
            "type": "string",
            "description": "Display name",
            "example": "Admin User"
          },
          "status": {
            "type": "string",
            "description": "Current user status",
            "enum": [
              "ACTIVE",
              "DEACTIVATED"
            ],
            "example": "ACTIVE"
          },
          "roleIds": {
            "type": "array",
            "description": "Assigned role IDs",
            "example": [
              "ADMIN"
            ],
            "items": {
              "type": "string"
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Creation timestamp",
            "example": "2026-04-01T12:00:00Z"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Last update timestamp",
            "example": "2026-04-08T12:00:00Z"
          },
          "deactivatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Deactivation timestamp",
            "example": "2026-04-08T12:00:00Z"
          },
          "deactivatedBy": {
            "$ref": "#/components/schemas/UserReference",
            "description": "User that deactivated the user"
          },
          "deletedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Soft-delete timestamp",
            "example": "2026-04-09T12:00:00Z"
          },
          "deletedBy": {
            "$ref": "#/components/schemas/UserReference",
            "description": "User that soft-deleted the user"
          }
        }
      },
      "UserReference": {
        "type": "object",
        "description": "Dereferenced user identity for audit fields",
        "properties": {
          "id": {
            "type": "string",
            "description": "Internal user ID",
            "example": "usr_admin456"
          },
          "displayName": {
            "type": "string",
            "description": "Display name",
            "example": "Admin User"
          },
          "email": {
            "type": "string",
            "description": "User email address",
            "example": "admin@example.com"
          }
        }
      }
    }
  }
}
