{"info":{"_postman_id":"4a1ca2e5-dd4c-4a9d-977a-78d2b50d8a7b","name":"Noventra SaaS Dashboard API","description":"<html><head></head><body><p>API documentation for Noventra SaaS Dashboard.</p>\n<p>Base URL: <a href=\"https://noventra-backend-dashboard.vercel.app\">https://noventra-backend-dashboard.vercel.app</a></p>\n<p>Authentication: Pass the JWT token in the request header as:\ntoken: </p>\n<p>Get the token from the Login endpoint. It saves automatically to  via the Tests script on the Login request.</p>\n<p>Roles:</p>\n<ul>\n<li>admin: full access</li>\n<li>manager: products, sales, employees (read), audit logs, dashboard</li>\n<li>employee: create sales, read products and sales</li>\n</ul>\n<p>Rate Limit: 200 requests per 15 minutes per IP.</p>\n</body></html>","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","toc":[],"owner":"49715513","collectionId":"4a1ca2e5-dd4c-4a9d-977a-78d2b50d8a7b","publishedId":"2sBY4TpJ1x","public":true,"customColor":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"FF6C37"},"publishDate":"2026-07-31T16:08:14.000Z"},"item":[{"name":"Auth","item":[{"name":"Create New Employee","id":"5e7b2caf-7f8f-4267-a480-77451ed33c98","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"token","value":"","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"name\": \"Diaa Eldeen\",\n  \"email\": \"diaaelseady@gmail.com\",\n  \"password\": \"Password@123\",\n  \"rePassword\": \"Password@123\",\n  \"gender\": \"male\",\n  \"phone\": \"01278396490\",\n  \"role\": \"employee\"\n}","options":{"raw":{"language":"json"}}},"url":"https://noventra-backend-dashboard.vercel.app/auth/newEmployee","description":"<p>Role: admin</p>\n<p>Body:\n{\n  \"name\": string, required, min 3 max 50\n  \"email\": string, required, valid email\n  \"password\": string, required, min 8 max 100\n  \"rePassword\": string, required, must match password\n  \"gender\": \"male\" | \"female\", optional\n  \"phone\": string, optional, Egyptian format 01[0125]XXXXXXXX\n  \"role\": \"admin\" | \"manager\" | \"employee\", optional, default employee\n}</p>\n<p>Response 201:\n{\n  \"success\": true,\n  \"data\": {\n    \"_id\": \"...\",\n    \"name\": \"Diaa Eldeen\",\n    \"email\": \"<a href=\"mailto:diaaelseady@gmail.com\">diaaelseady@gmail.com</a>\",\n    \"gender\": \"male\",\n    \"role\": \"employee\",\n    \"isActive\": true,\n    \"createdAt\": \"...\",\n    \"updatedAt\": \"...\"\n  }\n}</p>\n<p>Errors:</p>\n<ul>\n<li>409: email already exists</li>\n<li>400: validation error</li>\n</ul>\n","urlObject":{"path":["auth","newEmployee"],"host":["https://noventra-backend-dashboard.vercel.app"],"query":[],"variable":[]}},"response":[],"_postman_id":"5e7b2caf-7f8f-4267-a480-77451ed33c98"},{"name":"Login","event":[{"listen":"test","script":{"exec":["const res = pm.response.json();","if (res.data && res.data.token) {","  pm.collectionVariables.set('token', res.data.token);","}"],"type":"text/javascript","id":"6d356d8e-23da-4d46-962b-ce0247ac55c6"}}],"id":"e2b67f6a-7141-4778-9163-a25b59c83669","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"email\": \"diaaelseady@gmail.com\",\n  \"password\": \"Password@123\"\n}","options":{"raw":{"language":"json"}}},"url":"https://noventra-backend-dashboard.vercel.app/auth/login","description":"<p>Role: public</p>\n<p>Token is saved automatically to  via the Tests script.</p>\n<p>Body:\n{\n  \"email\": string, required\n  \"password\": string, required\n}</p>\n<p>Response 200:\n{\n  \"success\": true,\n  \"message\": \"LogIn Succefully\",\n  \"data\": {\n    \"token\": \"{{supabase_service_role_api_key_0hsq}}...\"\n  }\n}</p>\n<p>Errors:</p>\n<ul>\n<li>409: user does not exist</li>\n<li>400: invalid password</li>\n<li>403: account is deactivated</li>\n</ul>\n","urlObject":{"path":["auth","login"],"host":["https://noventra-backend-dashboard.vercel.app"],"query":[],"variable":[]}},"response":[],"_postman_id":"e2b67f6a-7141-4778-9163-a25b59c83669"},{"name":"Get My Profile","id":"8a6b52fc-cd3d-493d-b663-8f88752601f4","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"token","value":"","type":"text"}],"url":"https://noventra-backend-dashboard.vercel.app/auth/profile","description":"<p>Role: any authenticated user</p>\n<p>Phone is returned decrypted. Password is excluded.</p>\n<p>Response 200:\n{\n  \"success\": true,\n  \"data\": {\n    \"_id\": \"...\",\n    \"name\": \"Diaa Eldeen\",\n    \"email\": \"<a href=\"mailto:diaaelseady@gmail.com\">diaaelseady@gmail.com</a>\",\n    \"gender\": \"male\",\n    \"phone\": \"01278396490\",\n    \"role\": \"admin\",\n    \"isActive\": true\n  }\n}</p>\n","urlObject":{"path":["auth","profile"],"host":["https://noventra-backend-dashboard.vercel.app"],"query":[],"variable":[]}},"response":[],"_postman_id":"8a6b52fc-cd3d-493d-b663-8f88752601f4"},{"name":"Update My Password","id":"2bab77c7-3173-4957-91cd-1caf1980b3b0","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"PATCH","header":[{"key":"token","value":"","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"oldPassword\": \"Password@123\",\n  \"newPassword\": \"NewPassword@456\",\n  \"rePassword\": \"NewPassword@456\"\n}","options":{"raw":{"language":"json"}}},"url":"https://noventra-backend-dashboard.vercel.app/auth/updatePassword","description":"<p>Role: any authenticated user</p>\n<p>Body:\n{\n  \"oldPassword\": string, required, min 8 max 100\n  \"newPassword\": string, required, min 8 max 100, must differ from old\n  \"rePassword\": string, required, must match newPassword\n}</p>\n<p>Response 200:\n{\n  \"success\": true\n}</p>\n<p>Errors:</p>\n<ul>\n<li>400: old password is incorrect</li>\n<li>400: new password same as old password</li>\n<li>400: rePassword does not match newPassword</li>\n</ul>\n","urlObject":{"path":["auth","updatePassword"],"host":["https://noventra-backend-dashboard.vercel.app"],"query":[],"variable":[]}},"response":[],"_postman_id":"2bab77c7-3173-4957-91cd-1caf1980b3b0"},{"name":"Reset Employee Password","id":"15f0c9dc-19ad-49fc-b54f-478e91a5d800","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"PATCH","header":[{"key":"token","value":"","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"newPassword\": \"ResetPass@789\"\n}","options":{"raw":{"language":"json"}}},"url":"https://noventra-backend-dashboard.vercel.app/auth/users/:id/reset-password","description":"<p>Role: admin</p>\n<p>URL Param:</p>\n<ul>\n<li>id: MongoDB ObjectId of the employee</li>\n</ul>\n<p>Body:\n{\n  \"newPassword\": string, required, min 8 max 100, must differ from current\n}</p>\n<p>Response 200:\n{\n  \"success\": true,\n  \"message\": \"Password reset successfully\"\n}</p>\n<p>Errors:</p>\n<ul>\n<li>404: employee not found</li>\n<li>400: new password same as current password</li>\n</ul>\n","urlObject":{"path":["auth","users",":id","reset-password"],"host":["https://noventra-backend-dashboard.vercel.app"],"query":[],"variable":[{"id":"7965f336-be38-4227-be78-6adba77af23f","description":{"content":"<p>MongoDB ObjectId of the employee</p>\n","type":"text/plain"},"type":"any","value":"64f1a2b3c4d5e6f7a8b9c0d1","key":"id"}]}},"response":[],"_postman_id":"15f0c9dc-19ad-49fc-b54f-478e91a5d800"}],"id":"fb314076-aaf8-4e4b-aa29-1f0db103a9e9","_postman_id":"fb314076-aaf8-4e4b-aa29-1f0db103a9e9","description":""},{"name":"Users","item":[{"name":"Get All Employees","id":"2717c53f-24e2-41c7-9550-b88c99d52529","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"token","value":"","type":"text"}],"url":"https://noventra-backend-dashboard.vercel.app/users","description":"<p>Role: admin, manager</p>\n<p>Returns all users except admins. Phone is decrypted before returning. Password excluded.</p>\n<p>Response 200:\n{\n  \"success\": true,\n  \"data\": [\n    {\n      \"_id\": \"...\",\n      \"name\": \"Diaa Eldeen\",\n      \"email\": \"<a href=\"mailto:diaaelseady@gmail.com\">diaaelseady@gmail.com</a>\",\n      \"phone\": \"01278396490\",\n      \"gender\": \"male\",\n      \"role\": \"employee\",\n      \"isActive\": true,\n      \"createdAt\": \"...\",\n      \"updatedAt\": \"...\"\n    }\n  ]\n}</p>\n","urlObject":{"path":["users"],"host":["https://noventra-backend-dashboard.vercel.app"],"query":[],"variable":[]}},"response":[],"_postman_id":"2717c53f-24e2-41c7-9550-b88c99d52529"},{"name":"Get Specific Employee","id":"6c12f88c-0052-4d28-9021-f5d86aeb4df2","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"token","value":"","type":"text"}],"url":"https://noventra-backend-dashboard.vercel.app/users/:id","description":"<p>Role: admin, manager</p>\n<p>URL Param:</p>\n<ul>\n<li>id: MongoDB ObjectId</li>\n</ul>\n<p>Phone is decrypted before returning. Password excluded.</p>\n<p>Response 200:\n{\n  \"success\": true,\n  \"data\": {\n    \"_id\": \"...\",\n    \"name\": \"Diaa Eldeen\",\n    \"email\": \"<a href=\"mailto:diaaelseady@gmail.com\">diaaelseady@gmail.com</a>\",\n    \"phone\": \"01278396490\",\n    \"gender\": \"male\",\n    \"role\": \"employee\",\n    \"isActive\": true\n  }\n}</p>\n<p>Errors:</p>\n<ul>\n<li>404: employee not found</li>\n</ul>\n","urlObject":{"path":["users",":id"],"host":["https://noventra-backend-dashboard.vercel.app"],"query":[],"variable":[{"id":"fc8bc26c-6296-46c1-9ea8-7dd63a221571","description":{"content":"<p>MongoDB ObjectId of the employee</p>\n","type":"text/plain"},"type":"any","value":"64f1a2b3c4d5e6f7a8b9c0d1","key":"id"}]}},"response":[],"_postman_id":"6c12f88c-0052-4d28-9021-f5d86aeb4df2"},{"name":"Toggle Employee Status","id":"3a400e67-643f-4113-a273-a130a8ca0508","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"PATCH","header":[{"key":"token","value":"","type":"text"}],"url":"https://noventra-backend-dashboard.vercel.app/users/:id/status","description":"<p>Role: admin</p>\n<p>Toggles isActive. Deactivated employees cannot login.</p>\n<p>URL Param:</p>\n<ul>\n<li>id: MongoDB ObjectId</li>\n</ul>\n<p>No body required.</p>\n<p>Response 200:\n{\n  \"success\": true,\n  \"data\": {\n    \"_id\": \"...\",\n    \"name\": \"Diaa Eldeen\",\n    \"isActive\": false\n  }\n}</p>\n<p>Errors:</p>\n<ul>\n<li>404: employee not found</li>\n</ul>\n","urlObject":{"path":["users",":id","status"],"host":["https://noventra-backend-dashboard.vercel.app"],"query":[],"variable":[{"id":"2d50a34f-7ac5-4313-9230-18316a5c9b71","description":{"content":"<p>MongoDB ObjectId of the employee</p>\n","type":"text/plain"},"type":"any","value":"64f1a2b3c4d5e6f7a8b9c0d1","key":"id"}]}},"response":[],"_postman_id":"3a400e67-643f-4113-a273-a130a8ca0508"},{"name":"Update Employee","id":"85831581-0a9a-48c0-90c9-d12c4438ce8e","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"PUT","header":[{"key":"token","value":"","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"name\": \"Diaa Eldeen\",\n  \"email\": \"diaaelseady@gmail.com\",\n  \"gender\": \"male\",\n  \"phone\": \"01278396490\",\n  \"role\": \"manager\"\n}","options":{"raw":{"language":"json"}}},"url":"https://noventra-backend-dashboard.vercel.app/users/:id","description":"<p>Role: admin</p>\n<p>Updates an employee's profile. Phone number is encrypted before storage. If role changes, the change is recorded in the audit log.</p>\n<p>URL Param:</p>\n<ul>\n<li>id: MongoDB ObjectId</li>\n</ul>\n<p>Body (all fields optional):\n{\n  \"name\": string, optional, min 3 max 50\n  \"email\": string, optional, valid email\n  \"gender\": \"male\" | \"female\", optional\n  \"phone\": string, optional, Egyptian format 01[0125]XXXXXXXX\n  \"role\": \"admin\" | \"manager\" | \"employee\", optional\n}</p>\n<p>Response 200:\n{\n  \"success\": true,\n  \"data\": {\n    \"_id\": \"...\",\n    \"name\": \"Diaa Eldeen\",\n    \"email\": \"<a href=\"mailto:diaaelseady@gmail.com\">diaaelseady@gmail.com</a>\",\n    \"role\": \"manager\",\n    \"isActive\": true\n  }\n}</p>\n<p>Errors:</p>\n<ul>\n<li>404: employee not found</li>\n</ul>\n","urlObject":{"path":["users",":id"],"host":["https://noventra-backend-dashboard.vercel.app"],"query":[],"variable":[{"id":"5547764d-f2c3-4256-bb20-424e98068ac4","description":{"content":"<p>MongoDB ObjectId of the employee</p>\n","type":"text/plain"},"type":"any","value":"64f1a2b3c4d5e6f7a8b9c0d1","key":"id"}]}},"response":[],"_postman_id":"85831581-0a9a-48c0-90c9-d12c4438ce8e"}],"id":"ee83177a-fef7-4ab4-a60d-4665d21bb276","_postman_id":"ee83177a-fef7-4ab4-a60d-4665d21bb276","description":""},{"name":"Products","item":[{"name":"Add Product","id":"ecdb860c-ba03-4b48-afb6-b2e4090450f1","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"token","value":"","type":"text"}],"body":{"mode":"formdata","formdata":[{"key":"name","value":"Wireless Keyboard","type":"text"},{"key":"sku","value":"WK-2024-BLK","type":"text"},{"key":"description","value":"Compact keyboard with long battery life.","type":"text"},{"key":"purchasePrice","value":"150","type":"text"},{"key":"sellingPrice","value":"250","type":"text"},{"key":"stock","value":"100","type":"text"},{"key":"lowStockThreshold","value":"10","type":"text"},{"key":"category","value":"Electronics","type":"text"},{"key":"image","type":"file","value":null}]},"url":"https://noventra-backend-dashboard.vercel.app/products","description":"<p>Role: admin, manager</p>\n<p>Uses multipart/form-data because of the image upload. Do NOT set Content-Type manually.</p>\n<p>Image is uploaded to Cloudinary. Audit log is created automatically.</p>\n<p>Form Fields:</p>\n<ul>\n<li>name: string, required, min 2, unique</li>\n<li>sku: string, required, min 3, unique</li>\n<li>description: string, optional</li>\n<li>purchasePrice: string (number &gt;= 0), required</li>\n<li>sellingPrice: string (number &gt;= 0), required</li>\n<li>stock: string (number &gt;= 0), required</li>\n<li>lowStockThreshold: string (number &gt;= 0), optional, default 5</li>\n<li>category: string, required, min 2</li>\n<li>image: file, required, image only, max 5MB</li>\n</ul>\n<p>Note: All numeric fields are sent as strings. The API converts them internally.</p>\n<p>Response 201:\n{\n  \"success\": true,\n  \"data\": {\n    \"_id\": \"...\",\n    \"name\": \"Wireless Keyboard\",\n    \"slug\": \"wireless-keyboard\",\n    \"sku\": \"WK-2024-BLK\",\n    \"description\": \"Compact keyboard with long battery life.\",\n    \"purchasePrice\": 150,\n    \"sellingPrice\": 250,\n    \"stock\": 100,\n    \"lowStockThreshold\": 10,\n    \"category\": \"Electronics\",\n    \"image\": [\n      {\n        \"secure_url\": \"<a href=\"https://res.cloudinary.com/\">https://res.cloudinary.com/</a>...\",\n        \"public_id\": \"noventra_dashboard/products/...\"\n      }\n    ],\n    \"isAvailable\": true,\n    \"createdBy\": \"...\",\n    \"createdAt\": \"...\",\n    \"updatedAt\": \"...\"\n  }\n}</p>\n<p>Errors:</p>\n<ul>\n<li>400: name or SKU already exists</li>\n<li>400: image missing or not an image</li>\n<li>400: image exceeds 5MB</li>\n</ul>\n","urlObject":{"path":["products"],"host":["https://noventra-backend-dashboard.vercel.app"],"query":[],"variable":[]}},"response":[],"_postman_id":"ecdb860c-ba03-4b48-afb6-b2e4090450f1"},{"name":"Get All Products","id":"46486933-b9a2-4868-8fc8-b4ba38a1a4c9","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"token","value":"","type":"text"}],"url":"https://noventra-backend-dashboard.vercel.app/products?page=1&limit=10&search=keyboard&category=Electronics&sort=sellingPrice&order=asc","description":"<p>Role: admin, manager, employee</p>\n<p>Query Params:</p>\n<ul>\n<li>page: number, optional, default 1</li>\n<li>limit: number, optional, max 50, default 10</li>\n<li>search: string, optional, matches name or SKU</li>\n<li>category: string, optional, exact match</li>\n<li>sort: string, optional, any product field</li>\n<li>order: \"asc\" | \"desc\", optional, default desc</li>\n</ul>\n<p>Response 200:\n{\n  \"success\": true,\n  \"data\": {\n    \"products\": [\n      {\n        \"_id\": \"...\",\n        \"name\": \"Wireless Keyboard\",\n        \"slug\": \"wireless-keyboard\",\n        \"sku\": \"WK-2024-BLK\",\n        \"purchasePrice\": 150,\n        \"sellingPrice\": 250,\n        \"stock\": 100,\n        \"lowStockThreshold\": 10,\n        \"category\": \"Electronics\",\n        \"isAvailable\": true,\n        \"image\": [\n          {\n            \"secure_url\": \"<a href=\"https://res.cloudinary.com/\">https://res.cloudinary.com/</a>...\",\n            \"public_id\": \"noventra_dashboard/products/...\"\n          }\n        ]\n      }\n    ],\n    \"pagination\": {\n      \"page\": 1,\n      \"limit\": 10,\n      \"total\": 45,\n      \"pages\": 5\n    }\n  }\n}</p>\n","urlObject":{"path":["products"],"host":["https://noventra-backend-dashboard.vercel.app"],"query":[{"description":{"content":"<p>default 1</p>\n","type":"text/plain"},"key":"page","value":"1"},{"description":{"content":"<p>max 50, default 10</p>\n","type":"text/plain"},"key":"limit","value":"10"},{"description":{"content":"<p>searches name and SKU, case-insensitive</p>\n","type":"text/plain"},"key":"search","value":"keyboard"},{"description":{"content":"<p>exact match</p>\n","type":"text/plain"},"key":"category","value":"Electronics"},{"description":{"content":"<p>any product field</p>\n","type":"text/plain"},"key":"sort","value":"sellingPrice"},{"description":{"content":"<p>asc or desc, default desc</p>\n","type":"text/plain"},"key":"order","value":"asc"}],"variable":[]}},"response":[],"_postman_id":"46486933-b9a2-4868-8fc8-b4ba38a1a4c9"},{"name":"Get Low Stock Products","id":"a0b1c21c-ea2e-439d-930a-8a233b44b003","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"token","value":"","type":"text"}],"url":"https://noventra-backend-dashboard.vercel.app/products/low-stock","description":"<p>Role: admin, manager</p>\n<p>Returns products where stock &lt;= lowStockThreshold.</p>\n<p>No params or body required.</p>\n<p>Response 200:\n{\n  \"success\": true,\n  \"data\": [\n    {\n      \"_id\": \"...\",\n      \"name\": \"Wireless Keyboard\",\n      \"sku\": \"WK-2024-BLK\",\n      \"stock\": 3,\n      \"lowStockThreshold\": 5,\n      \"category\": \"Electronics\",\n      \"isAvailable\": true\n    }\n  ]\n}</p>\n","urlObject":{"path":["products","low-stock"],"host":["https://noventra-backend-dashboard.vercel.app"],"query":[],"variable":[]}},"response":[],"_postman_id":"a0b1c21c-ea2e-439d-930a-8a233b44b003"},{"name":"Get Specific Product","id":"a8615d3d-5b15-493f-bdd0-75bebca4f13b","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"token","value":"","type":"text"}],"url":"https://noventra-backend-dashboard.vercel.app/products/:productId","description":"<p>Role: admin, manager, employee</p>\n<p>URL Param:</p>\n<ul>\n<li>productId: MongoDB ObjectId</li>\n</ul>\n<p>Response 200:\n{\n  \"success\": true,\n  \"data\": {\n    \"_id\": \"...\",\n    \"name\": \"Wireless Keyboard\",\n    \"slug\": \"wireless-keyboard\",\n    \"sku\": \"WK-2024-BLK\",\n    \"description\": \"Compact keyboard with long battery life.\",\n    \"purchasePrice\": 150,\n    \"sellingPrice\": 250,\n    \"stock\": 100,\n    \"lowStockThreshold\": 10,\n    \"category\": \"Electronics\",\n    \"image\": [\n      {\n        \"secure_url\": \"<a href=\"https://res.cloudinary.com/\">https://res.cloudinary.com/</a>...\",\n        \"public_id\": \"noventra_dashboard/products/...\"\n      }\n    ],\n    \"isAvailable\": true,\n    \"createdBy\": \"...\",\n    \"createdAt\": \"...\",\n    \"updatedAt\": \"...\"\n  }\n}</p>\n<p>Errors:</p>\n<ul>\n<li>404: product not found</li>\n</ul>\n","urlObject":{"path":["products",":productId"],"host":["https://noventra-backend-dashboard.vercel.app"],"query":[],"variable":[{"id":"4ea951fc-e723-4531-952f-09bec55348ba","description":{"content":"<p>MongoDB ObjectId</p>\n","type":"text/plain"},"type":"any","value":"64f1a2b3c4d5e6f7a8b9c0d1","key":"productId"}]}},"response":[],"_postman_id":"a8615d3d-5b15-493f-bdd0-75bebca4f13b"},{"name":"Update Product","id":"140b1074-f7fb-4ca4-910a-ec2a26e2f60b","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"PUT","header":[{"key":"token","value":"","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"name\": \"Wireless Keyboard Pro\",\n  \"description\": \"Updated description.\",\n  \"purchasePrice\": \"170\",\n  \"sellingPrice\": \"280\",\n  \"stock\": \"95\",\n  \"lowStockThreshold\": \"15\",\n  \"category\": \"Electronics\"\n}","options":{"raw":{"language":"json"}}},"url":"https://noventra-backend-dashboard.vercel.app/products/:productId","description":"<p>Role: admin, manager</p>\n<p>All body fields are optional. If name is updated, slug is regenerated automatically. Audit log is created.</p>\n<p>URL Param:</p>\n<ul>\n<li>productId: MongoDB ObjectId</li>\n</ul>\n<p>Body (all optional):\n{\n  \"name\": string, min 2, unique\n  \"description\": string\n  \"purchasePrice\": string (number &gt;= 0)\n  \"sellingPrice\": string (number &gt;= 0)\n  \"stock\": string (number &gt;= 0)\n  \"lowStockThreshold\": string (number &gt;= 0)\n  \"category\": string, min 2\n}</p>\n<p>Note: Numeric fields are sent as strings.</p>\n<p>Response 200:\n{\n  \"success\": true,\n  \"data\": {\n    \"_id\": \"...\",\n    \"name\": \"Wireless Keyboard Pro\",\n    \"slug\": \"wireless-keyboard-pro\",\n    \"purchasePrice\": 170,\n    \"sellingPrice\": 280,\n    \"stock\": 95,\n    \"lowStockThreshold\": 15,\n    \"category\": \"Electronics\"\n  }\n}</p>\n<p>Errors:</p>\n<ul>\n<li>404: product not found</li>\n<li>400: name already exists</li>\n</ul>\n","urlObject":{"path":["products",":productId"],"host":["https://noventra-backend-dashboard.vercel.app"],"query":[],"variable":[{"id":"bfa8e681-8c89-427c-9320-7d43ebe4695d","description":{"content":"<p>MongoDB ObjectId</p>\n","type":"text/plain"},"type":"any","value":"64f1a2b3c4d5e6f7a8b9c0d1","key":"productId"}]}},"response":[],"_postman_id":"140b1074-f7fb-4ca4-910a-ec2a26e2f60b"},{"name":"Update Stock","id":"293bde3e-a912-4234-aa5a-962fa5d94558","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"PATCH","header":[{"key":"token","value":"","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"quantity\": \"1\"\n}","options":{"raw":{"language":"json"}}},"url":"https://noventra-backend-dashboard.vercel.app/products/:productId/stock","description":"<p>Role: admin, manager</p>\n<p>Adjusts stock by exactly 1 or -1. Audit log is created.</p>\n<p>URL Param:</p>\n<ul>\n<li>productId: MongoDB ObjectId</li>\n</ul>\n<p>Body:\n{\n  \"quantity\": \"1\" to increment or \"-1\" to decrement\n}</p>\n<p>Response 200:\n{\n  \"success\": true,\n  \"data\": {\n    \"_id\": \"...\",\n    \"name\": \"Wireless Keyboard\",\n    \"stock\": 101\n  }\n}</p>\n<p>Errors:</p>\n<ul>\n<li>404: product not found</li>\n<li>400: quantity must be 1 or -1</li>\n</ul>\n","urlObject":{"path":["products",":productId","stock"],"host":["https://noventra-backend-dashboard.vercel.app"],"query":[],"variable":[{"id":"a4a85fd8-bcff-47cc-8552-2791d532ece3","description":{"content":"<p>MongoDB ObjectId</p>\n","type":"text/plain"},"type":"any","value":"64f1a2b3c4d5e6f7a8b9c0d1","key":"productId"}]}},"response":[],"_postman_id":"293bde3e-a912-4234-aa5a-962fa5d94558"},{"name":"Toggle Product Availability","id":"e1a52c95-f4d2-444c-9cda-85052c3bb6d9","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"PATCH","header":[{"key":"token","value":"","type":"text"}],"url":"https://noventra-backend-dashboard.vercel.app/products/:productId/availability","description":"<p>Role: admin, manager</p>\n<p>Toggles isAvailable. Audit log is created.</p>\n<p>URL Param:</p>\n<ul>\n<li>productId: MongoDB ObjectId</li>\n</ul>\n<p>No body required.</p>\n<p>Response 200:\n{\n  \"success\": true,\n  \"data\": {\n    \"_id\": \"...\",\n    \"name\": \"Wireless Keyboard\",\n    \"isAvailable\": false\n  }\n}</p>\n<p>Errors:</p>\n<ul>\n<li>404: product not found</li>\n</ul>\n","urlObject":{"path":["products",":productId","availability"],"host":["https://noventra-backend-dashboard.vercel.app"],"query":[],"variable":[{"id":"ef8c9462-7bb2-49a2-b5f7-8cf81cfc3748","description":{"content":"<p>MongoDB ObjectId</p>\n","type":"text/plain"},"type":"any","value":"64f1a2b3c4d5e6f7a8b9c0d1","key":"productId"}]}},"response":[],"_postman_id":"e1a52c95-f4d2-444c-9cda-85052c3bb6d9"}],"id":"cf833643-2433-4307-94fa-dab5dfdf0dae","_postman_id":"cf833643-2433-4307-94fa-dab5dfdf0dae","description":""},{"name":"Sales","item":[{"name":"Create Sale","id":"b1cd55f0-f7eb-4b10-bedf-2f5e3ff30658","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"token","value":"","type":"text"},{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"items\": [\n    {\n      \"product\": \"64f1a2b3c4d5e6f7a8b9c0d1\",\n      \"quantity\": 2\n    },\n    {\n      \"product\": \"64f1a2b3c4d5e6f7a8b9c0d2\",\n      \"quantity\": 1\n    }\n  ],\n  \"paymentMethod\": \"cash\"\n}","options":{"raw":{"language":"json"}}},"url":"https://noventra-backend-dashboard.vercel.app/sales","description":"<p>Role: admin, manager, employee</p>\n<p>Processes a sale with a MongoDB transaction. Stock is decremented atomically. Invoice number is auto-generated. Audit log and in-app notifications are created. If any product stock drops to &lt;= 5 after the sale, a low stock email is sent to the admin.</p>\n<p>Duplicate product IDs in items are not allowed. Use a single item with the combined quantity instead.</p>\n<p>Body:\n{\n  \"items\": array, required, min 1 item, no duplicate product IDs\n    [\n      {\n        \"product\": string, required, MongoDB ObjectId\n        \"quantity\": number, required, integer &gt; 0\n      }\n    ]\n  \"paymentMethod\": \"cash\" | \"card\", optional, default cash\n}</p>\n<p>Response 201:\n{\n  \"success\": true,\n  \"message\": \"Sale completed successfully\",\n  \"data\": {\n    \"_id\": \"...\",\n    \"invoiceNumber\": \"INV-20241215-143022-4823\",\n    \"items\": [\n      {\n        \"productId\": \"...\",\n        \"quantity\": 2,\n        \"purchasePriceAtSale\": 150,\n        \"sellingPriceAtSale\": 250\n      }\n    ],\n    \"totalAmount\": 500,\n    \"totalProfit\": 200,\n    \"paymentMethod\": \"cash\",\n    \"soldBy\": \"...\",\n    \"isCancelled\": false,\n    \"createdAt\": \"...\",\n    \"updatedAt\": \"...\"\n  }\n}</p>\n<p>Errors:</p>\n<ul>\n<li>404: one or more products not found or unavailable</li>\n<li>400: insufficient stock for a product</li>\n<li>409: stock changed during transaction, retry the request</li>\n</ul>\n","urlObject":{"path":["sales"],"host":["https://noventra-backend-dashboard.vercel.app"],"query":[],"variable":[]}},"response":[],"_postman_id":"b1cd55f0-f7eb-4b10-bedf-2f5e3ff30658"},{"name":"Get All Sales","id":"57df630b-c200-4f12-8b83-1b40fec598a5","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"token","value":"","type":"text"}],"url":"https://noventra-backend-dashboard.vercel.app/sales?page=1&limit=10&paymentMethod=cash&startDate=2024-01-01&endDate=2024-12-31&isCancelled=false&soldBy=64f1a2b3c4d5e6f7a8b9c0d1","description":"<p>Role: admin, manager, employee</p>\n<p>Returns paginated sales. soldBy is populated with name, email, role. items.productId is populated with name, sellingPrice, category.</p>\n<p>Query Params:</p>\n<ul>\n<li>page: number, optional, default 1</li>\n<li>limit: number, optional, default 10</li>\n<li>paymentMethod: \"cash\" | \"card\", optional</li>\n<li>isCancelled: boolean string, optional, default false</li>\n<li>soldBy: MongoDB ObjectId, optional</li>\n<li>startDate: ISO date string, optional</li>\n<li>endDate: ISO date string, optional</li>\n</ul>\n<p>Response 200:\n{\n  \"success\": true,\n  \"message\": \"Sales fetched successfully\",\n  \"data\": {\n    \"sales\": [\n      {\n        \"_id\": \"...\",\n        \"invoiceNumber\": \"INV-20241215-143022-4823\",\n        \"items\": [\n          {\n            \"productId\": {\n              \"_id\": \"...\",\n              \"name\": \"Wireless Keyboard\",\n              \"sellingPrice\": 250,\n              \"category\": \"Electronics\"\n            },\n            \"quantity\": 2,\n            \"purchasePriceAtSale\": 150,\n            \"sellingPriceAtSale\": 250\n          }\n        ],\n        \"totalAmount\": 500,\n        \"totalProfit\": 200,\n        \"paymentMethod\": \"cash\",\n        \"soldBy\": {\n          \"_id\": \"...\",\n          \"name\": \"Diaa Eldeen\",\n          \"email\": \"<a href=\"mailto:diaaelseady@gmail.com\">diaaelseady@gmail.com</a>\",\n          \"role\": \"employee\"\n        },\n        \"isCancelled\": false,\n        \"createdAt\": \"...\"\n      }\n    ],\n    \"pagination\": {\n      \"totalDocs\": 120,\n      \"totalPages\": 12,\n      \"currentPage\": 1,\n      \"limit\": 10\n    }\n  }\n}</p>\n","urlObject":{"path":["sales"],"host":["https://noventra-backend-dashboard.vercel.app"],"query":[{"description":{"content":"<p>default 1</p>\n","type":"text/plain"},"key":"page","value":"1"},{"description":{"content":"<p>default 10</p>\n","type":"text/plain"},"key":"limit","value":"10"},{"description":{"content":"<p>cash or card</p>\n","type":"text/plain"},"key":"paymentMethod","value":"cash"},{"description":{"content":"<p>ISO date string, filters from start of this day</p>\n","type":"text/plain"},"key":"startDate","value":"2024-01-01"},{"description":{"content":"<p>ISO date string, filters to end of this day</p>\n","type":"text/plain"},"key":"endDate","value":"2024-12-31"},{"description":{"content":"<p>boolean string, optional, default false. Filter by cancellation status</p>\n","type":"text/plain"},"key":"isCancelled","value":"false"},{"description":{"content":"<p>MongoDB ObjectId, optional. Filter sales by a specific employee</p>\n","type":"text/plain"},"key":"soldBy","value":"64f1a2b3c4d5e6f7a8b9c0d1"}],"variable":[]}},"response":[],"_postman_id":"57df630b-c200-4f12-8b83-1b40fec598a5"},{"name":"Get Sale By ID","id":"a45ded19-8802-45ec-a0d1-a924cee49dc8","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"token","value":"","type":"text"}],"url":"https://noventra-backend-dashboard.vercel.app/sales/:id","description":"<p>Role: admin, manager, employee</p>\n<p>URL Param:</p>\n<ul>\n<li>id: MongoDB ObjectId</li>\n</ul>\n<p>Populates soldBy, cancelledBy, and items.productId.</p>\n<p>Response 200:\n{\n  \"success\": true,\n  \"message\": \"Sale invoice fetched successfully\",\n  \"data\": {\n    \"sale\": {\n      \"_id\": \"...\",\n      \"invoiceNumber\": \"INV-20241215-143022-4823\",\n      \"items\": [\n        {\n          \"productId\": {\n            \"_id\": \"...\",\n            \"name\": \"Wireless Keyboard\",\n            \"category\": \"Electronics\",\n            \"sellingPrice\": 250\n          },\n          \"quantity\": 2,\n          \"purchasePriceAtSale\": 150,\n          \"sellingPriceAtSale\": 250\n        }\n      ],\n      \"totalAmount\": 500,\n      \"totalProfit\": 200,\n      \"paymentMethod\": \"cash\",\n      \"soldBy\": {\n        \"_id\": \"...\",\n        \"name\": \"Diaa Eldeen\",\n        \"email\": \"<a href=\"mailto:diaaelseady@gmail.com\">diaaelseady@gmail.com</a>\",\n        \"role\": \"employee\"\n      },\n      \"isCancelled\": false,\n      \"cancelledBy\": null,\n      \"cancelledAt\": null,\n      \"createdAt\": \"...\",\n      \"updatedAt\": \"...\"\n    }\n  }\n}</p>\n<p>Errors:</p>\n<ul>\n<li>404: sale not found</li>\n</ul>\n","urlObject":{"path":["sales",":id"],"host":["https://noventra-backend-dashboard.vercel.app"],"query":[],"variable":[{"id":"be443c45-3f73-42b1-b632-76b098e57da0","description":{"content":"<p>MongoDB ObjectId of the sale</p>\n","type":"text/plain"},"type":"any","value":"64f1a2b3c4d5e6f7a8b9c0d1","key":"id"}]}},"response":[],"_postman_id":"a45ded19-8802-45ec-a0d1-a924cee49dc8"},{"name":"Print Single Sale","id":"3c83b1c7-5eca-46e0-9269-2d06c978a3b9","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"token","value":"","type":"text"}],"url":"https://noventra-backend-dashboard.vercel.app/sales/:id/print?format=pdf","description":"<p>Role: admin, manager, employee</p>\n<p>Exports a single sale invoice as a downloadable file.</p>\n<p>URL Param:</p>\n<ul>\n<li>id: MongoDB ObjectId</li>\n</ul>\n<p>Query Params:</p>\n<ul>\n<li>format: \"excel\" | \"pdf\" | \"word\", optional, default excel</li>\n</ul>\n<p>Response:</p>\n<ul>\n<li>format=excel: .xlsx file with invoice header and itemized product table</li>\n<li>format=pdf: .pdf inline invoice with product table and total</li>\n<li>format=word: .docx invoice with product table and total amount</li>\n</ul>\n<p>File contains: Invoice Number, Date, Sold By, Payment Method, per-item breakdown (Product Name, Qty, Unit Price, Total Price), and Total Amount</p>\n<p>Errors:</p>\n<ul>\n<li>404: sale not found</li>\n<li>400: unsupported format</li>\n</ul>\n","urlObject":{"path":["sales",":id","print"],"host":["https://noventra-backend-dashboard.vercel.app"],"query":[{"description":{"content":"<p>excel | pdf | word, optional, default excel</p>\n","type":"text/plain"},"key":"format","value":"pdf"}],"variable":[{"id":"d783aaf9-5e4e-43a0-b37c-6874a52347ea","description":{"content":"<p>MongoDB ObjectId of the sale</p>\n","type":"text/plain"},"type":"any","value":"64f1a2b3c4d5e6f7a8b9c0d1","key":"id"}]}},"response":[],"_postman_id":"3c83b1c7-5eca-46e0-9269-2d06c978a3b9"},{"name":"Cancel Sale","id":"342543b1-69b8-44ca-a875-171fdb03a518","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"PATCH","header":[{"key":"token","value":"","type":"text"}],"url":"https://noventra-backend-dashboard.vercel.app/sales/:id/cancel","description":"<p>Role: admin, manager</p>\n<p>Cancels a sale and restores the stock of all items using bulkWrite inside a transaction. Audit log and in-app notification are created.</p>\n<p>URL Param:</p>\n<ul>\n<li>id: MongoDB ObjectId</li>\n</ul>\n<p>No body required.</p>\n<p>Response 200:\n{\n  \"success\": true,\n  \"message\": \"Sale cancelled successfully and stock restored\",\n  \"data\": {\n    \"_id\": \"...\",\n    \"invoiceNumber\": \"INV-20241215-143022-4823\",\n    \"isCancelled\": true,\n    \"cancelledBy\": \"...\",\n    \"cancelledAt\": \"...\"\n  }\n}</p>\n<p>Errors:</p>\n<ul>\n<li>404: sale not found or already cancelled</li>\n</ul>\n","urlObject":{"path":["sales",":id","cancel"],"host":["https://noventra-backend-dashboard.vercel.app"],"query":[],"variable":[{"id":"6f244d68-85d9-454f-b7d4-bda9d3b9a455","description":{"content":"<p>MongoDB ObjectId of the sale</p>\n","type":"text/plain"},"type":"any","value":"64f1a2b3c4d5e6f7a8b9c0d1","key":"id"}]}},"response":[],"_postman_id":"342543b1-69b8-44ca-a875-171fdb03a518"},{"name":"Export Sales","id":"663be3f0-c73a-44fd-8fb5-c0708eb76d9a","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"token","value":"","type":"text"}],"url":"https://noventra-backend-dashboard.vercel.app/sales/export?format=excel&startDate=2024-01-01&endDate=2024-12-31","description":"<p>Role: admin, manager</p>\n<p>Exports sales data as a downloadable file. Max 5000 records. Cancelled sales are excluded.</p>\n<p>Query Params:</p>\n<ul>\n<li>format: \"excel\" | \"pdf\" | \"word\", optional, default excel</li>\n<li>startDate: ISO date string, optional</li>\n<li>endDate: ISO date string, optional</li>\n</ul>\n<p>Response:</p>\n<ul>\n<li>format=excel: .xlsx file download</li>\n<li>format=pdf: .pdf file download</li>\n<li>format=word: .docx file download</li>\n</ul>\n<p>File contains: Invoice Number, Date, Sold By, Items Count, Total Amount, Total Profit, Payment Method</p>\n<p>Errors:</p>\n<ul>\n<li>404: no sales data available for the given filters</li>\n<li>400: unsupported format</li>\n</ul>\n","urlObject":{"path":["sales","export"],"host":["https://noventra-backend-dashboard.vercel.app"],"query":[{"description":{"content":"<p>excel | pdf | word, default excel</p>\n","type":"text/plain"},"key":"format","value":"excel"},{"description":{"content":"<p>ISO date string, optional</p>\n","type":"text/plain"},"key":"startDate","value":"2024-01-01"},{"description":{"content":"<p>ISO date string, optional</p>\n","type":"text/plain"},"key":"endDate","value":"2024-12-31"}],"variable":[]}},"response":[],"_postman_id":"663be3f0-c73a-44fd-8fb5-c0708eb76d9a"}],"id":"991ae619-e3cc-49c0-95b8-0f36df2d5718","_postman_id":"991ae619-e3cc-49c0-95b8-0f36df2d5718","description":""},{"name":"Audit Logs","item":[{"name":"Get Audit Logs","id":"b7f0ed9a-dc8d-473c-ad16-874239c3f172","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"token","value":"","type":"text"}],"url":"https://noventra-backend-dashboard.vercel.app/audit-logs?page=1&limit=10&userId=&action=CREATE_SALE&targetModel=Sale&startDate=2024-01-01T00:00:00.000Z&endDate=2024-12-31T23:59:59.000Z","description":"<p>Role: admin, manager</p>\n<p>Returns paginated audit logs. userId is populated with name, email, role.</p>\n<p>Available action values:</p>\n<ul>\n<li>CREATE_PRODUCT</li>\n<li>UPDATE_PRODUCT</li>\n<li>UPDATE_STOCK</li>\n<li>TOGGLE_AVAILABILITY</li>\n<li>CREATE_SALE</li>\n<li>CANCEL_SALE</li>\n<li>LOW_STOCK_ALERT</li>\n</ul>\n<p>Available targetModel values:</p>\n<ul>\n<li>Product</li>\n<li>Sale</li>\n</ul>\n<p>Query Params:</p>\n<ul>\n<li>page: number, optional, default 1</li>\n<li>limit: number, optional, default 10</li>\n<li>userId: MongoDB ObjectId, optional</li>\n<li>action: string, optional</li>\n<li>targetModel: string, optional</li>\n<li>startDate: ISO datetime string, optional</li>\n<li>endDate: ISO datetime string, optional</li>\n</ul>\n<p>Note: startDate and endDate must be full ISO datetime strings (e.g. 2024-01-01T00:00:00.000Z)</p>\n<p>Response 200:\n{\n  \"success\": true,\n  \"message\": \"Audit logs fetched successfully\",\n  \"data\": {\n    \"logs\": [\n      {\n        \"_id\": \"...\",\n        \"userId\": {\n          \"_id\": \"...\",\n          \"name\": \"Diaa Eldeen\",\n          \"email\": \"<a href=\"mailto:diaaelseady@gmail.com\">diaaelseady@gmail.com</a>\",\n          \"role\": \"admin\"\n        },\n        \"action\": \"CREATE_SALE\",\n        \"targetId\": \"...\",\n        \"targetModel\": \"Sale\",\n        \"details\": \"Created sale invoice: INV-20241215-143022-4823 with total: 500\",\n        \"createdAt\": \"...\"\n      }\n    ],\n    \"pagination\": {\n      \"totalDocs\": 340,\n      \"totalPages\": 34,\n      \"currentPage\": 1,\n      \"limit\": 10\n    }\n  }\n}</p>\n","urlObject":{"path":["audit-logs"],"host":["https://noventra-backend-dashboard.vercel.app"],"query":[{"description":{"content":"<p>default 1</p>\n","type":"text/plain"},"key":"page","value":"1"},{"description":{"content":"<p>default 10</p>\n","type":"text/plain"},"key":"limit","value":"10"},{"description":{"content":"<p>MongoDB ObjectId, optional</p>\n","type":"text/plain"},"key":"userId","value":""},{"description":{"content":"<p>optional, e.g. CREATE_PRODUCT, UPDATE_STOCK, CREATE_SALE, CANCEL_SALE, TOGGLE_AVAILABILITY</p>\n","type":"text/plain"},"key":"action","value":"CREATE_SALE"},{"description":{"content":"<p>optional, e.g. Product, Sale</p>\n","type":"text/plain"},"key":"targetModel","value":"Sale"},{"description":{"content":"<p>ISO datetime string</p>\n","type":"text/plain"},"key":"startDate","value":"2024-01-01T00:00:00.000Z"},{"description":{"content":"<p>ISO datetime string</p>\n","type":"text/plain"},"key":"endDate","value":"2024-12-31T23:59:59.000Z"}],"variable":[]}},"response":[],"_postman_id":"b7f0ed9a-dc8d-473c-ad16-874239c3f172"},{"name":"Export Audit Logs","id":"a52ab75f-b4dd-4dd2-9bda-ddf5ea27a501","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"token","value":"","type":"text"}],"url":"https://noventra-backend-dashboard.vercel.app/audit-logs/export?format=excel&userId=&action=CREATE_SALE&targetModel=&startDate=2024-01-01T00:00:00.000Z&endDate=2024-12-31T23:59:59.000Z","description":"<p>Role: admin, manager</p>\n<p>Exports audit logs as a downloadable file. Same filters as Get Audit Logs. Max 5000 records.</p>\n<p>Query Params:</p>\n<ul>\n<li>format: \"excel\" | \"pdf\" | \"word\", optional, default excel</li>\n<li>userId: MongoDB ObjectId, optional</li>\n<li>action: string, optional</li>\n<li>targetModel: string, optional</li>\n<li>startDate: ISO datetime string, optional</li>\n<li>endDate: ISO datetime string, optional</li>\n</ul>\n<p>Response:</p>\n<ul>\n<li>format=excel: .xlsx file, columns: Date &amp; Time, User Name, User Email, Action, Target Model, Details</li>\n<li>format=pdf: .pdf file with same columns</li>\n<li>format=word: .docx file with columns: Date, User, Action, Details</li>\n</ul>\n<p>Errors:</p>\n<ul>\n<li>404: no audit logs available for the given filters</li>\n<li>400: unsupported format</li>\n</ul>\n","urlObject":{"path":["audit-logs","export"],"host":["https://noventra-backend-dashboard.vercel.app"],"query":[{"description":{"content":"<p>excel | pdf | word, default excel</p>\n","type":"text/plain"},"key":"format","value":"excel"},{"description":{"content":"<p>MongoDB ObjectId, optional</p>\n","type":"text/plain"},"key":"userId","value":""},{"description":{"content":"<p>optional</p>\n","type":"text/plain"},"key":"action","value":"CREATE_SALE"},{"description":{"content":"<p>optional, e.g. Product or Sale</p>\n","type":"text/plain"},"key":"targetModel","value":""},{"description":{"content":"<p>ISO datetime string</p>\n","type":"text/plain"},"key":"startDate","value":"2024-01-01T00:00:00.000Z"},{"description":{"content":"<p>ISO datetime string</p>\n","type":"text/plain"},"key":"endDate","value":"2024-12-31T23:59:59.000Z"}],"variable":[]}},"response":[],"_postman_id":"a52ab75f-b4dd-4dd2-9bda-ddf5ea27a501"}],"id":"eef42a03-b64e-4c20-a148-2964c5376317","_postman_id":"eef42a03-b64e-4c20-a148-2964c5376317","description":""},{"name":"Dashboard","item":[{"name":"Get Dashboard Stats","id":"b72c8e34-117b-4a0a-a0f7-c43dc856118a","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"token","value":"","type":"text"}],"url":"https://noventra-backend-dashboard.vercel.app/dashboard/stats","description":"<p>Role: admin, manager</p>\n<p>Returns overall KPIs. Result is cached in Redis for 10 minutes. Cache is invalidated automatically when a sale is created or cancelled.</p>\n<p>No params or body required.</p>\n<p>Response 200:\n{\n  \"success\": true,\n  \"message\": \"Dashboard stats fetched successfully\",\n  \"data\": {\n    \"totalSalesAmount\": 125000,\n    \"totalProfit\": 47000,\n    \"todaySalesAmount\": 3200,\n    \"monthSalesAmount\": 28000,\n    \"totalEmployees\": 12,\n    \"totalProducts\": 85,\n    \"lowStockProductsCount\": 4\n  }\n}</p>\n","urlObject":{"path":["dashboard","stats"],"host":["https://noventra-backend-dashboard.vercel.app"],"query":[],"variable":[]}},"response":[],"_postman_id":"b72c8e34-117b-4a0a-a0f7-c43dc856118a"},{"name":"Get Dashboard Charts","id":"9638db10-bda2-479d-b892-3a67d580c451","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"token","value":"","type":"text"}],"url":"https://noventra-backend-dashboard.vercel.app/dashboard/charts?period=monthly","description":"<p>Role: admin, manager</p>\n<p>Returns chart data for the selected period from Redis cache. Cache keys are invalidated when a sale is created or cancelled.</p>\n<p>Query Params:</p>\n<ul>\n<li>period: \"daily\" | \"monthly\" | \"yearly\", optional, default monthly</li>\n</ul>\n<p>Response 200:\n{\n  \"success\": true,\n  \"message\": \"Dashboard chart data (monthly) fetched successfully\",\n  \"data\": {\n    \"period\": \"monthly\",\n    \"chartData\": []\n  }\n}</p>\n<p>Note: chartData is populated by the internal cron system. It returns an empty array if no cache exists yet.</p>\n","urlObject":{"path":["dashboard","charts"],"host":["https://noventra-backend-dashboard.vercel.app"],"query":[{"description":{"content":"<p>daily | monthly | yearly, default monthly</p>\n","type":"text/plain"},"key":"period","value":"monthly"}],"variable":[]}},"response":[],"_postman_id":"9638db10-bda2-479d-b892-3a67d580c451"}],"id":"39adef80-64ad-4015-99a7-811d1f9fa135","_postman_id":"39adef80-64ad-4015-99a7-811d1f9fa135","description":""},{"name":"Notifications","item":[{"name":"Get My Notifications","id":"31cf7779-913b-4b28-afc7-e8cae31f65fd","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"token","value":"","type":"text"}],"url":"https://noventra-backend-dashboard.vercel.app/notification?page=1&limit=10&isRead=false","description":"<p>Role: any authenticated user</p>\n<p>Returns notifications for the logged-in user only. Sorted by newest first.</p>\n<p>Notification types: LOW_STOCK, SALE_CREATED, SALE_CANCELLED, AUDIT_ALERT, SYSTEM</p>\n<p>Query Params:</p>\n<ul>\n<li>page: number, optional, default 1</li>\n<li>limit: number, optional, default 10</li>\n<li>isRead: \"true\" | \"false\", optional</li>\n</ul>\n<p>Response 200:\n{\n  \"success\": true,\n  \"message\": \"Notifications fetched successfully\",\n  \"data\": {\n    \"notifications\": [\n      {\n        \"_id\": \"...\",\n        \"userId\": \"...\",\n        \"title\": \"Alert : CREATE_SALE\",\n        \"message\": \"A new invoice number INV-20241215-143022-4823 has been created with a total value of 500\",\n        \"type\": \"SALE_CREATED\",\n        \"action\": \"CREATE_SALE\",\n        \"targetId\": \"...\",\n        \"isRead\": false,\n        \"createdAt\": \"...\"\n      }\n    ],\n    \"unreadCount\": 5,\n    \"pagination\": {\n      \"totalDocs\": 23,\n      \"totalPages\": 3,\n      \"currentPage\": 1,\n      \"limit\": 10\n    }\n  }\n}</p>\n","urlObject":{"path":["notification"],"host":["https://noventra-backend-dashboard.vercel.app"],"query":[{"description":{"content":"<p>default 1</p>\n","type":"text/plain"},"key":"page","value":"1"},{"description":{"content":"<p>default 10</p>\n","type":"text/plain"},"key":"limit","value":"10"},{"description":{"content":"<p>true or false, optional</p>\n","type":"text/plain"},"key":"isRead","value":"false"}],"variable":[]}},"response":[],"_postman_id":"31cf7779-913b-4b28-afc7-e8cae31f65fd"},{"name":"Mark Notification As Read","id":"d4046317-316e-49aa-9d20-d6993487cb4c","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"PATCH","header":[{"key":"token","value":"","type":"text"}],"url":"https://noventra-backend-dashboard.vercel.app/notification/:id/read","description":"<p>Role: any authenticated user</p>\n<p>Marks a single notification as read. Only the owner of the notification can mark it.</p>\n<p>URL Param:</p>\n<ul>\n<li>id: MongoDB ObjectId</li>\n</ul>\n<p>No body required.</p>\n<p>Response 200:\n{\n  \"success\": true,\n  \"message\": \"Notification marked as read\",\n  \"data\": {\n    \"_id\": \"...\",\n    \"isRead\": true,\n    \"title\": \"Alert : CREATE_SALE\",\n    \"type\": \"SALE_CREATED\"\n  }\n}</p>\n<p>Errors:</p>\n<ul>\n<li>404: notification not found</li>\n</ul>\n","urlObject":{"path":["notification",":id","read"],"host":["https://noventra-backend-dashboard.vercel.app"],"query":[],"variable":[{"id":"d2f4c3a0-7c7f-4cf1-a95f-c72e611eb502","description":{"content":"<p>MongoDB ObjectId of the notification</p>\n","type":"text/plain"},"type":"any","value":"64f1a2b3c4d5e6f7a8b9c0d1","key":"id"}]}},"response":[],"_postman_id":"d4046317-316e-49aa-9d20-d6993487cb4c"},{"name":"Mark All Notifications As Read","id":"114ea9c8-0fd3-4228-a54e-ae13b328049d","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"PATCH","header":[{"key":"token","value":"","type":"text"}],"url":"https://noventra-backend-dashboard.vercel.app/notification/read-all","description":"<p>Role: any authenticated user</p>\n<p>Marks all unread notifications for the logged-in user as read.</p>\n<p>No body required.</p>\n<p>Response 200:\n{\n  \"success\": true,\n  \"message\": \"All notifications marked as read\"\n}</p>\n","urlObject":{"path":["notification","read-all"],"host":["https://noventra-backend-dashboard.vercel.app"],"query":[],"variable":[]}},"response":[],"_postman_id":"114ea9c8-0fd3-4228-a54e-ae13b328049d"}],"id":"65f343ba-4be0-45c8-8b1a-ef987815fae4","_postman_id":"65f343ba-4be0-45c8-8b1a-ef987815fae4","description":""}],"variable":[{"key":"baseUrl","value":"https://noventra-backend-dashboard.vercel.app"},{"key":"token","value":"","description":"Saved automatically after Login"},{"key":"supabase_service_role_api_key_0hsq","secret":true}]}