Implement display artifacts, pricing integrity, draft base and publish preview bundle
This commit is contained in:
135
backend/app/services/publish_preview.py
Normal file
135
backend/app/services/publish_preview.py
Normal file
@@ -0,0 +1,135 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from app.repositories.scheme_artifacts import list_scheme_artifacts
|
||||
from app.repositories.scheme_seats import list_scheme_version_seats
|
||||
from app.repositories.scheme_version_pricing import (
|
||||
find_effective_snapshot_price_rule,
|
||||
list_scheme_version_snapshot_categories,
|
||||
list_scheme_version_snapshot_rules,
|
||||
)
|
||||
from app.services.publish_preview_cache import (
|
||||
get_latest_publish_preview_artifact,
|
||||
save_publish_preview_artifact,
|
||||
)
|
||||
from app.services.scheme_validation import build_scheme_validation_report
|
||||
from app.services.structure_diff import build_structure_diff
|
||||
|
||||
|
||||
async def build_publish_preview_bundle(
|
||||
*,
|
||||
scheme_id: str,
|
||||
scheme_version_id: str,
|
||||
baseline_override_scheme_version_id: str | None = None,
|
||||
) -> dict:
|
||||
validation = await build_scheme_validation_report(
|
||||
scheme_id=scheme_id,
|
||||
scheme_version_id=scheme_version_id,
|
||||
)
|
||||
structure_diff = await build_structure_diff(
|
||||
scheme_id=scheme_id,
|
||||
draft_scheme_version_id=scheme_version_id,
|
||||
baseline_override_scheme_version_id=baseline_override_scheme_version_id,
|
||||
)
|
||||
artifacts_rows = await list_scheme_artifacts(scheme_version_id=scheme_version_id)
|
||||
seats = await list_scheme_version_seats(scheme_version_id)
|
||||
snapshot_categories = await list_scheme_version_snapshot_categories(scheme_version_id)
|
||||
snapshot_rules = await list_scheme_version_snapshot_rules(scheme_version_id)
|
||||
|
||||
priced = 0
|
||||
unpriced = 0
|
||||
snapshot_available = len(snapshot_rules) > 0 or len(snapshot_categories) > 0
|
||||
|
||||
for seat in seats:
|
||||
if not seat.seat_id:
|
||||
unpriced += 1
|
||||
continue
|
||||
|
||||
if not snapshot_available:
|
||||
unpriced += 1
|
||||
continue
|
||||
|
||||
try:
|
||||
await find_effective_snapshot_price_rule(
|
||||
scheme_version_id=scheme_version_id,
|
||||
seat_id=seat.seat_id,
|
||||
group_id=seat.group_id,
|
||||
sector_id=seat.sector_id,
|
||||
)
|
||||
priced += 1
|
||||
except Exception:
|
||||
unpriced += 1
|
||||
|
||||
artifacts = {
|
||||
"total": len(artifacts_rows),
|
||||
"items": [
|
||||
{
|
||||
"artifact_id": row.artifact_id,
|
||||
"artifact_type": row.artifact_type,
|
||||
"artifact_variant": row.artifact_variant,
|
||||
"status": row.status,
|
||||
"storage_path": row.storage_path,
|
||||
"meta_json": row.meta_json,
|
||||
"created_at": row.created_at.isoformat(),
|
||||
}
|
||||
for row in artifacts_rows
|
||||
],
|
||||
}
|
||||
|
||||
pricing_coverage = {
|
||||
"snapshot_available": snapshot_available,
|
||||
"snapshot_categories_count": len(snapshot_categories),
|
||||
"snapshot_rules_count": len(snapshot_rules),
|
||||
"total_seats": len(seats),
|
||||
"priced_seats": priced,
|
||||
"unpriced_seats": unpriced,
|
||||
}
|
||||
|
||||
summary = {
|
||||
"is_publishable": validation["summary"]["is_publishable"],
|
||||
"has_structure_changes": any(value > 0 for value in structure_diff["summary"].values()),
|
||||
"has_artifacts": len(artifacts_rows) > 0,
|
||||
"has_unpriced_seats": unpriced > 0,
|
||||
"snapshot_available": snapshot_available,
|
||||
}
|
||||
|
||||
return {
|
||||
"artifacts": artifacts,
|
||||
"validation": validation,
|
||||
"structure_diff": structure_diff,
|
||||
"pricing_coverage": pricing_coverage,
|
||||
"summary": summary,
|
||||
}
|
||||
|
||||
|
||||
async def get_or_build_publish_preview_bundle(
|
||||
*,
|
||||
scheme_id: str,
|
||||
scheme_version_id: str,
|
||||
baseline_override_scheme_version_id: str | None = None,
|
||||
refresh: bool = False,
|
||||
) -> dict:
|
||||
if not refresh:
|
||||
artifact = await get_latest_publish_preview_artifact(
|
||||
scheme_version_id=scheme_version_id,
|
||||
baseline_scheme_version_id=baseline_override_scheme_version_id,
|
||||
)
|
||||
if artifact:
|
||||
path = Path(artifact.storage_path)
|
||||
if path.exists():
|
||||
return json.loads(path.read_text(encoding="utf-8"))
|
||||
|
||||
payload = await build_publish_preview_bundle(
|
||||
scheme_id=scheme_id,
|
||||
scheme_version_id=scheme_version_id,
|
||||
baseline_override_scheme_version_id=baseline_override_scheme_version_id,
|
||||
)
|
||||
await save_publish_preview_artifact(
|
||||
scheme_id=scheme_id,
|
||||
scheme_version_id=scheme_version_id,
|
||||
payload=payload,
|
||||
baseline_scheme_version_id=payload["structure_diff"]["baseline_scheme_version_id"],
|
||||
)
|
||||
return payload
|
||||
Reference in New Issue
Block a user