{
  "openapi": "3.0.3",
  "info": {
    "title": "Nexus Loan Applications Workflow",
    "version": "1.0.0",
    "description": "Public form endpoints powering the Nexus loan-application experience, including draft persistence and resumed submissions."
  },
  "servers": [
    {
      "url": "http://localhost:3000",
      "description": "Local development"
    }
  ],
  "paths": {
    "/loan_applications": {
      "post": {
        "summary": "Submit a loan application",
        "description": "Validates applicant, business, and ownership details, exchanges owner SSNs for replacement identifiers via the Nexus credit-score service, and queues the application for admin review.",
        "requestBody": {
          "$ref": "#/components/requestBodies/LoanApplicationSubmission"
        },
        "responses": {
          "302": {
            "description": "Successful submission redirects to the confirmation page.",
            "headers": {
              "Location": {
                "description": "URL of the confirmation page.",
                "schema": {
                  "type": "string",
                  "format": "uri"
                }
              }
            },
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "500": {
            "description": "Unexpected error submitting the application."
          }
        }
      }
    },
    "/loan_applications/draft": {
      "post": {
        "summary": "Save or refresh a draft",
        "description": "Persists a serialized form payload for 30 days. Passing an existing `resume_token` refreshes the expiry.",
        "requestBody": {
          "$ref": "#/components/requestBodies/LoanApplicationDraftSubmission"
        },
        "responses": {
          "201": {
            "description": "Draft persisted successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoanApplicationDraftResponse"
                }
              }
            }
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          }
        }
      }
    },
    "/loan_applications/resume/{token}/submission": {
      "patch": {
        "summary": "Submit a resumed application",
        "description": "Validates the supplied form data against the existing draft, removes the draft on success, and redirects to the confirmation page.",
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "description": "Resume token returned by the draft endpoint.",
            "schema": {
              "type": "string",
              "minLength": 10
            }
          }
        ],
        "requestBody": {
          "$ref": "#/components/requestBodies/LoanApplicationSubmission"
        },
        "responses": {
          "302": {
            "description": "Submission accepted; browser redirected to confirmation.",
            "headers": {
              "Location": {
                "description": "URL of the confirmation page.",
                "schema": {
                  "type": "string",
                  "format": "uri"
                }
              }
            },
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Draft not found or expired."
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "500": {
            "description": "Unexpected error submitting the application."
          }
        }
      }
    }
  },
  "components": {
    "requestBodies": {
      "LoanApplicationSubmission": {
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/LoanApplicationSubmission"
            }
          },
          "application/x-www-form-urlencoded": {
            "schema": {
              "$ref": "#/components/schemas/LoanApplicationSubmission"
            }
          }
        }
      },
      "LoanApplicationDraftSubmission": {
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/LoanApplicationDraftRequest"
            }
          }
        }
      }
    },
    "responses": {
      "ValidationError": {
        "description": "Validation failed.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "errors": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              },
              "required": [
                "errors"
              ]
            }
          }
        }
      }
    },
    "schemas": {
      "LoanApplicationSubmission": {
        "type": "object",
        "required": [
          "loan_application"
        ],
        "properties": {
          "loan_application": {
            "$ref": "#/components/schemas/LoanApplicationPayload"
          }
        }
      },
      "LoanApplicationDraftRequest": {
        "type": "object",
        "required": [
          "loan_application"
        ],
        "properties": {
          "resume_token": {
            "type": "string",
            "description": "Optional token to update an existing draft."
          },
          "loan_application": {
            "$ref": "#/components/schemas/LoanApplicationPayload"
          }
        }
      },
      "LoanApplicationPayload": {
        "type": "object",
        "properties": {
          "first_name": {
            "type": "string"
          },
          "last_name": {
            "type": "string"
          },
          "phone": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "legal_business_name": {
            "type": "string"
          },
          "street_no": {
            "type": "string",
            "nullable": true
          },
          "street_address": {
            "type": "string"
          },
          "unit": {
            "type": "string",
            "nullable": true
          },
          "city": {
            "type": "string"
          },
          "state": {
            "type": "string",
            "minLength": 2,
            "maxLength": 2
          },
          "zip": {
            "type": "string"
          },
          "inception_year": {
            "type": "integer",
            "minimum": 1900,
            "nullable": true
          },
          "inception_month": {
            "type": "integer",
            "minimum": 1,
            "maximum": 12,
            "nullable": true
          },
          "tax_id": {
            "type": "string",
            "nullable": true
          },
          "business_type": {
            "type": "string",
            "nullable": true
          },
          "website": {
            "type": "string",
            "nullable": true
          },
          "loan_purpose": {
            "type": "string",
            "nullable": true
          },
          "loan_amount": {
            "type": "number",
            "minimum": 10000,
            "maximum": 5000000,
            "nullable": true
          },
          "financing_type": {
            "type": "string",
            "nullable": true
          },
          "company_type": {
            "type": "string",
            "nullable": true
          },
          "notes": {
            "type": "string",
            "nullable": true
          },
          "owner1": {
            "$ref": "#/components/schemas/LoanApplicationOwner"
          },
          "owner2": {
            "$ref": "#/components/schemas/LoanApplicationOwner"
          }
        }
      },
      "LoanApplicationOwner": {
        "type": "object",
        "properties": {
          "owner_number": {
            "type": "integer",
            "enum": [
              1,
              2
            ]
          },
          "first_name": {
            "type": "string"
          },
          "last_name": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "format": "email",
            "nullable": true
          },
          "street_no": {
            "type": "string",
            "nullable": true
          },
          "street_address": {
            "type": "string",
            "nullable": true
          },
          "unit": {
            "type": "string",
            "nullable": true
          },
          "city": {
            "type": "string",
            "nullable": true
          },
          "state": {
            "type": "string",
            "minLength": 2,
            "maxLength": 2,
            "nullable": true
          },
          "zip": {
            "type": "string",
            "nullable": true
          },
          "dob": {
            "type": "string",
            "format": "date",
            "nullable": true
          },
          "ssn_token": {
            "type": "string",
            "description": "Synthetic SSN following the 999XXXYYY pattern.",
            "nullable": true
          },
          "ssn_replacement": {
            "type": "string",
            "description": "Replacement SSN returned by the credit-score service.",
            "nullable": true
          },
          "ownership_percentage": {
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "nullable": true
          },
          "primary_guarantor": {
            "type": "boolean",
            "default": false
          },
          "signature": {
            "type": "string",
            "nullable": true
          },
          "signature_date": {
            "type": "string",
            "format": "date",
            "nullable": true
          }
        }
      },
      "LoanApplicationDraftResponse": {
        "type": "object",
        "required": [
          "resume_token",
          "resume_url",
          "expires_at"
        ],
        "properties": {
          "resume_token": {
            "type": "string"
          },
          "resume_url": {
            "type": "string",
            "format": "uri"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      }
    }
  }
}
