This repository has been archived on 2026-02-24. You can view files and clone it. You cannot open issues or pull requests or push a commit.
giles a626dd849d Fix AP Delete: Tombstone id must match original Create object id
Mastodon ignored Delete activities because the Tombstone id was the
post URL, not the object id from the original Create activity. Now
looks up the existing Create activity and uses its object id.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 09:25:30 +00:00

Shared

Shared infrastructure, models, templates, and configuration used by all four Rose Ash microservices (blog, market, cart, events). Included as a git submodule in each app.

Structure

shared/
  db/
    base.py                 # SQLAlchemy declarative Base
    session.py              # Async session factory (get_session)
  models/                   # Shared domain models
    user.py                 # User
    magic_link.py           # MagicLink (auth tokens)
    domain_event.py         # DomainEvent (transactional outbox)
    kv.py                   # KeyValue (key-value store)
    menu_item.py            # MenuItem
    ghost_membership_entities.py  # GhostNewsletter, UserNewsletter
  infrastructure/
    factory.py              # create_base_app() — Quart app factory
    cart_identity.py        # current_cart_identity() (user_id or session_id)
    cart_loader.py          # Cart data loader for context processors
    context.py              # Jinja2 context processors
    internal_api.py         # Inter-app HTTP client (get/post via httpx)
    jinja_setup.py          # Jinja2 template environment setup
    urls.py                 # URL helpers (coop_url, market_url, etc.)
    user_loader.py          # Load current user from session
    http_utils.py           # HTTP utility functions
  events/
    bus.py                  # emit_event(), register_handler()
    processor.py            # EventProcessor (polls domain_events, runs handlers)
  browser/app/
    csrf.py                 # CSRF protection
    errors.py               # Error handlers
    middleware.py            # Request/response middleware
    redis_cacher.py         # Tag-based Redis page caching
    authz.py                # Authorization helpers
    filters/                # Jinja2 template filters (currency, truncate, etc.)
    utils/                  # HTMX helpers, UTC time, parsing
    payments/sumup.py       # SumUp checkout API integration
  browser/templates/        # ~300 Jinja2 templates shared across all apps
  config.py                 # YAML config loader
  containers.py             # ContainerType, container_filter, content_filter helpers
  log_config/setup.py       # Logging configuration (JSON formatter)
  utils.py                  # host_url and other shared utilities
  static/                   # Shared static assets (CSS, JS, images, FontAwesome)
  editor/                   # Koenig (Ghost) rich text editor build
  alembic/                  # Database migrations (25 versions)
    env.py                  # Imports models from all apps (with try/except guards)
    versions/               # Migration files — single head: j0h8e4f6g7

Key Patterns

  • App factory: All apps call create_base_app() which sets up DB sessions, CSRF, error handling, event processing, logging, and the glue handler registry.
  • Event bus: emit_event() writes to domain_events table in the caller's transaction. EventProcessor polls and dispatches to registered handlers.
  • Inter-app HTTP: internal_api.get/post("cart", "/internal/cart/summary") for cross-app reads. URLs resolved from app-config.yaml.
  • Cart identity: current_cart_identity() returns {"user_id": int|None, "session_id": str|None} from the request session.

Alembic Migrations

All apps share one PostgreSQL database. Migrations are managed here and run from the blog app's entrypoint (other apps skip migrations on startup).

# From any app directory (shared/ must be on sys.path)
alembic -c shared/alembic.ini upgrade head

Current head: j0h8e4f6g7 (drop cross-domain FK constraints).

Description
No description provided
Readme 15 MiB
Languages
HTML 55.7%
Python 31.7%
CSS 7.6%
JavaScript 4.9%