Skip to content

Commit 0f779c0

Browse files
JAORMXclaude
andcommitted
Phase 4: Drop legacy entity tables
This completes the migration to the unified entity model by removing the deprecated repositories, artifacts, and pull_requests tables. ## Changes ### Database Migration - Add migration 000114 to drop legacy tables (repositories, artifacts, pull_requests) - All data now stored in entity_instances and properties tables - Down migration recreates empty tables (data recovery requires backup) ### Code Cleanup - Remove SQL query files: repositories.sql, artifacts.sql - Remove generated code: repositories.sql.go, artifacts.sql.go - Remove db.Repository, db.Artifact, db.PullRequest structs from models - Remove legacy methods from querier and mocks - Remove PBRepositoryFromDB converter (internal/repositories/db.go) ### Reminder Service - Document stateless throttling approach using evaluation history - No longer tracks reminder_last_sent timestamp - Enables horizontal scaling and improves reliability - Throttling based on MinElapsed check against actual evaluation times ### Test Updates - Create EntityRepository test helper for entity-based repository tests - Update all test files to use EntityRepository instead of db.Repository - Remove legacy repositories_test.go - Update mock fixtures to remove legacy struct parameters - All tests passing with full race detection ## Migration Path 1. Deploy this code to staging/production 2. Create database backup (CRITICAL - migration is irreversible) 3. Run migration to drop legacy tables 4. Monitor for errors 5. Optional: Run VACUUM to reclaim disk space 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 1b9742c commit 0f779c0

File tree

22 files changed

+252
-797
lines changed

22 files changed

+252
-797
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
-- SPDX-FileCopyrightText: Copyright 2025 The Minder Authors
2+
-- SPDX-License-Identifier: Apache-2.0
3+
4+
BEGIN;
5+
6+
-- WARNING: This down migration recreates the table structure ONLY.
7+
-- It does NOT restore any data that was deleted when the tables were dropped.
8+
-- This is for structural rollback only - data recovery requires restoring from backup.
9+
10+
-- Recreate repositories table
11+
CREATE TABLE repositories (
12+
id UUID NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY,
13+
provider TEXT NOT NULL,
14+
project_id UUID NOT NULL,
15+
repo_owner TEXT NOT NULL,
16+
repo_name TEXT NOT NULL,
17+
repo_id INTEGER NOT NULL,
18+
is_private BOOLEAN NOT NULL,
19+
is_fork BOOLEAN NOT NULL,
20+
webhook_id INTEGER,
21+
webhook_url TEXT NOT NULL,
22+
deploy_url TEXT NOT NULL,
23+
clone_url TEXT NOT NULL,
24+
default_branch TEXT,
25+
license VARCHAR(255) DEFAULT 'unknown',
26+
provider_id UUID,
27+
reminder_last_sent TIMESTAMP,
28+
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
29+
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
30+
FOREIGN KEY (project_id, provider) REFERENCES providers(project_id, name) ON DELETE CASCADE
31+
);
32+
33+
ALTER TABLE repositories ADD CONSTRAINT unique_repo_id UNIQUE (repo_id);
34+
ALTER TABLE repositories ADD CONSTRAINT fk_repositories_provider_id FOREIGN KEY (provider_id) REFERENCES providers (id) ON DELETE CASCADE;
35+
36+
-- Recreate artifacts table
37+
CREATE TABLE artifacts (
38+
id UUID NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY,
39+
repository_id UUID NOT NULL REFERENCES repositories(id) ON DELETE CASCADE,
40+
artifact_name TEXT NOT NULL,
41+
artifact_type TEXT NOT NULL,
42+
artifact_visibility TEXT NOT NULL,
43+
project_id UUID,
44+
provider_id UUID,
45+
provider_name TEXT,
46+
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
47+
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
48+
);
49+
50+
ALTER TABLE artifacts ADD CONSTRAINT fk_artifacts_project_id FOREIGN KEY (project_id) REFERENCES projects (id) ON DELETE CASCADE;
51+
ALTER TABLE artifacts ADD CONSTRAINT fk_artifacts_provider_id_and_name FOREIGN KEY (provider_id, provider_name) REFERENCES providers (id, name) ON DELETE CASCADE;
52+
53+
-- Recreate pull_requests table
54+
CREATE TABLE pull_requests (
55+
id UUID NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY,
56+
repository_id UUID NOT NULL REFERENCES repositories(id) ON DELETE CASCADE,
57+
pr_number BIGINT NOT NULL,
58+
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
59+
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
60+
);
61+
62+
CREATE UNIQUE INDEX pr_in_repo_unique ON pull_requests (repository_id, pr_number);
63+
64+
COMMIT;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
-- SPDX-FileCopyrightText: Copyright 2025 The Minder Authors
2+
-- SPDX-License-Identifier: Apache-2.0
3+
4+
BEGIN;
5+
6+
-- Drop legacy entity tables in correct order (respecting foreign keys)
7+
-- These tables have been fully replaced by the unified entity_instances and properties tables.
8+
-- All code has been migrated to use the new entity model.
9+
10+
-- WARNING: This is a destructive operation. Ensure backups exist before running.
11+
12+
DROP TABLE IF EXISTS pull_requests CASCADE;
13+
DROP TABLE IF EXISTS artifacts CASCADE;
14+
DROP TABLE IF EXISTS repositories CASCADE;
15+
16+
COMMIT;

database/mock/fixtures/store.go

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,12 @@ func WithSuccessfulGetFeatureInProject(
9898
}
9999

100100
func WithSuccessfulUpsertPullRequest(
101-
pullRequest db.PullRequest,
101+
instance db.EntityInstance,
102102
) func(*mockdb.MockStore) {
103103
return func(mockStore *mockdb.MockStore) {
104104
mockStore.EXPECT().
105105
CreateOrEnsureEntityByID(gomock.Any(), gomock.Any()).
106-
Return(db.EntityInstance{}, nil)
106+
Return(instance, nil)
107107
}
108108
}
109109

@@ -131,7 +131,6 @@ func (m createOrEnsureEntityByIDParamsMatcher) Matches(x interface{}) bool {
131131
}
132132

133133
func WithSuccessfulUpsertPullRequestWithParams(
134-
pullRequest db.PullRequest,
135134
instance db.EntityInstance,
136135
entParams db.CreateOrEnsureEntityByIDParams,
137136
) func(*mockdb.MockStore) {
@@ -144,15 +143,12 @@ func WithSuccessfulUpsertPullRequestWithParams(
144143
}
145144

146145
func WithSuccessfulUpsertArtifact(
147-
artifact db.Artifact,
146+
instance db.EntityInstance,
148147
) func(*mockdb.MockStore) {
149148
return func(mockStore *mockdb.MockStore) {
150-
mockStore.EXPECT().
151-
UpsertArtifact(gomock.Any(), gomock.Any()).
152-
Return(artifact, nil)
153149
mockStore.EXPECT().
154150
CreateOrEnsureEntityByID(gomock.Any(), gomock.Any()).
155-
Return(db.EntityInstance{}, nil)
151+
Return(instance, nil)
156152
}
157153
}
158154

database/mock/store.go

Lines changed: 0 additions & 72 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

database/query/artifacts.sql

Lines changed: 0 additions & 20 deletions
This file was deleted.

database/query/repositories.sql

Lines changed: 0 additions & 26 deletions
This file was deleted.

internal/auth/keycloak/client/client.gen.go

Lines changed: 15 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)