Skip to content

feat: Implement Zero-Gap Hot-to-Cold Time-Series Migration - #1107

Merged
Mosas2000 merged 1 commit into
StellaBridge:mainfrom
stableprogrammer:feat/hot-cold-migration-1021
Aug 24, 2026
Merged

feat: Implement Zero-Gap Hot-to-Cold Time-Series Migration#1107
Mosas2000 merged 1 commit into
StellaBridge:mainfrom
stableprogrammer:feat/hot-cold-migration-1021

Conversation

@stableprogrammer

Copy link
Copy Markdown
Contributor

Closes #1021

Summary

Implements a complete zero-gap hot-to-cold time-series migration protocol for the three live hypertables (prices, health_scores, liquidity_snapshots) and pool_events.

Migration manifest (051_hot_cold_migration_manifest.ts):

  • New migration_manifests table tracking each archival segment: status lifecycle (pending → migrating → verifying → complete / failed → rolled_back), SHA-256 checksum, row count, schema version, error message, timestamps
  • Unique constraint on (entity_type, range_start, range_end) prevents duplicate segments on resume

HotColdMigrationService (hotColdMigration.service.ts):

  • migrateRange() — idempotent INSERT … SELECT … ON CONFLICT DO NOTHING into archive tables; stamps checksum and row count; transitions manifest through all lifecycle states
  • dualRead() — UNIONs hot + archive rows (tagged source: "hot"|"archive") ensuring readers see a complete, gap-free range during any phase of migration; deduplicates rows that exist in both tables (hot copy wins)
  • atomicCutover() — verifies archive rows exist before deleting hot rows; aborts with an error if archive is empty to prevent data loss
  • rollback() — deletes archive rows and resets manifest to rolled_back; throws if called on a complete manifest
  • resume() — resets a failed manifest to pending and re-runs migrateRange; idempotent due to ON CONFLICT DO NOTHING
  • restoreDrill() — compares SHA-256 checksums between hot and archive for the range and verifies dual-read covers the full row set (gap-free assertion)
  • verifyContinuousAggregates() — non-fatal check that hourly/daily aggregate views have materialized data across the cutover boundary; logs warnings but never blocks migration
  • invalidateCaches() — uses Redis SCAN (not KEYS) to safely scan and delete cache entries per entity-specific key patterns

Unit tests (hotColdMigration.service.test.ts):

  • 28 tests covering all acceptance criteria: checksum determinism, dual-read zero-gap guarantee and deduplication, rollback guard, resume idempotency, restore drill pass/fail, cache invalidation patterns, atomicCutover empty-archive guard, manifest field mapping, non-fatal continuous aggregate verification

…dge#1021)

- Add migration_manifests table (051 migration) with status lifecycle,
  SHA-256 checksum, row count, schema version, and unique constraint on
  (entity_type, range_start, range_end) to prevent duplicate segments

- Add HotColdMigrationService with:
  · migrateRange() — idempotent INSERT…SELECT…ON CONFLICT DO NOTHING
    into archive tables with checksum stamping and status tracking
  · dualRead() — UNION of hot + archive rows tagged by source so
    readers see a complete, gap-free range during any migration phase
  · atomicCutover() — deletes hot rows only after archive rows are
    confirmed present; aborts if archive is empty
  · rollback() — deletes archive rows and resets manifest to rolled_back
  · resume() — resets a failed manifest to pending and re-runs
    migrateRange (idempotent due to ON CONFLICT DO NOTHING)
  · restoreDrill() — compares hot vs archive checksums and verifies
    dual-read covers the full row set (gap-free check)
  · verifyContinuousAggregates() — non-fatal check that hourly/daily
    aggregates have materialized data across the migration boundary
  · invalidateCaches() — Redis SCAN+DEL per entity cache key patterns

- Add comprehensive unit tests covering all acceptance criteria:
  checksum determinism, dual-read zero-gap guarantee, deduplication,
  rollback guard, resume idempotency, restore drill, cache invalidation,
  atomicCutover empty-archive guard, manifest field mapping

Closes StellaBridge#1021
@Mosas2000

Copy link
Copy Markdown
Contributor

This is perfect as the append-only design and deterministic checksums perfectly enforce non-repudiation and provide a cryptographically verifiable trail for digital forensics. Thank you @stableprogrammer

@Mosas2000
Mosas2000 merged commit fe2089f into StellaBridge:main Aug 24, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Implement Zero-Gap Hot-to-Cold Time-Series Migration

2 participants