Files
aiagent/backend/app/models/company_project_event.py
renjianbo 495eafcd78 feat: virtual company M2 control + tier-3/4 capabilities + per-dept session fix
- M2-a/b/c: stop/pause/resume/skip dept, plan/rework approval gates,
  budget & timeout circuit breakers, per-dept cancel and on-demand rework
- tier-3: batched event persistence (_EventBuffer), project/dept
  concurrency semaphores, company_ws event streaming
- tier-4: cross-dept deliverable handoff, CEO memory feedback loop,
  per-dept model override, one-click Markdown report export (RFC5987)
- fix: per-department independent SQLAlchemy session in parallel waves
  (shared Session race across asyncio tasks in company_orchestrator)
- fix: rename process_open_fds gauge to app_process_open_fds
  (collides with prometheus_client ProcessCollector on Linux)
- fix: dept role resolution ladder, real token usage & cost tracking,
  deliverable file capture (mtime scan of dept workspace)
- tests: test_company_orchestrator.py 22 cases with mocked LLM
- frontend: CompanyControlRoom, companyExecution store, EChart,
  dept model config dialog, ws proxy, build/typecheck decoupling
- docs: virtual company design/usage docs, M2 control plan,
  deepseek4pro handover docs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-26 18:16:39 +08:00

45 lines
1.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
公司级项目执行事件 — 白盒控制室的持久事件流
每条编排事件(CEO 规划 / 部门 ReAct / 打分 / 完成…)落一行,
供控制室按 seq 回放、断线恢复、审计。表由 create_all 自动创建。
"""
from sqlalchemy import Column, String, Integer, DateTime, JSON, ForeignKey, Index, func
from sqlalchemy.dialects.mysql import CHAR
from app.core.database import Base
import uuid
class CompanyProjectEvent(Base):
"""公司项目执行事件(一次编排 = 一串按 seq 递增的事件)。"""
__tablename__ = "company_project_events"
id = Column(CHAR(36), primary_key=True, default=lambda: str(uuid.uuid4()), comment="事件ID")
project_id = Column(
CHAR(36),
ForeignKey("company_projects.id", ondelete="CASCADE"),
nullable=False,
comment="所属项目ID",
)
seq = Column(Integer, nullable=False, comment="项目内自增序号,从 1")
type = Column(String(50), nullable=False, comment="事件类型")
payload = Column(JSON, nullable=True, comment="事件负载(原编排事件字段)")
created_at = Column(DateTime, default=func.now(), comment="落库时间")
__table_args__ = (
Index("idx_cpe_project_seq", "project_id", "seq"),
)
def __repr__(self):
return f"<CompanyProjectEvent(project_id={self.project_id}, seq={self.seq}, type={self.type})>"
def to_envelope(self) -> dict:
"""转为前端消费的事件信封。"""
return {
"seq": self.seq,
"pid": self.project_id,
"type": self.type,
"payload": self.payload,
"ts": self.created_at.timestamp() if self.created_at else None,
}