python : INFO [alembic.runtime.migration] Context impl PostgresqlImpl. At line:2 char:47 + ... mbic heads; python -m alembic upgrade head --sql *> ..\test-results\a ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (INFO [alembic....PostgresqlImpl.:String) [], RemoteException + FullyQualifiedErrorId : NativeCommandError INFO [alembic.runtime.migration] Generating static SQL INFO [alembic.runtime.migration] Will assume transactional DDL. BEGIN; CREATE TABLE alembic_version ( version_num VARCHAR(32) NOT NULL, CONSTRAINT alembic_version_pkc PRIMARY KEY (version_num) ); INFO [alembic.runtime.migration] Running upgrade -> 202601110001, Initial PostGIS schema for Sprint 1 foundation. -- Running upgrade -> 202601110001 CREATE EXTENSION IF NOT EXISTS postgis; CREATE EXTENSION IF NOT EXISTS postgis_topology; CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; CREATE TABLE projects ( id UUID NOT NULL, name TEXT NOT NULL, description TEXT, region TEXT DEFAULT 'Kempen' NOT NULL, status TEXT DEFAULT 'active' NOT NULL, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), PRIMARY KEY (id) ); CREATE TABLE areas ( id UUID NOT NULL, project_id UUID NOT NULL, name TEXT NOT NULL, geometry geometry(MULTIPOLYGON,4326) NOT NULL, original_crs TEXT, area_m2 FLOAT, bbox geometry(POLYGON,4326), created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), PRIMARY KEY (id), FOREIGN KEY(project_id) REFERENCES projects (id) ON DELETE CASCADE ); CREATE INDEX idx_areas_bbox ON areas USING gist (bbox); CREATE INDEX idx_areas_geometry ON areas USING gist (geometry); CREATE TABLE datasets ( id UUID NOT NULL, project_id UUID NOT NULL, area_id UUID, name TEXT NOT NULL, dataset_type TEXT NOT NULL, source TEXT NOT NULL, storage_path TEXT, derived_from_dataset_id UUID, crs TEXT, bounds_json JSON, resolution_json JSON, bands_json JSON, metadata_json JSON, status TEXT DEFAULT 'created' NOT NULL, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), PRIMARY KEY (id), FOREIGN KEY(project_id) REFERENCES projects (id) ON DELETE CASCADE, FOREIGN KEY(area_id) REFERENCES areas (id) ON DELETE SET NULL, FOREIGN KEY(derived_from_dataset_id) REFERENCES datasets (id) ON DELETE SET NULL ); CREATE TABLE dataset_versions ( id UUID NOT NULL, dataset_id UUID NOT NULL, version INTEGER DEFAULT '1' NOT NULL, storage_path TEXT, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), PRIMARY KEY (id), FOREIGN KEY(dataset_id) REFERENCES datasets (id) ON DELETE CASCADE ); CREATE TABLE analysis_runs ( id UUID NOT NULL, project_id UUID NOT NULL, area_id UUID, analysis_type TEXT NOT NULL, status TEXT NOT NULL, parameters_json JSON NOT NULL, started_at TIMESTAMP WITH TIME ZONE, finished_at TIMESTAMP WITH TIME ZONE, error_message TEXT, PRIMARY KEY (id), FOREIGN KEY(project_id) REFERENCES projects (id) ON DELETE CASCADE, FOREIGN KEY(area_id) REFERENCES areas (id) ON DELETE SET NULL ); CREATE TABLE exports ( id UUID NOT NULL, project_id UUID NOT NULL, analysis_run_id UUID, export_type TEXT NOT NULL, storage_path TEXT NOT NULL, metadata_json JSON, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), PRIMARY KEY (id), FOREIGN KEY(project_id) REFERENCES projects (id) ON DELETE CASCADE, FOREIGN KEY(analysis_run_id) REFERENCES analysis_runs (id) ON DELETE SET NULL ); CREATE INDEX ix_areas_geometry ON areas USING gist (geometry); CREATE INDEX ix_areas_project_id ON areas (project_id); CREATE INDEX ix_datasets_project_id ON datasets (project_id); INSERT INTO alembic_version (version_num) VALUES ('202601110001') RETURNING alembic_version.version_num; INFO [alembic.runtime.migration] Running upgrade 202601110001 -> 202601120001, Add dataset storage metadata columns. -- Running upgrade 202601110001 -> 202601120001 ALTER TABLE datasets ADD COLUMN original_filename TEXT; ALTER TABLE datasets ADD COLUMN stored_filename TEXT; ALTER TABLE datasets ADD COLUMN content_type TEXT; ALTER TABLE datasets ADD COLUMN size_bytes INTEGER; ALTER TABLE datasets ADD COLUMN checksum_sha256 TEXT; ALTER TABLE datasets ALTER COLUMN status SET DEFAULT 'uploaded'; INFO [alembic.runtime.migration] Running upgrade 202601120001 -> 20260611212435, Add lightweight job table for sprint- 3 async architecture foundation. INFO [alembic.runtime.migration] Running upgrade 20260611212435 -> 202606120001, Add dataset reference and provenance metadata columns. INFO [alembic.runtime.migration] Running upgrade 202606120001 -> 202606120700, Add Sprint 7A vector feature and QA per sistence foundation. UPDATE alembic_version SET version_num='202601120001' WHERE alembic_version.version_num = '202601110001'; -- Running upgrade 202601120001 -> 20260611212435 CREATE TABLE jobs ( id UUID NOT NULL, INFO [alembic.runtime.migration] Running upgrade 202606120700 -> 202606120800, Add Sprint 8 detection foundation. INFO [alembic.runtime.migration] Running upgrade 202606120800 -> 202606120900, Add Sprint 9 segmentation foundation. job_type TEXT NOT NULL, status TEXT DEFAULT 'queued' NOT NULL, project_id UUID NOT NULL, dataset_id UUID, input_dataset_id UUID, output_dataset_id UUID, parameters_json JSON NOT NULL, result_json JSON, error_message TEXT, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), started_at TIMESTAMP WITH TIME ZONE, finished_at TIMESTAMP WITH TIME ZONE, PRIMARY KEY (id), FOREIGN KEY(project_id) REFERENCES projects (id) ON DELETE CASCADE, FOREIGN KEY(dataset_id) REFERENCES datasets (id) ON DELETE SET NULL, FOREIGN KEY(input_dataset_id) REFERENCES datasets (id) ON DELETE SET NULL, FOREIGN KEY(output_dataset_id) REFERENCES datasets (id) ON DELETE SET NULL ); CREATE INDEX ix_jobs_project_id ON jobs (project_id); CREATE INDEX ix_jobs_status ON jobs (status); INFO [alembic.runtime.migration] Running upgrade 202606120900 -> 202607140001, Add temporal dataset metadata and durab le dataset-version provenance. UPDATE alembic_version SET version_num='20260611212435' WHERE alembic_version.version_num = '202601120001'; -- Running upgrade 20260611212435 -> 202606120001 ALTER TABLE datasets ADD COLUMN dataset_role TEXT DEFAULT 'source' NOT NULL; ALTER TABLE datasets ADD COLUMN source_name TEXT; ALTER TABLE datasets ADD COLUMN reference_layer_name TEXT; ALTER TABLE datasets ADD COLUMN source_metadata JSON; ALTER TABLE datasets ADD COLUMN provenance_metadata JSON; ALTER TABLE datasets ADD COLUMN imported_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() NOT NULL; UPDATE alembic_version SET version_num='202606120001' WHERE alembic_version.version_num = '20260611212435'; -- Running upgrade 202606120001 -> 202606120700 CREATE TABLE vector_features ( id UUID NOT NULL, dataset_id UUID NOT NULL, feature_class TEXT, source_feature_id TEXT, properties_json JSON, geometry geometry(GEOMETRY,4326) NOT NULL, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), PRIMARY KEY (id), FOREIGN KEY(dataset_id) REFERENCES datasets (id) ON DELETE CASCADE ); CREATE INDEX ix_vector_features_dataset_id ON vector_features (dataset_id); CREATE INDEX ix_vector_features_geometry ON vector_features USING gist (geometry); CREATE TABLE quality_checks ( id UUID NOT NULL, project_id UUID NOT NULL, job_id UUID, analysis_run_id UUID, candidate_dataset_id UUID, reference_dataset_id UUID NOT NULL, check_type TEXT NOT NULL, status TEXT NOT NULL, score FLOAT, parameters_json JSON, findings_json JSON, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), completed_at TIMESTAMP WITH TIME ZONE, PRIMARY KEY (id), FOREIGN KEY(project_id) REFERENCES projects (id) ON DELETE CASCADE, FOREIGN KEY(job_id) REFERENCES jobs (id) ON DELETE SET NULL, FOREIGN KEY(analysis_run_id) REFERENCES analysis_runs (id) ON DELETE SET NULL, FOREIGN KEY(candidate_dataset_id) REFERENCES datasets (id) ON DELETE SET NULL, FOREIGN KEY(reference_dataset_id) REFERENCES datasets (id) ON DELETE CASCADE ); CREATE INDEX ix_quality_checks_project_id ON quality_checks (project_id); CREATE INDEX ix_quality_checks_reference_dataset_id ON quality_checks (reference_dataset_id); CREATE INDEX ix_quality_checks_candidate_dataset_id ON quality_checks (candidate_dataset_id); CREATE INDEX ix_quality_checks_analysis_run_id ON quality_checks (analysis_run_id); CREATE TABLE metrics ( id UUID NOT NULL, quality_check_id UUID, analysis_run_id UUID, metric_key TEXT NOT NULL, metric_value FLOAT, metric_unit TEXT, label TEXT, metadata_json JSON, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), PRIMARY KEY (id), FOREIGN KEY(quality_check_id) REFERENCES quality_checks (id) ON DELETE CASCADE, FOREIGN KEY(analysis_run_id) REFERENCES analysis_runs (id) ON DELETE SET NULL ); CREATE INDEX ix_metrics_quality_check_id ON metrics (quality_check_id); CREATE INDEX ix_metrics_analysis_run_id ON metrics (analysis_run_id); UPDATE alembic_version SET version_num='202606120700' WHERE alembic_version.version_num = '202606120001'; -- Running upgrade 202606120700 -> 202606120800 ALTER TABLE analysis_runs ADD COLUMN dataset_id UUID; ALTER TABLE analysis_runs ADD FOREIGN KEY(dataset_id) REFERENCES datasets (id) ON DELETE SET NULL; ALTER TABLE analysis_runs ADD COLUMN job_id UUID; ALTER TABLE analysis_runs ADD FOREIGN KEY(job_id) REFERENCES jobs (id) ON DELETE SET NULL; ALTER TABLE analysis_runs ADD COLUMN model_name VARCHAR(255); ALTER TABLE analysis_runs ADD COLUMN model_version VARCHAR(120); ALTER TABLE analysis_runs ADD COLUMN result_json JSON; ALTER TABLE analysis_runs ADD COLUMN created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() NOT NULL; CREATE TABLE detections ( id UUID NOT NULL, project_id UUID NOT NULL, dataset_id UUID, analysis_run_id UUID, job_id UUID, model_name VARCHAR(255) NOT NULL, model_version VARCHAR(120), class_name VARCHAR(120) NOT NULL, confidence FLOAT NOT NULL, geometry geometry(GEOMETRY,4326) NOT NULL, bbox_json JSON, source_tile_path VARCHAR(500), properties_json JSON, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() NOT NULL, PRIMARY KEY (id), FOREIGN KEY(project_id) REFERENCES projects (id) ON DELETE CASCADE, FOREIGN KEY(dataset_id) REFERENCES datasets (id) ON DELETE SET NULL, FOREIGN KEY(analysis_run_id) REFERENCES analysis_runs (id) ON DELETE SET NULL, FOREIGN KEY(job_id) REFERENCES jobs (id) ON DELETE SET NULL ); CREATE INDEX ix_detections_project_id ON detections (project_id); CREATE INDEX ix_detections_dataset_id ON detections (dataset_id); CREATE INDEX ix_detections_analysis_run_id ON detections (analysis_run_id); CREATE INDEX ix_detections_class_name ON detections (class_name); CREATE INDEX ix_detections_geometry ON detections USING gist (geometry); UPDATE alembic_version SET version_num='202606120800' WHERE alembic_version.version_num = '202606120700'; -- Running upgrade 202606120800 -> 202606120900 CREATE TABLE segmentations ( id UUID NOT NULL, project_id UUID NOT NULL, dataset_id UUID, job_id UUID, analysis_run_id UUID, model_name VARCHAR(255) NOT NULL, model_version VARCHAR(120), class_name VARCHAR(120) NOT NULL, confidence FLOAT, geometry geometry(MULTIPOLYGON,4326) NOT NULL, bbox_json JSON, area_m2 FLOAT, mask_path TEXT, source_tile_path VARCHAR(500), tile_index INTEGER, properties_json JSON, provenance_json JSON, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() NOT NULL, PRIMARY KEY (id), FOREIGN KEY(project_id) REFERENCES projects (id) ON DELETE CASCADE, FOREIGN KEY(dataset_id) REFERENCES datasets (id) ON DELETE SET NULL, INFO [alembic.runtime.migration] Running upgrade 202607140001 -> 202607150001, Add durable operator review decisions f or detection QA evidence. INFO [alembic.runtime.migration] Running upgrade 202607150001 -> 202607160001, Index partitioned vector features by da taset and municipality. INFO [alembic.runtime.migration] Running upgrade 202607160001 -> 202607260001, Add resumable AOI parent and partition operations. FOREIGN KEY(job_id) REFERENCES jobs (id) ON DELETE SET NULL, FOREIGN KEY(analysis_run_id) REFERENCES analysis_runs (id) ON DELETE SET NULL ); CREATE INDEX ix_segmentations_project_id ON segmentations (project_id); CREATE INDEX ix_segmentations_dataset_id ON segmentations (dataset_id); CREATE INDEX ix_segmentations_analysis_run_id ON segmentations (analysis_run_id); CREATE INDEX ix_segmentations_job_id ON segmentations (job_id); CREATE INDEX ix_segmentations_class_name ON segmentations (class_name); CREATE INDEX ix_segmentations_geometry ON segmentations USING gist (geometry); UPDATE alembic_version SET version_num='202606120900' WHERE alembic_version.version_num = '202606120800'; -- Running upgrade 202606120900 -> 202607140001 ALTER TABLE datasets ADD COLUMN temporal_series_key VARCHAR(255); ALTER TABLE datasets ADD COLUMN observed_at TIMESTAMP WITH TIME ZONE; ALTER TABLE datasets ADD COLUMN valid_from TIMESTAMP WITH TIME ZONE; ALTER TABLE datasets ADD COLUMN valid_to TIMESTAMP WITH TIME ZONE; ALTER TABLE datasets ADD COLUMN temporal_granularity VARCHAR(32); ALTER TABLE datasets ADD COLUMN source_version VARCHAR(120); ALTER TABLE dataset_versions ADD COLUMN source_version VARCHAR(120); ALTER TABLE dataset_versions ADD COLUMN observed_at TIMESTAMP WITH TIME ZONE; ALTER TABLE dataset_versions ADD COLUMN valid_from TIMESTAMP WITH TIME ZONE; ALTER TABLE dataset_versions ADD COLUMN valid_to TIMESTAMP WITH TIME ZONE; ALTER TABLE dataset_versions ADD COLUMN checksum_sha256 VARCHAR(64); ALTER TABLE dataset_versions ADD COLUMN source_metadata JSON; ALTER TABLE dataset_versions ADD COLUMN provenance_metadata JSON; CREATE INDEX ix_datasets_project_temporal_series_observed ON datasets (project_id, temporal_series_key, observed_at); CREATE UNIQUE INDEX ix_dataset_versions_dataset_version ON dataset_versions (dataset_id, version); CREATE INDEX ix_vector_features_dataset_source_feature ON vector_features (dataset_id, source_feature_id); ALTER TABLE datasets ADD CONSTRAINT ck_datasets_temporal_valid_range CHECK (valid_to IS NULL OR valid_from IS NULL OR valid_to >= valid_from); ALTER TABLE dataset_versions ADD CONSTRAINT ck_dataset_versions_temporal_valid_range CHECK (valid_to IS NULL OR valid_from IS NULL OR valid_to >= valid_from); UPDATE alembic_version SET version_num='202607140001' WHERE alembic_version.version_num = '202606120900'; -- Running upgrade 202607140001 -> 202607150001 CREATE TABLE detection_reviews ( id UUID NOT NULL, project_id UUID NOT NULL, quality_check_id UUID NOT NULL, analysis_run_id UUID, evidence_role VARCHAR(32) NOT NULL, evidence_feature_id VARCHAR(255) NOT NULL, detection_id UUID, reference_feature_id UUID, decision VARCHAR(64) DEFAULT 'unreviewed' NOT NULL, notes TEXT, reviewed_by VARCHAR(120) DEFAULT 'operator' NOT NULL, created_at TIMESTAMP WITH TIME ZONE DEFAULT now() NOT NULL, updated_at TIMESTAMP WITH TIME ZONE DEFAULT now() NOT NULL, PRIMARY KEY (id), CONSTRAINT ck_detection_reviews_evidence_role CHECK (evidence_role IN ('false_positive', 'false_negative')), CONSTRAINT ck_detection_reviews_decision CHECK (decision IN ('confirmed_model_false_positive', 'confirmed_model_false_negative', 'reference_gap_or_change', 'qa_alignment_mismatch', 'imagery_obscured_or_uncertain', 'uncertain', 'unreviewed')), FOREIGN KEY(analysis_run_id) REFERENCES analysis_runs (id) ON DELETE SET NULL, FOREIGN KEY(detection_id) REFERENCES detections (id) ON DELETE SET NULL, FOREIGN KEY(project_id) REFERENCES projects (id) ON DELETE CASCADE, FOREIGN KEY(quality_check_id) REFERENCES quality_checks (id) ON DELETE CASCADE, FOREIGN KEY(reference_feature_id) REFERENCES vector_features (id) ON DELETE SET NULL, CONSTRAINT uq_detection_reviews_evidence UNIQUE (quality_check_id, evidence_role, evidence_feature_id) ); CREATE INDEX ix_detection_reviews_project_id ON detection_reviews (project_id); CREATE INDEX ix_detection_reviews_quality_check_id ON detection_reviews (quality_check_id); CREATE INDEX ix_detection_reviews_analysis_run_id ON detection_reviews (analysis_run_id); CREATE INDEX ix_detection_reviews_decision ON detection_reviews (decision); UPDATE alembic_version SET version_num='202607150001' WHERE alembic_version.version_num = '202607140001'; -- Running upgrade 202607150001 -> 202607160001 CREATE INDEX ix_vector_features_dataset_municipality ON vector_features (dataset_id, (properties_json ->> 'municipality')); UPDATE alembic_version SET version_num='202607160001' WHERE alembic_version.version_num = '202607150001'; -- Running upgrade 202607160001 -> 202607260001 CREATE TABLE aoi_operations ( id UUID NOT NULL, project_id UUID NOT NULL, area_id UUID, parent_job_id UUID, operation_type VARCHAR(128) NOT NULL, status VARCHAR(32) NOT NULL, geometry geometry(MULTIPOLYGON,4326) NOT NULL, request_json JSON NOT NULL, plan_json JSON NOT NULL, result_json JSON, error_message TEXT, created_at TIMESTAMP WITH TIME ZONE DEFAULT now(), started_at TIMESTAMP WITH TIME ZONE, finished_at TIMESTAMP WITH TIME ZONE, updated_at TIMESTAMP WITH TIME ZONE DEFAULT now(), PRIMARY KEY (id), CONSTRAINT ck_aoi_operations_status CHECK (status IN ('queued', 'running', 'partial', 'success', 'failed', 'cancelled')), FOREIGN KEY(project_id) REFERENCES projects (id) ON DELETE CASCADE, FOREIGN KEY(area_id) REFERENCES areas (id) ON DELETE SET NULL, FOREIGN KEY(parent_job_id) REFERENCES jobs (id) ON DELETE SET NULL ); CREATE INDEX ix_aoi_operations_project_status ON aoi_operations (project_id, status); CREATE INDEX ix_aoi_operations_geometry ON aoi_operations USING gist (geometry); CREATE TABLE aoi_operation_partitions ( id UUID NOT NULL, operation_id UUID NOT NULL, child_job_id UUID, partition_key VARCHAR(255) NOT NULL, provider_key VARCHAR(120) NOT NULL, product_key VARCHAR(120) NOT NULL, ordinal INTEGER NOT NULL, status VARCHAR(32) NOT NULL, geometry geometry(MULTIPOLYGON,4326) NOT NULL, attempt_count INTEGER DEFAULT '0' NOT NULL, max_attempts INTEGER DEFAULT '3' NOT NULL, checkpoint_json JSON, result_json JSON, error_message TEXT, created_at TIMESTAMP WITH TIME ZONE DEFAULT now(), started_at TIMESTAMP WITH TIME ZONE, finished_at TIMESTAMP WITH TIME ZONE, updated_at TIMESTAMP WITH TIME ZONE DEFAULT now(), PRIMARY KEY (id), CONSTRAINT ck_aoi_operation_partitions_status CHECK (status IN ('queued', 'running', 'success', 'failed', 'skipped')), CONSTRAINT uq_aoi_operation_partition_key UNIQUE (operation_id, partition_key), FOREIGN KEY(operation_id) REFERENCES aoi_operations (id) ON DELETE CASCADE, FOREIGN KEY(child_job_id) REFERENCES jobs (id) ON DELETE SET NULL ); CREATE INDEX ix_aoi_operation_partitions_operation_status ON aoi_operation_partitions (operation_id, status); CREATE INDEX ix_aoi_operation_partitions_geometry ON aoi_operation_partitions USING gist (geometry); UPDATE alembic_version SET version_num='202607260001' WHERE alembic_version.version_num = '202607160001'; COMMIT;