diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fed2913..18ab03b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,3 +31,59 @@ jobs: - name: Unit tests run: npm run test:unit + + integration: + name: Integration tests (Postgres & Redis) + runs-on: ubuntu-latest + services: + postgres: + image: timescale/timescaledb:2.29.1-pg16 + env: + POSTGRES_DB: bridge_watch_test + POSTGRES_USER: bridge_watch + POSTGRES_PASSWORD: test_password + ports: + - 5432:5432 + options: >- + --health-cmd "pg_isready -U bridge_watch -d bridge_watch_test" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + redis: + image: redis:7-alpine + ports: + - 6379:6379 + options: >- + --health-cmd "redis-cli ping" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + env: + NODE_ENV: test + POSTGRES_HOST: localhost + POSTGRES_PORT: 5432 + POSTGRES_DB: bridge_watch_test + POSTGRES_USER: bridge_watch + POSTGRES_PASSWORD: test_password + REDIS_HOST: localhost + REDIS_PORT: 6379 + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Install dependencies + run: npm install + + - name: Run migrations + run: npm run migrate + + - name: Seed database + run: npm run seed + + - name: Integration tests + run: npm run test:integration diff --git a/src/database/migrations/007_data_cleanup_system.ts b/src/database/migrations/007_data_cleanup_system.ts index 2d450ee..db719f1 100644 --- a/src/database/migrations/007_data_cleanup_system.ts +++ b/src/database/migrations/007_data_cleanup_system.ts @@ -231,25 +231,27 @@ export async function up(knex: Knex): Promise { $$ LANGUAGE plpgsql `); - // Create index for better cleanup performance + // A rolling NOW()-based partial-index predicate is invalid in PostgreSQL + // because index predicates must contain only immutable expressions. A + // regular time index still supports the range scans used by cleanup jobs. await knex.raw(` - CREATE INDEX IF NOT EXISTS idx_prices_time_cleanup ON prices (time DESC) WHERE time < NOW() - INTERVAL '7 days' + CREATE INDEX IF NOT EXISTS idx_prices_time_cleanup ON prices (time DESC) `); await knex.raw(` - CREATE INDEX IF NOT EXISTS idx_health_scores_time_cleanup ON health_scores (time DESC) WHERE time < NOW() - INTERVAL '30 days' + CREATE INDEX IF NOT EXISTS idx_health_scores_time_cleanup ON health_scores (time DESC) `); await knex.raw(` - CREATE INDEX IF NOT EXISTS idx_pool_events_time_cleanup ON pool_events (time DESC) WHERE time < NOW() - INTERVAL '14 days' + CREATE INDEX IF NOT EXISTS idx_pool_events_time_cleanup ON pool_events (time DESC) `); await knex.raw(` - CREATE INDEX IF NOT EXISTS idx_pool_metrics_time_cleanup ON pool_metrics (time DESC) WHERE time < NOW() - INTERVAL '30 days' + CREATE INDEX IF NOT EXISTS idx_pool_metrics_time_cleanup ON pool_metrics (time DESC) `); await knex.raw(` - CREATE INDEX IF NOT EXISTS idx_search_analytics_time_cleanup ON search_analytics (time DESC) WHERE time < NOW() - INTERVAL '7 days' + CREATE INDEX IF NOT EXISTS idx_search_analytics_time_cleanup ON search_analytics (time DESC) `); } diff --git a/vitest.integration.config.ts b/vitest.integration.config.ts index b26e0fe..3ce147d 100644 --- a/vitest.integration.config.ts +++ b/vitest.integration.config.ts @@ -5,7 +5,13 @@ export default defineConfig({ globals: true, environment: "node", setupFiles: ["./tests/integration/setup.ts"], - include: ["tests/integration/**/*.test.ts"], + include: [ + "tests/integration/**/*.test.ts", + "tests/api/smoke.test.ts", + "tests/api/analytics.test.ts", + "tests/api/circuitBreaker.test.ts", + "tests/api/exports.test.ts", + ], pool: "forks", poolOptions: { forks: { singleFork: true },