Files
dh-inspeccion-v2/scripts/phase-d2-acceptance.sh
T

173 lines
7.5 KiB
Bash
Executable File

#!/usr/bin/env bash
set -Eeuo pipefail
dhv2_base_url="${DHV2_BASE_URL:-https://dhv2.korexlabs.com}"
dhv2_base_url="${dhv2_base_url%/}"
dhv2_nil_uuid="00000000-0000-4000-8000-000000000000"
fail() {
echo "ERROR: $*" >&2
exit 1
}
echo "========== D2 · MIGRACIONES =========="
dhv2_migration_status="$(docker compose --profile tools run --rm migrate npm run migration:show 2>&1)"
grep -q 'Pending migrations: no' <<<"$dhv2_migration_status" \
|| fail "Quedaron migraciones pendientes"
echo "Migraciones pendientes: no"
echo
echo "========== D2 · HEALTH =========="
dhv2_internal="$(curl -fsS --connect-timeout 10 --max-time 30 http://127.0.0.1:3101/api/v3/health)"
dhv2_external="$(curl -fsS --connect-timeout 10 --max-time 30 "$dhv2_base_url/api/v3/health")"
grep -q '"version":"0.16.0"' <<<"$dhv2_internal" || fail "Health interno no informa v0.16.0"
grep -q '"phase":"D2"' <<<"$dhv2_internal" || fail "Health interno no informa D2"
grep -q '"version":"0.16.0"' <<<"$dhv2_external" || fail "Health externo no informa v0.16.0"
grep -q '"database":"ok"' <<<"$dhv2_external" || fail "La base no está saludable"
echo "$dhv2_external"
echo
echo "========== D2 · RUTAS PROTEGIDAS =========="
for dhv2_path in \
"inspection-visits/$dhv2_nil_uuid/acts" \
"inspection-acts/$dhv2_nil_uuid"; do
dhv2_code="$(curl -sS --connect-timeout 10 --max-time 30 \
-o /tmp/dhv2-d2-response.json -w '%{http_code}' \
"$dhv2_base_url/api/v3/$dhv2_path")"
test "$dhv2_code" = "401" \
|| fail "/api/v3/$dhv2_path devolvió HTTP $dhv2_code; se esperaba 401"
echo "/api/v3/$dhv2_path sin sesión: 401 OK"
done
rm -f /tmp/dhv2-d2-response.json
echo
echo "========== D2 · MODELO, ROLES Y PRIVILEGIOS =========="
dhv2_db_check="$(docker compose exec -T db sh -lc \
'psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -v ON_ERROR_STOP=1 -v app_user="$APP_DB_USER" -At' <<'SQL'
SELECT 'tables', COUNT(*)
FROM information_schema.tables
WHERE table_schema = 'public'
AND table_name IN (
'document_annual_sequences',
'inspection_acts',
'inspection_act_assets',
'inspection_act_versions'
);
SELECT 'act_checks', COUNT(*)
FROM pg_constraint
WHERE conname IN (
'chk_inspection_acts_year',
'chk_inspection_acts_number',
'chk_inspection_acts_code',
'chk_inspection_acts_status',
'chk_inspection_acts_current_version',
'chk_inspection_acts_cancellation'
);
SELECT 'annual_identity', COUNT(*)
FROM pg_constraint
WHERE conname IN (
'uq_inspection_acts_year_number',
'uq_inspection_acts_code'
);
SELECT 'reserved_states', COUNT(*)
FROM pg_constraint
WHERE conname = 'chk_inspection_acts_status'
AND pg_get_constraintdef(oid) LIKE '%READY%'
AND pg_get_constraintdef(oid) LIKE '%CLOSED%'
AND pg_get_constraintdef(oid) LIKE '%RECTIFIED%';
SELECT 'sequence_types', COUNT(*)
FROM pg_constraint
WHERE conname = 'chk_document_annual_sequences_type'
AND pg_get_constraintdef(oid) LIKE '%ACT%'
AND pg_get_constraintdef(oid) LIKE '%REPORT%';
SELECT 'immutable_versions', COUNT(*)
FROM pg_constraint
WHERE conname IN (
'uq_inspection_act_versions_number',
'chk_inspection_act_versions_number',
'chk_inspection_act_versions_event'
);
SELECT 'permissions', COUNT(*)
FROM permissions
WHERE code IN (
'inspection_acts.read',
'inspection_acts.create',
'inspection_acts.update',
'inspection_acts.cancel'
);
SELECT 'read_roles', COUNT(*)
FROM role_permissions role_permission
INNER JOIN roles role ON role.id = role_permission.role_id
INNER JOIN permissions permission ON permission.id = role_permission.permission_id
WHERE role.code IN ('admin', 'director', 'supervisor', 'inspector', 'auditor')
AND permission.code = 'inspection_acts.read';
SELECT 'create_roles', COUNT(*)
FROM role_permissions role_permission
INNER JOIN roles role ON role.id = role_permission.role_id
INNER JOIN permissions permission ON permission.id = role_permission.permission_id
WHERE role.code IN ('admin', 'supervisor', 'inspector')
AND permission.code = 'inspection_acts.create';
SELECT 'update_roles', COUNT(*)
FROM role_permissions role_permission
INNER JOIN roles role ON role.id = role_permission.role_id
INNER JOIN permissions permission ON permission.id = role_permission.permission_id
WHERE role.code IN ('admin', 'supervisor', 'inspector')
AND permission.code = 'inspection_acts.update';
SELECT 'cancel_roles', COUNT(*)
FROM role_permissions role_permission
INNER JOIN roles role ON role.id = role_permission.role_id
INNER JOIN permissions permission ON permission.id = role_permission.permission_id
WHERE role.code IN ('admin', 'supervisor')
AND permission.code = 'inspection_acts.cancel';
SELECT 'app_acts_select', has_table_privilege(:'app_user', 'inspection_acts', 'SELECT');
SELECT 'app_acts_update', has_table_privilege(:'app_user', 'inspection_acts', 'UPDATE');
SELECT 'app_acts_delete', has_table_privilege(:'app_user', 'inspection_acts', 'DELETE');
SELECT 'app_versions_insert', has_table_privilege(:'app_user', 'inspection_act_versions', 'INSERT');
SELECT 'app_versions_update', has_table_privilege(:'app_user', 'inspection_act_versions', 'UPDATE');
SELECT 'app_versions_delete', has_table_privilege(:'app_user', 'inspection_act_versions', 'DELETE');
SELECT 'app_sequence_update', has_table_privilege(:'app_user', 'document_annual_sequences', 'UPDATE');
SELECT 'app_sequence_delete', has_table_privilege(:'app_user', 'document_annual_sequences', 'DELETE');
SQL
)"
grep -q 'tables|4' <<<"$dhv2_db_check" || fail "Faltan tablas D2"
grep -q 'act_checks|6' <<<"$dhv2_db_check" || fail "Faltan controles del acta"
grep -q 'annual_identity|2' <<<"$dhv2_db_check" || fail "No se garantiza la identidad anual"
grep -q 'reserved_states|1' <<<"$dhv2_db_check" || fail "Faltan estados documentales reservados"
grep -q 'sequence_types|1' <<<"$dhv2_db_check" || fail "La secuencia no reserva ACT y REPORT"
grep -q 'immutable_versions|3' <<<"$dhv2_db_check" || fail "Faltan controles de versiones"
grep -q 'permissions|4' <<<"$dhv2_db_check" || fail "No se crearon los cuatro permisos D2"
grep -q 'read_roles|5' <<<"$dhv2_db_check" || fail "Faltan roles de lectura"
grep -q 'create_roles|3' <<<"$dhv2_db_check" || fail "Faltan roles de creación"
grep -q 'update_roles|3' <<<"$dhv2_db_check" || fail "Faltan roles de actualización"
grep -q 'cancel_roles|2' <<<"$dhv2_db_check" || fail "Faltan roles de cancelación"
grep -q 'app_acts_select|t' <<<"$dhv2_db_check" || fail "La API no puede leer actas"
grep -q 'app_acts_update|t' <<<"$dhv2_db_check" || fail "La API no puede actualizar actas"
grep -q 'app_acts_delete|f' <<<"$dhv2_db_check" || fail "La API no debe borrar actas"
grep -q 'app_versions_insert|t' <<<"$dhv2_db_check" || fail "La API no puede registrar versiones"
grep -q 'app_versions_update|f' <<<"$dhv2_db_check" || fail "La API no debe modificar versiones"
grep -q 'app_versions_delete|f' <<<"$dhv2_db_check" || fail "La API no debe borrar versiones"
grep -q 'app_sequence_update|t' <<<"$dhv2_db_check" || fail "La API no puede incrementar la secuencia"
grep -q 'app_sequence_delete|f' <<<"$dhv2_db_check" || fail "La API no debe borrar secuencias"
echo "$dhv2_db_check"
echo
echo "========== D2 · FRONTEND =========="
docker compose exec -T web sh -lc \
'grep -R "0.16.0" /usr/share/nginx/html/assets >/dev/null && grep -R "Múltiples actas por visita" /usr/share/nginx/html/assets >/dev/null && grep -R "Nueva acta" /usr/share/nginx/html/assets >/dev/null && grep -R "VERSIONES INMUTABLES" /usr/share/nginx/html/assets >/dev/null && grep -R "Crear y numerar acta" /usr/share/nginx/html/assets >/dev/null'
echo "Actas múltiples, versiones y footer v0.16.0: OK"
echo
echo "ACEPTACIÓN DE FASE D2: OK"