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.
fd163b577f8e9824bff9265b4dee00ecff09bfe9
- Replace async federation_handlers with inline try_publish() at write sites - Fix ap_delivery_handler: urlparse for signature path/host, @context array with security vocab, Delete/Tombstone object handling - Fix federation_impl: @context array for IPFS, .limit(1) + upsert follower Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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 todomain_eventstable in the caller's transaction.EventProcessorpolls and dispatches to registered handlers. - Inter-app HTTP:
internal_api.get/post("cart", "/internal/cart/summary")for cross-app reads. URLs resolved fromapp-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
Languages
HTML
55.7%
Python
31.7%
CSS
7.6%
JavaScript
4.9%