feat(api): add OpenAPI documentation
This commit is contained in:
363
backend/internal/httpapi/openapi.json
Normal file
363
backend/internal/httpapi/openapi.json
Normal file
@@ -0,0 +1,363 @@
|
||||
{
|
||||
"openapi": "3.0.3",
|
||||
"info": {
|
||||
"title": "Card to IBAN API",
|
||||
"version": "1.0.0",
|
||||
"description": "Converts an Iranian bank card number to its IBAN."
|
||||
},
|
||||
"servers": [
|
||||
{
|
||||
"url": "/",
|
||||
"description": "Current server"
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
{
|
||||
"name": "System"
|
||||
},
|
||||
{
|
||||
"name": "Conversion"
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
"/health": {
|
||||
"get": {
|
||||
"tags": ["System"],
|
||||
"summary": "Check service health",
|
||||
"operationId": "getHealth",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The service is running.",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HealthResponse"
|
||||
},
|
||||
"example": {
|
||||
"status": "ok"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/card-to-iban": {
|
||||
"post": {
|
||||
"tags": ["Conversion"],
|
||||
"summary": "Convert a card number to an IBAN",
|
||||
"operationId": "convertCardToIBAN",
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ConvertRequest"
|
||||
},
|
||||
"example": {
|
||||
"card": "6037997512345678"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The card number was converted successfully.",
|
||||
"headers": {
|
||||
"X-Request-ID": {
|
||||
"$ref": "#/components/headers/RequestID"
|
||||
}
|
||||
},
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ConvertResponse"
|
||||
},
|
||||
"example": {
|
||||
"data": {
|
||||
"iban": "IR820540102680020817909002"
|
||||
},
|
||||
"requestId": "SERVER_GENERATED_REQUEST_ID"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"$ref": "#/components/responses/InvalidCard"
|
||||
},
|
||||
"405": {
|
||||
"$ref": "#/components/responses/MethodNotAllowed"
|
||||
},
|
||||
"422": {
|
||||
"$ref": "#/components/responses/ConversionRejected"
|
||||
},
|
||||
"500": {
|
||||
"$ref": "#/components/responses/InternalError"
|
||||
},
|
||||
"502": {
|
||||
"$ref": "#/components/responses/UpstreamFailure"
|
||||
},
|
||||
"503": {
|
||||
"$ref": "#/components/responses/UpstreamUnavailable"
|
||||
},
|
||||
"504": {
|
||||
"$ref": "#/components/responses/UpstreamTimeout"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"headers": {
|
||||
"RequestID": {
|
||||
"description": "Identifier generated for tracing this request.",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
},
|
||||
"example": "SERVER_GENERATED_REQUEST_ID"
|
||||
}
|
||||
},
|
||||
"schemas": {
|
||||
"HealthResponse": {
|
||||
"type": "object",
|
||||
"required": ["status"],
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": ["ok"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"ConvertRequest": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["card"],
|
||||
"properties": {
|
||||
"card": {
|
||||
"type": "string",
|
||||
"description": "Iranian bank card number containing exactly 16 ASCII digits.",
|
||||
"pattern": "^[0-9]{16}$",
|
||||
"minLength": 16,
|
||||
"maxLength": 16,
|
||||
"example": "6037997512345678"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ConvertResponse": {
|
||||
"type": "object",
|
||||
"required": ["data", "requestId"],
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/components/schemas/ConvertData"
|
||||
},
|
||||
"requestId": {
|
||||
"type": "string",
|
||||
"example": "SERVER_GENERATED_REQUEST_ID"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ConvertData": {
|
||||
"type": "object",
|
||||
"required": ["iban"],
|
||||
"properties": {
|
||||
"iban": {
|
||||
"type": "string",
|
||||
"pattern": "^IR[0-9]{24}$",
|
||||
"example": "IR820540102680020817909002"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ErrorResponse": {
|
||||
"type": "object",
|
||||
"required": ["error", "requestId"],
|
||||
"properties": {
|
||||
"error": {
|
||||
"$ref": "#/components/schemas/ErrorDetail"
|
||||
},
|
||||
"requestId": {
|
||||
"type": "string",
|
||||
"example": "SERVER_GENERATED_REQUEST_ID"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ErrorDetail": {
|
||||
"type": "object",
|
||||
"required": ["code", "message"],
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"invalid_card",
|
||||
"method_not_allowed",
|
||||
"conversion_rejected",
|
||||
"internal_error",
|
||||
"upstream_failure",
|
||||
"upstream_unavailable",
|
||||
"upstream_timeout"
|
||||
]
|
||||
},
|
||||
"message": {
|
||||
"type": "string",
|
||||
"description": "A user-facing error message in Persian."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"InvalidCard": {
|
||||
"description": "The JSON body or card number is invalid.",
|
||||
"headers": {
|
||||
"X-Request-ID": {
|
||||
"$ref": "#/components/headers/RequestID"
|
||||
}
|
||||
},
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ErrorResponse"
|
||||
},
|
||||
"example": {
|
||||
"error": {
|
||||
"code": "invalid_card",
|
||||
"message": "شماره کارت باید شامل ۱۶ رقم باشد."
|
||||
},
|
||||
"requestId": "SERVER_GENERATED_REQUEST_ID"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"MethodNotAllowed": {
|
||||
"description": "The request method is not supported for this path.",
|
||||
"headers": {
|
||||
"X-Request-ID": {
|
||||
"$ref": "#/components/headers/RequestID"
|
||||
}
|
||||
},
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ErrorResponse"
|
||||
},
|
||||
"example": {
|
||||
"error": {
|
||||
"code": "method_not_allowed",
|
||||
"message": "این روش برای این مسیر پشتیبانی نمیشود."
|
||||
},
|
||||
"requestId": "SERVER_GENERATED_REQUEST_ID"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ConversionRejected": {
|
||||
"description": "The upstream service rejected the conversion.",
|
||||
"headers": {
|
||||
"X-Request-ID": {
|
||||
"$ref": "#/components/headers/RequestID"
|
||||
}
|
||||
},
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ErrorResponse"
|
||||
},
|
||||
"example": {
|
||||
"error": {
|
||||
"code": "conversion_rejected",
|
||||
"message": "تبدیل این شماره کارت انجام نشد."
|
||||
},
|
||||
"requestId": "SERVER_GENERATED_REQUEST_ID"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"InternalError": {
|
||||
"description": "An internal operation failed.",
|
||||
"headers": {
|
||||
"X-Request-ID": {
|
||||
"$ref": "#/components/headers/RequestID"
|
||||
}
|
||||
},
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ErrorResponse"
|
||||
},
|
||||
"example": {
|
||||
"error": {
|
||||
"code": "internal_error",
|
||||
"message": "خطایی در پردازش درخواست رخ داد."
|
||||
},
|
||||
"requestId": "SERVER_GENERATED_REQUEST_ID"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"UpstreamFailure": {
|
||||
"description": "Upstream authentication failed or its response was invalid.",
|
||||
"headers": {
|
||||
"X-Request-ID": {
|
||||
"$ref": "#/components/headers/RequestID"
|
||||
}
|
||||
},
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ErrorResponse"
|
||||
},
|
||||
"example": {
|
||||
"error": {
|
||||
"code": "upstream_failure",
|
||||
"message": "ارتباط با سرویس بانکی با خطا روبهرو شد."
|
||||
},
|
||||
"requestId": "SERVER_GENERATED_REQUEST_ID"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"UpstreamUnavailable": {
|
||||
"description": "The upstream service is temporarily unavailable.",
|
||||
"headers": {
|
||||
"X-Request-ID": {
|
||||
"$ref": "#/components/headers/RequestID"
|
||||
}
|
||||
},
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ErrorResponse"
|
||||
},
|
||||
"example": {
|
||||
"error": {
|
||||
"code": "upstream_unavailable",
|
||||
"message": "سرویس بانکی موقتاً در دسترس نیست."
|
||||
},
|
||||
"requestId": "SERVER_GENERATED_REQUEST_ID"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"UpstreamTimeout": {
|
||||
"description": "The upstream request timed out.",
|
||||
"headers": {
|
||||
"X-Request-ID": {
|
||||
"$ref": "#/components/headers/RequestID"
|
||||
}
|
||||
},
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ErrorResponse"
|
||||
},
|
||||
"example": {
|
||||
"error": {
|
||||
"code": "upstream_timeout",
|
||||
"message": "پاسخ سرویس بانکی بیش از حد طول کشید."
|
||||
},
|
||||
"requestId": "SERVER_GENERATED_REQUEST_ID"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user