Documentation Index
Fetch the complete documentation index at: https://mintlify.com/SidneyEmeka/church_management_system/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Church operations form the core of the Church Management System. This guide covers creating churches, managing membership, and communicating with members.
Church Data Structure
Each church contains:
- Pastor - User profile ID of the church pastor (creator)
- Name - Unique church name
- Address - Physical location
- Support Contact - Phone, email, and website
- Members - Array of user profile IDs
Creating a Church
Prerequisites
Only users with the pastor role can create churches. Ensure you’ve registered as a pastor and completed your profile.
Create Church Endpoint
POST /api/church/createchurch/:pastorId
Authorization: Bearer <token>
Content-Type: application/json
{
"name": "Grace Community Church",
"address": "789 Faith Avenue, Springfield, IL 62701",
"supportcontact": {
"phone": "+1-555-0123",
"email": "[email protected]",
"website": "https://gracecommunity.org"
}
}
Request Parameters
| Parameter | Location | Type | Description |
|---|
pastorId | URL path | String | The profile ID of the pastor creating the church |
name | Body | String | Unique church name |
address | Body | String | Church physical address |
supportcontact | Body | Object | Contact information |
Church Creation Logic
The system automatically handles church creation with validation:
const createAchurch = async (req, res) => {
const pastorID = req.params.pastorId;
const churchData = req.body;
try {
// Check if church name already exists
let church = await churchObject.findOne({ name: req.body.name });
if (church) {
res.status(200).send({
success: false,
message: `Church Name Already exists`,
data: church,
});
} else {
// Create church with pastor as first member
church = churchObject({
pastor: pastorID,
...churchData,
members: [pastorID], // Pastor automatically becomes first member
});
await church.save();
// Populate pastor and members data
church = await churchObject
.findById(church._id)
.populate({
path: "pastor",
select: "-_id -createdAt -updatedAt -__v",
populate: {
path: "authDetails",
select: "-_id -password -createdAt -updatedAt -__v",
},
})
.populate({
path: "members",
select: "-_id -createdAt -updatedAt -__v",
populate: {
path: "authDetails",
select: "-_id -password -createdAt -updatedAt -__v",
},
});
res.status(201).send({
success: true,
message: `Church Created`,
data: church,
});
}
} catch (err) {
res.status(500).send({
success: false,
message: "Church Creation not successful",
data: err.message,
});
}
};
Success Response
{
"success": true,
"message": "Church Created",
"data": {
"_id": "507f1f77bcf86cd799439011",
"name": "Grace Community Church",
"address": "789 Faith Avenue, Springfield, IL 62701",
"supportcontact": {
"phone": "+1-555-0123",
"email": "[email protected]",
"website": "https://gracecommunity.org"
},
"pastor": {
"name": "Pastor John Smith",
"phoneNumber": 5551234567,
"authDetails": {
"email": "[email protected]",
"role": "pastor"
}
},
"members": [
{
"name": "Pastor John Smith",
"phoneNumber": 5551234567
}
]
}
}
The pastor who creates the church is automatically added as the first member of the members array.
Managing Church Membership
Join a Church
Members can join any church using the church ID:
POST /api/church/:id/join
Authorization: Bearer <token>
Content-Type: application/json
{
"userId": "507f1f77bcf86cd799439012"
}
Join Church Logic
Verify church exists
const theChurch = await churchObject.findById(churchId);
if (!theChurch) {
return res.status(404).send({
success: false,
message: "Unable to join church",
data: "Church with this Id does not exist",
});
}
Check existing membership
const alreadyAmember = await churchObject
.findOne({ _id: churchId, members: userID })
.populate("pastor", "name -_id");
if (alreadyAmember) {
return res.status(200).send({
success: false,
message: "You are already a member of this church",
data: alreadyAmember,
});
}
Add member to church
theChurch.members.push(userID);
await theChurch.save();
res.status(200).send({
success: true,
message: `You have successfully joined ${theChurch.name}`,
data: theChurchNow,
});
Exit a Church
Members can leave a church they’ve joined:
POST /api/church/:id/exit
Authorization: Bearer <token>
Content-Type: application/json
{
"userId": "507f1f77bcf86cd799439012"
}
Exit Church Logic
const exitAChurch = async (req, res) => {
const churchId = req.params.id;
const userID = req.body.userId;
try {
const theChurch = await churchObject.findById(churchId);
if (theChurch) {
const isAmember = await churchObject
.findOne({ _id: churchId, members: userID })
.populate("pastor", "name -_id");
if (isAmember) {
// Remove user from members array
theChurch.members = theChurch.members.filter(
(member) => member.toString() !== userID.toString()
);
await theChurch.save();
res.status(200).send({
success: true,
message: `You have successfully exited ${isAmember.name}`,
data: isAmember,
});
} else {
res.status(400).send({
success: false,
message: "Unable to exit church",
data: "You are not a member of this church",
});
}
}
} catch (err) {
res.status(500).send({
success: false,
message: "Unable to exit church",
data: err.message,
});
}
};
Viewing Churches
Get Pastor’s Churches
Pastors can view all churches they’ve created:
GET /api/church/getchurches/:pastorId
Authorization: Bearer <token>
Response Example
{
"success": true,
"message": "You have 2 church(es)",
"data": [
{
"_id": "507f1f77bcf86cd799439011",
"name": "Grace Community Church",
"address": "789 Faith Avenue, Springfield, IL 62701",
"supportcontact": {
"phone": "+1-555-0123",
"email": "[email protected]",
"website": "https://gracecommunity.org"
},
"pastor": {
"name": "Pastor John Smith",
"phoneNumber": 5551234567
},
"members": [
{ "name": "Pastor John Smith" },
{ "name": "Jane Doe" },
{ "name": "Bob Wilson" }
]
}
]
}
Get User’s Churches
Members can view all churches they belong to:
GET /api/church/user/:id
Authorization: Bearer <token>
Implementation
const getAllUserChurches = async (req, res) => {
const userId = req.params.id;
try {
const theUserChurches = await churchObject
.find({ members: userId })
.select("-__v -createdAt -updatedAt -members")
.populate("pastor", "-_id -__v -createdAt -updatedAt -authDetails");
if (theUserChurches.length > 0) {
res.status(200).send({
success: true,
message: `You are in ${theUserChurches.length} church(es)`,
data: theUserChurches,
});
} else {
res.status(404).send({
success: false,
message: "Unable to fetch churches",
data: "You are not a member of any church yet",
});
}
} catch (err) {
res.status(500).send({
success: false,
message: "Unable to fetch churches",
data: err.message,
});
}
};
Church Communications
Send Email to All Members
Pastors can send emails to all church members:
POST /api/church/sendemailtoall
Authorization: Bearer <token>
Content-Type: application/json
{
"subject": "Sunday Service Announcement",
"message": "<p>Join us this Sunday at 10 AM for our worship service!</p>",
"churchId": "507f1f77bcf86cd799439011",
"pastorId": "507f1f77bcf86cd799439012"
}
Email Sending Logic
const sendEmailToAllMembers = async (req, res) => {
try {
const { subject, message, churchId, pastorId } = req.body;
// Get church with populated member emails
const theChurch = await churchObject.findOne({ _id: churchId }).populate({
path: "members",
populate: {
path: "authDetails",
select: "email",
},
});
if (theChurch) {
// Verify sender is the pastor
if (theChurch.pastor.toString() === pastorId) {
const members = theChurch.members;
if (!members.length) {
return res.status(404).json({ message: "No members found" });
}
// Extract all member emails
const emails = members.map((m) => m.authDetails.email);
// Send email using BCC to protect member privacy
await transporter.sendMail({
from: `${theChurch.name}`,
bcc: emails, // Blind carbon copy for privacy
subject: subject,
html: `<p>${message}</p>`,
});
res.status(200).send({
success: true,
message: `Email sent to ${emails.length} member(s)`,
data: emails,
});
} else {
res.status(400).send({
success: false,
message: "Unable to send emails",
data: "You are not the pastor of this church",
});
}
}
} catch (err) {
res.status(500).send({
success: false,
message: "Unable to send emails",
data: err.message,
});
}
};
Emails are sent using BCC (Blind Carbon Copy) to protect member privacy. No member can see other members’ email addresses.
Complete Church Workflow
Here’s a complete example of church operations:
Pastor creates a church
curl -X POST http://localhost:3001/api/church/createchurch/507f1f77bcf86cd799439012 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <pastor-token>" \
-d '{
"name": "Grace Community Church",
"address": "789 Faith Avenue, Springfield, IL 62701",
"supportcontact": {
"phone": "+1-555-0123",
"email": "[email protected]",
"website": "https://gracecommunity.org"
}
}'
Member joins the church
curl -X PATCH http://localhost:3001/api/church/joinchurch/507f1f77bcf86cd799439011 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <member-token>" \
-d '{
"userId": "507f1f77bcf86cd799439013"
}'
Pastor views church members
curl -X GET http://localhost:3001/api/church/getchurches/507f1f77bcf86cd799439012 \
-H "Authorization: Bearer <pastor-token>"
Pastor sends announcement to members
curl -X POST http://localhost:3001/api/church/sendemailtoall \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <pastor-token>" \
-d '{
"subject": "Sunday Service Update",
"message": "<p>Service starts at 10 AM this Sunday!</p>",
"churchId": "507f1f77bcf86cd799439011",
"pastorId": "507f1f77bcf86cd799439012"
}'
Virtual Fields
The church model includes a virtual field for counting active members:
churchSchema.virtual("activeMembersCount").get(function () {
return this.members?.length || 0;
});
This field is calculated dynamically and not stored in the database.
Error Handling
Common Errors
Duplicate Church Name:
{
"success": false,
"message": "Church Name Already exists",
"data": { /* existing church data */ }
}
Church Not Found:
{
"success": false,
"message": "Unable to join church",
"data": "Church with this Id does not exist"
}
Already a Member:
{
"success": false,
"message": "You are already a member of this church",
"data": { /* church data */ }
}
Not a Member:
{
"success": false,
"message": "Unable to exit church",
"data": "You are not a member of this church"
}
Unauthorized Email Send:
{
"success": false,
"message": "Unable to send emails",
"data": "You are not the pastor of this church"
}
Best Practices
Important Considerations:
- Only pastors can create churches and send emails
- Church names must be unique across the system
- The pastor is automatically added as the first member
- Members can join and leave churches freely
- Email addresses are protected using BCC
- Verify pastor ID matches the authenticated user before allowing church creation
Recommendations:
- Store church IDs on the client side for quick access
- Cache member lists to reduce database queries
- Implement rate limiting on email sending to prevent abuse
- Consider adding church categories or denominations for better organization
- Add image uploads for church logos and photos
Next Steps