mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2026-09-03 05:10:16 +03:00
## What this PR does Removes the **Flyway** migration system from the SaaS build: - drops `flyway-core` + `flyway-database-postgresql` from `app/saas/build.gradle` - deletes all `Vxx__*.sql` files under `app/saas/src/main/resources/db/migration/` - removes the `spring.flyway.*` config from `application-saas.properties` - clears the now-inert `SPRING_FLYWAY_ENABLED` override and stale Flyway comments in `testing/compose/docker-compose-saas.yml` `ddl-auto` is **left on `update`** (unchanged) — that's a separate decision (see "Not in this PR"). ## Why — Flyway never actually ran anywhere From a full schema-management review (`notes/FLYWAY_MIGRATION_REVIEW.md`), verified against the live databases: - **Prod & dev (v3):** no `flyway_schema_history` table exists in any schema → Flyway has never executed. Schema is authored by the Supabase migrations in `Stirling-PDF-SaaS` and applied by that repo's **GitHub integration** (merge to `main` → prod). - **Tests:** the saas module has zero `@SpringBootTest`; the only real-DB integration tests (in `proprietary`) use `ddl-auto=create-drop` and don't have Flyway on the classpath. - **The mock-DB harness** (`testing/compose/docker-compose-saas.yml`, PAYG cucumber) *explicitly disabled* Flyway, because the `Vxx` migrations can't run against a clean Postgres — they assume Supabase has already provisioned `users`/`teams` (`V2` ALTERs `users`, `V5` references `teams`). So Flyway was dead weight, and its 4 duplicate versions (`V25/V26/V30/V31`) were a latent trap: re-enabling it would crash boot on the collision. Everything it contained (schema + seeds like the default pricing policy) is already mirrored by the Supabase migrations, and by `saas-seed.sql` for the cucumber stack. ## ⚠️ Required follow-up (item #1) — capture the Flyway-only tables into Supabase migrations **This is documentation of the next step, not done in this PR.** Seven tables were defined in Flyway with **no matching Supabase migration**. They exist in prod today only because `ddl-auto=update` created them from their entities. Before `ddl-auto` is ever tightened to `validate` (see #3 below), and so any fresh Supabase branch is complete, they must be added as Supabase migrations in `Stirling-PDF-SaaS/supabase/migrations/`. **Capture (CREATE) — 6 live tables** (definitions are visible in the deleted files in this PR's diff): | Table | Source (deleted here) | Backing entity | |---|---|---| | `resource_grants` | `V25__resource_grants.sql` | `ResourceGrant` | | `integration_configs` | `V26__integration_configs.sql` | `IntegrationConfig` | | `policy_sources` | `V22__policy_engine_tables.sql` | `SourceEntity` | | `policy_source_doc_counts` | `V23__policy_source_doc_counts.sql` | `SourceDocCountEntity` | | `policy_source_doc_totals` | `V23__policy_source_doc_counts.sql` | `SourceDocTotalEntity` | | `saas_user_extensions` | `V9__saas_user_team_extensions.sql` | `SaasUserExtensions` | Write them as `CREATE TABLE IF NOT EXISTS stirling_pdf.<name> (...)` (idempotent — no-op against the existing prod/v3 tables). Preserve column types/defaults/constraints from the deleted `Vxx` files. **Drop (do NOT recreate) — 1 orphaned table:** - `classification_labels` — created by `V30` and dropped by `V39` within Flyway; its `ClassificationLabel` is now a plain `record`, not a JPA entity. It lingers in prod only because Flyway's `V39` drop never ran. The follow-up should emit a `DROP TABLE IF EXISTS stirling_pdf.classification_labels` (mirroring `V39`'s intent), after confirming nothing reads it. ## Not in this PR (deliberately) - **#3 — flip saas `ddl-auto` `update` → `validate`.** Held pending team confirmation; it has boot-risk and should be gated by a CI "validate-boot against a fresh Supabase branch" first. Self-hosted stays on `update` regardless. - **#4 — `billing_subscriptions` split-brain** (prod `public` has 23,164 rows, `stirling_pdf` has 0, Java reads the empty one). Tracked separately. ## Verification - `:saas:compileJava` succeeds with Flyway removed (no code imports `org.flywaydb.*`). - No test or ArchUnit rule references Flyway or the migration files. - No runtime/data impact: Flyway never ran against any live database. --------- Co-authored-by: James Brunton <jbrunton96@gmail.com>
103 lines
4.0 KiB
YAML
103 lines
4.0 KiB
YAML
services:
|
|
# ---------------------------------------------------------------------
|
|
# Postgres holding the stirling_pdf schema, built by Hibernate
|
|
# ddl-auto=create-drop when the backend starts (see below). Exposed on
|
|
# host port 5433 so the cucumber harness can connect via psycopg from
|
|
# features/steps/payg_*.
|
|
# ---------------------------------------------------------------------
|
|
postgres-saas:
|
|
image: postgres:17-alpine
|
|
container_name: payg-cucumber-postgres
|
|
environment:
|
|
POSTGRES_PASSWORD: postgres
|
|
POSTGRES_DB: postgres
|
|
ports:
|
|
- "5433:5432"
|
|
volumes:
|
|
# Bootstrap stirling_pdf schema + seed test team / api key.
|
|
# Runs once when the container is first created.
|
|
- ./payg/saas-init.sql:/docker-entrypoint-initdb.d/00-init.sql:ro
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U postgres -d postgres"]
|
|
interval: 3s
|
|
timeout: 5s
|
|
retries: 20
|
|
networks:
|
|
- payg-cucumber-network
|
|
|
|
# ---------------------------------------------------------------------
|
|
# Stirling-PDF backend with STIRLING_FLAVOR=saas. Authenticates via
|
|
# API key (SECURITY_CUSTOMGLOBALAPIKEY) — Supabase JWT enforcement is
|
|
# disabled for the test profile via SAAS_DB_PROJECT_REF=disabled so the
|
|
# OAuth resource-server filter no-ops. The PaygChargeInterceptor's
|
|
# resolveUser() ApiKey-token path is what the cucumber tests exercise.
|
|
# ---------------------------------------------------------------------
|
|
stirling-pdf-saas:
|
|
build:
|
|
context: ../..
|
|
dockerfile: docker/embedded/Dockerfile
|
|
args:
|
|
STIRLING_FLAVOR: saas
|
|
container_name: payg-cucumber-stirling
|
|
depends_on:
|
|
postgres-saas:
|
|
condition: service_healthy
|
|
restart: "no"
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
memory: 4G
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "curl -f http://localhost:8080/api/v1/info/status | grep -q 'UP'"]
|
|
interval: 5s
|
|
timeout: 10s
|
|
retries: 24
|
|
ports:
|
|
- "8080:8080"
|
|
environment:
|
|
# Activate the saas profile + bring the saas subproject onto the classpath.
|
|
# `payg-cucumber` registers the test-only throw-500 controller in
|
|
# `app/saas/.../payg/test/PaygCucumberThrowController.java` — that bean is
|
|
# @Profile("payg-cucumber") so it never registers in production.
|
|
SPRING_PROFILES_ACTIVE: "saas,payg-cucumber"
|
|
STIRLING_FLAVOR: "saas"
|
|
ENABLE_SAAS: "true"
|
|
DISABLE_ADDITIONAL_FEATURES: "false"
|
|
|
|
# Datasource — point Flyway + JPA at the test postgres.
|
|
SAAS_DB_URL: "jdbc:postgresql://postgres-saas:5432/postgres"
|
|
SAAS_DB_USERNAME: "postgres"
|
|
SAAS_DB_PASSWORD: "postgres"
|
|
SAAS_DB_PROJECT_REF: "disabled"
|
|
|
|
# On a clean test postgres the Supabase-provisioned `users`/`teams`
|
|
# tables don't exist, so we let Hibernate's `ddl-auto=create-drop`
|
|
# build the full schema from the entity graph. The default-pricing-
|
|
# policy row (seeded in production by the Supabase migrations) is
|
|
# re-seeded here by testing/compose/payg/saas-seed.sql.
|
|
SPRING_JPA_HIBERNATE_DDL_AUTO: "create-drop"
|
|
|
|
# Disable Supabase JWT enforcement for the test profile. The
|
|
# PaygChargeInterceptor resolves via ApiKey-token authority — that
|
|
# path is what we cover here.
|
|
SPRING_AUTOCONFIGURE_EXCLUDE: "org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration"
|
|
|
|
# Test API key matching the user seeded by saas-init.sql.
|
|
SECURITY_CUSTOMGLOBALAPIKEY: "payg-cucumber-key"
|
|
SECURITY_ENABLELOGIN: "false"
|
|
|
|
# Conservative defaults. The cucumber runs send small fixtures so
|
|
# the in-memory threshold never bites; the kill-switch is needed by
|
|
# one scenario but is toggled via a separate compose override.
|
|
PAYG_FILTER_ENABLED: "true"
|
|
PAYG_FILTER_RESPONSE_IN_MEMORY_THRESHOLD_BYTES: "10485760"
|
|
|
|
SYSTEM_DEFAULTLOCALE: "en-US"
|
|
SYSTEM_MAXFILESIZE: "100"
|
|
networks:
|
|
- payg-cucumber-network
|
|
|
|
networks:
|
|
payg-cucumber-network:
|
|
driver: bridge
|