feat(project): user_id isolation in create_project, list_projects and _to_dict
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
fe357668b4
commit
815400f3b6
|
|
@ -21,10 +21,10 @@ class ProjectManager:
|
|||
"""Gestiona projectes: metadades a BD, fitxers a StorageService."""
|
||||
|
||||
@classmethod
|
||||
def create_project(cls, name: str = "Unnamed Project", storage=None) -> Dict[str, Any]:
|
||||
def create_project(cls, name: str = "Unnamed Project", storage=None, user_id: str = None) -> Dict[str, Any]:
|
||||
project_id = str(uuid.uuid4())
|
||||
with get_session() as db:
|
||||
proj = ProjectModel(id=project_id, name=name, status="created")
|
||||
proj = ProjectModel(id=project_id, name=name, status="created", user_id=user_id)
|
||||
db.add(proj)
|
||||
db.commit()
|
||||
db.refresh(proj)
|
||||
|
|
@ -59,10 +59,12 @@ class ProjectManager:
|
|||
db.commit()
|
||||
|
||||
@classmethod
|
||||
def list_projects(cls, limit: int = 50) -> List[Dict[str, Any]]:
|
||||
def list_projects(cls, limit: int = 50, user_id: str = None) -> List[Dict[str, Any]]:
|
||||
from sqlalchemy import select, desc
|
||||
with get_session() as db:
|
||||
stmt = select(ProjectModel).order_by(desc(ProjectModel.created_at)).limit(limit)
|
||||
if user_id is not None:
|
||||
stmt = stmt.where(ProjectModel.user_id == user_id)
|
||||
projects = db.execute(stmt).scalars().all()
|
||||
for p in projects:
|
||||
db.expunge(p)
|
||||
|
|
@ -302,6 +304,7 @@ class ProjectManager:
|
|||
return {
|
||||
"id": proj.id,
|
||||
"project_id": proj.id,
|
||||
"user_id": proj.user_id,
|
||||
"name": proj.name,
|
||||
"status": proj.status,
|
||||
"analysis_summary": proj.analysis_summary,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
"""Tests d'aïllament de projectes per user_id."""
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def _db(in_memory_db):
|
||||
pass
|
||||
|
||||
|
||||
def _make_user(email, role='user'):
|
||||
from backend.app.models.db_models import UserModel
|
||||
from backend.app.db import get_session
|
||||
with get_session() as db:
|
||||
user = UserModel(email=email, name=email, role=role, status='active')
|
||||
db.add(user)
|
||||
db.commit()
|
||||
db.refresh(user)
|
||||
return user.id
|
||||
|
||||
|
||||
def test_list_projects_filtered_by_user():
|
||||
from backend.app.models.project import ProjectManager
|
||||
uid1 = _make_user('u1@test.com')
|
||||
uid2 = _make_user('u2@test.com')
|
||||
|
||||
ProjectManager.create_project(name="U1-A", user_id=uid1)
|
||||
ProjectManager.create_project(name="U1-B", user_id=uid1)
|
||||
ProjectManager.create_project(name="U2-A", user_id=uid2)
|
||||
|
||||
u1_projects = ProjectManager.list_projects(user_id=uid1)
|
||||
assert len(u1_projects) == 2
|
||||
assert all(p['user_id'] == uid1 for p in u1_projects)
|
||||
|
||||
u2_projects = ProjectManager.list_projects(user_id=uid2)
|
||||
assert len(u2_projects) == 1
|
||||
assert u2_projects[0]['name'] == 'U2-A'
|
||||
|
||||
|
||||
def test_list_projects_no_filter_returns_all():
|
||||
from backend.app.models.project import ProjectManager
|
||||
uid1 = _make_user('all1@test.com')
|
||||
uid2 = _make_user('all2@test.com')
|
||||
ProjectManager.create_project(name="P1", user_id=uid1)
|
||||
ProjectManager.create_project(name="P2", user_id=uid2)
|
||||
all_projects = ProjectManager.list_projects(user_id=None)
|
||||
assert len(all_projects) >= 2
|
||||
|
||||
|
||||
def test_create_project_assigns_user_id():
|
||||
from backend.app.models.project import ProjectManager
|
||||
uid = _make_user('owner@test.com')
|
||||
proj = ProjectManager.create_project(name="Owned", user_id=uid)
|
||||
assert proj['user_id'] == uid
|
||||
|
||||
|
||||
def test_to_dict_includes_user_id():
|
||||
from backend.app.models.project import ProjectManager
|
||||
uid = _make_user('dict@test.com')
|
||||
proj = ProjectManager.create_project(name="DictTest", user_id=uid)
|
||||
assert 'user_id' in proj
|
||||
assert proj['user_id'] == uid
|
||||
Loading…
Reference in New Issue