fedora-happiness-packets/AGENTS.md
Justin Wheeler 6e69255965
Some checks failed
CI / lint (push) Successful in 17s
CI / test (push) Failing after 48s
📝 docs: Update AGENTS.md and README.md for current project state
`AGENTS.md` was stale — still listed Phases 3–5 as upcoming, referenced
Docker Compose and deleted config files, and omitted Bootstrap 5.3 and
CKEditor 5 from the stack description. Updated to reflect all completed
phases through Phase 5, current stack, Podman Compose instructions, and
environment-variable-based configuration.

`README.md` was last updated in 2019 and referenced Pagure, old setup
instructions, and the GSoC 2018 onboarding flow. Rewrote it with the
current stack, a modernization roadmap showing completed and upcoming
phases, a Podman-based quick start guide, and current community links
(Forgejo, Matrix).

Assisted-by: Claude Opus 4.6 (1M context)
Signed-off-by: Justin Wheeler <jwheel@fedoraproject.org>
2026-05-11 06:21:43 -04:00

6 KiB
Raw Permalink Blame History

AGENTS.md

This file provides guidance to Claude Code (claude.ai/code) and other AI agents when working with code in this repository.

Project Overview

Fedora Happiness Packets is a Django web application that enables Fedora community members to send anonymous appreciation messages. It integrates with Fedora Account System (FAS) for user lookup, Fedora OIDC (via mozilla-django-oidc) for authentication, and fedora-messaging for publishing events to the Fedora message bus.

Current stack: Django 5.1, Python 3.123.14, Poetry for dependency management, PostgreSQL, Redis, Celery, Bootstrap 5.3, CKEditor 5.

Modernization Vision

This project was dormant from 2021 to 2026 and is undergoing an incremental modernization effort to bring it back into production as an OpenShift-native containerized application within Fedora's infrastructure.

Completed phases:

  • Phase 0: Dead code removal and housekeeping
  • Phase 1: Django 2.0 → 5.1 upgrade (four incremental LTS steps) and deprecated package replacement
  • Phase 2: Pipenv → Poetry migration, pyproject.toml, v1.0.0 release
  • Phase 2.5: Forgejo Actions CI pipeline (lint + test)
  • Phase 3: Containerfile and Podman migration (replace Docker)
  • Phase 4: Settings refactoring (12-factor env vars, eliminate config files)
  • Phase 5: Frontend modernization (Bootstrap 5.3, self-hosted fonts, CKEditor 5, jQuery removed)

Upcoming phases:

  • Phase 6: OpenShift-native manifests (Kustomize, health probes, Routes)
  • Phase 7: Search backend replacement (Haystack/Whoosh → PostgreSQL full-text search)
  • Phase 8: Fedora integration updates (OIDC JWKS discovery, FAS/Noggin API, Redis → Valkey)
  • Phase 9: Forgejo Package Registry and CI/CD (container images, RPM packaging)
  • Phase 10: Production hardening (CSP, HSTS, observability, Celery tuning)

Development Environment

Dependencies

# Install dependencies
poetry install

# Install without docs dependencies
poetry install --without docs

Environment Variables

All configuration is via environment variables (12-factor). Copy .env.example to .env for local development. See .env.example for the full list of available variables.

Running with Podman Compose

podman-compose up --build
podman-compose exec web python manage.py migrate

Testing and Linting

# Run all tests with coverage
poetry run pytest

# Run a specific test file
poetry run pytest happinesspackets/messaging/tests/test_views.py

# Run a specific test by name
poetry run pytest happinesspackets/messaging/tests/test_views.py::TestClassName::test_method

# Lint
poetry run ruff check .
  • Test settings: happinesspackets.settings.tsting (intentionally misspelled to avoid import during test discovery)
  • Tests use Django's ModelBackend instead of OIDC, and console email backend
  • Test and lint config lives in pyproject.toml under [tool.pytest.ini_options] and [tool.ruff]
  • CI: Forgejo Actions pipeline at .forgejo/workflows/ci.yml runs lint and test on every push and PR

Architecture

Single Django App: messaging

The entire application logic lives in happinesspackets/messaging/. There is only one app.

Message Lifecycle (core business logic)

  1. Sender composes a message via form, optionally looking up a Fedora username (FAS API call)
  2. System sends sender a confirmation email with a token-authenticated link
  3. Sender clicks confirmation link → message is sent to recipient and a fedora-messaging event (happinesspacket.send) is published
  4. Recipient receives email with token-authenticated links to view and manage privacy settings
  5. Both sender and recipient can independently grant permission for public archival

Each message has separate sender_email_token and recipient_email_token for authenticated access without login.

Settings Hierarchy

happinesspackets/settings/:

  • base.py — shared config, all settings via environment variables with sensible defaults
  • dev.py — extends base; DEBUG=True, console email, connects to Podman Compose services
  • tsting.py — extends dev; MD5 password hasher, ModelBackend auth, disables debug toolbar
  • deployment.py — production; Redis cache, file logging, Mailjet SMTP
  • ci.py — CI environment

Key Integration Points

  • OIDC auth: Custom backend at happinesspackets.messaging.auth.OIDC, endpoints on Fedora's iddev.fedorainfracloud.org
  • FAS username lookup: Uses python-fedora with admin credentials to query the Fedora Account System API
  • Fedora Messaging: Publishes MessageV1 schema events via AMQP (config in config.toml)
  • Celery + Redis: Async email delivery via django-celery-email
  • Haystack + Whoosh: Full-text search over messages (to be replaced with PostgreSQL FTS in Phase 7)

Privacy Model

Messages have layered privacy controls: sender_named, sender_approved_public, sender_approved_public_named, recipient_approved_public, recipient_approved_public_named, and admin_approved_public. All three parties (sender, recipient, admin) must independently approve before a message appears publicly with attribution.

Conventions

  • Dependency management: Poetry with pyproject.toml
  • URL routing: Uses re_path (regex patterns)
  • Views: Class-based views with django.contrib.auth.mixins
  • Forms: Crispy Forms with Bootstrap 5 template pack
  • Rich text: CKEditor 5 for message composition, nh3 for HTML sanitization
  • Email: HTML emails rendered from Django templates, sent via Celery
  • Database: PostgreSQL with ATOMIC_REQUESTS = True
  • Linting: ruff (configured in pyproject.toml)
  • CI: Forgejo Actions (.forgejo/workflows/ci.yml)

Git Conventions

  • Default branch: main
  • Feature branches: descriptive names off main (e.g., phase1/django-3.2-upgrade)
  • Commit messages: gitmoji prefix, component scope, detailed reasoning in body
  • Issue closing: Use Closes #NNN in commit message body for Forgejo auto-close
  • AI disclosure: Assisted-by: trailer per Fedora AI-Assisted Contributions Policy