feat(#221): add V39 migration for tag hierarchy and colors

Adds parent_id FK (ON DELETE SET NULL), self-reference check constraint,
parent_id index, and nullable color column to the tag table.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-04-16 15:15:17 +02:00
parent b0c6d15f99
commit f9ac963b9f
2 changed files with 64 additions and 0 deletions

View File

@@ -168,8 +168,63 @@ class MigrationIntegrationTest {
assertThat(rows).isEqualTo(1);
}
// ─── V39: tag hierarchy — parent_id FK + self-reference check + color ──────
@Test
void v39_parentId_allowsNull() {
UUID tagId = createTag("TagWithoutParent");
Integer count = jdbc.queryForObject(
"SELECT COUNT(*) FROM tag WHERE id = ? AND parent_id IS NULL", Integer.class, tagId);
assertThat(count).isEqualTo(1);
}
@Test
void v39_selfReferenceCheck_rejectsSelfAsParent() {
UUID tagId = createTag("SelfRef");
assertThatThrownBy(() ->
jdbc.update("UPDATE tag SET parent_id = id WHERE id = ?", tagId)
).isInstanceOf(DataIntegrityViolationException.class);
}
@Test
void v39_parentId_acceptsValidParent() {
UUID parent = createTag("Parent");
UUID child = createTag("Child");
int rows = jdbc.update("UPDATE tag SET parent_id = ? WHERE id = ?", parent, child);
assertThat(rows).isEqualTo(1);
}
@Test
void v39_color_allowsNull() {
UUID tagId = createTag("ColorlessTag");
Integer count = jdbc.queryForObject(
"SELECT COUNT(*) FROM tag WHERE id = ? AND color IS NULL", Integer.class, tagId);
assertThat(count).isEqualTo(1);
}
@Test
void v39_color_storesTokenName() {
UUID tagId = createTag("ColoredTag");
int rows = jdbc.update("UPDATE tag SET color = 'sage' WHERE id = ?", tagId);
String stored = jdbc.queryForObject("SELECT color FROM tag WHERE id = ?", String.class, tagId);
assertThat(rows).isEqualTo(1);
assertThat(stored).isEqualTo("sage");
}
// ─── helpers ─────────────────────────────────────────────────────────────
private UUID createTag(String name) {
UUID id = UUID.randomUUID();
jdbc.update("INSERT INTO tag (id, name) VALUES (?, ?)", id, name);
return id;
}
private UUID createDocument() {
Document doc = documentRepository.save(Document.builder()
.title("Testdokument")