feat: Goa GEL Blockchain e-Licensing Platform - Full Stack Implementation
Complete implementation of the Goa Government e-Licensing platform with: Backend: - NestJS API with JWT authentication - PostgreSQL database with Knex ORM - Redis caching and session management - MinIO document storage - Hyperledger Besu blockchain integration - Multi-department workflow system - Comprehensive API tests (266/282 passing) Frontend: - Angular 21 with standalone components - Angular Material + TailwindCSS UI - Visual workflow builder - Document upload with progress tracking - Blockchain explorer integration - Role-based dashboards (Admin, Department, Citizen) - E2E tests with Playwright (37 tests) Infrastructure: - Docker Compose orchestration - Blockscout blockchain explorer - Development and production configurations
This commit is contained in:
3448
api/openapi.json
Normal file
3448
api/openapi.json
Normal file
File diff suppressed because it is too large
Load Diff
2283
api/openapi.yaml
Normal file
2283
api/openapi.yaml
Normal file
File diff suppressed because it is too large
Load Diff
543
api/swagger-ui.html
Normal file
543
api/swagger-ui.html
Normal file
@@ -0,0 +1,543 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Goa GEL API Documentation</title>
|
||||
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5.11.0/swagger-ui.css">
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.swagger-ui .topbar {
|
||||
background-color: #1a365d;
|
||||
}
|
||||
.swagger-ui .info .title {
|
||||
color: #1a365d;
|
||||
}
|
||||
.swagger-ui .scheme-container {
|
||||
background: #f8f9fa;
|
||||
padding: 20px;
|
||||
}
|
||||
/* Custom header */
|
||||
.custom-header {
|
||||
background: linear-gradient(135deg, #1a365d 0%, #2c5282 100%);
|
||||
color: white;
|
||||
padding: 30px 50px;
|
||||
text-align: center;
|
||||
}
|
||||
.custom-header h1 {
|
||||
margin: 0 0 10px 0;
|
||||
font-size: 28px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.custom-header p {
|
||||
margin: 0;
|
||||
opacity: 0.9;
|
||||
font-size: 16px;
|
||||
}
|
||||
.custom-header .badges {
|
||||
margin-top: 15px;
|
||||
}
|
||||
.custom-header .badge {
|
||||
display: inline-block;
|
||||
background: rgba(255,255,255,0.2);
|
||||
padding: 5px 12px;
|
||||
border-radius: 20px;
|
||||
margin: 0 5px;
|
||||
font-size: 13px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="custom-header">
|
||||
<h1>🏛️ Goa GEL - Blockchain Document Verification Platform</h1>
|
||||
<p>Government of Goa | Hyperledger Besu | ERC-721 Soulbound NFTs</p>
|
||||
<div class="badges">
|
||||
<span class="badge">OpenAPI 3.0</span>
|
||||
<span class="badge">REST API</span>
|
||||
<span class="badge">Blockchain-backed</span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="swagger-ui"></div>
|
||||
|
||||
<script src="https://unpkg.com/swagger-ui-dist@5.11.0/swagger-ui-bundle.js"></script>
|
||||
<script src="https://unpkg.com/swagger-ui-dist@5.11.0/swagger-ui-standalone-preset.js"></script>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
// OpenAPI spec embedded inline
|
||||
const spec = {
|
||||
"openapi": "3.0.3",
|
||||
"info": {
|
||||
"title": "Goa GEL - Blockchain Document Verification Platform API",
|
||||
"description": "## Overview\nREST API for the Government of Goa's Blockchain-based Document Verification Platform (GEL).\nThis platform enables multi-department approval workflows for various licenses and permits,\nwith blockchain-backed verification using Hyperledger Besu and ERC-721 Soulbound NFTs.\n\n## Authentication\n- **Department APIs**: Use `X-API-Key` and `X-Department-Code` headers\n- **Applicant APIs**: Use Bearer token from DigiLocker authentication (mock for POC)\n- **Admin APIs**: Use Bearer token with admin role\n\n## Blockchain Integration\nAll critical operations (request creation, approvals, document updates) are recorded on-chain.\nResponse includes `transactionHash` for blockchain verification.\n\n## Webhooks\nDepartments can register webhooks to receive real-time notifications for:\n- `APPROVAL_REQUIRED` - New request pending approval\n- `DOCUMENT_UPDATED` - Applicant updated a document\n- `REQUEST_APPROVED` - Request fully approved\n- `REQUEST_REJECTED` - Request rejected",
|
||||
"version": "1.0.0",
|
||||
"contact": {
|
||||
"name": "Goa GEL Platform Support",
|
||||
"email": "support@goagel.gov.in"
|
||||
}
|
||||
},
|
||||
"servers": [
|
||||
{"url": "https://api.goagel.gov.in/api/v1", "description": "Production server"},
|
||||
{"url": "https://staging-api.goagel.gov.in/api/v1", "description": "Staging server"},
|
||||
{"url": "http://localhost:3001/api/v1", "description": "Local development"}
|
||||
],
|
||||
"tags": [
|
||||
{"name": "Requests", "description": "License request operations"},
|
||||
{"name": "Documents", "description": "Document upload and retrieval"},
|
||||
{"name": "Approvals", "description": "Department approval actions"},
|
||||
{"name": "Departments", "description": "Department management"},
|
||||
{"name": "Workflows", "description": "Workflow configuration"},
|
||||
{"name": "Webhooks", "description": "Webhook management"},
|
||||
{"name": "Admin", "description": "Platform administration"},
|
||||
{"name": "Verification", "description": "Public verification endpoints"}
|
||||
],
|
||||
"paths": {
|
||||
"/requests": {
|
||||
"post": {
|
||||
"tags": ["Requests"],
|
||||
"summary": "Create new license request",
|
||||
"description": "Creates a new license request and mints a draft NFT on the blockchain.",
|
||||
"operationId": "createRequest",
|
||||
"security": [{"BearerAuth": []}],
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {"$ref": "#/components/schemas/CreateRequestInput"},
|
||||
"example": {
|
||||
"applicantId": "DL-GOA-123456789",
|
||||
"requestType": "RESORT_LICENSE",
|
||||
"metadata": {
|
||||
"resortName": "Paradise Beach Resort",
|
||||
"location": "Calangute, North Goa",
|
||||
"plotArea": 5000,
|
||||
"builtUpArea": 3500,
|
||||
"numberOfRooms": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"201": {"description": "Request created successfully", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RequestResponse"}}}},
|
||||
"400": {"$ref": "#/components/responses/BadRequest"},
|
||||
"401": {"$ref": "#/components/responses/Unauthorized"}
|
||||
}
|
||||
},
|
||||
"get": {
|
||||
"tags": ["Requests"],
|
||||
"summary": "List requests",
|
||||
"description": "Get list of requests with optional filters",
|
||||
"operationId": "listRequests",
|
||||
"security": [{"BearerAuth": []}, {"ApiKeyAuth": []}],
|
||||
"parameters": [
|
||||
{"name": "status", "in": "query", "schema": {"$ref": "#/components/schemas/RequestStatus"}},
|
||||
{"name": "requestType", "in": "query", "schema": {"type": "string", "example": "RESORT_LICENSE"}},
|
||||
{"name": "page", "in": "query", "schema": {"type": "integer", "default": 1}},
|
||||
{"name": "limit", "in": "query", "schema": {"type": "integer", "default": 20}}
|
||||
],
|
||||
"responses": {"200": {"description": "List of requests", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RequestListResponse"}}}}}
|
||||
}
|
||||
},
|
||||
"/requests/pending": {
|
||||
"get": {
|
||||
"tags": ["Requests"],
|
||||
"summary": "Get requests pending for department",
|
||||
"operationId": "getPendingRequests",
|
||||
"security": [{"ApiKeyAuth": []}],
|
||||
"parameters": [
|
||||
{"name": "department", "in": "query", "required": true, "schema": {"type": "string"}, "example": "FIRE_DEPT"}
|
||||
],
|
||||
"responses": {"200": {"description": "List of pending requests"}}
|
||||
}
|
||||
},
|
||||
"/requests/{requestId}": {
|
||||
"get": {
|
||||
"tags": ["Requests"],
|
||||
"summary": "Get request details",
|
||||
"operationId": "getRequest",
|
||||
"security": [{"BearerAuth": []}, {"ApiKeyAuth": []}],
|
||||
"parameters": [{"$ref": "#/components/parameters/RequestId"}],
|
||||
"responses": {
|
||||
"200": {"description": "Request details", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RequestDetailResponse"}}}},
|
||||
"404": {"$ref": "#/components/responses/NotFound"}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/requests/{requestId}/submit": {
|
||||
"post": {
|
||||
"tags": ["Requests"],
|
||||
"summary": "Submit request for approval",
|
||||
"description": "Submits the request for departmental approval workflow.",
|
||||
"operationId": "submitRequest",
|
||||
"security": [{"BearerAuth": []}],
|
||||
"parameters": [{"$ref": "#/components/parameters/RequestId"}],
|
||||
"responses": {"200": {"description": "Request submitted successfully"}}
|
||||
}
|
||||
},
|
||||
"/requests/{requestId}/documents": {
|
||||
"post": {
|
||||
"tags": ["Documents"],
|
||||
"summary": "Upload document",
|
||||
"description": "Uploads a document. Hash is recorded on blockchain.",
|
||||
"operationId": "uploadDocument",
|
||||
"security": [{"BearerAuth": []}],
|
||||
"parameters": [{"$ref": "#/components/parameters/RequestId"}],
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"multipart/form-data": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": ["file", "docType"],
|
||||
"properties": {
|
||||
"file": {"type": "string", "format": "binary"},
|
||||
"docType": {"type": "string", "example": "FIRE_SAFETY_CERTIFICATE"},
|
||||
"description": {"type": "string"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {"201": {"description": "Document uploaded"}}
|
||||
}
|
||||
},
|
||||
"/requests/{requestId}/approve": {
|
||||
"post": {
|
||||
"tags": ["Approvals"],
|
||||
"summary": "Approve request",
|
||||
"description": "Records department approval on the blockchain.",
|
||||
"operationId": "approveRequest",
|
||||
"security": [{"ApiKeyAuth": []}],
|
||||
"parameters": [{"$ref": "#/components/parameters/RequestId"}],
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": ["remarks", "reviewedDocuments"],
|
||||
"properties": {
|
||||
"remarks": {"type": "string", "example": "All fire safety requirements met"},
|
||||
"reviewedDocuments": {"type": "array", "items": {"type": "string", "format": "uuid"}}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {"200": {"description": "Approval recorded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ApprovalResponse"}}}}}
|
||||
}
|
||||
},
|
||||
"/requests/{requestId}/reject": {
|
||||
"post": {
|
||||
"tags": ["Approvals"],
|
||||
"summary": "Reject request",
|
||||
"operationId": "rejectRequest",
|
||||
"security": [{"ApiKeyAuth": []}],
|
||||
"parameters": [{"$ref": "#/components/parameters/RequestId"}],
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": ["remarks", "reason"],
|
||||
"properties": {
|
||||
"remarks": {"type": "string"},
|
||||
"reason": {"type": "string", "enum": ["SAFETY_VIOLATION", "INCOMPLETE_DOCUMENTS", "POLICY_VIOLATION", "FRAUDULENT_APPLICATION", "OTHER"]}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {"200": {"description": "Rejection recorded"}}
|
||||
}
|
||||
},
|
||||
"/requests/{requestId}/request-changes": {
|
||||
"post": {
|
||||
"tags": ["Approvals"],
|
||||
"summary": "Request changes",
|
||||
"operationId": "requestChanges",
|
||||
"security": [{"ApiKeyAuth": []}],
|
||||
"parameters": [{"$ref": "#/components/parameters/RequestId"}],
|
||||
"responses": {"200": {"description": "Changes requested"}}
|
||||
}
|
||||
},
|
||||
"/departments": {
|
||||
"get": {
|
||||
"tags": ["Departments"],
|
||||
"summary": "List all departments",
|
||||
"operationId": "listDepartments",
|
||||
"security": [{"BearerAuth": []}, {"ApiKeyAuth": []}],
|
||||
"responses": {"200": {"description": "List of departments"}}
|
||||
},
|
||||
"post": {
|
||||
"tags": ["Departments"],
|
||||
"summary": "Register new department",
|
||||
"operationId": "createDepartment",
|
||||
"security": [{"AdminAuth": []}],
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreateDepartmentInput"}}}
|
||||
},
|
||||
"responses": {"201": {"description": "Department created"}}
|
||||
}
|
||||
},
|
||||
"/workflows": {
|
||||
"get": {
|
||||
"tags": ["Workflows"],
|
||||
"summary": "List workflow definitions",
|
||||
"operationId": "listWorkflows",
|
||||
"security": [{"AdminAuth": []}],
|
||||
"responses": {"200": {"description": "List of workflows"}}
|
||||
},
|
||||
"post": {
|
||||
"tags": ["Workflows"],
|
||||
"summary": "Create workflow definition",
|
||||
"operationId": "createWorkflow",
|
||||
"security": [{"AdminAuth": []}],
|
||||
"responses": {"201": {"description": "Workflow created"}}
|
||||
}
|
||||
},
|
||||
"/webhooks": {
|
||||
"get": {
|
||||
"tags": ["Webhooks"],
|
||||
"summary": "List registered webhooks",
|
||||
"operationId": "listWebhooks",
|
||||
"security": [{"ApiKeyAuth": []}, {"AdminAuth": []}],
|
||||
"responses": {"200": {"description": "List of webhooks"}}
|
||||
},
|
||||
"post": {
|
||||
"tags": ["Webhooks"],
|
||||
"summary": "Register webhook",
|
||||
"operationId": "createWebhook",
|
||||
"security": [{"ApiKeyAuth": []}],
|
||||
"responses": {"201": {"description": "Webhook registered"}}
|
||||
}
|
||||
},
|
||||
"/admin/stats": {
|
||||
"get": {
|
||||
"tags": ["Admin"],
|
||||
"summary": "Get platform statistics",
|
||||
"operationId": "getPlatformStats",
|
||||
"security": [{"AdminAuth": []}],
|
||||
"responses": {"200": {"description": "Platform statistics"}}
|
||||
}
|
||||
},
|
||||
"/admin/blockchain/status": {
|
||||
"get": {
|
||||
"tags": ["Admin"],
|
||||
"summary": "Get blockchain network status",
|
||||
"operationId": "getBlockchainStatus",
|
||||
"security": [{"AdminAuth": []}],
|
||||
"responses": {"200": {"description": "Blockchain status"}}
|
||||
}
|
||||
},
|
||||
"/verify/{tokenId}": {
|
||||
"get": {
|
||||
"tags": ["Verification"],
|
||||
"summary": "Verify license by token ID",
|
||||
"description": "Public endpoint for verifying a license using its NFT token ID. No authentication required.",
|
||||
"operationId": "verifyByTokenId",
|
||||
"parameters": [{"name": "tokenId", "in": "path", "required": true, "schema": {"type": "integer"}, "example": 12345}],
|
||||
"responses": {"200": {"description": "Verification result", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/VerificationResponse"}}}}}
|
||||
}
|
||||
},
|
||||
"/verify/document/{hash}": {
|
||||
"get": {
|
||||
"tags": ["Verification"],
|
||||
"summary": "Verify document by hash",
|
||||
"operationId": "verifyDocumentByHash",
|
||||
"parameters": [{"name": "hash", "in": "path", "required": true, "schema": {"type": "string"}}],
|
||||
"responses": {"200": {"description": "Document verification result"}}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"securitySchemes": {
|
||||
"BearerAuth": {"type": "http", "scheme": "bearer", "bearerFormat": "JWT", "description": "JWT token from DigiLocker authentication"},
|
||||
"ApiKeyAuth": {"type": "apiKey", "in": "header", "name": "X-API-Key", "description": "Department API key. Must be used with X-Department-Code header."},
|
||||
"AdminAuth": {"type": "http", "scheme": "bearer", "bearerFormat": "JWT", "description": "Admin JWT token"}
|
||||
},
|
||||
"parameters": {
|
||||
"RequestId": {"name": "requestId", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}, "description": "Unique request identifier"}
|
||||
},
|
||||
"responses": {
|
||||
"BadRequest": {"description": "Bad request", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}},
|
||||
"Unauthorized": {"description": "Unauthorized", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}},
|
||||
"NotFound": {"description": "Resource not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}
|
||||
},
|
||||
"schemas": {
|
||||
"CreateRequestInput": {
|
||||
"type": "object",
|
||||
"required": ["applicantId", "requestType"],
|
||||
"properties": {
|
||||
"applicantId": {"type": "string", "description": "DigiLocker ID", "example": "DL-GOA-123456789"},
|
||||
"requestType": {"type": "string", "enum": ["RESORT_LICENSE", "TRADE_LICENSE", "BUILDING_PERMIT"], "example": "RESORT_LICENSE"},
|
||||
"metadata": {"type": "object", "description": "Request-specific data"}
|
||||
}
|
||||
},
|
||||
"CreateDepartmentInput": {
|
||||
"type": "object",
|
||||
"required": ["code", "name"],
|
||||
"properties": {
|
||||
"code": {"type": "string", "pattern": "^[A-Z_]+$", "example": "FIRE_DEPT"},
|
||||
"name": {"type": "string", "example": "Fire & Emergency Services Department"},
|
||||
"webhookUrl": {"type": "string", "format": "uri"}
|
||||
}
|
||||
},
|
||||
"RequestResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"requestId": {"type": "string", "format": "uuid"},
|
||||
"requestNumber": {"type": "string", "example": "RL-2024-001234"},
|
||||
"status": {"$ref": "#/components/schemas/RequestStatus"},
|
||||
"transactionHash": {"type": "string"},
|
||||
"createdAt": {"type": "string", "format": "date-time"}
|
||||
}
|
||||
},
|
||||
"RequestListResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"requests": {"type": "array", "items": {"$ref": "#/components/schemas/RequestSummary"}},
|
||||
"pagination": {"$ref": "#/components/schemas/Pagination"}
|
||||
}
|
||||
},
|
||||
"RequestSummary": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"requestId": {"type": "string", "format": "uuid"},
|
||||
"requestNumber": {"type": "string"},
|
||||
"requestType": {"type": "string"},
|
||||
"status": {"$ref": "#/components/schemas/RequestStatus"},
|
||||
"applicantName": {"type": "string"},
|
||||
"currentStage": {"type": "string"},
|
||||
"createdAt": {"type": "string", "format": "date-time"}
|
||||
}
|
||||
},
|
||||
"RequestDetailResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"requestId": {"type": "string", "format": "uuid"},
|
||||
"requestNumber": {"type": "string"},
|
||||
"tokenId": {"type": "integer"},
|
||||
"requestType": {"type": "string"},
|
||||
"status": {"$ref": "#/components/schemas/RequestStatus"},
|
||||
"applicant": {"type": "object", "properties": {"id": {"type": "string"}, "name": {"type": "string"}, "email": {"type": "string"}}},
|
||||
"documents": {"type": "array", "items": {"$ref": "#/components/schemas/Document"}},
|
||||
"approvals": {"type": "array", "items": {"$ref": "#/components/schemas/Approval"}},
|
||||
"blockchainData": {"type": "object", "properties": {"tokenId": {"type": "integer"}, "contractAddress": {"type": "string"}, "creationTxHash": {"type": "string"}}}
|
||||
}
|
||||
},
|
||||
"ApprovalResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"approvalId": {"type": "string", "format": "uuid"},
|
||||
"status": {"$ref": "#/components/schemas/ApprovalStatus"},
|
||||
"transactionHash": {"type": "string"},
|
||||
"workflowStatus": {"type": "object", "properties": {"currentStage": {"type": "string"}, "isComplete": {"type": "boolean"}, "nextPendingDepartments": {"type": "array", "items": {"type": "string"}}}}
|
||||
}
|
||||
},
|
||||
"VerificationResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"isValid": {"type": "boolean"},
|
||||
"tokenId": {"type": "integer"},
|
||||
"requestNumber": {"type": "string"},
|
||||
"requestType": {"type": "string"},
|
||||
"status": {"$ref": "#/components/schemas/RequestStatus"},
|
||||
"applicantName": {"type": "string"},
|
||||
"issuedAt": {"type": "string", "format": "date-time"},
|
||||
"approvals": {"type": "array", "items": {"type": "object", "properties": {"departmentName": {"type": "string"}, "approvedAt": {"type": "string", "format": "date-time"}}}},
|
||||
"blockchainProof": {"type": "object", "properties": {"contractAddress": {"type": "string"}, "tokenId": {"type": "integer"}, "transactionHash": {"type": "string"}}}
|
||||
}
|
||||
},
|
||||
"Document": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"documentId": {"type": "string", "format": "uuid"},
|
||||
"docType": {"type": "string"},
|
||||
"originalFilename": {"type": "string"},
|
||||
"currentVersion": {"type": "integer"},
|
||||
"currentHash": {"type": "string"},
|
||||
"uploadedAt": {"type": "string", "format": "date-time"}
|
||||
}
|
||||
},
|
||||
"Approval": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"approvalId": {"type": "string", "format": "uuid"},
|
||||
"departmentCode": {"type": "string"},
|
||||
"departmentName": {"type": "string"},
|
||||
"status": {"$ref": "#/components/schemas/ApprovalStatus"},
|
||||
"remarks": {"type": "string"},
|
||||
"isActive": {"type": "boolean"},
|
||||
"transactionHash": {"type": "string"},
|
||||
"createdAt": {"type": "string", "format": "date-time"}
|
||||
}
|
||||
},
|
||||
"RequestStatus": {
|
||||
"type": "string",
|
||||
"enum": ["DRAFT", "SUBMITTED", "IN_REVIEW", "PENDING_RESUBMISSION", "APPROVED", "REJECTED", "REVOKED", "CANCELLED"]
|
||||
},
|
||||
"ApprovalStatus": {
|
||||
"type": "string",
|
||||
"enum": ["PENDING", "APPROVED", "REJECTED", "CHANGES_REQUESTED", "REVIEW_REQUIRED"]
|
||||
},
|
||||
"Pagination": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"page": {"type": "integer"},
|
||||
"limit": {"type": "integer"},
|
||||
"total": {"type": "integer"},
|
||||
"totalPages": {"type": "integer"},
|
||||
"hasNext": {"type": "boolean"},
|
||||
"hasPrev": {"type": "boolean"}
|
||||
}
|
||||
},
|
||||
"Error": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"code": {"type": "string"},
|
||||
"message": {"type": "string"},
|
||||
"details": {"type": "object"},
|
||||
"timestamp": {"type": "string", "format": "date-time"},
|
||||
"path": {"type": "string"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const ui = SwaggerUIBundle({
|
||||
spec: spec,
|
||||
dom_id: '#swagger-ui',
|
||||
deepLinking: true,
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIStandalonePreset
|
||||
],
|
||||
plugins: [
|
||||
SwaggerUIBundle.plugins.DownloadUrl
|
||||
],
|
||||
layout: "StandaloneLayout",
|
||||
validatorUrl: null,
|
||||
defaultModelsExpandDepth: 1,
|
||||
defaultModelExpandDepth: 1,
|
||||
displayRequestDuration: true,
|
||||
filter: true,
|
||||
showExtensions: true,
|
||||
showCommonExtensions: true,
|
||||
syntaxHighlight: {
|
||||
activate: true,
|
||||
theme: "monokai"
|
||||
}
|
||||
});
|
||||
|
||||
window.ui = ui;
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user