feat: modules creation

This commit is contained in:
2025-10-25 18:00:05 +04:00
parent 281600c72d
commit fcaa7fe177
6 changed files with 71 additions and 13 deletions

View File

@ -19,6 +19,7 @@ from .deal_tag import (
) )
from .module import ( # noqa: F401 from .module import ( # noqa: F401
Module as Module, Module as Module,
ModuleTab as ModuleTab,
project_module as project_module, project_module as project_module,
module_dependencies as module_dependencies, module_dependencies as module_dependencies,
) )

View File

@ -84,6 +84,6 @@ class ModuleTab(BaseModel):
id: Mapped[int] = mapped_column(primary_key=True) id: Mapped[int] = mapped_column(primary_key=True)
key: Mapped[str] = mapped_column(unique=True) key: Mapped[str] = mapped_column(unique=True)
label: Mapped[str] = mapped_column() label: Mapped[str] = mapped_column()
icon_name: Mapped[str] = mapped_column() icon_name: Mapped[Optional[str]] = mapped_column()
module_id: Mapped[int] = mapped_column(ForeignKey("modules.id")) module_id: Mapped[int] = mapped_column(ForeignKey("modules.id"))
device: Mapped[DeviceType] = mapped_column(default=DeviceType.BOTH) device: Mapped[DeviceType] = mapped_column(default=DeviceType.BOTH)

View File

