fix(cost): bill a session outside every workspace to its Linux account's user
A script's claude -p in a temp folder (the SG Flow eval runner strips the pane's env) had no workspace, so its spend reached nobody's Today, the Users page or a spend quota — ~$57 of a $74 day was missing from the status bar. sessions.account records the Linux account a session ran as (the hook's peer uid, else its folder for poller-made and old rows); a session no workspace owns is owned by that account's user — a member's to them, the host's to the admin ticked 'Owns this server's host account' (or the only admin). Workspace ownership still wins.
This commit is contained in:
+7
-1
@@ -213,6 +213,9 @@ const publicUser = (u) =>
|
||||
createdAt: u.created_at ?? null,
|
||||
// An admin gave this password: the account must pick its own first.
|
||||
mustChangePassword: Boolean(u.must_change_password),
|
||||
// Owns the host's Linux account: its sessions outside every workspace
|
||||
// are billed to this admin (server/lib/session-account.js).
|
||||
hostAccount: Boolean(u.host_account),
|
||||
};
|
||||
|
||||
const MAX_DISPLAY_NAME = 100;
|
||||
@@ -415,7 +418,10 @@ function setRole(username, role) {
|
||||
if (!ROLES.includes(role)) throw err("EBADROLE", `role: one of ${ROLES.join(", ")}`);
|
||||
const u = requireUser(username);
|
||||
if (role !== "admin") assertKeepsAdmin(u, "demoted");
|
||||
sql("UPDATE users SET role = ? WHERE id = ?").run(role, u.id);
|
||||
// Only an admin owns the host account (session-account.js): a demotion drops the mark.
|
||||
sql(
|
||||
"UPDATE users SET role = ?, host_account = CASE WHEN ? = 'admin' THEN host_account ELSE 0 END WHERE id = ?"
|
||||
).run(role, role, u.id);
|
||||
if (role !== "admin") stopHostPanes(u.id);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user