All 73 validation checkboxes marked as completed after successful implementation and testing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Clubber
A toolset for managing members of non-profit societies (Vereine) with AI-powered administration.
Overview
Clubber provides a GraphQL API for member management combined with an MCP (Model Context Protocol) server that enables AI assistants to help with society administration tasks.
Current Status: Early development - OpenSpec documentation and project structure in place.
Architecture
The system consists of two main components:
-
GraphQL API - Core backend for member data management
- Built with FastAPI and Strawberry GraphQL
- Database-agnostic design (SQLite for development, PostgreSQL for production)
- SQLAlchemy 2.0 ORM with async support
-
MCP Server - AI assistant integration layer
- Connects to the GraphQL API
- Provides tools for AI agents to manage society operations
- Service account authentication
Tech Stack
- Python 3.11+ - Primary language
- uv - Fast package and project manager
- FastAPI - Async web framework
- Strawberry GraphQL - Type-safe GraphQL with Python type hints
- SQLAlchemy 2.0 - Database ORM
- Alembic - Database migrations
Project Structure
clubber/
├── openspec/ # Specification-driven development
│ ├── project.md # Project conventions and context
│ ├── specs/ # Current specifications
│ └── changes/ # Change proposals
├── CLAUDE.md # AI assistant instructions
└── README.md # This file
Getting Started
Prerequisites
- Python 3.11 or higher
- uv package manager
Setup
# Clone the repository
git clone ssh://git@codeberg.org/gurix/clubber.git
cd clubber
# Install uv if not already installed
curl -LsSf https://astral.sh/uv/install.sh | sh
# Install dependencies
uv sync
# Run database migrations
uv run alembic upgrade head
# (Optional) Seed the database with sample data
PYTHONPATH=. uv run python scripts/seed.py
Running the Server
Start the development server:
uv run uvicorn src.main:app --host 127.0.0.1 --port 8000 --reload
The --reload flag enables auto-restart when code changes are detected.
Access the API:
- GraphQL Playground: http://127.0.0.1:8000/graphql
- API Documentation: http://127.0.0.1:8000/docs
- Root Endpoint: http://127.0.0.1:8000/
API Usage Examples
Member Data Model
Members have the following fields:
firstName(required) - Member's first namelastName(optional) - Member's last namestreet(optional) - Street addressapartmentNumber(optional) - Apartment or unit numberzip(optional) - Postal codecity(optional) - Citycountry(optional) - Countryemail(optional) - Email address (validated when provided)phone(optional) - Phone number in E.164 format (validated when provided)
Key Feature: Only firstName is required. All other fields are optional and can be populated later. Email and phone are validated only when provided (not when null/empty).
GraphQL Queries
List all members:
{
members {
id
firstName
lastName
email
phone
city
}
}
Get a single member:
{
member(id: 1) {
id
firstName
lastName
email
street
city
country
}
}
GraphQL Mutations
Create a member (minimal - only firstName):
mutation {
createMember(input: {
firstName: "Alice"
}) {
id
firstName
email
}
}
Create a member with all fields:
mutation {
createMember(input: {
firstName: "Bob"
lastName: "Johnson"
street: "123 Main St"
apartmentNumber: "4B"
zip: "12345"
city: "Springfield"
country: "USA"
email: "bob.johnson@example.com"
phone: "+14155551234"
}) {
id
firstName
lastName
email
phone
}
}
Update a member:
mutation {
updateMember(input: {
id: 1
email: "updated@example.com"
phone: "+14155559999"
}) {
id
firstName
email
phone
}
}
Delete a member:
mutation {
deleteMember(id: 2)
}
Using curl
Query members:
curl -X POST http://127.0.0.1:8000/graphql \
-H "Content-Type: application/json" \
-d '{"query": "{ members { id firstName lastName email } }"}'
Create a member:
curl -X POST http://127.0.0.1:8000/graphql \
-H "Content-Type: application/json" \
-d '{"query": "mutation { createMember(input: { firstName: \"Charlie\" }) { id firstName } }"}'
Development Workflow
This project uses OpenSpec for specification-driven development:
- Review existing specs in
openspec/specs/ - Create change proposals in
openspec/changes/before implementing features - Validate proposals with
openspec validate --strict - Implement changes following the proposal
- Archive completed changes after deployment
See openspec/AGENTS.md for detailed workflow instructions.
Working with Git Worktrees
We use git worktrees for parallel development:
# Create a worktree for a feature branch
git worktree add ../clubber-feature-name feature/feature-name
# Work in the worktree
cd ../clubber-feature-name
# Remove worktree after merge
git worktree remove ../clubber-feature-name
Contributing
- Read
openspec/project.mdfor project conventions - For new features, create an OpenSpec proposal first
- Follow the coding style (Black, isort, ruff)
- Write tests for new functionality
- Use conventional commits (
feat:,fix:,docs:, etc.)
License
The MIT License
Contact
Markus Graf - info@markusgraf.ch
Acknowledgments
Built with support from: