Skip to content

Latest commit

 

History

History
215 lines (150 loc) · 6.85 KB

File metadata and controls

215 lines (150 loc) · 6.85 KB

Resolution Migration - Implementation Summary

Assignment Completed ✓

A migration for the resolutions table has been created to support finalized market resolutions for settlement and portfolio closeout.


Files Created/Modified

1. Migration File

Location: prisma/migrations/20260428000000_add_resolutions_table/migration.sql

Contains:

  • ResolutionStatus enum with values: ACTIVE, CORRECTED, OVERRIDDEN
  • resolutions table with:
    • id (TEXT, PRIMARY KEY, UUID)
    • market_id (TEXT, FOREIGN KEY → markets.id with CASCADE delete)
    • outcome (BOOLEAN) - YES (true) or NO (false)
    • finalized_at (TIMESTAMP) - When resolution was finalized
    • provenance (TEXT) - Source attribution (e.g., CHAINLINK, PYTH, MANUAL)
    • status (ResolutionStatus) - Tracks state transitions
    • correction_override_metadata (JSONB) - Audit trail for corrections/overrides
    • created_at (TIMESTAMP)
    • updated_at (TIMESTAMP)
  • ✓ Enforces one ACTIVE resolution per market via partial unique index
  • ✓ 6 strategic indexes for query optimization

2. Schema File

Location: prisma/schema.prisma

Changes:

  • ✓ Added ResolutionStatus enum (ACTIVE, CORRECTED, OVERRIDDEN)
  • ✓ Added Resolution model with:
    • All required fields and relationships
    • Unique constraint on (marketId, ACTIVE status)
    • Proper field mappings to database column names
    • Comprehensive indexes for performance
    • Relationship to Market model with cascade delete
  • ✓ Updated Market model to include resolutions relationship

3. Testing Guide

Location: RESOLUTION_MIGRATION_TESTING.md

Includes:

  • Migration overview and acceptance criteria verification
  • Step-by-step testing procedures
  • SQL verification queries
  • TypeScript/Prisma ORM usage examples
  • Rollback plan
  • Success criteria checklist

Acceptance Criteria Met

Criterion Status Details
Resolution table keyed by market ID Primary key is UUID id, foreign key relationship with Markets
Includes outcome field Boolean field: true = YES, false = NO
Includes finalized_at field TIMESTAMP field for settlement cutoff
Includes provenance field TEXT field for source attribution
Enforces one active final resolution per market Partial unique index: resolutions_market_id_active_idx where status = 'ACTIVE'
Correction/override metadata strategy JSONB field correction_override_metadata with ResolutionStatus enum (ACTIVE, CORRECTED, OVERRIDDEN)

Key Features

1. Data Integrity

  • Foreign key constraint with cascade delete for data consistency
  • Unique partial index prevents multiple active resolutions per market
  • NOT NULL constraints on critical fields

2. Audit Trail

  • correctionOverrideMetadata JSONB field tracks:
    • When correction occurred
    • Previous outcome value
    • Reason for correction/override
    • Who made the change
  • Status transitions (ACTIVE → CORRECTED/OVERRIDDEN)

3. Performance

  • Market lookups: resolutions_market_id_idx
  • Status filtering: resolutions_status_idx
  • Temporal queries: resolutions_finalized_at_idx
  • Compound queries: resolutions_market_id_status_idx
  • Pagination: resolutions_created_at_idx (DESC)

4. Settlement Support

  • finalizedAt timestamp for settlement window enforcement
  • outcome boolean for payout calculations
  • status field distinguishes between active and historical resolutions
  • Cascade delete ensures referential integrity when markets are archived

How to Apply the Migration

Development

cd /workspaces/vatix-backend
pnpm prisma:migrate dev --name "verify resolutions migration"

Production

pnpm prisma:deploy

Validation

pnpm prisma:generate  # Regenerate Prisma client
pnpm test             # Run test suite

How to Verify Completion

1. Check Migration Applied

SELECT * FROM "_prisma_migrations"
WHERE migration = '20260428000000_add_resolutions_table';

2. Verify Table Structure

\d resolutions

3. Test One-Active-Per-Market Constraint

-- Insert first resolution (should succeed)
INSERT INTO resolutions (id, market_id, outcome, finalized_at, provenance, status)
VALUES ('res-1', 'market-1', true, NOW(), 'TEST', 'ACTIVE');

-- Try inserting second ACTIVE resolution (should fail)
INSERT INTO resolutions (id, market_id, outcome, finalized_at, provenance, status)
VALUES ('res-2', 'market-1', false, NOW(), 'TEST', 'ACTIVE');
-- Expected: Error: duplicate key violates unique constraint

-- Insert with different status (should succeed)
INSERT INTO resolutions (id, market_id, outcome, finalized_at, provenance, status)
VALUES ('res-2', 'market-1', false, NOW(), 'TEST', 'CORRECTED');

4. Test Prisma ORM Integration

import { prisma } from "@/services/prisma";

// Query should work
const activeResolution = await prisma.resolution.findFirst({
  where: { status: "ACTIVE" },
});

console.log("✓ Prisma client can access Resolution model");

Architecture Notes

Resolution Lifecycle

  1. ACTIVE: Current final resolution for the market
  2. CORRECTED: Previous ACTIVE resolution that was corrected (new one becomes ACTIVE)
  3. OVERRIDDEN: Previous ACTIVE resolution that was overridden (new one becomes ACTIVE)

Correction Strategy

When a resolution needs to be corrected:

  1. Update existing ACTIVE resolution to CORRECTED/OVERRIDDEN status
  2. Store previous state in correctionOverrideMetadata
  3. Create new ACTIVE resolution with updated outcome
  4. Partial unique index prevents simultaneous active resolutions

Settlement Workflow

  1. Market reaches endTime
  2. Resolution consensus established (via resolution candidates)
  3. Final resolution created with outcome and finalizedAt
  4. Settlement engine uses finalizedAt for cutoff
  5. Portfolio closeout completed
  6. Historical resolutions preserved for audit

Files to Review


Status: ✅ COMPLETE - Ready for testing and deployment