Skip to main content

Route mounting map

Atlas endpoints are split across multiple Express routers:
// Meridian/backend/app.js (excerpt)
app.use(orgRoutes); // Mounted at /
app.use('/org-roles', orgRoleRoutes);
app.use('/org-management', orgManagementRoutes);
app.use('/org-budgets', orgBudgetRoutes); // orgBudgetRoutes from routes/orgBudgetRoutes.js
app.use('/org-messages', orgMessageRoutes);
app.use('/org-event-management', orgEventManagementRoutes);
Route PrefixFilePurpose
/orgRoutes.jsGeneral org CRUD operations
/org-rolesorgRoleRoutes.jsRoles and membership management
/org-managementorgManagementRoutes.jsPlatform admin (config, verification, analytics, finance config & budget queue)
/org-budgetsorgBudgetRoutes.jsOrg-scoped budgets (templates metadata, CRUD, workflow actions, export)
/org-messagesorgMessageRoutes.jsOrg messaging and announcements
/org-event-managementorgEventManagementRoutes.jsOrg-scoped event management

Common auth behavior

Most endpoints require verifyToken and depend on cookies (withCredentials: true).
Frontend integration:
  • useFetch retries after POSTing /refresh-token on 401
  • apiRequest also attempts /refresh-token and retries

orgRoutes (mounted at /)

File: Meridian/backend/routes/orgRoutes.js

GET /get-org/:id

  • Auth: none
  • Behavior: Org.find({ _id: orgId }) (returns array)

GET /get-org-by-name/:name

GET /get-org-by-name/computer-science-club?exhaustive=true
Authorization: Bearer <token>
{
  "overview": {
    "_id": "...",
    "org_name": "Computer Science Club",
    "org_description": "...",
    "memberForm": { ... }
  },
  "members": [
    {
      "_id": "...",
      "user_id": { "_id": "...", "name": "..." },
      "role": "admin"
    }
  ],
  "followers": [...],
  "isMember": true,
  "isFollower": false,
  "isPending": false
}
Auth: Required (verifyToken) Query params:
  • exhaustive=true enables extra counters (e.g. eventCount)
Returns:
  • overview (org doc, populated memberForm)
  • members (OrgMember rows, populated user_id)
  • followers (OrgFollower rows, populated user_id)
  • isMember, isFollower, isPending

POST /create-org

POST /create-org
Content-Type: multipart/form-data
Authorization: Bearer <token>

org_name=Computer Science Club
org_description=We code things
weekly_meeting=Monday 6pm
custom_roles=["treasurer","secretary"]
image=<file>
{
  "success": true,
  "org": {
    "_id": "...",
    "org_name": "Computer Science Club",
    "owner": "..."
  }
}
Auth: Required Multipart: Supports image upload (S3) Side effects:
  • creates Org
  • creates OrgMember with role owner
  • pushes orgId into User.clubAssociations
Key request fields (form-data):
  • org_name, org_description
  • weekly_meeting
  • custom_roles (JSON string array)

POST /edit-org

  • Auth: required; owner-only (compares org.owner to req.user.userId)
  • Multipart: supports image upload and S3 update
  • Supports editing:
    • org_name, org_description, positions, weekly_meeting
    • requireApprovalForJoin
    • memberForm (creates or updates Form)

POST /:orgId/apply-to-org

POST /abc123/apply-to-org
Content-Type: application/json
Authorization: Bearer <token>

{
  "formAnswers": {
    "question1": "I love coding",
    "question2": "3 years"
  }
}
{
  "success": true,
  "member": {
    "_id": "...",
    "org_id": "abc123",
    "user_id": "...",
    "role": "member"
  }
}
Auth: Required Behavior:
// If org.requireApprovalForJoin === false
// Creates OrgMember(role='member') immediately

GET /get-meetings/:name

  • Auth: required
  • Fetches the org by org_name, then returns events where:
    • hostingId: org._id, hostingType: 'Org', type: 'meeting'

GET /:orgId/events

  • Auth: required
  • Lists upcoming org events (approved / not-applicable), paginated.

orgRoleRoutes (mounted at /org-roles)

File: Meridian/backend/routes/orgRoleRoutes.js This router is the “authoritative” API for:
  • org roles (Org.positions)
  • org membership (OrgMember)
  • applications (OrgMemberApplication)
Notable endpoints (subset):

Roles

EndpointMethodPermission Required
/org-roles/:orgId/rolesGETview_roles
/org-roles/:orgId/rolesPOSTmanage_roles
/org-roles/:orgId/rolesPUTmanage_roles
/org-roles/:orgId/roles/:roleNamePUTmanage_roles
/org-roles/:orgId/roles/:roleNameDELETEmanage_roles
DELETE endpoint disallows deleting roles assigned to members.

Membership + applications

GET /org-roles/:orgId/members

GET /org-roles/abc123/members
Authorization: Bearer <token>
{
  "members": [
    {
      "_id": "...",
      "user_id": { "_id": "...", "name": "..." },
      "role": "admin",
      "status": "active"
    }
  ],
  "applications": [
    {
      "_id": "...",
      "user_id": { "_id": "...", "name": "..." },
      "status": "pending",
      "formResponse": { ... }
    }
  ],
  "count": 10
}

POST /org-roles/:orgId/members/:userId/role

