recess-cli 3.3.0 → 3.3.1

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/args.js CHANGED
@@ -6,6 +6,7 @@ import { CliError } from "./errors.js";
6
6
  */
7
7
  export const REPEATABLE_FLAGS = new Set(["kid", "unassign"]);
8
8
  const BOOLEAN_FLAGS = new Set([
9
+ "zero-balance",
9
10
  "allow-assigned-edits",
10
11
  "all-references",
11
12
  "allow-strand",
package/dist/cli.js CHANGED
@@ -255,7 +255,8 @@ async function localWriteCommand(parsed, preview, execute) {
255
255
  fingerprint,
256
256
  target: preview.target,
257
257
  ...(preview.action.startsWith("mastery.") ||
258
- preview.request.attendanceTakenAt
258
+ preview.request.attendanceTakenAt ||
259
+ preview.request.zeroBalance === "true"
259
260
  ? { preview }
260
261
  : {}),
261
262
  });
@@ -3045,6 +3046,24 @@ export async function executeRecessCommand(argv, options = {}) {
3045
3046
  const account = unwrap(await api.client.GET("/admin/payout/recipient/", {
3046
3047
  params: { query: { id: accountId, includeArchived: "true" } },
3047
3048
  })).recipients[0];
3049
+ const zeroBalance = hasFlag(parsed, "zero-balance");
3050
+ // Keep the approved before-balance on retries, so the server can replay
3051
+ // a completed operation after the account has already been zeroed.
3052
+ const operationKey = flagString(parsed, "operation-key");
3053
+ const stored = zeroBalance && hasFlag(parsed, "confirm") && operationKey
3054
+ ? await getJob(operationKey)
3055
+ : undefined;
3056
+ const approvedBalance = stored?.history.find((event) => event.preview?.request.zeroBalance === "true")?.preview?.request.expectedBalanceCents;
3057
+ const expectedBalanceCents = typeof approvedBalance === "number"
3058
+ ? approvedBalance
3059
+ : account.accountBalance;
3060
+ const removalQuery = zeroBalance
3061
+ ? {
3062
+ zeroBalance: "true",
3063
+ reason: flagString(parsed, "reason", { required: true }),
3064
+ expectedBalanceCents,
3065
+ }
3066
+ : {};
3048
3067
  const effects = action === "archive"
3049
3068
  ? "Archive payout account, end all schedules and cancel all draft/review invoices. Stops new Recess accruals; preserves payment history and the guide login."
3050
3069
  : action === "unarchive"
@@ -3055,18 +3074,27 @@ export async function executeRecessCommand(argv, options = {}) {
3055
3074
  ? "Add active payout account to recurring schedule. Future payroll cycles will accrue compensation in Recess."
3056
3075
  : "Remove account from this payroll cycle and cancel its draft/review invoices. Future cycles are unchanged; regeneration will not re-add this account.";
3057
3076
  return writeCommand(parsed, {
3058
- action: effects,
3077
+ action: effects +
3078
+ (zeroBalance
3079
+ ? " OVERRIDE: cancel unpaid OPEN invoices in this scope and set the entire account balance to zero. Invoice amounts and payment history are preserved; no money is sent. Pending payments and obligations outside this scope must be resolved first."
3080
+ : ""),
3059
3081
  target: {
3060
3082
  accountId,
3061
3083
  ...(payRunId ? { payRunId } : {}),
3062
3084
  ...(scheduleId ? { scheduleId } : {}),
3063
3085
  },
3064
- request: { action },
3065
- details: { accountName: account.name, user: account.user },
3086
+ request: { action, ...removalQuery },
3087
+ details: {
3088
+ accountName: account.name,
3089
+ user: account.user,
3090
+ ...(zeroBalance
3091
+ ? { previousBalanceCents: expectedBalanceCents, balanceCents: 0 }
3092
+ : {}),
3093
+ },
3066
3094
  }, async () => {
3067
3095
  if (action === "archive")
3068
3096
  return unwrap(await api.client.DELETE("/admin/payout/recipient/{accountId}", {
3069
- params: { path: { accountId } },
3097
+ params: { path: { accountId }, query: removalQuery },
3070
3098
  }));
3071
3099
  if (action === "unarchive")
3072
3100
  return unwrap(await api.client.POST("/admin/payout/recipient/{accountId}/unarchive", { params: { path: { accountId } } }));
@@ -3075,8 +3103,18 @@ export async function executeRecessCommand(argv, options = {}) {
3075
3103
  body: { accountId, scheduleId: scheduleId },
3076
3104
  }));
3077
3105
  if (action === "remove-schedule")
3078
- return unwrap(await api.client.DELETE("/admin/payout/schedule/{targetId}/recipient/{accountId}", { params: { path: { accountId, targetId: scheduleId } } }));
3079
- return unwrap(await api.client.DELETE("/admin/payout/cycle/{targetId}/recipient/{accountId}", { params: { path: { accountId, targetId: payRunId } } }));
3106
+ return unwrap(await api.client.DELETE("/admin/payout/schedule/{targetId}/recipient/{accountId}", {
3107
+ params: {
3108
+ path: { accountId, targetId: scheduleId },
3109
+ query: removalQuery,
3110
+ },
3111
+ }));
3112
+ return unwrap(await api.client.DELETE("/admin/payout/cycle/{targetId}/recipient/{accountId}", {
3113
+ params: {
3114
+ path: { accountId, targetId: payRunId },
3115
+ query: removalQuery,
3116
+ },
3117
+ }));
3080
3118
  });
3081
3119
  }
3082
3120
  if (area === "invoices" && action === "list") {
@@ -1,6 +1,7 @@
1
1
  import { CliError } from "./errors.js";
2
2
  export const AGENT_CONTEXT_SCHEMA_VERSION = "4";
3
3
  const BOOLEAN_FLAGS = new Set([
4
+ "zero-balance",
4
5
  "allow-possible-duplicate",
5
6
  "allow-state-modification",
6
7
  "allow-assigned-edits",
package/dist/help.js CHANGED
@@ -134,11 +134,11 @@ Usage:
134
134
  [--limit 20] [--cursor <id>]
135
135
  recess [--json] payout invoices list [--payrun <id>] [--recipient <account-id>]
136
136
  [--user <id>] [--status A,B] (at least one filter)
137
- recess [--json] payout recipients archive <account-id> [--confirm]
137
+ recess [--json] payout recipients archive <account-id> [--zero-balance] [--confirm]
138
138
  recess [--json] payout recipients unarchive <account-id> [--confirm]
139
- recess [--json] payout recipients remove-schedule <account-id> --schedule <id> [--confirm]
139
+ recess [--json] payout recipients remove-schedule <account-id> --schedule <id> [--zero-balance] [--confirm]
140
140
  recess [--json] payout recipients add-schedule <account-id> --schedule <id> [--confirm]
141
- recess [--json] payout payruns remove-account <payrun-id> --recipient <account-id> [--confirm]
141
+ recess [--json] payout payruns remove-account <payrun-id> --recipient <account-id> [--zero-balance] [--confirm]
142
142
  recess [--json] payout invoices get <invoice-id>
143
143
  recess [--json] payout invoices set-status <invoice-id>
144
144
  --status IN_REVIEW|OPEN|PAID|CANCELED [--send-email] [--confirm]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "recess-cli",
3
- "version": "3.3.0",
3
+ "version": "3.3.1",
4
4
  "description": "Safe Recess administration and family AI tools from the command line.",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {