feat: Add VEX Status Chip component and integration tests for reachability drift detection
- Introduced `VexStatusChipComponent` to display VEX status with color coding and tooltips. - Implemented integration tests for reachability drift detection, covering various scenarios including drift detection, determinism, and error handling. - Enhanced `ScannerToSignalsReachabilityTests` with a null implementation of `ICallGraphSyncService` for better test isolation. - Updated project references to include the new Reachability Drift library.
This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
-- Excititor Schema Migration 005b: Complete timeline_events Partition Migration
|
||||
-- Sprint: SPRINT_3422_0001_0001 - Time-Based Partitioning
|
||||
-- Task: 4.2 - Migrate data from existing table
|
||||
-- Category: C (data migration, requires maintenance window)
|
||||
--
|
||||
-- IMPORTANT: Run this during maintenance window AFTER 005_partition_timeline_events.sql
|
||||
-- Prerequisites:
|
||||
-- 1. Stop application writes to vex.timeline_events
|
||||
-- 2. Verify partitioned table exists: \d+ vex.timeline_events_partitioned
|
||||
--
|
||||
-- Execution time depends on data volume. For large tables (>1M rows), consider
|
||||
-- batched migration (see bottom of file).
|
||||
|
||||
BEGIN;
|
||||
|
||||
-- ============================================================================
|
||||
-- Step 1: Verify partitioned table exists
|
||||
-- ============================================================================
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM pg_class c
|
||||
JOIN pg_namespace n ON c.relnamespace = n.oid
|
||||
WHERE n.nspname = 'vex' AND c.relname = 'timeline_events_partitioned'
|
||||
) THEN
|
||||
RAISE EXCEPTION 'Partitioned table vex.timeline_events_partitioned does not exist. Run 005_partition_timeline_events.sql first.';
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
-- ============================================================================
|
||||
-- Step 2: Record row counts for verification
|
||||
-- ============================================================================
|
||||
|
||||
DO $$
|
||||
DECLARE
|
||||
v_source_count BIGINT;
|
||||
BEGIN
|
||||
SELECT COUNT(*) INTO v_source_count FROM vex.timeline_events;
|
||||
RAISE NOTICE 'Source table row count: %', v_source_count;
|
||||
END
|
||||
$$;
|
||||
|
||||
-- ============================================================================
|
||||
-- Step 3: Migrate data from old table to partitioned table
|
||||
-- ============================================================================
|
||||
|
||||
INSERT INTO vex.timeline_events_partitioned (
|
||||
id, tenant_id, project_id, event_type, entity_type, entity_id,
|
||||
actor, details, occurred_at
|
||||
)
|
||||
SELECT
|
||||
id, tenant_id, project_id, event_type, entity_type, entity_id,
|
||||
actor, details, occurred_at
|
||||
FROM vex.timeline_events
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
-- ============================================================================
|
||||
-- Step 4: Verify row counts match
|
||||
-- ============================================================================
|
||||
|
||||
DO $$
|
||||
DECLARE
|
||||
v_source_count BIGINT;
|
||||
v_target_count BIGINT;
|
||||
BEGIN
|
||||
SELECT COUNT(*) INTO v_source_count FROM vex.timeline_events;
|
||||
SELECT COUNT(*) INTO v_target_count FROM vex.timeline_events_partitioned;
|
||||
|
||||
IF v_source_count <> v_target_count THEN
|
||||
RAISE WARNING 'Row count mismatch: source=% target=%. Check for conflicts.', v_source_count, v_target_count;
|
||||
ELSE
|
||||
RAISE NOTICE 'Row counts match: % rows migrated successfully', v_target_count;
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
-- ============================================================================
|
||||
-- Step 5: Swap tables
|
||||
-- ============================================================================
|
||||
|
||||
-- Rename old table to backup
|
||||
ALTER TABLE vex.timeline_events RENAME TO timeline_events_old;
|
||||
|
||||
-- Rename partitioned table to production name
|
||||
ALTER TABLE vex.timeline_events_partitioned RENAME TO timeline_events;
|
||||
|
||||
-- ============================================================================
|
||||
-- Step 6: Enable RLS on new table (if applicable)
|
||||
-- ============================================================================
|
||||
|
||||
ALTER TABLE vex.timeline_events ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
-- ============================================================================
|
||||
-- Step 7: Add comment about partitioning
|
||||
-- ============================================================================
|
||||
|
||||
COMMENT ON TABLE vex.timeline_events IS
|
||||
'VEX timeline events. Partitioned monthly by occurred_at. Migrated on ' || NOW()::TEXT;
|
||||
|
||||
COMMIT;
|
||||
|
||||
-- ============================================================================
|
||||
-- Post-migration verification (run manually)
|
||||
-- ============================================================================
|
||||
--
|
||||
-- Verify partition structure:
|
||||
-- SELECT tableoid::regclass, count(*) FROM vex.timeline_events GROUP BY 1;
|
||||
--
|
||||
-- Verify BRIN index is being used:
|
||||
-- EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM vex.timeline_events
|
||||
-- WHERE occurred_at > NOW() - INTERVAL '1 day';
|
||||
--
|
||||
-- After verification, drop old table:
|
||||
-- DROP TABLE IF EXISTS vex.timeline_events_old;
|
||||
|
||||
-- ============================================================================
|
||||
-- Batched migration alternative (for very large tables)
|
||||
-- ============================================================================
|
||||
--
|
||||
-- If the table is very large (>10M rows), use this batched approach instead:
|
||||
--
|
||||
-- DO $$
|
||||
-- DECLARE
|
||||
-- v_batch_size INT := 100000;
|
||||
-- v_offset INT := 0;
|
||||
-- v_inserted INT;
|
||||
-- BEGIN
|
||||
-- LOOP
|
||||
-- INSERT INTO vex.timeline_events_partitioned
|
||||
-- SELECT * FROM vex.timeline_events
|
||||
-- ORDER BY occurred_at
|
||||
-- LIMIT v_batch_size OFFSET v_offset;
|
||||
--
|
||||
-- GET DIAGNOSTICS v_inserted = ROW_COUNT;
|
||||
-- v_offset := v_offset + v_batch_size;
|
||||
--
|
||||
-- RAISE NOTICE 'Migrated % rows (offset: %)', v_inserted, v_offset;
|
||||
--
|
||||
-- EXIT WHEN v_inserted < v_batch_size;
|
||||
--
|
||||
-- -- Allow checkpoint between batches
|
||||
-- PERFORM pg_sleep(0.1);
|
||||
-- END LOOP;
|
||||
-- END
|
||||
-- $$;
|
||||
Reference in New Issue
Block a user