fix(modules): bump the CLIENT half of MODULE_API_VERSION to 1.9.0
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:
@@ -11,6 +11,13 @@
|
||||
// that the two files can drift, so a test asserts they agree
|
||||
// (client/test/moduleRegistry.test.js) rather than trusting a bump to remember
|
||||
// both.
|
||||
// 1.9.0 - a module may ship its own message bodies and rules:
|
||||
// `api.registerEngagementSeeds({ templates, ruleGroups })` (ENGAGEMENT.md Phase
|
||||
// 11b, decision 7). Nothing on this half changed - a seed is server-side data
|
||||
// and core's seeders write it on the boot path - but the bodies it ships are
|
||||
// edited through the template editor this half already renders, and an operator
|
||||
// meets them there. This file bumps for the reason at the top: the two halves
|
||||
// state ONE version, and a module declares one `coreApi` range against both.
|
||||
// 1.8.0 - the ceiling lattice gains `admin` (ENGAGEMENT.md Phase 11). Nothing on
|
||||
// this half changed: a ceiling is declared on the server's `api` and enforced
|
||||
// there, and the admin screens that render one read the vocabulary from
|
||||
@@ -58,4 +65,4 @@
|
||||
// but the two halves state ONE version: a module declares a single coreApi range
|
||||
// and is served one chunk, so a client that claimed 1.0.0 while the server
|
||||
// answered 1.1.0 would be two answers to one question.
|
||||
export const MODULE_API_VERSION = '1.8.0'
|
||||
export const MODULE_API_VERSION = '1.9.0'
|
||||
|
||||
@@ -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 () => {
|
||||
|
||||
Reference in New Issue
Block a user