Covers structure, key patterns, models, event bus, and alembic setup. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
70 lines
3.5 KiB
Markdown
70 lines
3.5 KiB
Markdown
# 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).
|
|
|
|
```bash
|
|
# 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).
|