Alumni Development Notes
Architecture Overview
- No traditional database tables for members; instead, we write to Google Sheets via
DateSheetsAdapter (see alumni/gsuite_adapter.py).
- Celery tasks (
alumni/tasks.py) handle the long-running side effects: sheet writes, email dispatch, audit logging, and token emails. Django 6’s built-in Tasks framework was evaluated, but Celery remains the production backend here.
- Two lightweight models live in Django:
AlumniEmailRecipient – list of admin recipients for notifications.
AlumniUpdateToken – UUID tokens for edit links with a 24h validity window.
AlumniSignUpForm collects create/update data. The operation field defaults to CREATE but the same form class is reused for updates.
alumni.views.alumni_signup validates captcha, checks duplicates against Sheets, and enqueues handle_alumni_signup.delay().
alumni_update_verify asks for an email, creates a token, and schedules send_token_email only after the token row commits.
alumni_update_form verifies the token, pre-fills the form, and on POST triggers the same handle_alumni_signup task with operation=UPDATE.
Task Flow
handle_alumni_signup pattern-matches on operation:
- CREATE →
handle_create appends a row to the member sheet, generates a payment reference number, sends both alumni and admin emails, and logs to the audit sheet.
- UPDATE →
handle_update finds the row by email, updates only the editable columns, logs the action, and deletes the token.
send_token_email verifies the request email actually exists in the sheet before sending a template-based message.
- Task payloads passed from views are normalized to JSON-safe primitives before enqueueing. In particular, tokens are stringified and update timestamps are passed as ISO 8601 strings.
Configuration
settings.ALUMNI_SETTINGS must contain JSON with Google API credentials and sheet IDs. Missing/invalid settings are logged as errors and disable the integration.
- Email templates live under
templates/members/ and templates/alumni/.
- Alumni messages are plain text and therefore use
.txt templates. Django renders them normally, while the extension prevents the HTML formatter from changing user-visible whitespace. Reserve .html for messages that are sent as HTML.
Extending
AlumniEmailRecipientAdmin uses the shared admin base so its forms and layout remain compatible with both classic admin and Unfold.
- Consider encrypting the token payload or adding rate limiting to avoid brute-force attempts.
- For better observability, persist audit logs inside Django in addition to Google Sheets.