{"openapi":"3.0.1","info":{"title":"Food Delivery API v1","version":"v1"},"servers":[{"url":"http://foodappbn.nexvsoft.com","description":"Generated server url"}],"tags":[{"name":"Health","description":"Service health and availability"},{"name":"Authentication","description":"Authentication endpoints for signup, login, and password reset"},{"name":"Reservations","description":"Create and manage reservations linked to orders"},{"name":"Settings","description":"Restaurant configuration — food categories (CRUD)"},{"name":"Admin dashboard","description":"Overview KPIs"},{"name":"Roles","description":"Create, update, and assign permissions to roles"},{"name":"User administration","description":"Manage users, roles, and effective permissions"},{"name":"Orders","description":"Admin order listing"},{"name":"Menus","description":"Food menu items per category (gallery: imageUrls)"},{"name":"Permissions","description":"Permission catalog (CRUD)"}],"paths":{"/api/users":{"get":{"tags":["User administration"],"summary":"List users","description":"Returns all users with their roles","operationId":"list","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}},"post":{"tags":["User administration"],"summary":"Create user","description":"Creates a user with hashed password and optional role assignments","operationId":"create","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/users/{id}":{"get":{"tags":["User administration"],"summary":"Get user by id","description":"Returns a single user with roles","operationId":"getById","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}},"post":{"tags":["User administration"],"summary":"Update user","description":"Updates profile fields; include roleIds to replace role assignments","operationId":"update","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUserRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}},"delete":{"tags":["User administration"],"summary":"Delete user","description":"Deletes a user and their role links","operationId":"delete","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/users/{id}/roles":{"post":{"tags":["User administration"],"summary":"Replace user roles","description":"Replaces the full role set. An empty set assigns the default USER role.","operationId":"assignRoles","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssignUserRolesRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/settings/food-categories":{"get":{"tags":["Settings"],"summary":"List food categories","description":"Returns all food categories ordered by display order","operationId":"list_1","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}},"post":{"tags":["Settings"],"summary":"Create food category","operationId":"create_1","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FoodCategoryRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/settings/food-categories/{id}":{"get":{"tags":["Settings"],"summary":"Get food category by id","operationId":"getById_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}},"post":{"tags":["Settings"],"summary":"Update food category","operationId":"update_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FoodCategoryRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}},"delete":{"tags":["Settings"],"summary":"Delete food category","description":"Deletes the category; linked menu items are removed (CASCADE).","operationId":"delete_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/roles":{"get":{"tags":["Roles"],"summary":"List roles","operationId":"list_2","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}},"post":{"tags":["Roles"],"summary":"Create role","operationId":"create_2","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/roles/{id}":{"get":{"tags":["Roles"],"summary":"Get role by id","description":"Includes permissions assigned to the role","operationId":"getById_2","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}},"post":{"tags":["Roles"],"summary":"Update role","operationId":"update_2","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}},"delete":{"tags":["Roles"],"summary":"Delete role","operationId":"delete_2","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/roles/{id}/permissions":{"get":{"tags":["Roles"],"summary":"List permissions for role","operationId":"listPermissions","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}},"post":{"tags":["Roles"],"summary":"Assign permissions to role","description":"Replaces the full set of permissions linked to the role","operationId":"assignPermissions","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssignPermissionsRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/reservations":{"get":{"tags":["Reservations"],"summary":"List reservations","description":"Returns all reservations","operationId":"list_3","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}},"post":{"tags":["Reservations"],"summary":"Create reservation","description":"Creates a reservation with multiple date/menu lines. Sends an email notification to the configured admin address.","operationId":"create_3","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateReservationRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/reservations/{id}":{"get":{"tags":["Reservations"],"summary":"Get reservation by id","description":"Returns a single reservation","operationId":"getById_3","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}},"post":{"tags":["Reservations"],"summary":"Update reservation","description":"Updates an existing reservation","operationId":"update_3","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateReservationRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}},"delete":{"tags":["Reservations"],"summary":"Delete reservation","description":"Deletes a reservation by id","operationId":"delete_3","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/reservations/{id}/confirm":{"post":{"tags":["Reservations"],"summary":"Confirm reservation","description":"Sets status to CONFIRMED and creates one order per line. Only allowed when status is PENDING.","operationId":"confirm","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/reservations/book":{"post":{"tags":["Reservations"],"summary":"Book a reservation","description":"Creates a pending reservation (reference e.g. RSR1) with one or more date/menu lines. Orders are created when the reservation is confirmed. Requires authentication.","operationId":"book","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookReservationRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/permissions":{"get":{"tags":["Permissions"],"summary":"List permissions","description":"Returns all permission definitions","operationId":"list_4","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}},"post":{"tags":["Permissions"],"summary":"Create permission","operationId":"create_4","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PermissionRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/permissions/{id}":{"get":{"tags":["Permissions"],"summary":"Get permission by id","description":"Returns a single permission","operationId":"getById_4","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}},"post":{"tags":["Permissions"],"summary":"Update permission","operationId":"update_4","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PermissionRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}},"delete":{"tags":["Permissions"],"summary":"Delete permission","operationId":"delete_4","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/menus":{"get":{"tags":["Menus"],"summary":"List menu items","description":"Without categoryId returns all items ordered by category then name; with categoryId filters to that category.","operationId":"list_5","parameters":[{"name":"categoryId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}},"post":{"tags":["Menus"],"summary":"Create menu item (JSON)","description":"Creates a menu item under a category. imageUrls is a list of image URLs (gallery).","operationId":"createMultipart_1","requestBody":{"content":{"multipart/form-data":{"schema":{"required":["data"],"type":"object","properties":{"data":{"$ref":"#/components/schemas/FoodMenuMultipartPayload"},"files":{"type":"array","items":{"type":"string","format":"binary"}}}}},"application/json":{"schema":{"$ref":"#/components/schemas/FoodMenuRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/menus/{id}":{"get":{"tags":["Menus"],"summary":"Get menu item by id","operationId":"getById_6","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}},"post":{"tags":["Menus"],"summary":"Update menu item (JSON)","description":"Updates fields including category, price, availability, and imageUrls gallery.","operationId":"updateMultipart_1","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"required":["data"],"type":"object","properties":{"data":{"$ref":"#/components/schemas/FoodMenuMultipartPayload"},"files":{"type":"array","items":{"type":"string","format":"binary"}}}}},"application/json":{"schema":{"$ref":"#/components/schemas/FoodMenuRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}},"delete":{"tags":["Menus"],"summary":"Delete menu item","operationId":"delete_5","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/auth/signup":{"post":{"tags":["Authentication"],"summary":"Sign up","description":"Create a new account (no email verification)","operationId":"signup","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/auth/reset-password":{"post":{"tags":["Authentication"],"summary":"Request password reset","description":"Send password reset email to user","operationId":"requestPasswordReset","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/auth/reset-password/confirm":{"get":{"tags":["Authentication"],"summary":"Handle reset link (GET)","description":"Redirects the user to the frontend reset password page with the token","operationId":"handleResetPasswordLink","parameters":[{"name":"token","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}},"post":{"tags":["Authentication"],"summary":"Confirm password reset","description":"Reset password using the token from email","operationId":"confirmPasswordReset","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetConfirmRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/auth/profile-picture":{"post":{"tags":["Authentication"],"summary":"Upload or update current user's profile picture","description":"Upload a new profile picture for the authenticated user. Accepts a multipart/form-data request with a 'file' field.","operationId":"uploadProfilePicture","requestBody":{"content":{"application/json":{"schema":{"required":["file"],"type":"object","properties":{"file":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/auth/login":{"post":{"tags":["Authentication"],"summary":"User login","description":"Authenticate user and return JWT token","operationId":"login","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}},"required":true},"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/users/{id}/permissions":{"get":{"tags":["User administration"],"summary":"Effective permissions for user (admin)","operationId":"userPermissions","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/users/paginated":{"get":{"tags":["User administration"],"summary":"Get paginated list of users","operationId":"getAllPaginated","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":10}},{"name":"sortColumn","in":"query","required":false,"schema":{"type":"string","default":"createdAt"}},{"name":"sortDirection","in":"query","required":false,"schema":{"type":"string","default":"desc"}},{"name":"search","in":"query","required":false,"schema":{"type":"string","default":""}},{"name":"filters","in":"query","required":true,"schema":{"$ref":"#/components/schemas/FilterUserDto"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/users/me/permissions":{"get":{"tags":["User administration"],"summary":"Effective permissions for current user","description":"Union of permissions from all active roles. Any authenticated user.","operationId":"currentUserPermissions","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/settings/food-categories/paginated":{"get":{"tags":["Settings"],"summary":"Get paginated list of food categories","operationId":"getAllPaginated_1","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":10}},{"name":"sortColumn","in":"query","required":false,"schema":{"type":"string","default":"displayOrder"}},{"name":"sortDirection","in":"query","required":false,"schema":{"type":"string","default":"asc"}},{"name":"search","in":"query","required":false,"schema":{"type":"string","default":""}},{"name":"filters","in":"query","required":true,"schema":{"$ref":"#/components/schemas/FilterFoodCategoryDto"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/roles/paginated":{"get":{"tags":["Roles"],"summary":"Get paginated list of roles","operationId":"getAllPaginated_2","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":10}},{"name":"sortColumn","in":"query","required":false,"schema":{"type":"string","default":"createdAt"}},{"name":"sortDirection","in":"query","required":false,"schema":{"type":"string","default":"desc"}},{"name":"search","in":"query","required":false,"schema":{"type":"string","default":""}},{"name":"filters","in":"query","required":true,"schema":{"$ref":"#/components/schemas/FilterRoleDto"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/reservations/recent":{"get":{"tags":["Reservations"],"summary":"Recent reservations","description":"Latest reservations by created date (admin overview)","operationId":"recent","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":8}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/reservations/paginated":{"get":{"tags":["Reservations"],"summary":"Get paginated list of reservations","operationId":"getAllPaginated_3","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":10}},{"name":"sortColumn","in":"query","required":false,"schema":{"type":"string","default":"createdAt"}},{"name":"sortDirection","in":"query","required":false,"schema":{"type":"string","default":"desc"}},{"name":"search","in":"query","required":false,"schema":{"type":"string","default":""}},{"name":"filters","in":"query","required":true,"schema":{"$ref":"#/components/schemas/FilterReservationDto"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/permissions/paginated":{"get":{"tags":["Permissions"],"summary":"Get paginated list of permissions","operationId":"getAllPaginated_4","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":10}},{"name":"sortColumn","in":"query","required":false,"schema":{"type":"string","default":"createdAt"}},{"name":"sortDirection","in":"query","required":false,"schema":{"type":"string","default":"desc"}},{"name":"search","in":"query","required":false,"schema":{"type":"string","default":""}},{"name":"filters","in":"query","required":true,"schema":{"$ref":"#/components/schemas/FilterPermissionDto"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/orders/{id}":{"get":{"tags":["Orders"],"summary":"Get order by id","description":"Returns a single order with notes and reservation links","operationId":"getById_5","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/orders/paginated":{"get":{"tags":["Orders"],"summary":"Paginated orders","description":"Filter by status; optionally only orders without a reservation.","operationId":"getAllPaginated_5","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":20}},{"name":"sortColumn","in":"query","required":false,"schema":{"type":"string","default":"createdAt"}},{"name":"sortDirection","in":"query","required":false,"schema":{"type":"string","default":"desc"}},{"name":"search","in":"query","required":false,"schema":{"type":"string","default":""}},{"name":"filters","in":"query","required":true,"schema":{"$ref":"#/components/schemas/FilterOrderDto"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/menus/paginated":{"get":{"tags":["Menus"],"summary":"Paginated menu items","description":"Search name/description; filter by categoryId and available.","operationId":"listPaginated","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":0}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":10}},{"name":"sortColumn","in":"query","required":false,"schema":{"type":"string","default":"name"}},{"name":"sortDirection","in":"query","required":false,"schema":{"type":"string","default":"asc"}},{"name":"search","in":"query","required":false,"schema":{"type":"string","default":""}},{"name":"filters","in":"query","required":true,"schema":{"$ref":"#/components/schemas/FilterFoodMenuDto"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/health":{"get":{"tags":["Health"],"summary":"Health check","description":"Returns whether the API process is running","operationId":"health","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/auth/reset-password/validate":{"get":{"tags":["Authentication"],"summary":"Validate reset token","description":"Validate if a password reset token is valid and not expired","operationId":"validateResetToken","parameters":[{"name":"token","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/auth/me":{"get":{"tags":["Authentication"],"summary":"Get current authenticated user's profile","description":"Returns basic profile information for the authenticated user, including profile picture URL if available.","operationId":"getCurrentUser","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/api/admin/dashboard/summary":{"get":{"tags":["Admin dashboard"],"summary":"Dashboard KPIs","description":"Orders count, reservations count, menu items count, total revenue","operationId":"summary","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}}},"components":{"schemas":{"CreateUserRequest":{"required":["email","name"],"type":"object","properties":{"name":{"type":"string"},"email":{"type":"string"},"password":{"type":"string"},"phone":{"type":"string"},"status":{"maxLength":50,"minLength":0,"type":"string"},"active":{"type":"boolean"},"roleIds":{"type":"array","items":{"type":"string","format":"uuid"}}}},"UpdateUserRequest":{"type":"object","properties":{"name":{"type":"string"},"email":{"type":"string"},"password":{"maxLength":128,"minLength":8,"type":"string"},"phone":{"type":"string"},"status":{"maxLength":50,"minLength":0,"type":"string"},"active":{"type":"boolean"},"roleIds":{"type":"array","items":{"type":"string","format":"uuid"}}}},"AssignUserRolesRequest":{"required":["roleIds"],"type":"object","properties":{"roleIds":{"uniqueItems":true,"type":"array","items":{"type":"string","format":"uuid"}}}},"FoodCategoryRequest":{"required":["name"],"type":"object","properties":{"name":{"maxLength":255,"minLength":0,"type":"string"},"description":{"type":"string"},"displayOrder":{"type":"integer","format":"int32"},"active":{"type":"boolean"}}},"RoleRequest":{"required":["name"],"type":"object","properties":{"name":{"maxLength":255,"minLength":0,"type":"string"},"description":{"type":"string"},"active":{"type":"boolean"}}},"AssignPermissionsRequest":{"required":["permissionIds"],"type":"object","properties":{"permissionIds":{"uniqueItems":true,"type":"array","items":{"type":"string","format":"uuid"}}}},"CreateReservationRequest":{"required":["lines","partySize","userId"],"type":"object","properties":{"userId":{"type":"string","format":"uuid"},"partySize":{"minimum":1,"type":"integer","format":"int32"},"status":{"maxLength":50,"minLength":0,"type":"string"},"specialRequests":{"type":"string"},"lines":{"type":"array","items":{"$ref":"#/components/schemas/ReservationLineRequest"}}}},"ReservationLineRequest":{"required":["foodMenuId","quantity","reservedAt"],"type":"object","properties":{"foodMenuId":{"type":"string","format":"uuid"},"reservedAt":{"type":"string","format":"date-time"},"quantity":{"minimum":1,"type":"integer","format":"int32"}}},"UpdateReservationRequest":{"type":"object","properties":{"partySize":{"minimum":1,"type":"integer","format":"int32"},"status":{"maxLength":50,"minLength":0,"type":"string"},"specialRequests":{"type":"string"}}},"BookReservationRequest":{"required":["lines","partySize"],"type":"object","properties":{"partySize":{"minimum":1,"type":"integer","format":"int32"},"specialRequests":{"type":"string"},"lines":{"type":"array","items":{"$ref":"#/components/schemas/ReservationLineRequest"}}}},"PermissionRequest":{"required":["name"],"type":"object","properties":{"name":{"maxLength":255,"minLength":0,"type":"string"},"description":{"type":"string"},"category":{"maxLength":100,"minLength":0,"type":"string"},"active":{"type":"boolean"}}},"FoodMenuMultipartPayload":{"required":["categoryId","gallerySlots","name","price"],"type":"object","properties":{"categoryId":{"type":"string","format":"uuid"},"name":{"maxLength":255,"minLength":0,"type":"string"},"description":{"maxLength":5000,"minLength":0,"type":"string"},"price":{"minimum":0.0,"exclusiveMinimum":true,"type":"number"},"available":{"type":"boolean"},"gallerySlots":{"maxItems":24,"minItems":0,"type":"array","items":{"$ref":"#/components/schemas/GallerySlotPayload"}}}},"GallerySlotPayload":{"type":"object","properties":{"kind":{"type":"string"},"url":{"type":"string"}}},"FoodMenuRequest":{"required":["categoryId","name","price"],"type":"object","properties":{"categoryId":{"type":"string","format":"uuid"},"name":{"maxLength":255,"minLength":0,"type":"string"},"description":{"maxLength":5000,"minLength":0,"type":"string"},"price":{"minimum":0.0,"exclusiveMinimum":true,"type":"number"},"available":{"type":"boolean"},"imageUrls":{"maxItems":24,"minItems":0,"type":"array","items":{"type":"string"}}}},"SignupRequest":{"required":["email","name","password"],"type":"object","properties":{"name":{"type":"string"},"email":{"type":"string"},"password":{"maxLength":128,"minLength":8,"type":"string"},"phone":{"type":"string"}}},"PasswordResetRequest":{"required":["email"],"type":"object","properties":{"email":{"type":"string"}}},"PasswordResetConfirmRequest":{"required":["newPassword","token"],"type":"object","properties":{"token":{"type":"string"},"newPassword":{"maxLength":128,"minLength":8,"type":"string"}}},"LoginRequest":{"required":["email","password"],"type":"object","properties":{"email":{"type":"string"},"password":{"type":"string"}}},"FilterUserDto":{"type":"object","properties":{"status":{"type":"string"},"active":{"type":"boolean"}}},"FilterFoodCategoryDto":{"type":"object","properties":{"active":{"type":"boolean"}}},"FilterRoleDto":{"type":"object","properties":{"active":{"type":"boolean"}}},"FilterReservationDto":{"type":"object","properties":{"status":{"type":"string"},"orderId":{"type":"string","format":"uuid"}}},"FilterPermissionDto":{"type":"object","properties":{"category":{"type":"string"},"active":{"type":"boolean"}}},"FilterOrderDto":{"type":"object","properties":{"status":{"type":"string"},"withoutReservation":{"type":"boolean"}}},"FilterFoodMenuDto":{"type":"object","properties":{"categoryId":{"type":"string","format":"uuid"},"available":{"type":"boolean"}}}},"securitySchemes":{"bearer-jwt":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}}}