Skip to content

Feat/super admin approval - #15

Merged
wailbentafat merged 3 commits into
mainfrom
feat/Super-Admin-approval
Mar 18, 2026
Merged

wailbentafat merged 3 commits into
mainfrom
feat/Super-Admin-approval

Conversation

@ademboukabes

Copy link
Copy Markdown
Collaborator

Summary

This PR adds the staff upload approval workflow using the current staff/admin model.

What was added

  • create upload requests from a batch of photos
  • enforce a maximum of 20 photos per request
  • store uploaded photos temporarily in upload_request_photos
  • allow admins to list pending requests
  • allow admins to approve or reject requests
  • move staged photos into the final photos table on approval
  • delete staged photos on approval or rejection
  • store optional rejection reasons
  • create staff notifications for approval/rejection events

Technical changes

  • added staff_notifications table and queries
  • added upload_request_photos staging table and queries
  • extended upload_requests with photo_count and rejection_reason
  • added staff upload and notification routes
  • added upload request and staff notification services
  • updated container wiring and generated models/queriers
  • merged Alembic heads and fixed the staff password migration for existing rows

Endpoints

  • POST /stuff/uploads/request
  • GET /stuff/uploads/my-requests
  • GET /stuff/uploads/pending
  • POST /stuff/uploads/{request_id}/approve
  • POST /stuff/uploads/{request_id}/reject
  • GET /stuff/notifications
  • POST /stuff/notifications/{notification_id}/read

@wailbentafat
wailbentafat marked this pull request as draft March 15, 2026 22:04
Comment thread app/router/staff/notifications.py Outdated
router = APIRouter(prefix="/notifications", tags=["staff-notifications"])


def _to_response(notification: StaffNotification) -> StaffNotificationSchema:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this logique must be in schema

Comment thread app/router/staff/notifications.py Outdated
)


@router.post("/{notification_id}/read", response_model=StaffNotificationSchema)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

must accept batch notfication read

Comment thread app/router/staff/uploads.py Outdated
router = APIRouter(prefix="/uploads", tags=["staff-uploads"])


def _to_response(upload_request: UploadRequestDetails) -> UploadRequestSchema:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also must be in schema folder in the dto

current_staff_user: StaffUser = Depends(get_current_staff_user),
container: Container = Depends(get_container),
) -> UploadRequestSchema:
upload_request = await container.upload_requests_service.create_request(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

validate the format and size for the pic

approved_by=admin_staff_user,
)
return _to_response(upload_request)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

those three are the same endpoint with one filter approaved and rejected and pending

Comment thread app/deps/staff_auth.py Outdated
async def require_admin_staff(
current_staff_user: Annotated[StaffUser, Depends(get_current_staff_user)],
) -> StaffUser:
if _role_value(current_staff_user.role) != "admin":

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here the role must be multi lead not admin

Comment thread app/schema/request/staff/uploads.py Outdated

class CreateUploadRequestPhotoRequest(BaseModel):
drive_file_id: str
staging_storage_key: str

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this logique is wrong how frontend will kno the storage key

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This implementation relies heavily on getattr and uses Sequence[object] for photos, which removes type safety and makes the code harder to reason about.

Because the function accepts object, it must defensively access fields like drive_file_id, staging_storage_key, taken_at, etc. using getattr. This suggests the input type is not well-defined. A clearer approach would be to define a dedicated input model (e.g., UploadPhotoInput using a dataclass or Pydantic model) and type the parameter as Sequence[UploadPhotoInput]. That would remove the need for repeated getattr calls and make the contract of the function explicit.

Comment thread app/service/upload_requests.py Outdated
for staged_photo in staged_photos:
created_photo = await self.photo_querier.create_photo(
event_id=upload_request.event_id,
uploaded_by=None,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ur forcing here none

@ademboukabes

Copy link
Copy Markdown
Collaborator Author

i addressed the review feedback:

  • moved response mapping logic out of routers into response schemas
  • added batch notification read
  • unified upload request listing with filters
  • switched approval guard to multi_team_lead
  • replaced the generic photo input with a typed DTO
  • removed staging_storage_key from the request payload and generate it server-side
  • added request validation for image format and size
  • improved upload request error handling for invalid event references and duplicate batch entries

@wailbentafat

Copy link
Copy Markdown
Collaborator

i addressed the review feedback:

  • moved response mapping logic out of routers into response schemas
  • added batch notification read
  • unified upload request listing with filters
  • switched approval guard to multi_team_lead
  • replaced the generic photo input with a typed DTO
  • removed staging_storage_key from the request payload and generate it server-side
  • added request validation for image format and size
  • improved upload request error handling for invalid event references and duplicate batch entries

okeyy 9owa fix merge issues brk

@ademboukabes
ademboukabes force-pushed the feat/Super-Admin-approval branch from 51c3bb7 to 5b993d2 Compare March 18, 2026 12:40
@ademboukabes
ademboukabes marked this pull request as ready for review March 18, 2026 12:40
@wailbentafat
wailbentafat merged commit 5904e57 into main Mar 18, 2026
1 check passed
@ademboukabes
ademboukabes deleted the feat/Super-Admin-approval branch March 18, 2026 17:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants