From 157f71e4573ac9bbb42cd0bb50687565e9f43235 Mon Sep 17 00:00:00 2001 From: Ben Sabic Date: Sun, 22 Feb 2026 15:56:22 +1100 Subject: [PATCH] feat: add members note command for updating member notes --- src/commands/members.ts | 26 ++++++++++++++++++++++++++ tests/commands/members.test.ts | 25 +++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/src/commands/members.ts b/src/commands/members.ts index 2870739..cbb37d2 100644 --- a/src/commands/members.ts +++ b/src/commands/members.ts @@ -453,6 +453,32 @@ membersCommand } }); +membersCommand + .command("note") + .description("Update a member's note") + .argument("", "Member ID (mem_...)") + .option("--text ", "Note text (omit to clear)") + .action(async (id: string, opts: { text?: string }) => { + const spinner = yoctoSpinner({ text: "Updating note..." }).start(); + try { + const result = await graphqlRequest<{ updateMemberNote: Member }>({ + query: `mutation($input: UpdateMemberNoteInput!) { + updateMemberNote(input: $input) { ${MEMBER_FIELDS} } +}`, + variables: { input: { memberId: id, note: opts.text ?? "" } }, + }); + spinner.stop(); + printSuccess(`Note updated for member ${id}.`); + printRecord(result.updateMemberNote); + } catch (error) { + spinner.stop(); + printError( + error instanceof Error ? error.message : "An unknown error occurred" + ); + process.exitCode = 1; + } + }); + membersCommand .command("delete") .description("Delete a member") diff --git a/tests/commands/members.test.ts b/tests/commands/members.test.ts index 07dba5b..d26bd64 100644 --- a/tests/commands/members.test.ts +++ b/tests/commands/members.test.ts @@ -205,6 +205,31 @@ describe("members", () => { expect(call.variables.input.json).toEqual({ key: "value" }); }); + it("note sends memberId and text", async () => { + graphqlRequest.mockResolvedValueOnce({ updateMemberNote: mockMember }); + + await runCommand(membersCommand, [ + "note", + "mem_1", + "--text", + "VIP customer", + ]); + + const call = graphqlRequest.mock.calls[0][0]; + expect(call.variables.input.memberId).toBe("mem_1"); + expect(call.variables.input.note).toBe("VIP customer"); + }); + + it("note clears when no text provided", async () => { + graphqlRequest.mockResolvedValueOnce({ updateMemberNote: mockMember }); + + await runCommand(membersCommand, ["note", "mem_1"]); + + const call = graphqlRequest.mock.calls[0][0]; + expect(call.variables.input.memberId).toBe("mem_1"); + expect(call.variables.input.note).toBe(""); + }); + it("handles errors gracefully", async () => { graphqlRequest.mockRejectedValueOnce(new Error("Unauthorized"));