Skip to content

Reconciliación: React 19 + Router v8, arnés E2E robosoft y fixes G-159/160/161 (rebrand BeyondNet) - #6

Merged
beyondnetPeru merged 4 commits into
mainfrom
migration/unimar-ums-resync-2026-07-25
Jul 25, 2026
Merged

Reconciliación: React 19 + Router v8, arnés E2E robosoft y fixes G-159/160/161 (rebrand BeyondNet)#6
beyondnetPeru merged 4 commits into
mainfrom
migration/unimar-ums-resync-2026-07-25

Conversation

@beyondnetPeru

Copy link
Copy Markdown
Contributor

Qué

Reconciliación selectiva: se trae a beyondnetcode/ums el trabajo de valor más reciente de unimar-ums (rebrandeado a BeyondNet), manteniendo el actual como base (feature de branding por-tenant, gobernanza Evolith). No se copia unimar-core; los shells siguen como paquetes NuGet BeyondNetCode.Shell.*.

Commits

Commit Contenido
d6a130b8 React 19 + React Router v8 + bumps de seguridad (axios/fast-uri/form-data/brace-expansion/storybook) + Dockerfile node:24. Conserva graphql/branding. 7 imports migrados react-router-domreact-router.
e7d2995b Arnés E2E robosoft (carril B, 32 archivos) rebrandeado: @unimar-peru/ums-sdk-*@ums/sdk-*, etc.
1bff04c0 Fixes backend G-159 / G-160 / G-161 (aislamiento/seguridad/integridad) + tests.
81ed609d Deuda de lint resuelta en los 7 archivos migrados (0 errores eslint).

Fixes backend

  • G-159 (aislamiento): GET /approval-requests ignoraba el filtro userId → ahora filtra por TargetUserId.
  • G-160 (seguridad): aprobar con grantedRoleId inexistente creaba un perfil con rol fantasma que rompía el login (AUTH_000) → se valida el rol vía IRoleRepository.
  • G-161 (integridad de contrato): provisión cross-tenant de sucursales devolvía 201 engañoso → nuevo BranchCodeExistsAsync (IgnoreQueryFilters) → 409.

Validación local

  • Web: vite build OK · vitest 1473/1476 (3 fallos preexistentes en NavRail.test.tsx, ajenos a este cambio) · eslint 0 errores en archivos tocados.
  • .NET: build 0 errores · Ums.Application.Test 608/608 · Ums.Domain.Test 717/717.
  • Arnés E2E: playwright --list compila todas las invariantes (ejecución en vivo requiere backend en E2E_BASE_URL).

Notas

  • Suite de integración .NET: ~80/161 pasan; los 79 fallos son preexistentes y sistémicos (afectan áreas no tocadas — Configuration/UserAccount/SystemSuite; gap G-014 "la suite de integración no siembra"). Ningún test fallido ejecuta el código nuevo de este PR.
  • Marca visual BeyondNet: aplicado solo el rebrand de naming; logos/paleta/tipografía quedan como placeholder pendiente del brand-kit oficial.
  • unimar-core: 0 líneas copiadas. evolith.yaml y Evolith.Contracts.* intactos.

🤖 Generated with Claude Code

beyondnetPeru and others added 4 commits July 25, 2026 12:33
Porta el trabajo de unimar-ums (rebrandeado a BeyondNet) manteniendo el
branding por-tenant propio del satelite (graphql conservado):

- react/react-dom 18.3.1 -> 19.2.8
- react-router-dom 6.30.4 -> react-router 8.3.0 (7 sitios de import migrados)
- axios 1.16.0 -> 1.18.0; +cookie-es (req. de react-router 8); +rollup (G-163)
- @types/react(-dom) -> 19; scripts test:coverage/test:e2e
- overrides de seguridad: react/react-dom 19, axios 1.18, fast-uri, form-data,
  brace-expansion (nx), storybook esbuild
- Dockerfile web: node:20-alpine -> node:24-alpine (RRv8 exige node>=22)

Base del lockfile tomada del lock react-19 probado de la fuente para evitar el
arbol incompleto que produce regenerar desde cero en este monorepo.

