@productbrain/cli 0.1.0-beta.1256 → 0.1.0-beta.1267
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/admin/manage.d.ts.map +1 -1
- package/dist/commands/admin/manage.js +186 -2
- package/dist/commands/admin/manage.js.map +1 -1
- package/dist/commands/admin/manage.test.d.ts +16 -0
- package/dist/commands/admin/manage.test.d.ts.map +1 -0
- package/dist/commands/admin/manage.test.js +159 -0
- package/dist/commands/admin/manage.test.js.map +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manage.d.ts","sourceRoot":"","sources":["../../../src/commands/admin/manage.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"manage.d.ts","sourceRoot":"","sources":["../../../src/commands/admin/manage.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA+DpC,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAoHzD"}
|
|
@@ -1,11 +1,43 @@
|
|
|
1
1
|
import { adminCall } from '../../lib/client.js';
|
|
2
|
+
import { resolveAdminConfig } from '../../lib/config.js';
|
|
2
3
|
import { resolveWorkspaceArg, resolveUserArg } from './inspect.js';
|
|
3
4
|
import { isJsonMode } from '../../lib/runner.js';
|
|
4
|
-
import {
|
|
5
|
+
import { requiresAdminDestructiveConfirmation } from '../../lib/deployment.js';
|
|
6
|
+
import { bold, red, green, dim, yellow } from '../../lib/style.js';
|
|
7
|
+
/** Ordered count/flag fields rendered for a single migration result. */
|
|
8
|
+
const TEAM_VOCAB_FIELDS = [
|
|
9
|
+
'entriesRenamed',
|
|
10
|
+
'rolesPatched',
|
|
11
|
+
'displayNamesPatched',
|
|
12
|
+
'membershipsPatched',
|
|
13
|
+
'teamCollectionFieldsPatched',
|
|
14
|
+
'teamEntriesPatched',
|
|
15
|
+
'glossaryNamesPatched',
|
|
16
|
+
'glossaryDefsPatched',
|
|
17
|
+
'rolesNamePatched',
|
|
18
|
+
'teamCollectionNamePatched',
|
|
19
|
+
'governanceTagsPatched',
|
|
20
|
+
];
|
|
21
|
+
/** Numeric fields that accumulate into fleet totals on the --all path. */
|
|
22
|
+
const TEAM_VOCAB_NUMERIC_FIELDS = [
|
|
23
|
+
'entriesRenamed',
|
|
24
|
+
'rolesPatched',
|
|
25
|
+
'membershipsPatched',
|
|
26
|
+
'teamEntriesPatched',
|
|
27
|
+
'glossaryNamesPatched',
|
|
28
|
+
'glossaryDefsPatched',
|
|
29
|
+
'rolesNamePatched',
|
|
30
|
+
'governanceTagsPatched',
|
|
31
|
+
'glossaryNameCollisionsSkipped',
|
|
32
|
+
'roleNameCollisionsSkipped',
|
|
33
|
+
];
|
|
34
|
+
// The migration's manifest command name (vocab-clean — the retired literal lives
|
|
35
|
+
// only inside the migration file, per the vocab guard).
|
|
36
|
+
const MIGRATE_TEAM_VOCAB_COMMAND = 'manage:migrate-team-vocab';
|
|
5
37
|
export function attachManageCommands(admin) {
|
|
6
38
|
const manage = admin
|
|
7
39
|
.command('manage')
|
|
8
|
-
.description('Dangerous operations: delete-workspace, delete-user (WP-324)');
|
|
40
|
+
.description('Dangerous operations: delete-workspace, delete-user, migrate-team-vocab (WP-324)');
|
|
9
41
|
// ── delete-workspace ────────────────────────────────────────────────────
|
|
10
42
|
manage
|
|
11
43
|
.command('delete-workspace <slug>')
|
|
@@ -72,5 +104,157 @@ export function attachManageCommands(admin) {
|
|
|
72
104
|
process.stdout.write(dim(` ${total} rows removed`) + '\n');
|
|
73
105
|
}
|
|
74
106
|
});
|
|
107
|
+
// ── migrate-team-vocab ────────────────────────────────────────────────────
|
|
108
|
+
// One-time persisted-data migration that finalizes the Phase 0 Team rename.
|
|
109
|
+
// Single-workspace by default; --all (requires --confirm) fans out across the
|
|
110
|
+
// whole fleet with a per-workspace try/catch so one throwing/partially-migrated
|
|
111
|
+
// workspace never aborts the run. Idempotent — safe to re-run.
|
|
112
|
+
manage
|
|
113
|
+
.command('migrate-team-vocab [slug]')
|
|
114
|
+
.description('Finalize the persisted-data team-vocab migration (one workspace, or --all). Idempotent.')
|
|
115
|
+
.option('--all', 'Run across ALL workspaces in the deployment (requires --confirm)', false)
|
|
116
|
+
.option('--confirm', 'Acknowledge the destructive cross-workspace run (required with --all)', false)
|
|
117
|
+
.action(async (slug, options) => {
|
|
118
|
+
if (options.confirm && !options.all) {
|
|
119
|
+
process.stderr.write(red('--confirm requires --all (the single-workspace path is always live)') + '\n');
|
|
120
|
+
process.exitCode = 1;
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
if (options.all && slug) {
|
|
124
|
+
// --all fans out to EVERY workspace and ignores the slug. Reject the
|
|
125
|
+
// ambiguous mix so `migrate-team-vocab acme --all` can't silently
|
|
126
|
+
// migrate the whole deployment instead of the named workspace.
|
|
127
|
+
process.stderr.write(red('Cannot combine a slug with --all — --all migrates every workspace. Drop one.') + '\n');
|
|
128
|
+
process.exitCode = 1;
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
if (options.all) {
|
|
132
|
+
await runMigrateTeamVocabAll(options.confirm);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
await runMigrateTeamVocabOne(slug);
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
/** Render a single migration result's 11 count/flag fields + the 2 collision warnings. */
|
|
139
|
+
function printTeamVocabResult(label, result) {
|
|
140
|
+
process.stdout.write(bold(label) + '\n');
|
|
141
|
+
for (const field of TEAM_VOCAB_FIELDS) {
|
|
142
|
+
process.stdout.write(` ${field}: ${String(result[field])}\n`);
|
|
143
|
+
}
|
|
144
|
+
printTeamVocabCollisions(' ', result);
|
|
145
|
+
}
|
|
146
|
+
/** Surface the two collision counters distinctly — non-zero is an operator warning, not a patch. */
|
|
147
|
+
function printTeamVocabCollisions(indent, result) {
|
|
148
|
+
const { glossaryNameCollisionsSkipped, roleNameCollisionsSkipped } = result;
|
|
149
|
+
if (glossaryNameCollisionsSkipped > 0 || roleNameCollisionsSkipped > 0) {
|
|
150
|
+
process.stdout.write(yellow(`${indent}⚠ collisions skipped (NOT migrated) — review manually:`) + '\n');
|
|
151
|
+
process.stdout.write(yellow(`${indent} glossaryNameCollisionsSkipped: ${glossaryNameCollisionsSkipped}`) + '\n');
|
|
152
|
+
process.stdout.write(yellow(`${indent} roleNameCollisionsSkipped: ${roleNameCollisionsSkipped}`) + '\n');
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
process.stdout.write(dim(`${indent}glossaryNameCollisionsSkipped: 0 roleNameCollisionsSkipped: 0`) + '\n');
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
/** Single-workspace path: resolve the slug, run the migration, print all 13 fields. */
|
|
159
|
+
async function runMigrateTeamVocabOne(slug) {
|
|
160
|
+
const workspaceId = await resolveWorkspaceArg(slug);
|
|
161
|
+
if (!workspaceId) {
|
|
162
|
+
process.stderr.write(red('Workspace required — pass a slug/id or run `pb session start` in this project.\n'));
|
|
163
|
+
process.exit(1);
|
|
164
|
+
}
|
|
165
|
+
const result = (await adminCall(MIGRATE_TEAM_VOCAB_COMMAND, {
|
|
166
|
+
workspaceId,
|
|
167
|
+
}));
|
|
168
|
+
if (isJsonMode()) {
|
|
169
|
+
process.stdout.write(JSON.stringify(result, null, 2) + '\n');
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
printTeamVocabResult(`Team-vocab migration — ${slug ?? workspaceId}`, result);
|
|
173
|
+
process.stdout.write(green('✓ Migration complete') + '\n');
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Fleet path: --all requires --confirm and the prod-destructive gate. Without --confirm
|
|
177
|
+
* we list what WILL run and exit. With it, enumerate via inspect:list-workspaces and run
|
|
178
|
+
* the migration per workspace under an isolated try/catch so failures don't abort the run.
|
|
179
|
+
*/
|
|
180
|
+
async function runMigrateTeamVocabAll(confirm) {
|
|
181
|
+
const { siteUrl } = resolveAdminConfig();
|
|
182
|
+
// Enumerate the fleet (also used for the pre-confirm "what will run" listing).
|
|
183
|
+
const workspaces = (await adminCall('inspect:list-workspaces', {}));
|
|
184
|
+
if (!confirm) {
|
|
185
|
+
if (isJsonMode()) {
|
|
186
|
+
process.stdout.write(JSON.stringify({ wouldRun: workspaces.map((w) => ({ _id: w._id, slug: w.slug })) }, null, 2) +
|
|
187
|
+
'\n');
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
process.stdout.write(bold(`Will run team-vocab migration on ${workspaces.length} workspace(s):`) + '\n');
|
|
191
|
+
for (const ws of workspaces) {
|
|
192
|
+
process.stdout.write(` ${ws.slug} ${dim(`(${ws._id})`)}\n`);
|
|
193
|
+
}
|
|
194
|
+
process.stdout.write(dim('Rerun with --all --confirm to execute') + '\n');
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
// Prod / remote deployments: surface the target loudly before fanning out.
|
|
198
|
+
// The gate is the mandatory --confirm flag + the no-confirm listing above
|
|
199
|
+
// (uniform across every deployment) — deliberately NOT an interactive prompt:
|
|
200
|
+
// a passed --confirm would bypass it anyway, and it would hang a non-interactive
|
|
201
|
+
// (CI / scripted) fleet run, which is exactly when --confirm is used.
|
|
202
|
+
if (requiresAdminDestructiveConfirmation(siteUrl)) {
|
|
203
|
+
// stderr, not stdout: in --json mode stdout carries the result payload, and
|
|
204
|
+
// a warning written there would corrupt it for jq/CI parsers.
|
|
205
|
+
process.stderr.write(yellow(`⚠ Running team-vocab migration across ALL ${workspaces.length} workspace(s) on ${siteUrl}`) +
|
|
206
|
+
'\n');
|
|
207
|
+
}
|
|
208
|
+
const succeeded = [];
|
|
209
|
+
const failed = [];
|
|
210
|
+
for (const ws of workspaces) {
|
|
211
|
+
try {
|
|
212
|
+
const result = (await adminCall(MIGRATE_TEAM_VOCAB_COMMAND, {
|
|
213
|
+
workspaceId: ws._id,
|
|
214
|
+
}));
|
|
215
|
+
succeeded.push({ slug: ws.slug, result });
|
|
216
|
+
}
|
|
217
|
+
catch (e) {
|
|
218
|
+
// One throwing / partially-migrated workspace must not abort the fleet.
|
|
219
|
+
failed.push({ slug: ws.slug, error: e instanceof Error ? e.message : String(e) });
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
// A throwing/partially-migrated workspace fails the run — set this BEFORE the
|
|
223
|
+
// JSON early-return so --json/CI callers get a non-zero exit too (not just the
|
|
224
|
+
// human path below). Skipped collisions are deliberately NOT a failure here:
|
|
225
|
+
// they are surfaced as warnings and their counts ride the result payload, so
|
|
226
|
+
// automation can gate on them explicitly.
|
|
227
|
+
if (failed.length > 0)
|
|
228
|
+
process.exitCode = 1;
|
|
229
|
+
if (isJsonMode()) {
|
|
230
|
+
process.stdout.write(JSON.stringify({ succeeded, failed }, null, 2) + '\n');
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
// Per-workspace counts.
|
|
234
|
+
for (const s of succeeded) {
|
|
235
|
+
printTeamVocabResult(`✓ ${s.slug}`, s.result);
|
|
236
|
+
process.stdout.write('\n');
|
|
237
|
+
}
|
|
238
|
+
// Fleet totals across the numeric fields (collisions included).
|
|
239
|
+
const totals = {};
|
|
240
|
+
for (const field of TEAM_VOCAB_NUMERIC_FIELDS) {
|
|
241
|
+
totals[field] = succeeded.reduce((sum, s) => sum + s.result[field], 0);
|
|
242
|
+
}
|
|
243
|
+
process.stdout.write(bold(`Fleet totals (${succeeded.length} succeeded, ${failed.length} failed)`) + '\n');
|
|
244
|
+
for (const field of TEAM_VOCAB_NUMERIC_FIELDS) {
|
|
245
|
+
const line = ` ${field}: ${totals[field]}`;
|
|
246
|
+
const isCollision = field === 'glossaryNameCollisionsSkipped' || field === 'roleNameCollisionsSkipped';
|
|
247
|
+
process.stdout.write((isCollision && totals[field] > 0 ? yellow(line) : line) + '\n');
|
|
248
|
+
}
|
|
249
|
+
// Explicit failure list — a throwing/partially-migrated workspace surfaces here.
|
|
250
|
+
if (failed.length > 0) {
|
|
251
|
+
process.stdout.write(red(`\n✗ ${failed.length} workspace(s) failed:`) + '\n');
|
|
252
|
+
for (const f of failed) {
|
|
253
|
+
process.stdout.write(red(` ${f.slug}: ${f.error}`) + '\n');
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
process.stdout.write(green('\n✓ All workspaces migrated') + '\n');
|
|
258
|
+
}
|
|
75
259
|
}
|
|
76
260
|
//# sourceMappingURL=manage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manage.js","sourceRoot":"","sources":["../../../src/commands/admin/manage.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"manage.js","sourceRoot":"","sources":["../../../src/commands/admin/manage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for `pb admin manage migrate-team-vocab` subcommand wiring.
|
|
3
|
+
*
|
|
4
|
+
* Covers the dispatch surface for the (already-shipped) persisted-data team-vocab
|
|
5
|
+
* migration:
|
|
6
|
+
* - [slug] path resolves the workspace and calls manage:migrate-team-vocab with it
|
|
7
|
+
* - --all WITHOUT --confirm enumerates but never dispatches the migration
|
|
8
|
+
* - --all --confirm enumerates then dispatches the migration per workspace
|
|
9
|
+
* - a throwing workspace is caught so the fleet loop continues
|
|
10
|
+
*
|
|
11
|
+
* The migration name literal is referenced via the vocab-clean manifest command
|
|
12
|
+
* string ('manage:migrate-team-vocab') — the retired token lives only in the
|
|
13
|
+
* migration file (see the vocab guard).
|
|
14
|
+
*/
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=manage.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manage.test.d.ts","sourceRoot":"","sources":["../../../src/commands/admin/manage.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for `pb admin manage migrate-team-vocab` subcommand wiring.
|
|
3
|
+
*
|
|
4
|
+
* Covers the dispatch surface for the (already-shipped) persisted-data team-vocab
|
|
5
|
+
* migration:
|
|
6
|
+
* - [slug] path resolves the workspace and calls manage:migrate-team-vocab with it
|
|
7
|
+
* - --all WITHOUT --confirm enumerates but never dispatches the migration
|
|
8
|
+
* - --all --confirm enumerates then dispatches the migration per workspace
|
|
9
|
+
* - a throwing workspace is caught so the fleet loop continues
|
|
10
|
+
*
|
|
11
|
+
* The migration name literal is referenced via the vocab-clean manifest command
|
|
12
|
+
* string ('manage:migrate-team-vocab') — the retired token lives only in the
|
|
13
|
+
* migration file (see the vocab guard).
|
|
14
|
+
*/
|
|
15
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
16
|
+
import { Command } from 'commander';
|
|
17
|
+
// Mock adminCall — the single server dispatch surface.
|
|
18
|
+
vi.mock('../../lib/client.js', () => ({
|
|
19
|
+
adminCall: vi.fn(async () => ({})),
|
|
20
|
+
}));
|
|
21
|
+
// Mock workspace resolution so the [slug] path is deterministic.
|
|
22
|
+
vi.mock('./inspect.js', () => ({
|
|
23
|
+
resolveWorkspaceArg: vi.fn(async (slug) => (slug ? `ws-${slug}` : undefined)),
|
|
24
|
+
resolveUserArg: vi.fn(async () => 'user_x'),
|
|
25
|
+
}));
|
|
26
|
+
// Non-JSON so the render paths execute (and never short-circuit).
|
|
27
|
+
vi.mock('../../lib/runner.js', () => ({
|
|
28
|
+
isJsonMode: vi.fn(() => false),
|
|
29
|
+
}));
|
|
30
|
+
// Local deployment → no prod-destructive confirmation ceremony in the gate.
|
|
31
|
+
vi.mock('../../lib/config.js', () => ({
|
|
32
|
+
resolveAdminConfig: vi.fn(() => ({ siteUrl: 'http://127.0.0.1:3210' })),
|
|
33
|
+
}));
|
|
34
|
+
vi.mock('../../lib/deployment.js', () => ({
|
|
35
|
+
requiresAdminDestructiveConfirmation: vi.fn(() => false),
|
|
36
|
+
}));
|
|
37
|
+
import { attachManageCommands } from './manage.js';
|
|
38
|
+
import { adminCall } from '../../lib/client.js';
|
|
39
|
+
import { isJsonMode } from '../../lib/runner.js';
|
|
40
|
+
const MIGRATE = 'manage:migrate-team-vocab';
|
|
41
|
+
/** Build a Commander tree with the manage subcommands attached and parse argv. */
|
|
42
|
+
async function runManage(argv) {
|
|
43
|
+
const admin = new Command();
|
|
44
|
+
attachManageCommands(admin);
|
|
45
|
+
// exitOverride so a parse error throws instead of calling process.exit.
|
|
46
|
+
admin.exitOverride();
|
|
47
|
+
await admin.parseAsync(['node', 'pb', 'manage', ...argv]);
|
|
48
|
+
}
|
|
49
|
+
/** Full 13-field migration result with overridable fields. */
|
|
50
|
+
function migrationResult(overrides = {}) {
|
|
51
|
+
return {
|
|
52
|
+
entriesRenamed: 0,
|
|
53
|
+
rolesPatched: 0,
|
|
54
|
+
displayNamesPatched: false,
|
|
55
|
+
membershipsPatched: 0,
|
|
56
|
+
teamCollectionFieldsPatched: false,
|
|
57
|
+
teamEntriesPatched: 0,
|
|
58
|
+
glossaryNamesPatched: 0,
|
|
59
|
+
glossaryDefsPatched: 0,
|
|
60
|
+
rolesNamePatched: 0,
|
|
61
|
+
teamCollectionNamePatched: false,
|
|
62
|
+
governanceTagsPatched: 0,
|
|
63
|
+
glossaryNameCollisionsSkipped: 0,
|
|
64
|
+
roleNameCollisionsSkipped: 0,
|
|
65
|
+
...overrides,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
beforeEach(() => {
|
|
69
|
+
vi.clearAllMocks();
|
|
70
|
+
vi.mocked(adminCall).mockResolvedValue(migrationResult());
|
|
71
|
+
});
|
|
72
|
+
// Reset exit state after every test — a failed assertion before an inline reset
|
|
73
|
+
// would otherwise leak process.exitCode into the next test (the file runs
|
|
74
|
+
// sequentially) and into the runner's own exit code on the last test.
|
|
75
|
+
afterEach(() => {
|
|
76
|
+
process.exitCode = 0;
|
|
77
|
+
});
|
|
78
|
+
describe('manage migrate-team-vocab [slug]', () => {
|
|
79
|
+
it('resolves the slug and dispatches manage:migrate-team-vocab with the workspaceId', async () => {
|
|
80
|
+
vi.mocked(adminCall).mockResolvedValueOnce(migrationResult({ entriesRenamed: 3 }));
|
|
81
|
+
await runManage(['migrate-team-vocab', 'acme']);
|
|
82
|
+
expect(adminCall).toHaveBeenCalledTimes(1);
|
|
83
|
+
expect(adminCall).toHaveBeenCalledWith(MIGRATE, { workspaceId: 'ws-acme' });
|
|
84
|
+
});
|
|
85
|
+
it('rejects --confirm without --all and never dispatches (single path is always live)', async () => {
|
|
86
|
+
await runManage(['migrate-team-vocab', 'acme', '--confirm']);
|
|
87
|
+
expect(adminCall).not.toHaveBeenCalled();
|
|
88
|
+
expect(process.exitCode).toBe(1);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
describe('manage migrate-team-vocab --all', () => {
|
|
92
|
+
it('rejects a slug combined with --all and never dispatches', async () => {
|
|
93
|
+
await runManage(['migrate-team-vocab', 'acme', '--all', '--confirm']);
|
|
94
|
+
// --all + slug is ambiguous (would migrate the whole fleet, ignoring the
|
|
95
|
+
// slug) — reject before any dispatch.
|
|
96
|
+
expect(adminCall).not.toHaveBeenCalled();
|
|
97
|
+
expect(process.exitCode).toBe(1);
|
|
98
|
+
});
|
|
99
|
+
it('without --confirm enumerates but does NOT dispatch the migration', async () => {
|
|
100
|
+
vi.mocked(adminCall).mockResolvedValueOnce([
|
|
101
|
+
{ _id: 'ws-1', slug: 'one', name: 'One' },
|
|
102
|
+
{ _id: 'ws-2', slug: 'two', name: 'Two' },
|
|
103
|
+
]);
|
|
104
|
+
await runManage(['migrate-team-vocab', '--all']);
|
|
105
|
+
// Exactly one call — the enumerator — and never the migration.
|
|
106
|
+
expect(adminCall).toHaveBeenCalledTimes(1);
|
|
107
|
+
expect(adminCall).toHaveBeenCalledWith('inspect:list-workspaces', {});
|
|
108
|
+
expect(adminCall).not.toHaveBeenCalledWith(MIGRATE, expect.anything());
|
|
109
|
+
});
|
|
110
|
+
it('with --confirm enumerates then dispatches the migration per workspace', async () => {
|
|
111
|
+
vi.mocked(adminCall)
|
|
112
|
+
.mockResolvedValueOnce([
|
|
113
|
+
{ _id: 'ws-1', slug: 'one', name: 'One' },
|
|
114
|
+
{ _id: 'ws-2', slug: 'two', name: 'Two' },
|
|
115
|
+
])
|
|
116
|
+
.mockResolvedValueOnce(migrationResult({ entriesRenamed: 1 }))
|
|
117
|
+
.mockResolvedValueOnce(migrationResult({ entriesRenamed: 2 }));
|
|
118
|
+
await runManage(['migrate-team-vocab', '--all', '--confirm']);
|
|
119
|
+
expect(adminCall).toHaveBeenNthCalledWith(1, 'inspect:list-workspaces', {});
|
|
120
|
+
expect(adminCall).toHaveBeenNthCalledWith(2, MIGRATE, { workspaceId: 'ws-1' });
|
|
121
|
+
expect(adminCall).toHaveBeenNthCalledWith(3, MIGRATE, { workspaceId: 'ws-2' });
|
|
122
|
+
expect(adminCall).toHaveBeenCalledTimes(3);
|
|
123
|
+
});
|
|
124
|
+
it('catches a throwing workspace and continues the fleet loop', async () => {
|
|
125
|
+
vi.mocked(adminCall)
|
|
126
|
+
.mockResolvedValueOnce([
|
|
127
|
+
{ _id: 'ws-1', slug: 'one', name: 'One' },
|
|
128
|
+
{ _id: 'ws-2', slug: 'two', name: 'Two' },
|
|
129
|
+
{ _id: 'ws-3', slug: 'three', name: 'Three' },
|
|
130
|
+
])
|
|
131
|
+
.mockResolvedValueOnce(migrationResult({ entriesRenamed: 1 }))
|
|
132
|
+
.mockRejectedValueOnce(new Error('legacy + renamed systemKey coexist'))
|
|
133
|
+
.mockResolvedValueOnce(migrationResult({ entriesRenamed: 3 }));
|
|
134
|
+
await runManage(['migrate-team-vocab', '--all', '--confirm']);
|
|
135
|
+
// All three workspaces were attempted despite ws-2 throwing.
|
|
136
|
+
expect(adminCall).toHaveBeenNthCalledWith(2, MIGRATE, { workspaceId: 'ws-1' });
|
|
137
|
+
expect(adminCall).toHaveBeenNthCalledWith(3, MIGRATE, { workspaceId: 'ws-2' });
|
|
138
|
+
expect(adminCall).toHaveBeenNthCalledWith(4, MIGRATE, { workspaceId: 'ws-3' });
|
|
139
|
+
expect(adminCall).toHaveBeenCalledTimes(4);
|
|
140
|
+
// Failing workspace marks a non-zero exit code.
|
|
141
|
+
expect(process.exitCode).toBe(1);
|
|
142
|
+
});
|
|
143
|
+
it('--json fleet run with a failing workspace still exits non-zero', async () => {
|
|
144
|
+
// The JSON payload is written and the function returns before the human
|
|
145
|
+
// failure block — the exit code must be set on the JSON path too, or CI
|
|
146
|
+
// parsing the payload treats a partial migration as success.
|
|
147
|
+
vi.mocked(isJsonMode).mockReturnValueOnce(true);
|
|
148
|
+
vi.mocked(adminCall)
|
|
149
|
+
.mockResolvedValueOnce([
|
|
150
|
+
{ _id: 'ws-1', slug: 'one', name: 'One' },
|
|
151
|
+
{ _id: 'ws-2', slug: 'two', name: 'Two' },
|
|
152
|
+
])
|
|
153
|
+
.mockResolvedValueOnce(migrationResult({ entriesRenamed: 1 }))
|
|
154
|
+
.mockRejectedValueOnce(new Error('legacy + renamed systemKey coexist'));
|
|
155
|
+
await runManage(['migrate-team-vocab', '--all', '--confirm']);
|
|
156
|
+
expect(process.exitCode).toBe(1);
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
//# sourceMappingURL=manage.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manage.test.js","sourceRoot":"","sources":["../../../src/commands/admin/manage.test.ts"],"names":[],"mappings":"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"}
|