Skip to content

Commit 7f79150

Browse files
authored
feat: add members note command for updating member notes (#15)
Add `members note` subcommand to set or clear a member's note via `--text` flag. Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com>
1 parent 0148b94 commit 7f79150

2 files changed

Lines changed: 51 additions & 0 deletions

File tree

src/commands/members.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,32 @@ membersCommand
453453
}
454454
});
455455

456+
membersCommand
457+
.command("note")
458+
.description("Update a member's note")
459+
.argument("<id>", "Member ID (mem_...)")
460+
.option("--text <text>", "Note text (omit to clear)")
461+
.action(async (id: string, opts: { text?: string }) => {
462+
const spinner = yoctoSpinner({ text: "Updating note..." }).start();
463+
try {
464+
const result = await graphqlRequest<{ updateMemberNote: Member }>({
465+
query: `mutation($input: UpdateMemberNoteInput!) {
466+
updateMemberNote(input: $input) { ${MEMBER_FIELDS} }
467+
}`,
468+
variables: { input: { memberId: id, note: opts.text ?? "" } },
469+
});
470+
spinner.stop();
471+
printSuccess(`Note updated for member ${id}.`);
472+
printRecord(result.updateMemberNote);
473+
} catch (error) {
474+
spinner.stop();
475+
printError(
476+
error instanceof Error ? error.message : "An unknown error occurred"
477+
);
478+
process.exitCode = 1;
479+
}
480+
});
481+
456482
membersCommand
457483
.command("delete")
458484
.description("Delete a member")

tests/commands/members.test.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,31 @@ describe("members", () => {
205205
expect(call.variables.input.json).toEqual({ key: "value" });
206206
});
207207

208+
it("note sends memberId and text", async () => {
209+
graphqlRequest.mockResolvedValueOnce({ updateMemberNote: mockMember });
210+
211+
await runCommand(membersCommand, [
212+
"note",
213+
"mem_1",
214+
"--text",
215+
"VIP customer",
216+
]);
217+
218+
const call = graphqlRequest.mock.calls[0][0];
219+
expect(call.variables.input.memberId).toBe("mem_1");
220+
expect(call.variables.input.note).toBe("VIP customer");
221+
});
222+
223+
it("note clears when no text provided", async () => {
224+
graphqlRequest.mockResolvedValueOnce({ updateMemberNote: mockMember });
225+
226+
await runCommand(membersCommand, ["note", "mem_1"]);
227+
228+
const call = graphqlRequest.mock.calls[0][0];
229+
expect(call.variables.input.memberId).toBe("mem_1");
230+
expect(call.variables.input.note).toBe("");
231+
});
232+
208233
it("handles errors gracefully", async () => {
209234
graphqlRequest.mockRejectedValueOnce(new Error("Unauthorized"));
210235

0 commit comments

Comments
 (0)