Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file.

## [Unreleased]

### Added

- `accounts create --vault` and `accounts update --vault/--no-vault` set the
savings-vault flag. A vault account keeps counting toward totals but the
backend rejects it as the source of an expense, a card payment, a loan
payment or a subscription with `422 VAULT_CANNOT_SEND`; transferring out of
it stays allowed. CREDIT and INVESTMENT accounts answer
`422 VAULT_TYPE_UNSUPPORTED`.

## [0.9.0] - 2026-08-12

### Added
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ List commands are intentionally agent-friendly:
- `accounts list --include-archived` includes archived accounts in the account
array and adds `archivedAccounts` metadata. Balance/debt totals remain the
active-account totals returned by LucasApp.
- `accounts` exposes the `vault` flag (`create --vault`,
`update --vault/--no-vault`). A vault account counts toward totals and can
receive money, but the backend rejects it as the source of an expense, card
payment, loan payment or subscription; only transfers out of it are allowed.
- `accounts list` adds `availableCredit` to CREDIT accounts:
`max(0, creditLimit - currentDebt)`. A negative `currentDebt` (overpaid
card) intentionally raises `availableCredit` above `creditLimit`.
Expand Down
6 changes: 6 additions & 0 deletions src/commands/accounts/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export interface CreateAccountOptions {
cashbackRate?: string;
color?: string;
icon?: string;
vault?: boolean;
}

export function buildCreateAccountBody(
Expand Down Expand Up @@ -53,6 +54,7 @@ export function buildCreateAccountBody(
body.cashbackEnabled = opts.cashbackEnabled;
if (opts.cashbackRate !== undefined)
body.cashbackRate = parseFiniteNumber(opts.cashbackRate, "--cashback-rate");
if (opts.vault !== undefined) body.vault = opts.vault;
return body;
}

Expand Down Expand Up @@ -89,4 +91,8 @@ export const createAccountCommand = new Command("create")
)
.option("--color <color>", "Account color")
.option("--icon <icon>", "Account icon")
.option(
"--vault",
"Savings vault: counts toward totals but cannot fund payments (not CREDIT/INVESTMENT)",
)
.action(runCreateAccount);
3 changes: 3 additions & 0 deletions src/commands/accounts/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ export const updateAccountCommand = new Command("update")
.option("--display-order <n>", "Display order")
.option("--excluded", "Exclude from totals")
.option("--no-excluded", "Include in totals")
.option("--vault", "Mark as savings vault (cannot fund payments)")
.option("--no-vault", "Clear the savings vault flag")
.option("--is-archived", "Archive account")
.option("--no-is-archived", "Unarchive account")
.action(async (id: string, opts) => {
Expand Down Expand Up @@ -68,6 +70,7 @@ export const updateAccountCommand = new Command("update")
},
{ opt: "displayOrder", body: "displayOrder", type: "number" },
{ opt: "excluded", body: "excluded", type: "boolean" },
{ opt: "vault", body: "vault", type: "boolean" },
{ opt: "isArchived", body: "isArchived", type: "boolean" },
]);
const data = await apiRequest(
Expand Down
1 change: 1 addition & 0 deletions src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export interface Account {
type?: string;
creditLimit?: number | null;
currentDebt?: number | null;
vault?: boolean;
[key: string]: unknown;
}

Expand Down
31 changes: 31 additions & 0 deletions tests/commands/accounts-vault.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { describe, expect, it, vi } from "vitest";

const apiRequest = vi.fn();

vi.mock("../../src/lib/api-client.js", () => ({
apiRequest,
}));

const { buildCreateAccountBody } =
await import("../../src/commands/accounts/create.js");

describe("accounts vault flag", () => {
it("omits vault when the flag is not passed", () => {
const body = buildCreateAccountBody({
name: "ITK Soles",
type: "DEBIT",
bank: "Interbank",
});
expect(body).not.toHaveProperty("vault");
});

it("sends vault true when --vault is passed", () => {
const body = buildCreateAccountBody({
name: "Ahorro carro",
type: "SAVINGS",
bank: "Interbank",
vault: true,
});
expect(body).toMatchObject({ type: "SAVINGS", vault: true });
});
});