name: F3.1 Inventory CI on: push: branches: - 'feature/f3-1*' workflow_dispatch: permissions: contents: read jobs: api: runs-on: ubuntu-latest timeout-minutes: 25 defaults: run: working-directory: api-v3 steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '24' cache: npm cache-dependency-path: api-v3/package-lock.json - run: npm ci - name: Typecheck run: npm run typecheck 2>&1 | tee typecheck.log - name: Tests run: npm test 2>&1 | tee test.log - name: Build run: npm run build 2>&1 | tee build.log - name: Diagnostics if: always() uses: actions/upload-artifact@v4 with: name: f3-1-api-diagnostics path: | api-v3/typecheck.log api-v3/test.log api-v3/build.log if-no-files-found: warn retention-days: 3 migrations: name: DB ยท F3.1 on PostgreSQL 16/PostGIS runs-on: ubuntu-latest timeout-minutes: 30 services: postgres: image: postgis/postgis:16-3.4 env: POSTGRES_USER: dhv2_owner POSTGRES_PASSWORD: owner_test_password POSTGRES_DB: dhv2_ci ports: - 5432:5432 options: >- --health-cmd "pg_isready -U dhv2_owner -d dhv2_ci" --health-interval 5s --health-timeout 5s --health-retries 20 env: DB_HOST: 127.0.0.1 DB_PORT: 5432 DB_NAME: dhv2_ci DB_MIGRATION_USER: dhv2_owner DB_MIGRATION_PASSWORD: owner_test_password DB_APP_USER: dhv2_app defaults: run: working-directory: api-v3 steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '24' cache: npm cache-dependency-path: api-v3/package-lock.json - name: PostgreSQL client run: | command -v psql >/dev/null || { sudo apt-get update sudo apt-get install -y postgresql-client } - name: Prepare roles and extensions env: PGPASSWORD: owner_test_password run: | psql -v ON_ERROR_STOP=1 -h 127.0.0.1 -U dhv2_owner -d dhv2_ci <<'SQL' CREATE EXTENSION IF NOT EXISTS postgis; CREATE EXTENSION IF NOT EXISTS pgcrypto; DO $$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname='dhv2_app') THEN CREATE ROLE dhv2_app LOGIN PASSWORD 'app_test_password'; END IF; END $$; GRANT CONNECT ON DATABASE dhv2_ci TO dhv2_app; GRANT USAGE ON SCHEMA public TO dhv2_app; CREATE TABLE IF NOT EXISTS typeorm_migrations ( id SERIAL PRIMARY KEY, timestamp bigint NOT NULL, name varchar NOT NULL ); INSERT INTO typeorm_migrations (timestamp,name) VALUES (1788652800000,'ResetProductionOperationalData1788652800000'); SQL - run: npm ci - run: npm run build - name: Run every pending migration run: npm run migration:run - name: Assert no pending migrations run: | npm run migration:show | tee /tmp/migrations.txt grep -Fq 'Pending migrations: no' /tmp/migrations.txt - name: Assert F3.1 structure, merge and Inspector profile env: PGPASSWORD: owner_test_password run: | set -Eeuo pipefail PSQL="psql -At -v ON_ERROR_STOP=1 -h 127.0.0.1 -U dhv2_owner -d dhv2_ci" test "$($PSQL -c \"SELECT count(*) FROM inventory_families WHERE level='INSTALLATION' AND is_active=true\")" = "15" test "$($PSQL -c \"SELECT count(*) FROM inventory_families WHERE level='SUBINSTALLATION' AND is_active=true\")" = "124" test "$($PSQL -c \"SELECT count(*) FROM inventory_families WHERE source_reference LIKE 'SYSTEM:F3.1:OTHER%'\")" = "16" test "$($PSQL -c \"SELECT count(*) FROM finding_categories WHERE lower(code)='app26r2' AND is_active=true\")" = "1" test "$($PSQL -c \"SELECT count(*) FROM finding_categories WHERE lower(code)='app26' AND is_active=false\")" = "1" test "$($PSQL -c \"SELECT count(*) FROM information_schema.tables WHERE table_name='asset_merges'\")" = "1" test "$($PSQL -c \"SELECT count(*) FROM pg_trigger WHERE tgname='trg_asset_merges_append_only' AND NOT tgisinternal\")" = "1" test "$($PSQL -c \"SELECT count(*) FROM information_schema.columns WHERE table_name='users' AND column_name IN ('dni','phone','job_title','employee_number')\")" = "4" test "$($PSQL -c \"SELECT count(*) FROM pg_trigger WHERE tgname IN ('trg_user_roles_inspector_email','trg_users_inspector_email') AND NOT tgisinternal\")" = "2" test "$($PSQL -c \"SELECT count(*) FROM assets a JOIN asset_types t ON t.id=a.asset_type_id WHERE a.data_origin='IMPORT' AND a.source_name='Tablas de yacimiento(1).xlsx' AND lower(t.code)='yacimiento'\")" = "230" test "$($PSQL -c \"SELECT count(*) FROM assets WHERE (operational_area_id IS NULL) <> (operator_company_id IS NULL)\")" = "0" web: runs-on: ubuntu-latest timeout-minutes: 20 defaults: run: working-directory: web-v2 steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '24' cache: npm cache-dependency-path: web-v2/package-lock.json - run: npm ci - name: Typecheck run: npm run typecheck 2>&1 | tee typecheck.log - name: Build run: npm run build 2>&1 | tee build.log - name: Diagnostics if: always() uses: actions/upload-artifact@v4 with: name: f3-1-web-diagnostics path: | web-v2/typecheck.log web-v2/build.log if-no-files-found: warn retention-days: 3 docker: needs: [api, web, migrations] runs-on: ubuntu-latest timeout-minutes: 25 steps: - uses: actions/checkout@v4 - name: Validate Compose run: docker compose --env-file .env.example config >/dev/null - name: Build production images run: docker compose --env-file .env.example build api migrate web