services.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. from pydantic import ValidationError
  2. from core_dsl import parse_workflow_definition
  3. from core_shared import JSONValue
  4. from app.db.models import AppDefinition, AppVersion, WorkflowDefinitionModel, WorkflowVersion
  5. from app.domain.repositories import (
  6. AppDefinitionRepository,
  7. AppVersionRepository,
  8. WorkflowDefinitionRepository,
  9. WorkflowVersionRepository,
  10. )
  11. from app.schemas.app import AppCreateRequest, AppVersionCreateRequest
  12. from app.schemas.workflow import WorkflowCreateRequest, WorkflowVersionCreateRequest
  13. class WorkflowApplicationService:
  14. def __init__(
  15. self,
  16. app_repository: AppDefinitionRepository,
  17. workflow_repository: WorkflowDefinitionRepository,
  18. app_version_repository: AppVersionRepository,
  19. workflow_version_repository: WorkflowVersionRepository,
  20. ) -> None:
  21. self.app_repository = app_repository
  22. self.workflow_repository = workflow_repository
  23. self.app_version_repository = app_version_repository
  24. self.workflow_version_repository = workflow_version_repository
  25. def create_app(self, payload: AppCreateRequest) -> AppDefinition:
  26. return self.app_repository.create(
  27. tenant_id=payload.tenant_id,
  28. code=payload.code,
  29. name=payload.name,
  30. description=payload.description,
  31. owner_user_id=payload.owner_user_id,
  32. settings_json=payload.settings_json,
  33. )
  34. def list_apps(self, tenant_id: str) -> list[AppDefinition]:
  35. return self.app_repository.list_by_tenant(tenant_id)
  36. def create_workflow(self, payload: WorkflowCreateRequest) -> WorkflowDefinitionModel:
  37. return self.workflow_repository.create(
  38. tenant_id=payload.tenant_id,
  39. app_id=payload.app_id,
  40. code=payload.code,
  41. name=payload.name,
  42. workflow_type=payload.workflow_type,
  43. )
  44. def list_workflows(self, tenant_id: str, app_id: str | None = None) -> list[WorkflowDefinitionModel]:
  45. return self.workflow_repository.list_by_scope(tenant_id=tenant_id, app_id=app_id)
  46. def create_workflow_version(self, payload: WorkflowVersionCreateRequest) -> WorkflowVersion:
  47. dsl_json = self._validate_workflow_dsl(payload.dsl_json)
  48. return self.workflow_version_repository.create(
  49. tenant_id=payload.tenant_id,
  50. workflow_id=payload.workflow_id,
  51. dsl_json=dsl_json,
  52. compiled_plan_json=payload.compiled_plan_json,
  53. schema_version=payload.schema_version,
  54. checksum=payload.checksum,
  55. status=payload.status,
  56. )
  57. def list_workflow_versions(self, tenant_id: str, workflow_id: str) -> list[WorkflowVersion]:
  58. return self.workflow_version_repository.list_by_workflow(
  59. tenant_id=tenant_id,
  60. workflow_id=workflow_id,
  61. )
  62. def get_workflow_version(self, tenant_id: str, workflow_version_id: str) -> WorkflowVersion | None:
  63. return self.workflow_version_repository.get_by_id(
  64. tenant_id=tenant_id,
  65. workflow_version_id=workflow_version_id,
  66. )
  67. def create_app_version(self, payload: AppVersionCreateRequest) -> AppVersion:
  68. return self.app_version_repository.create(
  69. tenant_id=payload.tenant_id,
  70. app_id=payload.app_id,
  71. workflow_version_id=payload.workflow_version_id,
  72. status=payload.status,
  73. published_by=payload.published_by,
  74. changelog=payload.changelog,
  75. )
  76. def list_app_versions(self, tenant_id: str, app_id: str) -> list[AppVersion]:
  77. return self.app_version_repository.list_by_app(tenant_id=tenant_id, app_id=app_id)
  78. def _validate_workflow_dsl(
  79. self,
  80. dsl_json: dict[str, JSONValue] | None,
  81. ) -> dict[str, JSONValue] | None:
  82. if dsl_json is None:
  83. return None
  84. try:
  85. workflow = parse_workflow_definition(dsl_json)
  86. except ValidationError as exc:
  87. raise ValueError(f"invalid workflow dsl: {exc}") from exc
  88. if workflow is None:
  89. return None
  90. return workflow.model_dump(mode="json")