Commit Graph

32 Commits

Author SHA1 Message Date
Milton Gonzalez e5dfc2feff fix: version 2.11.3 -- badges de Comentarios/Documentos de actividad no se actualizaban en vivo
CommentsPanel/AttachmentsPanel ya soportaban un onChanged opcional (agregado en 2.11.1 para
el nivel de proyecto), pero ActivityDetailPanel.jsx no se lo pasaba -- el badge de su propia
pestaña se quedaba con el numero viejo hasta cambiar de pestaña y volver (que es lo unico que
dispara el refetch de comments/attachments ahi). Se conecta reloadComments/reloadAttachments
como onChanged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-14 12:12:03 -05:00
Milton Gonzalez 47fe36a64e fix: version 2.11.2 -- badge de Tareas pasa a hechas/total en vez de pendientes/total
"3/4" se leia como "3 pendientes de 4", confuso. Ahora "1/4" = 1 hecha de 4, mismo criterio
que el resto de contadores nuevos (siempre n/n, nunca se oculta).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-14 12:01:45 -05:00
Milton Gonzalez d44f96bb6c fix: version 2.11.1 -- mueve los contadores de 2.11.0 de columnas de grilla a badges de pestaña
La 2.11.0 agrego los contadores de dependencias/comentarios/documentos/miembros como columnas
nuevas en las tablas de Proyectos y Actividades -- no era el pedido original, desbordaba la
grilla. Se revierten esas columnas (y el componente CountBadge que solo ellas usaban) y los
contadores van donde correspondia desde el principio: como badge junto al nombre de cada
pestaña, al mismo estilo que ya usaba "Tareas n/n" (componente Tabs + .tab-badge):
- Proyecto: pestañas Miembros, Actividades (completas/total), Comentarios, Documentos.
- Actividad: pestaña Dependencias (ya existia Tareas/Comentarios/Documentos, solo faltaba esta).

De paso: Tabs.jsx ocultaba el badge cuando count era 0 (!!tab.count) -- se cambia a mostrar
siempre que la pestaña mande la prop (count !== undefined), para que 0 se vea como "0" y no
desaparezca. CommentsPanel/AttachmentsPanel ganan un onChanged opcional para que el contador
de Comentarios/Documentos del PROYECTO se actualice al tiro sin tener que recargar la pagina
(el de la actividad ya se refrescaba solo al cambiar de pestaña).

El backend de 2.11.0 (subconsultas dependencies_count/comments_count/documents_count/
members_count/activities_total/activities_complete en los LIST_SELECT) se mantiene igual,
solo cambia donde el frontend los usa.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-14 11:53:43 -05:00
Milton Gonzalez 4520abe96f feat: version 2.11.0 -- contadores de dependencias/comentarios/documentos/miembros en listados
Actividades (dentro de un proyecto): nuevas columnas con la cantidad de dependencias,
comentarios y documentos de cada fila -- subconsultas correlacionadas agregadas al
LIST_SELECT existente (mismo patron que share_count de notas/proyectos), siempre numericas
(0 si no hay, nunca oculto).

Proyectos: nuevas columnas con la cantidad de miembros, actividades completas al 100% sobre
el total (ej. "1/4", mismo patron pendientes/total que ya usa la pestaña de tareas de una
actividad), comentarios y documentos.

Nuevo componente CountBadge (icono + numero) reutilizado en ambos listados -- a diferencia de
SharedWithIcon/Tabs que ocultan el badge en 0, este siempre lo muestra.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-14 11:40:07 -05:00
Milton Gonzalez 82308faeb1 feat: version 2.6.0 -- barra de progreso rediseñada + icono de compartido
Porcentaje de avance dentro de la barra (antes aparte), fondo gris
visible en vez de casi invisible sobre el tema oscuro. Nuevo icono en
el listado de Proyectos que muestra con quien esta compartido cada
proyecto y su permiso, solo si aplica.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-30 08:04:50 -05:00
Milton Gonzalez fda83e9dff fix: version 2.5.0 -- compartir proyectos con permisos reales (Lectura/Escritura)
Bug de seguridad real corregido: cualquier usuario autenticado veia
TODOS los proyectos (listado, detalle, actividades, tareas,
comentarios, adjuntos, KPIs del panel), sin importar si era miembro.
Ahora nadie ve un proyecto ajeno sin que su dueno se lo comparta --
los roles de administracion (superadmin/admin/it_manager) mantienen
visibilidad total para soporte.

