fix crosstable trustee

This commit is contained in:
ValueOn AG 2026-01-26 23:48:19 +01:00
parent 7ca957f664
commit ee15fd64b0
2 changed files with 40 additions and 8 deletions

View file

@ -1095,7 +1095,8 @@ class TrusteeObjects:
def deleteDocument(self, documentId: str) -> bool:
"""Delete a document.
Note: organisationId and contractId removed - feature instance IS the organisation.
All position-document cross-table entries (TrusteePositionDocument) referencing
this document are deleted first, then the document.
"""
# Get existing document to check creator
existingRecords = self.db.getRecordset(TrusteeDocument, recordFilter={"id": documentId})
@ -1112,6 +1113,7 @@ class TrusteeObjects:
logger.warning(f"User {self.userId} lacks permission to delete document")
return False
self._deletePositionDocumentLinksForDocument(documentId)
return self.db.recordDelete(TrusteeDocument, documentId)
# ===== Position CRUD =====
@ -1259,7 +1261,8 @@ class TrusteeObjects:
def deletePosition(self, positionId: str) -> bool:
"""Delete a position.
Note: organisationId and contractId removed - feature instance IS the organisation.
All position-document cross-table entries (TrusteePositionDocument) referencing
this position are deleted first, then the position.
"""
# Get existing position to check creator
existingRecords = self.db.getRecordset(TrusteePosition, recordFilter={"id": positionId})
@ -1276,6 +1279,7 @@ class TrusteeObjects:
logger.warning(f"User {self.userId} lacks permission to delete position")
return False
self._deletePositionDocumentLinksForPosition(positionId)
return self.db.recordDelete(TrusteePosition, positionId)
# ===== Position-Document Link CRUD =====
@ -1423,6 +1427,22 @@ class TrusteeObjects:
return self.db.recordDelete(TrusteePositionDocument, linkId)
def _deletePositionDocumentLinksForDocument(self, documentId: str) -> None:
"""Delete all position-document cross-table entries referencing this document."""
links = self.db.getRecordset(TrusteePositionDocument, recordFilter={"documentId": documentId})
for link in links:
linkId = link.get("id")
if linkId:
self.db.recordDelete(TrusteePositionDocument, linkId)
def _deletePositionDocumentLinksForPosition(self, positionId: str) -> None:
"""Delete all position-document cross-table entries referencing this position."""
links = self.db.getRecordset(TrusteePositionDocument, recordFilter={"positionId": positionId})
for link in links:
linkId = link.get("id")
if linkId:
self.db.recordDelete(TrusteePositionDocument, linkId)
# ===== Trustee-specific Access Check =====
def getUserAccessForOrganisation(self, userId: str, organisationId: str) -> List[Dict[str, Any]]:

View file

@ -878,6 +878,12 @@ class FeatureInstanceUserResponse(BaseModel):
enabled: bool
class FeatureInstanceUserUpdate(BaseModel):
"""Request model for updating a feature instance user (roles and active flag)"""
roleIds: List[str] = Field(..., description="Role IDs to assign")
enabled: Optional[bool] = Field(None, description="Whether this user's access is active (omit to leave unchanged)")
@router.get("/instances/{instanceId}/users", response_model=List[FeatureInstanceUserResponse])
@limiter.limit("60/minute")
async def list_feature_instance_users(
@ -1161,18 +1167,19 @@ async def update_feature_instance_user_roles(
request: Request,
instanceId: str,
userId: str,
roleIds: List[str],
data: FeatureInstanceUserUpdate,
context: RequestContext = Depends(getRequestContext)
) -> Dict[str, Any]:
"""
Update a user's roles in a feature instance.
Update a user's roles and active flag in a feature instance.
Replaces all existing FeatureAccessRole records with new ones.
If enabled is provided, updates the FeatureAccess.enabled flag.
Args:
instanceId: FeatureInstance ID
userId: User ID to update
roleIds: New list of role IDs
data: roleIds and optional enabled
"""
try:
rootInterface = getRootInterface()
@ -1215,6 +1222,10 @@ async def update_feature_instance_user_roles(
featureAccessId = existingAccess[0].get("id")
# Update enabled flag if provided
if data.enabled is not None:
rootInterface.db.recordModify(FeatureAccess, featureAccessId, {"enabled": data.enabled})
# Delete existing FeatureAccessRole records
existingRoles = rootInterface.db.getRecordset(
FeatureAccessRole,
@ -1224,7 +1235,7 @@ async def update_feature_instance_user_roles(
rootInterface.db.recordDelete(FeatureAccessRole, role.get("id"))
# Create new FeatureAccessRole records
for roleId in roleIds:
for roleId in data.roleIds:
featureAccessRole = FeatureAccessRole(
featureAccessId=featureAccessId,
roleId=roleId
@ -1232,14 +1243,15 @@ async def update_feature_instance_user_roles(
rootInterface.db.recordCreate(FeatureAccessRole, featureAccessRole.model_dump())
logger.info(
f"User {context.user.id} updated roles for user {userId} in feature instance {instanceId}: {roleIds}"
f"User {context.user.id} updated roles for user {userId} in feature instance {instanceId}: {data.roleIds}"
)
return {
"featureAccessId": featureAccessId,
"userId": userId,
"featureInstanceId": instanceId,
"roleIds": roleIds
"roleIds": data.roleIds,
"enabled": data.enabled if data.enabled is not None else existingAccess[0].get("enabled", True)
}
except HTTPException: