Skip to content

Commit 71f537f

Browse files
refactor: Consolidate query logic with parameter approach
1 parent ae558a9 commit 71f537f

1 file changed

Lines changed: 50 additions & 40 deletions

File tree

src/dstack/_internal/server/services/projects.py

Lines changed: 50 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,9 @@ async def list_user_accessible_projects(
8181
if user.global_role == GlobalRole.ADMIN:
8282
projects = await list_project_models(session=session)
8383
else:
84-
projects = await _list_user_accessible_project_models(session=session, user=user)
84+
projects = await list_user_project_models(
85+
session=session, user=user, include_public_non_member=True
86+
)
8587

8688
projects = sorted(projects, key=lambda p: p.created_at)
8789
return [
@@ -90,37 +92,6 @@ async def list_user_accessible_projects(
9092
]
9193

9294

93-
async def _list_user_accessible_project_models(
94-
session: AsyncSession,
95-
user: UserModel,
96-
) -> List[ProjectModel]:
97-
"""
98-
Get projects that a user can access:
99-
1. Projects where user is a member (regardless of public/private)
100-
2. Public projects where user is not a member
101-
"""
102-
res = await session.execute(
103-
select(ProjectModel)
104-
.where(
105-
ProjectModel.deleted == False,
106-
# Either user is a member, OR project is public and user is not a member
107-
(
108-
# User is a member (regardless of public/private)
109-
ProjectModel.id.in_(
110-
select(MemberModel.project_id).where(MemberModel.user_id == user.id)
111-
)
112-
) | (
113-
# OR project is public and user is not a member
114-
(ProjectModel.is_public == True) &
115-
ProjectModel.id.notin_(
116-
select(MemberModel.project_id).where(MemberModel.user_id == user.id)
117-
)
118-
)
119-
)
120-
)
121-
return list(res.scalars().all())
122-
123-
12495
async def list_projects(session: AsyncSession) -> List[Project]:
12596
projects = await list_project_models(session=session)
12697
return [
@@ -291,19 +262,58 @@ async def list_user_project_models(
291262
session: AsyncSession,
292263
user: UserModel,
293264
include_members: bool = False,
265+
include_public_non_member: bool = False,
294266
) -> List[ProjectModel]:
267+
"""
268+
Get projects for a user.
269+
270+
Args:
271+
session: Database session
272+
user: User model
273+
include_members: Whether to join and load project members
274+
include_public_non_member: Whether to include public projects where user is not a member
275+
276+
Returns:
277+
List of ProjectModel instances
278+
"""
295279
options = []
296280
if include_members:
297281
options.append(joinedload(ProjectModel.members))
298-
res = await session.execute(
299-
select(ProjectModel)
300-
.where(
301-
MemberModel.project_id == ProjectModel.id,
302-
MemberModel.user_id == user.id,
303-
ProjectModel.deleted == False,
282+
283+
if include_public_non_member:
284+
# Get both member projects AND public non-member projects
285+
res = await session.execute(
286+
select(ProjectModel)
287+
.where(
288+
ProjectModel.deleted == False,
289+
# Either user is a member, OR project is public and user is not a member
290+
(
291+
# User is a member (regardless of public/private)
292+
ProjectModel.id.in_(
293+
select(MemberModel.project_id).where(MemberModel.user_id == user.id)
294+
)
295+
) | (
296+
# OR project is public and user is not a member
297+
(ProjectModel.is_public == True) &
298+
ProjectModel.id.notin_(
299+
select(MemberModel.project_id).where(MemberModel.user_id == user.id)
300+
)
301+
)
302+
)
303+
.options(*options)
304304
)
305-
.options(*options)
306-
)
305+
else:
306+
# Original logic - only member projects
307+
res = await session.execute(
308+
select(ProjectModel)
309+
.where(
310+
MemberModel.project_id == ProjectModel.id,
311+
MemberModel.user_id == user.id,
312+
ProjectModel.deleted == False,
313+
)
314+
.options(*options)
315+
)
316+
307317
return list(res.scalars().unique().all())
308318

309319

0 commit comments

Comments
 (0)