Ghost has separate /posts/ and /pages/ endpoints. All admin functions
(get_post_for_edit, update_post, update_post_settings, sync) were
hardcoded to /posts/, causing 404s when editing pages. Now checks
is_page from post_data and uses the correct endpoint.
Also uses sync_single_page (not sync_single_post) after page saves
to prevent IntegrityError from mismatched fetch/upsert paths.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Register StubFederationService in services/__init__.py
- Add federation to CI sibling list
- Add federation URL to app-config.yaml
- Update shared submodule with federation models/contracts/services
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Delete coop_api.py (dead internal API endpoint)
- Replace cross-app calendar imports with shared service calls
- Update shared submodule
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The blog app's local templates/_types/post/_nav.html was shadowing
the shared version due to ChoiceLoader priority. Updated local copy
to use container_nav_widgets while keeping the blog-specific admin
cog link. Removed debug logging from context processor.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace explicit calendar/market service calls in post routes, auth
routes, and listing cards with widget-driven iteration. Zero cross-domain
imports remain in blog bp layer.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New GET /auth/tickets/ and /auth/bookings/ routes with HTMX support.
Update shared submodule with TicketDTO, service methods, nav links,
and panel templates.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Market CRUD in blog now delegates to services.market.create_marketplace()
and soft_delete_marketplace() instead of importing MarketPlace directly.
Adds TODO comments on Calendar imports in admin routes (deferred to
admin UI rework). Updates shared submodule.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The glue layer's models (MenuNode, ContainerRelation), services
(navigation, relationships), and event handlers have been absorbed
into shared/. The glue submodule caused duplicate SQLAlchemy table
registration for 'menu_nodes'.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace direct Calendar, MarketPlace, and Post model queries with typed
service calls (services.blog, services.calendar, services.market,
services.cart). Blog registers all 4 services via domain_services_fn
with has() guards for composable deployment.
Key changes:
- app.py: use domain_services_fn instead of inline service registration
- admin routes: MarketPlace queries → services.market.marketplaces_for_container()
- entry_associations: CalendarEntryPost → services.calendar.entry_ids_for_content()
- markets service: Post query → services.blog.get_post_by_id/slug()
- posts_data, post routes: use calendar/market/cart services
- menu_items: glue imports → shared imports
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Context processor now sums product count + calendar_count from the
cart API, so the cart badge shows the correct total on all pages.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace all imports from cart.models, market.models, events.models
with shared.models equivalents
- Convert blog/models/ghost_content.py to re-export stub
- Update shared + glue submodule pointers
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
These were duplicates of files in shared/browser/templates/ and
silently prevented shared updates from taking effect (as happened
with the auth nav orders link fix). 8 blog-specific overrides with
genuine differences are kept.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The orders link was using links.link macro which adds hx-get, causing
htmx:invalidPath because cart.rose-ash.com is cross-origin. Use a
plain <a> tag for this cross-domain link instead.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extract inline email body into separate Jinja2 templates
(_email/magic_link.html and .txt) with a styled sign-in
button and fallback plain-text link.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
List specific model imports, glue services, internal APIs, and
domain events that blog code actually references.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Document submodules, models, cross-app integration (event-driven
login adoption), and accurate directory structure.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
shared: migration to drop cross-domain FK constraints
glue: order lifecycle services, cart adoption, login/order handlers
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Emit user.logged_in event instead of HTTP POST to /internal/cart/adopt.
Event is emitted inside the last_login_at transaction for atomicity.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Wire up ContainerRelation tracking via attach_child/detach_child in:
- menu_items: create, update (re-link on post change), delete
- markets: create (including revive), soft_delete
- page config: creation in update_features and update_sumup routes
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Previous runs left self-copies (e.g. blog/blog/) that caused
'Table already defined' errors. Split into two loops: first rm -rf
all sibling dirs, then copy only non-self siblings.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Each app has its own models/ at the root (imported as bare `models.X`).
The CI copy was also creating {app}/models/ (imported as `{app}.models.X`),
causing SQLAlchemy to see the same table defined twice.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>