diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7fe93e6..e3f10d2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,6 +47,8 @@ jobs: cache-dependency-path: web-v2/package-lock.json - run: npm ci - run: npm run typecheck + - name: F3.1 WEB contract + run: bash ../scripts/check-f3-1-web-contract.sh - run: npm run build contract: @@ -62,5 +64,15 @@ jobs: done < <(find scripts -type f -name '*.sh' -print0) - name: Validate Compose run: docker compose --env-file .env.example config >/dev/null + - name: VPS-equivalent isolated API preflight + run: | + set -Eeuo pipefail + image="dhv2-api:ci-vps-preflight-${GITHUB_SHA::12}" + docker build --target builder -t "$image" api-v3 + docker run --rm \ + -v "$PWD/api-v3/test:/app/test:ro" \ + -v "$PWD/api-v3/tsconfig.test.json:/app/tsconfig.test.json:ro" \ + "$image" npm test + docker image rm "$image" >/dev/null 2>&1 || true - name: Build production images run: docker compose --env-file .env.example build api migrate web diff --git a/api-v3/test/unit/f3-1-inventory-structure.test.ts b/api-v3/test/unit/f3-1-inventory-structure.test.ts index ca63f5e..9761435 100644 --- a/api-v3/test/unit/f3-1-inventory-structure.test.ts +++ b/api-v3/test/unit/f3-1-inventory-structure.test.ts @@ -52,15 +52,3 @@ test('F3.1 fuerza Área → Yacimiento → Instalación → Subinstalación en s assert.match(service, /SUBINSTALACION: 'instalacion'/); assert.match(service, /INVENTORY_SUBINSTALLATION_FAMILY_PARENT_INVALID/); }); - -test('F3.1 retira Relevamientos del dashboard y usa alta guiada de cuatro niveles', () => { - const layout = readFileSync('../web-v2/src/layout/AppLayout.tsx', 'utf8'); - const app = readFileSync('../web-v2/src/app/App.tsx', 'utf8'); - const page = readFileSync('../web-v2/src/pages/InventoryCreatePage.tsx', 'utf8'); - assert.doesNotMatch(layout, /label: 'Relevamientos'/); - assert.match(app, /path="\/relevamiento\/\*" element={}/); - assert.match(app, /path="\/inventarios\/nuevo" element={}/); - for (const kind of ['AREA', 'YACIMIENTO', 'INSTALACION', 'SUBINSTALACION']) assert.match(page, new RegExp(`kind: '${kind}'`)); - assert.doesNotMatch(page, /kind: 'EQUIPO'/); - assert.match(page, /getInventoryFamilyFindings/); -}); diff --git a/scripts/check-f3-1-web-contract.sh b/scripts/check-f3-1-web-contract.sh new file mode 100644 index 0000000..83acb70 --- /dev/null +++ b/scripts/check-f3-1-web-contract.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +LAYOUT="$ROOT/web-v2/src/layout/AppLayout.tsx" +APP="$ROOT/web-v2/src/app/App.tsx" +PAGE="$ROOT/web-v2/src/pages/InventoryCreatePage.tsx" + +for file in "$LAYOUT" "$APP" "$PAGE"; do + test -f "$file" || { + echo "F3.1 WEB contract: falta $file" + exit 1 + } +done + +if grep -Fq "label: 'Relevamientos'" "$LAYOUT"; then + echo "F3.1 WEB contract: Relevamientos no debe volver al menú principal" + exit 1 +fi + +grep -Fq 'path="/relevamiento/*"' "$APP" +grep -Fq 'Navigate to="/inventarios" replace' "$APP" +grep -Fq 'path="/inventarios/nuevo"' "$APP" +grep -Fq 'InventoryCreatePage' "$APP" + +for kind in AREA YACIMIENTO INSTALACION SUBINSTALACION; do + grep -Fq "kind: '$kind'" "$PAGE" +done + +if grep -Fq "kind: 'EQUIPO'" "$PAGE"; then + echo "F3.1 WEB contract: el alta guiada no debe restaurar EQUIPO como quinto nivel estructural" + exit 1 +fi + +grep -Fq 'getInventoryFamilyFindings' "$PAGE" + +echo 'F3.1 WEB contract: OK'