forked from yvv/decision
Compartimentation : isolation stricte des données par espace de travail
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
- Ajout clause else IS NULL sur tous les endpoints list (protocols, decisions, mandates, documents, groups, votes) — sans X-Organization → données globales seulement, jamais le contenu d'un autre espace - _get_protocol/_get_decision/_get_mandate : org_id propagé à tous les endpoints GET/PUT/DELETE/advance/assign/revoke/steps → 404 si UUID d'un autre espace - votes.py : list_vote_sessions filtre via JOIN VotingProtocol.organization_id - groups.py : suppression _org_id_from_header() mort, create_group assigne organization_id correctement Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -34,13 +34,20 @@ router = APIRouter()
|
||||
# ── Helpers ─────────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
async def _get_protocol(db: AsyncSession, protocol_id: uuid.UUID) -> VotingProtocol:
|
||||
"""Fetch a voting protocol by ID with its formula config, or raise 404."""
|
||||
result = await db.execute(
|
||||
async def _get_protocol(
|
||||
db: AsyncSession, protocol_id: uuid.UUID, org_id: uuid.UUID | None = None
|
||||
) -> VotingProtocol:
|
||||
"""Fetch a voting protocol by ID within the active org scope, or raise 404."""
|
||||
stmt = (
|
||||
select(VotingProtocol)
|
||||
.options(selectinload(VotingProtocol.formula_config))
|
||||
.where(VotingProtocol.id == protocol_id)
|
||||
)
|
||||
if org_id is not None:
|
||||
stmt = stmt.where(VotingProtocol.organization_id == org_id)
|
||||
else:
|
||||
stmt = stmt.where(VotingProtocol.organization_id.is_(None))
|
||||
result = await db.execute(stmt)
|
||||
protocol = result.scalar_one_or_none()
|
||||
if protocol is None:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Protocole introuvable")
|
||||
@@ -74,6 +81,8 @@ async def list_protocols(
|
||||
|
||||
if org_id is not None:
|
||||
stmt = stmt.where(VotingProtocol.organization_id == org_id)
|
||||
else:
|
||||
stmt = stmt.where(VotingProtocol.organization_id.is_(None))
|
||||
if vote_type is not None:
|
||||
stmt = stmt.where(VotingProtocol.vote_type == vote_type)
|
||||
|
||||
@@ -111,7 +120,7 @@ async def create_protocol(
|
||||
await db.refresh(protocol)
|
||||
|
||||
# Reload with formula config
|
||||
protocol = await _get_protocol(db, protocol.id)
|
||||
protocol = await _get_protocol(db, protocol.id, org_id)
|
||||
return VotingProtocolOut.model_validate(protocol)
|
||||
|
||||
|
||||
@@ -119,9 +128,10 @@ async def create_protocol(
|
||||
async def get_protocol(
|
||||
id: uuid.UUID,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
org_id: uuid.UUID | None = Depends(get_active_org_id),
|
||||
) -> VotingProtocolOut:
|
||||
"""Get a single voting protocol with its formula configuration."""
|
||||
protocol = await _get_protocol(db, id)
|
||||
protocol = await _get_protocol(db, id, org_id)
|
||||
return VotingProtocolOut.model_validate(protocol)
|
||||
|
||||
|
||||
@@ -131,12 +141,13 @@ async def update_protocol(
|
||||
payload: VotingProtocolUpdate,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
identity: DuniterIdentity = Depends(get_current_identity),
|
||||
org_id: uuid.UUID | None = Depends(get_active_org_id),
|
||||
) -> VotingProtocolOut:
|
||||
"""Update a voting protocol (meta-governance).
|
||||
|
||||
Only provided fields will be updated. Requires authentication.
|
||||
"""
|
||||
protocol = await _get_protocol(db, id)
|
||||
protocol = await _get_protocol(db, id, org_id)
|
||||
|
||||
update_data = payload.model_dump(exclude_unset=True)
|
||||
for field, value in update_data.items():
|
||||
@@ -145,7 +156,7 @@ async def update_protocol(
|
||||
await db.commit()
|
||||
|
||||
# Reload with formula config
|
||||
protocol = await _get_protocol(db, protocol.id)
|
||||
protocol = await _get_protocol(db, protocol.id, org_id)
|
||||
return VotingProtocolOut.model_validate(protocol)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user