MII-003: Gestion de Tiendas
id: MII-003
type: Epic
status: Pendiente
priority: P0
phase: 1
story_points: 8
created_date: 2026-01-10
updated_date: 2026-01-10
simco_version: "4.0.0"
Metadata
| Campo |
Valor |
| ID |
MII-003 |
| Nombre |
Gestion de Tiendas |
| Fase |
1 - MVP Core |
| Prioridad |
P0 |
| Story Points |
8 |
| Estado |
Pendiente |
1. Descripcion
Implementar el sistema de gestion de tiendas multi-tenant ligero que permite a un usuario tener multiples tiendas/negocios y opcionalmente invitar operadores.
Objetivo
Permitir a los usuarios crear y gestionar una o mas tiendas, con la posibilidad de asignar roles.
2. Requerimientos Relacionados
| RF |
Descripcion |
Prioridad |
| FR-010 |
Multi-Tiendas (1..N por usuario) |
P0 |
| FR-011 |
Usuarios por tienda con roles (Owner/Operator) |
P2 |
3. Criterios de Aceptacion
AC-001: Crear Tienda
DADO que estoy autenticado
CUANDO creo una nueva tienda con nombre y giro
ENTONCES la tienda se crea exitosamente
Y quedo como Owner de la tienda
Y puedo ver la tienda en mi lista
AC-002: Multiples Tiendas
DADO que tengo una tienda
CUANDO creo otra tienda
ENTONCES ambas aparecen en mi lista
Y puedo seleccionar cual usar para inventarios
AC-003: Editar Tienda
DADO que soy Owner de una tienda
CUANDO edito el nombre o configuracion
ENTONCES los cambios se guardan
Y se reflejan en toda la aplicacion
AC-004: Invitar Operador (P2)
DADO que soy Owner de una tienda
CUANDO invito a un usuario por telefono/email
ENTONCES recibe una invitacion
Y al aceptar puede acceder a la tienda como Operator
AC-005: Cambiar Tienda Activa
DADO que tengo multiples tiendas
CUANDO selecciono otra tienda como activa
ENTONCES el contexto cambia
Y las operaciones se ejecutan sobre la nueva tienda
4. Tareas Tecnicas
| ID |
Tarea |
Estimacion |
Estado |
| T-001 |
Crear modulo stores en NestJS |
1 SP |
Pendiente |
| T-002 |
Implementar entidad Store |
1 SP |
Pendiente |
| T-003 |
Implementar relacion StoreUser |
1 SP |
Pendiente |
| T-004 |
Crear endpoints CRUD tiendas |
2 SP |
Pendiente |
| T-005 |
Implementar middleware de contexto tienda |
1 SP |
Pendiente |
| T-006 |
Crear pantallas tiendas en mobile |
1 SP |
Pendiente |
| T-007 |
Implementar selector de tienda |
1 SP |
Pendiente |
5. Modelo de Datos
Tabla: stores
CREATE TABLE stores (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR(100) NOT NULL,
giro VARCHAR(50),
address VARCHAR(255),
phone VARCHAR(20),
logo_url VARCHAR(500),
settings JSONB DEFAULT '{}',
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
Tabla: store_users
CREATE TABLE store_users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
store_id UUID REFERENCES stores(id) ON DELETE CASCADE,
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
role VARCHAR(20) NOT NULL, -- 'OWNER', 'OPERATOR'
invited_by UUID REFERENCES users(id),
invited_at TIMESTAMP,
accepted_at TIMESTAMP,
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMP DEFAULT NOW(),
UNIQUE(store_id, user_id)
);
Tabla: store_invitations
CREATE TABLE store_invitations (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
store_id UUID REFERENCES stores(id) ON DELETE CASCADE,
invited_by UUID REFERENCES users(id),
email VARCHAR(255),
phone VARCHAR(20),
role VARCHAR(20) NOT NULL,
token VARCHAR(255) UNIQUE,
status VARCHAR(20) DEFAULT 'PENDING', -- 'PENDING', 'ACCEPTED', 'EXPIRED'
expires_at TIMESTAMP,
created_at TIMESTAMP DEFAULT NOW()
);
6. Endpoints API
| Metodo |
Endpoint |
Descripcion |
Auth |
| GET |
/stores |
Listar mis tiendas |
JWT |
| POST |
/stores |
Crear tienda |
JWT |
| GET |
/stores/:id |
Obtener tienda |
JWT + Owner/Operator |
| PATCH |
/stores/:id |
Actualizar tienda |
JWT + Owner |
| DELETE |
/stores/:id |
Eliminar tienda |
JWT + Owner |
| GET |
/stores/:id/users |
Listar usuarios tienda |
JWT + Owner |
| POST |
/stores/:id/invite |
Invitar usuario |
JWT + Owner |
| POST |
/stores/accept-invite |
Aceptar invitacion |
JWT |
| DELETE |
/stores/:id/users/:userId |
Remover usuario |
JWT + Owner |
7. Pantallas Mobile
| Pantalla |
Componentes |
| StoreListScreen |
Lista de tiendas, boton crear |
| CreateStoreScreen |
Form nombre, giro, direccion |
| StoreDetailScreen |
Info, usuarios, configuracion |
| InviteUserScreen |
Input email/telefono, rol |
| StoreSelectorModal |
Lista para cambiar tienda activa |
8. Roles y Permisos
| Permiso |
Owner |
Operator |
| Ver tienda |
✓ |
✓ |
| Editar tienda |
✓ |
✗ |
| Eliminar tienda |
✓ |
✗ |
| Crear inventario |
✓ |
✓ |
| Ver inventarios |
✓ |
✓ |
| Invitar usuarios |
✓ |
✗ |
| Remover usuarios |
✓ |
✗ |
| Ver wallet |
✓ |
✗ |
| Hacer pagos |
✓ |
✗ |
9. Dependencias
Entrada (Requiere)
- MII-001: Infraestructura Base
- MII-002: Autenticacion
Salida (Bloquea)
- MII-004: Captura de Video
- MII-005: Procesamiento IA
- MII-006: Reportes
10. Row-Level Security
-- Politica RLS para stores
CREATE POLICY store_access ON stores
USING (
id IN (
SELECT store_id FROM store_users
WHERE user_id = current_user_id() AND is_active = true
)
);
-- Politica RLS para inventory_sessions
CREATE POLICY session_access ON inventory_sessions
USING (
store_id IN (
SELECT store_id FROM store_users
WHERE user_id = current_user_id() AND is_active = true
)
);
11. Riesgos
| Riesgo |
Probabilidad |
Impacto |
Mitigacion |
| RLS incorrecta |
Media |
Alto |
Tests exhaustivos, auditorias |
| Invitacion fraudulenta |
Baja |
Medio |
Expiracion, verificacion |
| Contexto incorrecto |
Media |
Alto |
Middleware robusto |
12. Notas de Implementacion
- El primer inventario debe crear tienda automaticamente si no existe
- Guardar store_id activo en AsyncStorage
- Considerar soft delete para tiendas (is_active)
- Limitar tiendas por usuario en plan gratuito (post-MVP)
13. Referencias
Ultima Actualizacion: 2026-01-10