Skip to content

Commit ce9d3a5

Browse files
♻️ refactor project listing DB function (🚨 We no longer list projects that do not have a product assigned) (#6692)
1 parent e32787b commit ce9d3a5

File tree

5 files changed

+291
-297
lines changed

5 files changed

+291
-297
lines changed

packages/models-library/src/models_library/folders.py

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,41 @@
11
from datetime import datetime
2+
from enum import auto
23
from typing import TypeAlias
34

4-
from models_library.users import GroupID, UserID
5-
from models_library.workspaces import WorkspaceID
6-
from pydantic import BaseModel, Field, PositiveInt
5+
from pydantic import BaseModel, Field, PositiveInt, validator
6+
7+
from .users import GroupID, UserID
8+
from .utils.enums import StrAutoEnum
9+
from .workspaces import WorkspaceID
710

811
FolderID: TypeAlias = PositiveInt
912

1013

14+
class FolderScope(StrAutoEnum):
15+
ROOT = auto()
16+
SPECIFIC = auto()
17+
ALL = auto()
18+
19+
20+
class FolderQuery(BaseModel):
21+
folder_scope: FolderScope
22+
folder_id: PositiveInt | None = None
23+
24+
@validator("folder_id", pre=True, always=True)
25+
@classmethod
26+
def validate_folder_id(cls, value, values):
27+
scope = values.get("folder_scope")
28+
if scope == FolderScope.SPECIFIC and value is None:
29+
raise ValueError(
30+
"folder_id must be provided when folder_scope is SPECIFIC."
31+
)
32+
if scope != FolderScope.SPECIFIC and value is not None:
33+
raise ValueError(
34+
"folder_id should be None when folder_scope is not SPECIFIC."
35+
)
36+
return value
37+
38+
1139
#
1240
# DB
1341
#

packages/models-library/src/models_library/workspaces.py

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,41 @@
11
from datetime import datetime
2+
from enum import auto
23
from typing import TypeAlias
34

4-
from models_library.access_rights import AccessRights
5-
from models_library.users import GroupID
6-
from pydantic import BaseModel, Field, PositiveInt
5+
from pydantic import BaseModel, Field, PositiveInt, validator
6+
7+
from .access_rights import AccessRights
8+
from .users import GroupID
9+
from .utils.enums import StrAutoEnum
710

811
WorkspaceID: TypeAlias = PositiveInt
912

1013

14+
class WorkspaceScope(StrAutoEnum):
15+
PRIVATE = auto()
16+
SHARED = auto()
17+
ALL = auto()
18+
19+
20+
class WorkspaceQuery(BaseModel):
21+
workspace_scope: WorkspaceScope
22+
workspace_id: PositiveInt | None = None
23+
24+
@validator("workspace_id", pre=True, always=True)
25+
@classmethod
26+
def validate_workspace_id(cls, value, values):
27+
scope = values.get("workspace_scope")
28+
if scope == WorkspaceScope.SHARED and value is None:
29+
raise ValueError(
30+
"workspace_id must be provided when workspace_scope is SHARED."
31+
)
32+
if scope != WorkspaceScope.SHARED and value is not None:
33+
raise ValueError(
34+
"workspace_id should be None when workspace_scope is not SHARED."
35+
)
36+
return value
37+
38+
1139
#
1240
# DB
1341
#

services/web/server/src/simcore_service_webserver/projects/_crud_api_read.py

Lines changed: 24 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,23 @@
66
"""
77

88
from aiohttp import web
9-
from models_library.access_rights import AccessRights
109
from models_library.api_schemas_webserver._base import OutputSchema
1110
from models_library.api_schemas_webserver.projects import ProjectListItem
12-
from models_library.folders import FolderID
11+
from models_library.folders import FolderID, FolderQuery, FolderScope
1312
from models_library.projects import ProjectID
1413
from models_library.rest_ordering import OrderBy
15-
from models_library.users import GroupID, UserID
16-
from models_library.workspaces import WorkspaceID
14+
from models_library.users import UserID
15+
from models_library.workspaces import WorkspaceID, WorkspaceQuery, WorkspaceScope
1716
from pydantic import NonNegativeInt
1817
from servicelib.utils import logged_gather
18+
from simcore_postgres_database.models.projects import ProjectType
1919
from simcore_postgres_database.webserver_models import ProjectType as ProjectTypeDB
2020
from simcore_service_webserver.workspaces._workspaces_api import (
2121
check_user_workspace_access,
2222
)
2323

2424
from ..catalog.client import get_services_for_user_in_product
2525
from ..folders import _folders_db as folders_db
26-
from ..workspaces import _workspaces_db as workspaces_db
2726
from . import projects_api
2827
from ._permalink_api import update_or_pop_permalink_in_project
2928
from .db import ProjectDBAPI
@@ -36,7 +35,6 @@ async def _append_fields(
3635
user_id: UserID,
3736
project: ProjectDict,
3837
is_template: bool,
39-
workspace_access_rights: dict[GroupID, AccessRights] | None,
4038
model_schema_cls: type[OutputSchema],
4139
):
4240
# state
@@ -50,12 +48,6 @@ async def _append_fields(
5048
# permalink
5149
await update_or_pop_permalink_in_project(request, project)
5250

53-
# replace project access rights (if project is in workspace)
54-
if workspace_access_rights:
55-
project["accessRights"] = {
56-
gid: access.dict() for gid, access in workspace_access_rights.items()
57-
}
58-
5951
# validate
6052
return model_schema_cls.parse_obj(project).data(exclude_unset=True)
6153

@@ -110,38 +102,39 @@ async def list_projects( # pylint: disable=too-many-arguments
110102
db_projects, db_project_types, total_number_projects = await db.list_projects(
111103
product_name=product_name,
112104
user_id=user_id,
113-
workspace_id=workspace_id,
114-
folder_id=folder_id,
105+
workspace_query=(
106+
WorkspaceQuery(
107+
workspace_scope=WorkspaceScope.SHARED, workspace_id=workspace_id
108+
)
109+
if workspace_id
110+
else WorkspaceQuery(workspace_scope=WorkspaceScope.PRIVATE)
111+
),
112+
folder_query=(
113+
FolderQuery(folder_scope=FolderScope.SPECIFIC, folder_id=folder_id)
114+
if folder_id
115+
else FolderQuery(folder_scope=FolderScope.ROOT)
116+
),
115117
# attrs
116118
filter_by_project_type=ProjectTypeAPI.to_project_type_db(project_type),
117119
filter_by_services=user_available_services,
118120
filter_trashed=trashed,
119121
filter_hidden=show_hidden,
120122
# composed attrs
121-
search=search,
123+
filter_by_text=search,
122124
# pagination
123125
offset=offset,
124126
limit=limit,
125127
# order
126128
order_by=order_by,
127129
)
128130

129-
# If workspace, override project access rights
130-
workspace_access_rights = None
131-
if workspace_id:
132-
workspace_db = await workspaces_db.get_workspace_for_user(
133-
app, user_id=user_id, workspace_id=workspace_id, product_name=product_name
134-
)
135-
workspace_access_rights = workspace_db.access_rights
136-
137131
projects: list[ProjectDict] = await logged_gather(
138132
*(
139133
_append_fields(
140134
request,
141135
user_id=user_id,
142136
project=prj,
143137
is_template=prj_type == ProjectTypeDB.TEMPLATE,
144-
workspace_access_rights=workspace_access_rights,
145138
model_schema_cls=ProjectListItem,
146139
)
147140
for prj, prj_type in zip(db_projects, db_project_types)
@@ -170,19 +163,18 @@ async def list_projects_full_search(
170163
request.app, user_id, product_name, only_key_versions=True
171164
)
172165

173-
(
174-
db_projects,
175-
db_project_types,
176-
total_number_projects,
177-
) = await db.list_projects_full_search(
178-
user_id=user_id,
166+
(db_projects, db_project_types, total_number_projects,) = await db.list_projects(
179167
product_name=product_name,
168+
user_id=user_id,
169+
workspace_query=WorkspaceQuery(workspace_scope=WorkspaceScope.ALL),
170+
folder_query=FolderQuery(folder_scope=FolderScope.ALL),
180171
filter_by_services=user_available_services,
181-
text=text,
172+
filter_by_text=text,
173+
filter_tag_ids_list=tag_ids_list,
174+
filter_by_project_type=ProjectType.STANDARD,
182175
offset=offset,
183176
limit=limit,
184177
order_by=order_by,
185-
tag_ids_list=tag_ids_list,
186178
)
187179

188180
projects: list[ProjectDict] = await logged_gather(
@@ -192,7 +184,6 @@ async def list_projects_full_search(
192184
user_id=user_id,
193185
project=prj,
194186
is_template=prj_type == ProjectTypeDB.TEMPLATE,
195-
workspace_access_rights=None,
196187
model_schema_cls=ProjectListItem,
197188
)
198189
for prj, prj_type in zip(db_projects, db_project_types)

0 commit comments

Comments
 (0)