From 7a1e3f869a47ecd5ea8d052ab5c9c877355ac5c2 Mon Sep 17 00:00:00 2001 From: SH-AHD Date: Sat, 11 Apr 2026 11:01:12 +0200 Subject: [PATCH 1/2] fix(orders): Fix the idempotency key issue --- index.js | 5 ++++- src/services/orderService.js | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index 7087329..d0a46bb 100644 --- a/index.js +++ b/index.js @@ -10,7 +10,10 @@ dotenv.config(); const app = express(); -app.use(cors()); +app.use(cors({ + origin: 'http://localhost:5173', + credentials: true +})); app.use(express.json()); app.use('/api/auth', authRoutes); diff --git a/src/services/orderService.js b/src/services/orderService.js index e77bd28..64e89ce 100644 --- a/src/services/orderService.js +++ b/src/services/orderService.js @@ -80,8 +80,8 @@ export const processOrder = async (buyerId, rawItems,idempotencyKey) => { const order = await tx.order.create({ data: { buyerId: bId, - idempotencyKey: idempotencyKey , - referenceId: `ORD-PAY-${Date.now()}-${crypto.randomBytes(3).toString('hex').toUpperCase()}`, + // idempotencyKey: idempotencyKey , + // referenceId: `ORD-PAY-${Date.now()}-${crypto.randomBytes(3).toString('hex').toUpperCase()}`, status: OrderStatus.PAID, totalAmount: totalAmount, items: { From 2daa103ebe242773dd830bf1e3cc8209209d964e Mon Sep 17 00:00:00 2001 From: KhaledSayed04 Date: Sun, 12 Apr 2026 05:37:20 +0200 Subject: [PATCH 2/2] feat(swagger): add basic auto-generated swagger documentation to the existing endpoints --- index.js | 7 + package-lock.json | 82 ++- package.json | 4 +- swagger-output.json | 1218 +++++++++++++++++++++++++++++++++++++++++++ swagger.js | 24 + 5 files changed, 1327 insertions(+), 8 deletions(-) create mode 100644 swagger-output.json create mode 100644 swagger.js diff --git a/index.js b/index.js index d0a46bb..381e555 100644 --- a/index.js +++ b/index.js @@ -5,17 +5,24 @@ import authRoutes from './src/routes/authRoutes.js'; import walletRoutes from './src/routes/walletRoutes.js'; import productRoutes from './src/routes/productRoutes.js'; import orderRoutes from './src/routes/orderRoutes.js'; +import swaggerUi from 'swagger-ui-express'; +import { createRequire } from 'module'; +const require = createRequire(import.meta.url); +const swaggerFile = require('./swagger-output.json'); dotenv.config(); const app = express(); + app.use(cors({ origin: 'http://localhost:5173', credentials: true })); app.use(express.json()); +app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerFile)); + app.use('/api/auth', authRoutes); app.use('/api/wallet', walletRoutes); app.use('/api/products', productRoutes); diff --git a/package-lock.json b/package-lock.json index 8e233bd..76a6189 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,8 @@ "express": "^5.2.1", "joi": "^18.0.2", "jsonwebtoken": "^9.0.3", - "pg": "^8.19.0" + "pg": "^8.19.0", + "swagger-autogen": "^2.23.7" }, "devDependencies": { "@types/express": "^5.0.6", @@ -1410,6 +1411,18 @@ "node": ">= 0.6" } }, + "node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -2032,7 +2045,6 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, "license": "MIT" }, "node_modules/content-disposition": { @@ -2150,7 +2162,6 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -2596,7 +2607,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true, "license": "ISC" }, "node_modules/function-bind": { @@ -2917,7 +2927,6 @@ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, "license": "ISC", "dependencies": { "once": "^1.3.0", @@ -3854,7 +3863,6 @@ "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, "license": "MIT", "bin": { "json5": "lib/cli.js" @@ -4398,7 +4406,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -5288,6 +5295,67 @@ "node": ">=4" } }, + "node_modules/swagger-autogen": { + "version": "2.23.7", + "resolved": "https://registry.npmjs.org/swagger-autogen/-/swagger-autogen-2.23.7.tgz", + "integrity": "sha512-vr7uRmuV0DCxWc0wokLJAwX3GwQFJ0jwN+AWk0hKxre2EZwusnkGSGdVFd82u7fQLgwSTnbWkxUL7HXuz5LTZQ==", + "license": "MIT", + "dependencies": { + "acorn": "^7.4.1", + "deepmerge": "^4.2.2", + "glob": "^7.1.7", + "json5": "^2.2.3" + } + }, + "node_modules/swagger-autogen/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/swagger-autogen/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/swagger-autogen/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/swagger-autogen/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/synckit": { "version": "0.11.12", "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.12.tgz", diff --git a/package.json b/package.json index dd3e788..046a63a 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "description": "", "main": "index.js", "scripts": { + "swagger": "node swagger.js", "start": "node index.js", "dev": "nodemon index.js", "test": "NODE_OPTIONS=--experimental-vm-modules jest", @@ -22,7 +23,8 @@ "express": "^5.2.1", "joi": "^18.0.2", "jsonwebtoken": "^9.0.3", - "pg": "^8.19.0" + "pg": "^8.19.0", + "swagger-autogen": "^2.23.7" }, "devDependencies": { "@types/express": "^5.0.6", diff --git a/swagger-output.json b/swagger-output.json new file mode 100644 index 0000000..a6d3969 --- /dev/null +++ b/swagger-output.json @@ -0,0 +1,1218 @@ +{ + "swagger": "2.0", + "info": { + "title": "The Unknowns S-T API", + "description": "Auto-generated documentation for all endpoints.", + "version": "1.0.0" + }, + "host": "localhost:3001", + "basePath": "/", + "schemes": [ + "http" + ], + "securityDefinitions": { + "bearerAuth": { + "type": "apiKey", + "name": "Authorization", + "scheme": "bearer", + "in": "header" + } + }, + "paths": { + "/api/auth/register": { + "post": { + "description": "", + "parameters": [ + { + "name": "body", + "in": "body", + "schema": { + "type": "object", + "properties": { + "email": { + "example": "any" + }, + "password": { + "example": "any" + } + } + } + } + ], + "responses": { + "201": { + "description": "Created" + }, + "400": { + "description": "Bad Request" + }, + "500": { + "description": "Internal Server Error" + } + } + } + }, + "/api/auth/login": { + "post": { + "description": "", + "parameters": [ + { + "name": "body", + "in": "body", + "schema": { + "type": "object", + "properties": { + "email": { + "example": "any" + }, + "password": { + "example": "any" + } + } + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Bad Request" + }, + "401": { + "description": "Unauthorized" + }, + "500": { + "description": "Internal Server Error" + } + } + } + }, + "/api/auth/users": { + "get": { + "description": "", + "parameters": [ + { + "name": "Authorization", + "in": "header", + "type": "string" + } + ], + "responses": { + "200": { + "description": "OK" + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "500": { + "description": "Internal Server Error" + } + } + } + }, + "/api/auth/profile": { + "get": { + "description": "", + "parameters": [ + { + "name": "Authorization", + "in": "header", + "type": "string" + } + ], + "responses": { + "200": { + "description": "OK" + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "Not Found" + }, + "500": { + "description": "Internal Server Error" + } + } + } + }, + "/api/wallet/deposit": { + "post": { + "description": "", + "parameters": [ + { + "name": "idempotency-key", + "in": "header", + "type": "string" + }, + { + "name": "body", + "in": "body", + "schema": { + "type": "object", + "properties": { + "amount": { + "example": "any" + }, + "description": { + "example": "any" + } + } + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Bad Request" + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "Not Found" + }, + "500": { + "description": "Internal Server Error" + } + } + } + }, + "/api/wallet/withdraw": { + "post": { + "description": "", + "parameters": [ + { + "name": "idempotency-key", + "in": "header", + "type": "string" + }, + { + "name": "body", + "in": "body", + "schema": { + "type": "object", + "properties": { + "amount": { + "example": "any" + }, + "description": { + "example": "any" + } + } + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Bad Request" + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "Not Found" + }, + "500": { + "description": "Internal Server Error" + } + } + } + }, + "/api/wallet/transfer": { + "post": { + "description": "", + "parameters": [ + { + "name": "idempotency-key", + "in": "header", + "type": "string" + }, + { + "name": "body", + "in": "body", + "schema": { + "type": "object", + "properties": { + "receiverId": { + "example": "any" + }, + "amount": { + "example": "any" + }, + "description": { + "example": "any" + } + } + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Bad Request" + }, + "401": { + "description": "Unauthorized" + }, + "500": { + "description": "Internal Server Error" + } + } + } + }, + "/api/wallet/history": { + "get": { + "description": "", + "parameters": [ + { + "name": "skip", + "in": "query", + "type": "string" + }, + { + "name": "take", + "in": "query", + "type": "string" + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Bad Request" + }, + "401": { + "description": "Unauthorized" + }, + "500": { + "description": "Internal Server Error" + } + } + } + }, + "/api/wallet/balance": { + "get": { + "description": "", + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Bad Request" + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "Not Found" + }, + "500": { + "description": "Internal Server Error" + } + } + } + }, + "/api/wallet/admin/all-wallets": { + "get": { + "description": "", + "parameters": [ + { + "name": "skip", + "in": "query", + "type": "string" + }, + { + "name": "take", + "in": "query", + "type": "string" + } + ], + "responses": { + "200": { + "description": "OK" + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + }, + "500": { + "description": "Internal Server Error" + } + } + } + }, + "/api/products/": { + "get": { + "description": "", + "parameters": [ + { + "name": "skip", + "in": "query", + "type": "string" + }, + { + "name": "take", + "in": "query", + "type": "string" + } + ], + "responses": { + "200": { + "description": "OK" + }, + "500": { + "description": "Internal Server Error" + } + } + }, + "post": { + "description": "", + "parameters": [ + { + "name": "Authorization", + "in": "header", + "type": "string" + }, + { + "name": "body", + "in": "body", + "schema": { + "type": "object", + "properties": { + "name": { + "example": "any" + }, + "price": { + "example": "any" + }, + "stock": { + "example": "any" + } + } + } + } + ], + "responses": { + "201": { + "description": "Created" + }, + "400": { + "description": "Bad Request" + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "500": { + "description": "Internal Server Error" + } + } + } + }, + "/api/products/{id}": { + "patch": { + "description": "", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "Authorization", + "in": "header", + "type": "string" + }, + { + "name": "body", + "in": "body", + "schema": { + "type": "object", + "properties": { + "name": { + "example": "any" + }, + "category": { + "example": "any" + }, + "price": { + "example": "any" + }, + "stock": { + "example": "any" + } + } + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Bad Request" + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + }, + "500": { + "description": "Internal Server Error" + } + } + }, + "delete": { + "description": "", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "Authorization", + "in": "header", + "type": "string" + } + ], + "responses": { + "200": { + "description": "OK" + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + }, + "500": { + "description": "Internal Server Error" + } + } + } + }, + "/api/products/my-products": { + "get": { + "description": "", + "parameters": [ + { + "name": "Authorization", + "in": "header", + "type": "string" + }, + { + "name": "skip", + "in": "query", + "type": "string" + }, + { + "name": "take", + "in": "query", + "type": "string" + } + ], + "responses": { + "200": { + "description": "OK" + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "500": { + "description": "Internal Server Error" + } + } + } + }, + "/api/orders/": { + "post": { + "description": "", + "parameters": [ + { + "name": "idempotency-key", + "in": "header", + "type": "string" + }, + { + "name": "body", + "in": "body", + "schema": { + "type": "object", + "properties": { + "items": { + "example": "any" + } + } + } + } + ], + "responses": { + "201": { + "description": "Created" + }, + "400": { + "description": "Bad Request" + }, + "401": { + "description": "Unauthorized" + }, + "500": { + "description": "Internal Server Error" + } + } + }, + "get": { + "description": "", + "responses": { + "200": { + "description": "OK" + }, + "401": { + "description": "Unauthorized" + }, + "500": { + "description": "Internal Server Error" + } + } + } + }, + "/api/orders/{id}/cancel": { + "patch": { + "description": "", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "idempotency-key", + "in": "header", + "type": "string" + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Bad Request" + }, + "401": { + "description": "Unauthorized" + }, + "500": { + "description": "Internal Server Error" + } + } + } + }, + "/register": { + "post": { + "description": "", + "parameters": [ + { + "name": "body", + "in": "body", + "schema": { + "type": "object", + "properties": { + "email": { + "example": "any" + }, + "password": { + "example": "any" + } + } + } + } + ], + "responses": { + "201": { + "description": "Created" + }, + "400": { + "description": "Bad Request" + }, + "500": { + "description": "Internal Server Error" + } + } + } + }, + "/login": { + "post": { + "description": "", + "parameters": [ + { + "name": "body", + "in": "body", + "schema": { + "type": "object", + "properties": { + "email": { + "example": "any" + }, + "password": { + "example": "any" + } + } + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Bad Request" + }, + "401": { + "description": "Unauthorized" + }, + "500": { + "description": "Internal Server Error" + } + } + } + }, + "/users": { + "get": { + "description": "", + "parameters": [ + { + "name": "Authorization", + "in": "header", + "type": "string" + } + ], + "responses": { + "200": { + "description": "OK" + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "500": { + "description": "Internal Server Error" + } + } + } + }, + "/profile": { + "get": { + "description": "", + "parameters": [ + { + "name": "Authorization", + "in": "header", + "type": "string" + } + ], + "responses": { + "200": { + "description": "OK" + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "Not Found" + }, + "500": { + "description": "Internal Server Error" + } + } + } + }, + "/": { + "post": { + "description": "", + "parameters": [ + { + "name": "Authorization", + "in": "header", + "type": "string" + }, + { + "name": "body", + "in": "body", + "schema": { + "type": "object", + "properties": { + "name": { + "example": "any" + }, + "price": { + "example": "any" + }, + "stock": { + "example": "any" + } + } + } + } + ], + "responses": { + "201": { + "description": "Created" + }, + "400": { + "description": "Bad Request" + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "500": { + "description": "Internal Server Error" + } + } + }, + "get": { + "description": "", + "parameters": [ + { + "name": "skip", + "in": "query", + "type": "string" + }, + { + "name": "take", + "in": "query", + "type": "string" + } + ], + "responses": { + "200": { + "description": "OK" + }, + "401": { + "description": "Unauthorized" + }, + "500": { + "description": "Internal Server Error" + } + } + } + }, + "/{id}/cancel": { + "patch": { + "description": "", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "idempotency-key", + "in": "header", + "type": "string" + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Bad Request" + }, + "401": { + "description": "Unauthorized" + }, + "500": { + "description": "Internal Server Error" + } + } + } + }, + "/{id}": { + "patch": { + "description": "", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "Authorization", + "in": "header", + "type": "string" + }, + { + "name": "body", + "in": "body", + "schema": { + "type": "object", + "properties": { + "name": { + "example": "any" + }, + "category": { + "example": "any" + }, + "price": { + "example": "any" + }, + "stock": { + "example": "any" + } + } + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Bad Request" + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + }, + "500": { + "description": "Internal Server Error" + } + } + }, + "delete": { + "description": "", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "Authorization", + "in": "header", + "type": "string" + } + ], + "responses": { + "200": { + "description": "OK" + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + }, + "500": { + "description": "Internal Server Error" + } + } + } + }, + "/my-products": { + "get": { + "description": "", + "parameters": [ + { + "name": "Authorization", + "in": "header", + "type": "string" + }, + { + "name": "skip", + "in": "query", + "type": "string" + }, + { + "name": "take", + "in": "query", + "type": "string" + } + ], + "responses": { + "200": { + "description": "OK" + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "500": { + "description": "Internal Server Error" + } + } + } + }, + "/deposit": { + "post": { + "description": "", + "parameters": [ + { + "name": "idempotency-key", + "in": "header", + "type": "string" + }, + { + "name": "body", + "in": "body", + "schema": { + "type": "object", + "properties": { + "amount": { + "example": "any" + }, + "description": { + "example": "any" + } + } + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Bad Request" + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "Not Found" + }, + "500": { + "description": "Internal Server Error" + } + } + } + }, + "/withdraw": { + "post": { + "description": "", + "parameters": [ + { + "name": "idempotency-key", + "in": "header", + "type": "string" + }, + { + "name": "body", + "in": "body", + "schema": { + "type": "object", + "properties": { + "amount": { + "example": "any" + }, + "description": { + "example": "any" + } + } + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Bad Request" + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "Not Found" + }, + "500": { + "description": "Internal Server Error" + } + } + } + }, + "/transfer": { + "post": { + "description": "", + "parameters": [ + { + "name": "idempotency-key", + "in": "header", + "type": "string" + }, + { + "name": "body", + "in": "body", + "schema": { + "type": "object", + "properties": { + "receiverId": { + "example": "any" + }, + "amount": { + "example": "any" + }, + "description": { + "example": "any" + } + } + } + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Bad Request" + }, + "401": { + "description": "Unauthorized" + }, + "500": { + "description": "Internal Server Error" + } + } + } + }, + "/history": { + "get": { + "description": "", + "parameters": [ + { + "name": "skip", + "in": "query", + "type": "string" + }, + { + "name": "take", + "in": "query", + "type": "string" + } + ], + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Bad Request" + }, + "401": { + "description": "Unauthorized" + }, + "500": { + "description": "Internal Server Error" + } + } + } + }, + "/balance": { + "get": { + "description": "", + "responses": { + "200": { + "description": "OK" + }, + "400": { + "description": "Bad Request" + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "Not Found" + }, + "500": { + "description": "Internal Server Error" + } + } + } + }, + "/admin/all-wallets": { + "get": { + "description": "", + "parameters": [ + { + "name": "skip", + "in": "query", + "type": "string" + }, + { + "name": "take", + "in": "query", + "type": "string" + } + ], + "responses": { + "200": { + "description": "OK" + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not Found" + }, + "500": { + "description": "Internal Server Error" + } + } + } + } + } +} \ No newline at end of file diff --git a/swagger.js b/swagger.js new file mode 100644 index 0000000..89dc003 --- /dev/null +++ b/swagger.js @@ -0,0 +1,24 @@ +import swaggerAutogen from 'swagger-autogen'; + +const doc = { + info: { + title: 'The Unknowns S-T API', + description: 'Auto-generated documentation for all endpoints.', + }, + host: 'localhost:3001', + schemes: ['http'], + securityDefinitions: { + bearerAuth: { + type: 'apiKey', + name: 'Authorization', + scheme: 'bearer', + in: 'header', + }, + }, +}; + +const outputFile = './swagger-output.json'; +// Crawl the root index and all route files +const endpointsFiles = ['./index.js', './src/routes/*.js']; + +swaggerAutogen()(outputFile, endpointsFiles, doc); \ No newline at end of file