Skip to content

Conversation

@solarmarius
Copy link

  • Complete REST API endpoints for committees (list, get, create, update, delete)
  • Committee member management (add, remove, list with pagination)
  • Committee application workflow with email notifications
  • Support for filtering by status and open spots availability
  • Automatic slug generation with uniqueness validation
  • Full test coverage for all endpoints and edge cases
  • Database indexes for committee member uniqueness
  • Test seeds for committee data

API Endpoints

GET /api/committee/ # List with filters & pagination
GET /api/committee/{id} # Get single committee
POST /api/committee/ # Create (admin)
PUT /api/committee/{id} # Update (admin)
DELETE /api/committee/{id} # Delete (admin)
POST /api/committee/{id}/apply # Apply to committee
POST /api/committee/{id}/members # Add member (admin)
GET /api/committee/{id}/members # List members (admin)
DELETE /api/committee/{id}/members/{userId} # Remove member (admin)

New Collections

committees - Stores committee definitions

{
  id: UUID,                    // Primary key
  name: String,                // Committee name
  slug: String,                // URL-friendly identifier (e.g., "tech-committee")
  description: String?,        // Optional description
  status: Enum,                // "active" | "inactive" (reuses existing Status enum)
  hasOpenSpots: Boolean,       // Whether accepting new members
  email: EmailStr,             // Contact email for applications
  createdAt: DateTime,
  updatedAt: DateTime,
  createdBy: EmailStr          // Email of admin who created it
}

committeeMembers - Junction table tracking committee membership

{
  committeeId: UUID,           // Foreign key to committees
  userId: UUID,                // Foreign key to members
  addedBy: EmailStr,           // Admin who added the member
  addedAt: DateTime,
  active: Boolean,             // Soft-delete flag (true = current member)
  leftAt: DateTime?,           // When member was removed
  leftBy: EmailStr?            // Admin who removed the member
}

Indexes

Unique Constraint

db.committeeMembers.create_index(
    [("committeeId", 1), ("userId", 1)],
    unique=True
)
  • Enforces one membership record per user per committee
  • Prevents duplicate member assignments
  • Allows member reactivation (update existing inactive record)

Seeding

Test Seeds

  • 4 sample committees (Board, Tech, Social, Inactive)
  • Seeds committees without members by default
  • Allows tests to control membership state

Seeding Logic

  • New seed_committees() function (76 LOC)
  • Parameter seed_members=False to skip auto-population
  • Sets createdBy to first admin in members collection

Data Retention

Soft-delete Pattern

Member removals preserve history:

  • active: false instead of document deletion
  • leftAt timestamp recorded
  • leftBy tracks which admin removed them
  • Enables audit trails and re-activation

- Complete REST API endpoints for committees (list, get, create, update, delete)
- Committee member management (add, remove, list with pagination)
- Committee application workflow with email notifications
- Support for filtering by status and open spots availability
- Automatic slug generation with uniqueness validation
- Full test coverage (455 lines) for all endpoints and edge cases
- Database indexes for committee member uniqueness
- Test seeds for committee data
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant