{"openapi":"3.0.3","info":{"title":"memo API","version":"1.0.0"},"servers":[{"url":"https://api.memo.wirewire.de/v1"}],"security":[{"bearerAuth":[]}],"tags":[{"name":"Accounts","description":"Authentication and authorization"},{"name":"Users","description":"User management for users of an Organization"},{"name":"Organizations","description":"Organization management"},{"name":"Devices","description":"Device management for IoT devices"},{"name":"IoTDevice","description":"IoT device management"}],"components":{"securitySchemes":{"x-api-key":{"type":"apiKey","in":"header","name":"x-api-key","description":"API key for authentication"},"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"JWT Bearer authentication"}},"schemas":{},"parameters":{}},"paths":{"/users/":{"post":{"summary":"Create a new user","description":"Creates a new user within the current organization.\n\n\nMiddlewares: `authMiddleware`, `validateBodyOrganization`, `normalizeMemoUserBody`","x-middlewares":["`authMiddleware`","`validateBodyOrganization`","`normalizeMemoUserBody`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Users"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"meta":{"type":"object","properties":{},"additionalProperties":{"nullable":true},"example":{"key":"value"},"description":"Additional metadata for the user"},"apps":{"type":"object","properties":{"memo":{"type":"object","properties":{"category":{"type":"string","enum":["doctor","nurse","patient","pharmacist","relative"],"description":"Memo user category"}}}},"additionalProperties":{"nullable":true},"description":"Application-specific user fields"},"organization":{"type":"string","example":"682fd0d7d4a6325d9d45b86d","description":"Organization ObjectId"},"email":{"type":"string","nullable":true,"format":"email","example":"user@example.com","description":"User email address"},"category":{"type":"string","enum":["doctor","nurse","patient","pharmacist","relative"],"description":"Memo user category"},"timezone":{"type":"string","example":"Europe/Berlin","description":"IANA timezone string"},"role":{"type":"string","enum":["user","admin","patient","onlyself"],"description":"Role assigned to the user"}},"required":["organization"]}}}},"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"682fd0d7d4a6325d9d45b86d"},"name":{"type":"string","example":"Jane Doe"},"email":{"type":"string","format":"email","example":"jane.doe@example.com"}},"required":["id","name","email"],"example":{"id":"682fd0d7d4a6325d9d45b86d","name":"Jane Doe","email":"jane.doe@example.com"}}}}}}},"get":{"summary":"Get a list of users","description":"Retrieves a paginated list of all users in the current organization.\n\n\nMiddlewares: `authMiddleware`, `validateQueryOrganization`","x-middlewares":["`authMiddleware`","`validateQueryOrganization`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Users"],"parameters":[{"schema":{"type":"string","example":"John","description":"Name to filter by"},"required":false,"description":"Name to filter by","name":"name","in":"query"},{"schema":{"type":"string","example":"admin","description":"Role to filter by"},"required":false,"description":"Role to filter by","name":"role","in":"query"},{"schema":{"type":"string","example":"createdAt","description":"Field to sort by"},"required":false,"description":"Field to sort by","name":"sortBy","in":"query"},{"schema":{"type":"string","example":"","description":"Search term to filter results"},"required":false,"description":"Search term to filter results","name":"search","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100000,"example":10,"description":"Number of items per page"},"required":false,"description":"Number of items per page","name":"limit","in":"query"},{"schema":{"type":"integer","nullable":true,"minimum":0,"maximum":100000,"example":0,"description":"Offset for pagination, used to skip a number of items"},"required":false,"description":"Offset for pagination, used to skip a number of items","name":"offset","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100000,"example":1,"description":"Page number for pagination"},"required":false,"description":"Page number for pagination","name":"page","in":"query"},{"schema":{"type":"string","example":"60c72b2f9b1e8d001c8e4f3a","description":"Filter users by organization ObjectId"},"required":true,"description":"Filter users by organization ObjectId","name":"organization","in":"query"}],"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","example":"682fd0d7d4a6325d9d45b86d"},"name":{"type":"string","example":"Jane Doe"},"email":{"type":"string","format":"email","example":"jane.doe@example.com"}},"required":["id","name","email"]},"example":[{"id":"682fd0d7d4a6325d9d45b86d","name":"Jane Doe","email":"jane.doe@example.com"},{"id":"682fd0d7d4a6325d9d45b86f","name":"John Smith","email":"john.smith@example.com"}]}}}}}}},"/users/{userId}":{"get":{"summary":"Get a user by ID","description":"Fetches a single user’s details by their unique ID.\n\n\nMiddlewares: `authMiddleware`, `validateParamsUser`","x-middlewares":["`authMiddleware`","`validateParamsUser`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Users"],"parameters":[{"schema":{"type":"string","example":"682fd0d7d4a6325d9d45b86d","description":"A valid MongoDB ObjectId"},"required":true,"description":"A valid MongoDB ObjectId","name":"userId","in":"path"}],"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","example":"682fd0d7d4a6325d9d45b86d"},"name":{"type":"string","example":"Jane Doe"},"email":{"type":"string","format":"email","example":"jane.doe@example.com"}},"required":["id","name","email"]},"example":[{"id":"682fd0d7d4a6325d9d45b86d","name":"Jane Doe","email":"jane.doe@example.com"},{"id":"682fd0d7d4a6325d9d45b86f","name":"John Smith","email":"john.smith@example.com"}]}}}}}},"patch":{"summary":"Partially update a user by ID","description":"Applies partial updates to a user’s record by ID.\n\n\nMiddlewares: `authMiddleware`, `validateParamsUser`, `normalizeMemoUserBody`","x-middlewares":["`authMiddleware`","`validateParamsUser`","`normalizeMemoUserBody`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Users"],"parameters":[{"schema":{"type":"string","example":"682fd0d7d4a6325d9d45b86d","description":"A valid MongoDB ObjectId"},"required":true,"description":"A valid MongoDB ObjectId","name":"userId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"User full name"},"timezone":{"type":"string","description":"IANA timezone"},"avatar":{"type":"string","description":"Avatar URL"},"category":{"type":"string","enum":["doctor","nurse","patient","pharmacist","relative"],"description":"Memo user category"},"meta":{"type":"object","properties":{},"additionalProperties":{"nullable":true},"description":"Additional metadata"},"apps":{"type":"object","properties":{"memo":{"type":"object","properties":{"category":{"type":"string","enum":["doctor","nurse","patient","pharmacist","relative"],"description":"Memo user category"}}}},"additionalProperties":{"nullable":true},"description":"Application-specific user fields"},"email":{"type":"string","nullable":true,"format":"email","description":"User email address"},"role":{"type":"string","enum":["user","admin","patient","onlyself"],"description":"User role"},"inviteCode":{"type":"string","nullable":true,"description":"Invite code"},"organization":{"type":"string","example":"682fd0d7d4a6325d9d45b86d","description":"Organization ObjectId"}}}}}},"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"682fd0d7d4a6325d9d45b86d"},"name":{"type":"string","example":"Jane Doe"},"email":{"type":"string","format":"email","example":"jane.doe@example.com"}},"required":["id","name","email"],"example":{"id":"682fd0d7d4a6325d9d45b86d","name":"Jane Doe","email":"jane.doe@example.com"}}}}}}},"delete":{"summary":"Delete a user by ID","description":"Removes a user from the system by their unique ID.\n\n\nMiddlewares: `authMiddleware`, `validateParamsUser`","x-middlewares":["`authMiddleware`","`validateParamsUser`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Users"],"parameters":[{"schema":{"type":"string","example":"682fd0d7d4a6325d9d45b86d","description":"A valid MongoDB ObjectId"},"required":true,"description":"A valid MongoDB ObjectId","name":"userId","in":"path"}],"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true}},"required":["success"],"example":{"success":true}}}}}}}},"/accounts/current":{"get":{"summary":"Get the current account","description":"Fetches the details of the currently authenticated account.\n\n\nMiddlewares: `authMiddleware`","x-middlewares":["`authMiddleware`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Accounts"],"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"auth0|60452f4c0dc85b0062326","description":"Authentication provider account ID"},"email":{"type":"string","format":"email","example":"jane.doe@example.com"},"firstName":{"type":"string","example":"Jane"},"lastName":{"type":"string","example":"Doe"},"organizationId":{"type":"string","example":"682fd0d7d4a6325d9d45b86e","description":"Organization ObjectId"},"roles":{"type":"array","items":{"type":"string"},"example":["admin","user"],"description":"Account roles"},"isMfaEnabled":{"type":"boolean","example":true},"createdAt":{"type":"string","format":"date-time","example":"2026-05-21T09:30:00.000Z"},"updatedAt":{"type":"string","format":"date-time","example":"2026-05-21T10:15:00.000Z"}},"required":["id","email","organizationId","roles","isMfaEnabled","createdAt","updatedAt"],"example":{"id":"auth0|60452f4c0dc85b0062326","email":"jane.doe@example.com","firstName":"Jane","lastName":"Doe","organizationId":"682fd0d7d4a6325d9d45b86e","roles":["admin","user"],"isMfaEnabled":true,"createdAt":"2026-05-21T09:30:00.000Z","updatedAt":"2026-05-21T10:15:00.000Z"}}}}}}},"delete":{"summary":"Delete the current user's account","description":"Permanently deletes the current user's account. Will not delete associated data. This action is irreversible.\n\n\nMiddlewares: `authMiddleware`","x-middlewares":["`authMiddleware`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Accounts"],"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"auth0|60452f4c0dc85b0062326","description":"Authentication provider account ID"},"email":{"type":"string","format":"email","example":"jane.doe@example.com"},"firstName":{"type":"string","example":"Jane"},"lastName":{"type":"string","example":"Doe"},"organizationId":{"type":"string","example":"682fd0d7d4a6325d9d45b86e","description":"Organization ObjectId"},"roles":{"type":"array","items":{"type":"string"},"example":["admin","user"],"description":"Account roles"},"isMfaEnabled":{"type":"boolean","example":true},"createdAt":{"type":"string","format":"date-time","example":"2026-05-21T09:30:00.000Z"},"updatedAt":{"type":"string","format":"date-time","example":"2026-05-21T10:15:00.000Z"}},"required":["id","email","organizationId","roles","isMfaEnabled","createdAt","updatedAt"],"example":{"id":"auth0|60452f4c0dc85b0062326","email":"jane.doe@example.com","firstName":"Jane","lastName":"Doe","organizationId":"682fd0d7d4a6325d9d45b86e","roles":["admin","user"],"isMfaEnabled":true,"createdAt":"2026-05-21T09:30:00.000Z","updatedAt":"2026-05-21T10:15:00.000Z"}}}}}}}},"/accounts/{accountId}":{"get":{"summary":"Get an account by ID","description":"Fetches the details of a single account by its ID.\n\n\nMiddlewares: `authMiddleware`, `validateParamsAccount`","x-middlewares":["`authMiddleware`","`validateParamsAccount`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Accounts"],"parameters":[{"schema":{"type":"string","example":"auth0|60452f4c0dc85b0062326","description":"Auth Account ID"},"required":true,"description":"Auth Account ID","name":"accountId","in":"path"}],"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"auth0|60452f4c0dc85b0062326","description":"Authentication provider account ID"},"email":{"type":"string","format":"email","example":"jane.doe@example.com"},"firstName":{"type":"string","example":"Jane"},"lastName":{"type":"string","example":"Doe"},"organizationId":{"type":"string","example":"682fd0d7d4a6325d9d45b86e","description":"Organization ObjectId"},"roles":{"type":"array","items":{"type":"string"},"example":["admin","user"],"description":"Account roles"},"isMfaEnabled":{"type":"boolean","example":true},"createdAt":{"type":"string","format":"date-time","example":"2026-05-21T09:30:00.000Z"},"updatedAt":{"type":"string","format":"date-time","example":"2026-05-21T10:15:00.000Z"}},"required":["id","email","organizationId","roles","isMfaEnabled","createdAt","updatedAt"],"example":{"id":"auth0|60452f4c0dc85b0062326","email":"jane.doe@example.com","firstName":"Jane","lastName":"Doe","organizationId":"682fd0d7d4a6325d9d45b86e","roles":["admin","user"],"isMfaEnabled":true,"createdAt":"2026-05-21T09:30:00.000Z","updatedAt":"2026-05-21T10:15:00.000Z"}}}}}}},"patch":{"summary":"Update fields on an account by ID","description":"Updates specific fields of an existing account identified by its ID.\n\n\nMiddlewares: `authMiddleware`, `validateParamsAccount`","x-middlewares":["`authMiddleware`","`validateParamsAccount`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Accounts"],"parameters":[{"schema":{"type":"string","example":"auth0|60452f4c0dc85b0062326","description":"Auth Account ID"},"required":true,"description":"Auth Account ID","name":"accountId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"language":{"type":"string","nullable":true,"example":"en","description":"Language code"},"gender":{"type":"string","nullable":true,"example":"female","description":"Gender"},"email":{"type":"string","format":"email","example":"jane.doe@example.com","description":"User email address"},"given_name":{"type":"string","example":"Jane","description":"Given name"},"family_name":{"type":"string","example":"Doe","description":"Family name"},"debug":{"type":"boolean","example":false},"demo":{"type":"boolean","example":false},"notification":{"type":"object","additionalProperties":{"nullable":true},"example":{"email":true,"push":false},"description":"Notification settings object"}},"example":{"language":"en","email":"jane.doe@example.com","given_name":"Jane","family_name":"Doe","notification":{"email":true,"push":false}}}}}},"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"auth0|60452f4c0dc85b0062326","description":"Authentication provider account ID"},"email":{"type":"string","format":"email","example":"jane.doe@example.com"},"firstName":{"type":"string","example":"Jane"},"lastName":{"type":"string","example":"Doe"},"organizationId":{"type":"string","example":"682fd0d7d4a6325d9d45b86e","description":"Organization ObjectId"},"roles":{"type":"array","items":{"type":"string"},"example":["admin","user"],"description":"Account roles"},"isMfaEnabled":{"type":"boolean","example":true},"createdAt":{"type":"string","format":"date-time","example":"2026-05-21T09:30:00.000Z"},"updatedAt":{"type":"string","format":"date-time","example":"2026-05-21T10:15:00.000Z"}},"required":["id","email","organizationId","roles","isMfaEnabled","createdAt","updatedAt"],"example":{"id":"auth0|60452f4c0dc85b0062326","email":"jane.doe@example.com","firstName":"Jane","lastName":"Doe","organizationId":"682fd0d7d4a6325d9d45b86e","roles":["admin","user"],"isMfaEnabled":true,"createdAt":"2026-05-21T09:30:00.000Z","updatedAt":"2026-05-21T10:15:00.000Z"}}}}}}}},"/organizations/":{"post":{"summary":"Create a new organization","description":"Creates a new organization with the provided details.\n\n\nMiddlewares: `authMiddleware`","x-middlewares":["`authMiddleware`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Organizations"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"kind":{"type":"string","example":"private","description":"The type or category of the organization"}},"required":["kind"],"example":{"kind":"private"}}}}},"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"682fd0d7d4a6325d9d45b86e"},"name":{"type":"string","example":"Acme Inc.","description":"Organization name"},"email":{"type":"string","format":"email","example":"contact@acme.example","description":"Primary contact email"},"kind":{"type":"string","example":"private","description":"The type or category of the organization"}},"required":["id","name","email"],"example":{"id":"682fd0d7d4a6325d9d45b86e","name":"Acme Inc.","email":"contact@acme.example","kind":"private"}}}}}}},"get":{"summary":"Get all organizations","description":"Retrieves all organizations accessible to the current user.\n\n\nMiddlewares: `authMiddleware`","x-middlewares":["`authMiddleware`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Organizations"],"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","example":"682fd0d7d4a6325d9d45b86e"},"name":{"type":"string","example":"Acme Inc.","description":"Organization name"},"email":{"type":"string","format":"email","example":"contact@acme.example","description":"Primary contact email"},"kind":{"type":"string","example":"private","description":"The type or category of the organization"}},"required":["id","name","email"],"example":{"id":"682fd0d7d4a6325d9d45b86e","name":"Acme Inc.","email":"contact@acme.example","kind":"private"}}}}}}}}},"/organizations/{organizationId}":{"get":{"summary":"Get an organization by ID","description":"Retrieves the details of a specific organization by its ID.\n\n\nMiddlewares: `authMiddleware`, `validateOrganization`","x-middlewares":["`authMiddleware`","`validateOrganization`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Organizations"],"parameters":[{"schema":{"type":"string","example":"682fd0d7d4a6325d9d45b86e","description":"A valid MongoDB ObjectId"},"required":true,"description":"A valid MongoDB ObjectId","name":"organizationId","in":"path"}],"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"682fd0d7d4a6325d9d45b86e"},"name":{"type":"string","example":"Acme Inc.","description":"Organization name"},"email":{"type":"string","format":"email","example":"contact@acme.example","description":"Primary contact email"},"kind":{"type":"string","example":"private","description":"The type or category of the organization"}},"required":["id","name","email"],"example":{"id":"682fd0d7d4a6325d9d45b86e","name":"Acme Inc.","email":"contact@acme.example","kind":"private"}}}}}}},"patch":{"summary":"Update an organization by ID","description":"Updates the details of a specific organization by its ID.\n\n\nMiddlewares: `authMiddleware`, `validateOrganization`, `validateOrganizationUpdate`","x-middlewares":["`authMiddleware`","`validateOrganization`","`validateOrganizationUpdate`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Organizations"],"parameters":[{"schema":{"type":"string","example":"682fd0d7d4a6325d9d45b86e","description":"A valid MongoDB ObjectId"},"required":true,"description":"A valid MongoDB ObjectId","name":"organizationId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","example":"Acme Inc.","description":"The name of the organization"},"organization":{"type":"string","example":"682fd0d7d4a6325d9d45b86d","description":"A valid MongoDB ObjectId"},"kind":{"type":"string","example":"private","description":"The type or category of the organization"},"meta":{"type":"object","additionalProperties":{"nullable":true},"example":{"billingId":"cus_123","region":"eu"},"description":"Additional metadata for the entry"}},"required":["organization"],"example":{"name":"Acme Inc.","organization":"682fd0d7d4a6325d9d45b86d","kind":"private","meta":{"billingId":"cus_123","region":"eu"}}}}}},"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"682fd0d7d4a6325d9d45b86e"},"name":{"type":"string","example":"Acme Inc.","description":"Organization name"},"email":{"type":"string","format":"email","example":"contact@acme.example","description":"Primary contact email"},"kind":{"type":"string","example":"private","description":"The type or category of the organization"}},"required":["id","name","email"],"example":{"id":"682fd0d7d4a6325d9d45b86e","name":"Acme Inc.","email":"contact@acme.example","kind":"private"}}}}}}},"delete":{"summary":"Delete an organization by ID","description":"Deletes a specific organization by its ID.\n\n\nMiddlewares: `authMiddleware`, `validateOrganization`, `validateOrganizationDelete`","x-middlewares":["`authMiddleware`","`validateOrganization`","`validateOrganizationDelete`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Organizations"],"parameters":[{"schema":{"type":"string","example":"682fd0d7d4a6325d9d45b86e","description":"A valid MongoDB ObjectId"},"required":true,"description":"A valid MongoDB ObjectId","name":"organizationId","in":"path"}],"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"682fd0d7d4a6325d9d45b86e"},"name":{"type":"string","example":"Acme Inc.","description":"Organization name"},"email":{"type":"string","format":"email","example":"contact@acme.example","description":"Primary contact email"},"kind":{"type":"string","example":"private","description":"The type or category of the organization"}},"required":["id","name","email"],"example":{"id":"682fd0d7d4a6325d9d45b86e","name":"Acme Inc.","email":"contact@acme.example","kind":"private"}}}}}}}},"/devices/":{"post":{"summary":"Create a new device","description":"Create a new device and associate it with the current organization.\n\n\nMiddlewares: `authMiddleware`, `validateBodyOrganization`, `validateOrganizationDelete`","x-middlewares":["`authMiddleware`","`validateBodyOrganization`","`validateOrganizationDelete`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Devices"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"kind":{"type":"string","example":"paper-display"},"patient":{"type":"string","nullable":true,"example":null,"description":"Patient ObjectId"},"paper":{"type":"string","nullable":true,"example":null,"description":"Paper ObjectId"},"organization":{"type":"string","example":"682fd0d7d4a6325d9d45b86e","description":"Organization ObjectId"}},"required":["organization"],"example":{"kind":"paper-display","patient":"682fd0d7d4a6325d9d45b86d","paper":null,"organization":"682fd0d7d4a6325d9d45b86e"}}}}},"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"682fd0d7d4a6325d9d45b86f"},"name":{"type":"string","example":"Kitchen Display"},"serialNumber":{"type":"string","example":"nrf-352656106701140"},"status":{"type":"string","enum":["online","offline","error"],"example":"online"},"createdAt":{"type":"string","format":"date-time","example":"2026-05-21T09:30:00.000Z"},"updatedAt":{"type":"string","format":"date-time","example":"2026-05-21T10:15:00.000Z"}},"required":["id","name","status","createdAt","updatedAt"],"example":{"id":"682fd0d7d4a6325d9d45b86f","name":"Kitchen Display","serialNumber":"nrf-352656106701140","status":"online","createdAt":"2026-05-21T09:30:00.000Z","updatedAt":"2026-05-21T10:15:00.000Z"}}}}}}},"get":{"summary":"Query devices by user","description":"Retrieve a paginated list of devices visible to the authenticated user. Either patient or organization is required.\n\n\nMiddlewares: `authMiddleware`, `validateQuerySearchUserAndOrganization`","x-middlewares":["`authMiddleware`","`validateQuerySearchUserAndOrganization`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Devices"],"parameters":[{"schema":{"type":"string","example":"John","description":"Name to filter by"},"required":false,"description":"Name to filter by","name":"name","in":"query"},{"schema":{"type":"string","example":"admin","description":"Role to filter by"},"required":false,"description":"Role to filter by","name":"role","in":"query"},{"schema":{"type":"string","example":"createdAt","description":"Field to sort by"},"required":false,"description":"Field to sort by","name":"sortBy","in":"query"},{"schema":{"type":"string","example":"","description":"Search term to filter results"},"required":false,"description":"Search term to filter results","name":"search","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100000,"example":10,"description":"Number of items per page"},"required":false,"description":"Number of items per page","name":"limit","in":"query"},{"schema":{"type":"integer","nullable":true,"minimum":0,"maximum":100000,"example":0,"description":"Offset for pagination, used to skip a number of items"},"required":false,"description":"Offset for pagination, used to skip a number of items","name":"offset","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100000,"example":1,"description":"Page number for pagination"},"required":false,"description":"Page number for pagination","name":"page","in":"query"},{"schema":{"type":"string","example":"682fd0d7d4a6325d9d45b86d","description":"Patient ObjectId. Required if organization is not provided."},"required":false,"description":"Patient ObjectId. Required if organization is not provided.","name":"patient","in":"query"},{"schema":{"type":"string","example":"682fd0d7d4a6325d9d45b86e","description":"Organization ObjectId. Required if patient is not provided."},"required":false,"description":"Organization ObjectId. Required if patient is not provided.","name":"organization","in":"query"}],"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","example":"682fd0d7d4a6325d9d45b86f"},"name":{"type":"string","example":"Kitchen Display"},"serialNumber":{"type":"string","example":"nrf-352656106701140"},"status":{"type":"string","enum":["online","offline","error"],"example":"online"},"createdAt":{"type":"string","format":"date-time","example":"2026-05-21T09:30:00.000Z"},"updatedAt":{"type":"string","format":"date-time","example":"2026-05-21T10:15:00.000Z"}},"required":["id","name","status","createdAt","updatedAt"],"example":{"id":"682fd0d7d4a6325d9d45b86f","name":"Kitchen Display","serialNumber":"nrf-352656106701140","status":"online","createdAt":"2026-05-21T09:30:00.000Z","updatedAt":"2026-05-21T10:15:00.000Z"}}}}}}}}},"/devices/events/{deviceId}":{"get":{"summary":"Get events for a device","description":"Fetch a chronological list of events generated by the specified device.\n\n\nMiddlewares: `authMiddleware`, `validateDevice`","x-middlewares":["`authMiddleware`","`validateDevice`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Devices"],"parameters":[{"schema":{"type":"string","example":"682fd0d7d4a6325d9d45b86f","description":"Device ObjectId"},"required":true,"description":"Device ObjectId","name":"deviceId","in":"path"},{"schema":{"type":"string","format":"date-time"},"required":false,"name":"DateStart","in":"query"},{"schema":{"type":"string","format":"date-time"},"required":false,"name":"DateEnd","in":"query"},{"schema":{"type":"string","description":"Event type filter. Common values include activate and state; any other string is accepted.","example":"activate"},"required":false,"description":"Event type filter. Common values include activate and state; any other string is accepted.","name":"TypeFilter","in":"query"}],"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","example":"evt_01HX0000000000000000000000"},"deviceId":{"type":"string","example":"682fd0d7d4a6325d9d45b86f"},"type":{"type":"string","example":"state"},"payload":{"type":"object","additionalProperties":{"nullable":true},"example":{"battery":87,"online":true}},"timestamp":{"type":"string","format":"date-time","example":"2026-05-21T10:15:00.000Z"}},"required":["id","deviceId","type","payload","timestamp"],"example":{"id":"evt_01HX0000000000000000000000","deviceId":"682fd0d7d4a6325d9d45b86f","type":"state","payload":{"battery":87,"online":true},"timestamp":"2026-05-21T10:15:00.000Z"}}}}}}}}},"/devices/{deviceId}":{"get":{"summary":"Get a device by ID","description":"Retrieve detailed information for the device identified by its ID.\n\n\nMiddlewares: `authMiddleware`, `validateDevice`","x-middlewares":["`authMiddleware`","`validateDevice`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Devices"],"parameters":[{"schema":{"type":"string","example":"682fd0d7d4a6325d9d45b86f","description":"A valid MongoDB ObjectId"},"required":true,"description":"A valid MongoDB ObjectId","name":"deviceId","in":"path"}],"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"682fd0d7d4a6325d9d45b86f"},"name":{"type":"string","example":"Kitchen Display"},"serialNumber":{"type":"string","example":"nrf-352656106701140"},"status":{"type":"string","enum":["online","offline","error"],"example":"online"},"createdAt":{"type":"string","format":"date-time","example":"2026-05-21T09:30:00.000Z"},"updatedAt":{"type":"string","format":"date-time","example":"2026-05-21T10:15:00.000Z"}},"required":["id","name","status","createdAt","updatedAt"],"example":{"id":"682fd0d7d4a6325d9d45b86f","name":"Kitchen Display","serialNumber":"nrf-352656106701140","status":"online","createdAt":"2026-05-21T09:30:00.000Z","updatedAt":"2026-05-21T10:15:00.000Z"}}}}}}},"patch":{"summary":"Update a device","description":"Updates specific fields of an existing device identified by its ID.\n\n\nMiddlewares: `authMiddleware`, `validateDevice`, `validateOrganizationUpdate`","x-middlewares":["`authMiddleware`","`validateDevice`","`validateOrganizationUpdate`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Devices"],"parameters":[{"schema":{"type":"string","example":"682fd0d7d4a6325d9d45b86f","description":"A valid MongoDB ObjectId"},"required":true,"description":"A valid MongoDB ObjectId","name":"deviceId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"intake":{"type":"object","additionalProperties":{"nullable":true},"example":{"morning":"08:00","evening":"20:00"}},"meta":{"type":"object","additionalProperties":{"nullable":true},"example":{"room":"kitchen"}},"organization":{"type":"string","example":"682fd0d7d4a6325d9d45b86d","description":"A valid MongoDB ObjectId"},"patient":{"type":"string","nullable":true,"example":"682fd0d7d4a6325d9d45b86d","description":"A valid MongoDB ObjectId"},"paper":{"type":"string","nullable":true,"example":"682fd0d7d4a6325d9d45b86d","description":"A valid MongoDB ObjectId"},"kind":{"type":"string","example":"paper-display"},"deviceId":{"type":"string","example":"nrf-352656106701140"},"alarmEnable":{"type":"integer","example":1},"takeOffsetTime":{"type":"integer","example":15},"iotDevice":{"type":"object","additionalProperties":{"nullable":true},"example":{"firmwareVersion":"1.2.3"}},"payment":{"type":"object","additionalProperties":{"nullable":true},"example":{"status":"active"}}},"example":{"kind":"paper-display","deviceId":"nrf-352656106701140","patient":"682fd0d7d4a6325d9d45b86d","paper":null,"meta":{"room":"kitchen"},"alarmEnable":1,"takeOffsetTime":15}}}}},"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","example":"682fd0d7d4a6325d9d45b86f"},"name":{"type":"string","example":"Kitchen Display"},"serialNumber":{"type":"string","example":"nrf-352656106701140"},"status":{"type":"string","enum":["online","offline","error"],"example":"online"},"createdAt":{"type":"string","format":"date-time","example":"2026-05-21T09:30:00.000Z"},"updatedAt":{"type":"string","format":"date-time","example":"2026-05-21T10:15:00.000Z"}},"required":["id","name","status","createdAt","updatedAt"],"example":{"id":"682fd0d7d4a6325d9d45b86f","name":"Kitchen Display","serialNumber":"nrf-352656106701140","status":"online","createdAt":"2026-05-21T09:30:00.000Z","updatedAt":"2026-05-21T10:15:00.000Z"}}}}}}},"delete":{"summary":"Delete a device","description":"Remove the specified device from the system.\n\n\nMiddlewares: `authMiddleware`, `validateDevice`, `validateOrganizationDelete`","x-middlewares":["`authMiddleware`","`validateDevice`","`validateOrganizationDelete`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Devices"],"parameters":[{"schema":{"type":"string","example":"682fd0d7d4a6325d9d45b86f","description":"A valid MongoDB ObjectId"},"required":true,"description":"A valid MongoDB ObjectId","name":"deviceId","in":"path"}],"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"nullable":true},"description":"Generic response payload","example":{"success":true,"message":"Operation completed successfully"}}}}}}}},"/devices/registerdevice/{deviceId}":{"post":{"summary":"Register a device","description":"Associate an existing device with the authenticated organization.\n\n\nMiddlewares: `authMiddleware`, `validateBodyOrganization`, `validateOrganizationDelete`","x-middlewares":["`authMiddleware`","`validateBodyOrganization`","`validateOrganizationDelete`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Devices"],"parameters":[{"schema":{"type":"string","description":"Device serial","example":"DEVICE-EXAMPLE"},"required":true,"description":"Device serial","name":"deviceId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"enable":{"type":"boolean"},"organization":{"type":"string","example":"682fd0d7d4a6325d9d45b86e","description":"A valid MongoDB ObjectId"},"patient":{"type":"string","nullable":true,"example":"682fd0d7d4a6325d9d45b86d","description":"A valid MongoDB ObjectId"},"paper":{"type":"string","nullable":true,"example":"682fd0d7d4a6325d9d45b86d","description":"A valid MongoDB ObjectId"}},"required":["enable","organization"],"example":{"enable":true,"organization":"682fd0d7d4a6325d9d45b86d","patient":"682fd0d7d4a6325d9d45b86d","paper":null}}}}},"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"nullable":true},"description":"Generic response payload","example":{"success":true,"message":"Operation completed successfully"}}}}}}}},"/devices/ping/{deviceId}":{"get":{"summary":"Ping a device","description":"Check connectivity and round-trip time to the specified device.\n\n\nMiddlewares: `authMiddleware`, `validateDevice`","x-middlewares":["`authMiddleware`","`validateDevice`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Devices"],"parameters":[{"schema":{"type":"string","example":"682fd0d7d4a6325d9d45b86f","description":"Device ObjectId"},"required":true,"description":"Device ObjectId","name":"deviceId","in":"path"},{"schema":{"type":"string","description":"Data response","example":"false"},"required":true,"description":"Data response","name":"dataResponse","in":"query"}],"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"nullable":true},"description":"Generic response payload","example":{"success":true,"message":"Operation completed successfully"}}}}}}}},"/devices/reset/{deviceId}":{"post":{"summary":"Reset the sensors of a device","description":"Remotely reset all sensors on the target device to factory defaults.\n\n\nMiddlewares: `authMiddleware`, `validateDevice`, `validateOrganizationDelete`","x-middlewares":["`authMiddleware`","`validateDevice`","`validateOrganizationDelete`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Devices"],"parameters":[{"schema":{"type":"string","example":"682fd0d7d4a6325d9d45b86f","description":"Device ObjectId"},"required":true,"description":"Device ObjectId","name":"deviceId","in":"path"}],"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","example":"Reset all Variables and Memory and reboot Device: nrf-352656106701140","description":"Response message from reset operation"},"success":{"type":"boolean","example":true,"description":"Indicates if the reset operation was successful"}},"required":["message","success"],"example":{"message":"Reset all Variables and Memory and reboot Device: nrf-352656106701140","success":true}}}}}}}},"/devices/reboot/{deviceId}":{"post":{"summary":"Reboot a device","description":"Initiate a remote reboot of the specified device.\n\n\nMiddlewares: `authMiddleware`, `validateDevice`, `validateOrganizationDelete`","x-middlewares":["`authMiddleware`","`validateDevice`","`validateOrganizationDelete`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Devices"],"parameters":[{"schema":{"type":"string","example":"682fd0d7d4a6325d9d45b86f","description":"A valid MongoDB ObjectId"},"required":true,"description":"A valid MongoDB ObjectId","name":"deviceId","in":"path"}],"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"nullable":true},"description":"Generic response payload","example":{"success":true,"message":"Operation completed successfully"}}}}}}}},"/users/updatetimes/{userId}":{"post":{"summary":"Update times for a user by ID","description":"Updates default intake times for a specific user identified by ID.\n\n\nMiddlewares: `authMiddleware`, `validateParamsUser`","x-middlewares":["`authMiddleware`","`validateParamsUser`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Users"],"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"rrule":{"type":"object","properties":{"freq":{"type":"string","example":"DAILY","description":"Recurrence frequency"},"byweekday":{"type":"array","items":{"type":"number"},"example":[0,1,2,6,3],"description":"Days of week to repeat (0=Sunday)"},"exclude":{"type":"array","items":{"type":"string"},"example":["2024-03-28T10:45:00.000Z"],"description":"Dates to skip"}},"required":["byweekday","exclude"],"description":"Recurrence rule object"},"medication":{"type":"string","example":"6152c5f3902e7f91374d9f75","description":"Medication ObjectId"},"patient":{"type":"string","example":"614fb1d709dd9f6de85d6374","description":"Patient ObjectId"},"date":{"type":"string","example":"2024-03-25T00:30:00.000Z","description":"Scheduled date/time (ISO)"},"timeCategory":{"type":"string","example":"noon","description":"Time category (e.g. morning, noon)"},"amount":{"type":"number","example":1,"description":"Dosage amount"},"emptyStomach":{"type":"boolean","example":false,"description":"Whether to take on empty stomach"},"instruction":{"type":"string","example":"","description":"Additional instructions"},"unit":{"type":"string","example":"St","description":"Dosage unit"},"bake":{"type":"boolean","example":false,"description":"Baking flag (if applicable)"},"id":{"type":"string","example":"660079fd11fdc2dd935e43af","description":"Entry identifier"}},"required":["rrule","patient","date","timeCategory","amount","emptyStomach","bake","id"]},"example":[{"rrule":{"freq":"DAILY","byweekday":[0,1,2,6,3],"exclude":["2024-03-28T10:45:00.000Z"]},"patient":"614fb1d709dd9f6de85d6374","date":"2024-03-25T00:30:00.000Z","timeCategory":"noon","amount":1,"emptyStomach":false,"instruction":"","unit":"St","bake":false,"id":"660079fd11fdc2dd935e43af"}],"description":"Array of updated time entries by ID"}}}}}}},"/calendars/aggregation":{"get":{"summary":"Get punctuality aggregation","description":"Retrieves punctuality metrics aggregated over calendar entries.\n\n\nMiddlewares: `authMiddleware`, `validateQueryUser`","x-middlewares":["`authMiddleware`","`validateQueryUser`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Calendars"],"parameters":[{"schema":{"type":"string","example":"682fd0d7d4a6325d9d45b86d","description":"A valid MongoDB ObjectId"},"required":false,"description":"A valid MongoDB ObjectId","name":"patient","in":"query"},{"schema":{"type":"string"},"required":true,"name":"from","in":"query"},{"schema":{"type":"string"},"required":true,"name":"to","in":"query"}],"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"object","properties":{"averagePunctuality":{"type":"number","example":3,"description":"Average punctuality score"},"trafficLight":{"type":"string","example":"green","description":"Overall status indicator"},"entries":{"type":"array","items":{"type":"object","properties":{"punctualityKey":{"type":"string","example":"punctual","description":"Status key"},"punctuality":{"type":"object","properties":{"icon":{"type":"string","example":"faCheck","description":"Icon identifier"},"className":{"type":"string","example":"trayPunctual","description":"CSS class name"}},"required":["icon","className"],"description":"Display data for punctuality"},"eventsOnlyBaked":{"type":"array","items":{"type":"object","properties":{"_id":{"type":"string"},"patient":{"type":"string"},"rrule":{"type":"object","properties":{"freq":{"type":"string","example":"DAILY","description":"Recurrence frequency"},"byweekday":{"type":"array","items":{"type":"number"},"example":[0,1,2,3,4,5,6],"description":"Weekdays included"},"exclude":{"type":"array","items":{"nullable":true},"example":[],"description":"Dates to exclude"}},"required":["freq","byweekday","exclude"],"description":"Recurrence rule"},"date":{"type":"string"},"timeCategory":{"type":"string"},"caseNumber":{"type":"string"},"from":{"type":"string"},"to":{"type":"string"},"amount":{"type":"number"},"emptyStomach":{"type":"boolean"},"instruction":{"type":"string"},"unit":{"type":"string"},"bake":{"type":"boolean"},"originalId":{"type":"string"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"__v":{"type":"number"}},"required":["_id","patient","rrule","date","timeCategory","caseNumber","from","to","amount","emptyStomach","instruction","unit","bake","originalId","createdAt","updatedAt","__v"],"description":"A baked calendar event"},"description":"Only baked events for this entry"},"caseDate":{"type":"string"},"trayCaseStoresOnlySameDay":{"type":"array","items":{"type":"object","properties":{"EventMessage":{"type":"object","properties":{"off":{"type":"number"},"early":{"type":"boolean"},"time":{"type":"number"}},"required":["off","early"],"description":"Message data for an event"},"AwsTopic":{"type":"string"},"DeviceMessageCount":{"type":"number"},"EventType":{"type":"string"},"DeviceId":{"type":"string"},"AwsTimestamp":{"type":"number"},"EventTimestamp":{"type":"number"}},"required":["EventMessage","AwsTopic","DeviceMessageCount","EventType","DeviceId","AwsTimestamp","EventTimestamp"],"description":"A single device message record"}},"trayCaseStores":{"type":"array","items":{"type":"object","properties":{"EventMessage":{"type":"object","properties":{"off":{"type":"number"},"early":{"type":"boolean"},"time":{"type":"number"}},"required":["off","early"],"description":"Message data for an event"},"AwsTopic":{"type":"string"},"DeviceMessageCount":{"type":"number"},"EventType":{"type":"string"},"DeviceId":{"type":"string"},"AwsTimestamp":{"type":"number"},"EventTimestamp":{"type":"number"}},"required":["EventMessage","AwsTopic","DeviceMessageCount","EventType","DeviceId","AwsTimestamp","EventTimestamp"],"description":"A single device message record"}},"trayCaseNumber":{"type":"string"},"intakeTime":{"type":"string"},"difference":{"type":"number"},"result":{"type":"object","properties":{"EventMessage":{"type":"object","properties":{"off":{"type":"number"},"early":{"type":"boolean"},"time":{"type":"number"}},"required":["off","early"],"description":"Message data for an event"},"AwsTopic":{"type":"string"},"DeviceMessageCount":{"type":"number"},"EventType":{"type":"string"},"DeviceId":{"type":"string"},"AwsTimestamp":{"type":"number"},"EventTimestamp":{"type":"number"}},"required":["EventMessage","AwsTopic","DeviceMessageCount","EventType","DeviceId","AwsTimestamp","EventTimestamp"],"description":"A single device message record"}},"required":["punctualityKey","punctuality","eventsOnlyBaked","caseDate","trayCaseStoresOnlySameDay","trayCaseStores","trayCaseNumber","intakeTime","difference","result"]},"description":"Detailed punctuality entries","example":[{"punctualityKey":"punctual","punctuality":{"icon":"faCheck","className":"trayPunctual"},"eventsOnlyBaked":[],"caseDate":"2024-05-19T06:00:00.000Z","trayCaseStoresOnlySameDay":[],"trayCaseStores":[],"trayCaseNumber":"7","intakeTime":"08:16","difference":16,"result":{}}]}},"required":["averagePunctuality","trafficLight","entries"],"description":"Aggregation result with punctuality overview","example":{"averagePunctuality":3,"trafficLight":"green","entries":[]}}}}}}}},"/calendars/":{"post":{"summary":"Create a calendar entry","description":"Creates a new calendar entry with the provided details.\n\n\nMiddlewares: `authMiddleware`, `validateBodyUser`","x-middlewares":["`authMiddleware`","`validateBodyUser`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Calendars"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"patient":{"type":"string","example":"682fd0d7d4a6325d9d45b86d","description":"Patient ObjectId"},"date":{"type":"string"},"timeCategory":{"type":"string"},"rrule":{"type":"object","additionalProperties":{"nullable":true}},"abdaMedication":{"type":"string"},"medication":{"type":"string"},"organization":{"type":"string"},"amount":{"type":"number"},"emptyStomach":{"anyOf":[{"type":"boolean"},{"type":"string","enum":[""]}]},"instruction":{"type":"string"},"unit":{"type":"string"},"intakeTime":{"type":"string"},"subTray":{"type":"string"},"batchNumber":{"type":"string"}},"required":["patient"],"additionalProperties":{"nullable":true},"description":"Payload to create a calendar entry"}}}},"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"userId":{"type":"string"},"date":{"type":"string"},"startTime":{"type":"string"},"endTime":{"type":"string"},"title":{"type":"string"},"description":{"type":"string","nullable":true},"baked":{"type":"boolean"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","userId","date","startTime","title","description","baked","createdAt","updatedAt"]}}}}}},"get":{"summary":"List calendar entries","description":"Returns a list of calendar entries, optionally filtered by query parameters.\n\n\nMiddlewares: `authMiddleware`, `validateQueryUser`","x-middlewares":["`authMiddleware`","`validateQueryUser`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Calendars"],"parameters":[{"schema":{"type":"string","example":"John","description":"Name to filter by"},"required":false,"description":"Name to filter by","name":"name","in":"query"},{"schema":{"type":"string","example":"admin","description":"Role to filter by"},"required":false,"description":"Role to filter by","name":"role","in":"query"},{"schema":{"type":"string","example":"createdAt","description":"Field to sort by"},"required":false,"description":"Field to sort by","name":"sortBy","in":"query"},{"schema":{"type":"string","example":"","description":"Search term to filter results"},"required":false,"description":"Search term to filter results","name":"search","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100000,"example":10,"description":"Number of items per page"},"required":false,"description":"Number of items per page","name":"limit","in":"query"},{"schema":{"type":"integer","nullable":true,"minimum":0,"maximum":100000,"example":0,"description":"Offset for pagination, used to skip a number of items"},"required":false,"description":"Offset for pagination, used to skip a number of items","name":"offset","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100000,"example":1,"description":"Page number for pagination"},"required":false,"description":"Page number for pagination","name":"page","in":"query"},{"schema":{"type":"string","example":"682fd0d7d4a6325d9d45b86d","description":"A valid MongoDB ObjectId"},"required":false,"description":"A valid MongoDB ObjectId","name":"patient","in":"query"}],"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"userId":{"type":"string"},"date":{"type":"string"},"startTime":{"type":"string"},"endTime":{"type":"string"},"title":{"type":"string"},"description":{"type":"string","nullable":true},"baked":{"type":"boolean"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","userId","date","startTime","title","description","baked","createdAt","updatedAt"]}}}}}}}},"/calendars/bake":{"get":{"summary":"Get baked calendar entries","description":"Fetches calendar entries that have been baked (finalized).\n\n\nMiddlewares: `authMiddleware`, `validateQueryUser`","x-middlewares":["`authMiddleware`","`validateQueryUser`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Calendars"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"patient":{"type":"string","example":"682fd0d7d4a6325d9d45b86d","description":"A valid MongoDB ObjectId"},"from":{"type":"string"},"to":{"type":"string"}},"required":["patient","from","to"],"description":"Generate multiple calendar entries"}}}},"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"userId":{"type":"string"},"date":{"type":"string"},"startTime":{"type":"string"},"endTime":{"type":"string"},"title":{"type":"string"},"description":{"type":"string","nullable":true},"baked":{"type":"boolean"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","userId","date","startTime","title","description","baked","createdAt","updatedAt"]}},"iotDevices":{"type":"array","items":{"nullable":true}},"dateNow":{"type":"string"},"alarms":{"type":"array","items":{"nullable":true}},"allAlarms":{"type":"array","items":{"type":"array","items":{"type":"number"},"minItems":2,"maxItems":2}}},"required":["data","iotDevices","dateNow","alarms","allAlarms"]}}}}}},"post":{"summary":"Bake calendar entries","description":"Finalizes (bakes) calendar entries based on the provided criteria.\n\n\nMiddlewares: `authMiddleware`, `validateQueryUser`","x-middlewares":["`authMiddleware`","`validateQueryUser`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Calendars"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"patient":{"type":"string","example":"682fd0d7d4a6325d9d45b86d","description":"A valid MongoDB ObjectId"},"from":{"type":"string"},"to":{"type":"string"},"updateAllPatients":{"type":"boolean","enum":[true]},"organization":{"type":"string","example":"682fd0d7d4a6325d9d45b86d","description":"A valid MongoDB ObjectId"}},"required":["from","to"],"description":"Generate multiple calendar entries"}}}},"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"userId":{"type":"string"},"date":{"type":"string"},"startTime":{"type":"string"},"endTime":{"type":"string"},"title":{"type":"string"},"description":{"type":"string","nullable":true},"baked":{"type":"boolean"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","userId","date","startTime","title","description","baked","createdAt","updatedAt"]}},"iotDevices":{"type":"array","items":{"nullable":true}},"dateNow":{"type":"string"},"alarms":{"type":"array","items":{"nullable":true}},"allAlarms":{"type":"array","items":{"type":"array","items":{"type":"number"},"minItems":2,"maxItems":2}}},"required":["data","iotDevices","dateNow","alarms","allAlarms"]}}}}}},"delete":{"summary":"Unbake calendar entries","description":"Reverts previously baked calendar entries back to draft state.\n\n\nMiddlewares: `authMiddleware`, `validateQueryUser`","x-middlewares":["`authMiddleware`","`validateQueryUser`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Calendars"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"patient":{"type":"string","example":"682fd0d7d4a6325d9d45b86d","description":"A valid MongoDB ObjectId"},"from":{"type":"string"},"to":{"type":"string"}},"required":["patient","from","to"],"description":"Generate multiple calendar entries"}}}},"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"userId":{"type":"string"},"date":{"type":"string"},"startTime":{"type":"string"},"endTime":{"type":"string"},"title":{"type":"string"},"description":{"type":"string","nullable":true},"baked":{"type":"boolean"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","userId","date","startTime","title","description","baked","createdAt","updatedAt"]}}}}}}}},"/calendars/{calendarId}":{"get":{"summary":"Get a calendar entry by ID","description":"Retrieves a single calendar entry using its unique identifier.\n\n\nMiddlewares: `authMiddleware`, `validateQueryCalendarEntry`","x-middlewares":["`authMiddleware`","`validateQueryCalendarEntry`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Calendars"],"parameters":[{"schema":{"type":"string","example":"682fd0d7d4a6325d9d45b86d","description":"A valid MongoDB ObjectId"},"required":true,"description":"A valid MongoDB ObjectId","name":"calendarId","in":"path"}],"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"userId":{"type":"string"},"date":{"type":"string"},"startTime":{"type":"string"},"endTime":{"type":"string"},"title":{"type":"string"},"description":{"type":"string","nullable":true},"baked":{"type":"boolean"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","userId","date","startTime","title","description","baked","createdAt","updatedAt"]}}}}}},"post":{"summary":"Replace a calendar entry by ID","description":"Replaces the entire calendar entry at the specified ID.\n\n\nMiddlewares: `authMiddleware`, `validateQueryCalendarEntry`, `validateOrganizationUpdate`","x-middlewares":["`authMiddleware`","`validateQueryCalendarEntry`","`validateOrganizationUpdate`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Calendars"],"parameters":[{"schema":{"type":"string","example":"682fd0d7d4a6325d9d45b86d","description":"A valid MongoDB ObjectId"},"required":true,"description":"A valid MongoDB ObjectId","name":"calendarId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"patient":{"type":"string","example":"682fd0d7d4a6325d9d45b86d","description":"A valid MongoDB ObjectId"},"date":{"type":"string"},"timeCategory":{"type":"string"},"rrule":{"nullable":true},"abdaMedication":{"type":"string"},"medication":{"type":"string"},"organization":{"type":"string"},"amount":{"type":"number"},"emptyStomach":{"anyOf":[{"type":"boolean"},{"type":"string","enum":[""]}]},"instruction":{"type":"string"},"unit":{"type":"string"},"intake":{"type":"object","additionalProperties":{"nullable":true}},"subTray":{"type":"string"},"batchNumber":{"type":"string"}},"additionalProperties":{"nullable":true},"description":"Payload to update a calendar entry"}}}},"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"userId":{"type":"string"},"date":{"type":"string"},"startTime":{"type":"string"},"endTime":{"type":"string"},"title":{"type":"string"},"description":{"type":"string","nullable":true},"baked":{"type":"boolean"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","userId","date","startTime","title","description","baked","createdAt","updatedAt"]}}}}}},"patch":{"summary":"Update a calendar entry by ID","description":"Applies partial updates to the calendar entry identified by ID.\n\n\nMiddlewares: `authMiddleware`, `validateQueryCalendarEntry`, `validateOrganizationUpdate`","x-middlewares":["`authMiddleware`","`validateQueryCalendarEntry`","`validateOrganizationUpdate`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Calendars"],"parameters":[{"schema":{"type":"string","example":"682fd0d7d4a6325d9d45b86d","description":"A valid MongoDB ObjectId"},"required":true,"description":"A valid MongoDB ObjectId","name":"calendarId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"patient":{"type":"string","example":"682fd0d7d4a6325d9d45b86d","description":"A valid MongoDB ObjectId"},"date":{"type":"string"},"timeCategory":{"type":"string"},"rrule":{"nullable":true},"abdaMedication":{"type":"string"},"medication":{"type":"string"},"organization":{"type":"string"},"amount":{"type":"number"},"emptyStomach":{"anyOf":[{"type":"boolean"},{"type":"string","enum":[""]}]},"instruction":{"type":"string"},"unit":{"type":"string"},"intake":{"type":"object","additionalProperties":{"nullable":true}},"subTray":{"type":"string"},"batchNumber":{"type":"string"}},"additionalProperties":{"nullable":true},"description":"Payload to update a calendar entry"}}}},"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"userId":{"type":"string"},"date":{"type":"string"},"startTime":{"type":"string"},"endTime":{"type":"string"},"title":{"type":"string"},"description":{"type":"string","nullable":true},"baked":{"type":"boolean"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","userId","date","startTime","title","description","baked","createdAt","updatedAt"]}}}}}}},"/medications/":{"post":{"summary":"Create a new medication","description":"\n\nMiddlewares: `authMiddleware`, `validateBodyOrganization`","x-middlewares":["`authMiddleware`","`validateBodyOrganization`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Medications"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","example":"Aspirin","description":"The name of the medication"},"organization":{"type":"string","example":"682fd0d7d4a6325d9d45b86d","description":"A valid MongoDB ObjectId"},"meta":{"nullable":true},"date":{"type":"string","format":"date-time"}}}}}},"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"organization":{"type":"string"},"meta":{"type":"object","additionalProperties":{"nullable":true}},"date":{"type":"string","format":"date-time"}},"required":["id","name","organization"]}}}}}},"get":{"summary":"Query medications by user","description":"\n\nMiddlewares: `authMiddleware`, `validateQueryOrganization`","x-middlewares":["`authMiddleware`","`validateQueryOrganization`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Medications"],"parameters":[{"schema":{"type":"string","description":"Filter by medication name"},"required":false,"description":"Filter by medication name","name":"name","in":"query"},{"schema":{"type":"string","example":"admin","description":"Role to filter by"},"required":false,"description":"Role to filter by","name":"role","in":"query"},{"schema":{"type":"string","example":"createdAt","description":"Field to sort by"},"required":false,"description":"Field to sort by","name":"sortBy","in":"query"},{"schema":{"type":"string","example":"","description":"Search term to filter results"},"required":false,"description":"Search term to filter results","name":"search","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100000,"example":10,"description":"Number of items per page"},"required":false,"description":"Number of items per page","name":"limit","in":"query"},{"schema":{"type":"integer","nullable":true,"minimum":0,"maximum":100000,"example":0,"description":"Offset for pagination, used to skip a number of items"},"required":false,"description":"Offset for pagination, used to skip a number of items","name":"offset","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100000,"example":1,"description":"Page number for pagination"},"required":false,"description":"Page number for pagination","name":"page","in":"query"},{"schema":{"type":"string","example":"682fd0d7d4a6325d9d45b86d","description":"Filter by organization ID"},"required":false,"description":"Filter by organization ID","name":"organization","in":"query"}],"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"organization":{"type":"string"},"meta":{"type":"object","additionalProperties":{"nullable":true}},"date":{"type":"string","format":"date-time"}},"required":["id","name","organization"]}}}}}}}},"/medications/{medicationId}":{"get":{"summary":"Get a medication by ID","description":"\n\nMiddlewares: `authMiddleware`, `validateMedicationRead`","x-middlewares":["`authMiddleware`","`validateMedicationRead`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Medications"],"parameters":[{"schema":{"type":"string","example":"682fd0d7d4a6325d9d45b86d","description":"A valid MongoDB ObjectId"},"required":true,"description":"A valid MongoDB ObjectId","name":"medicationId","in":"path"}],"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"organization":{"type":"string"},"meta":{"type":"object","additionalProperties":{"nullable":true}},"date":{"type":"string","format":"date-time"}},"required":["id","name","organization"]}}}}}},"post":{"summary":"Replace a medication by ID","description":"\n\nMiddlewares: `authMiddleware`, `validateMedication`, `validateOrganizationUpdate`","x-middlewares":["`authMiddleware`","`validateMedication`","`validateOrganizationUpdate`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Medications"],"parameters":[{"schema":{"type":"string","example":"682fd0d7d4a6325d9d45b86d","description":"A valid MongoDB ObjectId"},"required":true,"description":"A valid MongoDB ObjectId","name":"medicationId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","example":"Aspirin","description":"The name of the medication"},"meta":{"nullable":true},"organization":{"type":"string","example":"682fd0d7d4a6325d9d45b86d","description":"A valid MongoDB ObjectId"}}}}}},"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"organization":{"type":"string"},"meta":{"type":"object","additionalProperties":{"nullable":true}},"date":{"type":"string","format":"date-time"}},"required":["id","name","organization"]}}}}}},"patch":{"summary":"Update a medication by ID","description":"\n\nMiddlewares: `authMiddleware`, `validateMedication`, `validateOrganizationUpdate`","x-middlewares":["`authMiddleware`","`validateMedication`","`validateOrganizationUpdate`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Medications"],"parameters":[{"schema":{"type":"string","example":"682fd0d7d4a6325d9d45b86d","description":"A valid MongoDB ObjectId"},"required":true,"description":"A valid MongoDB ObjectId","name":"medicationId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","example":"Aspirin","description":"The name of the medication"},"meta":{"nullable":true},"organization":{"type":"string","example":"682fd0d7d4a6325d9d45b86d","description":"A valid MongoDB ObjectId"}}}}}},"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"organization":{"type":"string"},"meta":{"type":"object","additionalProperties":{"nullable":true}},"date":{"type":"string","format":"date-time"}},"required":["id","name","organization"]}}}}}},"delete":{"summary":"Delete a medication by ID","description":"\n\nMiddlewares: `authMiddleware`, `validateMedication`, `validateOrganizationDelete`","x-middlewares":["`authMiddleware`","`validateMedication`","`validateOrganizationDelete`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Medications"],"parameters":[{"schema":{"type":"string","example":"682fd0d7d4a6325d9d45b86d","description":"A valid MongoDB ObjectId"},"required":true,"description":"A valid MongoDB ObjectId","name":"medicationId","in":"path"}],"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"organization":{"type":"string"},"meta":{"type":"object","additionalProperties":{"nullable":true}},"date":{"type":"string","format":"date-time"}},"required":["id","name","organization"]}}}}}}},"/devices/alarms/{deviceId}":{"get":{"summary":"Get device alarms","description":"Retrieve current alarm states and notifications for the device.\n\n\nMiddlewares: `authMiddleware`, `validateDevice`","x-middlewares":["`authMiddleware`","`validateDevice`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Devices"],"parameters":[{"schema":{"type":"string","example":"682fd0d7d4a6325d9d45b86d","description":"Device ObjectId"},"required":true,"description":"Device ObjectId","name":"deviceId","in":"path"}],"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"additionalProperties":{"nullable":true}}}}}}}},"/devices/casestatus/{deviceId}":{"post":{"summary":"Get case status","description":"Query the physical enclosure status for the device.\n\n\nMiddlewares: `authMiddleware`, `validateDevice`","x-middlewares":["`authMiddleware`","`validateDevice`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Devices"],"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"additionalProperties":{"nullable":true}}}}}}}},"/devices/ledlight/{deviceId}":{"post":{"summary":"Set LED light on device","description":"Turn the device LED on or off, or set its color/brightness.\n\n\nMiddlewares: `authMiddleware`, `validateDevice`","x-middlewares":["`authMiddleware`","`validateDevice`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["Devices"],"parameters":[{"schema":{"type":"string","example":"682fd0d7d4a6325d9d45b86d","description":"Device ObjectId"},"required":true,"description":"Device ObjectId","name":"deviceId","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"led":{"type":"array","items":{"type":"array","items":{"type":"integer"},"minItems":2,"maxItems":2}},"timeout":{"type":"integer"}},"required":["led","timeout"],"description":"LED light configuration for device","example":{"led":[[0,0],[1,0],[2,0],[3,0],[4,0],[5,0],[6,0],[7,0],[8,0],[9,0],[10,0],[11,0],[12,0],[13,0],[14,0],[15,100],[16,100],[17,100],[18,100],[19,100],[20,100],[21,100],[22,0],[23,0],[24,0],[25,0],[26,0],[27,0],[28,0]],"timeout":40}}}}},"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"additionalProperties":{"nullable":true}}}}}}}},"/pdf/":{"get":{"summary":"Generate a PDF from a provided URL","description":"This endpoint allows users to generate a PDF document from a specified URL.\n\n\nMiddlewares: `authMiddleware`","x-middlewares":["`authMiddleware`"],"security":[{"x-api-key":[]},{"bearerAuth":[]}],"tags":["PDF"],"parameters":[{"schema":{"type":"string","example":"https://memo.wirewire.de/example.pdf","description":"URL path to the PDF generation endpoint. Allowed domains: https://memo.wirewire.de, https://web.wirewire.de"},"required":true,"description":"URL path to the PDF generation endpoint. Allowed domains: https://memo.wirewire.de, https://web.wirewire.de","name":"urlPath","in":"query"}],"responses":{"200":{"description":"Object with user data.","content":{"application/json":{"schema":{"type":"object","properties":{"signed":{"type":"string","format":"uri"}},"required":["signed"]}}}}}}}}}