feat: central RTC write modes (DISABLED/DRY_RUN/APPROVAL/ENABLED), R4 suggestion-only, preview/approval, per-record rollback, bulk blocker upsert; 1.2.0
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+31
-1
@@ -283,7 +283,8 @@ class Installation(Base):
|
||||
last_sync_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
last_sync_changed: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
||||
# RTC auto-apply is authorized centrally per installation and is OFF until an operator explicitly turns it on (the Agent has its own second switch).
|
||||
rtc_auto_apply_authorized: Mapped[bool] = mapped_column(Boolean, default=False, server_default="false")
|
||||
rtc_auto_apply_authorized: Mapped[bool] = mapped_column(Boolean, default=False, server_default="false") # legacy (0027); rtc_write_mode is the source of truth
|
||||
rtc_write_mode: Mapped[str] = mapped_column(String(24), default="DISABLED", server_default="DISABLED") # DISABLED | DRY_RUN | APPROVAL_REQUIRED | ENABLED
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
||||
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
|
||||
|
||||
@@ -755,4 +756,33 @@ class RtcWriteAudit(Base):
|
||||
official_source_version: Mapped[dict] = mapped_column(JSON, default=dict)
|
||||
local_catalog_hash: Mapped[str | None] = mapped_column(String(64), nullable=True)
|
||||
written_at: Mapped[str | None] = mapped_column(String(40), nullable=True)
|
||||
rule_version: Mapped[str | None] = mapped_column(String(32), nullable=True)
|
||||
company_crt: Mapped[str | None] = mapped_column(String(8), nullable=True)
|
||||
authorization_origin: Mapped[str | None] = mapped_column(String(48), nullable=True)
|
||||
description_snapshot: Mapped[str | None] = mapped_column(String(255), nullable=True)
|
||||
installation_uuid: Mapped[str | None] = mapped_column(String(64), nullable=True)
|
||||
rtc_status: Mapped[str | None] = mapped_column(String(24), nullable=True)
|
||||
local_catalog_state: Mapped[str | None] = mapped_column(String(32), nullable=True)
|
||||
action: Mapped[str | None] = mapped_column(String(16), nullable=True) # APPLY | ROLLBACK
|
||||
rollback_state: Mapped[str | None] = mapped_column(String(16), nullable=True) # REQUESTED | DONE | BLOCKED (on the original APPLY record)
|
||||
rollback_of: Mapped[int | None] = mapped_column(Integer, nullable=True, index=True)
|
||||
recorded_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now(), index=True)
|
||||
|
||||
|
||||
class RtcCandidate(Base):
|
||||
"""Server-side preview of the products the Agent could fill (R3 only). Rows are proposals; only the Agent's re-derivation at write time decides."""
|
||||
__tablename__ = "rtc_candidates"
|
||||
__table_args__ = (UniqueConstraint("installation_id", "product_code", name="uq_rtc_candidate_product"),)
|
||||
id: Mapped[int] = mapped_column(primary_key=True)
|
||||
tenant_id: Mapped[int] = mapped_column(ForeignKey("tenants.id"), index=True)
|
||||
installation_id: Mapped[int] = mapped_column(ForeignKey("installations.id"), index=True)
|
||||
product_code: Mapped[str] = mapped_column(String(64))
|
||||
description: Mapped[str | None] = mapped_column(String(255), nullable=True)
|
||||
ncm: Mapped[str | None] = mapped_column(String(16), nullable=True)
|
||||
current_value: Mapped[str | None] = mapped_column(String(16), nullable=True)
|
||||
proposed: Mapped[str] = mapped_column(String(16))
|
||||
cst_ibscbs: Mapped[str | None] = mapped_column(String(8), nullable=True)
|
||||
rule_id: Mapped[str] = mapped_column(String(32))
|
||||
basis: Mapped[str | None] = mapped_column(String(255), nullable=True)
|
||||
status: Mapped[str] = mapped_column(String(16), default="PENDING", server_default="PENDING", index=True) # PENDING | APPROVED | REJECTED | APPLIED | STALE
|
||||
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
|
||||
|
||||
Reference in New Issue
Block a user