refactor(server): split oversized backend services
This commit is contained in:
400
server/src/app/services/agent_foundation_spreadsheets.py
Normal file
400
server/src/app/services/agent_foundation_spreadsheets.py
Normal file
@@ -0,0 +1,400 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
from datetime import UTC, date, datetime
|
||||
from decimal import Decimal
|
||||
from pathlib import Path
|
||||
|
||||
from sqlalchemy import inspect, select, text
|
||||
|
||||
from app.core.agent_enums import (
|
||||
AgentAssetContentType,
|
||||
AgentAssetDomain,
|
||||
AgentAssetStatus,
|
||||
AgentAssetType,
|
||||
AgentName,
|
||||
AgentPermissionLevel,
|
||||
AgentReviewStatus,
|
||||
AgentRunSource,
|
||||
AgentRunStatus,
|
||||
AgentToolType,
|
||||
)
|
||||
from app.models.agent_asset import AgentAsset, AgentAssetReview, AgentAssetVersion
|
||||
from app.models.agent_run import AgentRun, AgentToolCall, SemanticParseLog
|
||||
from app.models.audit_log import AuditLog
|
||||
from app.models.financial_record import (
|
||||
AccountsPayableRecord,
|
||||
AccountsReceivableRecord,
|
||||
ExpenseClaim,
|
||||
ExpenseClaimItem,
|
||||
)
|
||||
from app.services.agent_asset_rule_library import AgentAssetRuleLibraryManager
|
||||
from app.services.agent_asset_spreadsheet import (
|
||||
AgentAssetSpreadsheetManager,
|
||||
COMPANY_COMMUNICATION_EXPENSE_RULE_CODE,
|
||||
COMPANY_COMMUNICATION_EXPENSE_RULE_FILENAME,
|
||||
COMPANY_TRAVEL_EXPENSE_RULE_CODE,
|
||||
COMPANY_TRAVEL_EXPENSE_RULE_FILENAME,
|
||||
FINANCE_RULES_LIBRARY,
|
||||
RISK_RULES_LIBRARY,
|
||||
)
|
||||
from app.services.expense_rule_runtime import (
|
||||
build_scene_submission_standard_markdown,
|
||||
build_travel_risk_control_standard_markdown,
|
||||
)
|
||||
from app.services.agent_foundation_constants import (
|
||||
ATTACHMENT_RULE_ASSET_CODE,
|
||||
ATTACHMENT_RULE_RUNTIME_CONFIG,
|
||||
COMPANY_COMMUNICATION_RULE_SCENARIO_JSON,
|
||||
COMPANY_COMMUNICATION_RULE_VERSION,
|
||||
COMPANY_TRAVEL_RULE_SCENARIO_JSON,
|
||||
COMPANY_TRAVEL_RULE_VERSION,
|
||||
DEMO_EXPENSE_CLAIM_SIGNATURES,
|
||||
DEMO_PAYABLE_SIGNATURES,
|
||||
DEMO_RECEIVABLE_SIGNATURES,
|
||||
LEGACY_RULE_CODES,
|
||||
PLATFORM_DESTINATION_LOCATION_RULE_FILENAME,
|
||||
)
|
||||
from app.core.logging import get_logger
|
||||
|
||||
logger = get_logger("app.services.agent_foundation")
|
||||
|
||||
class AgentFoundationSpreadsheetMixin:
|
||||
def _ensure_company_travel_rule_spreadsheet_seed(
|
||||
|
||||
self,
|
||||
|
||||
asset: AgentAsset,
|
||||
|
||||
*,
|
||||
|
||||
version: str,
|
||||
|
||||
actor_name: str,
|
||||
|
||||
):
|
||||
|
||||
manager = AgentAssetSpreadsheetManager()
|
||||
|
||||
manager.ensure_rule_library_dirs()
|
||||
|
||||
live_document = manager.store_rule_library_spreadsheet(
|
||||
|
||||
library=FINANCE_RULES_LIBRARY,
|
||||
|
||||
file_name=COMPANY_TRAVEL_EXPENSE_RULE_FILENAME,
|
||||
|
||||
content=self._read_or_build_company_travel_rule_file(manager),
|
||||
|
||||
actor_name=actor_name,
|
||||
|
||||
source="rule-library",
|
||||
|
||||
)
|
||||
|
||||
existing_document = (
|
||||
|
||||
asset.config_json.get("rule_document")
|
||||
|
||||
if isinstance(asset.config_json, dict)
|
||||
|
||||
else None
|
||||
|
||||
)
|
||||
|
||||
storage_key = (
|
||||
|
||||
str(existing_document.get("storage_key") or "").strip()
|
||||
|
||||
if isinstance(existing_document, dict)
|
||||
|
||||
else ""
|
||||
|
||||
)
|
||||
|
||||
if storage_key:
|
||||
|
||||
try:
|
||||
|
||||
existing_path = manager.resolve_storage_path(storage_key)
|
||||
|
||||
except FileNotFoundError:
|
||||
|
||||
existing_path = None
|
||||
|
||||
if existing_path is not None and existing_path.exists():
|
||||
|
||||
asset.config_json = {
|
||||
|
||||
**(asset.config_json or {}),
|
||||
|
||||
"detail_mode": "spreadsheet",
|
||||
|
||||
"tag": "财务规则",
|
||||
|
||||
"rule_library": FINANCE_RULES_LIBRARY,
|
||||
|
||||
"rule_document": {
|
||||
|
||||
**AgentAssetSpreadsheetManager.build_rule_document_config(
|
||||
|
||||
live_document,
|
||||
|
||||
asset_version=version,
|
||||
|
||||
),
|
||||
|
||||
"storage_key": live_document.storage_key,
|
||||
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
return live_document
|
||||
|
||||
asset.config_json = {
|
||||
|
||||
**(asset.config_json or {}),
|
||||
|
||||
"detail_mode": "spreadsheet",
|
||||
|
||||
"tag": "财务规则",
|
||||
|
||||
"rule_library": FINANCE_RULES_LIBRARY,
|
||||
|
||||
"rule_document": {
|
||||
|
||||
**AgentAssetSpreadsheetManager.build_rule_document_config(
|
||||
|
||||
live_document,
|
||||
|
||||
asset_version=version,
|
||||
|
||||
),
|
||||
|
||||
"storage_key": live_document.storage_key,
|
||||
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
return live_document
|
||||
|
||||
def _ensure_company_communication_rule_spreadsheet_seed(
|
||||
|
||||
self,
|
||||
|
||||
asset: AgentAsset,
|
||||
|
||||
*,
|
||||
|
||||
version: str,
|
||||
|
||||
actor_name: str,
|
||||
|
||||
):
|
||||
|
||||
return self._ensure_finance_rule_spreadsheet_seed(
|
||||
|
||||
asset,
|
||||
|
||||
version=version,
|
||||
|
||||
actor_name=actor_name,
|
||||
|
||||
file_name=COMPANY_COMMUNICATION_EXPENSE_RULE_FILENAME,
|
||||
|
||||
fallback_sheet_name="通信费报销规则",
|
||||
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
|
||||
def _read_or_build_company_travel_rule_file(
|
||||
|
||||
manager: AgentAssetSpreadsheetManager,
|
||||
|
||||
) -> bytes:
|
||||
|
||||
live_key = (
|
||||
|
||||
Path("rules")
|
||||
|
||||
/ FINANCE_RULES_LIBRARY
|
||||
|
||||
/ COMPANY_TRAVEL_EXPENSE_RULE_FILENAME
|
||||
|
||||
).as_posix()
|
||||
|
||||
live_path = manager.resolve_storage_path(live_key)
|
||||
|
||||
if live_path.exists():
|
||||
|
||||
return live_path.read_bytes()
|
||||
|
||||
return AgentAssetSpreadsheetManager.build_blank_rule_workbook("差旅费报销规则")
|
||||
|
||||
def _ensure_finance_rule_spreadsheet_seed(
|
||||
|
||||
self,
|
||||
|
||||
asset: AgentAsset,
|
||||
|
||||
*,
|
||||
|
||||
version: str,
|
||||
|
||||
actor_name: str,
|
||||
|
||||
file_name: str,
|
||||
|
||||
fallback_sheet_name: str,
|
||||
|
||||
):
|
||||
|
||||
manager = AgentAssetSpreadsheetManager()
|
||||
|
||||
manager.ensure_rule_library_dirs()
|
||||
|
||||
live_document = manager.store_rule_library_spreadsheet(
|
||||
|
||||
library=FINANCE_RULES_LIBRARY,
|
||||
|
||||
file_name=file_name,
|
||||
|
||||
content=self._read_or_build_finance_rule_file(
|
||||
|
||||
manager,
|
||||
|
||||
file_name=file_name,
|
||||
|
||||
fallback_sheet_name=fallback_sheet_name,
|
||||
|
||||
),
|
||||
|
||||
actor_name=actor_name,
|
||||
|
||||
source="rule-library",
|
||||
|
||||
)
|
||||
|
||||
existing_document = (
|
||||
|
||||
asset.config_json.get("rule_document")
|
||||
|
||||
if isinstance(asset.config_json, dict)
|
||||
|
||||
else None
|
||||
|
||||
)
|
||||
|
||||
storage_key = (
|
||||
|
||||
str(existing_document.get("storage_key") or "").strip()
|
||||
|
||||
if isinstance(existing_document, dict)
|
||||
|
||||
else ""
|
||||
|
||||
)
|
||||
|
||||
if storage_key:
|
||||
|
||||
try:
|
||||
|
||||
existing_path = manager.resolve_storage_path(storage_key)
|
||||
|
||||
except FileNotFoundError:
|
||||
|
||||
existing_path = None
|
||||
|
||||
if existing_path is not None and existing_path.exists():
|
||||
|
||||
asset.config_json = {
|
||||
|
||||
**(asset.config_json or {}),
|
||||
|
||||
"detail_mode": "spreadsheet",
|
||||
|
||||
"tag": "财务规则",
|
||||
|
||||
"rule_library": FINANCE_RULES_LIBRARY,
|
||||
|
||||
"rule_document": {
|
||||
|
||||
**AgentAssetSpreadsheetManager.build_rule_document_config(
|
||||
|
||||
live_document,
|
||||
|
||||
asset_version=version,
|
||||
|
||||
),
|
||||
|
||||
"storage_key": live_document.storage_key,
|
||||
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
return live_document
|
||||
|
||||
asset.config_json = {
|
||||
|
||||
**(asset.config_json or {}),
|
||||
|
||||
"detail_mode": "spreadsheet",
|
||||
|
||||
"tag": "财务规则",
|
||||
|
||||
"rule_library": FINANCE_RULES_LIBRARY,
|
||||
|
||||
"rule_document": {
|
||||
|
||||
**AgentAssetSpreadsheetManager.build_rule_document_config(
|
||||
|
||||
live_document,
|
||||
|
||||
asset_version=version,
|
||||
|
||||
),
|
||||
|
||||
"storage_key": live_document.storage_key,
|
||||
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
return live_document
|
||||
|
||||
@staticmethod
|
||||
|
||||
def _read_or_build_finance_rule_file(
|
||||
|
||||
manager: AgentAssetSpreadsheetManager,
|
||||
|
||||
*,
|
||||
|
||||
file_name: str,
|
||||
|
||||
fallback_sheet_name: str,
|
||||
|
||||
) -> bytes:
|
||||
|
||||
live_key = (
|
||||
|
||||
Path("rules")
|
||||
|
||||
/ FINANCE_RULES_LIBRARY
|
||||
|
||||
/ file_name
|
||||
|
||||
).as_posix()
|
||||
|
||||
live_path = manager.resolve_storage_path(live_key)
|
||||
|
||||
if live_path.exists():
|
||||
|
||||
return live_path.read_bytes()
|
||||
|
||||
return AgentAssetSpreadsheetManager.build_blank_rule_workbook(fallback_sheet_name)
|
||||
Reference in New Issue
Block a user