The volunteer system allows donors to contribute their time and skills instead of money. Here's how it works:
NGO logs in → Creates Volunteer Opportunity → Sets volunteer details
- Navigate to "Create Volunteer Opportunity"
- Fill in details:
- Title: "Weekend Literacy Tutor"
- Description: "Teach reading skills to children"
- Location: "Community Center Room 2"
- Hours needed: 4 hours
- Max volunteers: 10 people
- Date/Time: Sept 15, 2025, 9 AM - 1 PM
- Skills required: "Basic teaching skills"
- Linked Campaign (optional): for disaster response
VolunteerOpportunity created with:
├── active = true
├── currentVolunteers = 0
├── linkedCampaignId = null or campaignId
└── status = ACTIVEDonor logs in → Clicks "Time Donation" → Sees volunteer opportunities
- Login to platform
- Click "Time Donation" button
- Browse list of available volunteer opportunities
- See details like:
- What work needs to be done
- Where and when
- How many hours
- Skills needed
GET /api/donor/volunteer-opportunities
Returns list of opportunities where:
├── active = true
└── currentVolunteers < maxVolunteersDonor selects opportunity → Writes message → Commits hours → Applies
- Click on desired volunteer opportunity
- Fill application form:
- Message: "I have experience teaching and tutoring"
- Hours I can commit: 4 hours
- Availability: Confirm date/time works
- Submit application
Volunteer application created:
├── donorId = "donor123"...NGO logs in → Views volunteer applications → Reviews donor profiles → Approves/Rejects
- Login and navigate to "Volunteer Applications"
- See list of pending applications with:
- Donor name and profile
- Message from donor
- Hours they can commit
- Their volunteer history
- Review and decide to Approve or Reject
If APPROVED:
├── volunteer.status = APPROVED
├── opportunity.currentVolunteers += 1
└── Notification sent to donor
If REJECTED:
├── volunteer.status = REJECTED
└── Rejection notice sent to donorDonor shows up → Does the work → NGO confirms completion
- Donor: Shows up at location at scheduled time
- NGO Coordinator: Assigns specific tasks
- Work: Donor spends committed hours volunteering
- NGO: Marks work as completed in system
Work completion:
├── volunteer.status = COMPLETED
├── volunteer.hoursCompleted = committed hours
├── volunteer.completedDate = now()
└── Donor's total volunteer hours updatedCREATED → PENDING → APPROVED → IN_PROGRESS → COMPLETED
↓
REJECTED
- PENDING: Waiting for NGO review
- APPROVED: NGO accepted the volunteer
- REJECTED: NGO declined the application
- IN_PROGRESS: Volunteer work is happening
- COMPLETED: Work finished successfully
| Money Donation | Time Donation |
|---|---|
| Click "Donate" → Pay → Done | Apply → Get approved → Show up → Work → Complete |
| Instant process | Multi-step process |
| No approval needed | NGO must approve |
| System handles everything | Requires human coordination |
| Unlimited donations possible | Limited by volunteer slots |
Dashboard
├── "Money Donation" button
└── "Time Donation" button
├── Browse volunteer opportunities
├── Apply for positions
├── View my applications
└── See my volunteer history
Dashboard
├── "Create Money Campaign"
└── "Create Volunteer Opportunities"
├── Set volunteer requirements
├── Review applications
├── Approve/reject volunteers
└── Mark work as completed
payments: [
{ donorId, ngoId, amount, status: "SUCCESS" }
]
volunteers: [
{ donorId, opportunityId, ngoId, hoursCommitted, hoursCompleted, status: "COMPLETED" }
]
volunteer_opportunities: [
{ opportunityId, ngoId, title, active, linkedCampaignId=null or campaignId }
]
This updated workflow covers both standing volunteer opportunities and campaign-linked volunteer calls, providing NGOs with flexibility to engage donors any time.
| Method | Path | Role | Purpose |
|---|---|---|---|
| POST | /api/ngo/volunteer-opportunities | NGO | Create standing or campaign-linked volunteer opportunity |
| PUT | /api/ngo/volunteer-opportunities/{id}/close | NGO | Close/disable volunteer opportunity |
| GET | /api/donor/volunteer-opportunities | Donor | Browse all active volunteer opportunities |
| POST | /api/donor/volunteer | Donor | Apply to volunteer |
| GET | /api/donor/volunteers | Donor | View own volunteer applications/history |
| GET | /api/ngo/volunteers | NGO | List volunteer applications for NGO |
| PUT | /api/ngo/volunteers/{volId}/approve | NGO | Approve volunteer application |
| PUT | /api/ngo/volunteers/{volId}/complete | NGO | Mark volunteer work completed |
{
"title": "Weekend Literacy Tutor",
"description": "Teach basic reading to children in grades 3-5.",
"location": "Community Center – Room 2",
"startDate": "2025-09-15T09:00:00",
"endDate": "2025-09-15T13:00:00",
"maxVolunteers": 10,
"skillsRequired": ["Teaching", "Patience"],
"linkedCampaignId": null // or "camp123" when disaster-linked
}{
"opportunityId": "opp123",
"message": "I have prior experience tutoring at shelters.",
"hoursCommitted": 4
}No request body required - JWT for NGO authentication
{
"hoursDone": 4
}{
"success": true,
"message": "Volunteer application submitted",
"data": {
"volunteerId": "vol567",
"status": "PENDING",
"hoursCommitted": 4,
"applicationDate": "2025-08-30T12:06:00"
}
}The Campaign Management System enables NGOs to create, update, and manage fundraising or volunteer-related campaigns. Admins oversee approvals/rejections, while donors can view only approved campaigns. The system also supports automated cleanup of expired campaigns. In case of double rejection of campaign by admin the campaign will got deleted automatically.
NGO logs in → Creates Campaign → Sets details
-
Navigate to "Create Campaign"
-
Provide details:
- Description (≥ 10 characters, required)
- Volunteer Time (optional)
- Expiration Time (optional, ISO format)
Campaign created with:
├── ngoEmail = loggedInUserEmail
├── expirationTime = null or providedDate
├── volunteerTime = optional
├── approved = false
├── pendingCheckup = false
├── manualDeletionAllowed = true if expirationTime == null
└── status = CREATEDNGO logs in → Views own campaigns → Updates as needed
-
View campaigns with GET /api/camp/viewCampaign
-
Update campaign with PUT /api/camp/updateCampaign/{id}
- Can change volunteerTime
- Can set/remove expirationTime
- Reset
pendingCheckupflag
If updated:
├── volunteerTime = updated value
├── expirationTime = new date or null
├── manualDeletionAllowed = false if expirationTime set
├── pendingCheckup = false
└── campaign savedAdmin logs in → Sees unapproved campaigns → Approves or Rejects
- View pending campaigns via GET /api/camp/allUnApproved
- Approve campaign with PUT /api/camp/approve-campaign/{id}
- Reject campaign with PUT /api/camp/reject-campaign/{id} (with feedback)
If APPROVED:
├── campaign.approved = true
└── campaign saved
If REJECTED:
├── campaign.rejectFlag += 1
├── campaign.feedback = feedback message
├── campaign.pendingCheckup = true
├── if rejectFlag >= 2 → campaign deleted
└── campaign savedDonor logs in → Views approved campaigns
- Click "All Approved Campaigns"
- Browse list of active campaigns
GET /api/camp/allApproved
Returns list where:
├── approved = true
└── not expiredNGO requests deletion → System checks rules
- Call DELETE /api/camp/deleteCampaign/{id}
If expirationTime == null:
├── manualDeletionAllowed = true
├── campaign deleted
└── message = "Campaign deleted successfully"
If expirationTime != null:
└── manual deletion not allowed → 403 ForbiddenSystem scheduler runs daily at midnight
- Job checks all campaigns
- Deletes expired ones
If LocalDateTime.now() > expirationTime:
├── campaign removed from DB
└── console log "Deleted expired campaign: {description}"CREATED → PENDING → APPROVED → ACTIVE → EXPIRED (auto-deletion)
↓
REJECTED (→ deleted after 2nd rejection)
- CREATED: NGO created campaign, awaiting admin approval
- PENDING: Waiting for admin review
- APPROVED: Admin accepted the campaign
- REJECTED: Campaign rejected (deleted after 2 rejections)
- ACTIVE: Approved and visible to donors
- EXPIRED: Auto-deleted by scheduler after expiration date
| Volunteer System | Campaign System |
|---|---|
| Requires NGO approval of donor applications | Requires Admin approval of campaigns |
| Volunteer slots limit participation | No limit on donations |
| Status: PENDING → APPROVED → IN_PROGRESS → COMPLETED | Status: CREATED → APPROVED/REJECTED → ACTIVE → EXPIRED |
| Donors donate time & skills | Donors contribute money (and optional volunteer time) |
| Manual + real-world coordination | Mostly system + admin-driven |
Dashboard
├── Create Campaign
├── View Campaigns
├── Update Campaign
└── Delete Campaign (if allowed)
Dashboard
├── View Unapproved Campaigns
├── Approve Campaign
└── Reject Campaign (with feedback)
Dashboard
└── Browse Approved Campaigns
campaigns: [
{ campaignId, ngoEmail, description, expirationTime, volunteerTime,
approved, rejectFlag, feedback, pendingCheckup, manualDeletionAllowed }
]
| Method | Path | Role | Purpose |
|---|---|---|---|
| POST | /api/camp/createCampaign | NGO | Create a new campaign |
| GET | /api/camp/viewCampaign | NGO | View campaigns created by logged-in NGO |
| PUT | /api/camp/updateCampaign/{id} | NGO | Update campaign details |
| DELETE | /api/camp/deleteCampaign/{id} | NGO | Delete campaign (if allowed) |
| GET | /api/camp/allUnApproved | Admin | Browse unapproved campaigns |
| PUT | /api/camp/approve-campaign/{id} | Admin | Approve a campaign |
| PUT | /api/camp/reject-campaign/{id} | Admin | Reject campaign (with feedback) |
| GET | /api/camp/allApproved | Donor | Browse approved campaigns |
{
"description": "Flood relief fund for rural areas",
"expirationTime": "2025-09-30T23:59:00",
"volunteerTime": 20
}{
"volunteerTime": 15,
"expirationTime": "2025-10-10T23:59:00"
}"Feedback: Campaign lacks detailed plan."No request body required
{
"success": true,
"message": "Campaign updated successfully",
"data": {
"campaignId": "camp123",
"status": "APPROVED",
"expirationTime": "2025-09-30T23:59:00",
"manualDeletionAllowed": false
}Donor logs in → Selects campaign → Contributes money and/or volunteer time
- Navigate to a campaign
- Enter donation amount
- Optionally provide volunteer time
- Submit donation
POST /api/camp/{campaignId}
Creates CampaignDonation:
├── donorEmail = loggedInUserEmail
├── donationAmount = provided amount
├── volunteerTime = optional
Updates Campaign:
├── totalRaised += donationAmount
├── donations list updated
└── campaign saved