{"info":{"_postman_id":"e294b0ff-11fb-4512-898a-909467e4e9bd","name":"OpenFlow Coworking","description":"<html><head></head><body><h1 id=\"openflow-coworking-api\">OpenFlow Coworking API</h1>\n<p><strong>Sistema de Control de Acceso a Coworkings Empresariales</strong> — Nelumbo Consultores</p>\n<p>API REST para el control de ingreso y salida de personas en múltiples sedes de coworking, con histórico de accesos, generación de indicadores, facturación por tiempo de permanencia y sistema de cupones por fidelidad.</p>\n<hr>\n<h2 id=\"autenticación\">Autenticación</h2>\n<p>La API utiliza <strong>JWT (JSON Web Token)</strong> con expiración de <strong>6 horas</strong>. Para obtener un token, utiliza el endpoint de <strong>Login</strong> en la carpeta <code>Auth</code>.</p>\n<p><strong>Usuario precargado:</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Valor</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Email</td>\n<td><code>admin@mail.com</code></td>\n</tr>\n<tr>\n<td>Password</td>\n<td><code>admin</code></td>\n</tr>\n</tbody>\n</table>\n</div><p>Incluye el token en el header <code>Authorization: Bearer {{TOKEN}}</code> para acceder a los endpoints protegidos.</p>\n<hr>\n<h2 id=\"roles-y-permisos\">Roles y Permisos</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Rol</th>\n<th>Permisos</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>ADMIN</strong></td>\n<td>Crear usuarios OPERADOR, CRUD completo de sedes, asociar operadores a sedes, consultar accesos e indicadores globales, métricas financieras agregadas</td>\n</tr>\n<tr>\n<td><strong>OPERADOR</strong></td>\n<td>Registrar ingreso/salida de personas, consultar personas en su sede, visualizar indicadores de su sede</td>\n</tr>\n</tbody>\n</table>\n</div><hr>\n<h2 id=\"variables-de-entorno\">Variables de Entorno</h2>\n<p>Configura las siguientes variables en tu entorno antes de ejecutar las peticiones:</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Variable</th>\n<th>Descripción</th>\n<th>Ejemplo</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>HOST</code></td>\n<td>Host del servidor</td>\n<td><code>http://localhost</code></td>\n</tr>\n<tr>\n<td><code>PORT</code></td>\n<td>Puerto del servidor</td>\n<td><code>8080</code></td>\n</tr>\n<tr>\n<td><code>API_BASE_PATH</code></td>\n<td>Ruta base de la API</td>\n<td><code>api/v1</code></td>\n</tr>\n<tr>\n<td><code>TOKEN</code></td>\n<td>JWT de autenticación</td>\n<td><em>(se obtiene del Login)</em></td>\n</tr>\n<tr>\n<td><code>USER_ID</code></td>\n<td>ID del usuario objetivo</td>\n<td>UUID</td>\n</tr>\n<tr>\n<td><code>BRANCH_ID</code></td>\n<td>ID de la sede</td>\n<td>UUID</td>\n</tr>\n<tr>\n<td><code>OPERATOR_ID</code></td>\n<td>ID del operador</td>\n<td>UUID</td>\n</tr>\n<tr>\n<td><code>CLIENT_DOCUMENT</code></td>\n<td>Documento del cliente</td>\n<td><code>1010101010</code></td>\n</tr>\n<tr>\n<td><code>COUPON_CODE</code></td>\n<td>Código del cupón</td>\n<td>String</td>\n</tr>\n</tbody>\n</table>\n</div><hr>\n<h2 id=\"estructura-de-la-colección\">Estructura de la Colección</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Carpeta</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>User</strong></td>\n<td>Gestión de usuarios (ADMIN y OPERADOR)</td>\n</tr>\n<tr>\n<td><strong>Auth</strong></td>\n<td>Autenticación JWT (Login, Refresh, Logout)</td>\n</tr>\n<tr>\n<td><strong>Branch</strong></td>\n<td>CRUD de sedes y asignación de operadores</td>\n</tr>\n<tr>\n<td><strong>Access</strong></td>\n<td>Registro de ingresos (check-in) y salidas (check-out)</td>\n</tr>\n<tr>\n<td><strong>Indicators</strong></td>\n<td>Indicadores y métricas del sistema</td>\n</tr>\n<tr>\n<td><strong>Coupons</strong></td>\n<td>Gestión de cupones de fidelidad</td>\n</tr>\n</tbody>\n</table>\n</div></body></html>","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","toc":[{"content":"OpenFlow Coworking API","slug":"openflow-coworking-api"}],"owner":"52872949","collectionId":"e294b0ff-11fb-4512-898a-909467e4e9bd","publishedId":"2sBXcKDdyN","public":true,"customColor":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"FF6C37"},"publishDate":"2026-03-05T13:35:40.000Z"},"item":[{"name":"User","item":[{"name":"List","id":"3d626be8-30e2-4e4c-a0a6-9576f8f9f689","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{TOKEN}}"}]},"isInherited":false},"method":"GET","header":[],"url":"{{HOST}}:{{PORT}}/{{API_BASE_PATH}}/users?q=xavi&page=1&limit=2","description":"<h2 id=\"listar-usuarios\">Listar Usuarios</h2>\n<p>Obtiene la lista paginada de usuarios del sistema con opción de búsqueda por texto.</p>\n<p><strong>Rol requerido:</strong> <code>ADMIN</code></p>\n<h3 id=\"query-parameters\">Query Parameters</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parámetro</th>\n<th>Tipo</th>\n<th>Requerido</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>q</code></td>\n<td>string</td>\n<td>No</td>\n<td>Texto de búsqueda (nombre o email)</td>\n</tr>\n<tr>\n<td><code>page</code></td>\n<td>number</td>\n<td>No</td>\n<td>Número de página (default: 1)</td>\n</tr>\n<tr>\n<td><code>limit</code></td>\n<td>number</td>\n<td>No</td>\n<td>Cantidad de resultados por página (default: 10)</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"respuesta-exitosa-200-ok\">Respuesta exitosa <code>200 OK</code></h3>\n<p>Retorna un arreglo paginado de usuarios con sus datos básicos (id, nombre, email, documento, rol).</p>\n","urlObject":{"port":"{{PORT}}","path":["{{API_BASE_PATH}}","users"],"host":["{{HOST}}"],"query":[{"key":"q","value":"xavi"},{"key":"page","value":"1"},{"key":"limit","value":"2"}],"variable":[]}},"response":[],"_postman_id":"3d626be8-30e2-4e4c-a0a6-9576f8f9f689"},{"name":"Profile","id":"8c9f6d88-2c5a-4fb7-9f67-243100c86764","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{TOKEN}}"}]},"isInherited":false},"method":"GET","header":[],"url":"{{HOST}}:{{PORT}}/{{API_BASE_PATH}}/users/me","description":"<h2 id=\"mi-perfil\">Mi Perfil</h2>\n<p>Obtiene la información del usuario autenticado actualmente.</p>\n<p><strong>Rol requerido:</strong> <code>ADMIN</code> o <code>OPERADOR</code></p>\n<h3 id=\"respuesta-exitosa-200-ok\">Respuesta exitosa <code>200 OK</code></h3>\n<p>Retorna los datos del usuario autenticado: id, nombre, email, documento y rol.</p>\n","urlObject":{"port":"{{PORT}}","path":["{{API_BASE_PATH}}","users","me"],"host":["{{HOST}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"8c9f6d88-2c5a-4fb7-9f67-243100c86764"},{"name":"Detail","id":"4467b22e-f747-4acd-92a4-22abd90d80d9","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[],"url":"{{HOST}}:{{PORT}}/{{API_BASE_PATH}}/users/{{USER_ID}}","description":"<h2 id=\"detalle-de-usuario\">Detalle de Usuario</h2>\n<p>Obtiene la información detallada de un usuario específico por su ID.</p>\n<p><strong>Rol requerido:</strong> <code>ADMIN</code></p>\n<h3 id=\"path-parameters\">Path Parameters</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parámetro</th>\n<th>Tipo</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>USER_ID</code></td>\n<td>UUID</td>\n<td>ID del usuario a consultar</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"respuesta-exitosa-200-ok\">Respuesta exitosa <code>200 OK</code></h3>\n<p>Retorna los datos completos del usuario: id, nombre, email, documento y rol.</p>\n<h3 id=\"errores-comunes\">Errores comunes</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Código</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>404</code></td>\n<td>Usuario no encontrado</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"port":"{{PORT}}","path":["{{API_BASE_PATH}}","users","{{USER_ID}}"],"host":["{{HOST}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"4467b22e-f747-4acd-92a4-22abd90d80d9"},{"name":"Operator branches","id":"2877e878-d4bd-42ec-a776-2b370ce969e9","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{TOKEN}}"}]},"isInherited":false},"method":"GET","header":[],"url":"{{HOST}}:{{PORT}}/{{API_BASE_PATH}}/users/me/branches","description":"<h2 id=\"sedes-del-operador\">Sedes del Operador</h2>\n<p>Obtiene la lista de sedes asignadas al operador autenticado.</p>\n<p><strong>Rol requerido:</strong> <code>OPERADOR</code></p>\n<h3 id=\"respuesta-exitosa-200-ok\">Respuesta exitosa <code>200 OK</code></h3>\n<p>Retorna un arreglo con las sedes asignadas al operador, incluyendo nombre, dirección, capacidad máxima y costo por hora de cada sede.</p>\n","urlObject":{"port":"{{PORT}}","path":["{{API_BASE_PATH}}","users","me","branches"],"host":["{{HOST}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"2877e878-d4bd-42ec-a776-2b370ce969e9"},{"name":"Create","id":"af5f97c7-4fdf-451b-9d0f-56a9379d3a12","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{TOKEN}}"}]},"isInherited":false},"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"name\": \"Eduar\",\n    \"email\": \"xavieravendano2@gmail.com\",\n    \"document\": \"1111112111\",\n    \"password\": \"123123223\"\n}","options":{"raw":{"language":"json"}}},"url":"{{HOST}}:{{PORT}}/{{API_BASE_PATH}}/users","description":"<h2 id=\"crear-usuario\">Crear Usuario</h2>\n<p>Crea un nuevo usuario con rol <code>OPERADOR</code> en el sistema.</p>\n<p><strong>Rol requerido:</strong> <code>ADMIN</code></p>\n<h3 id=\"body-json\">Body (JSON)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>Requerido</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>name</code></td>\n<td>string</td>\n<td>✅</td>\n<td>Nombre completo del usuario</td>\n</tr>\n<tr>\n<td><code>email</code></td>\n<td>string</td>\n<td>✅</td>\n<td>Correo electrónico (único)</td>\n</tr>\n<tr>\n<td><code>document</code></td>\n<td>string</td>\n<td>✅</td>\n<td>Número de documento (único)</td>\n</tr>\n<tr>\n<td><code>password</code></td>\n<td>string</td>\n<td>✅</td>\n<td>Contraseña del usuario</td>\n</tr>\n</tbody>\n</table>\n</div><pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"name\": \"Eduar\",\n  \"email\": \"xavieravendano2@gmail.com\",\n  \"document\": \"1111112111\",\n  \"password\": \"123123223\"\n}\n</code></pre>\n<h3 id=\"respuesta-exitosa-201-created\">Respuesta exitosa <code>201 Created</code></h3>\n<p>Retorna el usuario creado con su ID asignado.</p>\n<h3 id=\"errores-comunes\">Errores comunes</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Código</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>400</code></td>\n<td>Datos inválidos o campos faltantes</td>\n</tr>\n<tr>\n<td><code>409</code></td>\n<td>Email o documento ya registrado</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"port":"{{PORT}}","path":["{{API_BASE_PATH}}","users"],"host":["{{HOST}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"af5f97c7-4fdf-451b-9d0f-56a9379d3a12"},{"name":"Update","id":"1052d5f4-f0e9-4a45-be5a-2573c25e958c","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"PATCH","header":[],"body":{"mode":"raw","raw":"{\n    \"name\": \"Eduar Xavier\",\n    \"email\": \"xavieravendano9@gmail.com\",\n    \"password\": \"123123123\"\n}","options":{"raw":{"language":"json"}}},"url":"{{HOST}}:{{PORT}}/{{API_BASE_PATH}}/users/{{USER_ID}}","description":"<h2 id=\"actualizar-usuario\">Actualizar Usuario</h2>\n<p>Actualiza los datos de un usuario existente. Solo se envían los campos que se desean modificar.</p>\n<p><strong>Rol requerido:</strong> <code>ADMIN</code></p>\n<h3 id=\"path-parameters\">Path Parameters</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parámetro</th>\n<th>Tipo</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>USER_ID</code></td>\n<td>UUID</td>\n<td>ID del usuario a actualizar</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"body-json\">Body (JSON)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>Requerido</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>name</code></td>\n<td>string</td>\n<td>No</td>\n<td>Nombre completo</td>\n</tr>\n<tr>\n<td><code>email</code></td>\n<td>string</td>\n<td>No</td>\n<td>Correo electrónico</td>\n</tr>\n<tr>\n<td><code>password</code></td>\n<td>string</td>\n<td>No</td>\n<td>Nueva contraseña</td>\n</tr>\n</tbody>\n</table>\n</div><pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"name\": \"Eduar Xavier\",\n  \"email\": \"xavieravendano9@gmail.com\",\n  \"password\": \"123123123\"\n}\n</code></pre>\n<h3 id=\"respuesta-exitosa-200-ok\">Respuesta exitosa <code>200 OK</code></h3>\n<p>Retorna el usuario con los datos actualizados.</p>\n<h3 id=\"errores-comunes\">Errores comunes</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Código</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>404</code></td>\n<td>Usuario no encontrado</td>\n</tr>\n<tr>\n<td><code>409</code></td>\n<td>Email ya registrado por otro usuario</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"port":"{{PORT}}","path":["{{API_BASE_PATH}}","users","{{USER_ID}}"],"host":["{{HOST}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"1052d5f4-f0e9-4a45-be5a-2573c25e958c"},{"name":"Delete","id":"4c38ae81-ca1f-4621-aea8-a0e610318e8d","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"DELETE","header":[],"url":"{{HOST}}:{{PORT}}/{{API_BASE_PATH}}/users/{{USER_ID}}","description":"<h2 id=\"eliminar-usuario\">Eliminar Usuario</h2>\n<p>Elimina un usuario del sistema de forma permanente.</p>\n<p><strong>Rol requerido:</strong> <code>ADMIN</code></p>\n<h3 id=\"path-parameters\">Path Parameters</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parámetro</th>\n<th>Tipo</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>USER_ID</code></td>\n<td>UUID</td>\n<td>ID del usuario a eliminar</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"respuesta-exitosa-204-no-content\">Respuesta exitosa <code>204 No Content</code></h3>\n<p>El usuario ha sido eliminado exitosamente. No retorna contenido.</p>\n<h3 id=\"errores-comunes\">Errores comunes</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Código</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>404</code></td>\n<td>Usuario no encontrado</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"port":"{{PORT}}","path":["{{API_BASE_PATH}}","users","{{USER_ID}}"],"host":["{{HOST}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"4c38ae81-ca1f-4621-aea8-a0e610318e8d"}],"id":"74491e14-b512-439c-a183-ea7d0150bac7","description":"<h1 id=\"user\">User</h1>\n<p>Gestión de usuarios del sistema. El rol <strong>ADMIN</strong> puede crear, listar, actualizar y eliminar usuarios con rol <strong>OPERADOR</strong>. Cada usuario tiene nombre, email, documento y contraseña.</p>\n<p><strong>Permisos requeridos:</strong> <code>ADMIN</code> para todas las operaciones de gestión. Cualquier usuario autenticado puede consultar su propio perfil.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Operación</th>\n<th>Método</th>\n<th>Endpoint</th>\n<th>Rol</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Listar usuarios</td>\n<td><code>GET</code></td>\n<td><code>/users</code></td>\n<td>ADMIN</td>\n</tr>\n<tr>\n<td>Ver perfil propio</td>\n<td><code>GET</code></td>\n<td><code>/users/me</code></td>\n<td>ADMIN, OPERADOR</td>\n</tr>\n<tr>\n<td>Detalle de usuario</td>\n<td><code>GET</code></td>\n<td><code>/users/:id</code></td>\n<td>ADMIN</td>\n</tr>\n<tr>\n<td>Sedes del operador</td>\n<td><code>GET</code></td>\n<td><code>/users/me/branches</code></td>\n<td>OPERADOR</td>\n</tr>\n<tr>\n<td>Crear usuario</td>\n<td><code>POST</code></td>\n<td><code>/users</code></td>\n<td>ADMIN</td>\n</tr>\n<tr>\n<td>Actualizar usuario</td>\n<td><code>PATCH</code></td>\n<td><code>/users/:id</code></td>\n<td>ADMIN</td>\n</tr>\n<tr>\n<td>Eliminar usuario</td>\n<td><code>DELETE</code></td>\n<td><code>/users/:id</code></td>\n<td>ADMIN</td>\n</tr>\n</tbody>\n</table>\n</div>","_postman_id":"74491e14-b512-439c-a183-ea7d0150bac7"},{"name":"Auth","item":[{"name":"Login","id":"8c56841a-cd0d-4896-83d7-e42be9503d6b","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"email\": \"admin@mail.com\",\n    \"password\": \"admin\"\n}","options":{"raw":{"language":"json"}}},"url":"{{HOST}}:{{PORT}}/{{API_BASE_PATH}}/tokens","description":"<h2 id=\"iniciar-sesión\">Iniciar Sesión</h2>\n<p>Autentica un usuario y retorna un token JWT con expiración de <strong>6 horas</strong> junto con un refresh token.</p>\n<p><strong>Autenticación:</strong> No requerida</p>\n<h3 id=\"body-json\">Body (JSON)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>Requerido</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>email</code></td>\n<td>string</td>\n<td>✅</td>\n<td>Correo electrónico del usuario</td>\n</tr>\n<tr>\n<td><code>password</code></td>\n<td>string</td>\n<td>✅</td>\n<td>Contraseña del usuario</td>\n</tr>\n</tbody>\n</table>\n</div><pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"email\": \"admin@mail.com\",\n  \"password\": \"admin\"\n}\n</code></pre>\n<h3 id=\"respuesta-exitosa-200-ok\">Respuesta exitosa <code>200 OK</code></h3>\n<p>Retorna el <code>accessToken</code> y el <code>refreshToken</code>. Guarda el <code>accessToken</code> en la variable <code>{{TOKEN}}</code> para autenticar las demás peticiones.</p>\n<h3 id=\"errores-comunes\">Errores comunes</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Código</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>401</code></td>\n<td>Credenciales inválidas</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"port":"{{PORT}}","path":["{{API_BASE_PATH}}","tokens"],"host":["{{HOST}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"8c56841a-cd0d-4896-83d7-e42be9503d6b"},{"name":"Refresh Token","id":"64ebacd3-898a-4ddc-8a6e-bfe6153c24d2","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{TOKEN}}"}]},"isInherited":false},"method":"PUT","header":[{"key":"X-Refresh-Token","value":"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ4YXZpZXJhdmVuZGFubzlAZ21haWwuY29tIiwiaWF0IjoxNzcyNTU1NzQ5LCJleHAiOjE3NzI1OTg5NDl9.iBmwP9J9ynFYkgsqkWaGhOX4qR5_M62O03TXXIkBD1s","type":"text"}],"url":"{{HOST}}:{{PORT}}/{{API_BASE_PATH}}/tokens","description":"<h2 id=\"refrescar-token\">Refrescar Token</h2>\n<p>Genera un nuevo par de tokens (access + refresh) utilizando un refresh token válido.</p>\n<p><strong>Autenticación:</strong> Bearer Token + Header personalizado</p>\n<h3 id=\"headers\">Headers</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Header</th>\n<th>Tipo</th>\n<th>Requerido</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>Authorization</code></td>\n<td>string</td>\n<td>✅</td>\n<td><code>Bearer {{TOKEN}}</code> — Token de acceso actual</td>\n</tr>\n<tr>\n<td><code>X-Refresh-Token</code></td>\n<td>string</td>\n<td>✅</td>\n<td>Refresh token obtenido en el login</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"respuesta-exitosa-200-ok\">Respuesta exitosa <code>200 OK</code></h3>\n<p>Retorna un nuevo <code>accessToken</code> y <code>refreshToken</code>. Actualiza la variable <code>{{TOKEN}}</code> con el nuevo token.</p>\n<h3 id=\"errores-comunes\">Errores comunes</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Código</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>401</code></td>\n<td>Refresh token inválido o expirado</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"port":"{{PORT}}","path":["{{API_BASE_PATH}}","tokens"],"host":["{{HOST}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"64ebacd3-898a-4ddc-8a6e-bfe6153c24d2"},{"name":"Logout","id":"3ca9b81b-0df3-4a17-b9ef-fb61c41ec6e7","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{TOKEN}}"}]},"isInherited":false},"method":"DELETE","header":[],"url":"{{HOST}}:{{PORT}}/{{API_BASE_PATH}}/tokens","description":"<h2 id=\"cerrar-sesión\">Cerrar Sesión</h2>\n<p>Invalida el token actual del usuario, cerrando la sesión activa.</p>\n<p><strong>Autenticación:</strong> Bearer Token</p>\n<h3 id=\"respuesta-exitosa-204-no-content\">Respuesta exitosa <code>204 No Content</code></h3>\n<p>La sesión ha sido cerrada exitosamente. El token queda invalidado y no podrá usarse nuevamente.</p>\n<h3 id=\"errores-comunes\">Errores comunes</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Código</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>401</code></td>\n<td>Token inválido o ya expirado</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"port":"{{PORT}}","path":["{{API_BASE_PATH}}","tokens"],"host":["{{HOST}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"3ca9b81b-0df3-4a17-b9ef-fb61c41ec6e7"}],"id":"16790622-9d38-41cd-aa40-db2a1990dd7b","description":"<h1 id=\"auth\">Auth</h1>\n<p>Endpoints de autenticación mediante <strong>JWT (JSON Web Token)</strong>. El token tiene una expiración de <strong>6 horas</strong>. Utiliza el endpoint de Login para obtener el token de acceso y el refresh token.</p>\n<p><strong>Usuario precargado:</strong></p>\n<ul>\n<li><strong>Email:</strong> <code>admin@mail.com</code></li>\n<li><strong>Password:</strong> <code>admin</code></li>\n</ul>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Operación</th>\n<th>Método</th>\n<th>Endpoint</th>\n<th>Autenticación</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Login</td>\n<td><code>POST</code></td>\n<td><code>/tokens</code></td>\n<td>No requerida</td>\n</tr>\n<tr>\n<td>Refresh Token</td>\n<td><code>PUT</code></td>\n<td><code>/tokens</code></td>\n<td>Bearer Token + Header <code>X-Refresh-Token</code></td>\n</tr>\n<tr>\n<td>Logout</td>\n<td><code>DELETE</code></td>\n<td><code>/tokens</code></td>\n<td>Bearer Token</td>\n</tr>\n</tbody>\n</table>\n</div>","_postman_id":"16790622-9d38-41cd-aa40-db2a1990dd7b"},{"name":"Branch","item":[{"name":"List","id":"33f5a946-4892-4a63-bd86-d38dd705e30e","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{TOKEN}}"}]},"isInherited":false},"method":"GET","header":[],"url":"{{HOST}}:{{PORT}}/{{API_BASE_PATH}}/branches","description":"<h2 id=\"listar-sedes\">Listar Sedes</h2>\n<p>Obtiene la lista completa de sedes de coworking registradas en el sistema.</p>\n<p><strong>Rol requerido:</strong> <code>ADMIN</code></p>\n<h3 id=\"respuesta-exitosa-200-ok\">Respuesta exitosa <code>200 OK</code></h3>\n<p>Retorna un arreglo con todas las sedes, incluyendo: id, nombre, dirección, capacidad máxima, costo por hora y ocupación actual.</p>\n","urlObject":{"port":"{{PORT}}","path":["{{API_BASE_PATH}}","branches"],"host":["{{HOST}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"33f5a946-4892-4a63-bd86-d38dd705e30e"},{"name":"Detail","id":"2153cc2d-aeaf-4013-b738-da7a2a8f1010","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{TOKEN}}"}]},"isInherited":false},"method":"GET","header":[],"url":"{{HOST}}:{{PORT}}/{{API_BASE_PATH}}/branches/{{BRANCH_ID}}","description":"<h2 id=\"detalle-de-sede\">Detalle de Sede</h2>\n<p>Obtiene la información detallada de una sede específica.</p>\n<p><strong>Rol requerido:</strong> <code>ADMIN</code></p>\n<h3 id=\"path-parameters\">Path Parameters</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parámetro</th>\n<th>Tipo</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>BRANCH_ID</code></td>\n<td>UUID</td>\n<td>ID de la sede a consultar</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"respuesta-exitosa-200-ok\">Respuesta exitosa <code>200 OK</code></h3>\n<p>Retorna los datos completos de la sede: id, nombre, dirección, capacidad máxima, costo por hora y ocupación actual.</p>\n<h3 id=\"errores-comunes\">Errores comunes</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Código</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>404</code></td>\n<td>Sede no encontrada</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"port":"{{PORT}}","path":["{{API_BASE_PATH}}","branches","{{BRANCH_ID}}"],"host":["{{HOST}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"2153cc2d-aeaf-4013-b738-da7a2a8f1010"},{"name":"List Operators","id":"1e86fd7b-205c-449c-95f4-37ab6f2b6e62","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{TOKEN}}"}]},"isInherited":false},"method":"GET","header":[],"url":"{{HOST}}:{{PORT}}/{{API_BASE_PATH}}/branches/{{BRANCH_ID}}/operators","description":"<h2 id=\"listar-operadores-de-sede\">Listar Operadores de Sede</h2>\n<p>Obtiene la lista de operadores asignados a una sede específica.</p>\n<p><strong>Rol requerido:</strong> <code>ADMIN</code></p>\n<h3 id=\"path-parameters\">Path Parameters</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parámetro</th>\n<th>Tipo</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>BRANCH_ID</code></td>\n<td>UUID</td>\n<td>ID de la sede</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"respuesta-exitosa-200-ok\">Respuesta exitosa <code>200 OK</code></h3>\n<p>Retorna un arreglo con los operadores asignados a la sede, incluyendo sus datos básicos (id, nombre, email).</p>\n<h3 id=\"errores-comunes\">Errores comunes</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Código</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>404</code></td>\n<td>Sede no encontrada</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"port":"{{PORT}}","path":["{{API_BASE_PATH}}","branches","{{BRANCH_ID}}","operators"],"host":["{{HOST}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"1e86fd7b-205c-449c-95f4-37ab6f2b6e62"},{"name":"Create","id":"bfffb929-0035-455f-bb90-caada868705b","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{TOKEN}}"}]},"isInherited":false},"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"name\": \"Sucursal de prueba\",\n    \"address\": \"Calle 1, ceiba\",\n    \"maxCapacity\": 10,\n    \"hourlyRate\": 20000\n}","options":{"raw":{"language":"json"}}},"url":"{{HOST}}:{{PORT}}/{{API_BASE_PATH}}/branches","description":"<h2 id=\"crear-sede\">Crear Sede</h2>\n<p>Registra una nueva sede de coworking en el sistema.</p>\n<p><strong>Rol requerido:</strong> <code>ADMIN</code></p>\n<h3 id=\"body-json\">Body (JSON)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>Requerido</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>name</code></td>\n<td>string</td>\n<td>Sí</td>\n<td>Nombre de la sede</td>\n</tr>\n<tr>\n<td><code>address</code></td>\n<td>string</td>\n<td>Sí</td>\n<td>Dirección física</td>\n</tr>\n<tr>\n<td><code>maxCapacity</code></td>\n<td>number</td>\n<td>Sí</td>\n<td>Capacidad máxima simultánea de personas</td>\n</tr>\n<tr>\n<td><code>hourlyRate</code></td>\n<td>number</td>\n<td>Sí</td>\n<td>Costo por hora de permanencia (COP)</td>\n</tr>\n</tbody>\n</table>\n</div><pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"name\": \"Sucursal de prueba\",\n  \"address\": \"Calle 1, ceiba\",\n  \"maxCapacity\": 10,\n  \"hourlyRate\": 20000\n}\n</code></pre>\n<h3 id=\"respuesta-exitosa-201-created\">Respuesta exitosa <code>201 Created</code></h3>\n<p>Retorna la sede creada con su ID asignado.</p>\n<h3 id=\"errores-comunes\">Errores comunes</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Código</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>400</code></td>\n<td>Datos inválidos o campos faltantes</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"port":"{{PORT}}","path":["{{API_BASE_PATH}}","branches"],"host":["{{HOST}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"bfffb929-0035-455f-bb90-caada868705b"},{"name":"Add operator","id":"1fee1aa5-9556-4e4e-891e-da9f0d2f272e","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{TOKEN}}"}]},"isInherited":false},"method":"POST","header":[],"url":"{{HOST}}:{{PORT}}/{{API_BASE_PATH}}/branches/{{BRANCH_ID}}/operators/{{OPERATOR_ID}}","description":"<h2 id=\"asignar-operador-a-sede\">Asignar Operador a Sede</h2>\n<p>Asocia un usuario con rol OPERADOR a una sede específica, permitiéndole gestionar los accesos de dicha sede.</p>\n<p><strong>Rol requerido:</strong> <code>ADMIN</code></p>\n<h3 id=\"path-parameters\">Path Parameters</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parámetro</th>\n<th>Tipo</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>BRANCH_ID</code></td>\n<td>UUID</td>\n<td>ID de la sede</td>\n</tr>\n<tr>\n<td><code>OPERATOR_ID</code></td>\n<td>UUID</td>\n<td>ID del operador a asignar</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"respuesta-exitosa-200-ok\">Respuesta exitosa <code>200 OK</code></h3>\n<p>Confirma la asignación del operador a la sede.</p>\n<h3 id=\"errores-comunes\">Errores comunes</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Código</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>404</code></td>\n<td>Sede u operador no encontrado</td>\n</tr>\n<tr>\n<td><code>400</code></td>\n<td>El usuario no tiene rol OPERADOR</td>\n</tr>\n<tr>\n<td><code>409</code></td>\n<td>El operador ya está asignado a esta sede</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"port":"{{PORT}}","path":["{{API_BASE_PATH}}","branches","{{BRANCH_ID}}","operators","{{OPERATOR_ID}}"],"host":["{{HOST}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"1fee1aa5-9556-4e4e-891e-da9f0d2f272e"},{"name":"Update","id":"b20fc392-265b-4ceb-acd0-25d7ba417c03","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{TOKEN}}"}]},"isInherited":false},"method":"PATCH","header":[],"body":{"mode":"raw","raw":"{\n    \"name\": \"Sucursal de prueba\",\n    \"address\": \"Calle 1, ceiba\",\n    \"maxCapacity\": 10,\n    \"hourlyRate\": 20000\n}","options":{"raw":{"language":"json"}}},"url":"{{HOST}}:{{PORT}}/{{API_BASE_PATH}}/branches/{{BRANCH_ID}}","description":"<h2 id=\"actualizar-sede\">Actualizar Sede</h2>\n<p>Modifica los datos de una sede existente. Solo se envían los campos que se desean actualizar.</p>\n<p><strong>Rol requerido:</strong> <code>ADMIN</code></p>\n<h3 id=\"path-parameters\">Path Parameters</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parámetro</th>\n<th>Tipo</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>BRANCH_ID</code></td>\n<td>UUID</td>\n<td>ID de la sede a actualizar</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"body-json\">Body (JSON)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>Requerido</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>name</code></td>\n<td>string</td>\n<td>No</td>\n<td>Nombre de la sede</td>\n</tr>\n<tr>\n<td><code>address</code></td>\n<td>string</td>\n<td>No</td>\n<td>Dirección física</td>\n</tr>\n<tr>\n<td><code>maxCapacity</code></td>\n<td>number</td>\n<td>No</td>\n<td>Capacidad máxima simultánea</td>\n</tr>\n<tr>\n<td><code>hourlyRate</code></td>\n<td>number</td>\n<td>No</td>\n<td>Costo por hora (COP)</td>\n</tr>\n</tbody>\n</table>\n</div><pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"name\": \"Sucursal de prueba\",\n  \"address\": \"Calle 1, ceiba\",\n  \"maxCapacity\": 10,\n  \"hourlyRate\": 20000\n}\n</code></pre>\n<h3 id=\"respuesta-exitosa-200-ok\">Respuesta exitosa <code>200 OK</code></h3>\n<p>Retorna la sede con los datos actualizados.</p>\n<h3 id=\"errores-comunes\">Errores comunes</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Código</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>404</code></td>\n<td>Sede no encontrada</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"port":"{{PORT}}","path":["{{API_BASE_PATH}}","branches","{{BRANCH_ID}}"],"host":["{{HOST}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"b20fc392-265b-4ceb-acd0-25d7ba417c03"},{"name":"Delete","id":"0b7dd9e3-34c3-41dd-bf6c-e3f36c960891","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{TOKEN}}"}]},"isInherited":false},"method":"DELETE","header":[],"url":"{{HOST}}:{{PORT}}/{{API_BASE_PATH}}/branches/{{BRANCH_ID}}","description":"<h2 id=\"eliminar-sede\">Eliminar Sede</h2>\n<p>Elimina una sede del sistema de forma permanente.</p>\n<p><strong>Rol requerido:</strong> <code>ADMIN</code></p>\n<h3 id=\"path-parameters\">Path Parameters</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parámetro</th>\n<th>Tipo</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>BRANCH_ID</code></td>\n<td>UUID</td>\n<td>ID de la sede a eliminar</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"respuesta-exitosa-204-no-content\">Respuesta exitosa <code>204 No Content</code></h3>\n<p>La sede ha sido eliminada exitosamente. No retorna contenido.</p>\n<h3 id=\"errores-comunes\">Errores comunes</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Código</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>404</code></td>\n<td>Sede no encontrada</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"port":"{{PORT}}","path":["{{API_BASE_PATH}}","branches","{{BRANCH_ID}}"],"host":["{{HOST}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"0b7dd9e3-34c3-41dd-bf6c-e3f36c960891"},{"name":"Delete operator","id":"0b4ed1e8-874f-4b01-88b1-c2e09c8225a7","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{TOKEN}}"}]},"isInherited":false},"method":"DELETE","header":[],"url":"{{HOST}}:{{PORT}}/{{API_BASE_PATH}}/branches/{{BRANCH_ID}}/operators/{{OPERATOR_ID}}","description":"<h2 id=\"desasignar-operador-de-sede\">Desasignar Operador de Sede</h2>\n<p>Remueve la asociación de un operador con una sede específica. El operador dejará de poder gestionar los accesos de dicha sede.</p>\n<p><strong>Rol requerido:</strong> <code>ADMIN</code></p>\n<h3 id=\"path-parameters\">Path Parameters</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parámetro</th>\n<th>Tipo</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>BRANCH_ID</code></td>\n<td>UUID</td>\n<td>ID de la sede</td>\n</tr>\n<tr>\n<td><code>OPERATOR_ID</code></td>\n<td>UUID</td>\n<td>ID del operador a desasignar</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"respuesta-exitosa-204-no-content\">Respuesta exitosa <code>204 No Content</code></h3>\n<p>El operador ha sido desasignado exitosamente.</p>\n<h3 id=\"errores-comunes\">Errores comunes</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Código</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>404</code></td>\n<td>Sede u operador no encontrado</td>\n</tr>\n<tr>\n<td><code>400</code></td>\n<td>El operador no está asignado a esta sede</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"port":"{{PORT}}","path":["{{API_BASE_PATH}}","branches","{{BRANCH_ID}}","operators","{{OPERATOR_ID}}"],"host":["{{HOST}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"0b4ed1e8-874f-4b01-88b1-c2e09c8225a7"}],"id":"1033ed60-602e-4a81-8e6b-e2c1abf5dc2f","description":"<h1 id=\"branch-sedes\">Branch (Sedes)</h1>\n<p>CRUD completo de sedes de coworking y gestión de operadores asignados. Cada sede contiene: nombre, dirección, capacidad máxima simultánea y costo por hora.</p>\n<p><strong>Permisos requeridos:</strong> <code>ADMIN</code> para todas las operaciones.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Operación</th>\n<th>Método</th>\n<th>Endpoint</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Listar sedes</td>\n<td><code>GET</code></td>\n<td><code>/branches</code></td>\n</tr>\n<tr>\n<td>Detalle de sede</td>\n<td><code>GET</code></td>\n<td><code>/branches/:id</code></td>\n</tr>\n<tr>\n<td>Listar operadores de sede</td>\n<td><code>GET</code></td>\n<td><code>/branches/:id/operators</code></td>\n</tr>\n<tr>\n<td>Crear sede</td>\n<td><code>POST</code></td>\n<td><code>/branches</code></td>\n</tr>\n<tr>\n<td>Asignar operador</td>\n<td><code>POST</code></td>\n<td><code>/branches/:id/operators/:operatorId</code></td>\n</tr>\n<tr>\n<td>Actualizar sede</td>\n<td><code>PATCH</code></td>\n<td><code>/branches/:id</code></td>\n</tr>\n<tr>\n<td>Eliminar sede</td>\n<td><code>DELETE</code></td>\n<td><code>/branches/:id</code></td>\n</tr>\n<tr>\n<td>Desasignar operador</td>\n<td><code>DELETE</code></td>\n<td><code>/branches/:id/operators/:operatorId</code></td>\n</tr>\n</tbody>\n</table>\n</div>","_postman_id":"1033ed60-602e-4a81-8e6b-e2c1abf5dc2f"},{"name":"Access","item":[{"name":"List by branch","id":"3c8e43a3-2acc-4444-9ab5-53693b55d308","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{TOKEN}}"}]},"isInherited":false},"method":"GET","header":[],"url":"{{HOST}}:{{PORT}}/{{API_BASE_PATH}}/branches/{{BRANCH_ID}}/accesses","description":"<h2 id=\"listar-accesos-por-sede\">Listar Accesos por Sede</h2>\n<p>Obtiene la lista de accesos activos (personas actualmente dentro) de una sede específica.</p>\n<p><strong>Rol requerido:</strong> <code>OPERADOR</code> (sede asignada) o <code>ADMIN</code></p>\n<h3 id=\"path-parameters\">Path Parameters</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parámetro</th>\n<th>Tipo</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>BRANCH_ID</code></td>\n<td>UUID</td>\n<td>ID de la sede</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"respuesta-exitosa-200-ok\">Respuesta exitosa <code>200 OK</code></h3>\n<p>Retorna un arreglo con los accesos activos, incluyendo: documento de la persona, email, fecha/hora de ingreso y tiempo transcurrido.</p>\n<h3 id=\"errores-comunes\">Errores comunes</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Código</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>404</code></td>\n<td>Sede no encontrada</td>\n</tr>\n<tr>\n<td><code>403</code></td>\n<td>Operador no asignado a esta sede</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"port":"{{PORT}}","path":["{{API_BASE_PATH}}","branches","{{BRANCH_ID}}","accesses"],"host":["{{HOST}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"3c8e43a3-2acc-4444-9ab5-53693b55d308"},{"name":"List All access","id":"fdfda188-e28b-4935-b91a-d3c05b6166ae","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{TOKEN}}"}]},"isInherited":false},"method":"GET","header":[],"url":"{{HOST}}:{{PORT}}/{{API_BASE_PATH}}/accesses","description":"<h2 id=\"listar-todos-los-accesos\">Listar Todos los Accesos</h2>\n<p>Obtiene la lista completa de todos los accesos activos en todas las sedes del sistema.</p>\n<p><strong>Rol requerido:</strong> <code>ADMIN</code></p>\n<h3 id=\"respuesta-exitosa-200-ok\">Respuesta exitosa <code>200 OK</code></h3>\n<p>Retorna un arreglo con todos los accesos activos del sistema, incluyendo la información de la sede, documento de la persona, email y fecha/hora de ingreso.</p>\n","urlObject":{"port":"{{PORT}}","path":["{{API_BASE_PATH}}","accesses"],"host":["{{HOST}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"fdfda188-e28b-4935-b91a-d3c05b6166ae"},{"name":"Check-in","id":"d66e3f26-d8db-4c97-8332-eb075557f5b9","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{TOKEN}}"}]},"isInherited":false},"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"email\": \"ingeeduar20@gmail.com\",\n    \"document\": \"1010101010\"\n}","options":{"raw":{"language":"json"}}},"url":"{{HOST}}:{{PORT}}/{{API_BASE_PATH}}/branches/{{BRANCH_ID}}/accesses","description":"<h2 id=\"registrar-ingreso-check-in\">Registrar Ingreso (Check-in)</h2>\n<p>Registra el ingreso de una persona a una sede de coworking.</p>\n<p><strong>Rol requerido:</strong> <code>OPERADOR</code> (sede asignada) o <code>ADMIN</code></p>\n<h3 id=\"path-parameters\">Path Parameters</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parámetro</th>\n<th>Tipo</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>BRANCH_ID</code></td>\n<td>UUID</td>\n<td>ID de la sede donde se registra el ingreso</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"body-json\">Body (JSON)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>Requerido</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>email</code></td>\n<td>string</td>\n<td>Sí</td>\n<td>Correo electrónico de la persona</td>\n</tr>\n<tr>\n<td><code>document</code></td>\n<td>string</td>\n<td>Sí</td>\n<td>Número de documento de identidad</td>\n</tr>\n</tbody>\n</table>\n</div><pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"email\": \"ingeeduar20@gmail.com\",\n  \"document\": \"1010101010\"\n}\n</code></pre>\n<h3 id=\"reglas-de-negocio\">Reglas de negocio</h3>\n<ul>\n<li>No puede existir un ingreso activo del mismo documento en <strong>ninguna</strong> sede</li>\n<li>Se valida que la sede tenga capacidad disponible antes de registrar</li>\n<li>Se registra la fecha y hora exacta del ingreso</li>\n</ul>\n<h3 id=\"respuesta-exitosa-201-created\">Respuesta exitosa <code>201 Created</code></h3>\n<p>Retorna el registro de acceso creado con la información del ingreso.</p>\n<h3 id=\"errores-comunes\">Errores comunes</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Código</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>400</code></td>\n<td>La persona ya tiene un ingreso activo en alguna sede</td>\n</tr>\n<tr>\n<td><code>400</code></td>\n<td>La sede ha alcanzado su capacidad máxima</td>\n</tr>\n<tr>\n<td><code>404</code></td>\n<td>Sede no encontrada</td>\n</tr>\n<tr>\n<td><code>403</code></td>\n<td>Operador no asignado a esta sede</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"port":"{{PORT}}","path":["{{API_BASE_PATH}}","branches","{{BRANCH_ID}}","accesses"],"host":["{{HOST}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"d66e3f26-d8db-4c97-8332-eb075557f5b9"},{"name":"Check-out","id":"a06461dd-7eb5-4e39-8707-98a8a9a995b0","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{TOKEN}}"}]},"isInherited":false},"method":"PATCH","header":[],"body":{"mode":"raw","raw":"{\n    \"document\": \"1010101010\"\n}","options":{"raw":{"language":"json"}}},"url":"{{HOST}}:{{PORT}}/{{API_BASE_PATH}}/branches/{{BRANCH_ID}}/accesses/checkout","description":"<h2 id=\"registrar-salida-check-out\">Registrar Salida (Check-out)</h2>\n<p>Registra la salida de una persona de una sede de coworking, calculando el valor a pagar según el tiempo de permanencia.</p>\n<p><strong>Rol requerido:</strong> <code>OPERADOR</code> (sede asignada) o <code>ADMIN</code></p>\n<h3 id=\"path-parameters\">Path Parameters</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parámetro</th>\n<th>Tipo</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>BRANCH_ID</code></td>\n<td>UUID</td>\n<td>ID de la sede donde se registra la salida</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"body-json\">Body (JSON)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Campo</th>\n<th>Tipo</th>\n<th>Requerido</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>document</code></td>\n<td>string</td>\n<td>Sí</td>\n<td>Número de documento de la persona</td>\n</tr>\n</tbody>\n</table>\n</div><pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"document\": \"1010101010\"\n}\n</code></pre>\n<h3 id=\"reglas-de-negocio\">Reglas de negocio</h3>\n<ul>\n<li>Debe existir un ingreso activo de la persona en esta sede</li>\n<li>Se registra la fecha y hora exacta de salida</li>\n<li>Se calcula el valor a pagar: <code>tiempo_permanencia x costo_por_hora</code></li>\n<li>El registro se mueve al histórico de accesos</li>\n<li>Se libera un cupo en la sede</li>\n<li>Si la persona acumula más de <strong>20 horas</strong> en esta sede, se genera un cupón de fidelidad y se envía notificación</li>\n</ul>\n<h3 id=\"respuesta-exitosa-200-ok\">Respuesta exitosa <code>200 OK</code></h3>\n<p>Retorna el registro de acceso con la información de salida, tiempo de permanencia y valor a pagar.</p>\n<h3 id=\"errores-comunes\">Errores comunes</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Código</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>400</code></td>\n<td>No existe ingreso activo para este documento en esta sede</td>\n</tr>\n<tr>\n<td><code>404</code></td>\n<td>Sede no encontrada</td>\n</tr>\n<tr>\n<td><code>403</code></td>\n<td>Operador no asignado a esta sede</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"port":"{{PORT}}","path":["{{API_BASE_PATH}}","branches","{{BRANCH_ID}}","accesses","checkout"],"host":["{{HOST}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"a06461dd-7eb5-4e39-8707-98a8a9a995b0"}],"id":"f8c120ad-d315-4dc6-8165-d9b04440a3a1","description":"<h1 id=\"access-control-de-acceso\">Access (Control de Acceso)</h1>\n<p>Registro de ingresos (check-in) y salidas (check-out) de personas en las sedes de coworking.</p>\n<p><strong>Reglas de negocio:</strong></p>\n<ul>\n<li>No puede existir un ingreso activo del mismo documento en ninguna sede</li>\n<li>Se valida la capacidad disponible de la sede antes del ingreso</li>\n<li>Al registrar la salida, se calcula el valor a pagar según el tiempo de permanencia</li>\n<li>Si una persona acumula más de 20 horas en una sede, se genera automáticamente un cupón de fidelidad</li>\n<li>Se envía notificación al microservicio simulado cuando aplique</li>\n</ul>\n<p><strong>Permisos requeridos:</strong> <code>OPERADOR</code> (solo en sedes asignadas) y <code>ADMIN</code>.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Operación</th>\n<th>Método</th>\n<th>Endpoint</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Listar accesos por sede</td>\n<td><code>GET</code></td>\n<td><code>/branches/:id/accesses</code></td>\n</tr>\n<tr>\n<td>Listar todos los accesos</td>\n<td><code>GET</code></td>\n<td><code>/accesses</code></td>\n</tr>\n<tr>\n<td>Check-in</td>\n<td><code>POST</code></td>\n<td><code>/branches/:id/accesses</code></td>\n</tr>\n<tr>\n<td>Check-out</td>\n<td><code>PATCH</code></td>\n<td><code>/branches/:id/accesses/checkout</code></td>\n</tr>\n</tbody>\n</table>\n</div>","_postman_id":"f8c120ad-d315-4dc6-8165-d9b04440a3a1"},{"name":"Indicators","item":[{"name":"Client top access","id":"3500d021-1e95-44e4-8aa2-835e19162a17","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{TOKEN}}"}]},"isInherited":false},"method":"GET","header":[],"url":"{{HOST}}:{{PORT}}/{{API_BASE_PATH}}/indicators/clients/top-accesses","description":"<h2 id=\"top-clientes-por-accesos-global\">Top Clientes por Accesos (Global)</h2>\n<p>Obtiene el ranking de las 10 personas con más ingresos registrados en todo el sistema.</p>\n<p><strong>Rol requerido:</strong> <code>ADMIN</code> o <code>OPERADOR</code></p>\n<h3 id=\"respuesta-exitosa-200-ok\">Respuesta exitosa <code>200 OK</code></h3>\n<p>Retorna un arreglo ordenado con las 10 personas que más veces han ingresado al sistema, incluyendo: documento, nombre/email y cantidad total de ingresos.</p>\n","urlObject":{"port":"{{PORT}}","path":["{{API_BASE_PATH}}","indicators","clients","top-accesses"],"host":["{{HOST}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"3500d021-1e95-44e4-8aa2-835e19162a17"},{"name":"Branch client top access","id":"81537309-8502-4815-a049-3fdafdee7a96","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{TOKEN}}"}]},"isInherited":false},"method":"GET","header":[],"url":"{{HOST}}:{{PORT}}/{{API_BASE_PATH}}/indicators/branches/{{BRANCH_ID}}/persons/top-accesses","description":"<h2 id=\"top-clientes-por-accesos-en-sede\">Top Clientes por Accesos en Sede</h2>\n<p>Obtiene el ranking de las 10 personas con más ingresos en una sede específica.</p>\n<p><strong>Rol requerido:</strong> <code>ADMIN</code> o <code>OPERADOR</code></p>\n<h3 id=\"path-parameters\">Path Parameters</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parámetro</th>\n<th>Tipo</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>BRANCH_ID</code></td>\n<td>UUID</td>\n<td>ID de la sede</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"respuesta-exitosa-200-ok\">Respuesta exitosa <code>200 OK</code></h3>\n<p>Retorna un arreglo ordenado con las 10 personas que más veces han ingresado a la sede indicada.</p>\n<h3 id=\"errores-comunes\">Errores comunes</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Código</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>404</code></td>\n<td>Sede no encontrada</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"port":"{{PORT}}","path":["{{API_BASE_PATH}}","indicators","branches","{{BRANCH_ID}}","persons","top-accesses"],"host":["{{HOST}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"81537309-8502-4815-a049-3fdafdee7a96"},{"name":"Client first time","id":"c9177abc-5613-4379-a735-f3e5b55e1899","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{TOKEN}}"}]},"isInherited":false},"method":"GET","header":[],"url":"{{HOST}}:{{PORT}}/{{API_BASE_PATH}}/indicators/clients/first-time","description":"<h2 id=\"clientes-primera-vez\">Clientes Primera Vez</h2>\n<p>Obtiene la lista de personas que han ingresado por primera vez al sistema de coworking.</p>\n<p><strong>Rol requerido:</strong> <code>ADMIN</code> o <code>OPERADOR</code></p>\n<h3 id=\"respuesta-exitosa-200-ok\">Respuesta exitosa <code>200 OK</code></h3>\n<p>Retorna un arreglo con las personas que registran un único ingreso en el sistema, incluyendo: documento, email y fecha de su primer ingreso.</p>\n","urlObject":{"port":"{{PORT}}","path":["{{API_BASE_PATH}}","indicators","clients","first-time"],"host":["{{HOST}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"c9177abc-5613-4379-a735-f3e5b55e1899"},{"name":"Revenue by branch","id":"e1360b9a-ade5-44be-b154-782e802adee7","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{TOKEN}}"}]},"isInherited":false},"method":"GET","header":[],"url":"{{HOST}}:{{PORT}}/{{API_BASE_PATH}}/indicators/branches/{{BRANCH_ID}}/revenue","description":"<h2 id=\"ingresos-económicos-por-sede\">Ingresos Económicos por Sede</h2>\n<p>Obtiene los ingresos económicos (facturación) de una sede específica, desglosados por período de tiempo.</p>\n<p><strong>Rol requerido:</strong> <code>OPERADOR</code> (sede asignada)</p>\n<h3 id=\"path-parameters\">Path Parameters</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parámetro</th>\n<th>Tipo</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>BRANCH_ID</code></td>\n<td>UUID</td>\n<td>ID de la sede</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"respuesta-exitosa-200-ok\">Respuesta exitosa <code>200 OK</code></h3>\n<p>Retorna los ingresos económicos de la sede desglosados en: Hoy, Semana, Mes y Año.</p>\n<h3 id=\"errores-comunes\">Errores comunes</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Código</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>404</code></td>\n<td>Sede no encontrada</td>\n</tr>\n<tr>\n<td><code>403</code></td>\n<td>Operador no asignado a esta sede</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"port":"{{PORT}}","path":["{{API_BASE_PATH}}","indicators","branches","{{BRANCH_ID}}","revenue"],"host":["{{HOST}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"e1360b9a-ade5-44be-b154-782e802adee7"},{"name":"Top revenue operators weekly","id":"cb5fdbca-e8f2-4c0d-9b72-3b4c4171127e","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{TOKEN}}"}]},"isInherited":false},"method":"GET","header":[],"url":"{{HOST}}:{{PORT}}/{{API_BASE_PATH}}/indicators/operators/top-revenue/weekly","description":"<h2 id=\"top-operadores-por-ingresos-semanales\">Top Operadores por Ingresos Semanales</h2>\n<p>Obtiene el ranking de los 3 operadores que han registrado más ingresos (check-ins) durante la semana en curso.</p>\n<p><strong>Rol requerido:</strong> <code>ADMIN</code></p>\n<h3 id=\"respuesta-exitosa-200-ok\">Respuesta exitosa <code>200 OK</code></h3>\n<p>Retorna un arreglo ordenado con los 3 operadores más activos de la semana, incluyendo: nombre, email y cantidad de ingresos registrados.</p>\n","urlObject":{"port":"{{PORT}}","path":["{{API_BASE_PATH}}","indicators","operators","top-revenue","weekly"],"host":["{{HOST}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"cb5fdbca-e8f2-4c0d-9b72-3b4c4171127e"},{"name":"Top revenue branches weekly","id":"d2575294-42f3-459e-902b-7e93caab3d95","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{TOKEN}}"}]},"isInherited":false},"method":"GET","header":[],"url":"{{HOST}}:{{PORT}}/{{API_BASE_PATH}}/indicators/branches/top-revenue/weekly","description":"<h2 id=\"top-sedes-por-facturación-semanal\">Top Sedes por Facturación Semanal</h2>\n<p>Obtiene el ranking de las 3 sedes con mayor facturación durante la semana en curso.</p>\n<p><strong>Rol requerido:</strong> <code>ADMIN</code></p>\n<h3 id=\"respuesta-exitosa-200-ok\">Respuesta exitosa <code>200 OK</code></h3>\n<p>Retorna un arreglo ordenado con las 3 sedes que más han facturado en la semana, incluyendo: nombre de la sede, dirección y monto total facturado.</p>\n","urlObject":{"port":"{{PORT}}","path":["{{API_BASE_PATH}}","indicators","branches","top-revenue","weekly"],"host":["{{HOST}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"d2575294-42f3-459e-902b-7e93caab3d95"}],"id":"813c9d45-0177-43e1-b5e1-f003114ee92f","description":"<h1 id=\"indicators-indicadores\">Indicators (Indicadores)</h1>\n<p>Métricas y estadísticas del sistema para la toma de decisiones. Los indicadores varían según el rol del usuario.</p>\n<p><strong>Indicadores disponibles para ADMIN y OPERADOR:</strong></p>\n<ul>\n<li>Top 10 personas con más ingresos (global)</li>\n<li>Top 10 personas con más ingresos por sede</li>\n<li>Personas que ingresan por primera vez</li>\n</ul>\n<p><strong>Solo OPERADOR:</strong></p>\n<ul>\n<li>Ingresos económicos por sede (hoy, semana, mes, año)</li>\n</ul>\n<p><strong>Solo ADMIN:</strong></p>\n<ul>\n<li>Top 3 operadores con más ingresos en la semana</li>\n<li>Top 3 sedes con mayor facturación semanal</li>\n</ul>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Indicador</th>\n<th>Método</th>\n<th>Endpoint</th>\n<th>Rol</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Top accesos global</td>\n<td><code>GET</code></td>\n<td><code>/indicators/clients/top-accesses</code></td>\n<td>ADMIN, OPERADOR</td>\n</tr>\n<tr>\n<td>Top accesos por sede</td>\n<td><code>GET</code></td>\n<td><code>/indicators/branches/:id/persons/top-accesses</code></td>\n<td>ADMIN, OPERADOR</td>\n</tr>\n<tr>\n<td>Primera vez</td>\n<td><code>GET</code></td>\n<td><code>/indicators/clients/first-time</code></td>\n<td>ADMIN, OPERADOR</td>\n</tr>\n<tr>\n<td>Ingresos por sede</td>\n<td><code>GET</code></td>\n<td><code>/indicators/branches/:id/revenue</code></td>\n<td>OPERADOR</td>\n</tr>\n<tr>\n<td>Top operadores semanal</td>\n<td><code>GET</code></td>\n<td><code>/indicators/operators/top-revenue/weekly</code></td>\n<td>ADMIN</td>\n</tr>\n<tr>\n<td>Top sedes semanal</td>\n<td><code>GET</code></td>\n<td><code>/indicators/branches/top-revenue/weekly</code></td>\n<td>ADMIN</td>\n</tr>\n</tbody>\n</table>\n</div>","_postman_id":"813c9d45-0177-43e1-b5e1-f003114ee92f"},{"name":"Coupons","item":[{"name":"Coupons by branch","id":"a02e1310-15ca-48b2-9be9-25e986ae2483","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{TOKEN}}"}]},"isInherited":false},"method":"GET","header":[],"url":"{{HOST}}:{{PORT}}/{{API_BASE_PATH}}/coupons/branches/{{BRANCH_ID}}","description":"<h2 id=\"cupones-por-sede\">Cupones por Sede</h2>\n<p>Obtiene la lista de todos los cupones de fidelidad generados para una sede específica.</p>\n<p><strong>Rol requerido:</strong> <code>ADMIN</code> o <code>OPERADOR</code></p>\n<h3 id=\"path-parameters\">Path Parameters</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parámetro</th>\n<th>Tipo</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>BRANCH_ID</code></td>\n<td>UUID</td>\n<td>ID de la sede</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"respuesta-exitosa-200-ok\">Respuesta exitosa <code>200 OK</code></h3>\n<p>Retorna un arreglo con los cupones de la sede, incluyendo: código del cupón, documento del cliente, estado (ACTIVO, UTILIZADO, EXPIRADO), fecha de generación y fecha de vencimiento.</p>\n<h3 id=\"errores-comunes\">Errores comunes</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Código</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>404</code></td>\n<td>Sede no encontrada</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"port":"{{PORT}}","path":["{{API_BASE_PATH}}","coupons","branches","{{BRANCH_ID}}"],"host":["{{HOST}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"a02e1310-15ca-48b2-9be9-25e986ae2483"},{"name":"Client coupon in branch","id":"46997cfd-c90b-4940-9dac-5586b7358c12","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{TOKEN}}"}]},"isInherited":false},"method":"GET","header":[],"url":"{{HOST}}:{{PORT}}/{{API_BASE_PATH}}/coupons/branches/{{BRANCH_ID}}/clients/{{CLIENT_DOCUMENT}}","description":"<h2 id=\"cupón-de-cliente-en-sede\">Cupón de Cliente en Sede</h2>\n<p>Consulta el cupón de fidelidad de un cliente específico en una sede determinada.</p>\n<p><strong>Rol requerido:</strong> <code>ADMIN</code> o <code>OPERADOR</code></p>\n<h3 id=\"path-parameters\">Path Parameters</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parámetro</th>\n<th>Tipo</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>BRANCH_ID</code></td>\n<td>UUID</td>\n<td>ID de la sede</td>\n</tr>\n<tr>\n<td><code>CLIENT_DOCUMENT</code></td>\n<td>string</td>\n<td>Número de documento del cliente</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"respuesta-exitosa-200-ok\">Respuesta exitosa <code>200 OK</code></h3>\n<p>Retorna la información del cupón del cliente: código, estado, fecha de generación, fecha de vencimiento y fecha de uso (si aplica).</p>\n<h3 id=\"errores-comunes\">Errores comunes</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Código</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>404</code></td>\n<td>Sede no encontrada o el cliente no tiene cupón en esta sede</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"port":"{{PORT}}","path":["{{API_BASE_PATH}}","coupons","branches","{{BRANCH_ID}}","clients","{{CLIENT_DOCUMENT}}"],"host":["{{HOST}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"46997cfd-c90b-4940-9dac-5586b7358c12"},{"name":"Redeem coupon","id":"209803b5-12d6-4885-ba54-6fb778b63cc1","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{TOKEN}}"}]},"isInherited":false},"method":"POST","header":[],"url":"{{HOST}}:{{PORT}}/{{API_BASE_PATH}}/coupons/{{COUPON_CODE}}/redeem","description":"<h2 id=\"redimir-cupón\">Redimir Cupón</h2>\n<p>Marca un cupón de fidelidad como utilizado (redimido).</p>\n<p><strong>Rol requerido:</strong> <code>ADMIN</code> o <code>OPERADOR</code></p>\n<h3 id=\"path-parameters\">Path Parameters</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parámetro</th>\n<th>Tipo</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>COUPON_CODE</code></td>\n<td>string</td>\n<td>Código único del cupón a redimir</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"reglas-de-negocio\">Reglas de negocio</h3>\n<ul>\n<li>El cupón debe estar en estado ACTIVO para poder ser redimido</li>\n<li>No puede redimirse un cupón ya UTILIZADO</li>\n<li>No puede redimirse un cupón EXPIRADO (vencimiento de 10 días)</li>\n<li>Una vez redimido, el estado cambia a UTILIZADO y se registra la fecha de uso</li>\n</ul>\n<h3 id=\"respuesta-exitosa-200-ok\">Respuesta exitosa <code>200 OK</code></h3>\n<p>Retorna el cupón actualizado con estado UTILIZADO y la fecha de redención.</p>\n<h3 id=\"errores-comunes\">Errores comunes</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Código</th>\n<th>Descripción</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>404</code></td>\n<td>Cupón no encontrado</td>\n</tr>\n<tr>\n<td><code>400</code></td>\n<td>El cupón ya fue utilizado</td>\n</tr>\n<tr>\n<td><code>400</code></td>\n<td>El cupón ha expirado</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"port":"{{PORT}}","path":["{{API_BASE_PATH}}","coupons","{{COUPON_CODE}}","redeem"],"host":["{{HOST}}"],"query":[],"variable":[]}},"response":[],"_postman_id":"209803b5-12d6-4885-ba54-6fb778b63cc1"}],"id":"0d3a61cf-9100-41aa-9c90-71e8876739d2","description":"<h1 id=\"coupons-cupones-de-fidelidad\">Coupons (Cupones de Fidelidad)</h1>\n<p>Gestión de cupones generados automáticamente por el sistema de fidelidad. Un cupón se genera cuando una persona acumula más de <strong>20 horas</strong> de permanencia en una misma sede.</p>\n<p><strong>Reglas del cupón:</strong></p>\n<ul>\n<li>Se otorga una única vez por persona y por sede</li>\n<li>Vigencia de 10 días calendario desde su generación</li>\n<li>Puede marcarse como utilizado (redimido)</li>\n<li>No puede reutilizarse una vez redimido</li>\n<li>Si expira, se registra como <code>EXPIRADO</code> y no podrá redimirse</li>\n</ul>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Operación</th>\n<th>Método</th>\n<th>Endpoint</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Cupones por sede</td>\n<td><code>GET</code></td>\n<td><code>/coupons/branches/:id</code></td>\n</tr>\n<tr>\n<td>Cupón de cliente en sede</td>\n<td><code>GET</code></td>\n<td><code>/coupons/branches/:id/clients/:document</code></td>\n</tr>\n<tr>\n<td>Redimir cupón</td>\n<td><code>POST</code></td>\n<td><code>/coupons/:code/redeem</code></td>\n</tr>\n</tbody>\n</table>\n</div>","_postman_id":"0d3a61cf-9100-41aa-9c90-71e8876739d2"}]}