Add Phase 2 durable workstation agent job routing
This commit is contained in:
@@ -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.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user