{
  "openapi": "3.0.3",
  "info": {
    "title": "AcreSeal API",
    "description": "HB 144 compliance platform API for Texas utilities. Forensic-grade complaint documentation, inspection tracking, and PUCT reporting.",
    "version": "1.0.0",
    "contact": {
      "name": "AcreSeal Support",
      "email": "lance@acreseal.com",
      "url": "https://acreseal.com"
    },
    "license": {
      "name": "Proprietary — Patent Pending"
    }
  },
  "servers": [
    {
      "url": "https://acreseal.com/api",
      "description": "Production"
    }
  ],
  "paths": {
    "/health": {
      "get": {
        "summary": "Health check",
        "description": "Returns platform health status. No authentication required.",
        "tags": ["System"],
        "security": [],
        "responses": {
          "200": {
            "description": "Healthy",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": { "type": "string", "example": "ok" },
                    "timestamp": { "type": "string", "format": "date-time" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/submit-complaint": {
      "post": {
        "summary": "Submit a landowner complaint",
        "description": "Creates a new utility pole complaint with photo evidence, GPS coordinates, and environmental context. Computes SHA-256 forensic hash chain. Rate limited to 5 requests per hour per IP. Requires Cloudflare Turnstile CAPTCHA for public submissions.",
        "tags": ["Complaints"],
        "security": [],
        "x-rate-limit": "5 requests/hour per IP",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["description", "category", "photoHash"],
                "properties": {
                  "description": { "type": "string", "minLength": 20, "maxLength": 5000, "description": "Detailed description of the pole issue" },
                  "category": { "type": "string", "enum": ["structural_lean", "wire_sag", "downed_wire", "wildlife_damage", "guy_wire_failure", "fire_risk", "equipment_damage", "accessibility_hazard", "vegetation_contact"] },
                  "latitude": { "type": "number", "minimum": -90, "maximum": 90 },
                  "longitude": { "type": "number", "minimum": -180, "maximum": 180 },
                  "locationMethod": { "type": "string", "enum": ["device_gps", "address", "map_pin", "description_only"] },
                  "photoHash": { "type": "string", "pattern": "^[0-9a-f]{64}$", "description": "SHA-256 hash of the photo file" },
                  "photoUrl": { "type": "string", "format": "uri", "description": "Supabase Storage URL of uploaded photo" },
                  "contactEmail": { "type": "string", "format": "email" },
                  "contactPhone": { "type": "string" },
                  "poleTag": { "type": "string", "description": "Visible pole asset tag if readable" },
                  "reportSource": { "type": "string", "enum": ["landowner", "utility_staff", "internal_finding"] },
                  "language": { "type": "string", "enum": ["en", "es"], "default": "en" },
                  "turnstileToken": { "type": "string", "description": "Cloudflare Turnstile CAPTCHA token" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Complaint created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "complaintId": { "type": "string", "format": "uuid" },
                    "complaintNumber": { "type": "string", "pattern": "^LC-\\d{4}-\\d{4}$", "example": "LC-2026-0847" },
                    "trackingCode": { "type": "string" },
                    "forensicHash": { "type": "string", "pattern": "^[0-9a-f]{64}$" }
                  }
                }
              }
            }
          },
          "422": { "description": "Validation error (missing required fields or invalid format)" },
          "429": { "description": "Rate limit exceeded" }
        }
      }
    },
    "/complaints": {
      "get": {
        "summary": "List complaints for your utility",
        "description": "Returns all complaints associated with the authenticated user's utility. PII fields are encrypted and decrypted server-side for authorized users only.",
        "tags": ["Complaints"],
        "security": [{ "BearerAuth": [] }],
        "parameters": [
          { "name": "status", "in": "query", "schema": { "type": "string", "enum": ["pending", "acknowledged", "assigned", "in_progress", "resolved", "verified", "escalated"] } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 50 } }
        ],
        "responses": {
          "200": {
            "description": "List of complaints",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": { "$ref": "#/components/schemas/Complaint" }
                }
              }
            }
          },
          "401": { "description": "Authentication required" }
        }
      }
    },
    "/verify-chain": {
      "get": {
        "summary": "Verify record integrity",
        "description": "Validates the SHA-256 hash chain for a complaint record. Public endpoint — no authentication required. Returns chain validity, length, and optional environmental hash recomputation.",
        "tags": ["Verification"],
        "security": [],
        "x-rate-limit": "30 requests/minute",
        "parameters": [
          { "name": "id", "in": "query", "required": true, "schema": { "type": "string" }, "description": "Complaint UUID or demo ID" },
          { "name": "verify_env", "in": "query", "schema": { "type": "boolean", "default": false }, "description": "Also verify environmental hash by recomputing from stored context" }
        ],
        "responses": {
          "200": {
            "description": "Chain verification result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "valid": { "type": "boolean" },
                    "chain_length": { "type": "integer" },
                    "broken_at": { "type": "string", "nullable": true },
                    "env_verification": {
                      "type": "object",
                      "properties": {
                        "valid": { "type": "boolean" },
                        "recomputed": { "type": "string" },
                        "stored": { "type": "string" }
                      }
                    },
                    "entries": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "action": { "type": "string" },
                          "forensic_hash": { "type": "string" },
                          "previous_hash": { "type": "string", "nullable": true },
                          "chain_valid": { "type": "boolean" },
                          "created_at": { "type": "string", "format": "date-time" }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": { "description": "Missing or invalid complaint ID" },
          "404": { "description": "No hash chain found" },
          "429": { "description": "Rate limit exceeded" }
        }
      }
    },
    "/export/hb144": {
      "post": {
        "summary": "Generate PUCT HB 144 report",
        "description": "Generates a monthly or annual PUCT compliance report in PDF or CSV format. Report sections are configurable via the template settings.",
        "tags": ["Exports"],
        "security": [{ "BearerAuth": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["type"],
                "properties": {
                  "type": { "type": "string", "enum": ["monthly", "plan_summary"] },
                  "month": { "type": "integer", "minimum": 1, "maximum": 12 },
                  "year": { "type": "integer" },
                  "format": { "type": "string", "enum": ["pdf", "csv"], "default": "pdf" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "PDF or CSV file", "content": { "application/pdf": {}, "text/csv": {} } },
          "401": { "description": "Authentication required" }
        }
      }
    },
    "/export/nerc-fac003": {
      "post": {
        "summary": "Generate NERC FAC-003-5 evidence report",
        "description": "Generates a NERC FAC-003-5 transmission vegetation management compliance report with MVCD clearance tracking and forensic chain attestation.",
        "tags": ["Exports"],
        "security": [{ "BearerAuth": [] }],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "startDate": { "type": "string", "format": "date" },
                  "endDate": { "type": "string", "format": "date" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "PDF report" },
          "401": { "description": "Authentication required" }
        }
      }
    },
    "/integration": {
      "post": {
        "summary": "External system integration webhook",
        "description": "Accepts complaint data from external systems (GIS, SCADA, work management). Validates against Zod schema and creates a complaint record with full forensic sealing.",
        "tags": ["Integration"],
        "security": [{ "BearerAuth": [] }],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["description", "category", "landowner_email"],
                "properties": {
                  "description": { "type": "string" },
                  "category": { "type": "string" },
                  "landowner_email": { "type": "string", "format": "email" },
                  "landowner_phone": { "type": "string" },
                  "latitude": { "type": "number" },
                  "longitude": { "type": "number" },
                  "pole_asset_tag": { "type": "string" },
                  "external_id": { "type": "string", "description": "Your system's reference ID" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Complaint created" },
          "401": { "description": "Authentication required" },
          "422": { "description": "Validation error" }
        }
      }
    },
    "/resolve": {
      "post": {
        "summary": "Submit complaint resolution",
        "description": "Records a field inspection resolution with photo evidence, GPS verification, and optional digital signature. GPS must be within 50m of the assigned pole (or supervisor override).",
        "tags": ["Inspections"],
        "security": [{ "BearerAuth": [] }],
        "x-rate-limit": "10 requests/minute",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["complaintId", "condition", "photoHash"],
                "properties": {
                  "complaintId": { "type": "string", "format": "uuid" },
                  "condition": { "type": "string", "enum": ["safe", "needs_repair", "critical"] },
                  "notes": { "type": "string" },
                  "photoHash": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
                  "gpsLat": { "type": "number" },
                  "gpsLng": { "type": "number" },
                  "gpsVerified": { "type": "boolean" },
                  "digitalSignature": {
                    "type": "object",
                    "description": "Required for P1/P2 severity",
                    "properties": {
                      "name": { "type": "string" },
                      "timestamp": { "type": "string", "format": "date-time" },
                      "gps": { "type": "object", "properties": { "lat": { "type": "number" }, "lng": { "type": "number" } } },
                      "session_id": { "type": "string" }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Resolution recorded" },
          "401": { "description": "Authentication required" },
          "422": { "description": "Validation error or GPS outside 50m threshold" }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "Supabase Auth JWT token obtained via magic link login. Include as: Authorization: Bearer <token>"
      }
    },
    "schemas": {
      "Complaint": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "tracking_code": { "type": "string" },
          "complaint_number": { "type": "string", "example": "LC-2026-0847" },
          "category": { "type": "string" },
          "status": { "type": "string", "enum": ["pending", "acknowledged", "assigned", "in_progress", "resolved", "verified", "escalated"] },
          "description": { "type": "string" },
          "created_at": { "type": "string", "format": "date-time" },
          "photo_hash": { "type": "string", "description": "SHA-256 of original photo" },
          "forensic_hash": { "type": "string", "description": "Environmental context hash" },
          "lat": { "type": "number" },
          "lng": { "type": "number" },
          "sla_met": { "type": "boolean", "nullable": true }
        }
      }
    }
  }
}