@ -1,17 +1,16 @@
from sqlalchemy import and_ import uuid
from sqlalchemy import and_, or_
from sqlalchemy.orm import selectinload from sqlalchemy.orm import selectinload
from models import Module, Attribute, AttributeLabel, module_attribute from models import Module, Attribute, AttributeLabel, module_attribute, ModuleTab
from models.module import DeviceType
from repositories.mixins import * from repositories.mixins import *
from schemas.module import UpdateModuleCommonInfoSchema from schemas.module import UpdateModuleCommonInfoSchema, CreateModuleSchema
class ModuleRepository( class ModuleRepository(
BaseRepository, RepCrudMixin[Module, CreateModuleSchema, UpdateModuleCommonInfoSchema]
RepGetAllMixin[Module],
RepGetByIdMixin[Module],
RepUpdateMixin[Module, UpdateModuleCommonInfoSchema],
RepDeleteMixin[Module]
): ):
entity_class = Module entity_class = Module
@ -43,7 +42,10 @@ class ModuleRepository(
), ),
isouter=True, isouter=True,
) )
.where(Module.is_deleted.is_(False), Attribute.is_deleted.is_(False)) .where(
Module.is_deleted.is_(False),
or_(Attribute.id.is_(None), Attribute.is_deleted.is_(False)),
)
.order_by(Attribute.id) .order_by(Attribute.id)
) )
@ -60,6 +62,36 @@ class ModuleRepository(
stmt = stmt.where(Module.id == pk) stmt = stmt.where(Module.id == pk)
return (await self.session.execute(stmt)).unique().all() return (await self.session.execute(stmt)).unique().all()
async def _prepare_create(self, data: CreateSchemaType) -> dict:
dump = data.model_dump()
dump["key"] = str(uuid.uuid4())
return dump
async def _after_create(self, module: Module, _) -> None:
tab = ModuleTab(
key=module.key,
label=module.label,
icon_name=None,
module_id=module.id,
device=DeviceType.BOTH,
)
self.session.add(tab)
async def get_module_tabs_by_module_id(self, module_id: int) -> list[ModuleTab]:
stmt = select(ModuleTab).where(ModuleTab.module_id == module_id)
result = await self.session.scalars(stmt)
return list(result.all())
async def update(
self, module: Module, data: UpdateModuleCommonInfoSchema
) -> Module:
tabs = await self.get_module_tabs_by_module_id(module.id)
for tab in tabs:
tab.label = data.label
self.session.add(tab)
return await self._apply_update_data_to_model(module, data, True)
async def add_attribute_to_module(self, module: Module, attribute: Attribute): async def add_attribute_to_module(self, module: Module, attribute: Attribute):
module.attributes.append(attribute) module.attributes.append(attribute)
await self.session.commit() await self.session.commit()

View File

@ -41,6 +41,18 @@ async def get_module_with_attributes(
return await ModuleService(session).get_by_id_with_attributes(pk) return await ModuleService(session).get_by_id_with_attributes(pk)
@router.post(
"/",
response_model=CreateModuleResponse,
operation_id="create_module",
)
async def create_module(
session: SessionDependency,
request: CreateModuleRequest,
):
return await ModuleService(session).create(request)
@router.patch( @router.patch(
"/{pk}/common-info", "/{pk}/common-info",
response_model=UpdateModuleCommonInfoResponse, response_model=UpdateModuleCommonInfoResponse,
@ -66,7 +78,6 @@ async def delete_module(
return await ModuleService(session).delete(pk) return await ModuleService(session).delete(pk)
@router.post( @router.post(
"/attribute", "/attribute",
response_model=AddAttributeResponse, response_model=AddAttributeResponse,

View File

@ -11,7 +11,7 @@ class ModuleTabSchema(BaseSchema):
id: int id: int
key: str key: str
label: str label: str
icon_name: str icon_name: Optional[str]
device: str device: str
@ -29,6 +29,11 @@ class ModuleWithAttributesSchema(ModuleSchema):
attributes: list[ModuleAttributeSchema] attributes: list[ModuleAttributeSchema]
class CreateModuleSchema(BaseSchema):
label: str
description: Optional[str]
class UpdateModuleCommonInfoSchema(BaseSchema): class UpdateModuleCommonInfoSchema(BaseSchema):
label: str label: str
description: Optional[str] description: Optional[str]
@ -50,6 +55,10 @@ class DeleteAttributeRequest(BaseSchema):
module_id: int module_id: int
class CreateModuleRequest(BaseSchema):
entity: CreateModuleSchema
class UpdateModuleCommonInfoRequest(BaseSchema): class UpdateModuleCommonInfoRequest(BaseSchema):
entity: UpdateModuleCommonInfoSchema entity: UpdateModuleCommonInfoSchema
@ -71,6 +80,10 @@ class GetByIdWithAttributesResponse(BaseSchema):
entity: ModuleWithAttributesSchema entity: ModuleWithAttributesSchema
class CreateModuleResponse(BaseResponse):
pass
class UpdateModuleCommonInfoResponse(BaseResponse): class UpdateModuleCommonInfoResponse(BaseResponse):
pass pass

View File

@ -7,6 +7,7 @@ from utils.exceptions import ForbiddenException
class ModuleService( class ModuleService(
ServiceGetAllMixin[Module, ModuleSchema], ServiceGetAllMixin[Module, ModuleSchema],
ServiceCreateMixin[Module, CreateModuleRequest, ModuleSchema],
ServiceUpdateMixin[Module, UpdateModuleCommonInfoRequest], ServiceUpdateMixin[Module, UpdateModuleCommonInfoRequest],
ServiceDeleteMixin[Module], ServiceDeleteMixin[Module],
): ):
@ -34,7 +35,7 @@ class ModuleService(
self, module_id: int, request: UpdateModuleCommonInfoRequest self, module_id: int, request: UpdateModuleCommonInfoRequest
) -> UpdateModuleCommonInfoResponse: ) -> UpdateModuleCommonInfoResponse:
module = await self.repository.get_by_id(module_id) module = await self.repository.get_by_id(module_id)
await self.repository.update_(module, request) await self.repository.update(module, request)
return UpdateModuleCommonInfoResponse(message="Данные модуля успешно сохранены") return UpdateModuleCommonInfoResponse(message="Данные модуля успешно сохранены")
def _build_modules_with_attributes( def _build_modules_with_attributes(