fix(modules): bump the CLIENT half of MODULE_API_VERSION to 1.9.0
All checks were successful
PR Checks / client-build (pull_request) Successful in 26s
PR Checks / bot-tests (pull_request) Successful in 28s
PR Checks / server-tests (pull_request) Successful in 13m0s

The two halves version ONE contract and a test asserts they agree
(client/test/moduleRegistry.test.js). I bumped server/src/modules/version.js and
not client/src/modules/version.js, so client-build went red — the job runs the
client suite before it builds.

Nothing on the client half changed: a seed is server-side data and core's seeders
write it on the boot path. It bumps for the reason its own header gives — a
module declares one `coreApi` range against both halves, and a client claiming
1.8.0 while the server answers 1.9.0 is two answers to one question.

327 client tests green; client build clean.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-09-01 01:22:00 -05:00
parent 0a9149a04f
commit 40ab1ce8d2
2 changed files with 33 additions and 1 deletions

View File

@@ -19,6 +19,7 @@ const { SEEDS, AMBIENT_VARIABLES, seedByKey } = require('../src/engagement/templ
const templatesDb = require('../src/model/engagement/engagementTemplates.db')
const settings = require('../src/model/settings/settings.model')
const templates = require('../src/engagement/templates')
const registries = require('../src/modules/registries')
const SITE = 'Runic Gateway'
const BASE = 'https://shard.example.com'
@@ -400,6 +401,30 @@ test('variablesFor answers from the seed for a template with no trigger, plus th
assert.deepEqual(templates.variablesFor({}).map((v) => v.name), ['siteName', 'siteUrl', 'logoUrl', 'year'])
})
test('a TRIGGER-bound template also gets the per-delivery variables', () => {
// Phase 11b. `emailChannel.deliver` computes an unsubscribe token per recipient
// and merges it last, so `{{unsubscribeUrl}}` has always RENDERED — but a
// trigger-bound template takes its variable list from the trigger, and a
// trigger has no business declaring a fact about how the mail was sent. Without
// this, a body carrying an unsubscribe line rendered correctly and then the
// save-time undeclared-variable check refused the first operator who edited it.
//
// Nothing had taken this path before: core's `notify.event` declares the
// variable in its own seed and is bound to no trigger.
registries.registerCore()
const names = templates.variablesFor({ trigger_id: 'news.post' }).map((v) => v.name)
assert.ok(names.includes('unsubscribeUrl'), 'a trigger-bound body may reference it')
assert.ok(names.includes('title'), 'and still gets the trigger\'s own')
assert.ok(names.includes('siteName'), 'and the ambient set')
// A SEEDLESS, triggerless template gets neither — there is no delivery to
// describe, and an unsubscribe link on a password reset is meaningless.
assert.equal(
templates.variablesFor({}).map((v) => v.name).includes('unsubscribeUrl'),
false,
)
})
// ── The seeder and the render entrypoint ────────────────────────────────────
test('the shipped default is used when the row is missing, and when it is unusable', async () => {