Actualiza cierre de Etapa 0 y control de horas
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
# Borradores de seguimiento técnico
|
||||
|
||||
Mensajes preparados; no enviados. Actualizar si los temas se resuelven en la sesión del 22-jul.
|
||||
|
||||
## 1. Correo a Noé y Pedro — salvaguardas y dudas de BIND
|
||||
|
||||
**Asunto:** Balam · Salvaguardas activas y dudas técnicas de la API de BIND
|
||||
|
||||
Hola Noé, Pedro:
|
||||
|
||||
Confirmo que el acceso de BIND se ha utilizado exclusivamente para operaciones de lectura. El cliente bloquea cualquier operación de escritura, controla el número de solicitudes y mantiene el token fuera del repositorio. La validación se realizó sin persistir datos reales y los reportes conservan únicamente estructura y resultados técnicos.
|
||||
|
||||
Para cualquier prueba futura de escritura mantendremos los candados definidos en la propuesta: autorización previa, dry-run, confirmación humana y feature flag desactivado por defecto. Si determinan crear un usuario específico de solo lectura, el cambio de token es transparente porque se carga mediante configuración segura.
|
||||
|
||||
La validación confirmó que el MVP de consulta, aging y descarga de PDF es viable. Quedaron estas dudas para revisar con ustedes:
|
||||
|
||||
1. ¿Existe algún endpoint de pagos individuales o complementos de pago (REP)?
|
||||
2. ¿Tienen la tabla que relaciona el código interno de `CFDIUse` con la clave SAT?
|
||||
3. ¿Qué formato devuelve el endpoint `/{id}/xml`?
|
||||
4. ¿BIND ofrece webhooks o eventos, o debemos operar únicamente con polling?
|
||||
5. ¿Qué token alimenta actualmente el Power BI? Arturo mencionó el suyo y queremos evitar afectar esa integración si se reemplaza el token.
|
||||
|
||||
Quedo atento. Muchas gracias.
|
||||
|
||||
Saludos,
|
||||
Johann Velázquez
|
||||
|
||||
## 2. WhatsApp a Erika/Pedro — flujo de horas en Jira
|
||||
|
||||
> Hola Erika, Pedro. Para mantener al día el corte de horas, ya inicié un control local por actividad. ¿Me ayudan a confirmar cómo debo registrar las horas en Jira y si necesito que me agreguen a algún proyecto o tablero específico? En cuanto tenga acceso concilio lo que ya llevo y continúo reportando ahí.
|
||||
|
||||
## 3. Confirmación al recibir el repositorio
|
||||
|
||||
> Listo, ya recibí la invitación y confirmé que tengo acceso de escritura al repositorio. Muchas gracias. Voy a publicar la estructura inicial del backend y les aviso cuando quede disponible.
|
||||
@@ -0,0 +1,126 @@
|
||||
# Etapa 0 — Hallazgos y decisiones de arquitectura
|
||||
|
||||
**Proyecto:** Plataforma de Automatización Financiera · Balam
|
||||
**Estado:** borrador para cerrar con la validación del prototipo
|
||||
**Última actualización:** 2026-07-15
|
||||
|
||||
## 1. Resultado del Discovery
|
||||
|
||||
El flujo operativo confirmado es:
|
||||
|
||||
**Jira ITSM → cotización en BIND → prefactura → validación humana → CFDI → envío según reglas del cliente → cobranza**
|
||||
|
||||
Reglas de negocio principales:
|
||||
|
||||
- Toda factura debe partir de una cotización en BIND.
|
||||
- La prefactura es obligatoria antes de timbrar.
|
||||
- PPD es el método predeterminado; PUE requiere una decisión consciente.
|
||||
- IVA esperado: 16 % en operación nacional y 0 % para operación extranjera sin efectos fiscales, sujeto a las excepciones fiscales que confirme Balam.
|
||||
- El alta de un cliente nuevo es un flujo separado y requiere definición final de Arturo.
|
||||
- Los recordatorios se desean para todos los clientes; los correos automáticos externos permanecen fuera del MVP original (Anexo B) hasta confirmar alcance.
|
||||
- La cobranza se controla por factura y folio. Debe tolerar diferencias por comisiones/fees conforme a la regla que confirme Arturo.
|
||||
|
||||
## 2. Resultado de la validación de BIND
|
||||
|
||||
La prueba del 6-jul realizó 117 solicitudes exclusivamente GET contra la cuenta real, sin persistir datos de Balam.
|
||||
|
||||
Confirmado:
|
||||
|
||||
- Saldo por factura viable con `Total - Payments - CreditNotes`.
|
||||
- Cotizaciones, prefacturas, facturas, clientes, impuestos, PPD/PUE, vencimientos y PDF son consultables.
|
||||
- Aging y alertas internas son viables sin consultar pagos individuales.
|
||||
- El volumen proyectado de sincronización consume aproximadamente 5 % del límite de 20,000 solicitudes diarias.
|
||||
|
||||
Restricciones:
|
||||
|
||||
- No se encontró endpoint de pagos individuales ni complementos de pago (REP).
|
||||
- BIND no expone el vínculo cotización→factura; la plataforma deberá conservarlo.
|
||||
- Algunos campos clave solo aparecen en el detalle de cada factura.
|
||||
- No hay webhooks confirmados; el diseño base usará sincronización incremental por polling.
|
||||
- El token está acotado a una sola empresa.
|
||||
- La cuenta actual es de producción y puede tener privilegios elevados; no se autoriza escritura todavía.
|
||||
|
||||
Detalle técnico: [`../bind-api-sandbox/VALIDACION-API.md`](../bind-api-sandbox/VALIDACION-API.md).
|
||||
|
||||
## 3. Decisiones de arquitectura
|
||||
|
||||
### ADR-001 · Lectura primero y escritura controlada
|
||||
|
||||
**Decisión:** operar inicialmente en modo solo lectura. Toda escritura futura requiere autorización expresa, dry-run, confirmación humana y feature flag desactivado por defecto.
|
||||
|
||||
**Motivo:** Balam no cuenta con sandbox y una operación incorrecta puede tener efecto fiscal.
|
||||
|
||||
### ADR-002 · Sincronización incremental
|
||||
|
||||
**Decisión:** persistir en PostgreSQL el último punto de sincronización y consultar únicamente registros nuevos o modificados. Paginar siempre con lotes de hasta 100.
|
||||
|
||||
**Motivo:** BIND no ofrece conteos ni `nextLink`; PPD/PUE y días de crédito requieren consultas de detalle.
|
||||
|
||||
### ADR-003 · Trazabilidad propia
|
||||
|
||||
**Decisión:** almacenar las relaciones `ticket Jira → cotización BIND → factura BIND` en la base de datos de la plataforma.
|
||||
|
||||
**Motivo:** la API de BIND no expone de forma confiable el vínculo cotización→factura.
|
||||
|
||||
### ADR-004 · Detección de pagos
|
||||
|
||||
**Decisión:** para el MVP, detectar pagos mediante cambios de estatus y saldo residual. Registrar la fecha de detección, no presentarla como fecha valor.
|
||||
|
||||
**Motivo:** no se encontró un recurso de pagos/REP. La fecha contable real requerirá información adicional o una ampliación.
|
||||
|
||||
### ADR-005 · Separación por empresa
|
||||
|
||||
**Decisión:** el MVP opera únicamente con la empresa Balam asociada al token. Multiempresa queda fuera del alcance.
|
||||
|
||||
**Motivo:** cada empresa requiere su propia cuenta/token de BIND.
|
||||
|
||||
### ADR-006 · Integración Jira→BIND pendiente de alcance
|
||||
|
||||
**Decisión:** diseñar el modelo para conservar el identificador del ticket, pero no comprometer todavía la automatización que crea cotizaciones desde Jira.
|
||||
|
||||
**Motivo:** el Discovery confirmó a Jira como entrada del proceso, pero la integración automática no estaba incluida explícitamente en el MVP. Antes de desarrollarla se requiere:
|
||||
|
||||
- Confirmación de alcance.
|
||||
- Cuenta técnica y acceso API/OAuth a Jira.
|
||||
- Webhook o regla de automatización.
|
||||
- Mapeo de campos y estatus disparador.
|
||||
- Acceso controlado de escritura a BIND.
|
||||
|
||||
## 4. Preguntas que deben cerrarse
|
||||
|
||||
### Con Arturo / CEO — sesión del 22-jul
|
||||
|
||||
1. Flujo definitivo de alta de cliente nuevo.
|
||||
2. Tratamiento en BIND de diferencias por comisión/fee.
|
||||
3. Particularidades de envío por cliente.
|
||||
4. Estatus de Jira que autoriza crear una cotización.
|
||||
5. Campos obligatorios y manejo de tickets incompletos.
|
||||
|
||||
### Con Pedro / Noé
|
||||
|
||||
1. Endpoint de pagos individuales o REP.
|
||||
2. Mapeo interno de `CFDIUse` a clave SAT.
|
||||
3. Formato de respuesta de `/{id}/xml`.
|
||||
4. Disponibilidad de webhooks en BIND.
|
||||
5. Token utilizado por Power BI y decisión sobre usuario de solo lectura.
|
||||
6. Permisos e identidad técnica para Jira, si se aprueba la integración.
|
||||
|
||||
## 5. Dependencias de infraestructura
|
||||
|
||||
| Dependencia | Estado al 15-jul | Impacto |
|
||||
|---|---|---|
|
||||
| Token BIND | Entregado; uso solo lectura | Desbloquea consultas y cliente BIND |
|
||||
| Repositorio privado GitHub | Autorizado por Noé; invitación pendiente | Necesario para publicar backend/frontend |
|
||||
| Azure | Programado para semana del 21-jul | No bloquea desarrollo local |
|
||||
| CI/CD y secretos | Actividad separada para 24-jul | Depende de repo y Azure |
|
||||
| Jira técnico | No solicitado todavía | Solo bloquea integración automática Jira→BIND |
|
||||
|
||||
## 6. Criterio de cierre de Etapa 0
|
||||
|
||||
La Etapa 0 se cierra cuando:
|
||||
|
||||
- Balam valida el prototipo o registra ajustes.
|
||||
- Se incorporan las decisiones de la sesión del 22-jul.
|
||||
- Se valida el prototipo en la sesión del 23-jul.
|
||||
- Este documento se actualiza con las respuestas finales.
|
||||
- Se emite un plan refinado con alcance explícito para Jira, recordatorios externos y escritura en BIND.
|
||||
Binary file not shown.
@@ -1,21 +1,24 @@
|
||||
# Plan de actividades — Etapas 0 a 3
|
||||
|
||||
**Proyecto:** Plataforma de Automatización Financiera · Balam
|
||||
> Fechas tentativas — el arranque depende de la entrega de accesos por Balam; se confirman en el kickoff. Las etapas 2 y 3 son estimadas y se afinan al cerrar el Discovery (Etapa 0). Total ~6–7 semanas (6-jul → 21-ago).
|
||||
> Fechas tentativas. Este documento incorpora los ajustes acordados al 15-jul y se mantiene sincronizado con el [Excel oficial consolidado](Plan-actividades-avance-2026-07-10-ajustado.xlsx). Las etapas 2 y 3 se afinan al validar el prototipo y cerrar las definiciones de la Etapa 1. Total estimado: ~6–7 semanas.
|
||||
>
|
||||
> Las horas reales se registran en [`Seguimiento-horas.csv`](Seguimiento-horas.csv); el porcentaje de avance no sustituye ese registro.
|
||||
|
||||
## Etapa 0
|
||||
|
||||
| Actividad | Inicio | Fin | Responsable | Apoyo de Balam |
|
||||
|---|---|---|---|---|
|
||||
| Sesión de arranque (kickoff) con el Ing. Noé | 01/07/2026 | 01/07/2026 | Johann | ✅ Realizada (1-jul, 7am) — Noé, Pedro, Erika |
|
||||
| Sesión de Discovery: proceso actual de facturación y cobranza | 06/07/2026 | 07/07/2026 | Johann | Sí — **Araceli + Arturo** (Erika agenda) |
|
||||
| Entrega y validación de accesos (token BIND de Arturo, Azure, repo) | 06/07/2026 | 07/07/2026 | Balam / Johann | Sí — token de Arturo, Azure (Pedro+Noé), repo. Manual de marca ✅ recibido (1-jul) |
|
||||
| Validación técnica de la API de BIND con la cuenta real | 07/07/2026 | 08/07/2026 | Johann | Apoyo: token de Arturo (solo consulta; probar primero) |
|
||||
| Configuración de infraestructura en Azure (+ staging) | 08/07/2026 | 09/07/2026 | Johann | Apoyo: accesos de Azure (Pedro+Noé) |
|
||||
| Repositorio + CI/CD + gestión de secretos | 08/07/2026 | 09/07/2026 | Johann | Sí — **Balam crea el repo** (GitHub privado) |
|
||||
| Prototipo visual navegable (5–6 pantallas) | 08/07/2026 | 10/07/2026 | Johann | Marca: `../marca/Marca-Balam.md` (✅ recibida) |
|
||||
| Sesión de validación del prototipo | 10/07/2026 | 10/07/2026 | Johann | Sí — Pedro, Araceli y Arturo |
|
||||
| Documento de hallazgos + ADRs + plan refinado | 10/07/2026 | 10/07/2026 | Johann | — |
|
||||
| Sesión de Discovery: facturación, envío y cobranza | 06/07/2026 | 07/07/2026 | Johann | ✅ Realizada — Araceli + Arturo |
|
||||
| Accesos iniciales: token BIND + manual de marca | 01/07/2026 | 06/07/2026 | Balam / Johann | ✅ Entregados y validados |
|
||||
| Validación técnica de la API de BIND con la cuenta real | 06/07/2026 | 06/07/2026 | Johann | ✅ Realizada: 117 GET, sin escritura |
|
||||
| Prototipo visual navegable | 08/07/2026 | 10/07/2026 | Johann | ✅ Entregado por correo el 10-jul; validación pendiente |
|
||||
| Repositorio privado GitHub | 13/07/2026 | 16/07/2026 | Balam / Johann | Noé autorizó su creación; usuario `Johann-28`; invitación pendiente |
|
||||
| Configuración de infraestructura en Azure (+ staging) | 21/07/2026 | 23/07/2026 | Johann | Apoyo: acceso acotado de Azure (Pedro+Noé); no bloquea trabajo local |
|
||||
| CI/CD + gestión de secretos | 24/07/2026 | 24/07/2026 | Johann | Depende de repo y Azure |
|
||||
| Documento de hallazgos + ADRs + plan refinado | 10/07/2026 | 23/07/2026 | Johann | Borrador creado; cerrar tras las sesiones del 22–23 jul |
|
||||
| Sesión de validación del prototipo | 23/07/2026 | 23/07/2026 | Johann | Confirmada a las 7:00 pm con CEO/equipo Balam |
|
||||
|
||||
**Entregable Etapa 0 (18–22 h): prototipo navegable + infraestructura Azure + repo/CI-CD + documento de hallazgos.**
|
||||
|
||||
@@ -23,15 +26,16 @@
|
||||
|
||||
| Actividad | Inicio | Fin | Responsable | Apoyo de Balam |
|
||||
|---|---|---|---|---|
|
||||
| Backend base: autenticación, roles y bitácora de auditoría | 13/07/2026 | 15/07/2026 | Johann | — |
|
||||
| Arquitectura multi-tenant (tenant_id + RLS) | 14/07/2026 | 15/07/2026 | Johann | — |
|
||||
| Sesión de reglas de negocio con Arturo | 13/07/2026 | 13/07/2026 | Johann | Sí — Arturo |
|
||||
| Backend base: autenticación, roles y bitácora de auditoría | 13/07/2026 | 17/07/2026 | Johann | Trabajo local; publicar al recibir el repositorio |
|
||||
| Arquitectura multi-tenant (tenant_id + RLS) | 14/07/2026 | 17/07/2026 | Johann | — |
|
||||
| Sesión de reglas y dudas de Etapa 1 | 22/07/2026 | 22/07/2026 | Johann | Confirmada con Arturo + CEO |
|
||||
| Definición de alcance Jira → cotización BIND | 22/07/2026 | 23/07/2026 | Johann / Balam | Requiere confirmar si la integración automática entra al MVP antes de pedir token técnico |
|
||||
| Cliente de la API de BIND (reintentos, OData, errores) | 15/07/2026 | 17/07/2026 | Johann | — |
|
||||
| Capa de escritura controlada (cotización→factura) | 17/07/2026 | 22/07/2026 | Johann | — |
|
||||
| Sincronización de clientes | 20/07/2026 | 21/07/2026 | Johann | — |
|
||||
| Sincronización de facturas y cotizaciones | 21/07/2026 | 23/07/2026 | Johann | — |
|
||||
| Modelo de facturas + migraciones + datos de prueba | 23/07/2026 | 24/07/2026 | Johann | — |
|
||||
| Demostración semanal (viernes) + reporte de horas | 10/07/2026 | 24/07/2026 | Johann | Sí — Erika/Pedro |
|
||||
| Demostración semanal (viernes) + reporte de horas | 10/07/2026 | 24/07/2026 | Johann | Sí — Erika/Pedro; control local en `Seguimiento-horas.csv` mientras Jira se habilita |
|
||||
|
||||
**Entregable Etapa 1 (32–39 h): plataforma base que sincroniza clientes y facturas de BIND, con capa de escritura controlada.**
|
||||
|
||||
@@ -41,7 +45,7 @@
|
||||
|---|---|---|---|---|
|
||||
| Implementación productiva de las pantallas (Angular Material) + integración con el backend | 27/07/2026 | 31/07/2026 | Johann | — |
|
||||
| Listado de facturas (filtros, búsqueda, paginación) + detalle con descarga PDF/XML | 28/07/2026 | 31/07/2026 | Johann | — |
|
||||
| Catálogo de clientes + lista blanca configurable (ACUNTIA + Top 3) | 03/08/2026 | 04/08/2026 | Johann | — |
|
||||
| Catálogo de clientes + reglas de cobranza | 03/08/2026 | 04/08/2026 | Johann | Lista blanca actualmente vacía: recordatorios para todos |
|
||||
| Creación de cotizaciones + conversión a factura vía API de BIND | 31/07/2026 | 04/08/2026 | Johann | — |
|
||||
| Emisión multimoneda MXN/USD + flujo con confirmación humana y dry-run | 04/08/2026 | 06/08/2026 | Johann | — |
|
||||
| Tipo de cambio del DOF (proceso programado) | 05/08/2026 | 05/08/2026 | Johann | — |
|
||||
@@ -57,7 +61,7 @@
|
||||
|---|---|---|---|---|
|
||||
| Sesión: alcance del tablero vs el Power BI existente (con Pedro) | 10/08/2026 | 10/08/2026 | Johann | Sí — Pedro |
|
||||
| Módulo de cobranza: antigüedad de cartera (30/60/90) + por vencer y vencidas | 10/08/2026 | 12/08/2026 | Johann | — |
|
||||
| Alertas internas configurables para Finanzas + aplicación de lista blanca | 12/08/2026 | 13/08/2026 | Johann | — |
|
||||
| Alertas internas configurables para Finanzas | 12/08/2026 | 13/08/2026 | Johann | Correos automáticos al cliente requieren confirmar ampliación de alcance |
|
||||
| Tablero directivo de cuentas por cobrar | 13/08/2026 | 15/08/2026 | Johann | — |
|
||||
| Reportes operativos configurables (CSV/XLSX/PDF) | 17/08/2026 | 18/08/2026 | Johann | — |
|
||||
| Endurecimiento de seguridad + respaldos + plan de recuperación | 18/08/2026 | 19/08/2026 | Johann | — |
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,19 @@
|
||||
fecha,semana,etapa,actividad_id,actividad,horas,estado_hora,fuente_evidencia,facturable,notas
|
||||
2026-07-01,2026-W27,0,E0-01,Sesión de arranque con Noé,1.00,confirmada,bitacora/REGISTRO.md#22,si,"Sesión calendarizada de 7:00 a 8:00 am"
|
||||
2026-07-01,2026-W27,0,E0-01,Preparación de plan kickoff y materiales,1.00,reconstruida,planeacion/Kickoff-2026-07-01.md,si,"Estimación retrospectiva; validar antes de facturar"
|
||||
2026-07-06,2026-W28,0,E0-02,Discovery de facturación y envío,1.08,confirmada,bitacora/REGISTRO.md#27,si,"Duración documentada: aproximadamente 1 h 5 min"
|
||||
2026-07-06,2026-W28,0,E0-02,Preparación y análisis de Discovery de facturación,1.92,reconstruida,bitacora/REGISTRO.md#27,si,"Completa 3.00 h para facturación/envío incluyendo sesión"
|
||||
2026-07-06,2026-W28,0,E0-03,Coordinación y validación de accesos BIND y marca,1.00,reconstruida,bitacora/REGISTRO.md#28-31,si,"Recepción documentación y salvaguardas"
|
||||
2026-07-06,2026-W28,0,E0-04,Validación técnica de API BIND,4.50,reconstruida,bind-api-sandbox/VALIDACION-API.md,si,"117 GET análisis y reporte técnico"
|
||||
2026-07-07,2026-W28,0,E0-02,Discovery de cobranza,1.00,confirmada,bitacora/REGISTRO.md#35,si,"Sesión calendarizada de 7:00 a 8:00 am; sin grabación"
|
||||
2026-07-07,2026-W28,0,E0-02,Preparación y documentación de Discovery de cobranza,1.50,reconstruida,fuentes/2026-07-07 - Notas - Proceso actual de cobranza (sin grabacion).md,si,"Estimación retrospectiva"
|
||||
2026-07-08,2026-W28,0,E0-05,Diseño y construcción del prototipo,3.00,reconstruida,prototipo/Prototipo-Etapa0.html,si,"Primera mitad del esfuerzo reconstruido"
|
||||
2026-07-09,2026-W28,0,E0-05,Ajustes de cobranza navegación y prototipo,3.00,reconstruida,prototipo/Prototipo-Etapa0.html,si,"Segunda mitad del esfuerzo reconstruido"
|
||||
2026-07-10,2026-W28,0,E0-06,Entregable hallazgos ADRs PDF correo y plan,3.00,reconstruida,prototipo/Correo-prototipo-Etapa0.md,si,"Incluye preparación del entregable y documentación"
|
||||
2026-07-13,2026-W29,1,E1-01,Backend base autenticación roles y auditoría,2.00,reconstruida,planeacion/Plan-actividades.md,si,"Trabajo local; falta conciliar contra evidencia de código"
|
||||
2026-07-13,2026-W29,1,E1-02,Coordinación del repositorio GitHub,0.50,reconstruida,bitacora/REGISTRO.md#43,si,"Seguimiento de creación y acceso"
|
||||
2026-07-14,2026-W29,1,E1-01,Backend base autenticación roles y auditoría,1.50,reconstruida,planeacion/Plan-actividades.md,si,"Trabajo local; completa 3.50 h"
|
||||
2026-07-14,2026-W29,1,E1-03,Arquitectura multi-tenant,1.00,reconstruida,planeacion/Plan-actividades.md,si,"Diseño inicial tenant_id y RLS"
|
||||
2026-07-15,2026-W29,1,E1-03,Arquitectura multi-tenant,0.50,reconstruida,planeacion/Plan-actividades.md,si,"Completa 1.50 h"
|
||||
2026-07-15,2026-W29,1,E1-04,Cliente productivo de API BIND,2.00,reconstruida,bind-api-sandbox/VALIDACION-API.md,si,"Inicio de reintentos OData y manejo de errores"
|
||||
2026-07-15,2026-W29,1,E1-05,Seguimiento ajuste de calendario y corte de horas,0.50,reconstruida,bitacora/REGISTRO.md#41-45,si,"Actualización de plan y control"
|
||||
|
@@ -0,0 +1,62 @@
|
||||
# Seguimiento de horas
|
||||
|
||||
Fuente local de horas efectivamente trabajadas para el proyecto Balam. Se mantiene mientras Johann obtiene acceso al flujo de Jira; después, Jira será el registro operativo y este archivo/CSV servirá para conciliación y facturación.
|
||||
|
||||
**Tarifa contractual:** $600 MXN/h + IVA
|
||||
**Cadencia:** corte semanal; factura los viernes; pago a 30 días
|
||||
**Datos tabulares:** [`Seguimiento-horas.csv`](Seguimiento-horas.csv)
|
||||
**Última actualización:** 2026-07-15
|
||||
|
||||
## Reglas de captura
|
||||
|
||||
1. Registrar el tiempo el mismo día, en incrementos de 0.25 h.
|
||||
2. Separar sesiones, desarrollo, análisis, documentación y gestión técnica.
|
||||
3. Vincular cada registro con una actividad del plan y una evidencia cuando exista.
|
||||
4. No convertir porcentajes de avance en horas: el avance mide entregable; las horas miden esfuerzo real.
|
||||
5. No completar retrospectivamente una duración sin respaldo. Si solo se conoce la actividad, dejarla en la lista de reconstrucción hasta que Johann confirme el tiempo.
|
||||
6. Al habilitarse Jira, conciliar ambos registros y evitar duplicados.
|
||||
|
||||
## Corte reconstruido al 15-jul
|
||||
|
||||
| Etapa | Horas al corte | Rango estimado de la etapa | Estado |
|
||||
|---|---:|---:|---|
|
||||
| Etapa 0 | **22.00 h** | 18–22 h | Límite superior consumido; prototipo pendiente de validación |
|
||||
| Etapa 1 | **8.00 h** | 32–39 h | En curso |
|
||||
| **Total** | **30.00 h** | | Coincide con la facturación inicial propuesta |
|
||||
|
||||
Las **26.92 h** que no corresponden a sesiones con duración documentada se reconstruyeron retrospectivamente por actividad. Deben validarse contra memoria, archivos de trabajo y Jira antes de presentarse como horas efectivamente trabajadas.
|
||||
|
||||
## Horas con duración comprobable
|
||||
|
||||
| Semana | Etapa | Horas confirmadas | Alcance incluido |
|
||||
|---|---:|---:|---|
|
||||
| 2026-W27 | 0 | 1.00 | Kickoff |
|
||||
| 2026-W28 | 0 | 2.08 | Discovery de facturación/envío y cobranza |
|
||||
| **Total comprobable** | | **3.08** | Solo sesiones con duración documentada |
|
||||
|
||||
> Las 3.08 h están incluidas dentro del corte reconstruido de 30 h; no deben sumarse nuevamente.
|
||||
|
||||
## Distribución reconstruida
|
||||
|
||||
Johann debe confirmar esta distribución antes de usarla para facturación:
|
||||
|
||||
| Etapa | Actividad consolidada | Horas |
|
||||
|---|---|---:|
|
||||
| 0 | Kickoff y preparación | 2.00 |
|
||||
| 0 | Discovery de facturación, envío y cobranza | 5.50 |
|
||||
| 0 | Accesos y salvaguardas | 1.00 |
|
||||
| 0 | Validación técnica de BIND | 4.50 |
|
||||
| 0 | Prototipo navegable | 6.00 |
|
||||
| 0 | Entregable, hallazgos, ADRs y plan | 3.00 |
|
||||
| 1 | Backend base | 3.50 |
|
||||
| 1 | Arquitectura multi-tenant | 1.50 |
|
||||
| 1 | Cliente productivo de BIND | 2.00 |
|
||||
| 1 | Repositorio y seguimiento | 1.00 |
|
||||
| | **Total** | **30.00** |
|
||||
|
||||
## Corte comercial
|
||||
|
||||
- La propuesta v1.2 contempla una **facturación inicial de 30 h ($18,000 + IVA)** que cubre Etapa 0 e inicio de Etapa 1.
|
||||
- Esas 30 h son el concepto comercial autorizado en la propuesta, pero el contrato exige reportar horas efectivamente trabajadas.
|
||||
- Antes de emitir, Johann debe validar el desglose reconstruido y conciliarlo contra Jira.
|
||||
- La emisión sigue pendiente de confirmación de Balam al correo del 2-jul.
|
||||
@@ -0,0 +1,88 @@
|
||||
# Sesión de reglas y definiciones — Etapa 1
|
||||
|
||||
**Fecha:** miércoles 22-jul-2026
|
||||
**Participantes esperados:** CEO, Arturo, Erika, Johann
|
||||
**Objetivo:** cerrar decisiones que afectan el modelo de datos y el alcance técnico antes de implementar escritura e integración Jira→BIND.
|
||||
|
||||
## Resultado esperado
|
||||
|
||||
Al terminar deben quedar definidos:
|
||||
|
||||
1. Flujo de alta de un cliente nuevo.
|
||||
2. Tratamiento de diferencias por comisión/fee.
|
||||
3. Fuente y reglas de particularidades de envío.
|
||||
4. Alcance de la automatización Jira→cotización BIND.
|
||||
5. Datos y autorización necesarios para comenzar escritura controlada.
|
||||
|
||||
## Agenda propuesta (45–60 min)
|
||||
|
||||
### 1. Alta de cliente nuevo — 10 min
|
||||
|
||||
- ¿Quién crea actualmente al cliente en BIND?
|
||||
- ¿Qué documentos y validaciones son obligatorios?
|
||||
- ¿Qué estatus de Jira indica que el alta está autorizada?
|
||||
- ¿La plataforma solo debe detectar que falta el cliente o también crearlo?
|
||||
- ¿Qué ocurre si el RFC ya existe o los datos fiscales no coinciden?
|
||||
|
||||
**Decisión a registrar:** alcance exacto del MVP y responsable de cada paso.
|
||||
|
||||
### 2. Comisión/fee en cobranza — 10 min
|
||||
|
||||
- Cuando el pago recibido es menor por una comisión, ¿cómo se registra en BIND?
|
||||
- ¿Pago parcial con saldo residual, nota de crédito, gasto/comisión o ajuste contable?
|
||||
- ¿Existe una tolerancia fija o cambia por cliente/banco?
|
||||
- ¿Quién autoriza considerar una factura como saldada con diferencia?
|
||||
|
||||
**Decisión a registrar:** fórmula de estado de cobranza y si el umbral es global o por cliente.
|
||||
|
||||
### 3. Particularidades de envío — 10 min
|
||||
|
||||
- Confirmar destinatarios, adjuntos, nomenclatura del asunto y cuerpo por cliente.
|
||||
- Definir quién mantiene estos datos y con qué frecuencia cambian.
|
||||
- Confirmar si el Excel en preparación será la fuente inicial para cargarlos.
|
||||
|
||||
**Decisión a registrar:** estructura mínima del catálogo y responsable de mantenimiento.
|
||||
|
||||
### 4. Jira → cotización BIND — 15 min
|
||||
|
||||
Explicar que Jira es parte confirmada del proceso, pero la creación automática de cotizaciones no estaba incluida explícitamente en el alcance inicial.
|
||||
|
||||
- ¿La expectativa del MVP es solo conservar el folio de Jira o crear automáticamente la cotización en BIND?
|
||||
- ¿Qué estatus o aprobación dispara la acción?
|
||||
- ¿Qué tipos de ticket aplican: adicional, baja, headhunting, staff augmentation?
|
||||
- ¿Qué campos son obligatorios y qué ocurre si falta alguno?
|
||||
- ¿Debe haber una previsualización/confirmación humana antes de escribir en BIND?
|
||||
|
||||
Si Balam confirma la automatización, solicitar posteriormente:
|
||||
|
||||
- Cuenta técnica de Jira con acceso mínimo al proyecto.
|
||||
- API token/OAuth y permiso para webhook o automatización.
|
||||
- Identificadores del sitio/proyecto y mapeo de campos.
|
||||
- Autorización de escritura controlada en BIND.
|
||||
|
||||
**Decisión a registrar:** incluido, diferido o sujeto a estimación/cambio de alcance.
|
||||
|
||||
### 5. Cierre técnico — 10 min
|
||||
|
||||
- Confirmar si ya está listo el repositorio GitHub y el acceso de Johann.
|
||||
- Confirmar fecha y responsable del acceso Azure.
|
||||
- Confirmar cuándo Pedro habilitará el reporte de horas en Jira.
|
||||
- Revisar las preguntas técnicas pendientes de BIND: pagos/REP, `CFDIUse`, XML, webhooks y token de Power BI.
|
||||
|
||||
## Límites que conviene explicitar
|
||||
|
||||
- Recordatorios automáticos enviados al cliente: Anexo B; el MVP contempla alertas internas.
|
||||
- Multiempresa: fuera del MVP; cada empresa requiere token/cuenta BIND.
|
||||
- Escritura en producción: solo con autorización, dry-run, confirmación humana y feature flag.
|
||||
- Integración Jira automática: pendiente de confirmación de alcance.
|
||||
|
||||
## Minuta para llenar durante la sesión
|
||||
|
||||
| Tema | Decisión | Responsable | Fecha |
|
||||
|---|---|---|---|
|
||||
| Alta de cliente | | | |
|
||||
| Fee/comisión | | | |
|
||||
| Particularidades de envío | | | |
|
||||
| Jira→BIND | | | |
|
||||
| Escritura BIND | | | |
|
||||
| Repo/Azure/Jira horas | | | |
|
||||
@@ -0,0 +1,288 @@
|
||||
"""Actualiza el plan oficial con el corte reconstruido de horas al 15-jul-2026."""
|
||||
|
||||
from copy import copy
|
||||
from pathlib import Path
|
||||
|
||||
import openpyxl
|
||||
from openpyxl.styles import Alignment, Font, PatternFill
|
||||
from openpyxl.utils import get_column_letter
|
||||
|
||||
|
||||
PATH = Path(__file__).with_name("Plan-actividades-avance-2026-07-10-ajustado.xlsx")
|
||||
|
||||
|
||||
def find_row(ws, task):
|
||||
for row in range(2, ws.max_row + 1):
|
||||
if ws.cell(row, 1).value == task:
|
||||
return row
|
||||
raise ValueError(f"No se encontró la tarea: {task}")
|
||||
|
||||
|
||||
def copy_row_style(ws, source_row, target_row, max_col=11):
|
||||
for col in range(1, max_col + 1):
|
||||
source = ws.cell(source_row, col)
|
||||
target = ws.cell(target_row, col)
|
||||
if source.has_style:
|
||||
target._style = copy(source._style)
|
||||
target.number_format = source.number_format
|
||||
target.alignment = copy(source.alignment)
|
||||
|
||||
|
||||
workbook = openpyxl.load_workbook(PATH)
|
||||
sheet = workbook["Plan"]
|
||||
|
||||
# Actividades separadas después del plan original. Las inserciones son idempotentes.
|
||||
if not any(
|
||||
sheet.cell(row, 1).value == "Definición de alcance Jira → cotización BIND"
|
||||
for row in range(2, sheet.max_row + 1)
|
||||
):
|
||||
source_row = find_row(sheet, "Sesión de reglas de negocio con Arturo")
|
||||
sheet.insert_rows(source_row + 1)
|
||||
copy_row_style(sheet, source_row, source_row + 1)
|
||||
values = [
|
||||
"Definición de alcance Jira → cotización BIND",
|
||||
"2 días",
|
||||
"mié 22/07/26",
|
||||
"jue 23/07/26",
|
||||
None,
|
||||
"Johan y Balam",
|
||||
0,
|
||||
]
|
||||
for column, value in enumerate(values, start=1):
|
||||
sheet.cell(source_row + 1, column, value)
|
||||
|
||||
if not any(
|
||||
sheet.cell(row, 1).value == "CI/CD + gestión de secretos"
|
||||
for row in range(2, sheet.max_row + 1)
|
||||
):
|
||||
source_row = find_row(sheet, "Repositorio + CI/CD + gestión de secretos")
|
||||
sheet.insert_rows(source_row + 1)
|
||||
copy_row_style(sheet, source_row, source_row + 1)
|
||||
values = [
|
||||
"CI/CD + gestión de secretos",
|
||||
"1 día",
|
||||
"vie 24/07/26",
|
||||
"vie 24/07/26",
|
||||
None,
|
||||
"Johan y Pedro",
|
||||
0,
|
||||
]
|
||||
for column, value in enumerate(values, start=1):
|
||||
sheet.cell(source_row + 1, column, value)
|
||||
|
||||
# Calendario ajustado con los acuerdos del 13–15 de julio.
|
||||
updates = {
|
||||
"Sesión de validación del prototipo": (
|
||||
"1 día",
|
||||
"jue 23/07/26",
|
||||
"jue 23/07/26",
|
||||
"Johan y Balam",
|
||||
),
|
||||
"Documento de hallazgos + ADRs + plan refinado": (
|
||||
"10 días",
|
||||
"vie 10/07/26",
|
||||
"jue 23/07/26",
|
||||
"Johan",
|
||||
),
|
||||
"Sesión de reglas de negocio con Arturo": (
|
||||
"1 día",
|
||||
"mié 22/07/26",
|
||||
"mié 22/07/26",
|
||||
"Arturo y CEO",
|
||||
),
|
||||
"Backend base: autenticación, roles y bitácora de auditoría": (
|
||||
"5 días",
|
||||
"lun 13/07/26",
|
||||
"vie 17/07/26",
|
||||
"Johan",
|
||||
),
|
||||
"Repositorio + CI/CD + gestión de secretos": (
|
||||
"4 días",
|
||||
"lun 13/07/26",
|
||||
"jue 16/07/26",
|
||||
"Pedro y Noé",
|
||||
),
|
||||
"Arquitectura multi-tenant (tenant_id + RLS)": (
|
||||
"4 días",
|
||||
"mar 14/07/26",
|
||||
"vie 17/07/26",
|
||||
"Johan",
|
||||
),
|
||||
}
|
||||
|
||||
for task, (duration, start, end, resources) in updates.items():
|
||||
row = find_row(sheet, task)
|
||||
sheet.cell(row, 2, duration)
|
||||
sheet.cell(row, 3, start)
|
||||
sheet.cell(row, 4, end)
|
||||
sheet.cell(row, 6, resources)
|
||||
|
||||
rules_row = find_row(sheet, "Sesión de reglas de negocio con Arturo")
|
||||
sheet.cell(rules_row, 1, "Sesión de reglas y dudas de Etapa 1")
|
||||
repo_row = find_row(sheet, "Repositorio + CI/CD + gestión de secretos")
|
||||
sheet.cell(repo_row, 1, "Repositorio privado GitHub")
|
||||
|
||||
headers = {
|
||||
8: "Horas al 15/07",
|
||||
9: "Tipo de registro",
|
||||
10: "Notas de horas",
|
||||
11: "Rango estimado",
|
||||
}
|
||||
for column, value in headers.items():
|
||||
cell = sheet.cell(1, column, value)
|
||||
cell.fill = copy(sheet.cell(1, 1).fill)
|
||||
cell.font = copy(sheet.cell(1, 1).font)
|
||||
cell.alignment = Alignment(horizontal="center", vertical="center", wrap_text=True)
|
||||
|
||||
# Corte: 22 h de Etapa 0 + 8 h del inicio de Etapa 1 = 30 h.
|
||||
hours = {
|
||||
"Sesión de arranque (kickoff) con el Ing. Noé": (
|
||||
2.00,
|
||||
"Incluye preparación y sesión de 1 h",
|
||||
),
|
||||
"Sesión de Discovery: proceso actual de facturación y cobranza": (
|
||||
5.50,
|
||||
"Incluye preparación, sesiones y documentación de facturación/cobranza",
|
||||
),
|
||||
"Entrega y validación de accesos (BIND + manual de marca)": (
|
||||
1.00,
|
||||
"Coordinación, recepción y salvaguardas",
|
||||
),
|
||||
"Validación técnica de la API de BIND con la cuenta real": (
|
||||
4.50,
|
||||
"117 consultas GET, análisis y reporte técnico",
|
||||
),
|
||||
"Prototipo visual navegable": (
|
||||
6.00,
|
||||
"Diseño, construcción y ajustes con datos ficticios",
|
||||
),
|
||||
"Sesión de validación del prototipo": (0.00, "Agendada para el 23-jul"),
|
||||
"Documento de hallazgos + ADRs + plan refinado": (
|
||||
3.00,
|
||||
"PDF/correo de entrega, hallazgos, ADRs y actualización del plan",
|
||||
),
|
||||
"Sesión de reglas y dudas de Etapa 1": (0.00, "Agendada para el 22-jul"),
|
||||
"Definición de alcance Jira → cotización BIND": (
|
||||
0.00,
|
||||
"Se define con Balam el 22–23 jul",
|
||||
),
|
||||
"Backend base: autenticación, roles y bitácora de auditoría": (
|
||||
3.50,
|
||||
"Trabajo local del 13–15 jul",
|
||||
),
|
||||
"Repositorio privado GitHub": (0.50, "Coordinación de creación y acceso"),
|
||||
"CI/CD + gestión de secretos": (0.00, "Programado para el 24-jul"),
|
||||
"Arquitectura multi-tenant (tenant_id + RLS)": (
|
||||
1.50,
|
||||
"Diseño técnico inicial",
|
||||
),
|
||||
"Cliente de la API de BIND (reintentos, OData, errores)": (
|
||||
2.00,
|
||||
"Inicio del cliente productivo",
|
||||
),
|
||||
"Demostración semanal (viernes) + reporte de horas": (
|
||||
0.50,
|
||||
"Seguimiento, ajuste de calendario y corte de horas",
|
||||
),
|
||||
}
|
||||
|
||||
pending = {
|
||||
"Sesión de validación del prototipo",
|
||||
"Sesión de reglas y dudas de Etapa 1",
|
||||
"Definición de alcance Jira → cotización BIND",
|
||||
"CI/CD + gestión de secretos",
|
||||
}
|
||||
|
||||
stage_rows = {0: [], 1: []}
|
||||
current_stage = None
|
||||
for row in range(2, sheet.max_row + 1):
|
||||
task = sheet.cell(row, 1).value
|
||||
if task == "Etapa 0":
|
||||
current_stage = 0
|
||||
sheet.cell(row, 11, "18–22 h")
|
||||
continue
|
||||
if task == "Etapa 1":
|
||||
current_stage = 1
|
||||
sheet.cell(row, 11, "32–39 h")
|
||||
continue
|
||||
if task == "Integracion de plataformas Balam":
|
||||
sheet.cell(row, 11, "112–136 h")
|
||||
continue
|
||||
if task not in hours:
|
||||
continue
|
||||
value, note = hours[task]
|
||||
sheet.cell(row, 8, value)
|
||||
sheet.cell(row, 9, "Pendiente" if task in pending else "Reconstruida")
|
||||
sheet.cell(row, 10, note)
|
||||
if current_stage in stage_rows:
|
||||
stage_rows[current_stage].append(row)
|
||||
|
||||
project_row = find_row(sheet, "Integracion de plataformas Balam")
|
||||
stage0_row = find_row(sheet, "Etapa 0")
|
||||
stage1_row = find_row(sheet, "Etapa 1")
|
||||
sheet.cell(stage0_row, 8, f"=SUM({','.join(f'H{row}' for row in stage_rows[0])})")
|
||||
sheet.cell(stage1_row, 8, f"=SUM({','.join(f'H{row}' for row in stage_rows[1])})")
|
||||
sheet.cell(project_row, 8, f"=H{stage0_row}+H{stage1_row}")
|
||||
|
||||
summaries = {
|
||||
project_row: "Corte reconstruido al 15-jul",
|
||||
stage0_row: "22 h: límite superior estimado de la etapa",
|
||||
stage1_row: "8 h consumidas al 15-jul; etapa aún en curso",
|
||||
}
|
||||
for row, note in summaries.items():
|
||||
sheet.cell(row, 9, "Resumen")
|
||||
sheet.cell(row, 10, note)
|
||||
|
||||
for row in range(2, sheet.max_row + 1):
|
||||
sheet.cell(row, 8).number_format = '0.00 "h"'
|
||||
for column in range(8, 12):
|
||||
sheet.cell(row, column).alignment = Alignment(vertical="top", wrap_text=True)
|
||||
if sheet.cell(row, 1).value in {
|
||||
"Integracion de plataformas Balam",
|
||||
"Etapa 0",
|
||||
"Etapa 1",
|
||||
}:
|
||||
for column in range(8, 12):
|
||||
sheet.cell(row, column).font = Font(bold=True, color="FFFFFF")
|
||||
sheet.cell(row, column).fill = PatternFill("solid", fgColor="331F0E")
|
||||
|
||||
widths = {
|
||||
1: 58,
|
||||
2: 13,
|
||||
3: 16,
|
||||
4: 16,
|
||||
5: 14,
|
||||
6: 22,
|
||||
7: 14,
|
||||
8: 16,
|
||||
9: 18,
|
||||
10: 55,
|
||||
11: 18,
|
||||
}
|
||||
for column, width in widths.items():
|
||||
sheet.column_dimensions[get_column_letter(column)].width = width
|
||||
|
||||
sheet.freeze_panes = "A2"
|
||||
sheet.auto_filter.ref = f"A1:K{sheet.max_row}"
|
||||
sheet.sheet_properties.pageSetUpPr.fitToPage = True
|
||||
sheet.page_setup.fitToWidth = 1
|
||||
sheet.page_setup.fitToHeight = 0
|
||||
sheet.oddFooter.center.text = (
|
||||
"Horas reconstruidas al 15-jul-2026; validar contra Jira antes de facturar"
|
||||
)
|
||||
|
||||
stage0_total = sum(hours[sheet.cell(row, 1).value][0] for row in stage_rows[0])
|
||||
stage1_total = sum(hours[sheet.cell(row, 1).value][0] for row in stage_rows[1])
|
||||
assert stage0_total == 22.0
|
||||
assert stage1_total == 8.0
|
||||
|
||||
temporary = PATH.with_suffix(".tmp.xlsx")
|
||||
workbook.save(temporary)
|
||||
check = openpyxl.load_workbook(temporary, data_only=False)["Plan"]
|
||||
assert check.max_column == 11
|
||||
assert check.cell(find_row(check, "Etapa 0"), 8).value.startswith("=SUM(")
|
||||
assert check.cell(find_row(check, "Etapa 1"), 8).value.startswith("=SUM(")
|
||||
temporary.replace(PATH)
|
||||
|
||||
print(f"Actualizado: {PATH}")
|
||||
print("Etapa 0: 22.00 h | Etapa 1: 8.00 h | Total al 15-jul: 30.00 h")
|
||||
Reference in New Issue
Block a user