Overview
The Admin API provides endpoints for administrators to review proposals, manage the review queue, and manage users. All endpoints require the ADMIN role.
All admin endpoints require authentication with the ADMIN role. Access is enforced by the @PreAuthorize("hasRole('ADMIN')") annotation at the controller level.
Get Pending Proposals
curl -X GET https://api.example.com/api/admin/proposals \
-H "Authorization: Bearer YOUR_TOKEN"
GET /api/admin/proposals
Authorization: Bearer YOUR_TOKEN
Retrieve all pending proposals for the admin’s department. The proposals returned depend on the administrator’s department:
- YOUTH_UNION - PENDING_L1 proposals for Youth Union events
- STUDENT_ASSOCIATION - PENDING_L1 proposals for Student Association events
- FACULTY - All PENDING_L2 proposals
- RECTOR - All PENDING_L3 proposals
Response
Success message indicating the department
Array of proposal objects (ProposalDTO)
{
"statusCode": 200,
"message": "Proposals for department YOUTH_UNION retrieved successfully",
"data": [
{
"proposalID": 1,
"title": "Spring Tech Conference 2024",
"description": "A comprehensive tech conference",
"proposedDate": "2024-05-15",
"startTime": "09:00:00",
"endTime": "17:00:00",
"venue": "Main Auditorium",
"capacity": 300,
"organizationType": "YOUTH_UNION",
"status": "PENDING_L1",
"attachmentsJson": "[{\"name\":\"budget.pdf\"}]",
"submittedAt": "2024-03-05T09:00:00",
"reviewedAt": null,
"reviewedByID": null,
"rejectionReason": null,
"organizerID": 12,
"organizerName": "John Smith"
}
],
"timestamp": "2024-03-07T10:30:00"
}
Get Proposal by ID
curl -X GET https://api.example.com/api/admin/proposals/1 \
-H "Authorization: Bearer YOUR_TOKEN"
GET /api/admin/proposals/{proposalID}
Authorization: Bearer YOUR_TOKEN
Retrieve detailed information about a specific proposal.
Path Parameters
ID of the proposal to retrieve
Response
{
"statusCode": 200,
"message": "Proposal retrieved successfully",
"data": {
"proposalID": 1,
"title": "Spring Tech Conference 2024",
"description": "A comprehensive tech conference featuring industry leaders and hands-on workshops",
"proposedDate": "2024-05-15",
"startTime": "09:00:00",
"endTime": "17:00:00",
"venue": "Main Auditorium",
"capacity": 300,
"organizationType": "YOUTH_UNION",
"status": "PENDING_L1",
"attachmentsJson": "[{\"name\":\"budget.pdf\",\"url\":\"https://...\"}]",
"submittedAt": "2024-03-05T09:00:00",
"reviewedAt": null,
"reviewedByID": null,
"rejectionReason": null,
"organizerID": 12,
"organizerName": "John Smith"
},
"timestamp": "2024-03-07T10:30:00"
}
Approve Proposal
curl -X PUT https://api.example.com/api/admin/proposals/1/approve \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"comment": "Excellent proposal. Budget is well-planned."
}'
PUT /api/admin/proposals/{proposalID}/approve
Content-Type: application/json
Authorization: Bearer YOUR_TOKEN
Approve a proposal. Depending on the current status and organization type, this may:
- Move to the next approval level (L1 → L2 → L3)
- Create an event if all approvals are complete
Path Parameters
ID of the proposal to approve
Request Body
Optional approval comment or feedback
Response
Success message: “Proposal approved successfully”
{
"statusCode": 200,
"message": "Proposal approved successfully",
"data": null,
"timestamp": "2024-03-07T10:30:00"
}
Reject Proposal
curl -X PUT https://api.example.com/api/admin/proposals/1/reject \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"rejectionReason": "Budget exceeds available funding. Please revise and resubmit."
}'
PUT /api/admin/proposals/{proposalID}/reject
Content-Type: application/json
Authorization: Bearer YOUR_TOKEN
Reject a proposal with a reason. The organizer can then revise and resubmit.
Path Parameters
ID of the proposal to reject
Request Body
Reason for rejecting the proposal (required)
Response
{
"statusCode": 200,
"message": "Proposal has been rejected",
"data": null,
"timestamp": "2024-03-07T10:30:00"
}
Get Unified Review Queue
curl -X GET https://api.example.com/api/admin/queue \
-H "Authorization: Bearer YOUR_TOKEN"
GET /api/admin/queue
Authorization: Bearer YOUR_TOKEN
Get a unified review queue containing both new proposals and event modification requests, sorted by submission date (newest first).
Response
Success message: “Unified review queue retrieved successfully”
Array of review queue items
ID of the proposal or update request
Event ID (only for MODIFICATION type)
Title of the proposal or event update
Type of review: NEW_PROPOSAL or MODIFICATION
ISO 8601 timestamp when submitted
{
"statusCode": 200,
"message": "Unified review queue retrieved successfully",
"data": [
{
"id": 5,
"eventID": null,
"title": "Spring Tech Conference 2024",
"reviewType": "NEW_PROPOSAL",
"submittedAt": "2024-03-07T09:00:00"
},
{
"id": 2,
"eventID": 10,
"title": "Career Fair 2024",
"reviewType": "MODIFICATION",
"submittedAt": "2024-03-06T14:30:00"
},
{
"id": 3,
"eventID": null,
"title": "Alumni Networking Night",
"reviewType": "NEW_PROPOSAL",
"submittedAt": "2024-03-05T11:15:00"
}
],
"timestamp": "2024-03-07T10:30:00"
}
User Management
List Users
curl -X GET 'https://api.example.com/api/admin/users?page=0&size=10&role=STUDENT&search=john' \
-H "Authorization: Bearer YOUR_TOKEN"
GET /api/admin/users?page=0&size=10&role=STUDENT&accountStatus=ACTIVE&search=john
Authorization: Bearer YOUR_TOKEN
Retrieve a paginated list of users with optional filtering.
Query Parameters
Filter by role: STUDENT, ORGANIZER, EVENT_ORGANIZER, ADMIN
Filter by account status: ACTIVE, SUSPENDED, PENDING_VERIFICATION
Response
{
"statusCode": 200,
"message": "User list fetched",
"data": {
"content": [
{
"userID": 1,
"email": "[email protected]",
"firstName": "John",
"lastName": "Doe",
"role": "STUDENT",
"accountStatus": "ACTIVE",
"createdAt": "2024-01-15T10:00:00",
"lastLogin": "2024-03-07T08:30:00"
}
],
"totalElements": 150,
"totalPages": 15,
"size": 10,
"number": 0
},
"timestamp": "2024-03-07T10:30:00"
}
Update User Status
curl -X PUT 'https://api.example.com/api/admin/users/5/status?status=SUSPENDED' \
-H "Authorization: Bearer YOUR_TOKEN"
PUT /api/admin/users/{userID}/status?status=SUSPENDED
Authorization: Bearer YOUR_TOKEN
Update a user’s account status.
Path Parameters
Query Parameters
New status: ACTIVE, SUSPENDED, PENDING_VERIFICATION
Response
{
"statusCode": 200,
"message": "Account status updated to SUSPENDED",
"data": null,
"timestamp": "2024-03-07T10:30:00"
}
Update User Role
curl -X PUT 'https://api.example.com/api/admin/users/5/role?role=ORGANIZER' \
-H "Authorization: Bearer YOUR_TOKEN"
PUT /api/admin/users/{userID}/role?role=ORGANIZER
Authorization: Bearer YOUR_TOKEN
Update a user’s role in the system.
Path Parameters
Query Parameters
New role: STUDENT, ORGANIZER, EVENT_ORGANIZER, ADMIN
Response
{
"statusCode": 200,
"message": "User role updated to ORGANIZER",
"data": null,
"timestamp": "2024-03-07T10:30:00"
}
Department-Based Access Control
From AdminController.java:123-129:
private AdminDepartment resolveAdminDepartment(CustomUserDetails userDetails) {
Administrator admin = extractAdmin(userDetails);
if (admin.getDepartment() == null) {
throw new ForbiddenException("Administrator has no department assigned.");
}
return admin.getDepartment();
}
Admins only see proposals and requests relevant to their department:
- YOUTH_UNION - Youth Union proposals at L1
- STUDENT_ASSOCIATION - Student Association proposals at L1
- FACULTY - All proposals at L2 (faculty level)
- RECTOR - All proposals at L3 (rector level)