diff --git a/CLAUDE.md b/CLAUDE.md index 61e10e8..9dd02af 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -139,9 +139,14 @@ assertion API; these ITs show how to wire and call it. They mirror core's three - The JPA example runs under the default `ddl-auto=none`: `SchemaEntityValidationAudit` walks Hibernate's entity mappings against the live schema and reports every mismatch in one run, instead of relying on Hibernate's fail-fast `ddl-auto=validate` startup check (which aborts on the first mismatch). -- Most show `EXCLUDED_*` exclusion constants (relations, SQL fragments, columns, indexes, statements) — the +- Nearly all show `EXCLUDED_*` exclusion constants (relations, SQL fragments, columns, indexes, statements) — the intended way for consumers to suppress known/intentional violations instead of weakening the audit. - `ForeignKeyIndexAuditIT` and `PrimaryKeyPresenceAuditIT` call the no-exclusion overload directly. + `PrimaryKeyPresenceAuditIT`'s `EXCLUDED_TABLES` is seeded with `PrimaryKeyPresenceAudit.LIQUIBASE_BOOKKEEPING_TABLES` + rather than empty — the plain no-arg `assertClean(schema)` applies that same default silently, so the constant + makes it explicit instead of introducing a footgun where filling it in naively would drop the default. The one + IT with no `EXCLUDED_*` constant is `SchemaEntityValidationAuditIT`: it isn't schema/table-scoped at all + (`assertClean()` takes no arguments — it walks every mapped entity against the live schema globally), so it calls + the no-exclusion overload directly. The **demo harness** that makes the examples run — `DemoApplication`, `app/*` (entities + repositories + `DemoDatabaseTestConfig`), `runtime/RepositoryWorkloadIT`, and `src/test/resources/` (`application.properties` + the Liquibase diff --git a/archetype/src/main/resources/archetype-resources/src/test/java/catalog/ForeignKeyIndexAuditIT.java b/archetype/src/main/resources/archetype-resources/src/test/java/catalog/ForeignKeyIndexAuditIT.java index 45819cb..5151410 100644 --- a/archetype/src/main/resources/archetype-resources/src/test/java/catalog/ForeignKeyIndexAuditIT.java +++ b/archetype/src/main/resources/archetype-resources/src/test/java/catalog/ForeignKeyIndexAuditIT.java @@ -1,5 +1,7 @@ package ${package}.catalog; +import java.util.Set; + #if($disabledTests == 'true') import org.junit.jupiter.api.Disabled; #end @@ -16,13 +18,17 @@ import io.github.databaseaudits.spring.boot.assertion.ForeignKeyIndexAuditAssertion; /** - * Asserts that every foreign key in the schema has a supporting index. + * Asserts that every foreign key in the schema has a supporting index, with a place to exclude one that is + * deliberately unindexed. */ #if($parentClass && $parentClass != '' && $parentClass != 'none') public class ForeignKeyIndexAuditIT extends ${simpleParentClass} { #else public class ForeignKeyIndexAuditIT extends AbstractDatabaseAuditIT { #end + /** Exclude a deliberately unindexed FK, e.g. Set.of("fk_orders_customer_legacy"). */ + private static final Set EXCLUDED_CONSTRAINTS = Set.of(); + @Autowired private ForeignKeyIndexAuditAssertion foreignKeyIndexAuditAssertion; @@ -34,6 +40,6 @@ public class ForeignKeyIndexAuditIT extends AbstractDatabaseAuditIT { @Disabled("Generated as disabled; remove @Disabled to enable") #end void testEveryForeignKeyHasSupportingIndex() { - foreignKeyIndexAuditAssertion.assertClean(schema); + foreignKeyIndexAuditAssertion.assertClean(schema, EXCLUDED_CONSTRAINTS); } } diff --git a/archetype/src/main/resources/archetype-resources/src/test/java/catalog/PrimaryKeyPresenceAuditIT.java b/archetype/src/main/resources/archetype-resources/src/test/java/catalog/PrimaryKeyPresenceAuditIT.java index a324b1b..20545a1 100644 --- a/archetype/src/main/resources/archetype-resources/src/test/java/catalog/PrimaryKeyPresenceAuditIT.java +++ b/archetype/src/main/resources/archetype-resources/src/test/java/catalog/PrimaryKeyPresenceAuditIT.java @@ -1,5 +1,7 @@ package ${package}.catalog; +import java.util.Set; + #if($disabledTests == 'true') import org.junit.jupiter.api.Disabled; #end @@ -13,16 +15,23 @@ #else import ${package}.AbstractDatabaseAuditIT; #end +import io.github.databaseaudits.audit.catalog.PrimaryKeyPresenceAudit; import io.github.databaseaudits.spring.boot.assertion.PrimaryKeyPresenceAuditAssertion; /** - * Asserts that every base table in the schema has a primary key. + * Asserts that every base table in the schema has a primary key, excluding Liquibase's own bookkeeping tables by + * default. */ #if($parentClass && $parentClass != '' && $parentClass != 'none') public class PrimaryKeyPresenceAuditIT extends ${simpleParentClass} { #else public class PrimaryKeyPresenceAuditIT extends AbstractDatabaseAuditIT { #end + /** Liquibase's own bookkeeping tables have no primary key by design; add your own genuinely-PK-less tables + * the same way. */ + private static final Set EXCLUDED_TABLES = + PrimaryKeyPresenceAudit.LIQUIBASE_BOOKKEEPING_TABLES; + @Autowired private PrimaryKeyPresenceAuditAssertion primaryKeyPresenceAuditAssertion; @@ -34,6 +43,6 @@ public class PrimaryKeyPresenceAuditIT extends AbstractDatabaseAuditIT { @Disabled("Generated as disabled; remove @Disabled to enable") #end void testEveryBaseTableHasPrimaryKey() { - primaryKeyPresenceAuditAssertion.assertClean(schema); + primaryKeyPresenceAuditAssertion.assertClean(schema, EXCLUDED_TABLES); } }