Validacion local: vite build OK; vitest 1473/1476 (3 fallos preexistentes en
NavRail.test.tsx, ajenos a este cambio).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Trae desde unimar-ums el arnés E2E funcional robosoft (32 archivos: specs
Playwright de API, helpers auth/invariant/provision, harness Python de
contexts, READMEs), rebrandeado por completo:

- @unimar-peru/ums-sdk-* -> @ums/sdk-*
- Unimar.Ums -> Ums; Unimar/unimar -> BeyondNet/beyondnet
- unimar-cluster-ums -> beyondnet-cluster-ums

Sin referencias a unimar-core. Autocontenido (solo @playwright/test + helpers
relativos + node:crypto). Validado: `playwright test --list` compila y enumera
todas las invariantes (INV-AR/WF/UD/AEP/AU...). La ejecución en vivo requiere el
backend en E2E_BASE_URL (por defecto http://localhost:8080).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Porta desde unimar-ums (adaptado a la estructura del satélite BeyondNet) tres
correcciones halladas por el arnés RoboSoft (carril B):

- G-159 (aislamiento): GET /approval-requests ignoraba el filtro userId y
  devolvía todas las solicitudes del inquilino. GetAllApprovalRequestsQueryHandler
  ahora filtra por TargetUserId cuando UserId viene informado.
- G-160 (seguridad): aprobar con un grantedRoleId inexistente creaba un Profile
  con rol FANTASMA que rompía el login del usuario objetivo (AUTH_000).
  ApproveRequestCommandHandler valida el rol vía IRoleRepository antes de
  Profile.Create. Test actualizado con mock de rol.
- G-161 (integridad de contrato): provisión cross-tenant de sucursales devolvía
  201 engañoso en un duplicado (el filtro global vaciaba la colección del
  agregado). Nuevo ITenantRepository.BranchCodeExistsAsync (IgnoreQueryFilters)
  invocado en AddBranchCommandHandler → 409. Implementado en Postgres, SqlServer
  e InMemory. Test de regresión Handle_WhenBranchCodeExistsCrossTenant.

Validación local: build 0 errores; Application.Test 608/608; Domain.Test 717/717.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Deja los 7 archivos tocados por el upgrade con 0 errores de eslint (pasan
lint-staged):

- no-explicit-any: catch (err: any) -> unknown + cast tipado (convención del
  repo); mock de i18n en NavRail.test tipado.
- no-unused-vars: retira `hasModuleAccess`, `authService`, `getByText`, `t`
  (y el import huérfano de useI18n).
- react-hooks/set-state-in-effect y purity: eslint-disable justificado sobre el
  timer de lockout de LoginScreen (patrón intencional preexistente; refactor
  omitido para no arriesgar el comportamiento por una regla nueva del plugin).

vite build OK; vitest 1473/1476 (3 fallos preexistentes de NavRail, ajenos).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
data: { userAccountId: userId, password },
});
if (pass.status() !== 201) throw new Error(`fijar contraseña ${pass.status()}: ${await pass.text()}`);
return { userId, tenantCode: 'BEYONDNET', username: email, password };
if (pwd.status() !== 201) throw new Error(`refresh/password ${pwd.status()}: ${await pwd.text()}`);
const act = await accionCuenta(request, cuenta.id, 'activate', ctx);
if (act.status() !== 204) throw new Error(`refresh/activate ${act.status()}: ${await act.text()}`);
return { tenantId: tenant.id, tenantCode: tenant.code, username: email, password, userAccountId: cuenta.id, contexto: ctx };
Comment on lines +13 to +28
import {
uid,
crearSuite,
agregarModulo,
activarModulo,
agregarNodo,
registrarAccion,
vincularAccionNodo,
crearRol,
actualizarRol,
crearPlantilla,
publicarPlantilla,
agregarItemPlantilla,
construirArbolMinimo,
resolverTenantIdPorCodigo,
} from '../helpers/provision';
invariante(
{ id: 'INV-TS08', contexto: CTX, descripcion: 'Seguridad: las proyecciones de lectura NO exponen contraseñas/hashes/secretos', referencia: 'ReadModels sin campos sensibles (FR-010)' },
async ({ request }) => {
const admin = adminBeyondNet();
@beyondnetPeru
beyondnetPeru merged commit e8cf8db into main Jul 25, 2026
11 of 23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants