diff --git a/authentication/app.js b/authentication/app.js index c206ed1a..1f8b773d 100644 --- a/authentication/app.js +++ b/authentication/app.js @@ -5,6 +5,8 @@ import cookieParser from 'cookie-parser'; import { user } from './src/api/user.js'; import { resetPassword } from './src/api/resetPassword.js'; import cors from 'cors'; +import swaggerUi from "swagger-ui-express"; +import { default as swaggerFile } from './src/swagger/swagger.json' assert { type: "json" }; const app = express(); @@ -18,6 +20,7 @@ app.use(cors({ credentials: true, })); +app.use("/api-docs", swaggerUi.serve, swaggerUi.setup(swaggerFile)); user(app); resetPassword(app); diff --git a/authentication/package-lock.json b/authentication/package-lock.json index e8feb82f..1900e27c 100644 --- a/authentication/package-lock.json +++ b/authentication/package-lock.json @@ -20,6 +20,8 @@ "mongoose": "^7.6.0", "morgan": "^1.10.0", "nodemailer": "^6.9.6", + "swagger-jsdoc": "^6.2.8", + "swagger-ui-express": "^5.0.0", "uuid": "^9.0.1" }, "devDependencies": { @@ -54,6 +56,46 @@ "node": ">=6.0.0" } }, + "node_modules/@apidevtools/json-schema-ref-parser": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.1.2.tgz", + "integrity": "sha512-r1w81DpR+KyRWd3f+rk6TNqMgedmAxZP5v5KWlXQWlgMUUtyEJch0DKEci1SorPMiSeM8XPl7MZ3miJ60JIpQg==", + "dependencies": { + "@jsdevtools/ono": "^7.1.3", + "@types/json-schema": "^7.0.6", + "call-me-maybe": "^1.0.1", + "js-yaml": "^4.1.0" + } + }, + "node_modules/@apidevtools/openapi-schemas": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@apidevtools/openapi-schemas/-/openapi-schemas-2.1.0.tgz", + "integrity": "sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@apidevtools/swagger-methods": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@apidevtools/swagger-methods/-/swagger-methods-3.0.2.tgz", + "integrity": "sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg==" + }, + "node_modules/@apidevtools/swagger-parser": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/@apidevtools/swagger-parser/-/swagger-parser-10.0.3.tgz", + "integrity": "sha512-sNiLY51vZOmSPFZA5TF35KZ2HbgYklQnTSDnkghamzLb3EkNtcQnrBQEj5AOCxHpTtXpqMCRM1CrmV2rG6nw4g==", + "dependencies": { + "@apidevtools/json-schema-ref-parser": "^9.0.6", + "@apidevtools/openapi-schemas": "^2.0.4", + "@apidevtools/swagger-methods": "^3.0.2", + "@jsdevtools/ono": "^7.1.3", + "call-me-maybe": "^1.0.1", + "z-schema": "^5.0.1" + }, + "peerDependencies": { + "openapi-types": ">=7" + } + }, "node_modules/@babel/code-frame": { "version": "7.22.13", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", @@ -1274,6 +1316,11 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@jsdevtools/ono": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", + "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==" + }, "node_modules/@mapbox/node-pre-gyp": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", @@ -1435,6 +1482,11 @@ "@types/istanbul-lib-report": "*" } }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" + }, "node_modules/@types/node": { "version": "20.8.2", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.2.tgz", @@ -1623,8 +1675,7 @@ "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "node_modules/array-buffer-byte-length": { "version": "1.0.0", @@ -2062,6 +2113,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/call-me-maybe": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", + "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==" + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -2221,6 +2277,14 @@ "node": ">= 0.8" } }, + "node_modules/commander": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.0.tgz", + "integrity": "sha512-zP4jEKbe8SHzKJYQmq8Y9gYjtO/POJLgIdKgV7B9qNmABVFVc+ctqSX6iXh4mCpJfRBOabiZ2YKPg8ciDw6C+Q==", + "engines": { + "node": ">= 6" + } + }, "node_modules/component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", @@ -2494,7 +2558,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, "dependencies": { "esutils": "^2.0.2" }, @@ -2907,7 +2970,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -4782,7 +4844,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, "dependencies": { "argparse": "^2.0.1" }, @@ -4962,6 +5023,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==" + }, "node_modules/lodash.includes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", @@ -4972,6 +5038,11 @@ "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" + }, "node_modules/lodash.isinteger": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", @@ -4998,6 +5069,11 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/lodash.mergewith": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", + "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==" + }, "node_modules/lodash.once": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", @@ -5614,6 +5690,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/openapi-types": { + "version": "12.1.3", + "resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-12.1.3.tgz", + "integrity": "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==", + "peer": true + }, "node_modules/optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -6669,6 +6751,74 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/swagger-jsdoc": { + "version": "6.2.8", + "resolved": "https://registry.npmjs.org/swagger-jsdoc/-/swagger-jsdoc-6.2.8.tgz", + "integrity": "sha512-VPvil1+JRpmJ55CgAtn8DIcpBs0bL5L3q5bVQvF4tAW/k/9JYSj7dCpaYCAv5rufe0vcCbBRQXGvzpkWjvLklQ==", + "dependencies": { + "commander": "6.2.0", + "doctrine": "3.0.0", + "glob": "7.1.6", + "lodash.mergewith": "^4.6.2", + "swagger-parser": "^10.0.3", + "yaml": "2.0.0-1" + }, + "bin": { + "swagger-jsdoc": "bin/swagger-jsdoc.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/swagger-jsdoc/node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/swagger-parser": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/swagger-parser/-/swagger-parser-10.0.3.tgz", + "integrity": "sha512-nF7oMeL4KypldrQhac8RyHerJeGPD1p2xDh900GPvc+Nk7nWP6jX2FcC7WmkinMoAmoO774+AFXcWsW8gMWEIg==", + "dependencies": { + "@apidevtools/swagger-parser": "10.0.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/swagger-ui-dist": { + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.11.0.tgz", + "integrity": "sha512-j0PIATqQSEFGOLmiJOJZj1X1Jt6bFIur3JpY7+ghliUnfZs0fpWDdHEkn9q7QUlBtKbkn6TepvSxTqnE8l3s0A==" + }, + "node_modules/swagger-ui-express": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-5.0.0.tgz", + "integrity": "sha512-tsU9tODVvhyfkNSvf03E6FAk+z+5cU3lXAzMy6Pv4av2Gt2xA0++fogwC4qo19XuFf6hdxevPuVCSKFuMHJhFA==", + "dependencies": { + "swagger-ui-dist": ">=5.0.0" + }, + "engines": { + "node": ">= v0.10.32" + }, + "peerDependencies": { + "express": ">=4.0.0 || >=5.0.0-beta" + } + }, "node_modules/tar": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", @@ -6956,6 +7106,14 @@ "node": ">=10.12.0" } }, + "node_modules/validator": { + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", + "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -7135,6 +7293,14 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, + "node_modules/yaml": { + "version": "2.0.0-1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.0.0-1.tgz", + "integrity": "sha512-W7h5dEhywMKenDJh2iX/LABkbFnBxasD27oyXWDS/feDsxiw0dD5ncXdYXgkvAsXIY2MpW/ZKkr9IU30DBdMNQ==", + "engines": { + "node": ">= 6" + } + }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", @@ -7173,6 +7339,34 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/z-schema": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-5.0.5.tgz", + "integrity": "sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==", + "dependencies": { + "lodash.get": "^4.4.2", + "lodash.isequal": "^4.5.0", + "validator": "^13.7.0" + }, + "bin": { + "z-schema": "bin/z-schema" + }, + "engines": { + "node": ">=8.0.0" + }, + "optionalDependencies": { + "commander": "^9.4.1" + } + }, + "node_modules/z-schema/node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "optional": true, + "engines": { + "node": "^12.20.0 || >=14" + } } } } diff --git a/authentication/package.json b/authentication/package.json index 243ba4c0..456d7b98 100644 --- a/authentication/package.json +++ b/authentication/package.json @@ -23,6 +23,8 @@ "mongoose": "^7.6.0", "morgan": "^1.10.0", "nodemailer": "^6.9.6", + "swagger-jsdoc": "^6.2.8", + "swagger-ui-express": "^5.0.0", "uuid": "^9.0.1" }, "devDependencies": { @@ -34,4 +36,4 @@ "jest": "^29.7.0", "supertest": "^6.3.3" } -} \ No newline at end of file +} diff --git a/authentication/src/swagger/swagger.json b/authentication/src/swagger/swagger.json new file mode 100644 index 00000000..b04286dd --- /dev/null +++ b/authentication/src/swagger/swagger.json @@ -0,0 +1,571 @@ +{ + "swagger": "2.0", + "info": { + "version": "1.0.0", + "title": "Authentication Service API", + "description": "API documentation for the authentication service" + }, + "basePath": "/", + "schemes": ["http", "https"], + "consumes": ["application/json"], + "produces": ["application/json"], + "paths": { + "/reset-password": { + "post": { + "summary": "Reset User Password", + "description": "Endpoint to initiate the password reset process.", + "parameters": [ + { + "name": "email", + "in": "formData", + "required": true, + "type": "string", + "description": "User's email address" + } + ], + "responses": { + "200": { + "description": "Email sent successfully", + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string", + "description": "Success message" + } + } + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + } + } + } + }, + "/signup/{request}": { + "post": { + "summary": "User Signup", + "description": "Endpoint for user registration.", + "parameters": [ + { + "name": "request", + "in": "path", + "required": true, + "type": "string", + "enum": ["clinic", "pharmacy"], + "description": "Type of request (clinic or pharmacy)" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/definitions/UserSignupRequest" + } + } + } + }, + "responses": { + "200": { + "description": "User signup successful" + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + } + } + } + }, + "/users/{id}": { + "delete": { + "summary": "Delete User", + "description": "Endpoint to delete a user by ID.", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string", + "description": "User ID to be deleted" + } + ], + "responses": { + "200": { + "description": "User deleted successfully" + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + } + } + } + }, + "/users/{id}/email/{email}": { + "patch": { + "summary": "Update User Email", + "description": "Endpoint to update a user's email by ID.", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string", + "description": "User ID to be updated" + }, + { + "name": "email", + "in": "path", + "required": true, + "type": "string", + "description": "New email for the user" + } + ], + "responses": { + "200": { + "description": "Email updated successfully", + "schema": { + "$ref": "#/definitions/PatchUserEmailResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + } + } + } + }, + "/doctors": { + "post": { + "summary": "Add Doctor", + "description": "Endpoint to add a doctor.", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/definitions/DoctorRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Doctor added successfully" + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + } + } + } + }, + "/pharmacists": { + "post": { + "summary": "Add Pharmacist", + "description": "Endpoint to add a pharmacist.", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/definitions/PharmacistRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Pharmacist added successfully" + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + } + } + } + }, + "/login/{request}": { + "post": { + "summary": "User Login", + "description": "Endpoint for user login.", + "parameters": [ + { + "name": "request", + "in": "path", + "required": true, + "type": "string", + "enum": ["clinic", "pharmacy"], + "description": "Type of login request (clinic or pharmacy)" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/definitions/LoginRequest" + } + } + } + }, + "responses": { + "200": { + "description": "User logged in successfully", + "schema": { + "$ref": "#/definitions/LoginResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + } + } + } + }, + "/user/{id}/email": { + "get": { + "summary": "Get User Email", + "description": "Endpoint to retrieve a user's email by ID.", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "type": "string", + "description": "User ID to retrieve the email" + } + ], + "responses": { + "200": { + "description": "User email retrieved successfully", + "schema": { + "type": "object", + "properties": { + "email": { + "type": "string", + "description": "User's email address" + } + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + } + } + } + }, + "/check-user": { + "get": { + "summary": "Check User Authentication", + "description": "Endpoint to check if the user is authenticated.", + "responses": { + "200": { + "description": "User is authenticated", + "schema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "User ID" + }, + "userName": { + "type": "string", + "description": "User's username" + }, + "type": { + "type": "string", + "description": "User type" + } + } + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + } + } + } + }, + "/change-password/{userId}": { + "patch": { + "summary": "Change Password", + "description": "Endpoint to change user password by ID.", + "parameters": [ + { + "name": "userId", + "in": "path", + "required": true, + "type": "string", + "description": "User ID to change the password" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/definitions/ChangePasswordRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Password changed successfully" + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + } + } + } + }, + "/remove-cookie": { + "get": { + "summary": "Remove Cookie", + "description": "Endpoint to remove the JWT cookie.", + "responses": { + "200": { + "description": "Cookie removed successfully" + } + } + } + }, + "/pharmacists/id": { + "get": { + "summary": "Get Pharmacist IDs", + "description": "Endpoint to retrieve IDs of pharmacists.", + "responses": { + "200": { + "description": "Pharmacist IDs retrieved successfully", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/ErrorResponse" + } + } + } + } + } + }, + "definitions": { + "UserSchema": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "format": "uuid", + "description": "Unique identifier for the user", + "example": "550e8400-e29b-41d4-a716-446655440000" + }, + "email": { + "type": "string", + "description": "User's email address", + "example": "user@example.com" + }, + "userName": { + "type": "string", + "description": "User's username", + "example": "john_doe" + }, + "password": { + "type": "string", + "description": "User's password", + "example": "password123" + }, + "type": { + "type": "string", + "description": "User type", + "enum": ["CLINIC_ADMIN", "PHARMACY_ADMIN", "PATIENT", "DOCTOR", "PHARMACIST"], + "example": "PATIENT" + } + }, + "required": ["userId", "email", "userName", "password", "type"], + "uniqueItems": ["userId", "email", "userName"] + }, + "ResetSchema": { + "type": "object", + "properties": { + "email": { + "type": "string", + "description": "User's email address", + "example": "user@example.com" + }, + "OTP": { + "type": "string", + "description": "One-Time Password for resetting", + "example": "123456" + }, + "resetTokenExpiration": { + "type": "string", + "format": "date-time", + "description": "Token expiration date and time", + "example": "2024-01-13T12:00:00Z" + } + }, + "required": ["email", "OTP", "resetTokenExpiration"] + }, + "UserSignupRequest": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["PATIENT", "DOCTOR", "PHARMACIST"], + "description": "Type of user" + }, + "email": { + "type": "string", + "description": "User's email address" + }, + "userName": { + "type": "string", + "description": "User's username" + } + }, + "required": ["type", "email", "userName"] + }, + "PatchUserEmailResponse": { + "type": "object", + "properties": { + "message": { + "type": "string", + "description": "Success message" + } + } + }, + "DoctorRequest": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "Unique identifier for the doctor", + "example": "550e8400-e29b-41d4-a716-446655440000" + } + }, + "required": ["userId"] + }, + "PharmacistRequest": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "Unique identifier for the pharmacist", + "example": "550e8400-e29b-41d4-a716-446655440000" + } + }, + "required": ["userId"] + }, + "AdminRequest": { + "type": "object", + "properties": { + "userName": { + "type": "string", + "description": "Admin's username" + }, + "email": { + "type": "string", + "description": "Admin's email address" + } + }, + "required": ["userName", "email"] + }, + "AdminResponse": { + "type": "object", + "properties": { + "message": { + "type": "string", + "description": "Success message" + } + } + }, + "LoginRequest": { + "type": "object", + "properties": { + "userName": { + "type": "string", + "description": "User's username" + }, + "password": { + "type": "string", + "description": "User's password" + } + }, + "required": ["userName", "password"] + }, + "LoginResponse": { + "type": "object", + "properties": { + "token": { + "type": "string", + "description": "User authentication token" + }, + "type": { + "type": "string", + "description": "User type" + } + } + }, + "ChangePasswordRequest": { + "type": "object", + "properties": { + "password": { + "type": "string", + "description": "New password for the user" + } + }, + "required": ["password"] + }, + "ErrorResponse": { + "type": "object", + "properties": { + "errMessage": { + "type": "string", + "description": "Error message" + } + } + } + } + } + \ No newline at end of file diff --git a/payment/app.js b/payment/app.js index baa7fde7..885999cf 100644 --- a/payment/app.js +++ b/payment/app.js @@ -3,7 +3,8 @@ import morgan from 'morgan'; import {payment} from './src/api/PaymentAPI.js'; import cors from 'cors'; import bodyParser from 'body-parser'; - +import swaggerUi from "swagger-ui-express"; +import { default as swaggerFile } from './src/swagger/swagger.json' assert { type: "json" }; const app = express(); @@ -16,6 +17,8 @@ app.use(cors({ credentials: true })); +app.use("/api-docs", swaggerUi.serve, swaggerUi.setup(swaggerFile)); + payment(app); export default app; diff --git a/payment/package-lock.json b/payment/package-lock.json index 23524633..1d88fdea 100644 --- a/payment/package-lock.json +++ b/payment/package-lock.json @@ -17,7 +17,9 @@ "mongoose": "^8.0.2", "morgan": "^1.10.0", "nodemon": "^3.0.1", - "stripe": "^14.1.0" + "stripe": "^14.1.0", + "swagger-jsdoc": "^6.2.8", + "swagger-ui-express": "^5.0.0" }, "devDependencies": { "@babel/plugin-transform-modules-commonjs": "^7.23.3", @@ -40,6 +42,62 @@ "node": ">=6.0.0" } }, + "node_modules/@apidevtools/json-schema-ref-parser": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.1.2.tgz", + "integrity": "sha512-r1w81DpR+KyRWd3f+rk6TNqMgedmAxZP5v5KWlXQWlgMUUtyEJch0DKEci1SorPMiSeM8XPl7MZ3miJ60JIpQg==", + "dependencies": { + "@jsdevtools/ono": "^7.1.3", + "@types/json-schema": "^7.0.6", + "call-me-maybe": "^1.0.1", + "js-yaml": "^4.1.0" + } + }, + "node_modules/@apidevtools/json-schema-ref-parser/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/@apidevtools/json-schema-ref-parser/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@apidevtools/openapi-schemas": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@apidevtools/openapi-schemas/-/openapi-schemas-2.1.0.tgz", + "integrity": "sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@apidevtools/swagger-methods": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@apidevtools/swagger-methods/-/swagger-methods-3.0.2.tgz", + "integrity": "sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg==" + }, + "node_modules/@apidevtools/swagger-parser": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/@apidevtools/swagger-parser/-/swagger-parser-10.0.3.tgz", + "integrity": "sha512-sNiLY51vZOmSPFZA5TF35KZ2HbgYklQnTSDnkghamzLb3EkNtcQnrBQEj5AOCxHpTtXpqMCRM1CrmV2rG6nw4g==", + "dependencies": { + "@apidevtools/json-schema-ref-parser": "^9.0.6", + "@apidevtools/openapi-schemas": "^2.0.4", + "@apidevtools/swagger-methods": "^3.0.2", + "@jsdevtools/ono": "^7.1.3", + "call-me-maybe": "^1.0.1", + "z-schema": "^5.0.1" + }, + "peerDependencies": { + "openapi-types": ">=7" + } + }, "node_modules/@babel/code-frame": { "version": "7.22.13", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", @@ -1083,6 +1141,11 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@jsdevtools/ono": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", + "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==" + }, "node_modules/@mongodb-js/saslprep": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.1.tgz", @@ -1189,6 +1252,11 @@ "@types/istanbul-lib-report": "*" } }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" + }, "node_modules/@types/node": { "version": "20.8.7", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.7.tgz", @@ -1599,6 +1667,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/call-me-maybe": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", + "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==" + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -1789,6 +1862,14 @@ "node": ">= 0.8" } }, + "node_modules/commander": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.0.tgz", + "integrity": "sha512-zP4jEKbe8SHzKJYQmq8Y9gYjtO/POJLgIdKgV7B9qNmABVFVc+ctqSX6iXh4mCpJfRBOabiZ2YKPg8ciDw6C+Q==", + "engines": { + "node": ">= 6" + } + }, "node_modules/component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", @@ -1988,6 +2069,17 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/dotenv": { "version": "16.3.1", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", @@ -2081,6 +2173,14 @@ "node": ">=4" } }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", @@ -2343,8 +2443,7 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "node_modules/fsevents": { "version": "2.3.3", @@ -2616,7 +2715,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -3494,6 +3592,21 @@ "node": ">=8" } }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==" + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" + }, + "node_modules/lodash.mergewith": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", + "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==" + }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -3914,7 +4027,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, "dependencies": { "wrappy": "1" } @@ -3934,6 +4046,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/openapi-types": { + "version": "12.1.3", + "resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-12.1.3.tgz", + "integrity": "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==", + "peer": true + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -4024,7 +4142,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, "engines": { "node": ">=0.10.0" } @@ -4677,6 +4794,74 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/swagger-jsdoc": { + "version": "6.2.8", + "resolved": "https://registry.npmjs.org/swagger-jsdoc/-/swagger-jsdoc-6.2.8.tgz", + "integrity": "sha512-VPvil1+JRpmJ55CgAtn8DIcpBs0bL5L3q5bVQvF4tAW/k/9JYSj7dCpaYCAv5rufe0vcCbBRQXGvzpkWjvLklQ==", + "dependencies": { + "commander": "6.2.0", + "doctrine": "3.0.0", + "glob": "7.1.6", + "lodash.mergewith": "^4.6.2", + "swagger-parser": "^10.0.3", + "yaml": "2.0.0-1" + }, + "bin": { + "swagger-jsdoc": "bin/swagger-jsdoc.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/swagger-jsdoc/node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/swagger-parser": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/swagger-parser/-/swagger-parser-10.0.3.tgz", + "integrity": "sha512-nF7oMeL4KypldrQhac8RyHerJeGPD1p2xDh900GPvc+Nk7nWP6jX2FcC7WmkinMoAmoO774+AFXcWsW8gMWEIg==", + "dependencies": { + "@apidevtools/swagger-parser": "10.0.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/swagger-ui-dist": { + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.11.0.tgz", + "integrity": "sha512-j0PIATqQSEFGOLmiJOJZj1X1Jt6bFIur3JpY7+ghliUnfZs0fpWDdHEkn9q7QUlBtKbkn6TepvSxTqnE8l3s0A==" + }, + "node_modules/swagger-ui-express": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-5.0.0.tgz", + "integrity": "sha512-tsU9tODVvhyfkNSvf03E6FAk+z+5cU3lXAzMy6Pv4av2Gt2xA0++fogwC4qo19XuFf6hdxevPuVCSKFuMHJhFA==", + "dependencies": { + "swagger-ui-dist": ">=5.0.0" + }, + "engines": { + "node": ">= v0.10.32" + }, + "peerDependencies": { + "express": ">=4.0.0 || >=5.0.0-beta" + } + }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -4850,6 +5035,14 @@ "node": ">=10.12.0" } }, + "node_modules/validator": { + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", + "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -4922,8 +5115,7 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/write-file-atomic": { "version": "4.0.2", @@ -4952,6 +5144,14 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, + "node_modules/yaml": { + "version": "2.0.0-1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.0.0-1.tgz", + "integrity": "sha512-W7h5dEhywMKenDJh2iX/LABkbFnBxasD27oyXWDS/feDsxiw0dD5ncXdYXgkvAsXIY2MpW/ZKkr9IU30DBdMNQ==", + "engines": { + "node": ">= 6" + } + }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", @@ -4990,6 +5190,34 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/z-schema": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-5.0.5.tgz", + "integrity": "sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==", + "dependencies": { + "lodash.get": "^4.4.2", + "lodash.isequal": "^4.5.0", + "validator": "^13.7.0" + }, + "bin": { + "z-schema": "bin/z-schema" + }, + "engines": { + "node": ">=8.0.0" + }, + "optionalDependencies": { + "commander": "^9.4.1" + } + }, + "node_modules/z-schema/node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "optional": true, + "engines": { + "node": "^12.20.0 || >=14" + } } } } diff --git a/payment/package.json b/payment/package.json index d4167c78..c4a5deaf 100644 --- a/payment/package.json +++ b/payment/package.json @@ -19,7 +19,9 @@ "mongoose": "^8.0.2", "morgan": "^1.10.0", "nodemon": "^3.0.1", - "stripe": "^14.1.0" + "stripe": "^14.1.0", + "swagger-jsdoc": "^6.2.8", + "swagger-ui-express": "^5.0.0" }, "devDependencies": { "@babel/plugin-transform-modules-commonjs": "^7.23.3", diff --git a/payment/src/swagger/swagger.json b/payment/src/swagger/swagger.json new file mode 100644 index 00000000..e006005e --- /dev/null +++ b/payment/src/swagger/swagger.json @@ -0,0 +1,213 @@ +{ + "swagger": "2.0", + "info": { + "version": "1.0.0", + "title": "Payment Service API", + "description": "API documentation for the payment service" + }, + "basePath": "/api", + "schemes": ["http", "https"], + "consumes": ["application/json"], + "produces": ["application/json"], + "paths": { + "/payment/card": { + "post": { + "summary": "Create Payment Intent for Card Payment", + "description": "Creates a payment intent for processing card payments.", + "parameters": [ + { + "name": "paymentAmount", + "in": "body", + "description": "Total payment amount", + "required": true, + "schema": { + "type": "object", + "properties": { + "paymentAmount": { + "type": "number", + "description": "The total amount to be paid" + } + }, + "required": ["paymentAmount"] + } + } + ], + "responses": { + "200": { + "description": "Successful operation", + "schema": { + "type": "object", + "properties": { + "clientSecret": { + "type": "string", + "description": "Client secret for payment intent" + } + } + } + }, + "400": { + "description": "Bad request", + "schema": { + "type": "object", + "properties": { + "err": { + "type": "string", + "description": "Error message" + }, + "status": { + "type": "integer", + "description": "Error status code" + } + } + } + } + } + } + }, + "/payment/wallet": { + "post": { + "summary": "Make Payment Using Wallet", + "description": "Allows patients to make payments using their wallet.", + "parameters": [ + { + "name": "amountToPayByWallet", + "in": "body", + "description": "Amount to pay using the wallet", + "required": true, + "schema": { + "type": "object", + "properties": { + "amountToPayByWallet": { + "type": "number", + "description": "The amount to be paid using the wallet" + }, + "userId": { + "type": "string", + "description": "User ID of the patient" + } + }, + "required": ["amountToPayByWallet", "userId"] + } + } + ], + "responses": { + "200": { + "description": "Payment successful" + }, + "400": { + "description": "Bad request", + "schema": { + "type": "string", + "description": "Insufficient amount in the wallet" + } + }, + "500": { + "description": "Internal server error", + "schema": { + "type": "object", + "properties": { + "err": { + "type": "string", + "description": "Error message" + }, + "status": { + "type": "integer", + "description": "Error status code" + } + } + } + } + } + } + }, + "/payment-salary/doctor/{doctorId}/wallet": { + "post": { + "summary": "Make Salary Payment to Doctor's Wallet", + "description": "Allows making salary payments to a doctor's wallet.", + "parameters": [ + { + "name": "doctorId", + "in": "path", + "description": "ID of the doctor", + "required": true, + "type": "string" + }, + { + "name": "pricePaidToDoctor", + "in": "body", + "description": "Price paid to the doctor", + "required": true, + "schema": { + "type": "object", + "properties": { + "pricePaidToDoctor": { + "type": "number", + "description": "The amount paid to the doctor" + } + }, + "required": ["pricePaidToDoctor"] + } + } + ], + "responses": { + "200": { + "description": "Successful operation", + "schema": { + "type": "object", + "properties": { + "updatedDoctor": { + "$ref": "#/definitions/Doctor" + } + } + } + }, + "400": { + "description": "Bad request", + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string", + "description": "Error message" + } + } + } + }, + "500": { + "description": "Internal server error", + "schema": { + "type": "object", + "properties": { + "err": { + "type": "string", + "description": "Error message" + }, + "status": { + "type": "integer", + "description": "Error status code" + } + } + } + } + } + } + } + }, + "definitions": { + "Doctor": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "walletAmount": { + "type": "number" + } + } + } + } + } + \ No newline at end of file