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 3febef074b Fix menu item highlighting with aria-selected attribute
Added app_name Jinja global and aria-selected to nav menu links.
Matches by first path segment (e.g. /market/... → "market") or by
app_name for cross-domain cases (e.g. cart app → "cart" menu item).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 13:56:07 +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%