feat(platform): close AI expense value loop
Add tenant-safe value, telemetry, connector, commercial, and production-readiness foundations.
This commit is contained in:
@@ -50,6 +50,7 @@ def build_client() -> tuple[TestClient, sessionmaker[Session]]:
|
||||
def seed_employee(db: Session) -> None:
|
||||
manager = Employee(
|
||||
id="steward-action-manager",
|
||||
tenant_id="tenant-steward-action",
|
||||
employee_no="E90000",
|
||||
name="李总",
|
||||
email="leader@example.com",
|
||||
@@ -58,6 +59,7 @@ def seed_employee(db: Session) -> None:
|
||||
)
|
||||
employee = Employee(
|
||||
id="steward-action-employee",
|
||||
tenant_id="tenant-steward-action",
|
||||
employee_no="E90001",
|
||||
name="张三",
|
||||
email="zhangsan@example.com",
|
||||
@@ -166,6 +168,7 @@ def issue_application_preview(
|
||||
def seed_approved_application(db: Session) -> None:
|
||||
application = ExpenseClaim(
|
||||
id="application-action-approved",
|
||||
tenant_id="tenant-steward-action",
|
||||
claim_no="AAPPROVED1",
|
||||
employee_id="steward-action-employee",
|
||||
employee_name="张三",
|
||||
@@ -252,7 +255,10 @@ def test_steward_action_executor_records_pending_interrupt_in_conversation_state
|
||||
headers=auth_headers(),
|
||||
json={
|
||||
"action_type": "submit_application",
|
||||
"message": "2026-02-20 至 2026-02-23,去上海出差,辅助国网仿生产服务器部署,交通火车,直接提交",
|
||||
"message": (
|
||||
"2026-02-20 至 2026-02-23,去上海出差,"
|
||||
"辅助国网仿生产服务器部署,交通火车,直接提交"
|
||||
),
|
||||
"conversation_id": "conv-action-submit",
|
||||
"client_trace_id": "trace-submit-pending",
|
||||
"task": base_application_task("submit"),
|
||||
@@ -368,7 +374,8 @@ def test_steward_action_checkpoint_does_not_replay_across_tenants() -> None:
|
||||
}
|
||||
|
||||
|
||||
def test_steward_action_executor_reuses_checkpoint_for_duplicate_trace_without_duplicate_draft() -> None:
|
||||
def test_steward_action_executor_reuses_checkpoint_for_duplicate_trace_without_duplicate_draft(
|
||||
) -> None:
|
||||
client, session_factory = build_client()
|
||||
with session_factory() as db:
|
||||
seed_employee(db)
|
||||
@@ -380,7 +387,10 @@ def test_steward_action_executor_reuses_checkpoint_for_duplicate_trace_without_d
|
||||
)
|
||||
request_payload = {
|
||||
"action_type": "save_application_draft",
|
||||
"message": "2026-02-20 至 2026-02-23,去上海出差,辅助国网仿生产服务器部署,交通火车,保存草稿",
|
||||
"message": (
|
||||
"2026-02-20 至 2026-02-23,去上海出差,"
|
||||
"辅助国网仿生产服务器部署,交通火车,保存草稿"
|
||||
),
|
||||
"conversation_id": "conv-action-draft",
|
||||
"client_trace_id": "trace-save-draft",
|
||||
"decision_id": issued["decision_id"],
|
||||
@@ -425,7 +435,10 @@ def test_steward_action_executor_requires_confirmation_before_submit_side_effect
|
||||
headers=auth_headers(),
|
||||
json={
|
||||
"action_type": "submit_application",
|
||||
"message": "2026-02-20 至 2026-02-23,去上海出差,辅助国网仿生产服务器部署,交通火车,直接提交",
|
||||
"message": (
|
||||
"2026-02-20 至 2026-02-23,去上海出差,"
|
||||
"辅助国网仿生产服务器部署,交通火车,直接提交"
|
||||
),
|
||||
"task": base_application_task("submit"),
|
||||
"confirmed": False,
|
||||
"context_json": {
|
||||
@@ -460,7 +473,10 @@ def test_steward_action_executor_saves_application_draft_from_action_step() -> N
|
||||
headers=auth_headers(),
|
||||
json={
|
||||
"action_type": "save_application_draft",
|
||||
"message": "2026-02-20 至 2026-02-23,去上海出差,辅助国网仿生产服务器部署,交通火车,保存草稿",
|
||||
"message": (
|
||||
"2026-02-20 至 2026-02-23,去上海出差,"
|
||||
"辅助国网仿生产服务器部署,交通火车,保存草稿"
|
||||
),
|
||||
"conversation_id": "conv-action-save",
|
||||
"client_trace_id": "trace-save-application-action",
|
||||
"decision_id": issued["decision_id"],
|
||||
@@ -541,7 +557,8 @@ def test_steward_action_executor_blocks_save_without_decision_and_stable_trace()
|
||||
assert claim_count(db) == 0
|
||||
|
||||
|
||||
def test_steward_action_executor_submits_verified_application_after_confirmation_and_precheck() -> None:
|
||||
def test_steward_action_executor_submits_verified_application_after_confirmation_and_precheck(
|
||||
) -> None:
|
||||
client, session_factory = build_client()
|
||||
with session_factory() as db:
|
||||
seed_employee(db)
|
||||
|
||||
Reference in New Issue
Block a user