Admin · Menú y catálogo¶
Esta área de la API es el panel de administración del catálogo del restaurante: la jerarquía Menu → Category → Product, sus añadidos de pago (extras), las preguntas estructuradas (option-groups) y las operaciones de mantenimiento del día a día (alta, edición, borrado lógico, reordenación y activación/desactivación en lote). Es la cara de escritura del mismo catálogo que los clientes leen por la superficie pública y que otros módulos (comanda, chat) consultan para validar pedidos y recomendar platos. Para el modelo de dominio completo —entidades, mappers y el puerto IMenuCatalogGateway— ver Menú y catálogo.
Autenticación y multitenancy. Todos los endpoints están montados bajo /api/v1/admin/menu y exigen un AdminUser autenticado por JWT. Cada operación está protegida por un permiso granular (MENU_VIEW, MENU_CREATE, MENU_EDIT, MENU_DELETE); si el rol del admin no lo tiene, la respuesta es 403. Además, el acceso está acotado por restaurante: el restaurant_id se verifica siempre con require_restaurant_access (vía query param, body o resolviéndolo desde el recurso), nunca se confía a ciegas en el restaurant_id del cuerpo. SUPER_ADMIN puede operar sobre cualquier restaurante.
Patrones a tener en cuenta
- Precios en céntimos. Todos los importes (
price,cost_price, elpricede los extras) son enteros en céntimos (12,50 € →1250). El campoprice_formattedda la versión con divisa. - i18n. Los campos traducibles (
name,description,ai_description,selling_points) se almacenan como dicts JSON por idioma; la capa de interfaz los resuelve según?lang=(por defectoes). - Borrado lógico. Borrar un
menu,categoryoproductno destruye la fila (soft-delete); preserva el audit trail. No se puede borrar un producto referenciado por líneas de comanda activas (409), ni un menú con categorías (400). - Paginación. Los listados usan el shape canónico con
page+size/per_page.
Toda escritura admin queda registrada en el audit trail e invalida la caché del menú público del restaurante afectado, de modo que los clientes ven los cambios de inmediato. La distinción entre disponibilidad (is_available, toggle reversible, con operación en lote) y borrado lógico, así como la diferencia entre extras y grupos de opciones, está explicada en Menú y catálogo. Para la visión general de la API ver Referencia de la API.
Generado automáticamente
Las tablas y fichas de endpoints de esta página se generan desde el contrato OpenAPI. No las edites a mano; edita la intro en documentation/reference/api/_intros/admin-menu.md y regenera con python scripts/gen_openapi_reference.py.
Resumen de endpoints¶
| Método | Ruta | Resumen | Auth |
|---|---|---|---|
GET |
/api/v1/admin/knowledge |
Get Knowledge | Bearer (admin) |
PUT |
/api/v1/admin/knowledge |
Update Knowledge | Bearer (admin) |
GET |
/api/v1/admin/knowledge/completion |
Get Completion Status | Bearer (admin) |
POST |
/api/v1/admin/knowledge/events |
Add Event | Bearer (admin) |
DELETE |
/api/v1/admin/knowledge/events/{index} |
Delete Event | Bearer (admin) |
POST |
/api/v1/admin/knowledge/faqs |
Add Faq | Bearer (admin) |
DELETE |
/api/v1/admin/knowledge/faqs/{index} |
Delete Faq | Bearer (admin) |
PUT |
/api/v1/admin/knowledge/faqs/{index} |
Update Faq | Bearer (admin) |
GET |
/api/v1/admin/menu/categories |
List Categories Admin | Bearer (admin) |
POST |
/api/v1/admin/menu/categories |
Create Category | Bearer (admin) |
DELETE |
/api/v1/admin/menu/categories/{category_id} |
Delete Category | Bearer (admin) |
PUT |
/api/v1/admin/menu/categories/{category_id} |
Update Category | Bearer (admin) |
PATCH |
/api/v1/admin/menu/categories/{category_id}/reorder |
Reorder Category Products | Bearer (admin) |
GET |
/api/v1/admin/menu/menus |
List Menus | Bearer (admin) |
POST |
/api/v1/admin/menu/menus |
Create Menu | Bearer (admin) |
DELETE |
/api/v1/admin/menu/menus/{menu_id} |
Delete Menu | Bearer (admin) |
PUT |
/api/v1/admin/menu/menus/{menu_id} |
Update Menu | Bearer (admin) |
PATCH |
/api/v1/admin/menu/menus/{menu_id}/toggle |
Toggle Menu Active | Bearer (admin) |
GET |
/api/v1/admin/menu/products |
List All Products | Bearer (admin) |
POST |
/api/v1/admin/menu/products |
Create Product | Bearer (admin) |
PATCH |
/api/v1/admin/menu/products/bulk-toggle |
Bulk Toggle Product Availability | Bearer (admin) |
DELETE |
/api/v1/admin/menu/products/{product_id} |
Delete Product | Bearer (admin) |
GET |
/api/v1/admin/menu/products/{product_id} |
Get Product Admin | Bearer (admin) |
PATCH |
/api/v1/admin/menu/products/{product_id} |
Update Product | Bearer (admin) |
PUT |
/api/v1/admin/menu/products/{product_id} |
Update Product | Bearer (admin) |
GET |
/api/v1/admin/menu/products/{product_id}/option-groups |
List Option Groups | Bearer (admin) |
POST |
/api/v1/admin/menu/products/{product_id}/option-groups |
Create Option Group | Bearer (admin) |
DELETE |
/api/v1/admin/menu/products/{product_id}/option-groups/{group_id} |
Delete Option Group | Bearer (admin) |
PUT |
/api/v1/admin/menu/products/{product_id}/option-groups/{group_id} |
Update Option Group | Bearer (admin) |
GET |
/api/v1/admin/promotions |
List Promotions | Bearer (admin) |
POST |
/api/v1/admin/promotions |
Create Promotion | Bearer (admin) |
GET |
/api/v1/admin/promotions/active |
Get Active Promotions | Bearer (admin) |
DELETE |
/api/v1/admin/promotions/{promotion_id} |
Delete Promotion | Bearer (admin) |
GET |
/api/v1/admin/promotions/{promotion_id} |
Get Promotion | Bearer (admin) |
PUT |
/api/v1/admin/promotions/{promotion_id} |
Update Promotion | Bearer (admin) |
PATCH |
/api/v1/admin/promotions/{promotion_id}/toggle |
Toggle Promotion | Bearer (admin) |
Detalle¶
GET /api/v1/admin/knowledge¶
Get Knowledge
Get the knowledge base for a restaurant.
- Auth: Bearer (admin)
- Parámetros:
restaurant_id(query, requerido) - Respuestas:
200KnowledgeDetailResponse,422HTTPValidationError
PUT /api/v1/admin/knowledge¶
Update Knowledge
Update the knowledge base for a restaurant.
- Auth: Bearer (admin)
- Parámetros:
restaurant_id(query, requerido) - Body:
RestaurantKnowledgeResponse - Respuestas:
200KnowledgeDetailResponse,422HTTPValidationError
GET /api/v1/admin/knowledge/completion¶
Get Completion Status
Get the completion status of the knowledge base.
- Auth: Bearer (admin)
- Parámetros:
restaurant_id(query, requerido) - Respuestas:
200CompletionStatusResponse,422HTTPValidationError
POST /api/v1/admin/knowledge/events¶
Add Event
Add a special event or announcement.
- Auth: Bearer (admin)
- Parámetros:
restaurant_id(query, requerido) - Body:
EventCreate - Respuestas:
201,422HTTPValidationError
DELETE /api/v1/admin/knowledge/events/{index}¶
Delete Event
Delete an event at a specific index.
- Auth: Bearer (admin)
- Parámetros:
index(path, requerido),restaurant_id(query, requerido) - Respuestas:
200RestaurantKnowledgeResponse,422HTTPValidationError
POST /api/v1/admin/knowledge/faqs¶
Add Faq
Add a FAQ to the knowledge base.
- Auth: Bearer (admin)
- Parámetros:
restaurant_id(query, requerido) - Body:
FAQCreate - Respuestas:
201,422HTTPValidationError
DELETE /api/v1/admin/knowledge/faqs/{index}¶
Delete Faq
Delete a FAQ at a specific index.
- Auth: Bearer (admin)
- Parámetros:
index(path, requerido),restaurant_id(query, requerido) - Respuestas:
200RestaurantKnowledgeResponse,422HTTPValidationError
PUT /api/v1/admin/knowledge/faqs/{index}¶
Update Faq
Update a FAQ at a specific index.
- Auth: Bearer (admin)
- Parámetros:
index(path, requerido),restaurant_id(query, requerido) - Body:
FAQUpdate - Respuestas:
200,422HTTPValidationError
GET /api/v1/admin/menu/categories¶
List Categories Admin
Get all categories for admin management.
- Auth: Bearer (admin)
- Parámetros:
restaurant_id(query, requerido) - Respuestas:
200CategoryResponse[],422HTTPValidationError
POST /api/v1/admin/menu/categories¶
Create Category
Create a new category.
- Auth: Bearer (admin)
- Parámetros: —
- Body:
CategoryCreateRequest - Respuestas:
201CategoryResponse,422HTTPValidationError
DELETE /api/v1/admin/menu/categories/{category_id}¶
Delete Category
Delete a category (soft delete).
- Auth: Bearer (admin)
- Parámetros:
category_id(path, requerido) - Respuestas:
204,422HTTPValidationError
PUT /api/v1/admin/menu/categories/{category_id}¶
Update Category
Update an existing category.
- Auth: Bearer (admin)
- Parámetros:
category_id(path, requerido) - Body:
CategoryUpdateRequest - Respuestas:
200CategoryResponse,422HTTPValidationError
PATCH /api/v1/admin/menu/categories/{category_id}/reorder¶
Reorder Category Products
Reorder products within a category.
- Auth: Bearer (admin)
- Parámetros:
category_id(path, requerido) - Body:
ReorderProductsRequest - Respuestas:
200,422HTTPValidationError
GET /api/v1/admin/menu/menus¶
List Menus
Get all menus for a restaurant.
- Auth: Bearer (admin)
- Parámetros:
restaurant_id(query, requerido) - Respuestas:
200MenuMetadataResponse[],422HTTPValidationError
POST /api/v1/admin/menu/menus¶
Create Menu
Create a new menu.
- Auth: Bearer (admin)
- Parámetros: —
- Body:
MenuCreateRequest - Respuestas:
201MenuMetadataResponse,422HTTPValidationError
DELETE /api/v1/admin/menu/menus/{menu_id}¶
Delete Menu
Delete a menu (only if it has no categories).
- Auth: Bearer (admin)
- Parámetros:
menu_id(path, requerido),restaurant_id(query, requerido) - Respuestas:
204,422HTTPValidationError
PUT /api/v1/admin/menu/menus/{menu_id}¶
Update Menu
Update an existing menu (legacy: restaurant_id falls back to admin.restaurant_id).
- Auth: Bearer (admin)
- Parámetros:
menu_id(path, requerido),restaurant_id(query, opcional) - Body:
MenuUpdateRequest - Respuestas:
200MenuMetadataResponse,422HTTPValidationError
PATCH /api/v1/admin/menu/menus/{menu_id}/toggle¶
Toggle Menu Active
Toggle menu active status.
- Auth: Bearer (admin)
- Parámetros:
menu_id(path, requerido),restaurant_id(query, requerido) - Respuestas:
200MenuMetadataResponse,422HTTPValidationError
GET /api/v1/admin/menu/products¶
List All Products
Get paginated products for admin management.
- Auth: Bearer (admin)
- Parámetros:
page(query, opcional),restaurant_id(query, requerido),size(query, opcional) - Respuestas:
200ProductListResponse,422HTTPValidationError
POST /api/v1/admin/menu/products¶
Create Product
Create a new product.
- Auth: Bearer (admin)
- Parámetros: —
- Body:
ProductCreateRequest - Respuestas:
201ProductDetailResponse,422HTTPValidationError
PATCH /api/v1/admin/menu/products/bulk-toggle¶
Bulk Toggle Product Availability
Toggle availability for multiple products.
- Auth: Bearer (admin)
- Parámetros: —
- Body:
BulkToggleRequest - Respuestas:
200,422HTTPValidationError
DELETE /api/v1/admin/menu/products/{product_id}¶
Delete Product
Delete a product (soft delete).
- Auth: Bearer (admin)
- Parámetros:
product_id(path, requerido) - Respuestas:
204,422HTTPValidationError
GET /api/v1/admin/menu/products/{product_id}¶
Get Product Admin
Get product details for admin.
- Auth: Bearer (admin)
- Parámetros:
product_id(path, requerido) - Respuestas:
200ProductDetailResponse,422HTTPValidationError
PATCH /api/v1/admin/menu/products/{product_id}¶
Update Product
Update an existing product.
- Auth: Bearer (admin)
- Parámetros:
product_id(path, requerido) - Body:
ProductUpdateRequest - Respuestas:
200ProductDetailResponse,422HTTPValidationError
PUT /api/v1/admin/menu/products/{product_id}¶
Update Product
Update an existing product.
- Auth: Bearer (admin)
- Parámetros:
product_id(path, requerido) - Body:
ProductUpdateRequest - Respuestas:
200ProductDetailResponse,422HTTPValidationError
GET /api/v1/admin/menu/products/{product_id}/option-groups¶
List Option Groups
List a product's option groups.
- Auth: Bearer (admin)
- Parámetros:
product_id(path, requerido) - Respuestas:
200ProductOptionGroupResponse[],422HTTPValidationError
POST /api/v1/admin/menu/products/{product_id}/option-groups¶
Create Option Group
Create a new option group on a product.
- Auth: Bearer (admin)
- Parámetros:
product_id(path, requerido) - Body:
ProductOptionGroupCreateRequest - Respuestas:
201ProductOptionGroupResponse,422HTTPValidationError
DELETE /api/v1/admin/menu/products/{product_id}/option-groups/{group_id}¶
Delete Option Group
Delete an option group from a product.
- Auth: Bearer (admin)
- Parámetros:
group_id(path, requerido),product_id(path, requerido) - Respuestas:
204,422HTTPValidationError
PUT /api/v1/admin/menu/products/{product_id}/option-groups/{group_id}¶
Update Option Group
Replace an option group's fields and options.
- Auth: Bearer (admin)
- Parámetros:
group_id(path, requerido),product_id(path, requerido) - Body:
ProductOptionGroupUpdateRequest - Respuestas:
200ProductOptionGroupResponse,422HTTPValidationError
GET /api/v1/admin/promotions¶
List Promotions
List all promotions for a restaurant with optional filters & client-side pagination.
- Auth: Bearer (admin)
- Parámetros:
is_active(query, opcional),page(query, opcional),product_id(query, opcional),promotion_type(query, opcional),restaurant_id(query, requerido),size(query, opcional) - Respuestas:
200PromotionListResponse,422HTTPValidationError
POST /api/v1/admin/promotions¶
Create Promotion
Create a new product promotion.
- Auth: Bearer (admin)
- Parámetros:
restaurant_id(query, requerido) - Body:
ProductPromotionCreate - Respuestas:
201,422HTTPValidationError
GET /api/v1/admin/promotions/active¶
Get Active Promotions
Get only currently active promotions.
- Auth: Bearer (admin)
- Parámetros:
restaurant_id(query, requerido) - Respuestas:
200ActivePromotionsResponse,422HTTPValidationError
DELETE /api/v1/admin/promotions/{promotion_id}¶
Delete Promotion
Delete a promotion.
- Auth: Bearer (admin)
- Parámetros:
promotion_id(path, requerido),restaurant_id(query, requerido) - Respuestas:
204,422HTTPValidationError
GET /api/v1/admin/promotions/{promotion_id}¶
Get Promotion
Get a specific promotion by ID.
- Auth: Bearer (admin)
- Parámetros:
promotion_id(path, requerido),restaurant_id(query, requerido) - Respuestas:
200,422HTTPValidationError
PUT /api/v1/admin/promotions/{promotion_id}¶
Update Promotion
Update an existing promotion.
- Auth: Bearer (admin)
- Parámetros:
promotion_id(path, requerido),restaurant_id(query, requerido) - Body:
ProductPromotionUpdate - Respuestas:
200,422HTTPValidationError
PATCH /api/v1/admin/promotions/{promotion_id}/toggle¶
Toggle Promotion
Toggle a promotion's active status.
- Auth: Bearer (admin)
- Parámetros:
promotion_id(path, requerido),restaurant_id(query, requerido) - Respuestas:
200,422HTTPValidationError