fix: ps node models
This commit is contained in:
@@ -27,135 +27,6 @@ api_router = APIRouter(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@api_router.delete("", dependencies=[Depends(bearer_schema)], status_code=status.HTTP_200_OK)
|
|
||||||
async def delete_ps_node_endpoint(
|
|
||||||
ps_node_delete_data: Ps_NodeDeleteRequest,
|
|
||||||
connection: AsyncConnection = Depends(get_connection_dep),
|
|
||||||
current_user=Depends(get_current_user),
|
|
||||||
):
|
|
||||||
process_schema = await get_process_schema_by_id(connection, ps_node_delete_data.schema_id)
|
|
||||||
if process_schema is None:
|
|
||||||
raise create_operation_error(
|
|
||||||
message="Process schema not found",
|
|
||||||
status_code=status.HTTP_404_NOT_FOUND,
|
|
||||||
details={"schema_id": ps_node_delete_data.schema_id},
|
|
||||||
)
|
|
||||||
|
|
||||||
validator = UserRoleValidator(connection)
|
|
||||||
try:
|
|
||||||
await validator.validate_ownership(current_user, process_schema.creator_id)
|
|
||||||
except Exception as e:
|
|
||||||
raise create_access_error(
|
|
||||||
message="Access denied",
|
|
||||||
status_code=status.HTTP_403_FORBIDDEN,
|
|
||||||
details={"user_id": current_user, "schema_creator_id": process_schema.creator_id, "reason": str(e)},
|
|
||||||
)
|
|
||||||
|
|
||||||
ps_node = await get_ps_node_by_id(connection, ps_node_delete_data.node_id)
|
|
||||||
if ps_node is None:
|
|
||||||
raise create_operation_error(
|
|
||||||
message="PS node not found",
|
|
||||||
status_code=status.HTTP_404_NOT_FOUND,
|
|
||||||
details={"node_id": ps_node_delete_data.node_id},
|
|
||||||
)
|
|
||||||
|
|
||||||
next_ps_node = await get_ps_node_by_id(connection, ps_node_delete_data.next_node_id)
|
|
||||||
if next_ps_node is None:
|
|
||||||
raise create_operation_error(
|
|
||||||
message="Next PS node not found",
|
|
||||||
status_code=status.HTTP_400_BAD_REQUEST,
|
|
||||||
details={"next_node_id": ps_node_delete_data.next_node_id},
|
|
||||||
)
|
|
||||||
|
|
||||||
service = PsNodeService(connection)
|
|
||||||
try:
|
|
||||||
result = await service.delete(ps_node_delete_data.next_node_id)
|
|
||||||
except Exception as e:
|
|
||||||
raise create_server_error(
|
|
||||||
message="Failed to delete nodes",
|
|
||||||
status_code=500,
|
|
||||||
details={"error": str(e), "next_node_id": ps_node_delete_data.next_node_id},
|
|
||||||
)
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
@api_router.post("", dependencies=[Depends(bearer_schema)], response_model=Ps_NodeFrontResponse)
|
|
||||||
async def create_ps_node_endpoint(
|
|
||||||
ps_node: Ps_NodeRequest,
|
|
||||||
connection: AsyncConnection = Depends(get_connection_dep),
|
|
||||||
current_user=Depends(get_current_user),
|
|
||||||
):
|
|
||||||
user_validation = await get_user_by_login(connection, current_user)
|
|
||||||
|
|
||||||
process_schema = await get_process_schema_by_id(connection, ps_node.data["ps_id"])
|
|
||||||
if process_schema is None:
|
|
||||||
raise create_operation_error(
|
|
||||||
message="Process schema not found",
|
|
||||||
status_code=status.HTTP_404_NOT_FOUND,
|
|
||||||
details={"schema_id": ps_node.data["ps_id"]},
|
|
||||||
)
|
|
||||||
|
|
||||||
validator = UserRoleValidator(connection)
|
|
||||||
try:
|
|
||||||
await validator.validate_ownership(current_user, process_schema.creator_id)
|
|
||||||
except Exception as e:
|
|
||||||
raise create_access_error(
|
|
||||||
message="Access denied",
|
|
||||||
status_code=status.HTTP_403_FORBIDDEN,
|
|
||||||
details={"user_id": current_user, "schema_creator_id": process_schema.creator_id, "reason": str(e)},
|
|
||||||
)
|
|
||||||
|
|
||||||
registery = VorkNodeRegistry()
|
|
||||||
|
|
||||||
vork_node = registery.get(ps_node.data["node_type"])
|
|
||||||
|
|
||||||
if vork_node is None:
|
|
||||||
raise create_operation_error(
|
|
||||||
message="Node type not found",
|
|
||||||
status_code=status.HTTP_404_NOT_FOUND,
|
|
||||||
details={"node_type": ps_node.data["node_type"]},
|
|
||||||
)
|
|
||||||
|
|
||||||
try:
|
|
||||||
node_instance = vork_node(data=ps_node.data, links=ps_node.links)
|
|
||||||
node_instance_validated = node_instance.validate()
|
|
||||||
except Exception as e:
|
|
||||||
raise create_validation_error(
|
|
||||||
message="Node validation failed",
|
|
||||||
status_code=status.HTTP_400_BAD_REQUEST,
|
|
||||||
details={"error": str(e)},
|
|
||||||
)
|
|
||||||
|
|
||||||
parent_id = node_instance_validated.parent_id
|
|
||||||
target_ps_id = ps_node.data["ps_id"]
|
|
||||||
|
|
||||||
parent_node = await get_ps_node_by_id(connection, parent_id)
|
|
||||||
if parent_node is None:
|
|
||||||
raise create_operation_error(
|
|
||||||
message="Parent PS node not found",
|
|
||||||
status_code=status.HTTP_404_NOT_FOUND,
|
|
||||||
details={"parent_id": parent_id},
|
|
||||||
)
|
|
||||||
if parent_node.ps_id != target_ps_id:
|
|
||||||
raise create_validation_error(
|
|
||||||
message="Parent PS node belongs to another process schema",
|
|
||||||
status_code=status.HTTP_400_BAD_REQUEST,
|
|
||||||
details={"parent_id": parent_id, "expected_ps_id": target_ps_id, "actual_ps_id": parent_node.ps_id},
|
|
||||||
)
|
|
||||||
|
|
||||||
service = PsNodeService(connection)
|
|
||||||
try:
|
|
||||||
ps_node_front_response = await service.create(ps_node.data, ps_node.links, user_validation.id)
|
|
||||||
except Exception as e:
|
|
||||||
raise create_server_error(
|
|
||||||
message="Failed to create node",
|
|
||||||
status_code=500,
|
|
||||||
details={"error": str(e)},
|
|
||||||
)
|
|
||||||
|
|
||||||
return ps_node_front_response
|
|
||||||
|
|
||||||
|
|
||||||
@api_router.get("/available", dependencies=[Depends(bearer_schema)], response_model=AllAvailableNodesResponse)
|
@api_router.get("/available", dependencies=[Depends(bearer_schema)], response_model=AllAvailableNodesResponse)
|
||||||
async def get_all_available_nodes_endpoint(
|
async def get_all_available_nodes_endpoint(
|
||||||
@@ -184,12 +55,12 @@ async def get_ps_node_endpoint(
|
|||||||
details={"node_id": node_id},
|
details={"node_id": node_id},
|
||||||
)
|
)
|
||||||
|
|
||||||
process_schema = await get_process_schema_by_id(connection, ps_node_response.node["ps_id"])
|
process_schema = await get_process_schema_by_id(connection, ps_node_response.node.ps_id)
|
||||||
if process_schema is None:
|
if process_schema is None:
|
||||||
raise create_operation_error(
|
raise create_operation_error(
|
||||||
message="Process schema not found",
|
message="Process schema not found",
|
||||||
status_code=status.HTTP_404_NOT_FOUND,
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
details={"schema_id": ps_node_response.node["ps_id"]},
|
details={"schema_id": ps_node_response.node.ps_id},
|
||||||
)
|
)
|
||||||
|
|
||||||
validator = UserRoleValidator(connection)
|
validator = UserRoleValidator(connection)
|
||||||
@@ -204,6 +75,75 @@ async def get_ps_node_endpoint(
|
|||||||
|
|
||||||
return ps_node_response
|
return ps_node_response
|
||||||
|
|
||||||
|
@api_router.post("", dependencies=[Depends(bearer_schema)], response_model=Ps_NodeFrontResponse)
|
||||||
|
async def create_ps_node_endpoint(
|
||||||
|
ps_node: Ps_NodeRequest,
|
||||||
|
connection: AsyncConnection = Depends(get_connection_dep),
|
||||||
|
current_user=Depends(get_current_user),
|
||||||
|
):
|
||||||
|
user_validation = await get_user_by_login(connection, current_user)
|
||||||
|
|
||||||
|
process_schema = await get_process_schema_by_id(connection, ps_node.data.ps_id)
|
||||||
|
if process_schema is None:
|
||||||
|
raise create_operation_error(
|
||||||
|
message="Process schema not found",
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
details={"schema_id": ps_node.data.ps_id},
|
||||||
|
)
|
||||||
|
|
||||||
|
validator = UserRoleValidator(connection)
|
||||||
|
try:
|
||||||
|
await validator.validate_ownership(current_user, process_schema.creator_id)
|
||||||
|
except Exception as e:
|
||||||
|
raise create_access_error(
|
||||||
|
message="Access denied",
|
||||||
|
status_code=status.HTTP_403_FORBIDDEN,
|
||||||
|
details={"user_id": current_user, "schema_creator_id": process_schema.creator_id, "reason": str(e)},
|
||||||
|
)
|
||||||
|
|
||||||
|
registery = VorkNodeRegistry()
|
||||||
|
|
||||||
|
vork_node = registery.get(ps_node.data.node_type.value)
|
||||||
|
|
||||||
|
if vork_node is None:
|
||||||
|
raise create_operation_error(
|
||||||
|
message="Node type not found",
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
details={"node_type": ps_node.data.node_type},
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Преобразуем объекты Pydantic в словари для vork_node
|
||||||
|
node_instance = vork_node(data=ps_node.data.model_dump(), links=ps_node.links.model_dump())
|
||||||
|
node_instance_validated = node_instance.validate()
|
||||||
|
except Exception as e:
|
||||||
|
raise create_validation_error(
|
||||||
|
message="Node validation failed",
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
details={"error": str(e)},
|
||||||
|
)
|
||||||
|
|
||||||
|
parent_id = node_instance_validated.parent_id
|
||||||
|
target_ps_id = ps_node.data.ps_id
|
||||||
|
|
||||||
|
parent_node = await get_ps_node_by_id(connection, parent_id)
|
||||||
|
if parent_node is None:
|
||||||
|
raise create_operation_error(
|
||||||
|
message="Parent PS node not found",
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
details={"parent_id": parent_id},
|
||||||
|
)
|
||||||
|
if parent_node.ps_id != target_ps_id:
|
||||||
|
raise create_validation_error(
|
||||||
|
message="Parent PS node belongs to another process schema",
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
details={"parent_id": parent_id, "expected_ps_id": target_ps_id, "actual_ps_id": parent_node.ps_id},
|
||||||
|
)
|
||||||
|
|
||||||
|
service = PsNodeService(connection)
|
||||||
|
ps_node_response = await service.create(ps_node.data.model_dump(), ps_node.links.model_dump(), user_validation.id)
|
||||||
|
|
||||||
|
return ps_node_response
|
||||||
|
|
||||||
@api_router.put("", dependencies=[Depends(bearer_schema)], response_model=Ps_NodeFrontResponse)
|
@api_router.put("", dependencies=[Depends(bearer_schema)], response_model=Ps_NodeFrontResponse)
|
||||||
async def update_ps_node_endpoint(
|
async def update_ps_node_endpoint(
|
||||||
@@ -292,3 +232,57 @@ async def update_ps_node_endpoint(
|
|||||||
)
|
)
|
||||||
|
|
||||||
return updated_ps_node
|
return updated_ps_node
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@api_router.delete("", dependencies=[Depends(bearer_schema)], status_code=status.HTTP_200_OK)
|
||||||
|
async def delete_ps_node_endpoint(
|
||||||
|
ps_node_delete_data: Ps_NodeDeleteRequest,
|
||||||
|
connection: AsyncConnection = Depends(get_connection_dep),
|
||||||
|
current_user=Depends(get_current_user),
|
||||||
|
):
|
||||||
|
process_schema = await get_process_schema_by_id(connection, ps_node_delete_data.schema_id)
|
||||||
|
if process_schema is None:
|
||||||
|
raise create_operation_error(
|
||||||
|
message="Process schema not found",
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
details={"schema_id": ps_node_delete_data.schema_id},
|
||||||
|
)
|
||||||
|
|
||||||
|
validator = UserRoleValidator(connection)
|
||||||
|
try:
|
||||||
|
await validator.validate_ownership(current_user, process_schema.creator_id)
|
||||||
|
except Exception as e:
|
||||||
|
raise create_access_error(
|
||||||
|
message="Access denied",
|
||||||
|
status_code=status.HTTP_403_FORBIDDEN,
|
||||||
|
details={"user_id": current_user, "schema_creator_id": process_schema.creator_id, "reason": str(e)},
|
||||||
|
)
|
||||||
|
|
||||||
|
ps_node = await get_ps_node_by_id(connection, ps_node_delete_data.node_id)
|
||||||
|
if ps_node is None:
|
||||||
|
raise create_operation_error(
|
||||||
|
message="PS node not found",
|
||||||
|
status_code=status.HTTP_404_NOT_FOUND,
|
||||||
|
details={"node_id": ps_node_delete_data.node_id},
|
||||||
|
)
|
||||||
|
|
||||||
|
next_ps_node = await get_ps_node_by_id(connection, ps_node_delete_data.next_node_id)
|
||||||
|
if next_ps_node is None:
|
||||||
|
raise create_operation_error(
|
||||||
|
message="Next PS node not found",
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
details={"next_node_id": ps_node_delete_data.next_node_id},
|
||||||
|
)
|
||||||
|
|
||||||
|
service = PsNodeService(connection)
|
||||||
|
try:
|
||||||
|
result = await service.delete(ps_node_delete_data.next_node_id)
|
||||||
|
except Exception as e:
|
||||||
|
raise create_server_error(
|
||||||
|
message="Failed to delete nodes",
|
||||||
|
status_code=500,
|
||||||
|
details={"error": str(e), "next_node_id": ps_node_delete_data.next_node_id},
|
||||||
|
)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ from typing import Any
|
|||||||
from orm.tables.process import NodeStatus, NodeType
|
from orm.tables.process import NodeStatus, NodeType
|
||||||
|
|
||||||
from api.schemas.base import Base
|
from api.schemas.base import Base
|
||||||
|
from api.schemas.process.node_link import NodeLink
|
||||||
|
|
||||||
|
|
||||||
class Ps_NodeDeleteRequest(Base):
|
class Ps_NodeDeleteRequest(Base):
|
||||||
@@ -12,10 +13,17 @@ class Ps_NodeDeleteRequest(Base):
|
|||||||
port: str
|
port: str
|
||||||
next_node_id: int
|
next_node_id: int
|
||||||
|
|
||||||
|
class Ps_NodeRequestData(Base):
|
||||||
|
ps_id: int
|
||||||
|
node_type: NodeType
|
||||||
|
|
||||||
|
class Ps_NodeRequestLinks(Base):
|
||||||
|
parent_port_number: int
|
||||||
|
parent_id: int
|
||||||
|
|
||||||
class Ps_NodeRequest(Base):
|
class Ps_NodeRequest(Base):
|
||||||
data: dict[str, Any]
|
data: Ps_NodeRequestData
|
||||||
links: dict[str, Any]
|
links: Ps_NodeRequestLinks
|
||||||
|
|
||||||
|
|
||||||
class Ps_Node(Base):
|
class Ps_Node(Base):
|
||||||
@@ -35,8 +43,8 @@ class Ps_NodeUpdate(Base):
|
|||||||
|
|
||||||
|
|
||||||
class Ps_NodeFrontResponse(Base):
|
class Ps_NodeFrontResponse(Base):
|
||||||
node: dict[str, Any] | None = None
|
node: Ps_Node
|
||||||
link: list[dict[str, Any]] | None = None
|
link: list[NodeLink] | None = None
|
||||||
|
|
||||||
|
|
||||||
class AllAvailableNodesResponse(Base):
|
class AllAvailableNodesResponse(Base):
|
||||||
|
|||||||
@@ -53,11 +53,11 @@ class ProcessSchemaService:
|
|||||||
nodes_response = []
|
nodes_response = []
|
||||||
for node in nodes:
|
for node in nodes:
|
||||||
node_links = links_by_node_id.get(node.id, [])
|
node_links = links_by_node_id.get(node.id, [])
|
||||||
links_list = [{"link": link.model_dump()} for link in node_links]
|
link = node_links if node_links else None
|
||||||
|
|
||||||
ps_node_front_response = Ps_NodeFrontResponse(
|
ps_node_front_response = Ps_NodeFrontResponse(
|
||||||
node=node.model_dump(),
|
node=node.model_dump(),
|
||||||
link=links_list,
|
link=link,
|
||||||
)
|
)
|
||||||
nodes_response.append(ps_node_front_response)
|
nodes_response.append(ps_node_front_response)
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@ class ProcessSchemaService:
|
|||||||
|
|
||||||
ps_node_front_response = Ps_NodeFrontResponse(
|
ps_node_front_response = Ps_NodeFrontResponse(
|
||||||
node=db_start_schema.model_dump(),
|
node=db_start_schema.model_dump(),
|
||||||
link=[],
|
link=None,
|
||||||
)
|
)
|
||||||
response_data = {
|
response_data = {
|
||||||
"process_schema": process_schema_new.model_dump(),
|
"process_schema": process_schema_new.model_dump(),
|
||||||
|
|||||||
@@ -42,7 +42,10 @@ class PsNodeService:
|
|||||||
Создаёт новую ноду с линком и обновляет настройки схемы процесса.
|
Создаёт новую ноду с линком и обновляет настройки схемы процесса.
|
||||||
"""
|
"""
|
||||||
registery = VorkNodeRegistry()
|
registery = VorkNodeRegistry()
|
||||||
vork_node = registery.get(ps_node_data["node_type"])
|
|
||||||
|
node_type = ps_node_data.get("node_type")
|
||||||
|
vork_node = registery.get(node_type.value)
|
||||||
|
|
||||||
node_descriptor = vork_node.form()
|
node_descriptor = vork_node.form()
|
||||||
|
|
||||||
node_instance = vork_node(data=ps_node_data, links=links)
|
node_instance = vork_node(data=ps_node_data, links=links)
|
||||||
@@ -64,8 +67,8 @@ class PsNodeService:
|
|||||||
db_node_link = await create_node_link_schema(self.connection, validated_link, creator_id)
|
db_node_link = await create_node_link_schema(self.connection, validated_link, creator_id)
|
||||||
|
|
||||||
ps_node_front_response = Ps_NodeFrontResponse(
|
ps_node_front_response = Ps_NodeFrontResponse(
|
||||||
node=db_ps_node.model_dump(),
|
node=db_ps_node,
|
||||||
link=[{"link": db_node_link.model_dump()}],
|
link=[db_node_link] if db_node_link else None,
|
||||||
)
|
)
|
||||||
|
|
||||||
return ps_node_front_response
|
return ps_node_front_response
|
||||||
@@ -80,29 +83,28 @@ class PsNodeService:
|
|||||||
|
|
||||||
node_links = await get_all_node_links_by_next_node_ids(self.connection, [node_id])
|
node_links = await get_all_node_links_by_next_node_ids(self.connection, [node_id])
|
||||||
|
|
||||||
links_list = [{"link": link.model_dump()} for link in node_links]
|
|
||||||
|
|
||||||
return Ps_NodeFrontResponse(
|
return Ps_NodeFrontResponse(
|
||||||
node=ps_node.model_dump(),
|
node=ps_node,
|
||||||
link=links_list,
|
link=node_links if node_links else None,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def update(self, node_id: int, update_data: dict[str, Any], ps_node: Ps_Node) -> Ps_NodeFrontResponse:
|
async def update(self, node_id: int, update_data: dict[str, Any], ps_node: Ps_Node) -> Ps_NodeFrontResponse:
|
||||||
"""
|
"""
|
||||||
Обновляет данные PS ноды (settings).
|
Обновляет данные PS ноды (settings).
|
||||||
|
Принимает уже полученную ноду, чтобы избежать лишних запросов к БД.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
await update_ps_node_by_id(self.connection, {"settings": update_data}, ps_node)
|
await update_ps_node_by_id(self.connection, {"settings": update_data}, ps_node)
|
||||||
|
|
||||||
node_links = await get_all_node_links_by_next_node_ids(self.connection, [node_id])
|
node_links = await get_all_node_links_by_next_node_ids(self.connection, [node_id])
|
||||||
links_list = [{"link": link.model_dump()} for link in node_links]
|
|
||||||
|
|
||||||
|
# Создаем обновленный объект Ps_Node с новыми settings
|
||||||
updated_node_dict = ps_node.model_dump()
|
updated_node_dict = ps_node.model_dump()
|
||||||
updated_node_dict["settings"] = update_data
|
updated_node_dict["settings"] = update_data
|
||||||
|
updated_ps_node = Ps_Node.model_validate(updated_node_dict)
|
||||||
|
|
||||||
return Ps_NodeFrontResponse(
|
return Ps_NodeFrontResponse(
|
||||||
node=updated_node_dict,
|
node=updated_ps_node,
|
||||||
link=links_list,
|
link=node_links if node_links else None,
|
||||||
)
|
)
|
||||||
|
|
||||||
def check_constraint(self, form_descriptor: dict[str, Any], settings_data: dict[str, Any]) -> bool:
|
def check_constraint(self, form_descriptor: dict[str, Any], settings_data: dict[str, Any]) -> bool:
|
||||||
|
|||||||
Reference in New Issue
Block a user