feat(16.2-07): purge the host site cache on every admin post and category write

- 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
This commit is contained in:
2026-10-10 18:27:12 +02:00
parent f3b223f131
commit 2a3afb5107
8 changed files with 192 additions and 25 deletions

View File

@@ -6,27 +6,28 @@ import (
"git.golem15.com/golem15/sm-journal-plugin/classes"
"git.golem15.com/golem15/summercms/modules/backpack"
"git.golem15.com/golem15/summercms/modules/cabana"
"gorm.io/gorm"
)
// purgeSiteCache registers a site cache purge for one saved entity to run
// after the save transaction commits. Without a published
// *classes.SiteCachePurger (no purge configured) or outside a save
// transaction it does nothing.
func purgeSiteCache(ctx context.Context, app func() *backpack.App, kind, slug string) {
// siteCachePurger returns the published *classes.SiteCachePurger and the
// save transaction of ctx, for classes.PurgeSiteCacheAfterCommit. Without a
// purger (no purge configured) or outside a save transaction it returns a
// nil purger, which PurgeSiteCacheAfterCommit ignores.
func siteCachePurger(ctx context.Context, app func() *backpack.App) (*classes.SiteCachePurger, *gorm.DB) {
if app == nil {
return
return nil, nil
}
a := app()
if a == nil {
return
return nil, nil
}
purger, ok := a.Lookup[*classes.SiteCachePurger]()
if !ok || purger == nil {
return
return nil, nil
}
tx, ok := cabana.TxFromContext(ctx)
if !ok {
return
return nil, nil
}
classes.PurgeSiteCacheAfterCommit(ctx, tx, purger, kind, slug)
return purger, tx
}