POST /org-roles/abc123/members/user456/role
Content-Type: application/json
Authorization: Bearer <token>

{
  "role": "treasurer"
}
Side effects:
  • Assigns/changes a member’s role
  • Pushes the org into User.clubAssociations if missing

DELETE /org-roles/:orgId/members/:userId

Permission: manage_members
Prevents removing org owner.

POST /org-roles/:orgId/applications/:applicationId/approve

Permission: manage_members Side effect: Turns an application into an active OrgMember

orgManagementRoutes (mounted at /org-management)

File: Meridian/backend/routes/orgManagementRoutes.js This is the platform-admin surface (intended for admin/root roles).

Verification requests

  • POST /org-management/verification-requests
    • requires org membership role owner or admin (checked inline)
    • requires system config verificationEnabled
    • validates verificationType against OrgManagementConfig.verificationTiers
  • GET /org-management/verification-requests
    • admin/root can see all
    • others see only requests for orgs where they are owner/admin
  • PUT /org-management/verification-requests/:requestId
    • admin/root only
    • on approve, updates Org.verified, Org.verificationType, etc.

Config

  • GET /org-management/config → admin/root only
    • creates a default config document if missing
  • PUT /org-management/config → admin/root only
    • converts nested objects into dot-notation $set paths

Analytics

GET /org-management/analytics

GET /org-management/analytics?timeRange=30d
Authorization: Bearer <token>
{
  "totalOrgs": 150,
  "verifiedOrgs": 45,
  "newOrgs": 12,
  "totalMembers": 2500,
  "eventsCreated": 320,
  "verificationRequests": {
    "pending": 8,
    "approved": 45,
    "rejected": 12
  },
  "topOrgs": [
    {
      "org_name": "Computer Science Club",
      "memberCount": 120
    }
  ]
}
Auth: Admin/root only Query params:
  • timeRange: 7d, 30d, or 90d
Aggregates: Org counts, member counts, events, verification request stats

Orgs list + export

  • GET /org-management/organizations
    • admin/root only
    • server-side pagination + per-org computed memberCount and recentEventCount
  • GET /org-management/organizations/export?format=json|csv

Finance (CMS Phase 2)

  • GET /org-management/finance/configverifyToken + requireAdmin; returns budgetTemplates and workflowPresets
  • PUT /org-management/finance/config — admin; replaces budgetTemplates / workflowPresets when sent in body
  • GET /org-management/finance/budgets?status=&search=&page=&limit= — admin; cross-org list with optional filters
  • PUT /org-management/organizations/:orgId/budgets/:budgetId/stages/:stageKey/approve|reject|request-revision — admin; platform_admin workflow stages only

orgBudgetRoutes (mounted at /org-budgets)

File: Meridian/backend/routes/orgBudgetRoutes.js Business logic: Meridian/backend/services/budgetService.js.
MethodPathPermission
GET/org-budgets/:orgId/budget-templatesview_finances
GET/org-budgets/:orgId/budgetsview_finances
GET/org-budgets/:orgId/budgets/:budgetIdview_finances
POST/org-budgets/:orgId/budgetsmanage_finances
PATCH/org-budgets/:orgId/budgets/:budgetIdmanage_finances
POST/org-budgets/:orgId/budgets/:budgetId/submitmanage_finances
POST/org-budgets/:orgId/budgets/:budgetId/commentsmanage_finances
PUT/org-budgets/:orgId/budgets/:budgetId/stages/:stageKey/approvemanage_finances (org_permission stages)
PUT.../reject, .../request-revisionmanage_finances (org_permission stages)
GET`/org-budgets/:orgId/budgets/:budgetId/export?format=jsoncsv`view_finances

orgMessageRoutes (mounted at /org-messages)

File: Meridian/backend/routes/orgMessageRoutes.js Endpoints:
  • POST /org-messages/:orgId/messages
  • GET /org-messages/:orgId/messages
  • GET /org-messages/:orgId/messages/:messageId
  • POST /org-messages/:orgId/messages/:messageId/like
  • POST /org-messages/:orgId/messages/:messageId/reply
  • PUT /org-messages/:orgId/messages/:messageId
  • DELETE /org-messages/:orgId/messages/:messageId
See /atlas/messaging for details.

orgEventManagementRoutes (mounted at /org-event-management)

File: Meridian/backend/routes/orgEventManagementRoutes.js This is an org-scoped “events management” API gated by requireEventManagement('orgId') (i.e. manage_events). Endpoints:
  • GET /org-event-management/:orgId/analytics
  • GET /org-event-management/:orgId/events
  • GET /org-event-management/:orgId/events/:eventId
  • POST /org-event-management/:orgId/events/bulk-action
  • POST /org-event-management/:orgId/event-templates
  • GET /org-event-management/:orgId/event-templates
  • POST /org-event-management/:orgId/events/from-template/:templateId
See /atlas/event-analytics for details.

Atlas architecture

How Atlas models, routes, and UIs connect beyond this route map.

Atlas permissions

Org roles and middleware that gate the endpoints listed here.

Event management API

Narrative REST reference for org events, RSVPs, and agendas.

Event dashboard

Organizer flows implemented on top of orgEventManagementRoutes.

Backend best practices

Shared Express patterns: getModels, verifyToken, error shapes.

Multi-tenant identity

How platform admins and memberships interact with org APIs.