feat: enhance import functionality with commit results and summary models for projects and scenarios
This commit is contained in:
@@ -135,6 +135,19 @@ class StagedImportView(Generic[TImportRow]):
|
||||
rows: tuple[StagedRowView[TImportRow], ...]
|
||||
|
||||
|
||||
@dataclass(slots=True, frozen=True)
|
||||
class ImportCommitSummary:
|
||||
created: int
|
||||
updated: int
|
||||
|
||||
|
||||
@dataclass(slots=True, frozen=True)
|
||||
class ImportCommitResult(Generic[TImportRow]):
|
||||
token: str
|
||||
rows: tuple[StagedRowView[TImportRow], ...]
|
||||
summary: ImportCommitSummary
|
||||
|
||||
|
||||
UnitOfWorkFactory = Callable[[], UnitOfWork]
|
||||
|
||||
|
||||
@@ -402,6 +415,136 @@ class ImportIngestionService:
|
||||
def clear_staged_scenarios(self, token: str) -> bool:
|
||||
return self._scenario_stage.pop(token, None) is not None
|
||||
|
||||
def commit_project_import(self, token: str) -> ImportCommitResult[ProjectImportRow]:
|
||||
staged = self._project_stage.get(token)
|
||||
if not staged:
|
||||
raise ValueError(f"Unknown project import token: {token}")
|
||||
|
||||
staged_view = _build_staged_view(staged)
|
||||
created = updated = 0
|
||||
|
||||
with self._uow_factory() as uow:
|
||||
if not uow.projects:
|
||||
raise RuntimeError("Project repository is unavailable")
|
||||
|
||||
for row in staged.rows:
|
||||
mode = row.context.get("mode")
|
||||
data = row.parsed.data
|
||||
|
||||
if mode == "create":
|
||||
project = Project(
|
||||
name=data.name,
|
||||
location=data.location,
|
||||
operation_type=data.operation_type,
|
||||
description=data.description,
|
||||
)
|
||||
if data.created_at:
|
||||
project.created_at = data.created_at
|
||||
if data.updated_at:
|
||||
project.updated_at = data.updated_at
|
||||
uow.projects.create(project)
|
||||
created += 1
|
||||
elif mode == "update":
|
||||
project_id = row.context.get("project_id")
|
||||
if not project_id:
|
||||
raise ValueError(
|
||||
"Staged project update is missing project_id context"
|
||||
)
|
||||
project = uow.projects.get(project_id)
|
||||
project.name = data.name
|
||||
project.location = data.location
|
||||
project.operation_type = data.operation_type
|
||||
project.description = data.description
|
||||
if data.created_at:
|
||||
project.created_at = data.created_at
|
||||
if data.updated_at:
|
||||
project.updated_at = data.updated_at
|
||||
updated += 1
|
||||
else:
|
||||
raise ValueError(
|
||||
f"Unsupported staged project mode: {mode!r}")
|
||||
|
||||
self._project_stage.pop(token, None)
|
||||
return ImportCommitResult(
|
||||
token=token,
|
||||
rows=staged_view.rows,
|
||||
summary=ImportCommitSummary(created=created, updated=updated),
|
||||
)
|
||||
|
||||
def commit_scenario_import(self, token: str) -> ImportCommitResult[ScenarioImportRow]:
|
||||
staged = self._scenario_stage.get(token)
|
||||
if not staged:
|
||||
raise ValueError(f"Unknown scenario import token: {token}")
|
||||
|
||||
staged_view = _build_staged_view(staged)
|
||||
created = updated = 0
|
||||
|
||||
with self._uow_factory() as uow:
|
||||
if not uow.scenarios or not uow.projects:
|
||||
raise RuntimeError("Scenario repositories are unavailable")
|
||||
|
||||
for row in staged.rows:
|
||||
mode = row.context.get("mode")
|
||||
data = row.parsed.data
|
||||
|
||||
project_id = row.context.get("project_id")
|
||||
if not project_id:
|
||||
raise ValueError(
|
||||
"Staged scenario row is missing project_id context"
|
||||
)
|
||||
|
||||
project = uow.projects.get(project_id)
|
||||
|
||||
if mode == "create":
|
||||
scenario = Scenario(
|
||||
project_id=project.id,
|
||||
name=data.name,
|
||||
status=data.status,
|
||||
start_date=data.start_date,
|
||||
end_date=data.end_date,
|
||||
discount_rate=data.discount_rate,
|
||||
currency=data.currency,
|
||||
primary_resource=data.primary_resource,
|
||||
description=data.description,
|
||||
)
|
||||
if data.created_at:
|
||||
scenario.created_at = data.created_at
|
||||
if data.updated_at:
|
||||
scenario.updated_at = data.updated_at
|
||||
uow.scenarios.create(scenario)
|
||||
created += 1
|
||||
elif mode == "update":
|
||||
scenario_id = row.context.get("scenario_id")
|
||||
if not scenario_id:
|
||||
raise ValueError(
|
||||
"Staged scenario update is missing scenario_id context"
|
||||
)
|
||||
scenario = uow.scenarios.get(scenario_id)
|
||||
scenario.project_id = project.id
|
||||
scenario.name = data.name
|
||||
scenario.status = data.status
|
||||
scenario.start_date = data.start_date
|
||||
scenario.end_date = data.end_date
|
||||
scenario.discount_rate = data.discount_rate
|
||||
scenario.currency = data.currency
|
||||
scenario.primary_resource = data.primary_resource
|
||||
scenario.description = data.description
|
||||
if data.created_at:
|
||||
scenario.created_at = data.created_at
|
||||
if data.updated_at:
|
||||
scenario.updated_at = data.updated_at
|
||||
updated += 1
|
||||
else:
|
||||
raise ValueError(
|
||||
f"Unsupported staged scenario mode: {mode!r}")
|
||||
|
||||
self._scenario_stage.pop(token, None)
|
||||
return ImportCommitResult(
|
||||
token=token,
|
||||
rows=staged_view.rows,
|
||||
summary=ImportCommitSummary(created=created, updated=updated),
|
||||
)
|
||||
|
||||
def _store_project_stage(
|
||||
self, rows: list[StagedRow[ProjectImportRow]]
|
||||
) -> str:
|
||||
|
||||
Reference in New Issue
Block a user