Nuevo modelo de permisos por proyecto, simple y no granular:
- Solo el dueno original puede compartir un proyecto (agregar/quitar
  miembros, cambiar su nivel) -- ni un admin del proyecto ni un rol
  global pueden hacerlo por el.
- Dos niveles: Lectura (solo ver) y Escritura (crear/editar/eliminar
  actividades y tareas -- nunca el proyecto en si: no lo borra, no
  edita sus datos, no crea proyectos nuevos).

Actividades y tareas pasan a borrado logico (antes se borraban
fisico sin poder recuperar) -- nueva papelera por proyecto con
restaurar.

Incluye tambien el filtro "Usuario" en Proyectos (probado en dev en
un paso anterior), que va de la mano con este cambio de visibilidad.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-25 18:19:41 -05:00
Milton Gonzalez 043433bf9b feat: convertir una actividad en proyecto (con sus tareas)
Una tarea siempre necesita una actividad contenedora, asi que convertir crea DOS cosas: el
proyecto nuevo y, dentro, una actividad nueva que recibe las tareas -- y comentarios/adjuntos --
de la actividad original. Se piden ambos nombres (precargados con el nombre actual) antes de
confirmar. La actividad original se borra al final, ya vacia de tareas (no choca con el bloqueo
de removeActivity). Exige el mismo permiso que crear un proyecto, no solo escribir la actividad.

Nuevo POST /api/activities/:id/convert-to-project. Probado de punta a punta en dev: prioridad
heredada, tareas y comentario movidos correctamente, actividad original eliminada, navega al
proyecto nuevo al terminar.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-17 08:59:16 -05:00
Milton Gonzalez 67cb58ed0b feat: el buscador de Proyectos y Actividades tambien busca en tareas
Buscador de Proyectos: ahora busca tambien en actividades y tareas de cualquier proyecto (antes
solo nombre/codigo del proyecto). Resultados en un panel flotante con la ruta completa
"Proyecto - Actividad - Tarea"; clic navega al proyecto y abre la actividad encontrada
(pestaña Tareas si el resultado era una tarea).

Buscador de Actividades (dentro de un proyecto): busca tambien en las tareas de esa actividad,
mismo panel con "Actividad - Tarea".

