ReadonlyadminThe authoring-surface partition (EmailTemplate projection).
ReadonlysendThe send-surface partition (ActiveEmailTemplate projection).
Bust every cached page — send or authoring — that a write touching
templateKeys could have affected. The collection tag is always cleared
alongside, because an unscoped (id-only) page carries only that tag, so no
template-key tag can reach it.
keys deletes exact entries in addition to the tag surgery, passing the
key arguments — the cache hashes and prefixes them. It exists because
invalidateTag resolves keys through the Valkey FT index, which does not
exist in memory mode (valkeyClient: null); there the tag bust is a total
no-op, and an exact-key delete is the only thing that keeps read-after-
write honest.
The tag surgery runs against admin (one partition of the shared
namespace) — invalidateTag is namespace-scoped, so it reaches the send
partition's Valkey entries too. keys deletes only reach the admin
partition's key space, which is the one the writer re-reads through.
Optionalkeys?: readonly CacheKey[]Exact cache-key arguments (this cache hashes them) to also delete.
The one
email-template-searchcache, shared as an injected dependency by both surfaces (CACHING.md "shared cache layer" collaborator, in the shape ofTransactionCacheBusterrather than a base class the services extend).EmailTemplateServicereads through send;EmailTemplateAdminServicereads through admin and busts both on every write via invalidate. Holding the twoServiceCaches behind one object means a single namespace + TTL + tag vocabulary, like the single-SearchCache-per- entity rule the collections follow — but dependency-injected, so the authoring service isn't handed a read API it doesn't need.