Bridge legacy QuoteJudge database columns

This commit is contained in:
2026-07-18 01:16:49 -03:00
parent a232cc28a8
commit 8b6b5188a5
4 changed files with 38 additions and 7 deletions

View File

@@ -1,5 +1,5 @@
name: quote-judge-studio-v1
version: 0.1.4
version: 0.1.5
entrypoint: agent:QuoteJudgeStudioV1
expose:
public: false

View File

@@ -108,7 +108,7 @@ class QuoteJudgeStudioV1(A2AAgent[QuoteJudgeStudioV1Config, PlatformUserAuth]):
"QuoteJudge compares vendor quotes with weighted price, delivery, and "
"warranty scoring, persists per-user comparisons, and serves a one-page product UI."
)
version = "0.1.4"
version = "0.1.5"
config_model = QuoteJudgeStudioV1Config
auth_model = PlatformUserAuth
@@ -574,11 +574,14 @@ async def _save_comparison(tenant_key: str, payload: dict[str, Any]) -> None:
cur.execute(
"""
INSERT INTO quote_comparisons
(tenant_key, comparison_id, recommended_vendor, score, normalized_total, payload, updated_at)
VALUES (%s, %s, %s, %s, %s, %s, NOW())
(tenant_key, comparison_id, recommended_vendor, recommendation_vendor,
score, weighted_score, normalized_total, payload, updated_at)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, NOW())
ON CONFLICT (tenant_key, comparison_id) DO UPDATE SET
recommended_vendor = EXCLUDED.recommended_vendor,
recommendation_vendor = EXCLUDED.recommendation_vendor,
score = EXCLUDED.score,
weighted_score = EXCLUDED.weighted_score,
normalized_total = EXCLUDED.normalized_total,
payload = EXCLUDED.payload,
updated_at = NOW()
@@ -587,6 +590,8 @@ async def _save_comparison(tenant_key: str, payload: dict[str, Any]) -> None:
tenant_key,
payload["comparison_id"],
payload["recommendation"]["vendor"],
payload["recommendation"]["vendor"],
payload["recommendation"]["score"],
payload["recommendation"]["score"],
payload["recommendation"]["normalized_total"],
json.dumps(payload),
@@ -645,16 +650,18 @@ async def _persist_receipt(
cur.execute(
"""
INSERT INTO quote_execution_receipts
(tenant_key, comparison_id, receipt_id, skill_name, status, input_hash,
result_hash, payload, created_at)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, NOW())
(tenant_key, comparison_id, receipt_id, skill_name, tool_name, status, ok,
input_hash, result_hash, payload, created_at)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NOW())
""",
(
tenant_key,
comparison_id,
receipt["receipt_id"],
skill_name,
skill_name,
status,
status == "ok",
receipt["input_hash"],
receipt["result_hash"],
json.dumps(receipt),

View File

@@ -0,0 +1,19 @@
-- Bridge the earliest QuoteJudge schema and the current typed schema without
-- dropping data or weakening historical NOT NULL constraints.
ALTER TABLE quote_comparisons
ADD COLUMN IF NOT EXISTS recommendation_vendor TEXT,
ADD COLUMN IF NOT EXISTS weighted_score NUMERIC(10,4);
UPDATE quote_comparisons
SET recommendation_vendor = COALESCE(recommendation_vendor, recommended_vendor),
weighted_score = COALESCE(weighted_score, score)
WHERE recommendation_vendor IS NULL OR weighted_score IS NULL;
ALTER TABLE quote_execution_receipts
ADD COLUMN IF NOT EXISTS tool_name TEXT,
ADD COLUMN IF NOT EXISTS ok BOOLEAN;
UPDATE quote_execution_receipts
SET tool_name = COALESCE(tool_name, skill_name),
ok = COALESCE(ok, status = 'ok')
WHERE tool_name IS NULL OR ok IS NULL;

View File

@@ -60,6 +60,11 @@ def test_full_stack_product_contract():
migrations = list((ROOT / "db" / "migrations").glob("*.sql"))
assert migrations and all(path.read_text(encoding="utf-8").strip() for path in migrations)
compatibility = (ROOT / "db" / "migrations" / "003_quotejudge_legacy_bridge.sql").read_text()
assert "recommendation_vendor" in compatibility
assert "tool_name" in compatibility
assert "recommendation_vendor = EXCLUDED.recommendation_vendor" in source
assert "tool_name, status, ok" in source
card = load_local_project(ROOT).agent_cls().card()
skill_names = {skill.name for skill in card.skills}