feat: move report artifacts to OSS storage
This commit is contained in:
94
database/016_monthly_report_oss_artifacts.down.sql
Normal file
94
database/016_monthly_report_oss_artifacts.down.sql
Normal file
@@ -0,0 +1,94 @@
|
||||
-- Restore the 012 local-only publication guard.
|
||||
|
||||
BEGIN;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF current_database() <> 'booking_test' THEN
|
||||
RAISE EXCEPTION
|
||||
'ARR monthly OSS artifact rollback is allowed only in booking_test';
|
||||
END IF;
|
||||
IF to_regclass('reporting.monthly_runs') IS NULL
|
||||
OR to_regprocedure('reporting.validate_monthly_run_publication()') IS NULL THEN
|
||||
RAISE EXCEPTION
|
||||
'ARR migration 016 is not applied';
|
||||
END IF;
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM reporting.monthly_runs AS run
|
||||
JOIN ingestion.artifacts AS artifact
|
||||
ON artifact.id IN (run.workbook_artifact_id, run.result_artifact_id)
|
||||
WHERE run.report_status IN ('active', 'superseded')
|
||||
AND artifact.storage_provider <> 'local'
|
||||
) THEN
|
||||
RAISE EXCEPTION
|
||||
'ARR monthly OSS artifact rollback refused while a published OSS artifact exists';
|
||||
END IF;
|
||||
END;
|
||||
$$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION reporting.validate_monthly_run_publication()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
DECLARE
|
||||
workbook_kind text;
|
||||
workbook_provider text;
|
||||
result_kind text;
|
||||
result_provider text;
|
||||
manifest_count integer;
|
||||
manifest_rows bigint;
|
||||
manifest_min integer;
|
||||
manifest_max integer;
|
||||
lineage_count integer;
|
||||
BEGIN
|
||||
IF NEW.report_status NOT IN ('active', 'superseded') THEN
|
||||
RETURN NEW;
|
||||
END IF;
|
||||
|
||||
SELECT artifact_kind, storage_provider
|
||||
INTO workbook_kind, workbook_provider
|
||||
FROM ingestion.artifacts
|
||||
WHERE id = NEW.workbook_artifact_id;
|
||||
|
||||
SELECT artifact_kind, storage_provider
|
||||
INTO result_kind, result_provider
|
||||
FROM ingestion.artifacts
|
||||
WHERE id = NEW.result_artifact_id;
|
||||
|
||||
IF workbook_kind IS DISTINCT FROM 'monthly_xlsx'
|
||||
OR workbook_provider IS DISTINCT FROM 'local'
|
||||
OR result_kind IS DISTINCT FROM 'result_json'
|
||||
OR result_provider IS DISTINCT FROM 'local' THEN
|
||||
RAISE EXCEPTION
|
||||
'published monthly run must reference controlled local monthly_xlsx and result_json artifacts';
|
||||
END IF;
|
||||
|
||||
SELECT count(*), COALESCE(sum(row_count), 0), min(worksheet_order), max(worksheet_order)
|
||||
INTO manifest_count, manifest_rows, manifest_min, manifest_max
|
||||
FROM reporting.monthly_channel_manifest
|
||||
WHERE report_id = NEW.id;
|
||||
|
||||
IF manifest_count <> NEW.channel_count
|
||||
OR manifest_rows <> NEW.row_count
|
||||
OR manifest_min <> 1
|
||||
OR manifest_max <> manifest_count THEN
|
||||
RAISE EXCEPTION
|
||||
'published monthly run requires a continuous reconciled channel manifest';
|
||||
END IF;
|
||||
|
||||
SELECT count(*)
|
||||
INTO lineage_count
|
||||
FROM reporting.monthly_run_daily_versions
|
||||
WHERE report_id = NEW.id;
|
||||
|
||||
IF lineage_count < 1 THEN
|
||||
RAISE EXCEPTION
|
||||
'published monthly run requires daily-version lineage';
|
||||
END IF;
|
||||
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$;
|
||||
|
||||
COMMIT;
|
||||
88
database/016_monthly_report_oss_artifacts.sql
Normal file
88
database/016_monthly_report_oss_artifacts.sql
Normal file
@@ -0,0 +1,88 @@
|
||||
-- Allow durable monthly publication artifacts in the existing private OSS.
|
||||
-- Historical local artifacts remain valid and readable.
|
||||
|
||||
BEGIN;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF current_database() <> 'booking_test' THEN
|
||||
RAISE EXCEPTION
|
||||
'ARR monthly OSS artifact migration is allowed only in booking_test';
|
||||
END IF;
|
||||
IF to_regclass('reporting.monthly_runs') IS NULL
|
||||
OR to_regclass('ingestion.artifacts') IS NULL
|
||||
OR to_regprocedure('reporting.validate_monthly_run_publication()') IS NULL THEN
|
||||
RAISE EXCEPTION
|
||||
'ARR migration 012 must be applied first';
|
||||
END IF;
|
||||
END;
|
||||
$$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION reporting.validate_monthly_run_publication()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
DECLARE
|
||||
workbook_kind text;
|
||||
workbook_provider text;
|
||||
result_kind text;
|
||||
result_provider text;
|
||||
manifest_count integer;
|
||||
manifest_rows bigint;
|
||||
manifest_min integer;
|
||||
manifest_max integer;
|
||||
lineage_count integer;
|
||||
BEGIN
|
||||
IF NEW.report_status NOT IN ('active', 'superseded') THEN
|
||||
RETURN NEW;
|
||||
END IF;
|
||||
|
||||
SELECT artifact_kind, storage_provider
|
||||
INTO workbook_kind, workbook_provider
|
||||
FROM ingestion.artifacts
|
||||
WHERE id = NEW.workbook_artifact_id;
|
||||
|
||||
SELECT artifact_kind, storage_provider
|
||||
INTO result_kind, result_provider
|
||||
FROM ingestion.artifacts
|
||||
WHERE id = NEW.result_artifact_id;
|
||||
|
||||
IF workbook_kind IS DISTINCT FROM 'monthly_xlsx'
|
||||
OR COALESCE(workbook_provider, '') NOT IN ('oss', 's3', 'local')
|
||||
OR result_kind IS DISTINCT FROM 'result_json'
|
||||
OR COALESCE(result_provider, '') NOT IN ('oss', 's3', 'local') THEN
|
||||
RAISE EXCEPTION
|
||||
'published monthly run must reference OSS or controlled local monthly artifacts';
|
||||
END IF;
|
||||
|
||||
SELECT count(*), COALESCE(sum(row_count), 0), min(worksheet_order), max(worksheet_order)
|
||||
INTO manifest_count, manifest_rows, manifest_min, manifest_max
|
||||
FROM reporting.monthly_channel_manifest
|
||||
WHERE report_id = NEW.id;
|
||||
|
||||
IF manifest_count <> NEW.channel_count
|
||||
OR manifest_rows <> NEW.row_count
|
||||
OR manifest_min <> 1
|
||||
OR manifest_max <> manifest_count THEN
|
||||
RAISE EXCEPTION
|
||||
'published monthly run requires a continuous reconciled channel manifest';
|
||||
END IF;
|
||||
|
||||
SELECT count(*)
|
||||
INTO lineage_count
|
||||
FROM reporting.monthly_run_daily_versions
|
||||
WHERE report_id = NEW.id;
|
||||
|
||||
IF lineage_count < 1 THEN
|
||||
RAISE EXCEPTION
|
||||
'published monthly run requires daily-version lineage';
|
||||
END IF;
|
||||
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$;
|
||||
|
||||
COMMENT ON FUNCTION reporting.validate_monthly_run_publication() IS
|
||||
'Published monthly artifacts may be private OSS/S3 or legacy controlled-local objects.';
|
||||
|
||||
COMMIT;
|
||||
@@ -1,7 +1,7 @@
|
||||
# ARR 测试数据库已执行记录
|
||||
|
||||
更新时间:2026-07-31
|
||||
状态:008–015 已提交;014/015 已通过迁移回滚探针、正式应用、结构/数据复核及真实 PostgreSQL 草稿激活外层回滚验收。首次真实业务工作簿激活仍待操作员授权。
|
||||
更新时间:2026-08-04
|
||||
状态:008–015 已提交;014/015 已通过迁移回滚探针、正式应用、结构/数据复核及真实 PostgreSQL 草稿激活外层回滚验收。016 已提交代码、待在测试机 booking_test 应用并完成 OSS 月报验收。首次真实业务工作簿激活仍待操作员授权。
|
||||
|
||||
## 目标与隔离
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
| `013_daily_upload_filename.sql` | `f7ea18d6b844d9bd90fa757a4cf8428d1dd5833c088ae23444ac81fbe204fb0a` | 已提交并验收 |
|
||||
| `014_booking_current_source_batch.sql` | `23bf0fcc880225ca276d4d7d871057be4f7950e761ddbeed1df2a3c6e25463b5` | 2026-07-31 已通过同事务回滚探针后由受控连接正式应用;数据复核通过 |
|
||||
| `015_booking_excel_review_drafts.sql` | `a80689c4ecc3b6b3502e8f094a8c175af38df8c09f9d2c64412a9aec55bae12a` | 2026-07-31 已由受控连接正式应用;真实 PostgreSQL 草稿编辑/激活外层回滚通过 |
|
||||
| `016_monthly_report_oss_artifacts.sql` | `70ca052f71da9f88e83fe8bccf0a6682cdd3138c3525981c80eebc868e401626` | 代码已提交;尚未在远程 `booking_test` 应用 |
|
||||
|
||||
## 014/015 最新核查状态
|
||||
|
||||
|
||||
Reference in New Issue
Block a user