129 lines
7.3 KiB
Bash
Executable File
129 lines
7.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -Eeuo pipefail
|
|
|
|
ROOT="${ROOT:-/var/www/dhv2.korexlabs.com}"
|
|
API_URL="${API_URL:-http://127.0.0.1:3101/api/v3}"
|
|
DUMMY_UUID="00000000-0000-4000-8000-000000000000"
|
|
TMP_MIGRATION="/tmp/dhv2-d53722-accept-migration-$$.log"
|
|
TMP_ROUTE="/tmp/dhv2-d5372-route-$$.txt"
|
|
trap 'rm -f "$TMP_MIGRATION" "$TMP_ROUTE"' EXIT
|
|
cd "$ROOT"
|
|
|
|
echo "========== D5.3.7.2.2 · VERSIONES =========="
|
|
[[ "$(node -p "require('./api-v3/package.json').version")" == "0.19.3-7.2.2" ]]
|
|
[[ "$(node -p "require('./web-v2/package.json').version")" == "0.19.3-7.2.2" ]]
|
|
grep -Fq "API_PHASE = 'D5.3.7.2.2'" api-v3/src/version.ts
|
|
echo "API: 0.19.3-7.2.2"
|
|
echo "WEB: 0.19.3-7.2.2"
|
|
|
|
echo
|
|
echo "========== D5.3.7.2.2 · DISCO Y DB =========="
|
|
FREE_KB="$(df -Pk "$ROOT" | awk 'NR==2 {print $4}')"
|
|
(( FREE_KB >= 2 * 1024 * 1024 ))
|
|
[[ "$(docker inspect dhv2-db --format '{{.State.Health.Status}}')" == "healthy" ]]
|
|
docker compose exec -T db sh -lc 'pg_isready -U "$POSTGRES_USER" -d "$POSTGRES_DB"'
|
|
echo "Libre: $(( FREE_KB / 1024 / 1024 )) GB · PostgreSQL healthy"
|
|
|
|
echo
|
|
echo "========== D5.3.7.2.2 · MIGRACIONES =========="
|
|
docker compose --profile tools run --rm migrate npm run migration:show 2>&1 | tee "$TMP_MIGRATION"
|
|
grep -Fq 'Pending migrations: no' "$TMP_MIGRATION"
|
|
|
|
echo
|
|
echo "========== D5.3.7.2.2 · HEALTH =========="
|
|
HEALTH="$(curl -fsS "$API_URL/health")"
|
|
echo "$HEALTH"
|
|
grep -Fq '"version":"0.19.3-7.2.2"' <<<"$HEALTH"
|
|
grep -Fq '"phase":"D5.3.7.2.2"' <<<"$HEALTH"
|
|
grep -Fq '"database":"ok"' <<<"$HEALTH"
|
|
|
|
echo
|
|
echo "========== D5.3.7.2.2 · RUTA DE DETALLE PROTEGIDA =========="
|
|
CODE="$(curl -sS -o "$TMP_ROUTE" -w '%{http_code}' "$API_URL/asset-imports/$DUMMY_UUID/plan/items")"
|
|
[[ "$CODE" == "401" ]]
|
|
echo "/asset-imports/:id/plan/items sin sesión: 401 OK"
|
|
|
|
echo
|
|
echo "========== D5.3.7.2.2 · MODELO RELACIONAL =========="
|
|
DB_CHECK="$(
|
|
cat <<'SQL' | docker compose exec -T db sh -c 'psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -At -v ON_ERROR_STOP=1 -v app_user="$APP_DB_USER"'
|
|
SELECT CASE WHEN to_regclass('public.administrative_departments') IS NOT NULL AND to_regclass('public.area_department_relations') IS NOT NULL THEN 'RELATIONAL_TABLES_OK' ELSE 'RELATIONAL_TABLES_BAD' END;
|
|
SELECT CASE WHEN
|
|
has_table_privilege(:'app_user','administrative_departments','SELECT') AND
|
|
has_table_privilege(:'app_user','administrative_departments','INSERT') AND
|
|
has_table_privilege(:'app_user','administrative_departments','UPDATE') AND
|
|
NOT has_table_privilege(:'app_user','administrative_departments','DELETE') AND
|
|
has_table_privilege(:'app_user','area_department_relations','SELECT') AND
|
|
has_table_privilege(:'app_user','area_department_relations','INSERT') AND
|
|
has_table_privilege(:'app_user','area_department_relations','UPDATE') AND
|
|
NOT has_table_privilege(:'app_user','area_department_relations','DELETE')
|
|
THEN 'RELATIONAL_PRIVILEGES_OK' ELSE 'RELATIONAL_PRIVILEGES_BAD' END;
|
|
SELECT CASE WHEN EXISTS (SELECT 1 FROM typeorm_migrations WHERE name='PhaseD5372RelationalTerritoryPlan1787767200000') THEN 'MIGRATION_OK' ELSE 'MIGRATION_BAD' END;
|
|
SELECT CASE WHEN EXISTS (
|
|
SELECT 1 FROM pg_constraint
|
|
WHERE conname='chk_asset_import_plan_item_kind'
|
|
AND pg_get_constraintdef(oid) LIKE '%DEPARTMENT%'
|
|
AND pg_get_constraintdef(oid) LIKE '%AREA_DEPARTMENT_RELATION%'
|
|
AND pg_get_constraintdef(oid) LIKE '%LEGAL_RIGHT%'
|
|
AND pg_get_constraintdef(oid) LIKE '%LEGAL_RIGHT_ORGANIZATION%'
|
|
) THEN 'PLAN_KINDS_OK' ELSE 'PLAN_KINDS_BAD' END;
|
|
SQL
|
|
)"
|
|
echo "$DB_CHECK"
|
|
grep -Fq 'RELATIONAL_TABLES_OK' <<<"$DB_CHECK"
|
|
grep -Fq 'RELATIONAL_PRIVILEGES_OK' <<<"$DB_CHECK"
|
|
grep -Fq 'MIGRATION_OK' <<<"$DB_CHECK"
|
|
grep -Fq 'PLAN_KINDS_OK' <<<"$DB_CHECK"
|
|
|
|
echo
|
|
echo "========== D5.3.7.2.2 · NORMALIZACIÓN Y DEDUPLICACIÓN =========="
|
|
grep -Fq 'organizationImportKey' api-v3/src/asset-imports/asset-import-plan.ts
|
|
grep -Fq 'normalizedLegalRightType' api-v3/src/asset-imports/asset-import-plan.ts
|
|
grep -Fq "entityKind: 'DEPARTMENT'" api-v3/src/asset-imports/asset-imports.service.ts
|
|
grep -Fq "entityKind:'AREA_DEPARTMENT_RELATION'" api-v3/src/asset-imports/asset-imports.service.ts || grep -Fq "entityKind: 'AREA_DEPARTMENT_RELATION'" api-v3/src/asset-imports/asset-imports.service.ts
|
|
grep -Fq "entityKind:'LEGAL_RIGHT'" api-v3/src/asset-imports/asset-imports.service.ts || grep -Fq "entityKind: 'LEGAL_RIGHT'" api-v3/src/asset-imports/asset-imports.service.ts
|
|
grep -Fq "entityKind:'LEGAL_RIGHT_ORGANIZATION'" api-v3/src/asset-imports/asset-imports.service.ts || grep -Fq "entityKind: 'LEGAL_RIGHT_ORGANIZATION'" api-v3/src/asset-imports/asset-imports.service.ts
|
|
grep -Fq "operatorUnassigned ? '' : organizationImportKey(operator)" api-v3/src/asset-imports/asset-imports.service.ts
|
|
grep -Fq "organizationImportKey\(operator\)" api-v3/test/unit/asset-imports-d5-3-7.test.ts || grep -Fq "organizationImportKey(operator)" api-v3/test/unit/asset-imports-d5-3-7.test.ts
|
|
if grep -Fq "add('departamento'" api-v3/src/asset-imports/asset-imports.service.ts; then
|
|
echo "ERROR: Departamento no debe persistirse como atributo textual duplicado"; exit 1
|
|
fi
|
|
grep -Fq "status:'PENDING'" api-v3/src/asset-imports/asset-imports.service.ts || grep -Fq "status: 'PENDING'" api-v3/src/asset-imports/asset-imports.service.ts
|
|
grep -Fq 'no se infiere titularidad' api-v3/src/asset-imports/asset-imports.service.ts
|
|
echo "Departamentos únicos, siglas de organizaciones, derechos normalizados y relaciones explícitas: OK"
|
|
|
|
echo
|
|
echo "========== D5.3.7.2.2 · APLICACIÓN Y ROLLBACK =========="
|
|
grep -Fq 'INSERT INTO administrative_departments' api-v3/src/asset-imports/asset-imports.service.ts
|
|
grep -Fq 'INSERT INTO area_department_relations' api-v3/src/asset-imports/asset-imports.service.ts
|
|
grep -Fq 'INSERT INTO area_legal_rights' api-v3/src/asset-imports/asset-imports.service.ts
|
|
grep -Fq 'INSERT INTO area_legal_right_organizations' api-v3/src/asset-imports/asset-imports.service.ts
|
|
grep -Fq "area_department_relations SET valid_until=CURRENT_DATE" api-v3/src/asset-imports/asset-imports.service.ts
|
|
grep -Fq "area_legal_rights SET status='REVOKED'" api-v3/src/asset-imports/asset-imports.service.ts
|
|
grep -Fq "administrative_departments SET is_active=false" api-v3/src/asset-imports/asset-imports.service.ts
|
|
if grep -Eq 'DELETE FROM (assets|administrative_departments|area_department_relations|area_legal_rights)' api-v3/src/asset-imports/asset-imports.service.ts; then
|
|
echo "ERROR: rollback relacional no debe hacer DELETE físico"; exit 1
|
|
fi
|
|
grep -Fq '::integer,$${base+2}::uuid' api-v3/src/asset-imports/asset-imports.service.ts
|
|
grep -Fq 'row.row_number=v.row_number' api-v3/src/asset-imports/asset-imports.service.ts
|
|
echo "Aplicación transaccional, casteo row_number y reversión lógica relacional: OK"
|
|
|
|
echo
|
|
echo "========== D5.3.7.2.2 · FRONTEND =========="
|
|
grep -Fq 'Plan relacional por entidad' web-v2/src/pages/AssetImportsPage.tsx
|
|
grep -Fq 'Ver detalle' web-v2/src/pages/AssetImportsPage.tsx
|
|
grep -Fq 'Departamentos' web-v2/src/pages/AssetImportsPage.tsx
|
|
grep -Fq 'Marco jurídico' web-v2/src/pages/AssetImportsPage.tsx
|
|
grep -Fq 'listAssetImportPlanItems' web-v2/src/lib/api.ts
|
|
echo "Desglose por tipo y detalle paginado: OK"
|
|
|
|
echo
|
|
echo "========== D5.3.7.2.2 · CONTENEDORES =========="
|
|
docker compose ps -a
|
|
[[ "$(docker inspect dhv2-db --format '{{.State.Health.Status}}')" == "healthy" ]]
|
|
[[ "$(docker inspect dhv2-api --format '{{.State.Status}}')" == "running" ]]
|
|
[[ "$(docker inspect dhv2-web --format '{{.State.Status}}')" == "running" ]]
|
|
|
|
echo
|
|
echo "ACEPTACIÓN DE FASE D5.3.7.2.2: OK"
|