From df47ed141700332dc163c6162c0206f7e09e9c7a Mon Sep 17 00:00:00 2001 From: Accusys Date: Thu, 14 May 2026 14:46:30 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20identity=20inactive=20cleanup=20?= =?UTF-8?q?=E2=80=94=20migration=20script=20+=20release.rs=20excludes=20st?= =?UTF-8?q?atus=3D'inactive'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - New SQL migration: mark auto identities with no face references as inactive - release.rs identities export now filters out status='inactive' --- .../migrate_cleanup_inactive_identities.sql | 33 +++++++++++++++++++ src/bin/release.rs | 4 +-- 2 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 release/migrate_cleanup_inactive_identities.sql diff --git a/release/migrate_cleanup_inactive_identities.sql b/release/migrate_cleanup_inactive_identities.sql new file mode 100644 index 0000000..9e647e8 --- /dev/null +++ b/release/migrate_cleanup_inactive_identities.sql @@ -0,0 +1,33 @@ +-- Identity Inactive Cleanup Migration +-- Date: 2026-05-14 +-- Purpose: Mark auto-generated identities with no face_detection references as 'inactive' +-- Run after pipeline completes to clean up orphaned auto identities + +BEGIN; + +-- Mark auto identities as inactive if they have zero face_detection references +UPDATE identities +SET status = 'inactive', + metadata = metadata || jsonb_build_object('inactivated_at', NOW()::text, 'reason', 'no_face_references') +WHERE source = 'auto' + AND status != 'inactive' + AND id NOT IN ( + SELECT DISTINCT identity_id FROM face_detections WHERE identity_id IS NOT NULL + ); + +-- Delete identity_bindings pointing to newly inactive identities +DELETE FROM identity_bindings +WHERE identity_id IN ( + SELECT id FROM identities WHERE status = 'inactive' +); + +-- Log +DO $$ +DECLARE + marked INT; +BEGIN + SELECT COUNT(*) INTO marked FROM identities WHERE status = 'inactive' AND metadata->>'reason' = 'no_face_references'; + RAISE NOTICE 'Marked % auto identities as inactive (no face references)', marked; +END $$; + +COMMIT; diff --git a/src/bin/release.rs b/src/bin/release.rs index d3edc4a..874a457 100644 --- a/src/bin/release.rs +++ b/src/bin/release.rs @@ -406,12 +406,12 @@ async fn cmd_package(db: &PostgresDb, uuid: &str) -> Result<()> { // Export identities with file_uuid (direct column, no JOIN needed) // FILE LOCAL: file_uuid = '{uuid}' - // GLOBAL (cross-file): tmdb identities + user-defined (exclude inactive auto) + // GLOBAL (cross-file): tmdb identities + user-defined (exclude inactive auto + status='inactive') let idents_name = "dev_identities"; let idents_path = sql_dir.join(format!("{}.sql", idents_name)); { let idents_query = format!( - "COPY (SELECT * FROM dev.identities WHERE file_uuid = '{}' OR (file_uuid IS NULL AND source IN ('tmdb', 'merged', 'user_defined'))) TO STDOUT WITH CSV HEADER", uuid + "COPY (SELECT * FROM dev.identities WHERE (file_uuid = '{}' OR (file_uuid IS NULL AND source IN ('tmdb', 'merged', 'user_defined'))) AND status IS DISTINCT FROM 'inactive') TO STDOUT WITH CSV HEADER", uuid ); let cols = psql_exec(&format!( "SELECT string_agg(column_name, ', ' ORDER BY ordinal_position) FROM information_schema.columns WHERE table_schema='dev' AND table_name='identities' AND is_updatable='YES'"