- posts: FormAfterCreate/Update purge after the content_html translations,
new FormAfterDelete; categories: FormAfterCreate and FormAfterDelete
- NewSiteCachePurger refuses half configuration, non-http(s) URLs, user
info, fragments, http to a non-loopback host and tokens under 32 chars;
Boot logs the endpoint host and path once
- TestPostsAdminPurgesSiteCache smoke test
- README: Configuration section (keys, contract, timing, scope), API rows
- classes.SiteCachePurger posts {kind, slug} with a bearer token to
golem15.journal.site_cache.purge_url, 2 s timeout, logged, never fails a save
- PurgeSiteCacheAfterCommit runs it through lagoon.AfterCommit
- Boot builds and publishes the purger from the two config keys
- categories FormAfterUpdate registers the purge; Postgres test proves
one authorized request after the commit
- POST /_journal/api/v1/media/upload requires access_posts and stays under journal/
- Anonymous GET rss is RSS 2.0 honoring rss_* settings; unpublished posts are omitted
- beachcomber Gate reads search_use_typesense (default false) so a fresh save makes no Typesense HTTP
Co-authored-by: Cursor <cursoragent@cursor.com>
- Public and write groups under /_journal/api/v1 with journal-public-api and journal-api buckets (Max 120)
- Index omits drafts and future published_at; per_page default 9 max 30
- Optional backend JWT on GET; missing Bearer on writes returns PHP {error:Authentication required}
Co-authored-by: Cursor <cursoragent@cursor.com>
Operators get UI catalogs for plugin, journal, post, category, and tag
keys, plus an application-neutral README for the compiled plugin.
Co-authored-by: Cursor <cursoragent@cursor.com>
- Register golem15.journal requiring exactly golem15.translate
- Squash golem15_journal_posts DDL with unique slug and JSONB columns
- Persist one en/pl Post through translate helpers on real Postgres
Co-authored-by: Cursor <cursoragent@cursor.com>