Fix API authentication and identity service updates
This commit is contained in:
@@ -0,0 +1,25 @@
|
|||||||
|
$content = Get-Content -Raw "c:\Users\Lenovo\Desktop\ai_pharma_frontend\src\services\api.ts"
|
||||||
|
$target = "}, (error) => {`r`n return Promise.reject(error);`r`n});"
|
||||||
|
$replacement = @"
|
||||||
|
}, (error) => {
|
||||||
|
return Promise.reject(error);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Response interceptor to handle global errors like 401 Unauthorized
|
||||||
|
api.interceptors.response.use(
|
||||||
|
(response) => response,
|
||||||
|
(error) => {
|
||||||
|
if (error.response && error.response.status === 401) {
|
||||||
|
// Token is invalid or expired
|
||||||
|
localStorage.removeItem('auth_token');
|
||||||
|
localStorage.removeItem('user');
|
||||||
|
localStorage.removeItem('actor_id');
|
||||||
|
window.location.href = '/login';
|
||||||
|
}
|
||||||
|
return Promise.reject(error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
"@
|
||||||
|
|
||||||
|
$content = $content.Replace($target, $replacement)
|
||||||
|
Set-Content -Path "c:\Users\Lenovo\Desktop\ai_pharma_frontend\src\services\api.ts" -Value $content -NoNewline
|
||||||
@@ -0,0 +1,176 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
const collection = {
|
||||||
|
info: {
|
||||||
|
name: "Pharmacy Core API",
|
||||||
|
description: "API collection for Pharmacy Core API",
|
||||||
|
schema: "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
|
||||||
|
},
|
||||||
|
variable: [
|
||||||
|
{
|
||||||
|
key: "baseUrl",
|
||||||
|
value: "http://localhost:8080",
|
||||||
|
type: "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "token",
|
||||||
|
value: "",
|
||||||
|
type: "string"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
auth: {
|
||||||
|
type: "bearer",
|
||||||
|
bearer: [
|
||||||
|
{
|
||||||
|
key: "token",
|
||||||
|
value: "{{token}}",
|
||||||
|
type: "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
item: []
|
||||||
|
};
|
||||||
|
|
||||||
|
function createFolder(name, endpoints, prefix) {
|
||||||
|
const items = endpoints.map(ep => {
|
||||||
|
const method = ep.method.toUpperCase();
|
||||||
|
const fullPath = (prefix + ep.path).replace(/\/$/, "");
|
||||||
|
const urlParts = fullPath.split('/').filter(p => p !== '');
|
||||||
|
|
||||||
|
const request = {
|
||||||
|
method: method,
|
||||||
|
header: [],
|
||||||
|
url: {
|
||||||
|
raw: `{{baseUrl}}${fullPath}`,
|
||||||
|
host: ["{{baseUrl}}"],
|
||||||
|
path: urlParts
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (['POST', 'PUT', 'PATCH'].includes(method)) {
|
||||||
|
request.body = {
|
||||||
|
mode: "raw",
|
||||||
|
raw: "{}",
|
||||||
|
options: {
|
||||||
|
raw: {
|
||||||
|
language: "json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: ep.name || `${method} ${ep.path}`,
|
||||||
|
request: request
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: name,
|
||||||
|
item: items
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const modules = [
|
||||||
|
{
|
||||||
|
name: "Auth / Identity",
|
||||||
|
prefix: "/v1/auth",
|
||||||
|
endpoints: [
|
||||||
|
{ method: "GET", path: "/me", name: "Get Current User" },
|
||||||
|
{ method: "PUT", path: "/me", name: "Update Current User" },
|
||||||
|
{ method: "POST", path: "/register", name: "Register" },
|
||||||
|
{ method: "POST", path: "/login", name: "Login" },
|
||||||
|
{ method: "POST", path: "/logout", name: "Logout" },
|
||||||
|
{ method: "POST", path: "/token", name: "Refresh Token" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Catalogue",
|
||||||
|
prefix: "/v1",
|
||||||
|
endpoints: [
|
||||||
|
{ method: "GET", path: "/drugs", name: "Get Drugs" },
|
||||||
|
{ method: "POST", path: "/drugs", name: "Create Drug" },
|
||||||
|
{ method: "GET", path: "/drugs/search", name: "Search Drugs" },
|
||||||
|
{ method: "GET", path: "/products/:product_id/batches", name: "Get Product Batches" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Inventory",
|
||||||
|
prefix: "/v1/inventory",
|
||||||
|
endpoints: [
|
||||||
|
{ method: "POST", path: "/grn", name: "Create GRN" },
|
||||||
|
{ method: "GET", path: "/expiring", name: "Get Expiring Stock" },
|
||||||
|
{ method: "GET", path: "/low-stock", name: "Get Low Stock" },
|
||||||
|
{ method: "POST", path: "/adjustments", name: "Stock Adjustment" },
|
||||||
|
{ method: "GET", path: "/recall/:batch_no", name: "Recall Batch" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Dispensing (Orders)",
|
||||||
|
prefix: "/v1/orders",
|
||||||
|
endpoints: [
|
||||||
|
{ method: "GET", path: "/history", name: "Get Order History" },
|
||||||
|
{ method: "GET", path: "/h1-register", name: "Get H1 Register" },
|
||||||
|
{ method: "GET", path: "/:id/invoice/pdf", name: "Get Invoice PDF" },
|
||||||
|
{ method: "POST", path: "/", name: "Create Order" },
|
||||||
|
{ method: "PATCH", path: "/:id/items", name: "Update Order Items" },
|
||||||
|
{ method: "POST", path: "/:id/precheck", name: "Precheck Order" },
|
||||||
|
{ method: "POST", path: "/:id/dispense", name: "Dispense Order" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Audit",
|
||||||
|
prefix: "/v1/audit",
|
||||||
|
endpoints: [
|
||||||
|
{ method: "GET", path: "/ai-calls", name: "Get AI Calls" },
|
||||||
|
{ method: "GET", path: "/overrides", name: "Get Overrides" },
|
||||||
|
{ method: "GET", path: "/h1-register", name: "Get H1 Register Audit" },
|
||||||
|
{ method: "GET", path: "/sales-register", name: "Get Sales Register" },
|
||||||
|
{ method: "GET", path: "/dashboard-metrics", name: "Get Dashboard Metrics" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Prescription",
|
||||||
|
prefix: "/v1/rx",
|
||||||
|
endpoints: [
|
||||||
|
{ method: "POST", path: "/", name: "Upload Prescription" },
|
||||||
|
{ method: "GET", path: "/", name: "Get Prescriptions" },
|
||||||
|
{ method: "GET", path: "/:id", name: "Get Prescription by ID" },
|
||||||
|
{ method: "POST", path: "/:id/confirm", name: "Confirm Prescription" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "AI",
|
||||||
|
prefix: "/v1/ai",
|
||||||
|
endpoints: [
|
||||||
|
{ method: "POST", path: "/voice", name: "Voice AI" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Integration",
|
||||||
|
prefix: "/v1/integration",
|
||||||
|
endpoints: [
|
||||||
|
{ method: "POST", path: "/hospital/patient-sync", name: "Sync Hospital Patient" },
|
||||||
|
{ method: "GET", path: "/hospital/patients", name: "Get Hospital Patients" },
|
||||||
|
{ method: "POST", path: "/telegaruda/prescription", name: "Receive Telegaruda Rx" },
|
||||||
|
{ method: "GET", path: "/telegaruda/patient/:patientId", name: "Fetch Telegaruda Patient" },
|
||||||
|
{ method: "GET", path: "/hospital/prescriptions", name: "Get Hospital Prescriptions" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Upload",
|
||||||
|
prefix: "/v1/upload",
|
||||||
|
endpoints: [
|
||||||
|
{ method: "POST", path: "/", name: "Upload File" },
|
||||||
|
{ method: "GET", path: "/presigned", name: "Get Presigned URL" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
modules.forEach(mod => {
|
||||||
|
collection.item.push(createFolder(mod.name, mod.endpoints, mod.prefix));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Write to file
|
||||||
|
fs.writeFileSync('postman_collection.json', JSON.stringify(collection, null, 2));
|
||||||
|
console.log('Collection generated at postman_collection.json');
|
||||||
@@ -0,0 +1,948 @@
|
|||||||
|
{
|
||||||
|
"info": {
|
||||||
|
"name": "Pharmacy Core API",
|
||||||
|
"description": "API collection for Pharmacy Core API",
|
||||||
|
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
|
||||||
|
},
|
||||||
|
"variable": [
|
||||||
|
{
|
||||||
|
"key": "baseUrl",
|
||||||
|
"value": "http://localhost:8080",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "token",
|
||||||
|
"value": "",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"auth": {
|
||||||
|
"type": "bearer",
|
||||||
|
"bearer": [
|
||||||
|
{
|
||||||
|
"key": "token",
|
||||||
|
"value": "{{token}}",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"item": [
|
||||||
|
{
|
||||||
|
"name": "Auth / Identity",
|
||||||
|
"item": [
|
||||||
|
{
|
||||||
|
"name": "Get Current User",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/auth/me",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"auth",
|
||||||
|
"me"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Update Current User",
|
||||||
|
"request": {
|
||||||
|
"method": "PUT",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/auth/me",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"auth",
|
||||||
|
"me"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "{}",
|
||||||
|
"options": {
|
||||||
|
"raw": {
|
||||||
|
"language": "json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Register",
|
||||||
|
"request": {
|
||||||
|
"method": "POST",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/auth/register",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"auth",
|
||||||
|
"register"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "{}",
|
||||||
|
"options": {
|
||||||
|
"raw": {
|
||||||
|
"language": "json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Login",
|
||||||
|
"request": {
|
||||||
|
"method": "POST",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/auth/login",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"auth",
|
||||||
|
"login"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "{}",
|
||||||
|
"options": {
|
||||||
|
"raw": {
|
||||||
|
"language": "json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Logout",
|
||||||
|
"request": {
|
||||||
|
"method": "POST",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/auth/logout",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"auth",
|
||||||
|
"logout"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "{}",
|
||||||
|
"options": {
|
||||||
|
"raw": {
|
||||||
|
"language": "json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Refresh Token",
|
||||||
|
"request": {
|
||||||
|
"method": "POST",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/auth/token",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"auth",
|
||||||
|
"token"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "{}",
|
||||||
|
"options": {
|
||||||
|
"raw": {
|
||||||
|
"language": "json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Catalogue",
|
||||||
|
"item": [
|
||||||
|
{
|
||||||
|
"name": "Get Drugs",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/drugs",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"drugs"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Create Drug",
|
||||||
|
"request": {
|
||||||
|
"method": "POST",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/drugs",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"drugs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "{}",
|
||||||
|
"options": {
|
||||||
|
"raw": {
|
||||||
|
"language": "json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Search Drugs",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/drugs/search",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"drugs",
|
||||||
|
"search"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Get Product Batches",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/products/:product_id/batches",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"products",
|
||||||
|
":product_id",
|
||||||
|
"batches"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Inventory",
|
||||||
|
"item": [
|
||||||
|
{
|
||||||
|
"name": "Create GRN",
|
||||||
|
"request": {
|
||||||
|
"method": "POST",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/inventory/grn",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"inventory",
|
||||||
|
"grn"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "{}",
|
||||||
|
"options": {
|
||||||
|
"raw": {
|
||||||
|
"language": "json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Get Expiring Stock",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/inventory/expiring",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"inventory",
|
||||||
|
"expiring"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Get Low Stock",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/inventory/low-stock",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"inventory",
|
||||||
|
"low-stock"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Stock Adjustment",
|
||||||
|
"request": {
|
||||||
|
"method": "POST",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/inventory/adjustments",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"inventory",
|
||||||
|
"adjustments"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "{}",
|
||||||
|
"options": {
|
||||||
|
"raw": {
|
||||||
|
"language": "json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Recall Batch",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/inventory/recall/:batch_no",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"inventory",
|
||||||
|
"recall",
|
||||||
|
":batch_no"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Dispensing (Orders)",
|
||||||
|
"item": [
|
||||||
|
{
|
||||||
|
"name": "Get Order History",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/orders/history",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"orders",
|
||||||
|
"history"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Get H1 Register",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/orders/h1-register",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"orders",
|
||||||
|
"h1-register"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Get Invoice PDF",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/orders/:id/invoice/pdf",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"orders",
|
||||||
|
":id",
|
||||||
|
"invoice",
|
||||||
|
"pdf"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Create Order",
|
||||||
|
"request": {
|
||||||
|
"method": "POST",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/orders",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"orders"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "{}",
|
||||||
|
"options": {
|
||||||
|
"raw": {
|
||||||
|
"language": "json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Update Order Items",
|
||||||
|
"request": {
|
||||||
|
"method": "PATCH",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/orders/:id/items",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"orders",
|
||||||
|
":id",
|
||||||
|
"items"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "{}",
|
||||||
|
"options": {
|
||||||
|
"raw": {
|
||||||
|
"language": "json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Precheck Order",
|
||||||
|
"request": {
|
||||||
|
"method": "POST",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/orders/:id/precheck",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"orders",
|
||||||
|
":id",
|
||||||
|
"precheck"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "{}",
|
||||||
|
"options": {
|
||||||
|
"raw": {
|
||||||
|
"language": "json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Dispense Order",
|
||||||
|
"request": {
|
||||||
|
"method": "POST",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/orders/:id/dispense",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"orders",
|
||||||
|
":id",
|
||||||
|
"dispense"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "{}",
|
||||||
|
"options": {
|
||||||
|
"raw": {
|
||||||
|
"language": "json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Audit",
|
||||||
|
"item": [
|
||||||
|
{
|
||||||
|
"name": "Get AI Calls",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/audit/ai-calls",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"audit",
|
||||||
|
"ai-calls"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Get Overrides",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/audit/overrides",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"audit",
|
||||||
|
"overrides"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Get H1 Register Audit",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/audit/h1-register",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"audit",
|
||||||
|
"h1-register"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Get Sales Register",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/audit/sales-register",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"audit",
|
||||||
|
"sales-register"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Get Dashboard Metrics",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/audit/dashboard-metrics",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"audit",
|
||||||
|
"dashboard-metrics"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Prescription",
|
||||||
|
"item": [
|
||||||
|
{
|
||||||
|
"name": "Upload Prescription",
|
||||||
|
"request": {
|
||||||
|
"method": "POST",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/rx",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"rx"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "{}",
|
||||||
|
"options": {
|
||||||
|
"raw": {
|
||||||
|
"language": "json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Get Prescriptions",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/rx",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"rx"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Get Prescription by ID",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/rx/:id",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"rx",
|
||||||
|
":id"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Confirm Prescription",
|
||||||
|
"request": {
|
||||||
|
"method": "POST",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/rx/:id/confirm",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"rx",
|
||||||
|
":id",
|
||||||
|
"confirm"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "{}",
|
||||||
|
"options": {
|
||||||
|
"raw": {
|
||||||
|
"language": "json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "AI",
|
||||||
|
"item": [
|
||||||
|
{
|
||||||
|
"name": "Voice AI",
|
||||||
|
"request": {
|
||||||
|
"method": "POST",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/ai/voice",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"ai",
|
||||||
|
"voice"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "{}",
|
||||||
|
"options": {
|
||||||
|
"raw": {
|
||||||
|
"language": "json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Integration",
|
||||||
|
"item": [
|
||||||
|
{
|
||||||
|
"name": "Sync Hospital Patient",
|
||||||
|
"request": {
|
||||||
|
"method": "POST",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/integration/hospital/patient-sync",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"integration",
|
||||||
|
"hospital",
|
||||||
|
"patient-sync"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "{}",
|
||||||
|
"options": {
|
||||||
|
"raw": {
|
||||||
|
"language": "json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Get Hospital Patients",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/integration/hospital/patients",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"integration",
|
||||||
|
"hospital",
|
||||||
|
"patients"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Receive Telegaruda Rx",
|
||||||
|
"request": {
|
||||||
|
"method": "POST",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/integration/telegaruda/prescription",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"integration",
|
||||||
|
"telegaruda",
|
||||||
|
"prescription"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "{}",
|
||||||
|
"options": {
|
||||||
|
"raw": {
|
||||||
|
"language": "json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Fetch Telegaruda Patient",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/integration/telegaruda/patient/:patientId",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"integration",
|
||||||
|
"telegaruda",
|
||||||
|
"patient",
|
||||||
|
":patientId"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Get Hospital Prescriptions",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/integration/hospital/prescriptions",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"integration",
|
||||||
|
"hospital",
|
||||||
|
"prescriptions"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Upload",
|
||||||
|
"item": [
|
||||||
|
{
|
||||||
|
"name": "Upload File",
|
||||||
|
"request": {
|
||||||
|
"method": "POST",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/upload",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"upload"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"body": {
|
||||||
|
"mode": "raw",
|
||||||
|
"raw": "{}",
|
||||||
|
"options": {
|
||||||
|
"raw": {
|
||||||
|
"language": "json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Get Presigned URL",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/v1/upload/presigned",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"v1",
|
||||||
|
"upload",
|
||||||
|
"presigned"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ import express from 'express';
|
|||||||
import cors from 'cors';
|
import cors from 'cors';
|
||||||
import helmet from 'helmet';
|
import helmet from 'helmet';
|
||||||
import { errorHandler } from './middleware/error';
|
import { errorHandler } from './middleware/error';
|
||||||
|
import { requireApiKey } from './middleware/auth';
|
||||||
|
|
||||||
// Import routers
|
// Import routers
|
||||||
import identityRouter from './modules/identity/router';
|
import identityRouter from './modules/identity/router';
|
||||||
@@ -39,6 +40,9 @@ app.use((req, res, next) => {
|
|||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Global API Key Check
|
||||||
|
app.use(requireApiKey);
|
||||||
|
|
||||||
// API Routes
|
// API Routes
|
||||||
app.use('/v1/auth', identityRouter);
|
app.use('/v1/auth', identityRouter);
|
||||||
app.use('/v1', catalogueRouter);
|
app.use('/v1', catalogueRouter);
|
||||||
@@ -61,3 +65,4 @@ app.use(errorHandler);
|
|||||||
app.listen(PORT, () => {
|
app.listen(PORT, () => {
|
||||||
console.log(`Pharmacy Core API listening on port ${PORT}`);
|
console.log(`Pharmacy Core API listening on port ${PORT}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
+23
-2
@@ -1,7 +1,8 @@
|
|||||||
import { Request, Response, NextFunction, RequestHandler } from 'express';
|
import { Request, Response, NextFunction, RequestHandler } from 'express';
|
||||||
import jwt from 'jsonwebtoken';
|
import jwt from 'jsonwebtoken';
|
||||||
|
|
||||||
const JWT_SECRET = process.env.JWT_SECRET || 'super_secret_pharmacy_key_2026';
|
// JWT_SECRET will be evaluated at runtime to avoid loading order issues
|
||||||
|
const API_KEY = process.env.API_KEY;
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
namespace Express {
|
namespace Express {
|
||||||
@@ -12,7 +13,26 @@ declare global {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const requireApiKey: RequestHandler = (req: Request, res: Response, next: NextFunction): void => {
|
||||||
|
const apiKey = req.headers['x-api-key'];
|
||||||
|
const expectedApiKey = process.env.API_KEY;
|
||||||
|
|
||||||
|
// If API_KEY is set in .env, enforce it
|
||||||
|
if (expectedApiKey && apiKey !== expectedApiKey) {
|
||||||
|
res.status(401).json({
|
||||||
|
error: 'UNAUTHORIZED',
|
||||||
|
message: 'Missing or invalid API Key.',
|
||||||
|
details: {},
|
||||||
|
retryable: false
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
next();
|
||||||
|
};
|
||||||
|
|
||||||
export const requireAuth: RequestHandler = (req: Request, res: Response, next: NextFunction): void => {
|
export const requireAuth: RequestHandler = (req: Request, res: Response, next: NextFunction): void => {
|
||||||
|
|
||||||
const authHeader = req.headers.authorization;
|
const authHeader = req.headers.authorization;
|
||||||
const actorId = req.headers['x-actor-id'] as string;
|
const actorId = req.headers['x-actor-id'] as string;
|
||||||
|
|
||||||
@@ -29,8 +49,9 @@ export const requireAuth: RequestHandler = (req: Request, res: Response, next: N
|
|||||||
const token = authHeader.split(' ')[1];
|
const token = authHeader.split(' ')[1];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const secret = process.env.JWT_SECRET || 'super_secret_pharmacy_key_2026';
|
||||||
// Cryptographically verify the token using our secret key
|
// Cryptographically verify the token using our secret key
|
||||||
const payload = jwt.verify(token, JWT_SECRET) as any;
|
const payload = jwt.verify(token, secret) as any;
|
||||||
|
|
||||||
if (payload.userId) {
|
if (payload.userId) {
|
||||||
// User JWT Token
|
// User JWT Token
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ const router = Router();
|
|||||||
const upload = multer({ storage: multer.memoryStorage() });
|
const upload = multer({ storage: multer.memoryStorage() });
|
||||||
const s3Service = new S3Service();
|
const s3Service = new S3Service();
|
||||||
const identityService = new IdentityService();
|
const identityService = new IdentityService();
|
||||||
const JWT_SECRET = process.env.JWT_SECRET || 'super_secret_pharmacy_key_2026';
|
// JWT_SECRET evaluated at runtime
|
||||||
|
|
||||||
// GET /v1/auth/me (Get Profile)
|
// GET /v1/auth/me (Get Profile)
|
||||||
router.get('/me', requireAuth, async (req, res) => {
|
router.get('/me', requireAuth, async (req, res) => {
|
||||||
@@ -123,7 +123,7 @@ router.post('/token', (req, res) => {
|
|||||||
tenantId: client_id,
|
tenantId: client_id,
|
||||||
scopes: ['rx:read', 'rx:write', 'dispense:human', 'catalogue:read']
|
scopes: ['rx:read', 'rx:write', 'dispense:human', 'catalogue:read']
|
||||||
},
|
},
|
||||||
JWT_SECRET,
|
process.env.JWT_SECRET || 'super_secret_pharmacy_key_2026',
|
||||||
{ expiresIn: '8h' }
|
{ expiresIn: '8h' }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { pool } from '../../db/pool';
|
|||||||
import bcrypt from 'bcrypt';
|
import bcrypt from 'bcrypt';
|
||||||
import jwt from 'jsonwebtoken';
|
import jwt from 'jsonwebtoken';
|
||||||
|
|
||||||
const JWT_SECRET = process.env.JWT_SECRET || 'super_secret_pharmacy_key_2026';
|
// JWT_SECRET evaluated at runtime
|
||||||
|
|
||||||
export class IdentityService {
|
export class IdentityService {
|
||||||
async registerUser(payload: {
|
async registerUser(payload: {
|
||||||
@@ -63,7 +63,7 @@ export class IdentityService {
|
|||||||
role: user.role,
|
role: user.role,
|
||||||
tenant_id: user.tenant_id
|
tenant_id: user.tenant_id
|
||||||
},
|
},
|
||||||
JWT_SECRET,
|
process.env.JWT_SECRET || 'super_secret_pharmacy_key_2026',
|
||||||
{ expiresIn: '12h' } // Usually 8-12 hours for a shift
|
{ expiresIn: '12h' } // Usually 8-12 hours for a shift
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
filepath = r"c:\Users\Lenovo\Desktop\ai_pharma_frontend\src\services\api.ts"
|
||||||
|
|
||||||
|
with open(filepath, "r", encoding="utf-8") as f:
|
||||||
|
content = f.read()
|
||||||
|
|
||||||
|
# Replacement 1: Add API_KEY to axios.create
|
||||||
|
old_axios_create = """export const api = axios.create({
|
||||||
|
baseURL: API_BASE_URL,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
});"""
|
||||||
|
|
||||||
|
new_axios_create = """export const api = axios.create({
|
||||||
|
baseURL: API_BASE_URL,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'x-api-key': import.meta.env.VITE_API_KEY || '',
|
||||||
|
},
|
||||||
|
});"""
|
||||||
|
|
||||||
|
content = content.replace(old_axios_create, new_axios_create)
|
||||||
|
|
||||||
|
# Replacement 2: update authenticate
|
||||||
|
old_auth = """ const response = await axios.post(`${API_BASE_URL}/auth/token`, {
|
||||||
|
grant_type: 'client_credentials',
|
||||||
|
client_id: 'jayam_web_ai',
|
||||||
|
client_secret: 'my_secret_key'
|
||||||
|
});"""
|
||||||
|
|
||||||
|
new_auth = """ const response = await axios.post(`${API_BASE_URL}/auth/token`, {
|
||||||
|
grant_type: 'client_credentials',
|
||||||
|
client_id: 'jayam_web_ai',
|
||||||
|
client_secret: 'my_secret_key'
|
||||||
|
}, {
|
||||||
|
headers: { 'x-api-key': import.meta.env.VITE_API_KEY || '' }
|
||||||
|
});"""
|
||||||
|
|
||||||
|
content = content.replace(old_auth, new_auth)
|
||||||
|
|
||||||
|
# Replacement 3: update loginPharmacist
|
||||||
|
old_login = """ const response = await axios.post(`${API_BASE_URL}/auth/login`, credentials);"""
|
||||||
|
|
||||||
|
new_login = """ const response = await axios.post(`${API_BASE_URL}/auth/login`, credentials, {
|
||||||
|
headers: { 'x-api-key': import.meta.env.VITE_API_KEY || '' }
|
||||||
|
});"""
|
||||||
|
|
||||||
|
content = content.replace(old_login, new_login)
|
||||||
|
|
||||||
|
# Replacement 4: update logoutPharmacist
|
||||||
|
old_logout = """ const response = await axios.post(`${API_BASE_URL}/auth/logout`);"""
|
||||||
|
new_logout = """ const response = await axios.post(`${API_BASE_URL}/auth/logout`, {}, {
|
||||||
|
headers: { 'x-api-key': import.meta.env.VITE_API_KEY || '' }
|
||||||
|
});"""
|
||||||
|
|
||||||
|
content = content.replace(old_logout, new_logout)
|
||||||
|
|
||||||
|
with open(filepath, "w", encoding="utf-8") as f:
|
||||||
|
f.write(content)
|
||||||
|
|
||||||
|
print("Updated api.ts")
|
||||||
Reference in New Issue
Block a user