ui(pool): pick an account's users from its own Edit
Each account row in the Account pool card has a pencil: tick the users whose sessions run on it (one moves off any other account, unticking sends one back to the balancer). PUT /api/accounts/:name/users saves the set in one transaction, audits each change and switches a Claude login into each added user's home at once. The card-level switch button and pinned list are gone.
This commit is contained in:
@@ -201,6 +201,42 @@ describe("pinning a user to one account", () => {
|
||||
assert.equal(pins.pinFor(miaId, "claude"), null);
|
||||
});
|
||||
|
||||
it("sets exactly who runs on one account from its Edit", async () => {
|
||||
const boss = await login("boss", BOSS_PASS);
|
||||
const id = (name) => db.prepare("SELECT id FROM users WHERE username = ?").get(name).id;
|
||||
claudePool.addAccount("team-y", `sk-ant-oat01-${"y".repeat(40)}`);
|
||||
pins.setPin(id("ana"), "claude", "team-1");
|
||||
const edit = (account, userIds, extra = {}) =>
|
||||
call("PUT", `/api/accounts/${account}/users`, {
|
||||
cookie: boss,
|
||||
body: { tool: "claude", userIds, currentPassword: BOSS_PASS, ...extra },
|
||||
});
|
||||
const r = await edit("team-y", [id("mia"), id("ana")]);
|
||||
assert.equal(r.status, 200);
|
||||
assert.deepEqual(r.body.added.map((u) => [u.username, u.switched]).sort(), [
|
||||
["ana", "next-session"],
|
||||
["mia", "next-session"],
|
||||
]);
|
||||
assert.equal(pins.pinFor(id("ana"), "claude"), "team-y", "moved off team-1");
|
||||
const again = await edit("team-y", [id("mia")]);
|
||||
assert.deepEqual(again.body.added, []);
|
||||
assert.deepEqual(
|
||||
again.body.removed.map((u) => u.username),
|
||||
["ana"]
|
||||
);
|
||||
assert.equal(pins.pinFor(id("ana"), "claude"), null);
|
||||
assert.equal(pins.pinFor(id("mia"), "claude"), "team-y");
|
||||
const audit = db.prepare("SELECT path FROM audit_log ORDER BY id DESC LIMIT 1").get();
|
||||
assert.match(audit.path, /unpin ana from claude/);
|
||||
assert.equal((await edit("team-y", [9999])).body.error.code, "ENOUSER");
|
||||
assert.equal((await edit("team-y", "x")).body.error.code, "EBADUSER");
|
||||
assert.equal((await edit("nope", [])).body.error.code, "ENOACCOUNT");
|
||||
assert.equal((await edit("team-y", [], { currentPassword: "x" })).body.error.code, "EREAUTH");
|
||||
assert.equal(pins.pinFor(id("mia"), "claude"), "team-y", "a refused edit changes nothing");
|
||||
await edit("team-y", []);
|
||||
claudePool.removeAccount("team-y");
|
||||
});
|
||||
|
||||
it("is ignored in local mode and dropped with its user", async () => {
|
||||
const miaId = db.prepare("SELECT id FROM users WHERE username = 'mia'").get().id;
|
||||
pins.setPin(miaId, "claude", "team-1");
|
||||
|
||||
Reference in New Issue
Block a user