Skip to content
2,574 changes: 1,333 additions & 1,241 deletions api/poetry.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions api/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ click = "^8.1.7"
pypandoc-binary = "^1.13"
pypandoc = "^1.13"
fastapi-versionizer = "^4.0.1"
aiohttp = "3.11.15"
authlib = "^1.5.2"

[tool.poetry.group.docs]
Expand Down
33 changes: 33 additions & 0 deletions api/src/v0/repositories/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -334,3 +334,36 @@ def delete(self, project_uuid: str):
VertexRepository(self._client).delete(v.id)
VertexRepository(self._client).delete(project_uuid)
return

def report_project(self, project_uuid: str) -> dict:
"""Reporting of the project as a static document

fetch relevant data from the DB

Args:
project_uuid (str): UUID of the project to report

Returns:
dict: project components as a dictionary
"""
project = VertexRepository(self._client).read(project_uuid)
objectives_nodes = VertexRepository(self._client).read_out_vertex(
project_uuid,
original_vertex_label="objective",
edge_label="contains",
)
opportunities_nodes = VertexRepository(self._client).read_out_vertex(
project_uuid,
original_vertex_label="opportunity",
edge_label="contains",
)
issue_nodes = VertexRepository(self._client).read_out_vertex(
project_uuid, original_vertex_label="issue", edge_label="contains"
)

return {
"project": project.model_dump(),
"opportunities": [item.model_dump() for item in opportunities_nodes],
"objectives": [item.model_dump() for item in objectives_nodes],
"issues": [item.model_dump() for item in issue_nodes],
}
31 changes: 31 additions & 0 deletions api/src/v0/routes/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,34 @@ def delete(project_uuid: str, service: ProjectService = Depends(get_service)) ->
None
"""
return service.delete(project_uuid)


@api_version(database_version)
@router.get(
"/projects/{project_uuid}/report",
response_model=None,
summary="Create a report for a project",
)
def report_project(
project_uuid: str,
level: int = 1,
filepath: str = "-",
template: str = None,
service: ProjectService = Depends(get_service),
) -> None:
"""Create a report from the project

Args:
project_uuid (str): id of the project vertex
level (int, optional): level of main section of the report. Defaults to 1.
It can be used when planned to merge several reports together and say start
at level=2. A level one can then be manually added.
filepath (str, optional): path of the created report. Defaults to "-" meaning
display in the terminal.
template (str, optional): path of an eventual (say MS office template) for the
output file. Defaults to None, meaning no template is used

Returns:
None
"""
return service.report_project(project_uuid, level, filepath, template)
23 changes: 23 additions & 0 deletions api/src/v0/services/project.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from ..models.project import ProjectCreate, ProjectResponse, ProjectUpdate
from ..repositories.project import ProjectRepository
from .reporting_utils.markdown_report import generate_report


class ProjectService:
Expand Down Expand Up @@ -92,3 +93,25 @@ def delete(self, project_uuid: str) -> None:
None
"""
return self.repository.delete(project_uuid)

def report_project(
self, project_uuid: str, level=1, filepath="-", template: str = None
) -> None:
"""Reporting of the project as a static document

Args
project_uuid (str): id of the project vertex
level (int, optional): main section level of the document. Default = 1.
filepath (Path| str, optional): file path to write the document. The
extension of the filepath indicates the desired format. Default = "-"
meaning display in the terminal.
template (str, optional): template for output file (e.g. MS office files).
Defaults to None, meaning no template.
Remarks
- The code uses pypandoc and the file extension should be compatible.
- The level can be useful when planning to merge several projects into
one document. Selecting for example level=2 allows merging them and add
later a level one section manually
"""
project_data = self.repository.report_project(project_uuid)
return generate_report(project_data, level, filepath, template)
Empty file.
Loading