132 lines
5.1 KiB
Python
132 lines
5.1 KiB
Python
from typing import Any
|
||
from sqlalchemy.ext.asyncio import AsyncConnection
|
||
from orm.tables.process import ProcessStatus
|
||
|
||
from api.db.logic.process_schema import (
|
||
get_process_schema_by_id,
|
||
get_process_schema_page_DTO,
|
||
update_process_schema_by_id,
|
||
create_process_schema,
|
||
)
|
||
from api.db.logic.ps_node import create_ps_node_schema, get_all_ps_nodes_by_ps_id
|
||
from api.db.logic.node_link import get_all_node_links_by_next_node_ids
|
||
from api.schemas.process.process_schema import ProcessSchema, ProcessSchemaResponse
|
||
from api.schemas.endpoints.process_schema import AllProcessSchemaResponse, ProcessSchemaFilterDTO, ProcessSchemaUpdate
|
||
from api.schemas.process.ps_node import Ps_NodeFrontResponse
|
||
from orm.tables.process import NodeType
|
||
from core import VorkNodeRegistry
|
||
from model_nodes import ListenNodeData
|
||
from api.utils.node_counter import increment_node_counter
|
||
|
||
|
||
class ProcessSchemaService:
|
||
"""Сервис для работы с process schema"""
|
||
|
||
def __init__(self, connection: AsyncConnection):
|
||
self.connection = connection
|
||
|
||
async def list(self, filter_dto: ProcessSchemaFilterDTO) -> AllProcessSchemaResponse | None:
|
||
"""
|
||
Получает список схем процессов с пагинацией и фильтрацией.
|
||
"""
|
||
return await get_process_schema_page_DTO(self.connection, filter_dto)
|
||
|
||
async def get(self, process_schema_id: int) -> ProcessSchemaResponse | None:
|
||
"""
|
||
Получает схему процесса по ID со всеми нодами и линками.
|
||
"""
|
||
process_schema = await get_process_schema_by_id(self.connection, process_schema_id)
|
||
if process_schema is None:
|
||
return None
|
||
|
||
nodes = await get_all_ps_nodes_by_ps_id(self.connection, process_schema_id)
|
||
|
||
node_ids = [node.id for node in nodes]
|
||
all_links = await get_all_node_links_by_next_node_ids(self.connection, node_ids)
|
||
|
||
links_by_node_id = {}
|
||
for link in all_links:
|
||
if link.next_node_id not in links_by_node_id:
|
||
links_by_node_id[link.next_node_id] = []
|
||
links_by_node_id[link.next_node_id].append(link)
|
||
|
||
nodes_response = []
|
||
for node in nodes:
|
||
node_links = links_by_node_id.get(node.id, [])
|
||
links_list = [{"link": link.model_dump()} for link in node_links]
|
||
|
||
ps_node_front_response = Ps_NodeFrontResponse(
|
||
node=node.model_dump(),
|
||
link=links_list,
|
||
)
|
||
nodes_response.append(ps_node_front_response)
|
||
|
||
return ProcessSchemaResponse(
|
||
process_schema=process_schema,
|
||
nodes=nodes_response,
|
||
)
|
||
|
||
async def create(self, creator_id: int) -> dict[str, Any]:
|
||
"""
|
||
Создаёт новую схему процесса с начальной нодой LISTEN.
|
||
"""
|
||
current_node_counter = increment_node_counter()
|
||
title = f"Новая схема {current_node_counter}"
|
||
description = "Default description"
|
||
|
||
node_id = await create_process_schema(self.connection, creator_id, title, description)
|
||
|
||
process_schema_new = await get_process_schema_by_id(self.connection, node_id)
|
||
|
||
start_node_data = ListenNodeData(ps_id=process_schema_new.id, node_type=NodeType.START.value, is_start="True")
|
||
|
||
start_node_links = {}
|
||
|
||
registery = VorkNodeRegistry()
|
||
|
||
vork_node = registery.get("LISTEN")
|
||
|
||
node_descriptor = vork_node.form()
|
||
|
||
start_node = vork_node(data=start_node_data.model_dump(), links=start_node_links)
|
||
|
||
validated_start_schema = start_node.validate()
|
||
|
||
start_settings_payload = {
|
||
**node_descriptor.model_dump(),
|
||
**validated_start_schema.data.model_dump(),
|
||
}
|
||
|
||
db_start_schema = await create_ps_node_schema(
|
||
self.connection,
|
||
validated_start_schema,
|
||
node_descriptor,
|
||
creator_id,
|
||
start_settings_payload,
|
||
)
|
||
|
||
ps_node_front_response = Ps_NodeFrontResponse(
|
||
node=db_start_schema.model_dump(),
|
||
link=[],
|
||
)
|
||
response_data = {
|
||
"process_schema": process_schema_new.model_dump(),
|
||
"nodes": [ps_node_front_response], # Список объектов, а не словарей
|
||
}
|
||
return response_data
|
||
|
||
async def update(self, process_schema_id: int, update_data: dict, process_schema: ProcessSchema) -> ProcessSchema:
|
||
"""
|
||
Обновляет данные схемы процесса.
|
||
"""
|
||
await update_process_schema_by_id(self.connection, update_data, process_schema)
|
||
return await get_process_schema_by_id(self.connection, process_schema_id)
|
||
|
||
async def delete(self, process_schema_id: int, process_schema: ProcessSchema) -> None:
|
||
"""
|
||
Помечает схему процесса как удалённую.
|
||
"""
|
||
process_schema_update = ProcessSchemaUpdate(status=ProcessStatus.DELETED.value)
|
||
update_data = process_schema_update.model_dump(by_alias=True, exclude_none=True)
|
||
await update_process_schema_by_id(self.connection, update_data, process_schema)
|