Add Phase 2 durable workstation agent job routing

This commit is contained in:
A R R R Associates
2026-08-22 11:50:20 +05:30
parent c8b7dcb805
commit f7bf1437ef
9 changed files with 657 additions and 10 deletions
+56
View File
@@ -218,6 +218,62 @@ class ERPWorkstationAgent(CommonBase):
storage_node = relationship("BranchStorageNode")
class ERPAgentJob(CommonBase):
"""Durable server-side job routed to one specific ERP workstation agent."""
__tablename__ = "erp_agent_jobs"
__table_args__ = (
UniqueConstraint("job_uuid", name="uq_erp_agent_jobs_uuid"),
UniqueConstraint("workstation_agent_id", "idempotency_key", name="uq_erp_agent_jobs_workstation_idempotency"),
)
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
job_uuid: Mapped[str] = mapped_column(String(64), nullable=False, index=True)
tenant_id: Mapped[int] = mapped_column(ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False, index=True)
branch_id: Mapped[int | None] = mapped_column(ForeignKey("branches.id", ondelete="SET NULL"), nullable=True, index=True)
storage_node_id: Mapped[int] = mapped_column(ForeignKey("branch_storage_nodes.id", ondelete="CASCADE"), nullable=False, index=True)
workstation_agent_id: Mapped[int] = mapped_column(ForeignKey("erp_workstation_agents.id", ondelete="CASCADE"), nullable=False, index=True)
action: Mapped[str] = mapped_column(String(120), nullable=False, index=True)
payload_json: Mapped[str] = mapped_column(Text, nullable=False, default="{}")
idempotency_key: Mapped[str | None] = mapped_column(String(200), nullable=True, index=True)
status: Mapped[str] = mapped_column(String(30), nullable=False, default="queued", index=True)
priority: Mapped[int] = mapped_column(Integer, nullable=False, default=5, index=True)
max_attempts: Mapped[int] = mapped_column(Integer, nullable=False, default=3)
attempts: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
last_error: Mapped[str | None] = mapped_column(Text, nullable=True)
result_json: Mapped[str | None] = mapped_column(Text, nullable=True)
created_by_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"), nullable=True, index=True)
created_at_utc: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), nullable=False, index=True)
updated_at_utc: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), nullable=False)
claimed_at_utc: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True, index=True)
lease_expires_at_utc: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True, index=True)
agent_completed_at_utc: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
completed_at_utc: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True, index=True)
failed_at_utc: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True, index=True)
cancelled_at_utc: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True, index=True)
workstation = relationship("ERPWorkstationAgent")
storage_node = relationship("BranchStorageNode")
class ERPAgentJobEvent(CommonBase):
"""Immutable audit event for an ERP workstation-agent job."""
__tablename__ = "erp_agent_job_events"
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
job_id: Mapped[int] = mapped_column(ForeignKey("erp_agent_jobs.id", ondelete="CASCADE"), nullable=False, index=True)
tenant_id: Mapped[int] = mapped_column(ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False, index=True)
branch_id: Mapped[int | None] = mapped_column(ForeignKey("branches.id", ondelete="SET NULL"), nullable=True, index=True)
workstation_agent_id: Mapped[int] = mapped_column(ForeignKey("erp_workstation_agents.id", ondelete="CASCADE"), nullable=False, index=True)
event_type: Mapped[str] = mapped_column(String(40), nullable=False, index=True)
detail: Mapped[str | None] = mapped_column(Text, nullable=True)
actor_user_id: Mapped[int | None] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"), nullable=True, index=True)
occurred_at_utc: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), nullable=False, index=True)
job = relationship("ERPAgentJob")
class DocumentStorageJob(CommonBase):
"""Cloud-to-local branch storage transfer job.