- Python 52.7%
- JavaScript 28.1%
- HTML 12.4%
- Shell 3.3%
- CSS 2.9%
- Other 0.6%
| cask | ||
| cask_requests | ||
| deploy | ||
| docs | ||
| scripts | ||
| static | ||
| templates | ||
| .env.example | ||
| .gitignore | ||
| CLAUDE.md | ||
| dev | ||
| devenv.nix | ||
| feature-ideas.md | ||
| gunicorn.conf.py | ||
| LICENSE | ||
| Makefile | ||
| manage.py | ||
| pyproject.toml | ||
| README.md | ||
c-ask
A Django form tool for c-base members and aliens (non-members) to formally request something from the circle (c-base's plenum group) in a structured, auditable way.
On submission, c-ask sends a formatted email to the appropriate address (circle@c-base.org, cultorga@c-base.org, or counselor@c-base.org) with a link to review the request on the c-ask dashboard. A backoffice lets staff examine requests, add comments, close/reopen items, generate plenum topic lists, and respond via templates.
Request types
| Type | Who | Description |
|---|---|---|
| Event | Everyone | Request c-base infrastructure for an event (bar, projector, streaming, etc.) |
| Filming | Everyone | Use c-base as a filming location |
| Info Topic | Everyone | General announcement or member presentation |
| Dispute | Members | File a formal dispute between members |
| Funding | Members | Apply for project/EVA/event funding |
| Circle Membership | Members | Apply to join c-base's circle |
| CEY / Soundlab / C-Lab Membership | Members | Apply for group membership + key access |
Tech stack
- Framework: Django 6.0 (ASGI)
- Database: PostgreSQL
- Auth: django-allauth (c-base OAuth provider, Apple, Discord, GitHub, Google, etc.) + MFA (TOTP, WebAuthn, recovery codes)
- Admin UI: django-unfold
- Forms/UI: Bootstrap 5, crispy-forms, HTMX, Chart.js
- Async: Django Channels (Redis channel layer)
- Email: django-mailer + template-based email composition
- Dev: Nix (devenv.sh), uv, pytest, pyright
Quick start
Prerequisites
Run locally
# Enter the dev environment (spawns PostgreSQL, Mailpit, dev server, Sass watcher)
devenv shell
# Run migrations and load fixtures
make setup
# Open the dev server at http://127.0.0.1:8000
# Mailpit catches all emails at http://127.0.0.1:8025
Tests
# Unit + integration tests
make test
# E2E tests (Playwright)
make e2e
Linting
make lint # ruff check
make format # ruff format
make typecheck # pyright strict mode
make watch-typecheck # file-watcher mode
Database
make migrate # apply pending migrations
make makemigrations # generate new migrations
make graphmodels # draw model diagram to docs/models.png
Project structure
├── cask/ # Django project config (settings, URLs, ASGI)
│ ├── settings.py # all Django settings
│ ├── asgi.py # ASGI entry point (Channels)
│ └── urls.py # top-level URL routing
├── cask_requests/ # Django app (models, views, forms, emails)
│ ├── models.py # request/appeal domain models
│ ├── views.py # list/create/detail/update views
│ ├── forms.py # form definitions with crispy
│ ├── emails.py # email composition & templates
│ ├── email_templates/ # email body templates per request type
│ ├── markdown_templates/ # email header/footer markdown
│ ├── admin.py # unfold admin customizations
│ ├── filters.py # django-filter filter sets
│ ├── signals.py # post-save signal handlers
│ ├── widgets.py # custom form widgets
│ ├── templatetags/ # template filters (cask_extras, json_serializer)
│ └── migrations/ # schema migrations (0001–0007)
├── templates/ # project templates
│ ├── base.html # base layout (navbar, bootstrap, htmx)
│ ├── index.html # landing page (request type cards)
│ ├── office/ # backoffice templates
│ ├── requests/ # request form/detail templates
│ └── account/ # allauth template overrides
├── deploy/ # production deployment (nginx, systemd, backup)
├── scripts/ # utility scripts (runserver, sass, lint)
├── production_static/ # collected static files (auto-generated)
├── devenv.nix # dev environment definition
├── pyproject.toml # dependencies & tool configs
├── .env.example # environment variable reference
└── docs/PLAN.md # domain logic & request type specs
Configuration
Copy .env.example to .env and set the required values. The critical variables:
| Variable | Required | Notes |
|---|---|---|
SECRET_KEY |
Yes | Never deploy without one |
DB_PASSWORD |
Yes | PostgreSQL password |
DEBUG |
No | False in production (required) |
CASKDEV |
No | Set to 1 for dev mode |
ALLOWED_HOSTS_EXTRA |
No | Comma-separated production domains |
MAIL_HOST / MAIL_PORT |
No | Mailpit default: localhost:1025 |
Production deployment
A one-shot bootstrap script is provided:
# Run on a fresh VM as root
sudo bash deploy/setup.sh [--domain circle.c-base.org]
This installs system packages, sets up PostgreSQL, configures nginx + systemd services, obtains an SSL cert via certbot, and starts the app. Post-deploy:
# Configure .env with real values
# Run daily backups (set up cron)
sudo bash deploy/backup.sh
Email routing
| Request type | To | CC |
|---|---|---|
| Event | cultorga@c-base.org | — |
| Filming | cultorga@c-base.org | — |
| Dispute | circle@c-base.org | counselor@c-base.org |
| Funding | circle@c-base.org | — |
| Info Topic | circle@c-base.org | — |
| Circle Membership | circle@c-base.org | — |
Contributing
devenv shellto enter the dev environment- Work on your feature
make lint && make typecheck && make testto verify- Commit with gitmoji prefix (e.g.
feat:,fix:,chore:) - Open a PR
License: AGPL3
This project is licensed under the GNU Affero Public License 3.0 (AGPL-3.0) which you can find in fulltext in the provided LICENSE file.