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."""
|
"""Gestiona projectes: metadades a BD, fitxers a StorageService."""
|
||||||
|
|
||||||
@classmethod
|
@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())
|
project_id = str(uuid.uuid4())
|
||||||
with get_session() as db:
|
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.add(proj)
|
||||||
db.commit()
|
db.commit()
|
||||||
db.refresh(proj)
|
db.refresh(proj)
|
||||||
|
|
@ -59,10 +59,12 @@ class ProjectManager:
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
@classmethod
|
@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
|
from sqlalchemy import select, desc
|
||||||
with get_session() as db:
|
with get_session() as db:
|
||||||
stmt = select(ProjectModel).order_by(desc(ProjectModel.created_at)).limit(limit)
|
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()
|
projects = db.execute(stmt).scalars().all()
|
||||||
for p in projects:
|
for p in projects:
|
||||||
db.expunge(p)
|
db.expunge(p)
|
||||||
|
|
@ -302,6 +304,7 @@ class ProjectManager:
|
||||||
return {
|
return {
|
||||||
"id": proj.id,
|
"id": proj.id,
|
||||||
"project_id": proj.id,
|
"project_id": proj.id,
|
||||||
|
"user_id": proj.user_id,
|
||||||
"name": proj.name,
|
"name": proj.name,
|
||||||
"status": proj.status,
|
"status": proj.status,
|
||||||
"analysis_summary": proj.analysis_summary,
|
"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