|
|
@@ -0,0 +1,635 @@
|
|
|
+from __future__ import annotations
|
|
|
+
|
|
|
+from datetime import datetime
|
|
|
+from decimal import Decimal
|
|
|
+from typing import Any
|
|
|
+
|
|
|
+from sqlalchemy import (
|
|
|
+ BigInteger,
|
|
|
+ Boolean,
|
|
|
+ DateTime,
|
|
|
+ ForeignKey,
|
|
|
+ Index,
|
|
|
+ Integer,
|
|
|
+ JSON,
|
|
|
+ Numeric,
|
|
|
+ String,
|
|
|
+ Text,
|
|
|
+ UniqueConstraint,
|
|
|
+ func,
|
|
|
+)
|
|
|
+from sqlalchemy.orm import Mapped, mapped_column
|
|
|
+
|
|
|
+from supply_infra.db.base import Base
|
|
|
+
|
|
|
+
|
|
|
+class EvidencePackage(Base):
|
|
|
+ """Immutable evidence snapshot owned by one durable pipeline run."""
|
|
|
+
|
|
|
+ __tablename__ = "evidence_package"
|
|
|
+ __table_args__ = (
|
|
|
+ UniqueConstraint("run_id", name="uk_evidence_package_run"),
|
|
|
+ Index("idx_evidence_package_biz", "biz_dt", "created_at"),
|
|
|
+ )
|
|
|
+
|
|
|
+ package_id: Mapped[str] = mapped_column(String(36), primary_key=True)
|
|
|
+ run_id: Mapped[str] = mapped_column(
|
|
|
+ String(36),
|
|
|
+ ForeignKey("pipeline_run.run_id", ondelete="RESTRICT"),
|
|
|
+ nullable=False,
|
|
|
+ )
|
|
|
+ biz_dt: Mapped[str] = mapped_column(String(8), nullable=False)
|
|
|
+ package_version: Mapped[int] = mapped_column(Integer, nullable=False, default=1)
|
|
|
+ status: Mapped[str] = mapped_column(
|
|
|
+ String(24), nullable=False, default="frozen"
|
|
|
+ )
|
|
|
+ source_snapshot_hash: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
|
+ source_versions_json: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
|
|
|
+ evidence_count: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
|
|
|
+ created_at: Mapped[datetime] = mapped_column(
|
|
|
+ DateTime, nullable=False, server_default=func.now()
|
|
|
+ )
|
|
|
+
|
|
|
+
|
|
|
+class RawDemandExpression(Base):
|
|
|
+ """Unmodified source expression captured inside an evidence package."""
|
|
|
+
|
|
|
+ __tablename__ = "raw_demand_expression"
|
|
|
+ __table_args__ = (
|
|
|
+ UniqueConstraint(
|
|
|
+ "package_id",
|
|
|
+ "source_type",
|
|
|
+ "source_record_id",
|
|
|
+ name="uk_raw_expression_source",
|
|
|
+ ),
|
|
|
+ Index("idx_raw_expression_package", "package_id"),
|
|
|
+ Index("idx_raw_expression_hash", "content_hash"),
|
|
|
+ )
|
|
|
+
|
|
|
+ expression_id: Mapped[str] = mapped_column(String(36), primary_key=True)
|
|
|
+ package_id: Mapped[str] = mapped_column(
|
|
|
+ String(36),
|
|
|
+ ForeignKey("evidence_package.package_id", ondelete="RESTRICT"),
|
|
|
+ nullable=False,
|
|
|
+ )
|
|
|
+ source_type: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
|
+ source_record_id: Mapped[str] = mapped_column(String(128), nullable=False)
|
|
|
+ raw_text: Mapped[str] = mapped_column(String(512), nullable=False)
|
|
|
+ original_payload_json: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
|
|
|
+ content_hash: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
|
+ observed_biz_dt: Mapped[str] = mapped_column(String(8), nullable=False)
|
|
|
+ data_quality: Mapped[str] = mapped_column(
|
|
|
+ String(24), nullable=False, default="available"
|
|
|
+ )
|
|
|
+ created_at: Mapped[datetime] = mapped_column(
|
|
|
+ DateTime, nullable=False, server_default=func.now()
|
|
|
+ )
|
|
|
+
|
|
|
+
|
|
|
+class StandardDemandTerm(Base):
|
|
|
+ """Canonical term with stable identity across daily runs."""
|
|
|
+
|
|
|
+ __tablename__ = "standard_demand_term"
|
|
|
+ __table_args__ = (
|
|
|
+ UniqueConstraint("canonical_key", name="uk_standard_demand_term_key"),
|
|
|
+ Index("idx_standard_demand_term_text", "normalized_text"),
|
|
|
+ )
|
|
|
+
|
|
|
+ term_id: Mapped[str] = mapped_column(String(36), primary_key=True)
|
|
|
+ canonical_key: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
|
+ canonical_text: Mapped[str] = mapped_column(String(256), nullable=False)
|
|
|
+ normalized_text: Mapped[str] = mapped_column(String(256), nullable=False)
|
|
|
+ status: Mapped[str] = mapped_column(
|
|
|
+ String(24), nullable=False, default="active"
|
|
|
+ )
|
|
|
+ created_at: Mapped[datetime] = mapped_column(
|
|
|
+ DateTime, nullable=False, server_default=func.now()
|
|
|
+ )
|
|
|
+ updated_at: Mapped[datetime] = mapped_column(
|
|
|
+ DateTime, nullable=False, server_default=func.now(), onupdate=func.now()
|
|
|
+ )
|
|
|
+
|
|
|
+
|
|
|
+class StandardDemandAlias(Base):
|
|
|
+ """Traceable relationship from a canonical term to a raw expression."""
|
|
|
+
|
|
|
+ __tablename__ = "standard_demand_alias"
|
|
|
+ __table_args__ = (
|
|
|
+ UniqueConstraint(
|
|
|
+ "term_id",
|
|
|
+ "expression_id",
|
|
|
+ name="uk_standard_demand_alias_expression",
|
|
|
+ ),
|
|
|
+ Index("idx_standard_demand_alias_term", "term_id"),
|
|
|
+ )
|
|
|
+
|
|
|
+ alias_id: Mapped[str] = mapped_column(String(36), primary_key=True)
|
|
|
+ term_id: Mapped[str] = mapped_column(
|
|
|
+ String(36),
|
|
|
+ ForeignKey("standard_demand_term.term_id", ondelete="RESTRICT"),
|
|
|
+ nullable=False,
|
|
|
+ )
|
|
|
+ expression_id: Mapped[str] = mapped_column(
|
|
|
+ String(36),
|
|
|
+ ForeignKey("raw_demand_expression.expression_id", ondelete="RESTRICT"),
|
|
|
+ nullable=False,
|
|
|
+ )
|
|
|
+ alias_text: Mapped[str] = mapped_column(String(512), nullable=False)
|
|
|
+ relation_type: Mapped[str] = mapped_column(
|
|
|
+ String(32), nullable=False, default="source_expression"
|
|
|
+ )
|
|
|
+ confidence: Mapped[Decimal] = mapped_column(
|
|
|
+ Numeric(6, 5), nullable=False, default=1
|
|
|
+ )
|
|
|
+ reason: Mapped[str] = mapped_column(Text, nullable=False)
|
|
|
+ created_at: Mapped[datetime] = mapped_column(
|
|
|
+ DateTime, nullable=False, server_default=func.now()
|
|
|
+ )
|
|
|
+
|
|
|
+
|
|
|
+class PlatformDemand(Base):
|
|
|
+ """Stable business object consumed by scoring, people and agents."""
|
|
|
+
|
|
|
+ __tablename__ = "platform_demand"
|
|
|
+ __table_args__ = (
|
|
|
+ UniqueConstraint("canonical_key", name="uk_platform_demand_key"),
|
|
|
+ Index("idx_platform_demand_name", "name"),
|
|
|
+ Index("idx_platform_demand_status", "status"),
|
|
|
+ )
|
|
|
+
|
|
|
+ platform_demand_id: Mapped[str] = mapped_column(String(36), primary_key=True)
|
|
|
+ canonical_key: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
|
+ name: Mapped[str] = mapped_column(String(256), nullable=False)
|
|
|
+ description: Mapped[str] = mapped_column(Text, nullable=False)
|
|
|
+ status: Mapped[str] = mapped_column(
|
|
|
+ String(24), nullable=False, default="active"
|
|
|
+ )
|
|
|
+ lifecycle_state: Mapped[str] = mapped_column(
|
|
|
+ String(24), nullable=False, default="new"
|
|
|
+ )
|
|
|
+ created_at: Mapped[datetime] = mapped_column(
|
|
|
+ DateTime, nullable=False, server_default=func.now()
|
|
|
+ )
|
|
|
+ updated_at: Mapped[datetime] = mapped_column(
|
|
|
+ DateTime, nullable=False, server_default=func.now(), onupdate=func.now()
|
|
|
+ )
|
|
|
+
|
|
|
+
|
|
|
+class PlatformDemandVersion(Base):
|
|
|
+ """Append-only daily cognition version for a platform demand."""
|
|
|
+
|
|
|
+ __tablename__ = "platform_demand_version"
|
|
|
+ __table_args__ = (
|
|
|
+ UniqueConstraint(
|
|
|
+ "platform_demand_id",
|
|
|
+ "version_no",
|
|
|
+ name="uk_platform_demand_version_no",
|
|
|
+ ),
|
|
|
+ UniqueConstraint(
|
|
|
+ "platform_demand_id",
|
|
|
+ "run_id",
|
|
|
+ name="uk_platform_demand_version_run",
|
|
|
+ ),
|
|
|
+ Index("idx_platform_demand_version_biz", "biz_dt", "run_id"),
|
|
|
+ )
|
|
|
+
|
|
|
+ platform_demand_version_id: Mapped[str] = mapped_column(
|
|
|
+ String(36), primary_key=True
|
|
|
+ )
|
|
|
+ platform_demand_id: Mapped[str] = mapped_column(
|
|
|
+ String(36),
|
|
|
+ ForeignKey("platform_demand.platform_demand_id", ondelete="RESTRICT"),
|
|
|
+ nullable=False,
|
|
|
+ )
|
|
|
+ term_id: Mapped[str] = mapped_column(
|
|
|
+ String(36),
|
|
|
+ ForeignKey("standard_demand_term.term_id", ondelete="RESTRICT"),
|
|
|
+ nullable=False,
|
|
|
+ )
|
|
|
+ package_id: Mapped[str] = mapped_column(
|
|
|
+ String(36),
|
|
|
+ ForeignKey("evidence_package.package_id", ondelete="RESTRICT"),
|
|
|
+ nullable=False,
|
|
|
+ )
|
|
|
+ run_id: Mapped[str] = mapped_column(
|
|
|
+ String(36),
|
|
|
+ ForeignKey("pipeline_run.run_id", ondelete="RESTRICT"),
|
|
|
+ nullable=False,
|
|
|
+ )
|
|
|
+ source_demand_grade_id: Mapped[int] = mapped_column(BigInteger, nullable=False)
|
|
|
+ version_no: Mapped[int] = mapped_column(Integer, nullable=False)
|
|
|
+ biz_dt: Mapped[str] = mapped_column(String(8), nullable=False)
|
|
|
+ name: Mapped[str] = mapped_column(String(256), nullable=False)
|
|
|
+ description: Mapped[str] = mapped_column(Text, nullable=False)
|
|
|
+ cognition_confidence: Mapped[Decimal] = mapped_column(
|
|
|
+ Numeric(6, 5), nullable=False
|
|
|
+ )
|
|
|
+ reason: Mapped[str] = mapped_column(Text, nullable=False)
|
|
|
+ change_type: Mapped[str] = mapped_column(String(24), nullable=False)
|
|
|
+ evidence_hash: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
|
+ created_at: Mapped[datetime] = mapped_column(
|
|
|
+ DateTime, nullable=False, server_default=func.now()
|
|
|
+ )
|
|
|
+
|
|
|
+
|
|
|
+class PlatformDemandCategoryRel(Base):
|
|
|
+ """Versioned graph edge from one platform-demand version to the tree."""
|
|
|
+
|
|
|
+ __tablename__ = "platform_demand_category_rel"
|
|
|
+ __table_args__ = (
|
|
|
+ UniqueConstraint(
|
|
|
+ "platform_demand_version_id",
|
|
|
+ "category_id",
|
|
|
+ "relation_type",
|
|
|
+ name="uk_platform_demand_category_rel",
|
|
|
+ ),
|
|
|
+ Index("idx_platform_demand_category_node", "category_id"),
|
|
|
+ )
|
|
|
+
|
|
|
+ rel_id: Mapped[str] = mapped_column(String(36), primary_key=True)
|
|
|
+ platform_demand_version_id: Mapped[str] = mapped_column(
|
|
|
+ String(36),
|
|
|
+ ForeignKey(
|
|
|
+ "platform_demand_version.platform_demand_version_id",
|
|
|
+ ondelete="RESTRICT",
|
|
|
+ ),
|
|
|
+ nullable=False,
|
|
|
+ )
|
|
|
+ category_id: Mapped[int] = mapped_column(BigInteger, nullable=False)
|
|
|
+ relation_type: Mapped[str] = mapped_column(String(32), nullable=False)
|
|
|
+ relation_source: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
|
+ reason: Mapped[str] = mapped_column(Text, nullable=False)
|
|
|
+ confidence: Mapped[Decimal] = mapped_column(
|
|
|
+ Numeric(6, 5), nullable=False
|
|
|
+ )
|
|
|
+ is_inferred: Mapped[bool] = mapped_column(
|
|
|
+ Boolean, nullable=False, default=False
|
|
|
+ )
|
|
|
+ status: Mapped[str] = mapped_column(
|
|
|
+ String(24), nullable=False, default="active"
|
|
|
+ )
|
|
|
+ valid_from_biz_dt: Mapped[str] = mapped_column(String(8), nullable=False)
|
|
|
+ created_at: Mapped[datetime] = mapped_column(
|
|
|
+ DateTime, nullable=False, server_default=func.now()
|
|
|
+ )
|
|
|
+
|
|
|
+
|
|
|
+class StrategyVersion(Base):
|
|
|
+ """Versioned scoring and allocation policy; published versions are immutable."""
|
|
|
+
|
|
|
+ __tablename__ = "strategy_version"
|
|
|
+ __table_args__ = (
|
|
|
+ UniqueConstraint("version_key", name="uk_strategy_version_key"),
|
|
|
+ Index("idx_strategy_version_status", "status", "activated_at"),
|
|
|
+ )
|
|
|
+
|
|
|
+ strategy_version_id: Mapped[str] = mapped_column(String(36), primary_key=True)
|
|
|
+ version_key: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
|
+ status: Mapped[str] = mapped_column(String(24), nullable=False)
|
|
|
+ definition_json: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
|
|
|
+ change_reason: Mapped[str] = mapped_column(Text, nullable=False)
|
|
|
+ created_by: Mapped[str] = mapped_column(String(128), nullable=False)
|
|
|
+ activated_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
|
|
|
+ created_at: Mapped[datetime] = mapped_column(
|
|
|
+ DateTime, nullable=False, server_default=func.now()
|
|
|
+ )
|
|
|
+
|
|
|
+
|
|
|
+class DemandEvaluationSnapshot(Base):
|
|
|
+ """Two reproducible 0-1 decisions for one platform-demand version."""
|
|
|
+
|
|
|
+ __tablename__ = "demand_evaluation_snapshot"
|
|
|
+ __table_args__ = (
|
|
|
+ UniqueConstraint(
|
|
|
+ "platform_demand_version_id",
|
|
|
+ name="uk_demand_evaluation_version",
|
|
|
+ ),
|
|
|
+ Index("idx_demand_evaluation_biz", "biz_dt", "action_tier"),
|
|
|
+ )
|
|
|
+
|
|
|
+ evaluation_id: Mapped[str] = mapped_column(String(36), primary_key=True)
|
|
|
+ platform_demand_version_id: Mapped[str] = mapped_column(
|
|
|
+ String(36),
|
|
|
+ ForeignKey(
|
|
|
+ "platform_demand_version.platform_demand_version_id",
|
|
|
+ ondelete="RESTRICT",
|
|
|
+ ),
|
|
|
+ nullable=False,
|
|
|
+ )
|
|
|
+ run_id: Mapped[str] = mapped_column(
|
|
|
+ String(36),
|
|
|
+ ForeignKey("pipeline_run.run_id", ondelete="RESTRICT"),
|
|
|
+ nullable=False,
|
|
|
+ )
|
|
|
+ strategy_version_id: Mapped[str] = mapped_column(
|
|
|
+ String(36),
|
|
|
+ ForeignKey("strategy_version.strategy_version_id", ondelete="RESTRICT"),
|
|
|
+ nullable=False,
|
|
|
+ )
|
|
|
+ biz_dt: Mapped[str] = mapped_column(String(8), nullable=False)
|
|
|
+ validity_score: Mapped[Decimal] = mapped_column(Numeric(6, 5), nullable=False)
|
|
|
+ local_supply_priority: Mapped[Decimal] = mapped_column(
|
|
|
+ Numeric(6, 5), nullable=False
|
|
|
+ )
|
|
|
+ data_confidence: Mapped[Decimal] = mapped_column(Numeric(6, 5), nullable=False)
|
|
|
+ posterior_state: Mapped[str] = mapped_column(String(24), nullable=False)
|
|
|
+ action_tier: Mapped[str] = mapped_column(String(32), nullable=False)
|
|
|
+ metrics_json: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
|
|
|
+ missing_dimensions_json: Mapped[list[str]] = mapped_column(JSON, nullable=False)
|
|
|
+ decision_reason: Mapped[str] = mapped_column(Text, nullable=False)
|
|
|
+ created_at: Mapped[datetime] = mapped_column(
|
|
|
+ DateTime, nullable=False, server_default=func.now()
|
|
|
+ )
|
|
|
+
|
|
|
+
|
|
|
+class DemandScoreContribution(Base):
|
|
|
+ """Expandable score contribution; contributions sum to the stored score."""
|
|
|
+
|
|
|
+ __tablename__ = "demand_score_contribution"
|
|
|
+ __table_args__ = (
|
|
|
+ UniqueConstraint(
|
|
|
+ "evaluation_id",
|
|
|
+ "score_type",
|
|
|
+ "dimension",
|
|
|
+ name="uk_demand_score_contribution",
|
|
|
+ ),
|
|
|
+ Index("idx_demand_score_contribution_eval", "evaluation_id"),
|
|
|
+ )
|
|
|
+
|
|
|
+ contribution_id: Mapped[str] = mapped_column(String(36), primary_key=True)
|
|
|
+ evaluation_id: Mapped[str] = mapped_column(
|
|
|
+ String(36),
|
|
|
+ ForeignKey("demand_evaluation_snapshot.evaluation_id", ondelete="RESTRICT"),
|
|
|
+ nullable=False,
|
|
|
+ )
|
|
|
+ score_type: Mapped[str] = mapped_column(String(24), nullable=False)
|
|
|
+ dimension: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
|
+ raw_value_json: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
|
|
|
+ normalized_value: Mapped[Decimal] = mapped_column(
|
|
|
+ Numeric(8, 7), nullable=False
|
|
|
+ )
|
|
|
+ configured_weight: Mapped[Decimal] = mapped_column(
|
|
|
+ Numeric(8, 7), nullable=False
|
|
|
+ )
|
|
|
+ effective_weight: Mapped[Decimal] = mapped_column(
|
|
|
+ Numeric(8, 7), nullable=False
|
|
|
+ )
|
|
|
+ contribution: Mapped[Decimal] = mapped_column(Numeric(8, 7), nullable=False)
|
|
|
+ data_status: Mapped[str] = mapped_column(String(24), nullable=False)
|
|
|
+ reason: Mapped[str] = mapped_column(Text, nullable=False)
|
|
|
+ created_at: Mapped[datetime] = mapped_column(
|
|
|
+ DateTime, nullable=False, server_default=func.now()
|
|
|
+ )
|
|
|
+
|
|
|
+
|
|
|
+class DailyDemandPackage(Base):
|
|
|
+ """The only published daily contract shared by people and agents."""
|
|
|
+
|
|
|
+ __tablename__ = "daily_demand_package"
|
|
|
+ __table_args__ = (
|
|
|
+ UniqueConstraint("run_id", name="uk_daily_demand_package_run"),
|
|
|
+ Index("idx_daily_demand_package_biz", "biz_dt", "status"),
|
|
|
+ )
|
|
|
+
|
|
|
+ demand_package_id: Mapped[str] = mapped_column(String(36), primary_key=True)
|
|
|
+ run_id: Mapped[str] = mapped_column(
|
|
|
+ String(36),
|
|
|
+ ForeignKey("pipeline_run.run_id", ondelete="RESTRICT"),
|
|
|
+ nullable=False,
|
|
|
+ )
|
|
|
+ evidence_package_id: Mapped[str] = mapped_column(
|
|
|
+ String(36),
|
|
|
+ ForeignKey("evidence_package.package_id", ondelete="RESTRICT"),
|
|
|
+ nullable=False,
|
|
|
+ )
|
|
|
+ strategy_version_id: Mapped[str] = mapped_column(
|
|
|
+ String(36),
|
|
|
+ ForeignKey("strategy_version.strategy_version_id", ondelete="RESTRICT"),
|
|
|
+ nullable=False,
|
|
|
+ )
|
|
|
+ biz_dt: Mapped[str] = mapped_column(String(8), nullable=False)
|
|
|
+ package_version: Mapped[int] = mapped_column(Integer, nullable=False)
|
|
|
+ status: Mapped[str] = mapped_column(String(24), nullable=False)
|
|
|
+ content_hash: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
|
+ item_count: Mapped[int] = mapped_column(Integer, nullable=False)
|
|
|
+ published_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
|
|
|
+ created_at: Mapped[datetime] = mapped_column(
|
|
|
+ DateTime, nullable=False, server_default=func.now()
|
|
|
+ )
|
|
|
+
|
|
|
+
|
|
|
+class DailyDemandTask(Base):
|
|
|
+ """Immutable agent/human task view for one evaluated demand."""
|
|
|
+
|
|
|
+ __tablename__ = "daily_demand_task"
|
|
|
+ __table_args__ = (
|
|
|
+ UniqueConstraint(
|
|
|
+ "demand_package_id",
|
|
|
+ "platform_demand_version_id",
|
|
|
+ name="uk_daily_demand_task_version",
|
|
|
+ ),
|
|
|
+ Index("idx_daily_demand_task_tier", "demand_package_id", "action_tier"),
|
|
|
+ )
|
|
|
+
|
|
|
+ task_id: Mapped[str] = mapped_column(String(36), primary_key=True)
|
|
|
+ demand_package_id: Mapped[str] = mapped_column(
|
|
|
+ String(36),
|
|
|
+ ForeignKey("daily_demand_package.demand_package_id", ondelete="RESTRICT"),
|
|
|
+ nullable=False,
|
|
|
+ )
|
|
|
+ platform_demand_version_id: Mapped[str] = mapped_column(
|
|
|
+ String(36),
|
|
|
+ ForeignKey(
|
|
|
+ "platform_demand_version.platform_demand_version_id",
|
|
|
+ ondelete="RESTRICT",
|
|
|
+ ),
|
|
|
+ nullable=False,
|
|
|
+ )
|
|
|
+ evaluation_id: Mapped[str] = mapped_column(
|
|
|
+ String(36),
|
|
|
+ ForeignKey("demand_evaluation_snapshot.evaluation_id", ondelete="RESTRICT"),
|
|
|
+ nullable=False,
|
|
|
+ )
|
|
|
+ action_tier: Mapped[str] = mapped_column(String(32), nullable=False)
|
|
|
+ search_terms_json: Mapped[list[str]] = mapped_column(JSON, nullable=False)
|
|
|
+ exclude_terms_json: Mapped[list[str]] = mapped_column(JSON, nullable=False)
|
|
|
+ hit_rules_json: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
|
|
|
+ hypotheses_json: Mapped[list[str]] = mapped_column(JSON, nullable=False)
|
|
|
+ evidence_gaps_json: Mapped[list[str]] = mapped_column(JSON, nullable=False)
|
|
|
+ existing_content_json: Mapped[list[str]] = mapped_column(JSON, nullable=False)
|
|
|
+ allocation_json: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
|
|
|
+ task_payload_json: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
|
|
|
+ created_at: Mapped[datetime] = mapped_column(
|
|
|
+ DateTime, nullable=False, server_default=func.now()
|
|
|
+ )
|
|
|
+
|
|
|
+
|
|
|
+class ContentDemandCoverage(Base):
|
|
|
+ """Many-to-many content coverage edge linked to a published task."""
|
|
|
+
|
|
|
+ __tablename__ = "content_demand_coverage"
|
|
|
+ __table_args__ = (
|
|
|
+ UniqueConstraint(
|
|
|
+ "platform_demand_version_id",
|
|
|
+ "content_id",
|
|
|
+ "coverage_role",
|
|
|
+ name="uk_content_demand_coverage",
|
|
|
+ ),
|
|
|
+ Index("idx_content_demand_coverage_content", "content_id"),
|
|
|
+ )
|
|
|
+
|
|
|
+ coverage_id: Mapped[str] = mapped_column(String(36), primary_key=True)
|
|
|
+ platform_demand_version_id: Mapped[str] = mapped_column(
|
|
|
+ String(36),
|
|
|
+ ForeignKey(
|
|
|
+ "platform_demand_version.platform_demand_version_id",
|
|
|
+ ondelete="RESTRICT",
|
|
|
+ ),
|
|
|
+ nullable=False,
|
|
|
+ )
|
|
|
+ task_id: Mapped[str] = mapped_column(
|
|
|
+ String(36),
|
|
|
+ ForeignKey("daily_demand_task.task_id", ondelete="RESTRICT"),
|
|
|
+ nullable=False,
|
|
|
+ )
|
|
|
+ content_id: Mapped[str] = mapped_column(String(128), nullable=False)
|
|
|
+ content_url: Mapped[str | None] = mapped_column(String(1024), nullable=True)
|
|
|
+ source_type: Mapped[str] = mapped_column(String(32), nullable=False)
|
|
|
+ coverage_role: Mapped[str] = mapped_column(String(24), nullable=False)
|
|
|
+ coverage_score: Mapped[Decimal] = mapped_column(Numeric(6, 5), nullable=False)
|
|
|
+ evidence_json: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
|
|
|
+ status: Mapped[str] = mapped_column(String(24), nullable=False)
|
|
|
+ discovered_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
|
|
|
+ content_published_at: Mapped[datetime | None] = mapped_column(
|
|
|
+ DateTime, nullable=True
|
|
|
+ )
|
|
|
+ created_at: Mapped[datetime] = mapped_column(
|
|
|
+ DateTime, nullable=False, server_default=func.now()
|
|
|
+ )
|
|
|
+
|
|
|
+
|
|
|
+class ContentPerformanceFact(Base):
|
|
|
+ """Immutable raw content performance observation."""
|
|
|
+
|
|
|
+ __tablename__ = "content_performance_fact"
|
|
|
+ __table_args__ = (
|
|
|
+ UniqueConstraint(
|
|
|
+ "content_id",
|
|
|
+ "biz_dt",
|
|
|
+ "source",
|
|
|
+ "payload_hash",
|
|
|
+ name="uk_content_performance_fact",
|
|
|
+ ),
|
|
|
+ Index("idx_content_performance_fact_content", "content_id", "biz_dt"),
|
|
|
+ )
|
|
|
+
|
|
|
+ performance_fact_id: Mapped[str] = mapped_column(String(36), primary_key=True)
|
|
|
+ content_id: Mapped[str] = mapped_column(String(128), nullable=False)
|
|
|
+ biz_dt: Mapped[str] = mapped_column(String(8), nullable=False)
|
|
|
+ source: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
|
+ payload_hash: Mapped[str] = mapped_column(String(64), nullable=False)
|
|
|
+ exposure_count: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
|
|
|
+ sample_size: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
|
|
|
+ content_quality: Mapped[Decimal | None] = mapped_column(
|
|
|
+ Numeric(6, 5), nullable=True
|
|
|
+ )
|
|
|
+ rov: Mapped[Decimal | None] = mapped_column(Numeric(16, 8), nullable=True)
|
|
|
+ vov: Mapped[Decimal | None] = mapped_column(Numeric(16, 8), nullable=True)
|
|
|
+ raw_payload_json: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
|
|
|
+ observed_at: Mapped[datetime] = mapped_column(DateTime, nullable=False)
|
|
|
+ created_at: Mapped[datetime] = mapped_column(
|
|
|
+ DateTime, nullable=False, server_default=func.now()
|
|
|
+ )
|
|
|
+
|
|
|
+
|
|
|
+class DemandAttributionSnapshot(Base):
|
|
|
+ """Reproducible attribution from one content fact to one demand version."""
|
|
|
+
|
|
|
+ __tablename__ = "demand_attribution_snapshot"
|
|
|
+ __table_args__ = (
|
|
|
+ UniqueConstraint(
|
|
|
+ "coverage_id",
|
|
|
+ "performance_fact_id",
|
|
|
+ "strategy_version_id",
|
|
|
+ name="uk_demand_attribution_snapshot",
|
|
|
+ ),
|
|
|
+ Index(
|
|
|
+ "idx_demand_attribution_version",
|
|
|
+ "platform_demand_version_id",
|
|
|
+ "created_at",
|
|
|
+ ),
|
|
|
+ )
|
|
|
+
|
|
|
+ attribution_id: Mapped[str] = mapped_column(String(36), primary_key=True)
|
|
|
+ platform_demand_version_id: Mapped[str] = mapped_column(
|
|
|
+ String(36),
|
|
|
+ ForeignKey(
|
|
|
+ "platform_demand_version.platform_demand_version_id",
|
|
|
+ ondelete="RESTRICT",
|
|
|
+ ),
|
|
|
+ nullable=False,
|
|
|
+ )
|
|
|
+ coverage_id: Mapped[str] = mapped_column(
|
|
|
+ String(36),
|
|
|
+ ForeignKey("content_demand_coverage.coverage_id", ondelete="RESTRICT"),
|
|
|
+ nullable=False,
|
|
|
+ )
|
|
|
+ performance_fact_id: Mapped[str] = mapped_column(
|
|
|
+ String(36),
|
|
|
+ ForeignKey(
|
|
|
+ "content_performance_fact.performance_fact_id",
|
|
|
+ ondelete="RESTRICT",
|
|
|
+ ),
|
|
|
+ nullable=False,
|
|
|
+ )
|
|
|
+ strategy_version_id: Mapped[str] = mapped_column(
|
|
|
+ String(36),
|
|
|
+ ForeignKey("strategy_version.strategy_version_id", ondelete="RESTRICT"),
|
|
|
+ nullable=False,
|
|
|
+ )
|
|
|
+ support_state: Mapped[str] = mapped_column(String(24), nullable=False)
|
|
|
+ attributable_rov: Mapped[Decimal | None] = mapped_column(
|
|
|
+ Numeric(16, 8), nullable=True
|
|
|
+ )
|
|
|
+ attributable_vov: Mapped[Decimal | None] = mapped_column(
|
|
|
+ Numeric(16, 8), nullable=True
|
|
|
+ )
|
|
|
+ attribution_confidence: Mapped[Decimal] = mapped_column(
|
|
|
+ Numeric(6, 5), nullable=False
|
|
|
+ )
|
|
|
+ validity_influence: Mapped[Decimal] = mapped_column(
|
|
|
+ Numeric(8, 7), nullable=False
|
|
|
+ )
|
|
|
+ priority_influence: Mapped[Decimal] = mapped_column(
|
|
|
+ Numeric(8, 7), nullable=False
|
|
|
+ )
|
|
|
+ reason: Mapped[str] = mapped_column(Text, nullable=False)
|
|
|
+ created_at: Mapped[datetime] = mapped_column(
|
|
|
+ DateTime, nullable=False, server_default=func.now()
|
|
|
+ )
|
|
|
+
|
|
|
+
|
|
|
+class StrategyChangeProposal(Base):
|
|
|
+ """Draft/preview/approval workflow for changing business strategy."""
|
|
|
+
|
|
|
+ __tablename__ = "strategy_change_proposal"
|
|
|
+ __table_args__ = (Index("idx_strategy_proposal_status", "status", "created_at"),)
|
|
|
+
|
|
|
+ proposal_id: Mapped[str] = mapped_column(String(36), primary_key=True)
|
|
|
+ base_strategy_version_id: Mapped[str] = mapped_column(
|
|
|
+ String(36),
|
|
|
+ ForeignKey("strategy_version.strategy_version_id", ondelete="RESTRICT"),
|
|
|
+ nullable=False,
|
|
|
+ )
|
|
|
+ status: Mapped[str] = mapped_column(String(24), nullable=False)
|
|
|
+ requested_change_json: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
|
|
|
+ proposed_definition_json: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
|
|
|
+ diff_json: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False)
|
|
|
+ preview_json: Mapped[dict[str, Any] | None] = mapped_column(JSON, nullable=True)
|
|
|
+ reason: Mapped[str] = mapped_column(Text, nullable=False)
|
|
|
+ created_by: Mapped[str] = mapped_column(String(128), nullable=False)
|
|
|
+ approved_by: Mapped[str | None] = mapped_column(String(128), nullable=True)
|
|
|
+ approved_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
|
|
|
+ created_at: Mapped[datetime] = mapped_column(
|
|
|
+ DateTime, nullable=False, server_default=func.now()
|
|
|
+ )
|