fix(metadata): hide inactive projects from user list

Project selection previously relied only on membership, so inactive projects remained visible. Filter at the repository boundary and add regression coverage.
This commit is contained in:
2026-09-10 14:49:53 +08:00
parent bd857ea5e1
commit 10a7a66a41
2 changed files with 55 additions and 1 deletions
@@ -465,7 +465,10 @@ class MetadataRepository:
models.UserProjectMembership, models.UserProjectMembership,
models.UserProjectMembership.project_id == models.Project.id, models.UserProjectMembership.project_id == models.Project.id,
) )
.where(models.UserProjectMembership.user_id == user_id) .where(
models.UserProjectMembership.user_id == user_id,
models.Project.status == "active",
)
.order_by(models.Project.name) .order_by(models.Project.name)
) )
result = await self.session.execute(stmt) result = await self.session.execute(stmt)
@@ -0,0 +1,51 @@
from types import SimpleNamespace
from unittest.mock import AsyncMock
from uuid import uuid4
import pytest
from sqlalchemy.dialects import postgresql
from app.infra.db.metadb.repositories.metadata_repository import MetadataRepository
@pytest.fixture
def anyio_backend():
return "asyncio"
class _ProjectListResult:
def __init__(self, rows):
self._rows = rows
def all(self):
return self._rows
@pytest.mark.anyio
async def test_list_projects_for_user_only_queries_active_projects():
user_id = uuid4()
project = SimpleNamespace(
id=uuid4(),
name="Active Project",
code="active-project",
description=None,
gs_workspace="active-project",
map_extent=None,
status="active",
)
session = SimpleNamespace(
execute=AsyncMock(return_value=_ProjectListResult([(project, "member")]))
)
projects = await MetadataRepository(session).list_projects_for_user(user_id)
statement = session.execute.await_args.args[0]
sql = str(
statement.compile(
dialect=postgresql.dialect(),
compile_kwargs={"literal_binds": True},
)
)
assert "user_project_membership.user_id" in sql
assert "projects.status = 'active'" in sql
assert [item.code for item in projects] == ["active-project"]