Nuevo GET /api/search?q=...&projectId= (global o acotado a un proyecto). Nuevos componentes/hooks
reutilizables: SearchResultsDropdown, useDebouncedValue.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 15:04:53 -05:00
Milton Gonzalez 53570bd4f8 feat: mover una actividad (con sus tareas) a otro proyecto
Menu de tres puntos en el listado de Actividades -> elegir proyecto destino -> confirmar
("Se movera la actividad... (junto con sus tareas)... Aceptar/Cancelar) antes de ejecutar.

Tareas, comentarios y adjuntos se mueven solos (referencian la actividad, no el proyecto). Las
dependencias existentes se eliminan al mover -- solo tienen sentido dentro del mismo proyecto
(addDependency ya lo exigia). Nuevo PUT /api/activities/:id/move, exige permiso de escritura en
ambos proyectos (origen y destino).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 14:47:57 -05:00
Milton Gonzalez 9d76e1b79b feat: columna Actualizado (fecha y hora) en el listado de Actividades
Mismo formato que ya existia en Proyectos. Ordenable por columna; no cambia el orden por
defecto (sigue siendo el orden manual arrastrado con el mouse).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 14:38:44 -05:00
Milton Gonzalez 696ab0d092 fix: arrastrar tareas para reordenar dejo de funcionar
Regresion del fix del checkbox (v1.15.2): draggable/onDragStart quedaron directo sobre el <svg>
del icono de agarre, que solo capta el mousedown sobre lo pintado (huecos entre sus formas), no
sobre todo su recuadro -- el navegador no siempre detectaba el inicio del arrastre. Envuelto en
un <span> con area de agarre solida, mismo patron ya usado en el listado de Actividades.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 14:22:26 -05:00
Milton Gonzalez 60347fab72 feat: contador de Tareas muestra pendientes/total (ej. 2/3)
Solo la pestaña Tareas -- Comentarios y Documentos siguen con el total simple. Se recalcula al
agregar, quitar o marcar/desmarcar tareas.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 13:02:34 -05:00
Milton Gonzalez 1b23da7151 feat: contador en las pestañas de Tareas/Comentarios/Documentos de una actividad
Circulo con el numero al lado del nombre de la pestaña: Tareas muestra las pendientes (sin
marcar), Comentarios y Documentos el total. Soporte agregado al componente Tabs reutilizable
(tab.count), no solo al detalle de actividad.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 12:52:00 -05:00
Milton Gonzalez c84a07968f fix: checkbox de tarea (hecho) no se actualizaba tras guardar
useDragReorder resincronizaba su copia local solo cuando cambiaba el conjunto de ids, no cuando
se editaba un campo de una tarea existente (marcar hecho, renombrar) -- la fila se quedaba
mostrando el snapshot viejo para siempre despues de guardar. Ahora compara el contenido completo.

De paso: draggable/onDragStart pasan a vivir solo en el icono de agarre, nunca en toda la fila --
un ancestro draggable=true le gana el mousedown a los controles interactivos que tenga adentro en
algunos navegadores (no era la causa de este bug puntual, pero es un problema real del mismo
patron que conviene cerrar ya que se reutiliza en cualquier lista futura).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 12:33:35 -05:00
Milton Gonzalez 80981e9063 feat: arrastrar con el mouse para reordenar actividades y tareas
Hook reutilizable useDragReorder (drag & drop nativo HTML5, sin
libreria nueva) usado en dos lugares: ListView (opt-in via onReorder,
deshabilitado mientras haya un ordenamiento por columna activo) para
el listado de actividades de un proyecto, y el listado de tareas de
una actividad. Orden persistido en sort_order (activities y tasks,
migracion 012, posiciones siempre 1..N).

Fix real encontrado durante las pruebas: sincronizar el estado interno
del hook por la REFERENCIA del arreglo de entrada entraba en loop
infinito de renders cuando el llamador pasa "algo || []" (un arreglo
nuevo en cada render mientras los datos cargan). Corregido para
sincronizar por el contenido (ids), no por referencia.

Probado en dev con curl (persistencia del orden) y Playwright
(arrastrar filas en el navegador, orden visible y guardado
correctamente, sin errores de consola tras el fix).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 12:41:19 -05:00
Milton Gonzalez 5e0bc0809e feat: eliminar actividad, bloqueado si tiene tareas pendientes
No existia forma de borrar una actividad. Agregado DELETE
/api/activities/:id con boton "Eliminar" en el listado (popup de
confirmacion). Si tiene tareas, se bloquea con 400 y mensaje claro en
vez de arrastrar todo en cascada sin avisar.

De paso: la logica de borrar adjunto (fila + archivo en disco) se
extrajo a un attachments/service.js reutilizable, usado tanto por el
borrado individual como por el borrado en cascada de una actividad
(evita archivos huerfanos). Comentarios de la actividad tambien se
limpian (sin FK fisica cruzada, entity_type/entity_id es polimorfico).

Probado en dev con curl (bloquea con tarea, permite sin tareas, 404
tras borrar) y Playwright (mensaje de advertencia visible).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 12:30:53 -05:00
Milton Gonzalez 8fa45de6d0 feat: reemplaza "Creado" por "Actualizado" en el listado de Proyectos
Columna con fecha y hora, orden por defecto (mas reciente primero) en
vez de fecha de creacion.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-14 17:26:41 -05:00
Milton Gonzalez a9904074e5 feat: boton editar (lapiz) en cada tarea de una actividad
El backend ya soportaba renombrar una tarea (PUT /api/tasks/:id), solo
faltaba el boton en la UI. Edicion en linea: input + guardar (Enter o
icono) / cancelar (Escape o icono).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-14 09:29:49 -05:00
Milton Gonzalez 13a69aadc3 feat: campo "hasta" opcional en Tareas recurrentes
Vacio = se repite sin fin (comportamiento previo). Al completar un
ciclo cuyo proximo vencimiento supera "hasta", la tarea se desactiva
sola. Probado en dev con curl (3 ciclos seguidos, se desactiva justo
al superar la fecha) y validacion de que "hasta" no puede ser anterior
al proximo vencimiento.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 10:29:09 -05:00
Milton Gonzalez 72b616bd02 feat: Tareas recurrentes con recordatorio por correo
Menu propio en la barra lateral, independiente de Proyectos:
- Periodicidad configurable (cada N dias/meses/años), proximo
  vencimiento, responsable, proyecto de origen opcional.
- "Completar ciclo" avanza el proximo vencimiento sumando la
  periodicidad y limpia el recordatorio ya enviado.
- Recordatorio por correo automatico N dias antes del vencimiento
  (default 7), a una hora del dia configurable. Un job en el propio
  proceso del backend (setInterval cada 15 min) revisa y envia, sin
  infraestructura nueva (cron del SO, cola, etc).
- Desde la pestaña Tareas de una actividad, cada tarea tiene un boton
  "Convertir en recurrente" que la promueve (la tarea original no se
  borra).

Probado en dev con curl (crear, completar ciclo avanza next_due_date,
promover desde una tarea real, disparo real del job de recordatorios
verificado forzando fecha/hora, segunda corrida no reenvia) y Playwright
(listado, popup de creacion, popup de promocion anidado sobre el detalle
de actividad) sin errores de consola.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 10:17:02 -05:00
Milton Gonzalez 3ab0656a3e feat: filtros de Estado, Prioridad y proximos a vencer en Proyectos
El backend ya soportaba filtrar por statusId/priorityId; solo faltaba
exponerlo en la UI. "Proximos a vencer" es client-side, ventana de 7
dias (misma definicion que el KPI del dashboard).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 09:56:09 -05:00
Milton Gonzalez ccf5cbeb13 feat: ordenar proyectos por prioridad real + separa paginas web de dominios
canWriteProject/ListView ya soportaba ordenar por cualquier columna con
clic en el encabezado; solo Prioridad ordenaba alfabetico por el texto
en vez de por severidad real. Se agrega pr.level a la consulta y
sortValue en la columna.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 09:41:07 -05:00
Milton Gonzalez 92591f5c44 fix: mensaje claro cuando no hay actividades para agregar como dependencia
"Agregar dependencia" no daba ninguna señal cuando el combo quedaba vacio
(proyecto con una sola actividad, o ya se agregaron todas las demas) --
se podia percibir como que el boton "no hacia nada". El mecanismo en si
funcionaba bien (verificado con curl y Playwright con 2+ actividades).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-10 11:40:26 -05:00
Milton Gonzalez bb6bd6865c refactor: renombra Subtareas a Tareas en todo el sistema
Actividad -> Tarea, sin nivel "sub" intermedio (no hay una entidad "Tarea"
de la que estas fueran sub-, asi que el prefijo sobraba). Tabla subtasks
-> tasks (RENAME TABLE idempotente en la migracion 005; 001_initial.sql
tambien actualizado para que una instalacion nueva cree la tabla ya con
el nombre final, sin pasar por el nombre viejo). Modulo backend, rutas,
servicio frontend, pestaña del detalle de actividad, i18n y documentacion
actualizados. Sin cambios de comportamiento, solo nombres.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-10 08:55:58 -05:00
Milton Gonzalez d7478d0f21 feat: invitar a un proyecto por correo a alguien que aun no es usuario
Al agregar un miembro, el popup ahora permite elegir un usuario existente
o escribir un correo nuevo. Si ese correo no pertenece a nadie, se crea
una cuenta en estado 'invited' (nombre/clave placeholder) y se le manda
un correo con un enlace de un solo uso para que complete su registro
(elige su nombre y clave). La fila de project_members se crea de una vez
al invitar, asi que en cuanto acepta ya es miembro sin pasos adicionales.
A diferencia del autorregistro publico, no pasa por aprobacion de un
admin -- quien lo agrego a su proyecto ya lo vetó.

Nuevos endpoints publicos GET /api/auth/invite y POST /api/auth/accept-invite.
Nueva pagina AcceptInvitePage (/aceptar-invitacion). Migracion 004 agrega
el status 'invited' al enum de users.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-09 23:55:02 -05:00
Milton Gonzalez f96391d360 feat: administradores por proyecto y Configuracion solo para superadmin
- Un proyecto puede tener uno o mas administradores (role_in_project=
  'admin' en project_members), independiente del rol global del usuario.
  Nuevo PUT /api/projects/:id/members/:userId/role; canWriteProject lo
  reconoce ademas del comportamiento previo (admin/superadmin/it_manager
  global, o project_lead miembro). UI: casilla al agregar miembro + boton
  de escudo para promover/degradar (nunca toca al Dueño).
- Menu "Configuracion" (apariencia, catalogos, SMTP) visible y accesible
  solo para el superadmin: oculto en el nav y con guarda en la ruta
  /configuracion para quien la teclee directo. Escritura de catalogos
  restringida de [superadmin, admin] a solo superadmin para que el
  backend sea consistente con la UI.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-09 09:41:06 -05:00
Milton Gonzalez 5a25ed066d feat: eliminar proyecto (logico), papelera para superadmin y orden por creacion
- DELETE /api/projects/🆔 eliminacion logica (deleted_at/deleted_by), mismo
  permiso que editar el proyecto. Popup de confirmacion antes de aplicarla.
- Papelera (GET /api/projects?trash=true, POST /:id/restore, DELETE
  /:id/permanent) restringida al superadmin; el borrado fisico exige que el
  proyecto ya este en la papelera y arrastra actividades/comentarios/adjuntos
  por ON DELETE CASCADE.
- Dashboard (KPIs, actividades pendientes/calendario, proyectos por estado)
  excluye proyectos eliminados logicamente.
- Columna "Creado" en el listado de proyectos, ordenado por defecto de mas
  nuevo a mas antiguo (ListView admite initialSort ademas del orden por clic
  en cabecera que ya tenia).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-09 09:26:35 -05:00
Milton Gonzalez 827d798ef8 feat(proyectos): Miembros pasa a ser su propia pestaña junto a Info
Antes la lista de miembros del proyecto vivia dentro de la pestaña Info,
mezclada con los campos del proyecto. Se extrae a un componente propio
(ProjectMembersTab) y se agrega como pestaña "Miembros" justo a la derecha
de "Info" en el detalle del proyecto.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-03 14:44:58 -05:00
Milton Gonzalez 2661d31977 fix(ui): elimina los 2 casos que quedaban de formulario debajo de un listado
Auditoria completa del frontend: quedaban 2 lugares con el mismo antipatron que
ya se habia corregido en Proyectos/Departamentos/Usuarios/Catalogos.

- ProjectActivitiesTab: "Nueva actividad" se apilaba debajo del listado de
  actividades. Ahora abre en su propio DetailPopup, igual que el resto.
- ProjectInfoTab (pestaña Info de un proyecto): el combo "agregar miembro" se
  apilaba debajo de la lista de miembros. Ahora hay un boton "Agregar miembro"
  en el encabezado de esa tarjeta que abre un DetailPopup chico.

Con esto no queda ningun listado del sistema con un formulario apilado debajo:
todos usan DetailPopup (ver regla en project-md-templates/UI-UX-WINDOWS.md).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-03 11:39:35 -05:00
Milton Gonzalez b172a8f087 fix(ui): no desmontar la pantalla en cada recarga en segundo plano
Las 11 pantallas con listado/detalle bloqueaban TODO su render con
"if (loading || !data) return <Cargando/>". Como useAsync pone loading=true en
cada reload (no solo en la carga inicial), cualquier accion dentro de un
DetailPopup abierto que dispara un reload del padre (agregar subtarea, agregar
dependencia, guardar comentario, etc.) desmontaba momentaneamente TODA la
pantalla -y con ella el popup y su estado interno (pestaña activa)-, que volvia
a montarse desde cero con sus valores iniciales.

Sintoma reportado: al agregar una subtarea (Enter o boton "Nuevo"), el popup de
la actividad volvia a la pestaña Info en vez de quedarse en Subtareas.

Fix: la guarda ahora es solo "if (!data)" -bloquea unicamente la carga
inicial, cuando todavia no hay nada que mostrar-. Las recargas subsiguientes
actualizan el contenido en el sitio sin desmontar nada.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-03 11:30:20 -05:00
Milton Gonzalez 1e6e7fecdd fix(ui): reemplaza panel-debajo-del-listado por DetailPopup de tamaño fijo
El detalle de un item de listado (actividad, departamento, usuario, proyecto nuevo,
catalogo) ya no se apila debajo ni al costado del listado: ahora abre en un popup que
cubre la ventana, deja el listado inactivo detras, nunca se cierra con clic afuera (solo
con el boton Cerrar o una accion explicita del formulario) y mantiene un alto FIJO por
instancia para que cambiar de pestaña interna (Info/Subtareas/Dependencias/Comentarios/
Documentos) no reajuste su tamaño.

De paso corrige un bug real de stacking: ContentDialog no usaba portal a document.body,
así que un dialogo de confirmacion abierto desde dentro de un DetailPopup quedaba oculto
detras de este. Ahora ambos son portales con una jerarquia de z-index explicita
(Flyout 100 < DetailPopup 200 < ContentDialog 250 < Toast 300).

En el detalle de actividad, Subtareas y Dependencias pasan de estar apiladas dentro de la
pestaña Info a ser cada una su propia pestaña.

Regla documentada en project-md-templates/UI-UX-WINDOWS.md (componente DetailPopup) para
que aplique a futuros proyectos de escritorio Windows del grupo.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-03 11:21:07 -05:00
Milton Gonzalez 1d22adc42e chore: estructura inicial del MVP
Backend (Express + MariaDB) y frontend (React + Vite, identidad Fluent/Windows) con el
nucleo funcional: seguridad, organizacion, proyectos, actividades, subtareas, dependencias,
dashboard, calendario, gantt, comentarios, adjuntos, notificaciones in-app y catalogos.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-03 08:37:58 -05:00