diff --git a/ShopIt_API_Postman_Collection.json b/ShopIt_API_Postman_Collection.json index 43d8531..7bb4ba5 100644 --- a/ShopIt_API_Postman_Collection.json +++ b/ShopIt_API_Postman_Collection.json @@ -1,1474 +1,5384 @@ { - "info": { - "_postman_id": "76fd6fd2-53b9-4d92-8e02-1ddcc6207fa2", - "name": "ShopIt API", - "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", - "description": "Colección de la API vigente de ShopIt. El script previo agrega automáticamente el Bearer token guardado por Login User." - }, - "item": [ - { - "name": "Tenants", - "item": [ + "info": { + "_postman_id": "76fd6fd2-53b9-4d92-8e02-1ddcc6207fa2", + "name": "ShopIt API — Complete", + "description": "Colección canónica generada desde las rutas reales de Laravel. Incluye 123 operaciones HTTP, ejemplos de payload, filtros, archivos y tokens separados para Storefront, Admin App y Scanner.\n\nUso rápido:\n1. Ajustá `base_url` y las credenciales.\n2. Ejecutá el Login de la aplicación correspondiente; el token se guarda automáticamente.\n3. Ajustá los IDs y códigos de las variables de colección.\n\nRegeneración: `php postman/generate-shopit-collection.php`.", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + }, + "item": [ { - "name": "List Tenants", - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": { - "raw": "{{base_url}}/api/tenants", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants" - ] - } - }, - "response": [] - }, - { - "name": "Create Tenant OnTicket (JSON)", - "request": { - "method": "POST", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - }, - { - "key": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"codigo\": \"festival-demo\",\n \"nombre\": \"Festival Demo\",\n \"dominio\": \"festival-demo.test\",\n \"primary_color\": \"#111111\",\n \"secondary_color\": \"#222222\",\n \"danger_color\": \"#ff0000\",\n \"success_color\": \"#00aa55\",\n \"header_bg_color\": \"#333333\",\n \"footer_bg_color\": \"#333333\",\n \"header_logo\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==\",\n \"footer_logo\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==\",\n \"search_product_layout\": \"column_with_image\",\n \"search_group_layout\": \"paginated\",\n \"search_items_per_page\": 12,\n \"website_type_code\": \"onticket\",\n \"extras\": {\n \"heroConfig\": {\n \"title_html\": \"

Festival Demo

\",\n \"description_html\": \"

Una experiencia inolvidable

\",\n \"button_text\": \"Comprar entradas\",\n \"button_href\": \"/tickets\",\n \"background_image_id\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==\"\n },\n \"eventConfig\": {\n \"title\": \"Festival Demo\",\n \"location\": \"Buenos Aires\",\n \"dates_text\": \"10 y 11 de octubre de 2026\",\n \"dates\": [\n \"2026-10-10\",\n \"2026-10-11\"\n ]\n }\n }\n}" - }, - "url": { - "raw": "{{base_url}}/api/tenants", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants" - ] - } - }, - "response": [] - }, - { - "name": "Create Tenant ShopIt (Form Data)", - "request": { - "method": "POST", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "body": { - "mode": "formdata", - "formdata": [ + "name": "Storefront API", + "description": "API pública y autenticada consumida por el storefront: autenticación, catálogo, carrito, compras y tickets.", + "item": [ { - "key": "codigo", - "value": "acme", - "type": "text" + "name": "Auth", + "item": [ + { + "name": "Google Token Exchange", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/auth/google/exchange`\n\nControlador: `App\\Domains\\Auth\\Controllers\\GoogleTokenExchangeController`", + "url": { + "raw": "{{base_url}}/api/auth/google/exchange", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "auth", + "google", + "exchange" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"oauth_code\": \"{{oauth_code}}\",\n \"tenant_codigo\": \"{{tenant_code}}\"\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [] + }, + { + "name": "Login", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/login`\n\nControlador: `App\\Domains\\Auth\\Controllers\\LoginController`", + "url": { + "raw": "{{base_url}}/api/login", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "login" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"email\": \"{{user_email}}\",\n \"password\": \"{{user_password}}\",\n \"tenant_codigo\": \"{{tenant_code}}\"\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [], + "event": [ + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "if (pm.response.code >= 200 && pm.response.code < 300) {", + " const payload = pm.response.json();", + " if (payload.token) pm.collectionVariables.set('token', payload.token);", + "}" + ] + } + } + ] + }, + { + "name": "Logout", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/logout`\n\nControlador: `App\\Domains\\Auth\\Controllers\\LogoutController`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/logout", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "logout" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Me", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/me`\n\nControlador: `App\\Domains\\Auth\\Controllers\\MeController`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/me", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "me" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Update Profile", + "request": { + "method": "PUT", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `PUT /api/me`\n\nControlador: `App\\Domains\\Auth\\Controllers\\UpdateProfileController`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/me", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "me" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"nombre_apellido\": \"Usuario Demo Actualizado\",\n \"email\": \"{{user_email}}\",\n \"dni\": \"30123456\",\n \"telefono\": \"+5491112345678\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Reset Password", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/password/reset`\n\nControlador: `App\\Domains\\Auth\\Controllers\\ResetPasswordController`", + "url": { + "raw": "{{base_url}}/api/password/reset", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "password", + "reset" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"email\": \"{{user_email}}\",\n \"codigo\": \"{{reset_code}}\",\n \"password\": \"{{user_password}}\",\n \"password_confirmation\": \"{{user_password}}\"\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [] + }, + { + "name": "Create Reset Password Attempt", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/password/reset-attempts`\n\nControlador: `App\\Domains\\Auth\\Controllers\\CreateResetPasswordAttemptController`", + "url": { + "raw": "{{base_url}}/api/password/reset-attempts", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "password", + "reset-attempts" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"tenant_codigo\": \"{{tenant_code}}\",\n \"email\": \"{{user_email}}\"\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [] + }, + { + "name": "Validate Reset Password Attempt", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/password/reset-attempts/validate`\n\nControlador: `App\\Domains\\Auth\\Controllers\\ValidateResetPasswordAttemptController`", + "url": { + "raw": "{{base_url}}/api/password/reset-attempts/validate", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "password", + "reset-attempts", + "validate" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"email\": \"{{user_email}}\",\n \"codigo\": \"{{reset_code}}\"\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [] + }, + { + "name": "Register", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/register`\n\nControlador: `App\\Domains\\Auth\\Controllers\\RegisterController`", + "url": { + "raw": "{{base_url}}/api/register", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "register" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"tenant_codigo\": \"{{tenant_code}}\",\n \"nombre_apellido\": \"Usuario Demo\",\n \"email\": \"{{user_email}}\",\n \"password\": \"{{user_password}}\",\n \"password_confirmation\": \"{{user_password}}\",\n \"dni\": \"30123456\",\n \"telefono\": \"+5491112345678\"\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [] + } + ] }, { - "key": "nombre", - "value": "Acme", - "type": "text" + "name": "Bootstrap", + "item": [ + { + "name": "Tenant Bootstrap", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/tenants/bootstrap`\n\nControlador: `App\\Domains\\Bootstrap\\Controllers\\TenantBootstrapController`", + "url": { + "raw": "{{base_url}}/api/tenants/bootstrap?dominio={{tenant_domain}}&path=/", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "tenants", + "bootstrap" + ], + "query": [ + { + "key": "dominio", + "value": "{{tenant_domain}}" + }, + { + "key": "path", + "value": "/" + } + ] + } + }, + "response": [] + } + ] }, { - "key": "dominio", - "value": "acme.test", - "type": "text" + "name": "Cart", + "item": [ + { + "name": "Get Cart", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/tenants/{tenant:codigo}/cart`\n\nControlador: `App\\Domains\\Cart\\Controllers\\CartController@show`", + "url": { + "raw": "{{base_url}}/api/tenants/{{tenant_code}}/cart", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "tenants", + "{{tenant_code}}", + "cart" + ] + } + }, + "response": [] + }, + { + "name": "Add Item Cart", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/tenants/{tenant:codigo}/cart/items`\n\nControlador: `App\\Domains\\Cart\\Controllers\\CartController@addItem`", + "url": { + "raw": "{{base_url}}/api/tenants/{{tenant_code}}/cart/items", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "tenants", + "{{tenant_code}}", + "cart", + "items" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"catalog_item_id\": {{catalog_item_id}},\n \"variant_id\": {{variant_id}},\n \"cantidad\": 1\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [] + }, + { + "name": "Update Item Quantity Cart", + "request": { + "method": "PATCH", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `PATCH /api/tenants/{tenant:codigo}/cart/items/{cartItem}`\n\nControlador: `App\\Domains\\Cart\\Controllers\\CartController@updateItemQuantity`", + "url": { + "raw": "{{base_url}}/api/tenants/{{tenant_code}}/cart/items/{{cart_item_id}}", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "tenants", + "{{tenant_code}}", + "cart", + "items", + "{{cart_item_id}}" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"cantidad\": 2,\n \"variant_id\": {{variant_id}}\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [] + }, + { + "name": "Remove Item Cart", + "request": { + "method": "DELETE", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `DELETE /api/tenants/{tenant:codigo}/cart/items/{cartItem}`\n\nControlador: `App\\Domains\\Cart\\Controllers\\CartController@removeItem`", + "url": { + "raw": "{{base_url}}/api/tenants/{{tenant_code}}/cart/items/{{cart_item_id}}", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "tenants", + "{{tenant_code}}", + "cart", + "items", + "{{cart_item_id}}" + ] + } + }, + "response": [] + } + ] }, { - "key": "primary_color", - "value": "#111111", - "type": "text" + "name": "Catalog", + "item": [ + { + "name": "List Catalog", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/tenants/{tenant:codigo}/catalog`\n\nControlador: `App\\Domains\\Catalog\\Controllers\\CatalogController@index`", + "url": { + "raw": "{{base_url}}/api/tenants/{{tenant_code}}/catalog", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "tenants", + "{{tenant_code}}", + "catalog" + ] + } + }, + "response": [] + }, + { + "name": "Search Catalog", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/tenants/{tenant:codigo}/catalog-items`\n\nControlador: `App\\Domains\\Catalog\\Controllers\\CatalogController@search`", + "url": { + "raw": "{{base_url}}/api/tenants/{{tenant_code}}/catalog-items?q=demo&page=1", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "tenants", + "{{tenant_code}}", + "catalog-items" + ], + "query": [ + { + "key": "q", + "value": "demo" + }, + { + "key": "page", + "value": "1" + } + ] + } + }, + "response": [] + }, + { + "name": "Create Catalog", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/tenants/{tenant:codigo}/catalog-items`\n\nControlador: `App\\Domains\\Catalog\\Controllers\\CatalogController@store`", + "url": { + "raw": "{{base_url}}/api/tenants/{{tenant_code}}/catalog-items?q=demo&page=1", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "tenants", + "{{tenant_code}}", + "catalog-items" + ], + "query": [ + { + "key": "q", + "value": "demo" + }, + { + "key": "page", + "value": "1" + } + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"type\": \"standard\",\n \"category_id\": {{category_id}},\n \"slug\": \"producto-demo\",\n \"nombre\": \"Producto Demo\",\n \"descripcion\": \"Producto creado desde Postman\",\n \"precio\": 10000,\n \"inventory_policy\": \"tracked\",\n \"inventory_subject\": \"product\",\n \"max_units_per_user\": 5,\n \"has_tickets\": false,\n \"real_stock\": 100,\n \"images\": [\n \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==\"\n ]\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [] + }, + { + "name": "Get Catalog", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/tenants/{tenant:codigo}/catalog-items/{catalogItem}`\n\nControlador: `App\\Domains\\Catalog\\Controllers\\CatalogController@show`", + "url": { + "raw": "{{base_url}}/api/tenants/{{tenant_code}}/catalog-items/{{catalog_item_id}}", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "tenants", + "{{tenant_code}}", + "catalog-items", + "{{catalog_item_id}}" + ], + "query": [ + { + "key": "variant_id", + "value": "{{variant_id}}", + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "Get Variant Options Catalog", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/tenants/{tenant:codigo}/catalog-items/{catalogItem}/variant-options`\n\nControlador: `App\\Domains\\Catalog\\Controllers\\CatalogController@variantOptions`", + "url": { + "raw": "{{base_url}}/api/tenants/{{tenant_code}}/catalog-items/{{catalog_item_id}}/variant-options", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "tenants", + "{{tenant_code}}", + "catalog-items", + "{{catalog_item_id}}", + "variant-options" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"selected_values\": {\n \"color\": \"azul\"\n },\n \"cart_item_id\": {{cart_item_id}}\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [] + }, + { + "name": "List Featured Group Items Catalog", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/tenants/{tenant:codigo}/catalog/featured-groups/{featuredGroup}/items`\n\nControlador: `App\\Domains\\Catalog\\Controllers\\CatalogController@featuredGroupItems`", + "url": { + "raw": "{{base_url}}/api/tenants/{{tenant_code}}/catalog/featured-groups/{{featured_group_id}}/items?page=1", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "tenants", + "{{tenant_code}}", + "catalog", + "featured-groups", + "{{featured_group_id}}", + "items" + ], + "query": [ + { + "key": "page", + "value": "1" + } + ] + } + }, + "response": [] + }, + { + "name": "Get Category Catalog", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/tenants/{tenant:codigo}/categories/{category}`\n\nControlador: `App\\Domains\\Catalog\\Controllers\\CatalogController@category`", + "url": { + "raw": "{{base_url}}/api/tenants/{{tenant_code}}/categories/{{category_id}}?page=1", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "tenants", + "{{tenant_code}}", + "categories", + "{{category_id}}" + ], + "query": [ + { + "key": "page", + "value": "1" + } + ] + } + }, + "response": [] + } + ] }, { - "key": "secondary_color", - "value": "#222222", - "type": "text" + "name": "Purchase", + "item": [ + { + "name": "List Purchase", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/tenants/{tenant:codigo}/compras`\n\nControlador: `App\\Domains\\Purchase\\Controllers\\PurchaseController@index`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/tenants/{{tenant_code}}/compras?page=1", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "tenants", + "{{tenant_code}}", + "compras" + ], + "query": [ + { + "key": "status", + "value": "pending_payment", + "disabled": true + }, + { + "key": "page", + "value": "1" + } + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Start Checkout Purchase", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/tenants/{tenant:codigo}/compras/start-checkout`\n\nControlador: `App\\Domains\\Purchase\\Controllers\\PurchaseController@startCheckout`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/tenants/{{tenant_code}}/compras/start-checkout", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "tenants", + "{{tenant_code}}", + "compras", + "start-checkout" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"cart_id\": {{cart_id}}\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Get Purchase", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/tenants/{tenant:codigo}/compras/{compra}`\n\nControlador: `App\\Domains\\Purchase\\Controllers\\PurchaseController@show`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/tenants/{{tenant_code}}/compras/{{purchase_id}}", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "tenants", + "{{tenant_code}}", + "compras", + "{{purchase_id}}" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Cancel Purchase", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/tenants/{tenant:codigo}/compras/{compra}/cancel`\n\nControlador: `App\\Domains\\Purchase\\Controllers\\PurchaseController@cancel`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/tenants/{{tenant_code}}/compras/{{purchase_id}}/cancel", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "tenants", + "{{tenant_code}}", + "compras", + "{{purchase_id}}", + "cancel" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Complete Purchase", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/tenants/{tenant:codigo}/compras/{compra}/complete`\n\nControlador: `App\\Domains\\Purchase\\Controllers\\PurchaseController@complete`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/tenants/{{tenant_code}}/compras/{{purchase_id}}/complete", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "tenants", + "{{tenant_code}}", + "compras", + "{{purchase_id}}", + "complete" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Update Customer Data Purchase", + "request": { + "method": "PATCH", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `PATCH /api/tenants/{tenant:codigo}/compras/{compra}/customer-data`\n\nControlador: `App\\Domains\\Purchase\\Controllers\\PurchaseController@updateCustomerData`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/tenants/{{tenant_code}}/compras/{{purchase_id}}/customer-data", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "tenants", + "{{tenant_code}}", + "compras", + "{{purchase_id}}", + "customer-data" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"dni\": \"30123456\",\n \"telefono\": \"+5491112345678\",\n \"nombre_apellido\": \"Usuario Demo\",\n \"email\": \"{{user_email}}\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Prepare Item Editing Purchase", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/tenants/{tenant:codigo}/compras/{compra}/edit-items`\n\nControlador: `App\\Domains\\Purchase\\Controllers\\PurchaseController@prepareItemEditing`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/tenants/{{tenant_code}}/compras/{{purchase_id}}/edit-items", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "tenants", + "{{tenant_code}}", + "compras", + "{{purchase_id}}", + "edit-items" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Update Item Quantity Purchase", + "request": { + "method": "PATCH", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `PATCH /api/tenants/{tenant:codigo}/compras/{compra}/items/{item}`\n\nControlador: `App\\Domains\\Purchase\\Controllers\\PurchaseController@updateItemQuantity`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/tenants/{{tenant_code}}/compras/{{purchase_id}}/items/{{purchase_item_id}}", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "tenants", + "{{tenant_code}}", + "compras", + "{{purchase_id}}", + "items", + "{{purchase_item_id}}" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"quantity\": 2\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Create Payment Intent Purchase", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/tenants/{tenant:codigo}/compras/{compra}/payment-intent`\n\nControlador: `App\\Domains\\Purchase\\Controllers\\PurchaseController@paymentIntent`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/tenants/{{tenant_code}}/compras/{{purchase_id}}/payment-intent", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "tenants", + "{{tenant_code}}", + "compras", + "{{purchase_id}}", + "payment-intent" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"method\": \"transfer\",\n \"transfer_payer_dni\": \"30123456\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Submit for Review Purchase", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/tenants/{tenant:codigo}/compras/{compra}/review`\n\nControlador: `App\\Domains\\Purchase\\Controllers\\PurchaseController@submitForReview`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/tenants/{{tenant_code}}/compras/{{purchase_id}}/review", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "tenants", + "{{tenant_code}}", + "compras", + "{{purchase_id}}", + "review" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + } + }, + "response": [] + } + ] }, { - "key": "danger_color", - "value": "#ff0000", - "type": "text" - }, - { - "key": "success_color", - "value": "#00aa55", - "type": "text" - }, - { - "key": "header_bg_color", - "value": "#333333", - "type": "text" - }, - { - "key": "footer_bg_color", - "value": "#333333", - "type": "text" - }, - { - "key": "header_logo", - "type": "file", - "src": [] - }, - { - "key": "footer_logo", - "type": "file", - "src": [] - }, - { - "key": "search_product_layout", - "value": "column_with_image", - "type": "text" - }, - { - "key": "search_group_layout", - "value": "paginated", - "type": "text" - }, - { - "key": "search_items_per_page", - "value": "12", - "type": "text" - }, - { - "key": "website_type_code", - "value": "shopit", - "type": "text" - }, - { - "key": "extras[carousel][]", - "type": "file", - "src": [], - "description": "Se puede repetir esta key hasta 10 veces. También acepta una imagen base64 o el UUID de un attachment." + "name": "Ticket", + "item": [ + { + "name": "List Ticket", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/tenants/{tenant:codigo}/tickets`\n\nControlador: `App\\Domains\\Ticket\\Controllers\\TicketController@index`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/tenants/{{tenant_code}}/tickets", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "tenants", + "{{tenant_code}}", + "tickets" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Download PDF Ticket", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/tenants/{tenant:codigo}/tickets/pdf`\n\nControlador: `App\\Domains\\Ticket\\Controllers\\TicketController@downloadPdf`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/tenants/{{tenant_code}}/tickets/pdf", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "tenants", + "{{tenant_code}}", + "tickets", + "pdf" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"ticket_ids\": [\n 1\n ]\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + } + }, + "response": [] + } + ] } - ] - }, - "url": { - "raw": "{{base_url}}/api/tenants", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants" - ] - } - }, - "response": [] + ] }, { - "name": "Bootstrap Tenant", - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": { - "raw": "{{base_url}}/api/tenants/bootstrap?dominio={{tenant_domain}}&path={{tenant_path}}", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "bootstrap" - ], - "query": [ - {"key": "dominio", "value": "{{tenant_domain}}"}, - {"key": "path", "value": "{{tenant_path}}"} - ] - } - }, - "response": [] + "name": "Platform Management", + "description": "CRUD y configuración de tenants, clientes, menús e integraciones.", + "item": [ + { + "name": "Client", + "item": [ + { + "name": "List Client", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/clients`\n\nControlador: `App\\Domains\\Client\\Controllers\\ClientController@index`", + "url": { + "raw": "{{base_url}}/api/clients", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "clients" + ] + } + }, + "response": [] + }, + { + "name": "Create Client", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/clients`\n\nControlador: `App\\Domains\\Client\\Controllers\\ClientController@store`", + "url": { + "raw": "{{base_url}}/api/clients", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "clients" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"code\": \"cliente-demo\",\n \"name\": \"Cliente Demo\"\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [] + }, + { + "name": "Get Client", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/clients/{client}`\n\nControlador: `App\\Domains\\Client\\Controllers\\ClientController@show`", + "url": { + "raw": "{{base_url}}/api/clients/{{client_id}}", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "clients", + "{{client_id}}" + ] + } + }, + "response": [] + }, + { + "name": "Update Client (PUT)", + "request": { + "method": "PUT", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `PUT /api/clients/{client}`\n\nControlador: `App\\Domains\\Client\\Controllers\\ClientController@update`", + "url": { + "raw": "{{base_url}}/api/clients/{{client_id}}", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "clients", + "{{client_id}}" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"code\": \"cliente-demo\",\n \"name\": \"Cliente Demo Actualizado\"\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [] + }, + { + "name": "Update Client (PATCH)", + "request": { + "method": "PATCH", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `PATCH /api/clients/{client}`\n\nControlador: `App\\Domains\\Client\\Controllers\\ClientController@update`", + "url": { + "raw": "{{base_url}}/api/clients/{{client_id}}", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "clients", + "{{client_id}}" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"name\": \"Cliente Demo Actualizado\"\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [] + }, + { + "name": "Delete Client", + "request": { + "method": "DELETE", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `DELETE /api/clients/{client}`\n\nControlador: `App\\Domains\\Client\\Controllers\\ClientController@destroy`", + "url": { + "raw": "{{base_url}}/api/clients/{{client_id}}", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "clients", + "{{client_id}}" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Integration", + "item": [ + { + "name": "List Client Integration", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/clients/{client}/integrations`\n\nControlador: `App\\Domains\\Integration\\Controllers\\ClientIntegrationController@index`", + "url": { + "raw": "{{base_url}}/api/clients/{{client_id}}/integrations", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "clients", + "{{client_id}}", + "integrations" + ] + } + }, + "response": [] + }, + { + "name": "Get Client Integration", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/clients/{client}/integrations/{integration_code}`\n\nControlador: `App\\Domains\\Integration\\Controllers\\ClientIntegrationController@show`", + "url": { + "raw": "{{base_url}}/api/clients/{{client_id}}/integrations/{{integration_code}}", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "clients", + "{{client_id}}", + "integrations", + "{{integration_code}}" + ] + } + }, + "response": [] + }, + { + "name": "Create Client Integration", + "request": { + "method": "PUT", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `PUT /api/clients/{client}/integrations/{integration_code}`\n\nControlador: `App\\Domains\\Integration\\Controllers\\ClientIntegrationController@store`", + "url": { + "raw": "{{base_url}}/api/clients/{{client_id}}/integrations/{{integration_code}}", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "clients", + "{{client_id}}", + "integrations", + "{{integration_code}}" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"integration_data\": {\n \"api_key\": \"replace-me\"\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [] + }, + { + "name": "List Integration", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/integrations`\n\nControlador: `App\\Domains\\Integration\\Controllers\\IntegrationController@index`", + "url": { + "raw": "{{base_url}}/api/integrations", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "integrations" + ] + } + }, + "response": [] + }, + { + "name": "Create Integration", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/integrations`\n\nControlador: `App\\Domains\\Integration\\Controllers\\IntegrationController@store`", + "url": { + "raw": "{{base_url}}/api/integrations", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "integrations" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"integration_code\": \"telepagos\",\n \"name\": \"Telepagos\",\n \"url\": \"https://api.example.com\",\n \"integration_data_schema\": {\n \"api_key\": [\n \"required\",\n \"string\"\n ]\n },\n \"requires_client_configuration\": true\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [] + }, + { + "name": "Get Integration", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/integrations/{integration}`\n\nControlador: `App\\Domains\\Integration\\Controllers\\IntegrationController@show`", + "url": { + "raw": "{{base_url}}/api/integrations/{{integration_id}}", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "integrations", + "{{integration_id}}" + ] + } + }, + "response": [] + }, + { + "name": "Update Integration", + "request": { + "method": "PUT", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `PUT /api/integrations/{integration}`\n\nControlador: `App\\Domains\\Integration\\Controllers\\IntegrationController@update`", + "url": { + "raw": "{{base_url}}/api/integrations/{{integration_id}}", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "integrations", + "{{integration_id}}" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"name\": \"Telepagos\",\n \"url\": \"https://api.example.com\",\n \"requires_client_configuration\": true\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [] + }, + { + "name": "Delete Integration", + "request": { + "method": "DELETE", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `DELETE /api/integrations/{integration}`\n\nControlador: `App\\Domains\\Integration\\Controllers\\IntegrationController@destroy`", + "url": { + "raw": "{{base_url}}/api/integrations/{{integration_id}}", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "integrations", + "{{integration_id}}" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Menu", + "item": [ + { + "name": "List Menu", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/menues`\n\nControlador: `App\\Domains\\Menu\\Controllers\\MenuController@index`", + "url": { + "raw": "{{base_url}}/api/menues", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "menues" + ] + } + }, + "response": [] + }, + { + "name": "Create Menu", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/menues`\n\nControlador: `App\\Domains\\Menu\\Controllers\\MenuController@store`", + "url": { + "raw": "{{base_url}}/api/menues", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "menues" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"code\": \"demo\",\n \"label\": \"Demo\",\n \"parent_menu_code\": null,\n \"content_type\": \"static\",\n \"static_content_schema\": {\n \"title\": [\n \"required\",\n \"string\"\n ]\n },\n \"route\": \"/demo\"\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [] + }, + { + "name": "Get Menu", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/menues/{menue}`\n\nControlador: `App\\Domains\\Menu\\Controllers\\MenuController@show`", + "url": { + "raw": "{{base_url}}/api/menues/{{menu_id}}", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "menues", + "{{menu_id}}" + ] + } + }, + "response": [] + }, + { + "name": "Update Menu (PUT)", + "request": { + "method": "PUT", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `PUT /api/menues/{menue}`\n\nControlador: `App\\Domains\\Menu\\Controllers\\MenuController@update`", + "url": { + "raw": "{{base_url}}/api/menues/{{menu_id}}", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "menues", + "{{menu_id}}" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"label\": \"Demo actualizado\",\n \"route\": \"/demo\"\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [] + }, + { + "name": "Update Menu (PATCH)", + "request": { + "method": "PATCH", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `PATCH /api/menues/{menue}`\n\nControlador: `App\\Domains\\Menu\\Controllers\\MenuController@update`", + "url": { + "raw": "{{base_url}}/api/menues/{{menu_id}}", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "menues", + "{{menu_id}}" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"label\": \"Demo actualizado\"\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [] + }, + { + "name": "Delete Menu", + "request": { + "method": "DELETE", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `DELETE /api/menues/{menue}`\n\nControlador: `App\\Domains\\Menu\\Controllers\\MenuController@destroy`", + "url": { + "raw": "{{base_url}}/api/menues/{{menu_id}}", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "menues", + "{{menu_id}}" + ] + } + }, + "response": [] + }, + { + "name": "Create Tenant Menu", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/{tenant_code}/menues/{menu_code}`\n\nControlador: `App\\Domains\\Menu\\Controllers\\TenantMenuController@store`", + "url": { + "raw": "{{base_url}}/api/{{tenant_code}}/menues/{{menu_code}}", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "{{tenant_code}}", + "menues", + "{{menu_code}}" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"static_content\": {\n \"title\": \"Contenido demo\"\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [] + } + ] + }, + { + "name": "Tenant", + "item": [ + { + "name": "List Tenant", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/tenants`\n\nControlador: `App\\Domains\\Tenant\\Controllers\\TenantController@index`", + "url": { + "raw": "{{base_url}}/api/tenants", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "tenants" + ] + } + }, + "response": [] + }, + { + "name": "Create Tenant", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/tenants`\n\nControlador: `App\\Domains\\Tenant\\Controllers\\TenantController@store`", + "url": { + "raw": "{{base_url}}/api/tenants", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "tenants" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"client_id\": {{client_id}},\n \"codigo\": \"{{tenant_code}}\",\n \"nombre\": \"Tenant Demo\",\n \"dominio\": \"{{tenant_domain}}\",\n \"site_title\": \"ShopIt Demo\",\n \"primary_color\": \"#111827\",\n \"secondary_color\": \"#2563EB\",\n \"danger_color\": \"#DC2626\",\n \"success_color\": \"#16A34A\",\n \"header_bg_color\": \"#FFFFFF\",\n \"footer_bg_color\": \"#111827\",\n \"header_logo\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==\",\n \"footer_logo\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==\",\n \"search_product_layout\": \"column_with_image\",\n \"search_group_layout\": \"paginated\",\n \"search_items_per_page\": 12,\n \"display_categories\": true,\n \"display_seach_bar\": true,\n \"display_cart\": true,\n \"cart_editing_enabled\": true,\n \"website_type_code\": \"shopit\"\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [] + }, + { + "name": "Get Tenant", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/tenants/{tenant}`\n\nControlador: `App\\Domains\\Tenant\\Controllers\\TenantController@show`", + "url": { + "raw": "{{base_url}}/api/tenants/{{tenant_id}}", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "tenants", + "{{tenant_id}}" + ] + } + }, + "response": [] + }, + { + "name": "Update Tenant (PUT)", + "request": { + "method": "PUT", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `PUT /api/tenants/{tenant}`\n\nControlador: `App\\Domains\\Tenant\\Controllers\\TenantController@update`", + "url": { + "raw": "{{base_url}}/api/tenants/{{tenant_id}}", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "tenants", + "{{tenant_id}}" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"nombre\": \"Tenant Demo Actualizado\",\n \"site_title\": \"ShopIt Demo\",\n \"primary_color\": \"#111827\",\n \"cart_editing_enabled\": true\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [] + }, + { + "name": "Update Tenant (PATCH)", + "request": { + "method": "PATCH", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `PATCH /api/tenants/{tenant}`\n\nControlador: `App\\Domains\\Tenant\\Controllers\\TenantController@update`", + "url": { + "raw": "{{base_url}}/api/tenants/{{tenant_id}}", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "tenants", + "{{tenant_id}}" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"nombre\": \"Tenant Demo Actualizado\",\n \"site_title\": \"ShopIt Demo\",\n \"primary_color\": \"#111827\",\n \"cart_editing_enabled\": true\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [] + }, + { + "name": "Delete Tenant", + "request": { + "method": "DELETE", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `DELETE /api/tenants/{tenant}`\n\nControlador: `App\\Domains\\Tenant\\Controllers\\TenantController@destroy`", + "url": { + "raw": "{{base_url}}/api/tenants/{{tenant_id}}", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "tenants", + "{{tenant_id}}" + ] + } + }, + "response": [] + } + ] + } + ] }, { - "name": "Show Tenant", - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_id}}", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_id}}" - ] - } - }, - "response": [] + "name": "Developer Utilities", + "description": "Endpoints de diagnóstico de correo y almacenamiento. No deberían exponerse en producción.", + "item": [ + { + "name": "Storage Test", + "item": [ + { + "name": "Generate Temporary URL S3 Test", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/storage-test/s3/temporary-url`\n\nControlador: `App\\Domains\\StorageTest\\Controllers\\S3TestController@temporaryUrl`", + "url": { + "raw": "{{base_url}}/api/storage-test/s3/temporary-url?path={{s3_path}}&expires_in_minutes=60", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "storage-test", + "s3", + "temporary-url" + ], + "query": [ + { + "key": "path", + "value": "{{s3_path}}" + }, + { + "key": "expires_in_minutes", + "value": "60" + } + ] + } + }, + "response": [] + }, + { + "name": "Create S3 Test", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/storage-test/s3/upload`\n\nControlador: `App\\Domains\\StorageTest\\Controllers\\S3TestController@store`", + "url": { + "raw": "{{base_url}}/api/storage-test/s3/upload", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "storage-test", + "s3", + "upload" + ] + }, + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "path", + "value": "postman/test-file.png", + "type": "text" + }, + { + "key": "expires_in_minutes", + "value": "60", + "type": "text" + }, + { + "key": "file", + "type": "file", + "src": [] + } + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Mail Test", + "item": [ + { + "name": "Mail Test", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/{tenant_code}/mail-test/send`\n\nControlador: `App\\Domains\\MailTest\\Controllers\\MailTestController`", + "url": { + "raw": "{{base_url}}/api/{{tenant_code}}/mail-test/send", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "{{tenant_code}}", + "mail-test", + "send" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"to\": \"destinatario@example.com\",\n \"subject\": \"Prueba ShopIt\",\n \"message\": \"Correo de prueba enviado desde Postman.\"\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [] + } + ] + } + ] }, { - "name": "Update Tenant (JSON)", - "request": { - "method": "PATCH", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - }, - { - "key": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"nombre\": \"Acme Updated\",\n \"primary_color\": \"#555555\"\n}" - }, - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_id}}", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_id}}" - ] - } - }, - "response": [] + "name": "Admin App API", + "description": "Operaciones de administración del tenant. Ejecutá Login primero para completar `admin_token`.", + "item": [ + { + "name": "Bootstrap", + "item": [ + { + "name": "Admin App Bootstrap", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/v1/adminapp/bootstrap/{dominio}`\n\nControlador: `App\\Domains\\Bootstrap\\Controllers\\AdminAppBootstrapController`", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/bootstrap/{{tenant_domain}}?path=/", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "bootstrap", + "{{tenant_domain}}" + ], + "query": [ + { + "key": "path", + "value": "/" + } + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Forms", + "item": [ + { + "name": "Event Form", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/v1/adminapp/forms/event`\n\nControlador: `App\\Domains\\Forms\\Controllers\\AdminApp\\EventFormController`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/forms/event", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "forms", + "event" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Food Form", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/v1/adminapp/forms/fiesta-futbol-infantil/food`\n\nControlador: `App\\Domains\\Forms\\Controllers\\AdminApp\\FoodFormController`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/forms/fiesta-futbol-infantil/food", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "forms", + "fiesta-futbol-infantil", + "food" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Merchandise Form", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/v1/adminapp/forms/fiesta-futbol-infantil/merchandise`\n\nControlador: `App\\Domains\\Forms\\Controllers\\AdminApp\\MerchandiseFormController`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/forms/fiesta-futbol-infantil/merchandise", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "forms", + "fiesta-futbol-infantil", + "merchandise" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Sale Form", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/v1/adminapp/forms/sale`\n\nControlador: `App\\Domains\\Forms\\Controllers\\AdminApp\\SaleFormController`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/forms/sale", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "forms", + "sale" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Staff Form", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/v1/adminapp/forms/staff`\n\nControlador: `App\\Domains\\Forms\\Controllers\\AdminApp\\StaffFormController`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/forms/staff", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "forms", + "staff" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Auth", + "item": [ + { + "name": "Admin App Login", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/v1/adminapp/login`\n\nControlador: `App\\Domains\\Auth\\Controllers\\AdminAppLoginController`", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/login", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "login" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"email\": \"{{admin_email}}\",\n \"password\": \"{{admin_password}}\"\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [], + "event": [ + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "if (pm.response.code >= 200 && pm.response.code < 300) {", + " const payload = pm.response.json();", + " if (payload.token) pm.collectionVariables.set('admin_token', payload.token);", + "}" + ] + } + } + ] + }, + { + "name": "Admin App Me", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/v1/adminapp/me`\n\nControlador: `App\\Domains\\Auth\\Controllers\\AdminAppMeController`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/me", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "me" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Reset Password", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/v1/adminapp/password/reset`\n\nControlador: `App\\Domains\\Auth\\Controllers\\ResetPasswordController`", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/password/reset", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "password", + "reset" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"email\": \"{{admin_email}}\",\n \"codigo\": \"{{reset_code}}\",\n \"password\": \"{{admin_password}}\",\n \"password_confirmation\": \"{{admin_password}}\"\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [] + }, + { + "name": "Create Admin App Reset Password Attempt", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/v1/adminapp/password/reset-attempts`\n\nControlador: `App\\Domains\\Auth\\Controllers\\CreateAdminAppResetPasswordAttemptController`", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/password/reset-attempts", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "password", + "reset-attempts" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"email\": \"{{admin_email}}\"\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [] + }, + { + "name": "Validate Reset Password Attempt", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/v1/adminapp/password/reset-attempts/validate`\n\nControlador: `App\\Domains\\Auth\\Controllers\\ValidateResetPasswordAttemptController`", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/password/reset-attempts/validate", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "password", + "reset-attempts", + "validate" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"email\": \"{{admin_email}}\",\n \"codigo\": \"{{reset_code}}\"\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [] + } + ] + }, + { + "name": "Fiesta Futbol Infantil", + "item": [ + { + "name": "List Accommodation", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/v1/adminapp/tenant/accommodations`\n\nControlador: `App\\Domains\\FiestaFutbolInfantil\\Controllers\\AccommodationController@index`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/accommodations", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "accommodations" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Create Accommodation", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/v1/adminapp/tenant/accommodations`\n\nControlador: `App\\Domains\\FiestaFutbolInfantil\\Controllers\\AccommodationController@store`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/accommodations", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "accommodations" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"variants\": [\n {\n \"title\": \"Habitación doble\",\n \"description\": \"Dos personas\",\n \"stock\": 10,\n \"price\": 100000\n }\n ]\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Delete Accommodation", + "request": { + "method": "DELETE", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `DELETE /api/v1/adminapp/tenant/accommodations/{accommodation}`\n\nControlador: `App\\Domains\\FiestaFutbolInfantil\\Controllers\\AccommodationController@destroy`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/accommodations/{{accommodation_id}}", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "accommodations", + "{{accommodation_id}}" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "List Entry", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/v1/adminapp/tenant/entries`\n\nControlador: `App\\Domains\\FiestaFutbolInfantil\\Controllers\\EntryController@index`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/entries", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "entries" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Create Entry", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/v1/adminapp/tenant/entries`\n\nControlador: `App\\Domains\\FiestaFutbolInfantil\\Controllers\\EntryController@store`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/entries", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "entries" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"entries\": [\n {\n \"title\": \"Entrada general\",\n \"description\": \"Acceso general\",\n \"event_date_ids\": [\n 1\n ],\n \"stock\": 100,\n \"price\": 25000\n }\n ]\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Delete Entry", + "request": { + "method": "DELETE", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `DELETE /api/v1/adminapp/tenant/entries/{entry}`\n\nControlador: `App\\Domains\\FiestaFutbolInfantil\\Controllers\\EntryController@destroy`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/entries/{{entry_id}}", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "entries", + "{{entry_id}}" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "List Food", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/v1/adminapp/tenant/foods`\n\nControlador: `App\\Domains\\FiestaFutbolInfantil\\Controllers\\FoodController@index`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/foods", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "foods" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Create Food", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/v1/adminapp/tenant/foods`\n\nControlador: `App\\Domains\\FiestaFutbolInfantil\\Controllers\\FoodController@store`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/foods", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "foods" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"variants\": [\n {\n \"event_date_id\": 1,\n \"schedule\": \"21:00\",\n \"service\": \"Cena\",\n \"description\": \"Menú completo\",\n \"stock\": 100,\n \"price\": 15000\n }\n ]\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Delete Food", + "request": { + "method": "DELETE", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `DELETE /api/v1/adminapp/tenant/foods/{food}`\n\nControlador: `App\\Domains\\FiestaFutbolInfantil\\Controllers\\FoodController@destroy`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/foods/{{food_id}}", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "foods", + "{{food_id}}" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "List Merchandise", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/v1/adminapp/tenant/merchandise`\n\nControlador: `App\\Domains\\FiestaFutbolInfantil\\Controllers\\MerchandiseController@index`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/merchandise", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "merchandise" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Create Merchandise", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/v1/adminapp/tenant/merchandise`\n\nControlador: `App\\Domains\\FiestaFutbolInfantil\\Controllers\\MerchandiseController@store`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/merchandise", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "merchandise" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"items\": [\n {\n \"title\": \"Camiseta\",\n \"description\": \"Camiseta oficial\",\n \"max_units_per_user\": 2,\n \"variants\": [\n {\n \"color\": \"Azul\",\n \"size\": \"M\",\n \"stock\": 20,\n \"price\": 30000\n }\n ]\n }\n ]\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Delete Merchandise", + "request": { + "method": "DELETE", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `DELETE /api/v1/adminapp/tenant/merchandise/{merchandise}`\n\nControlador: `App\\Domains\\FiestaFutbolInfantil\\Controllers\\MerchandiseController@destroy`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/merchandise/{{merchandise_id}}", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "merchandise", + "{{merchandise_id}}" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Desfile", + "item": [ + { + "name": "Get Entry", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/v1/adminapp/tenant/desfile/entries`\n\nControlador: `App\\Domains\\Desfile\\Controllers\\EntryController@show`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/desfile/entries", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "desfile", + "entries" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Update Entry", + "request": { + "method": "PUT", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `PUT /api/v1/adminapp/tenant/desfile/entries`\n\nControlador: `App\\Domains\\Desfile\\Controllers\\EntryController@update`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/desfile/entries", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "desfile", + "entries" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"rows\": [\n {\n \"type\": \"General\",\n \"sector\": \"A\",\n \"row\": 1,\n \"max_seat\": 20,\n \"price\": 25000\n }\n ]\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Replace Image Entry", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/v1/adminapp/tenant/desfile/entries/image`\n\nControlador: `App\\Domains\\Desfile\\Controllers\\EntryController@replaceImage`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/desfile/entries/image", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "desfile", + "entries", + "image" + ] + }, + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "is_enabled", + "value": "1", + "type": "text" + }, + { + "key": "image", + "type": "file", + "src": [] + } + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Update Image Entry", + "request": { + "method": "PATCH", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `PATCH /api/v1/adminapp/tenant/desfile/entries/image`\n\nControlador: `App\\Domains\\Desfile\\Controllers\\EntryController@updateImage`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/desfile/entries/image", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "desfile", + "entries", + "image" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"is_enabled\": true\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Delete Image Entry", + "request": { + "method": "DELETE", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `DELETE /api/v1/adminapp/tenant/desfile/entries/image`\n\nControlador: `App\\Domains\\Desfile\\Controllers\\EntryController@destroyImage`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/desfile/entries/image", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "desfile", + "entries", + "image" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Event", + "item": [ + { + "name": "Get Event", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/v1/adminapp/tenant/event`\n\nControlador: `App\\Domains\\Event\\Controllers\\AdminApp\\EventController@show`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/event", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "event" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Update Event", + "request": { + "method": "PUT", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `PUT /api/v1/adminapp/tenant/event`\n\nControlador: `App\\Domains\\Event\\Controllers\\AdminApp\\EventController@update`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/event", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "event" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"title\": \"Evento Demo\",\n \"location\": \"Buenos Aires\",\n \"dates\": [\n {\n \"date\": \"2026-12-01\",\n \"start_time\": \"18:00\",\n \"end_time\": \"23:00\"\n }\n ],\n \"social_media\": [\n {\n \"code\": \"instagram\",\n \"url\": \"https://instagram.com/example\",\n \"orden\": 0\n }\n ]\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Catalog", + "item": [ + { + "name": "List On Ticket Featured Group", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/v1/adminapp/tenant/featured-groups`\n\nControlador: `App\\Domains\\Catalog\\Controllers\\AdminApp\\OnTicketFeaturedGroupController@index`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/featured-groups", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "featured-groups" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Create On Ticket Featured Group", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/v1/adminapp/tenant/featured-groups`\n\nControlador: `App\\Domains\\Catalog\\Controllers\\AdminApp\\OnTicketFeaturedGroupController@store`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/featured-groups", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "featured-groups" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"category_name\": \"Destacados\",\n \"is_featured\": true\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Update On Ticket Featured Group", + "request": { + "method": "PUT", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `PUT /api/v1/adminapp/tenant/featured-groups/{featuredGroup}`\n\nControlador: `App\\Domains\\Catalog\\Controllers\\AdminApp\\OnTicketFeaturedGroupController@update`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/featured-groups/{{featured_group_id}}", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "featured-groups", + "{{featured_group_id}}" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"category_name\": \"Destacados\",\n \"is_featured\": true\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Sale", + "item": [ + { + "name": "List Sale", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/v1/adminapp/tenant/sales`\n\nControlador: `App\\Domains\\Sale\\Controllers\\AdminApp\\SaleController@index`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/sales?sort_by=date&sort_direction=desc&page=1&per_page=20", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "sales" + ], + "query": [ + { + "key": "q", + "value": "", + "disabled": true + }, + { + "key": "status", + "value": "confirmed", + "disabled": true + }, + { + "key": "sale_date", + "value": "2026-12-01", + "disabled": true + }, + { + "key": "sort_by", + "value": "date" + }, + { + "key": "sort_direction", + "value": "desc" + }, + { + "key": "page", + "value": "1" + }, + { + "key": "per_page", + "value": "20" + } + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "List Modifications Sale", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/v1/adminapp/tenant/sales/modifications`\n\nControlador: `App\\Domains\\Sale\\Controllers\\AdminApp\\SaleController@modifications`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/sales/modifications", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "sales", + "modifications" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Download Modifications PDF Sale", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/v1/adminapp/tenant/sales/modifications/pdf`\n\nControlador: `App\\Domains\\Sale\\Controllers\\AdminApp\\SaleController@downloadModificationsPdf`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/sales/modifications/pdf", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "sales", + "modifications", + "pdf" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Download PDF Sale", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/v1/adminapp/tenant/sales/pdf`\n\nControlador: `App\\Domains\\Sale\\Controllers\\AdminApp\\SaleController@downloadPdf`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/sales/pdf?sort_by=date&sort_direction=desc&page=1&per_page=20", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "sales", + "pdf" + ], + "query": [ + { + "key": "q", + "value": "", + "disabled": true + }, + { + "key": "status", + "value": "confirmed", + "disabled": true + }, + { + "key": "sale_date", + "value": "2026-12-01", + "disabled": true + }, + { + "key": "sort_by", + "value": "date" + }, + { + "key": "sort_direction", + "value": "desc" + }, + { + "key": "page", + "value": "1" + }, + { + "key": "per_page", + "value": "20" + } + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Get Sale", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/v1/adminapp/tenant/sales/{sale}`\n\nControlador: `App\\Domains\\Sale\\Controllers\\AdminApp\\SaleController@show`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/sales/{{sale_id}}", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "sales", + "{{sale_id}}" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Cancel Sale", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/v1/adminapp/tenant/sales/{sale}/cancel`\n\nControlador: `App\\Domains\\Sale\\Controllers\\AdminApp\\SaleController@cancel`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/sales/{{sale_id}}/cancel", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "sales", + "{{sale_id}}", + "cancel" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Confirm Sale", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/v1/adminapp/tenant/sales/{sale}/confirm`\n\nControlador: `App\\Domains\\Sale\\Controllers\\AdminApp\\SaleController@confirm`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/sales/{{sale_id}}/confirm", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "sales", + "{{sale_id}}", + "confirm" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "List Tickets Sale", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/v1/adminapp/tenant/sales/{sale}/tickets`\n\nControlador: `App\\Domains\\Sale\\Controllers\\AdminApp\\SaleController@tickets`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/sales/{{sale_id}}/tickets", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "sales", + "{{sale_id}}", + "tickets" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Staff", + "item": [ + { + "name": "List Admin App Staff", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/v1/adminapp/tenant/staff`\n\nControlador: `App\\Domains\\Staff\\Controllers\\AdminAppStaffController@index`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/staff", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "staff" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Create Admin App Staff", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/v1/adminapp/tenant/staff`\n\nControlador: `App\\Domains\\Staff\\Controllers\\AdminAppStaffController@store`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/staff", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "staff" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"nombre_apellido\": \"Operador Demo\",\n \"dni\": \"30123456\",\n \"email\": \"operador@example.com\",\n \"category_ids\": [\n 1\n ]\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Update Admin App Staff (PUT)", + "request": { + "method": "PUT", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `PUT /api/v1/adminapp/tenant/staff/{staff}`\n\nControlador: `App\\Domains\\Staff\\Controllers\\AdminAppStaffController@update`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/staff/{{staff_id}}", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "staff", + "{{staff_id}}" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"nombre_apellido\": \"Operador Demo\",\n \"dni\": \"30123456\",\n \"email\": \"operador@example.com\",\n \"category_ids\": [\n 1\n ]\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Update Admin App Staff (PATCH)", + "request": { + "method": "PATCH", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `PATCH /api/v1/adminapp/tenant/staff/{staff}`\n\nControlador: `App\\Domains\\Staff\\Controllers\\AdminAppStaffController@update`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/staff/{{staff_id}}", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "staff", + "{{staff_id}}" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"nombre_apellido\": \"Operador Demo\",\n \"dni\": \"30123456\",\n \"email\": \"operador@example.com\",\n \"category_ids\": [\n 1\n ]\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Delete Admin App Staff", + "request": { + "method": "DELETE", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `DELETE /api/v1/adminapp/tenant/staff/{staff}`\n\nControlador: `App\\Domains\\Staff\\Controllers\\AdminAppStaffController@destroy`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/staff/{{staff_id}}", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "staff", + "{{staff_id}}" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Tenant", + "item": [ + { + "name": "Get Website Extra", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/v1/adminapp/tenant/website-extras`\n\nControlador: `App\\Domains\\Tenant\\Controllers\\AdminApp\\WebsiteExtraController@show`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/website-extras", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "website-extras" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Get Extra Website Extra", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/v1/adminapp/tenant/website-extras/{websiteExtraCode}`\n\nControlador: `App\\Domains\\Tenant\\Controllers\\AdminApp\\WebsiteExtraController@showExtra`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/website-extras/{{website_extra_code}}", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "website-extras", + "{{website_extra_code}}" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Update Website Extra", + "request": { + "method": "PUT", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `PUT /api/v1/adminapp/tenant/website-extras/{websiteExtraCode}`\n\nControlador: `App\\Domains\\Tenant\\Controllers\\AdminApp\\WebsiteExtraController@update`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/website-extras/{{website_extra_code}}", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "website-extras", + "{{website_extra_code}}" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"enabled\": true,\n \"content\": {\n \"title\": \"Contenido demo\"\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Toggle Website Extra", + "request": { + "method": "PATCH", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `PATCH /api/v1/adminapp/tenant/website-extras/{websiteExtraCode}/toggle`\n\nControlador: `App\\Domains\\Tenant\\Controllers\\AdminApp\\WebsiteExtraController@toggle`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/adminapp/tenant/website-extras/{{website_extra_code}}/toggle", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "adminapp", + "tenant", + "website-extras", + "{{website_extra_code}}", + "toggle" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"enabled\": true\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{admin_token}}", + "type": "string" + } + ] + } + }, + "response": [] + } + ] + } + ] }, { - "name": "Delete Tenant", - "request": { - "method": "DELETE", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_id}}", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_id}}" - ] - } - }, - "response": [] + "name": "Scanner API", + "description": "Operaciones de la aplicación de escaneo. Ejecutá Login primero para completar `scanner_token`.", + "item": [ + { + "name": "Bootstrap", + "item": [ + { + "name": "Scanner Bootstrap", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/v1/scanner/bootstrap/{dominio}`\n\nControlador: `App\\Domains\\Bootstrap\\Controllers\\ScannerBootstrapController`", + "url": { + "raw": "{{base_url}}/api/v1/scanner/bootstrap/{{tenant_domain}}?path=/", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "scanner", + "bootstrap", + "{{tenant_domain}}" + ], + "query": [ + { + "key": "path", + "value": "/" + } + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Auth", + "item": [ + { + "name": "Scanner Login", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/v1/scanner/login`\n\nControlador: `App\\Domains\\Auth\\Controllers\\ScannerLoginController`", + "url": { + "raw": "{{base_url}}/api/v1/scanner/login", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "scanner", + "login" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"email\": \"{{scanner_email}}\",\n \"password\": \"{{scanner_password}}\"\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [], + "event": [ + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "if (pm.response.code >= 200 && pm.response.code < 300) {", + " const payload = pm.response.json();", + " if (payload.token) pm.collectionVariables.set('scanner_token', payload.token);", + "}" + ] + } + } + ] + }, + { + "name": "Scanner Me", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/v1/scanner/me`\n\nControlador: `App\\Domains\\Auth\\Controllers\\ScannerMeController`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/scanner/me", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "scanner", + "me" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{scanner_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Reset Password", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/v1/scanner/password/reset`\n\nControlador: `App\\Domains\\Auth\\Controllers\\ResetPasswordController`", + "url": { + "raw": "{{base_url}}/api/v1/scanner/password/reset", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "scanner", + "password", + "reset" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"email\": \"{{scanner_email}}\",\n \"codigo\": \"{{reset_code}}\",\n \"password\": \"{{scanner_password}}\",\n \"password_confirmation\": \"{{scanner_password}}\"\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [] + }, + { + "name": "Create Scanner Reset Password Attempt", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/v1/scanner/password/reset-attempts`\n\nControlador: `App\\Domains\\Auth\\Controllers\\CreateScannerResetPasswordAttemptController`", + "url": { + "raw": "{{base_url}}/api/v1/scanner/password/reset-attempts", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "scanner", + "password", + "reset-attempts" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"email\": \"{{scanner_email}}\"\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [] + }, + { + "name": "Validate Reset Password Attempt", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/v1/scanner/password/reset-attempts/validate`\n\nControlador: `App\\Domains\\Auth\\Controllers\\ValidateResetPasswordAttemptController`", + "url": { + "raw": "{{base_url}}/api/v1/scanner/password/reset-attempts/validate", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "scanner", + "password", + "reset-attempts", + "validate" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"email\": \"{{scanner_email}}\",\n \"codigo\": \"{{reset_code}}\"\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [] + } + ] + }, + { + "name": "Ticket", + "item": [ + { + "name": "List Ticket", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/v1/scanner/tickets`\n\nControlador: `App\\Domains\\Ticket\\Controllers\\Scanner\\TicketController@index`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/scanner/tickets?page=1&per_page=20", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "scanner", + "tickets" + ], + "query": [ + { + "key": "q", + "value": "", + "disabled": true + }, + { + "key": "page", + "value": "1" + }, + { + "key": "per_page", + "value": "20" + } + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{scanner_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Get Ticket", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `GET /api/v1/scanner/tickets/{ticketUuid}`\n\nControlador: `App\\Domains\\Ticket\\Controllers\\Scanner\\TicketController@show`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/scanner/tickets/{{ticket_uuid}}", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "scanner", + "tickets", + "{{ticket_uuid}}" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{scanner_token}}", + "type": "string" + } + ] + } + }, + "response": [] + }, + { + "name": "Scan Ticket", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/v1/scanner/tickets/{ticketUuid}/scan`\n\nControlador: `App\\Domains\\Ticket\\Controllers\\Scanner\\TicketController@scan`\n\nRequiere autenticación Sanctum.", + "url": { + "raw": "{{base_url}}/api/v1/scanner/tickets/{{ticket_uuid}}/scan", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "v1", + "scanner", + "tickets", + "{{ticket_uuid}}", + "scan" + ] + }, + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{scanner_token}}", + "type": "string" + } + ] + } + }, + "response": [] + } + ] + } + ] + }, + { + "name": "Webhooks", + "description": "Entradas públicas para notificaciones de proveedores externos.", + "item": [ + { + "name": "Integration", + "item": [ + { + "name": "Receive Telepagos Webhook", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "description": "Ruta Laravel: `POST /api/webhooks/telepagos/{client}`\n\nControlador: `App\\Domains\\Integration\\Controllers\\TelepagosWebhookController@handle`", + "url": { + "raw": "{{base_url}}/api/webhooks/telepagos/{{client_id}}", + "host": [ + "{{base_url}}" + ], + "path": [ + "api", + "webhooks", + "telepagos", + "{{client_id}}" + ] + }, + "body": { + "mode": "raw", + "raw": "{\n \"id\": \"payment-id-demo\"\n}", + "options": { + "raw": { + "language": "json" + } + } + } + }, + "response": [] + } + ] + } + ] } - ] - }, - { - "name": "Catalog", - "item": [ + ], + "variable": [ { - "name": "Get Catalog", - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": "{{base_url}}/api/tenants/{{tenant_codigo}}/catalog" - }, - "response": [] + "key": "base_url", + "value": "http://localhost:8000", + "type": "string" }, { - "name": "List Featured Group Items", - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": "{{base_url}}/api/tenants/{{tenant_codigo}}/catalog/featured-groups/{{featured_group_id}}/items?page=1", - "description": "Returns one page of items for a featured catalog group." - }, - "response": [] + "key": "token", + "value": "", + "type": "string" }, { - "name": "Show Catalog Item", - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": "{{base_url}}/api/tenants/{{tenant_codigo}}/catalog-items/{{catalog_item_id}}?variant_id={{variant_id}}", - "description": "variant_id is optional; remove the query parameter when the item has no selected variant." - }, - "response": [] + "key": "admin_token", + "value": "", + "type": "string" }, { - "name": "Create Standard Catalog Item", - "request": { - "method": "POST", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - }, - { - "key": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "url": "{{base_url}}/api/tenants/{{tenant_codigo}}/catalog-items", - "body": { - "mode": "raw", - "raw": "{\n \"type\": \"standard\",\n \"category_id\": 1,\n \"brand_id\": 1,\n \"slug\": \"entrada-general\",\n \"nombre\": \"Entrada general\",\n \"descripcion\": \"Entrada general de ejemplo\",\n \"precio\": 15000,\n \"inventory_policy\": \"tracked\",\n \"has_tickets\": true,\n \"minimum_use_date\": \"2026-08-01\",\n \"maximum_use_date\": \"2026-08-31\",\n \"real_stock\": 100,\n \"attribute_codes\": [],\n \"images\": [],\n \"variants\": []\n}", - "options": { - "raw": { - "language": "json" - } - } - } - }, - "response": [] + "key": "scanner_token", + "value": "", + "type": "string" + }, + { + "key": "user_email", + "value": "usuario@example.com", + "type": "string" + }, + { + "key": "user_password", + "value": "Password!123", + "type": "string" + }, + { + "key": "admin_email", + "value": "admin@example.com", + "type": "string" + }, + { + "key": "admin_password", + "value": "Password!123", + "type": "string" + }, + { + "key": "scanner_email", + "value": "scanner@example.com", + "type": "string" + }, + { + "key": "scanner_password", + "value": "Password!123", + "type": "string" + }, + { + "key": "tenant_code", + "value": "demo", + "type": "string" + }, + { + "key": "tenant_id", + "value": "1", + "type": "string" + }, + { + "key": "tenant_domain", + "value": "demo.test", + "type": "string" + }, + { + "key": "client_id", + "value": "1", + "type": "string" + }, + { + "key": "integration_id", + "value": "1", + "type": "string" + }, + { + "key": "integration_code", + "value": "telepagos", + "type": "string" + }, + { + "key": "menu_id", + "value": "1", + "type": "string" + }, + { + "key": "menu_code", + "value": "demo", + "type": "string" + }, + { + "key": "catalog_item_id", + "value": "1", + "type": "string" + }, + { + "key": "variant_id", + "value": "1", + "type": "string" + }, + { + "key": "category_id", + "value": "1", + "type": "string" + }, + { + "key": "featured_group_id", + "value": "1", + "type": "string" + }, + { + "key": "cart_id", + "value": "1", + "type": "string" + }, + { + "key": "cart_item_id", + "value": "1", + "type": "string" + }, + { + "key": "purchase_id", + "value": "1", + "type": "string" + }, + { + "key": "purchase_item_id", + "value": "1", + "type": "string" + }, + { + "key": "sale_id", + "value": "1", + "type": "string" + }, + { + "key": "staff_id", + "value": "1", + "type": "string" + }, + { + "key": "website_extra_code", + "value": "hero", + "type": "string" + }, + { + "key": "accommodation_id", + "value": "1", + "type": "string" + }, + { + "key": "entry_id", + "value": "1", + "type": "string" + }, + { + "key": "food_id", + "value": "1", + "type": "string" + }, + { + "key": "merchandise_id", + "value": "1", + "type": "string" + }, + { + "key": "ticket_uuid", + "value": "00000000-0000-0000-0000-000000000000", + "type": "string" + }, + { + "key": "oauth_code", + "value": "00000000-0000-0000-0000-000000000000", + "type": "string" + }, + { + "key": "reset_code", + "value": "1234", + "type": "string" + }, + { + "key": "s3_path", + "value": "postman/test-file.png", + "type": "string" } - ] - }, - { - "name": "Cart", - "item": [ - { - "name": "Show Cart", - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": "{{base_url}}/api/tenants/{{tenant_codigo}}/cart" - }, - "response": [] - }, - { - "name": "Add Cart Item", - "request": { - "method": "POST", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - }, - { - "key": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "url": "{{base_url}}/api/tenants/{{tenant_codigo}}/cart/items", - "description": "variant_id is optional and may be removed for catalog items without variants.", - "body": { - "mode": "raw", - "raw": "{\n \"catalog_item_id\": {{catalog_item_id}},\n \"variant_id\": {{variant_id}},\n \"cantidad\": 1\n}", - "options": { - "raw": { - "language": "json" - } - } - } - }, - "response": [] - }, - { - "name": "Update Cart Item Quantity", - "request": { - "method": "PATCH", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - }, - { - "key": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "url": "{{base_url}}/api/tenants/{{tenant_codigo}}/cart/items/{{cart_item_id}}", - "body": { - "mode": "raw", - "raw": "{\n \"cantidad\": 2\n}", - "options": { - "raw": { - "language": "json" - } - } - } - }, - "response": [] - }, - { - "name": "Remove Cart Item", - "request": { - "method": "DELETE", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": "{{base_url}}/api/tenants/{{tenant_codigo}}/cart/items/{{cart_item_id}}" - }, - "response": [] - } - ] - }, - { - "name": "Auth", - "item": [ - { - "name": "Register User", - "request": { - "method": "POST", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - }, - { - "key": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"nombre_apellido\": \"Ada Lovelace\",\n \"email\": \"ada@example.com\",\n \"password\": \"secret123\",\n \"password_confirmation\": \"secret123\"\n}" - }, - "url": { - "raw": "{{base_url}}/api/register", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "register" - ] - } - }, - "response": [] - }, - { - "name": "Login User", - "event": [ - { - "listen": "test", - "script": { - "type": "text/javascript", - "exec": [ - "const response = pm.response.json();", - "", - "if (response.token) {", - " pm.collectionVariables.set('auth_token', response.token);", - " console.log('auth_token saved to collection variables');", - "} else {", - " console.warn('Login response does not contain token');", - "}" - ] - } - } - ], - "request": { - "method": "POST", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - }, - { - "key": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"email\": \"ada@example.com\",\n \"password\": \"secret123\"\n}" - }, - "url": { - "raw": "{{base_url}}/api/login", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "login" - ] - } - }, - "response": [] - }, - { - "name": "Logout User", - "request": { - "method": "POST", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": { - "raw": "{{base_url}}/api/logout", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "logout" - ] - } - }, - "response": [] - }, - { - "name": "Me", - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": { - "raw": "{{base_url}}/api/me", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "me" - ] - } - }, - "response": [] - }, - { - "name": "Update Profile", - "request": { - "method": "PUT", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - }, - { - "key": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "url": "{{base_url}}/api/me", - "body": { - "mode": "raw", - "raw": "{\n \"nombre_apellido\": \"Ada Lovelace\",\n \"email\": \"ada@example.com\",\n \"dni\": \"12345678\",\n \"telefono\": \"+54 9 341 555-1234\"\n}", - "options": { - "raw": { - "language": "json" - } - } - } - }, - "response": [] - } - ] - }, - { - "name": "Purchases", - "item": [ - { - "name": "List Purchases", - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/compras", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "compras" - ] - } - }, - "response": [] - }, - { - "name": "Create Purchase", - "request": { - "method": "POST", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - }, - { - "key": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"cart_id\": {{cart_id}},\n \"dni\": \"12345678\",\n \"telefono\": \"+54 9 341 555-4321\",\n \"nombre_apellido\": \"Juan Perez\",\n \"email\": \"juan.perez@example.com\"\n}" - }, - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/compras", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "compras" - ] - } - }, - "response": [] - }, - { - "name": "Show Purchase", - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": { - "raw": "{{base_url}}/api/tenants/{{tenant_codigo}}/compras/{{compra_id}}", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "tenants", - "{{tenant_codigo}}", - "compras", - "{{compra_id}}" - ] - } - }, - "response": [] - }, - { - "name": "Create QR Payment Intent", - "request": { - "method": "POST", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - }, - { - "key": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "url": "{{base_url}}/api/tenants/{{tenant_codigo}}/compras/{{compra_id}}/payment-intent", - "body": { - "mode": "raw", - "raw": "{\n \"method\": \"qr\"\n}", - "options": { - "raw": { - "language": "json" - } - } - } - }, - "response": [] - }, - { - "name": "Create Transfer Payment Intent", - "request": { - "method": "POST", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - }, - { - "key": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "url": "{{base_url}}/api/tenants/{{tenant_codigo}}/compras/{{compra_id}}/payment-intent", - "body": { - "mode": "raw", - "raw": "{\n \"method\": \"transfer\",\n \"transfer_payer_dni\": \"12345678\"\n}", - "options": { - "raw": { - "language": "json" - } - } - } - }, - "response": [] - }, - { - "name": "Complete Purchase", - "request": { - "method": "POST", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": "{{base_url}}/api/tenants/{{tenant_codigo}}/compras/{{compra_id}}/complete" - }, - "response": [] - } - ] - }, - { - "name": "Tickets", - "item": [ - { - "name": "List My Tickets", - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": "{{base_url}}/api/tenants/{{tenant_codigo}}/tickets", - "description": "Requires authentication and returns only the current user tickets for this tenant." - }, - "response": [] - } - ] - }, - { - "name": "Menus", - "item": [ - { - "name": "List Menus", - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": "{{base_url}}/api/menues" - }, - "response": [] - }, - { - "name": "Create Menu", - "request": { - "method": "POST", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - }, - { - "key": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "url": "{{base_url}}/api/menues", - "body": { - "mode": "raw", - "raw": "{\n \"code\": \"catalog\",\n \"route\": \"/catalog\"\n}", - "options": { - "raw": { - "language": "json" - } - } - } - }, - "response": [] - }, - { - "name": "Show Menu", - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": "{{base_url}}/api/menues/{{menu_id}}" - }, - "response": [] - }, - { - "name": "Update Menu", - "request": { - "method": "PUT", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - }, - { - "key": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "url": "{{base_url}}/api/menues/{{menu_id}}", - "body": { - "mode": "raw", - "raw": "{\n \"code\": \"catalog\",\n \"route\": \"/catalogo\"\n}", - "options": { - "raw": { - "language": "json" - } - } - } - }, - "response": [] - }, - { - "name": "Delete Menu", - "request": { - "method": "DELETE", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": "{{base_url}}/api/menues/{{menu_id}}" - }, - "response": [] - } - ] - }, - { - "name": "Integrations", - "item": [ - { - "name": "List Integrations", - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": { - "raw": "{{base_url}}/api/integrations", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "integrations" - ] - } - }, - "response": [] - }, - { - "name": "Create Integration", - "request": { - "method": "POST", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - }, - { - "key": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"integration_code\": \"mercadopago\",\n \"name\": \"Mercado Pago\",\n \"url\": \"https://api.mercadopago.com\",\n \"integration_data_schema\": {\n \"access_token\": \"required|string\",\n \"public_key\": \"nullable|string\"\n }\n}" - }, - "url": { - "raw": "{{base_url}}/api/integrations", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "integrations" - ] - } - }, - "response": [] - }, - { - "name": "Show Integration", - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": { - "raw": "{{base_url}}/api/integrations/{{integration_id}}", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "integrations", - "{{integration_id}}" - ] - } - }, - "response": [] - }, - { - "name": "Update Integration", - "request": { - "method": "PUT", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - }, - { - "key": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"integration_code\": \"mercadopago\",\n \"name\": \"Mercado Pago Updated\",\n \"url\": \"https://api.mercadopago.com\",\n \"integration_data_schema\": {\n \"access_token\": \"required|string\",\n \"public_key\": \"nullable|string\"\n }\n}" - }, - "url": { - "raw": "{{base_url}}/api/integrations/{{integration_id}}", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "integrations", - "{{integration_id}}" - ] - } - }, - "response": [] - }, - { - "name": "Delete Integration", - "request": { - "method": "DELETE", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": { - "raw": "{{base_url}}/api/integrations/{{integration_id}}", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "integrations", - "{{integration_id}}" - ] - } - }, - "response": [] - } - ] - }, - { - "name": "Tenant Integrations", - "item": [ - { - "name": "List Tenant Integrations", - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": { - "raw": "{{base_url}}/api/{{tenant_codigo}}/integrations", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "{{tenant_codigo}}", - "integrations" - ] - } - }, - "response": [] - }, - { - "name": "Show Tenant Integration", - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": { - "raw": "{{base_url}}/api/{{tenant_codigo}}/integrations/{{integration_code}}", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "{{tenant_codigo}}", - "integrations", - "{{integration_code}}" - ] - } - }, - "response": [] - }, - { - "name": "Configure Tenant Integration", - "request": { - "method": "POST", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - }, - { - "key": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"integration_data\": {\n \"access_token\": \"APP_USR-demo-token\",\n \"public_key\": \"APP_PUBLIC-demo-key\"\n }\n}" - }, - "url": { - "raw": "{{base_url}}/api/{{tenant_codigo}}/integrations/{{integration_code}}", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "{{tenant_codigo}}", - "integrations", - "{{integration_code}}" - ] - } - }, - "response": [] - } - ] - }, - { - "name": "Webhooks", - "item": [ - { - "name": "Telepagos Cash-in Notification", - "request": { - "method": "POST", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - }, - { - "key": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "url": "{{base_url}}/api/webhooks/telepagos/{{tenant_codigo}}", - "description": "Receives a Telepagos cash-in identifier and updates the related purchase payment.", - "body": { - "mode": "raw", - "raw": "{\n \"id\": \"{{telepagos_cashin_id}}\"\n}", - "options": { - "raw": { - "language": "json" - } - } - } - }, - "response": [] - } - ] - }, - { - "name": "Storage Test", - "item": [ - { - "name": "Upload S3 File (Base64)", - "request": { - "method": "POST", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - }, - { - "key": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "body": { - "mode": "raw", - "raw": "{\n \"file_base64\": \"data:text/plain;base64,SG9sYSBTaG9wSXQ=\",\n \"path\": \"tests/postman\",\n \"expires_in_minutes\": 10\n}" - }, - "url": { - "raw": "{{base_url}}/api/storage-test/s3/upload", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "storage-test", - "s3", - "upload" - ] - } - }, - "response": [] - }, - { - "name": "Upload S3 File (Form Data)", - "request": { - "method": "POST", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "body": { - "mode": "formdata", - "formdata": [ - { - "key": "file", - "type": "file", - "src": [] - }, - { - "key": "path", - "value": "tests/postman", - "type": "text" - }, - { - "key": "expires_in_minutes", - "value": "10", - "type": "text" - } - ] - }, - "url": { - "raw": "{{base_url}}/api/storage-test/s3/upload", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "storage-test", - "s3", - "upload" - ] - } - }, - "response": [] - }, - { - "name": "Generate S3 Temporary URL", - "request": { - "method": "GET", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - } - ], - "url": { - "raw": "{{base_url}}/api/storage-test/s3/temporary-url?path=tests/postman/example.txt&expires_in_minutes=10", - "host": [ - "{{base_url}}" - ], - "path": [ - "api", - "storage-test", - "s3", - "temporary-url" - ], - "query": [ - { - "key": "path", - "value": "tests/postman/example.txt" - }, - { - "key": "expires_in_minutes", - "value": "10" - } - ] - } - }, - "response": [] - } - ] - }, - { - "name": "Mail Test", - "item": [ - { - "name": "Send Test Email", - "request": { - "method": "POST", - "header": [ - { - "key": "Accept", - "value": "application/json", - "type": "text" - }, - { - "key": "Content-Type", - "value": "application/json", - "type": "text" - } - ], - "url": "{{base_url}}/api/mail-test/send", - "description": "Sends a real message through the mailer configured in the backend environment.", - "body": { - "mode": "raw", - "raw": "{\n \"to\": \"{{test_email}}\",\n \"subject\": \"Prueba de correo de Shopit\",\n \"message\": \"Este es un correo de prueba enviado desde Postman.\"\n}", - "options": { - "raw": { - "language": "json" - } - } - } - }, - "response": [] - } - ] - } - ], - "event": [ - { - "listen": "prerequest", - "script": { - "type": "text/javascript", - "exec": [ - "const authToken = pm.collectionVariables.get('auth_token');", - "", - "if (authToken) {", - " pm.request.headers.upsert({", - " key: 'Authorization',", - " value: `Bearer ${authToken}`,", - " });", - "}" - ] - } - }, - { - "listen": "test", - "script": { - "type": "text/javascript", - "exec": [ - "" - ] - } - } - ], - "variable": [ - { - "key": "base_url", - "value": "http://127.0.0.1:8000", - "type": "string" - }, - { - "key": "auth_token", - "value": "", - "type": "string" - }, - { - "key": "tenant_codigo", - "value": "sonder", - "type": "string" - }, - { - "key": "tenant_domain", - "value": "localhost", - "type": "string" - }, - { - "key": "tenant_path", - "value": "/", - "type": "string" - }, - { - "key": "tenant_id", - "value": "1", - "type": "string" - }, - { - "key": "catalog_item_id", - "value": "1", - "type": "string" - }, - { - "key": "featured_group_id", - "value": "1", - "type": "string" - }, - { - "key": "variant_id", - "value": "1", - "type": "string" - }, - { - "key": "cart_item_id", - "value": "1", - "type": "string" - }, - { - "key": "cart_id", - "value": "1", - "type": "string" - }, - { - "key": "compra_id", - "value": "1", - "type": "string" - }, - { - "key": "integration_id", - "value": "1", - "type": "string" - }, - { - "key": "integration_code", - "value": "mercadopago", - "type": "string" - }, - { - "key": "menu_id", - "value": "1", - "type": "string" - }, - { - "key": "telepagos_cashin_id", - "value": "7000", - "type": "string" - }, - { - "key": "test_email", - "value": "destinatario@example.com", - "type": "string" - } - ] + ] } diff --git a/app/Domains/Tenant/Models/Tenant.php b/app/Domains/Tenant/Models/Tenant.php index 504e3e7..96eb515 100644 --- a/app/Domains/Tenant/Models/Tenant.php +++ b/app/Domains/Tenant/Models/Tenant.php @@ -43,6 +43,7 @@ use Illuminate\Support\Facades\Schema; 'display_categories', 'display_seach_bar', 'display_cart', + 'cart_editing_enabled', 'scanner_category_validation_enabled', 'event_title', 'event_location', @@ -59,6 +60,7 @@ class Tenant extends Model 'display_categories' => true, 'display_seach_bar' => true, 'display_cart' => true, + 'cart_editing_enabled' => true, 'scanner_category_validation_enabled' => true, ]; @@ -108,6 +110,7 @@ class Tenant extends Model 'display_categories' => 'boolean', 'display_seach_bar' => 'boolean', 'display_cart' => 'boolean', + 'cart_editing_enabled' => 'boolean', 'scanner_category_validation_enabled' => 'boolean', ]; } diff --git a/app/Domains/Tenant/Requests/StoreTenantRequest.php b/app/Domains/Tenant/Requests/StoreTenantRequest.php index ec158da..35f6a7c 100644 --- a/app/Domains/Tenant/Requests/StoreTenantRequest.php +++ b/app/Domains/Tenant/Requests/StoreTenantRequest.php @@ -83,6 +83,7 @@ class StoreTenantRequest extends FormRequest 'display_categories' => ['sometimes', 'boolean'], 'display_seach_bar' => ['sometimes', 'boolean'], 'display_cart' => ['sometimes', 'boolean'], + 'cart_editing_enabled' => ['sometimes', 'boolean'], 'scanner_category_validation_enabled' => ['sometimes', 'boolean'], 'website_type_code' => [ 'required_with:extras', diff --git a/app/Domains/Tenant/Requests/UpdateTenantRequest.php b/app/Domains/Tenant/Requests/UpdateTenantRequest.php index 6061493..1b59861 100644 --- a/app/Domains/Tenant/Requests/UpdateTenantRequest.php +++ b/app/Domains/Tenant/Requests/UpdateTenantRequest.php @@ -93,6 +93,7 @@ class UpdateTenantRequest extends FormRequest 'display_categories' => ['sometimes', 'boolean'], 'display_seach_bar' => ['sometimes', 'boolean'], 'display_cart' => ['sometimes', 'boolean'], + 'cart_editing_enabled' => ['sometimes', 'boolean'], 'scanner_category_validation_enabled' => ['sometimes', 'boolean'], ]; } diff --git a/app/Domains/Tenant/Resources/TenantResource.php b/app/Domains/Tenant/Resources/TenantResource.php index b26428b..5a86700 100644 --- a/app/Domains/Tenant/Resources/TenantResource.php +++ b/app/Domains/Tenant/Resources/TenantResource.php @@ -74,6 +74,7 @@ class TenantResource extends JsonResource 'display_categories' => $this->display_categories, 'display_seach_bar' => $this->display_seach_bar, 'display_cart' => $this->display_cart, + 'cart_editing_enabled' => $this->cart_editing_enabled, 'scanner_category_validation_enabled' => $this->scanner_category_validation_enabled, 'social_media' => $this->whenLoaded( 'socialMedia', diff --git a/database/migrations/2026_08_18_040000_create_clients_and_assign_tenants.php b/database/migrations/2026_08_18_040000_create_clients_and_assign_tenants.php index 94f623f..69269dc 100644 --- a/database/migrations/2026_08_18_040000_create_clients_and_assign_tenants.php +++ b/database/migrations/2026_08_18_040000_create_clients_and_assign_tenants.php @@ -9,27 +9,35 @@ return new class extends Migration { public function up(): void { - Schema::create('clients', function (Blueprint $table): void { - $table->id(); - $table->string('code')->unique(); - $table->string('name'); - $table->timestamps(); - }); + if (! Schema::hasTable('clients')) { + Schema::create('clients', function (Blueprint $table): void { + $table->id(); + $table->string('code')->unique(); + $table->string('name'); + $table->timestamps(); + }); + } - Schema::table('tenants', function (Blueprint $table): void { - $table->foreignId('client_id')->nullable()->after('id')->constrained('clients')->restrictOnDelete(); - }); + if (! Schema::hasColumn('tenants', 'client_id')) { + Schema::table('tenants', function (Blueprint $table): void { + $table->foreignId('client_id')->nullable()->after('id')->constrained('clients')->restrictOnDelete(); + }); + } DB::table('tenants') ->select(['id', 'codigo', 'nombre', 'created_at', 'updated_at']) ->orderBy('id') ->each(function (object $tenant): void { - $clientId = DB::table('clients')->insertGetId([ - 'code' => $tenant->codigo, - 'name' => $tenant->nombre, - 'created_at' => $tenant->created_at ?? now(), - 'updated_at' => $tenant->updated_at ?? now(), - ]); + $clientId = DB::table('clients')->where('code', $tenant->codigo)->value('id'); + + if ($clientId === null) { + $clientId = DB::table('clients')->insertGetId([ + 'code' => $tenant->codigo, + 'name' => $tenant->nombre, + 'created_at' => $tenant->created_at ?? now(), + 'updated_at' => $tenant->updated_at ?? now(), + ]); + } DB::table('tenants')->where('id', $tenant->id)->update(['client_id' => $clientId]); }); diff --git a/database/migrations/2026_08_18_060000_add_cart_editing_enabled_to_tenants_table.php b/database/migrations/2026_08_18_060000_add_cart_editing_enabled_to_tenants_table.php new file mode 100644 index 0000000..5c1cd4b --- /dev/null +++ b/database/migrations/2026_08_18_060000_add_cart_editing_enabled_to_tenants_table.php @@ -0,0 +1,29 @@ +boolean('cart_editing_enabled')->default(true)->after('display_cart'); + }); + + DB::table('tenants') + ->where('codigo', self::DESFILE_TENANT_CODE) + ->update(['cart_editing_enabled' => false]); + } + + public function down(): void + { + Schema::table('tenants', function (Blueprint $table): void { + $table->dropColumn('cart_editing_enabled'); + }); + } +}; diff --git a/database/seeders/DesfilePuraTendenciaSeeder.php b/database/seeders/DesfilePuraTendenciaSeeder.php index 553789c..15c2542 100644 --- a/database/seeders/DesfilePuraTendenciaSeeder.php +++ b/database/seeders/DesfilePuraTendenciaSeeder.php @@ -40,7 +40,10 @@ class DesfilePuraTendenciaSeeder extends Seeder $tenant = Tenant::query()->where('codigo', self::TENANT_CODE)->first(); if ($tenant) { - $tenant->update(['client_id' => $client->id]); + $tenant->update([ + 'client_id' => $client->id, + 'cart_editing_enabled' => false, + ]); return; } @@ -72,6 +75,7 @@ class DesfilePuraTendenciaSeeder extends Seeder 'display_categories' => false, 'display_seach_bar' => false, 'display_cart' => true, + 'cart_editing_enabled' => false, 'scanner_category_validation_enabled' => false, 'website_type_code' => 'onticket', 'header_logo' => $this->uploadedImage( diff --git a/postman/generate-shopit-collection.php b/postman/generate-shopit-collection.php new file mode 100644 index 0000000..bee6476 --- /dev/null +++ b/postman/generate-shopit-collection.php @@ -0,0 +1,451 @@ + */ +function jsonBody(array $payload): array +{ + $raw = json_encode($payload, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); + $raw = preg_replace('/"\{\{([a-z_]+_id)\}\}"/', '{{$1}}', $raw); + + return [ + 'mode' => 'raw', + 'raw' => $raw, + 'options' => ['raw' => ['language' => 'json']], + ]; +} + +/** @param array $fields + * @return array + */ +function formDataBody(array $fields, array $fileFields = []): array +{ + $formData = []; + + foreach ($fields as $key => $value) { + $formData[] = ['key' => $key, 'value' => $value, 'type' => 'text']; + } + + foreach ($fileFields as $key) { + $formData[] = ['key' => $key, 'type' => 'file', 'src' => []]; + } + + return ['mode' => 'formdata', 'formdata' => $formData]; +} + +/** @return array|null */ +function bodyFor(string $method, string $uri): ?array +{ + $key = $method.' '.$uri; + + $exact = [ + 'POST api/auth/google/exchange' => ['oauth_code' => '{{oauth_code}}', 'tenant_codigo' => '{{tenant_code}}'], + 'POST api/register' => ['tenant_codigo' => '{{tenant_code}}', 'nombre_apellido' => 'Usuario Demo', 'email' => '{{user_email}}', 'password' => '{{user_password}}', 'password_confirmation' => '{{user_password}}', 'dni' => '30123456', 'telefono' => '+5491112345678'], + 'POST api/login' => ['email' => '{{user_email}}', 'password' => '{{user_password}}', 'tenant_codigo' => '{{tenant_code}}'], + 'PUT api/me' => ['nombre_apellido' => 'Usuario Demo Actualizado', 'email' => '{{user_email}}', 'dni' => '30123456', 'telefono' => '+5491112345678'], + 'POST api/password/reset-attempts' => ['tenant_codigo' => '{{tenant_code}}', 'email' => '{{user_email}}'], + 'POST api/password/reset-attempts/validate' => ['email' => '{{user_email}}', 'codigo' => '{{reset_code}}'], + 'POST api/password/reset' => ['email' => '{{user_email}}', 'codigo' => '{{reset_code}}', 'password' => '{{user_password}}', 'password_confirmation' => '{{user_password}}'], + 'POST api/clients' => ['code' => 'cliente-demo', 'name' => 'Cliente Demo'], + 'PUT api/clients/{client}' => ['code' => 'cliente-demo', 'name' => 'Cliente Demo Actualizado'], + 'PATCH api/clients/{client}' => ['name' => 'Cliente Demo Actualizado'], + 'POST api/integrations' => ['integration_code' => 'telepagos', 'name' => 'Telepagos', 'url' => 'https://api.example.com', 'integration_data_schema' => ['api_key' => ['required', 'string']], 'requires_client_configuration' => true], + 'PUT api/integrations/{integration}' => ['name' => 'Telepagos', 'url' => 'https://api.example.com', 'requires_client_configuration' => true], + 'PUT api/clients/{client}/integrations/{integration_code}' => ['integration_data' => ['api_key' => 'replace-me']], + 'POST api/menues' => ['code' => 'demo', 'label' => 'Demo', 'parent_menu_code' => null, 'content_type' => 'static', 'static_content_schema' => ['title' => ['required', 'string']], 'route' => '/demo'], + 'PUT api/menues/{menue}' => ['label' => 'Demo actualizado', 'route' => '/demo'], + 'PATCH api/menues/{menue}' => ['label' => 'Demo actualizado'], + 'POST api/{tenant_code}/menues/{menu_code}' => ['static_content' => ['title' => 'Contenido demo']], + 'POST api/webhooks/telepagos/{client}' => ['id' => 'payment-id-demo'], + 'POST api/{tenant_code}/mail-test/send' => ['to' => 'destinatario@example.com', 'subject' => 'Prueba ShopIt', 'message' => 'Correo de prueba enviado desde Postman.'], + 'POST api/tenants/{tenant:codigo}/cart/items' => ['catalog_item_id' => '{{catalog_item_id}}', 'variant_id' => '{{variant_id}}', 'cantidad' => 1], + 'PATCH api/tenants/{tenant:codigo}/cart/items/{cartItem}' => ['cantidad' => 2, 'variant_id' => '{{variant_id}}'], + 'POST api/tenants/{tenant:codigo}/catalog-items/{catalogItem}/variant-options' => ['selected_values' => ['color' => 'azul'], 'cart_item_id' => '{{cart_item_id}}'], + 'POST api/tenants/{tenant:codigo}/compras/start-checkout' => ['cart_id' => '{{cart_id}}'], + 'PATCH api/tenants/{tenant:codigo}/compras/{compra}/customer-data' => ['dni' => '30123456', 'telefono' => '+5491112345678', 'nombre_apellido' => 'Usuario Demo', 'email' => '{{user_email}}'], + 'PATCH api/tenants/{tenant:codigo}/compras/{compra}/items/{item}' => ['quantity' => 2], + 'POST api/tenants/{tenant:codigo}/compras/{compra}/payment-intent' => ['method' => 'transfer', 'transfer_payer_dni' => '30123456'], + 'POST api/tenants/{tenant:codigo}/tickets/pdf' => ['ticket_ids' => [1]], + 'POST api/v1/adminapp/login' => ['email' => '{{admin_email}}', 'password' => '{{admin_password}}'], + 'POST api/v1/adminapp/password/reset-attempts' => ['email' => '{{admin_email}}'], + 'POST api/v1/adminapp/password/reset-attempts/validate' => ['email' => '{{admin_email}}', 'codigo' => '{{reset_code}}'], + 'POST api/v1/adminapp/password/reset' => ['email' => '{{admin_email}}', 'codigo' => '{{reset_code}}', 'password' => '{{admin_password}}', 'password_confirmation' => '{{admin_password}}'], + 'PUT api/v1/adminapp/tenant/event' => ['title' => 'Evento Demo', 'location' => 'Buenos Aires', 'dates' => [['date' => '2026-12-01', 'start_time' => '18:00', 'end_time' => '23:00']], 'social_media' => [['code' => 'instagram', 'url' => 'https://instagram.com/example', 'orden' => 0]]], + 'POST api/v1/adminapp/tenant/featured-groups' => ['category_name' => 'Destacados', 'is_featured' => true], + 'PUT api/v1/adminapp/tenant/featured-groups/{featuredGroup}' => ['category_name' => 'Destacados', 'is_featured' => true], + 'POST api/v1/adminapp/tenant/staff' => ['nombre_apellido' => 'Operador Demo', 'dni' => '30123456', 'email' => 'operador@example.com', 'category_ids' => [1]], + 'PUT api/v1/adminapp/tenant/staff/{staff}' => ['nombre_apellido' => 'Operador Demo', 'dni' => '30123456', 'email' => 'operador@example.com', 'category_ids' => [1]], + 'PATCH api/v1/adminapp/tenant/staff/{staff}' => ['nombre_apellido' => 'Operador Demo', 'dni' => '30123456', 'email' => 'operador@example.com', 'category_ids' => [1]], + 'PUT api/v1/adminapp/tenant/website-extras/{websiteExtraCode}' => ['enabled' => true, 'content' => ['title' => 'Contenido demo']], + 'PATCH api/v1/adminapp/tenant/website-extras/{websiteExtraCode}/toggle' => ['enabled' => true], + 'POST api/v1/adminapp/tenant/accommodations' => ['variants' => [['title' => 'Habitación doble', 'description' => 'Dos personas', 'stock' => 10, 'price' => 100000]]], + 'POST api/v1/adminapp/tenant/entries' => ['entries' => [['title' => 'Entrada general', 'description' => 'Acceso general', 'event_date_ids' => [1], 'stock' => 100, 'price' => 25000]]], + 'POST api/v1/adminapp/tenant/foods' => ['variants' => [['event_date_id' => 1, 'schedule' => '21:00', 'service' => 'Cena', 'description' => 'Menú completo', 'stock' => 100, 'price' => 15000]]], + 'POST api/v1/adminapp/tenant/merchandise' => ['items' => [['title' => 'Camiseta', 'description' => 'Camiseta oficial', 'max_units_per_user' => 2, 'variants' => [['color' => 'Azul', 'size' => 'M', 'stock' => 20, 'price' => 30000]]]]], + 'PUT api/v1/adminapp/tenant/desfile/entries' => ['rows' => [['type' => 'General', 'sector' => 'A', 'row' => 1, 'max_seat' => 20, 'price' => 25000]]], + 'PATCH api/v1/adminapp/tenant/desfile/entries/image' => ['is_enabled' => true], + 'POST api/v1/scanner/login' => ['email' => '{{scanner_email}}', 'password' => '{{scanner_password}}'], + 'POST api/v1/scanner/password/reset-attempts' => ['email' => '{{scanner_email}}'], + 'POST api/v1/scanner/password/reset-attempts/validate' => ['email' => '{{scanner_email}}', 'codigo' => '{{reset_code}}'], + 'POST api/v1/scanner/password/reset' => ['email' => '{{scanner_email}}', 'codigo' => '{{reset_code}}', 'password' => '{{scanner_password}}', 'password_confirmation' => '{{scanner_password}}'], + ]; + + if (isset($exact[$key])) { + return jsonBody($exact[$key]); + } + + if ($key === 'POST api/tenants') { + return jsonBody([ + 'client_id' => '{{client_id}}', + 'codigo' => '{{tenant_code}}', + 'nombre' => 'Tenant Demo', + 'dominio' => '{{tenant_domain}}', + 'site_title' => 'ShopIt Demo', + 'primary_color' => '#111827', + 'secondary_color' => '#2563EB', + 'danger_color' => '#DC2626', + 'success_color' => '#16A34A', + 'header_bg_color' => '#FFFFFF', + 'footer_bg_color' => '#111827', + 'header_logo' => TINY_PNG, + 'footer_logo' => TINY_PNG, + 'search_product_layout' => 'column_with_image', + 'search_group_layout' => 'paginated', + 'search_items_per_page' => 12, + 'display_categories' => true, + 'display_seach_bar' => true, + 'display_cart' => true, + 'cart_editing_enabled' => true, + 'website_type_code' => 'shopit', + ]); + } + + if (in_array($key, ['PUT api/tenants/{tenant}', 'PATCH api/tenants/{tenant}'], true)) { + return jsonBody(['nombre' => 'Tenant Demo Actualizado', 'site_title' => 'ShopIt Demo', 'primary_color' => '#111827', 'cart_editing_enabled' => true]); + } + + if ($key === 'POST api/tenants/{tenant:codigo}/catalog-items') { + return jsonBody([ + 'type' => 'standard', + 'category_id' => '{{category_id}}', + 'slug' => 'producto-demo', + 'nombre' => 'Producto Demo', + 'descripcion' => 'Producto creado desde Postman', + 'precio' => 10000, + 'inventory_policy' => 'tracked', + 'inventory_subject' => 'product', + 'max_units_per_user' => 5, + 'has_tickets' => false, + 'real_stock' => 100, + 'images' => [TINY_PNG], + ]); + } + + if ($key === 'POST api/storage-test/s3/upload') { + return formDataBody(['path' => 'postman/test-file.png', 'expires_in_minutes' => '60'], ['file']); + } + + if ($key === 'POST api/v1/adminapp/tenant/desfile/entries/image') { + return formDataBody(['is_enabled' => '1'], ['image']); + } + + return null; +} + +/** @return array */ +function queryFor(string $uri): array +{ + return match ($uri) { + 'api/tenants/bootstrap' => [['key' => 'dominio', 'value' => '{{tenant_domain}}'], ['key' => 'path', 'value' => '/']], + 'api/v1/adminapp/bootstrap/{dominio}', 'api/v1/scanner/bootstrap/{dominio}' => [['key' => 'path', 'value' => '/']], + 'api/tenants/{tenant:codigo}/catalog-items' => [['key' => 'q', 'value' => 'demo'], ['key' => 'page', 'value' => '1']], + 'api/tenants/{tenant:codigo}/catalog-items/{catalogItem}' => [['key' => 'variant_id', 'value' => '{{variant_id}}', 'disabled' => true]], + 'api/tenants/{tenant:codigo}/catalog/featured-groups/{featuredGroup}/items', + 'api/tenants/{tenant:codigo}/categories/{category}' => [['key' => 'page', 'value' => '1']], + 'api/tenants/{tenant:codigo}/compras' => [['key' => 'status', 'value' => 'pending_payment', 'disabled' => true], ['key' => 'page', 'value' => '1']], + 'api/v1/adminapp/tenant/sales', 'api/v1/adminapp/tenant/sales/pdf' => [ + ['key' => 'q', 'value' => '', 'disabled' => true], + ['key' => 'status', 'value' => 'confirmed', 'disabled' => true], + ['key' => 'sale_date', 'value' => '2026-12-01', 'disabled' => true], + ['key' => 'sort_by', 'value' => 'date'], + ['key' => 'sort_direction', 'value' => 'desc'], + ['key' => 'page', 'value' => '1'], + ['key' => 'per_page', 'value' => '20'], + ], + 'api/v1/scanner/tickets' => [['key' => 'q', 'value' => '', 'disabled' => true], ['key' => 'page', 'value' => '1'], ['key' => 'per_page', 'value' => '20']], + 'api/storage-test/s3/temporary-url' => [['key' => 'path', 'value' => '{{s3_path}}'], ['key' => 'expires_in_minutes', 'value' => '60']], + default => [], + }; +} + +/** @return array{0: string, 1: string} */ +function folderFor(string $uri, string $action): array +{ + preg_match('/App\\\\Domains\\\\([^\\\\]+)/', $action, $matches); + $domain = $matches[1] ?? 'Other'; + + if (str_starts_with($uri, 'api/v1/adminapp/')) { + return ['Admin App API', $domain]; + } + + if (str_starts_with($uri, 'api/v1/scanner/')) { + return ['Scanner API', $domain]; + } + + if (str_starts_with($uri, 'api/webhooks/')) { + return ['Webhooks', $domain]; + } + + if (in_array($domain, ['StorageTest', 'MailTest'], true)) { + return ['Developer Utilities', $domain]; + } + + if (in_array($domain, ['Client', 'Integration', 'Menu', 'Tenant'], true) && ! str_contains($uri, '{tenant:codigo}')) { + return ['Platform Management', $domain]; + } + + return ['Storefront API', $domain]; +} + +function humanize(string $value): string +{ + $value = preg_replace('/Controller$/', '', $value); + $value = preg_replace('/(? 'List', 'store' => 'Create', 'show' => 'Get', 'update' => 'Update', + 'destroy' => 'Delete', 'addItem' => 'Add Item', 'updateItemQuantity' => 'Update Item Quantity', + 'removeItem' => 'Remove Item', 'search' => 'Search', 'category' => 'Get Category', + 'featuredGroupItems' => 'List Featured Group Items', 'variantOptions' => 'Get Variant Options', + 'startCheckout' => 'Start Checkout', 'updateCustomerData' => 'Update Customer Data', + 'prepareItemEditing' => 'Prepare Item Editing', 'paymentIntent' => 'Create Payment Intent', + 'submitForReview' => 'Submit for Review', 'cancel' => 'Cancel', 'complete' => 'Complete', + 'downloadPdf' => 'Download PDF', 'downloadModificationsPdf' => 'Download Modifications PDF', + 'modifications' => 'List Modifications', 'tickets' => 'List Tickets', 'confirm' => 'Confirm', + 'temporaryUrl' => 'Generate Temporary URL', 'replaceImage' => 'Replace Image', + 'updateImage' => 'Update Image', 'destroyImage' => 'Delete Image', 'showExtra' => 'Get Extra', + 'toggle' => 'Toggle', 'scan' => 'Scan', 'handle' => 'Receive', + ]; + + $name = $handler === '__invoke' + ? $controller + : (($verbs[$handler] ?? humanize($handler)).' '.$controller); + + return $multiMethod ? $name.' ('.$method.')' : $name; +} + +function pathFor(string $uri): string +{ + $variables = [ + 'tenant:codigo' => 'tenant_code', 'tenant' => 'tenant_id', 'client' => 'client_id', + 'integration_code' => 'integration_code', 'integration' => 'integration_id', 'menue' => 'menu_id', + 'menu_code' => 'menu_code', 'tenant_code' => 'tenant_code', 'catalogItem' => 'catalog_item_id', + 'featuredGroup' => 'featured_group_id', 'category' => 'category_id', 'cartItem' => 'cart_item_id', + 'compra' => 'purchase_id', 'item' => 'purchase_item_id', 'dominio' => 'tenant_domain', + 'sale' => 'sale_id', 'staff' => 'staff_id', 'websiteExtraCode' => 'website_extra_code', + 'accommodation' => 'accommodation_id', 'entry' => 'entry_id', 'food' => 'food_id', + 'merchandise' => 'merchandise_id', 'ticketUuid' => 'ticket_uuid', + ]; + + return preg_replace_callback('/\{([^}]+)\}/', function (array $matches) use ($variables): string { + $variable = $variables[$matches[1]] ?? strtolower((string) preg_replace('/(? */ +function authFor(string $uri, array $middleware): ?array +{ + $protected = count(array_filter( + $middleware, + fn (string $item): bool => str_contains($item, 'Authenticate:sanctum'), + )) > 0; + + if (! $protected) { + return null; + } + + $variable = str_starts_with($uri, 'api/v1/adminapp/') + ? 'admin_token' + : (str_starts_with($uri, 'api/v1/scanner/') ? 'scanner_token' : 'token'); + + return ['type' => 'bearer', 'bearer' => [['key' => 'token', 'value' => '{{'.$variable.'}}', 'type' => 'string']]]; +} + +/** @return array */ +function tokenCaptureEvent(string $uri): array +{ + $variable = $uri === 'api/v1/adminapp/login' ? 'admin_token' : ($uri === 'api/v1/scanner/login' ? 'scanner_token' : 'token'); + + return [ + 'listen' => 'test', + 'script' => [ + 'type' => 'text/javascript', + 'exec' => [ + 'if (pm.response.code >= 200 && pm.response.code < 300) {', + ' const payload = pm.response.json();', + " if (payload.token) pm.collectionVariables.set('{$variable}', payload.token);", + '}', + ], + ], + ]; +} + +$tree = []; +$registeredOperations = 0; + +foreach ($routes as $route) { + $methods = array_values(array_filter(explode('|', $route['method']), fn (string $method): bool => $method !== 'HEAD')); + $multiMethod = count($methods) > 1; + + foreach ($methods as $method) { + [$section, $folder] = folderFor($route['uri'], $route['action']); + $path = pathFor($route['uri']); + $query = queryFor($route['uri']); + $enabledQuery = array_values(array_filter($query, fn (array $item): bool => ! ($item['disabled'] ?? false))); + $queryString = $enabledQuery === [] ? '' : '?'.implode('&', array_map( + fn (array $item): string => rawurlencode($item['key']).'='.$item['value'], + $enabledQuery, + )); + $body = bodyFor($method, $route['uri']); + $auth = authFor($route['uri'], $route['middleware']); + $headers = [['key' => 'Accept', 'value' => 'application/json', 'type' => 'text']]; + + if (($body['mode'] ?? null) === 'raw') { + $headers[] = ['key' => 'Content-Type', 'value' => 'application/json', 'type' => 'text']; + } + + $request = [ + 'method' => $method, + 'header' => $headers, + 'description' => sprintf( + "Ruta Laravel: `%s /%s`\n\nControlador: `%s`%s", + $method, + $route['uri'], + $route['action'], + $auth === null ? '' : "\n\nRequiere autenticación Sanctum.", + ), + 'url' => [ + 'raw' => '{{base_url}}/'.$path.$queryString, + 'host' => ['{{base_url}}'], + 'path' => explode('/', $path), + ], + ]; + + if ($query !== []) { + $request['url']['query'] = $query; + } + + if ($body !== null) { + $request['body'] = $body; + } + + if ($auth !== null) { + $request['auth'] = $auth; + } + + $item = [ + 'name' => requestName($method, $route['action'], $multiMethod), + 'request' => $request, + 'response' => [], + ]; + + if (in_array($route['uri'], ['api/login', 'api/v1/adminapp/login', 'api/v1/scanner/login'], true)) { + $item['event'] = [tokenCaptureEvent($route['uri'])]; + } + + $tree[$section][$folder][] = $item; + $registeredOperations++; + } +} + +$sectionDescriptions = [ + 'Storefront API' => 'API pública y autenticada consumida por el storefront: autenticación, catálogo, carrito, compras y tickets.', + 'Admin App API' => 'Operaciones de administración del tenant. Ejecutá Login primero para completar `admin_token`.', + 'Scanner API' => 'Operaciones de la aplicación de escaneo. Ejecutá Login primero para completar `scanner_token`.', + 'Platform Management' => 'CRUD y configuración de tenants, clientes, menús e integraciones.', + 'Webhooks' => 'Entradas públicas para notificaciones de proveedores externos.', + 'Developer Utilities' => 'Endpoints de diagnóstico de correo y almacenamiento. No deberían exponerse en producción.', +]; + +$items = []; +foreach ($tree as $section => $folders) { + $children = []; + foreach ($folders as $folder => $requests) { + $children[] = ['name' => humanize($folder), 'item' => $requests]; + } + + $items[] = [ + 'name' => $section, + 'description' => $sectionDescriptions[$section] ?? '', + 'item' => $children, + ]; +} + +$variables = [ + 'base_url' => 'http://localhost:8000', + 'token' => '', 'admin_token' => '', 'scanner_token' => '', + 'user_email' => 'usuario@example.com', 'user_password' => 'Password!123', + 'admin_email' => 'admin@example.com', 'admin_password' => 'Password!123', + 'scanner_email' => 'scanner@example.com', 'scanner_password' => 'Password!123', + 'tenant_code' => 'demo', 'tenant_id' => '1', 'tenant_domain' => 'demo.test', + 'client_id' => '1', 'integration_id' => '1', 'integration_code' => 'telepagos', + 'menu_id' => '1', 'menu_code' => 'demo', 'catalog_item_id' => '1', 'variant_id' => '1', + 'category_id' => '1', 'featured_group_id' => '1', 'cart_id' => '1', 'cart_item_id' => '1', + 'purchase_id' => '1', 'purchase_item_id' => '1', 'sale_id' => '1', 'staff_id' => '1', + 'website_extra_code' => 'hero', 'accommodation_id' => '1', 'entry_id' => '1', 'food_id' => '1', + 'merchandise_id' => '1', 'ticket_uuid' => '00000000-0000-0000-0000-000000000000', + 'oauth_code' => '00000000-0000-0000-0000-000000000000', 'reset_code' => '1234', + 's3_path' => 'postman/test-file.png', +]; + +$collection = [ + 'info' => [ + '_postman_id' => '76fd6fd2-53b9-4d92-8e02-1ddcc6207fa2', + 'name' => 'ShopIt API — Complete', + 'description' => "Colección canónica generada desde las rutas reales de Laravel. Incluye {$registeredOperations} operaciones HTTP, ejemplos de payload, filtros, archivos y tokens separados para Storefront, Admin App y Scanner.\n\nUso rápido:\n1. Ajustá `base_url` y las credenciales.\n2. Ejecutá el Login de la aplicación correspondiente; el token se guarda automáticamente.\n3. Ajustá los IDs y códigos de las variables de colección.\n\nRegeneración: `php postman/generate-shopit-collection.php`.", + 'schema' => 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json', + ], + 'item' => $items, + 'variable' => array_map( + fn (string $key, string $value): array => ['key' => $key, 'value' => $value, 'type' => 'string'], + array_keys($variables), + array_values($variables), + ), +]; + +$output = $root.DIRECTORY_SEPARATOR.'ShopIt_API_Postman_Collection.json'; +file_put_contents($output, json_encode($collection, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE).PHP_EOL); + +fwrite(STDOUT, "Generated {$registeredOperations} operations in {$output}\n"); diff --git a/tests/Feature/Migrations/AddCartEditingEnabledToTenantsTest.php b/tests/Feature/Migrations/AddCartEditingEnabledToTenantsTest.php new file mode 100644 index 0000000..eb10e23 --- /dev/null +++ b/tests/Feature/Migrations/AddCartEditingEnabledToTenantsTest.php @@ -0,0 +1,38 @@ +down(); + $migration->up(); + + $this->assertDatabaseHas('tenants', [ + 'codigo' => 'desfile_pura_tendencia', + 'cart_editing_enabled' => false, + ]); + + DB::table('tenants')->insert([ + 'codigo' => 'cart-editing-default', + 'nombre' => 'Cart editing default', + 'dominio' => 'cart-editing-default.test', + ]); + + $this->assertDatabaseHas('tenants', [ + 'codigo' => 'cart-editing-default', + 'cart_editing_enabled' => true, + ]); + } +} diff --git a/tests/Feature/Seeders/DesfilePuraTendenciaSeederTest.php b/tests/Feature/Seeders/DesfilePuraTendenciaSeederTest.php index 64e02b4..60ce57b 100644 --- a/tests/Feature/Seeders/DesfilePuraTendenciaSeederTest.php +++ b/tests/Feature/Seeders/DesfilePuraTendenciaSeederTest.php @@ -44,6 +44,7 @@ class DesfilePuraTendenciaSeederTest extends TestCase 'footer_bg_color' => '#D4441C', 'display_categories' => false, 'display_seach_bar' => false, + 'cart_editing_enabled' => false, 'site_title' => 'Desfile Pura Tendencia', ]); diff --git a/tests/Feature/Tenant/BootstrapTenantControllerTest.php b/tests/Feature/Tenant/BootstrapTenantControllerTest.php index 3bdea04..6230aa6 100644 --- a/tests/Feature/Tenant/BootstrapTenantControllerTest.php +++ b/tests/Feature/Tenant/BootstrapTenantControllerTest.php @@ -73,6 +73,7 @@ class BootstrapTenantControllerTest extends TestCase 'display_categories' => false, 'display_seach_bar' => false, 'display_cart' => false, + 'cart_editing_enabled' => false, ]); $response = $this->getJson('/api/tenants/bootstrap?dominio=acme.com&path=%2F'); @@ -89,6 +90,7 @@ class BootstrapTenantControllerTest extends TestCase ->assertJsonPath('data.display_categories', false) ->assertJsonPath('data.display_seach_bar', false) ->assertJsonPath('data.display_cart', false) + ->assertJsonPath('data.cart_editing_enabled', false) ->assertJsonPath('data.header_bg_color', '#ffffff')->assertJsonPath('data.footer_bg_color', '#ffffff'); $headerUrl = $response->json('data.header_logo'); @@ -745,19 +747,22 @@ class BootstrapTenantControllerTest extends TestCase $response = $this->putJson("/api/tenants/{$tenant->codigo}", [ 'primary_color' => '#000000', + 'cart_editing_enabled' => false, ]); $response ->assertOk() ->assertJsonPath('data.codigo', 'acme') ->assertJsonPath('data.nombre', 'Acme') - ->assertJsonPath('data.primary_color', '#000000'); + ->assertJsonPath('data.primary_color', '#000000') + ->assertJsonPath('data.cart_editing_enabled', false); $this->assertDatabaseHas('tenants', [ 'id' => $tenant->id, 'codigo' => 'acme', 'nombre' => 'Acme', 'primary_color' => '#000000', + 'cart_editing_enabled' => false, ]); }