> ## Documentation Index
> Fetch the complete documentation index at: https://docs.meridian.study/llms.txt
> Use this file to discover all available pages before exploring further.

# Atlas Backend (Routes & APIs)

> Endpoint map, auth/permission requirements, and request/response shapes

## Route mounting map

Atlas endpoints are split across multiple Express routers:

```javascript theme={null}
// 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 Prefix            | File                          | Purpose                                                                         |
| ----------------------- | ----------------------------- | ------------------------------------------------------------------------------- |
| `/`                     | `orgRoutes.js`                | General org CRUD operations                                                     |
| `/org-roles`            | `orgRoleRoutes.js`            | Roles and membership management                                                 |
| `/org-management`       | `orgManagementRoutes.js`      | Platform admin (config, verification, analytics, finance config & budget queue) |
| `/org-budgets`          | `orgBudgetRoutes.js`          | Org-scoped budgets (templates metadata, CRUD, workflow actions, export)         |
| `/org-messages`         | `orgMessageRoutes.js`         | Org messaging and announcements                                                 |
| `/org-event-management` | `orgEventManagementRoutes.js` | Org-scoped event management                                                     |

## Common auth behavior

Most endpoints require `verifyToken` and depend on cookies (`withCredentials: true`).

<Note>
  **Frontend integration:**

  * `useFetch` retries after POSTing `/refresh-token` on 401
  * `apiRequest` also attempts `/refresh-token` and retries
</Note>

## `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`

<RequestExample>
  ```bash theme={null}
  GET /get-org-by-name/computer-science-club?exhaustive=true
  Authorization: Bearer <token>
  ```
</RequestExample>

<ResponseExample>
  ```json theme={null}
  {
    "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
  }
  ```
</ResponseExample>

**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`

<RequestExample>
  ```bash theme={null}
  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>
  ```
</RequestExample>

<ResponseExample>
  ```json theme={null}
  {
    "success": true,
    "org": {
      "_id": "...",
      "org_name": "Computer Science Club",
      "owner": "..."
    }
  }
  ```
</ResponseExample>

**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`

<RequestExample>
  ```bash theme={null}
  POST /abc123/apply-to-org
  Content-Type: application/json
  Authorization: Bearer <token>

  {
    "formAnswers": {
      "question1": "I love coding",
      "question2": "3 years"
    }
  }
  ```
</RequestExample>

<ResponseExample>
  ```json theme={null}
  {
    "success": true,
    "member": {
      "_id": "...",
      "org_id": "abc123",
      "user_id": "...",
      "role": "member"
    }
  }
  ```
</ResponseExample>

**Auth**: Required

**Behavior**:

<CodeGroup>
  ```javascript title="Immediate join" theme={null}
  // If org.requireApprovalForJoin === false
  // Creates OrgMember(role='member') immediately
  ```

  ```javascript title="Application required" theme={null}
  // If org.requireApprovalForJoin === true
  // Creates OrgMemberApplication(status='pending')
  // If org has memberForm, creates FormResponse snapshot
  // Notifies org admins via NotificationService template 'org_member_applied'
  ```
</CodeGroup>

### 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

| Endpoint                            | Method | Permission Required |
| ----------------------------------- | ------ | ------------------- |
| `/org-roles/:orgId/roles`           | GET    | `view_roles`        |
| `/org-roles/:orgId/roles`           | POST   | `manage_roles`      |
| `/org-roles/:orgId/roles`           | PUT    | `manage_roles`      |
| `/org-roles/:orgId/roles/:roleName` | PUT    | `manage_roles`      |
| `/org-roles/:orgId/roles/:roleName` | DELETE | `manage_roles`      |

<Warning>
  DELETE endpoint disallows deleting roles assigned to members.
</Warning>

### Membership + applications

#### GET `/org-roles/:orgId/members`

<RequestExample>
  ```bash theme={null}
  GET /org-roles/abc123/members
  Authorization: Bearer <token>
  ```
</RequestExample>

<ResponseExample>
  ```json theme={null}
  {
    "members": [
      {
        "_id": "...",
        "user_id": { "_id": "...", "name": "..." },
        "role": "admin",
        "status": "active"
      }
    ],
    "applications": [
      {
        "_id": "...",
        "user_id": { "_id": "...", "name": "..." },
        "status": "pending",
        "formResponse": { ... }
      }
    ],
    "count": 10
  }
  ```
</ResponseExample>

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

<RequestExample>
  ```bash theme={null}
  POST /org-roles/abc123/members/user456/role
  Content-Type: application/json
  Authorization: Bearer <token>

  {
    "role": "treasurer"
  }
  ```
</RequestExample>

**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`

<Warning>
  Prevents removing org owner.
</Warning>

#### 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`

<RequestExample>
  ```bash theme={null}
  GET /org-management/analytics?timeRange=30d
  Authorization: Bearer <token>
  ```
</RequestExample>

<ResponseExample>
  ```json theme={null}
  {
    "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
      }
    ]
  }
  ```
</ResponseExample>

**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/config` — `verifyToken` + `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`.

| Method | Path                                                             | Permission                                 |                 |
| ------ | ---------------------------------------------------------------- | ------------------------------------------ | --------------- |
| GET    | `/org-budgets/:orgId/budget-templates`                           | `view_finances`                            |                 |
| GET    | `/org-budgets/:orgId/budgets`                                    | `view_finances`                            |                 |
| GET    | `/org-budgets/:orgId/budgets/:budgetId`                          | `view_finances`                            |                 |
| POST   | `/org-budgets/:orgId/budgets`                                    | `manage_finances`                          |                 |
| PATCH  | `/org-budgets/:orgId/budgets/:budgetId`                          | `manage_finances`                          |                 |
| POST   | `/org-budgets/:orgId/budgets/:budgetId/submit`                   | `manage_finances`                          |                 |
| POST   | `/org-budgets/:orgId/budgets/:budgetId/comments`                 | `manage_finances`                          |                 |
| PUT    | `/org-budgets/:orgId/budgets/:budgetId/stages/:stageKey/approve` | `manage_finances` (org\_permission stages) |                 |
| PUT    | `.../reject`, `.../request-revision`                             | `manage_finances` (org\_permission stages) |                 |
| GET    | \`/org-budgets/:orgId/budgets/:budgetId/export?format=json       | csv\`                                      | `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.

***

## Related pages

<CardGroup cols={2}>
  <Card title="Atlas architecture" icon="sitemap" href="/atlas/architecture">
    How Atlas models, routes, and UIs connect beyond this route map.
  </Card>

  <Card title="Atlas permissions" icon="key" href="/atlas/permissions">
    Org roles and middleware that gate the endpoints listed here.
  </Card>

  <Card title="Event management API" icon="calendar" href="/api-reference/event-management">
    Narrative REST reference for org events, RSVPs, and agendas.
  </Card>

  <Card title="Event dashboard" icon="table-columns" href="/atlas/event-dashboard">
    Organizer flows implemented on top of `orgEventManagementRoutes`.
  </Card>

  <Card title="Backend best practices" icon="server" href="/backend/best-practices">
    Shared Express patterns: `getModels`, `verifyToken`, error shapes.
  </Card>

  <Card title="Multi-tenant identity" icon="users" href="/backend/multi-tenant-identity">
    How platform admins and memberships interact with org APIs.
  </Card>
</CardGroup>
