Commit Graph

16 Commits

Author SHA1 Message Date
giles
82968a366f Rename coop to blog in app code and config
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m13s
- App name: "coop" → "blog"
- coop_context() → blog_context()
- coop_url → blog_url imports
- app_url("coop") → app_url("blog")
- Config keys: coop_root/coop_title → market_root/market_title
- Sync shared submodule

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 08:33:07 +00:00
giles
36c33d9ce2 Use full post body in AP notes, not just excerpt
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 54s
Federated content has no character limit — use the complete plaintext
body so followers see the full post in their timeline.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 09:40:19 +00:00
giles
4c44fc64c5 Enrich AP posts: Note type, images, hashtags, HTML excerpt
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 52s
- Switch object type from Article to Note (Mastodon first-class support)
- Include title + excerpt as HTML content with "Read more" link
- Feature image + up to 3 inline images as AP attachments
- Post tags as AP Hashtag objects with inline links in content

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 09:35:40 +00:00
giles
fe3bc9d893 Inline federation publication in ghost_sync
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m2s
Replace emit_event("post.published/updated/unpublished") with direct
try_publish() calls. AP activities are now created at write time,
fixing the race condition where multiple EventProcessors competed
for federation events.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 07:55:48 +00:00
giles
ceacf7a56e Fix _upsert_post to return (post, old_status) tuple
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 2m25s
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 23:40:27 +00:00
giles
0d18fd8fd9 Track status changes for unpublish + edit federation events
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m0s
- _upsert_post returns (post, old_status) to detect status transitions
- Emit post.unpublished when published→draft (triggers Delete activity)
- Emit post.updated only when already-published posts are edited
- Emit post.published only for new publishes (not re-syncs)
- Same logic for pages via sync_single_page

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 23:27:04 +00:00
giles
507200893d Fix _upsert_post savepoint: add() inside begin_nested()
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 57s
begin_nested() auto-flushes on entry which triggers the INSERT before
the savepoint is active. Move sess.add() inside the savepoint block
and split into update vs insert paths.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 22:59:54 +00:00
giles
9d6a458115 Wire real FederationService + add page federation events
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m2s
- Blog app now registers SqlFederationService (was stub/no-op)
- sync_single_page emits post.published/updated events for pages
- Updated shared submodule: fix sign_request in AP delivery handler

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 22:52:36 +00:00
giles
80e4f21b0b Fix page creation labels and webhook race condition
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 56s
- Updated shared submodule: page-aware blog_new template labels
- _upsert_post: handle concurrent webhook INSERTs via savepoint + retry

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 22:32:05 +00:00
giles
954b6cc06a Set page flag in sync_single_page to ensure is_page=true
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 56s
Ghost /pages/ endpoint may not include "page": true in the response.
Explicitly set it so _upsert_post correctly marks is_page=true.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 22:23:19 +00:00
giles
23fe8c233e Fix page editing: use Ghost /pages/ API for pages, not /posts/
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 56s
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>
2026-02-21 22:03:41 +00:00
giles
53dff0d41b Update shared submodule + emit post events for federation
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m18s
- Emit post.published/post.updated events from Ghost webhook sync
- Updated shared with federation handlers, delivery, anchoring

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 15:59:53 +00:00
giles
c537770172 Decouple blog: use shared.models for all cross-app imports
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 47s
- 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>
2026-02-18 20:57:56 +00:00
giles
a01016d8d5 feat: decouple blog from shared_lib, add app-owned models
Phase 1-3 of decoupling:
- path_setup.py adds project root to sys.path
- Blog-owned models in blog/models/ (ghost_content, snippet, tag_group)
- Re-export shims for shared models (user, kv, magic_link, menu_item)
- All imports updated: shared.infrastructure, shared.db, shared.browser, etc.
- No more cross-app post_id FKs in calendar/market/page_config

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 12:46:31 +00:00
giles
8b6320619e feat: implement Pages as Spaces Phase 1
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 45s
- Add PageConfig model with feature flags (calendar, market)
- Auto-create PageConfig on Ghost page sync
- Add create_page() for Ghost /pages/ API endpoint
- Add /new-page/ route for creating pages
- Add ?type=pages blog filter with Posts|Pages tab toggle
- Add list_pages() to DBClient with PageConfig eager loading
- Add PUT /<slug>/admin/features/ route for feature toggles
- Add feature badges (calendar, market) on page cards
- Add features panel to page admin dashboard
- Update shared_lib submodule with PageConfig model

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 14:25:34 +00:00
giles
8f7a15186c feat: initialize blog app with blueprints and templates
Some checks failed
Build and Deploy / build-and-deploy (push) Has been cancelled
Extract blog-specific code from the coop monolith into a standalone
repository. Includes auth, blog, post, admin, menu_items, snippets
blueprints, associated templates, Dockerfile (APP_MODULE=app:app),
entrypoint, and Gitea CI workflow.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 23:15:56 +00:00