Skip to content
death.tech home
All recent changes

Let advisors assign a new will amendment case to themselves

3c936ebfeat(amendments)merged 2d ago3 review threads

Illustrative: based on a real change, edited for clarity and privacy.

src/domains/cases/actions/create-amendment-case.ts+20 −5

Changes to src/domains/cases/actions/create-amendment-case.ts. Lines with review comments are numbered.
@@ const inputSchema = z.object({
2626 willBank: z.enum(WILL_BANK_NAMES).optional(),
2727 /** Triage summary attached as a NOTE activity on the new case. */
2828 intakeNote: z.string().trim().min(1).max(3000).optional(),
29added /** When true, assign the new case to the signed-in advisor. */
1 line 30, review thread 1added assignToMe: z.boolean().optional().default(false),
2931})
3032
31removedexport type CreateAmendmentCaseInput = z.infer<typeof inputSchema>
2 line 33, review thread 2addedexport type CreateAmendmentCaseInput = z.input<typeof inputSchema>
3234
3335export type CreateAmendmentCaseResult =
34removed | { success: true; caseRef: string }
36added | { success: true; caseRef: string; selfAssignFailed: boolean }
3537 | { success: false; error: string }
3638
3739const log = createLogger('cases', 'create-amendment-case')
3840
@@ export async function createAmendmentCase(
7189 return { success: false, error: 'Case service is not configured' }
7290 }
7391
74removed const { customerRef, initialState, willBank, intakeNote, idempotencySession } =
75removed parsed.data
92added const {
93added customerRef,
94added initialState,
95added willBank,
96added intakeNote,
97added idempotencySession,
98added assignToMe,
99added } = parsed.data
100added const assignTo = assignToMe ? advisorId : undefined
76101
77102 log.info('Creating amendment case', {
78103 advisorId,
@@ export async function createAmendmentCase(
96121 initial_state: initialState,
97122 data: { is_amendment_case: true },
98123 ...(intakeNote ? { intake_note: intakeNote } : {}),
3 line 124, review thread 3added ...(assignTo ? { assign_to: assignTo } : {}),
99125 }
100126
101127 try {
@@ export async function createAmendmentCase(
117143
118144 log.info('Amendment case created', { advisorId, caseRef })
119145 emitMetric('AmendmentCaseCreated')
120removed return { success: true, caseRef }
146added return {
147added success: true,
148added caseRef,
149added // The case exists either way; the modal says so if self-assignment didn't stick.
150added selfAssignFailed: assignmentMissed(assignTo, response),
151added }
121152 } catch (error) {
    1. advisors team

      Most amendments I triage I end up handling myself, so this saves a step every time. Could it be ticked by default?

    2. author

      Starting unticked so nobody picks up a case by accident. If most people tick it over the next couple of weeks, we’ll flip the default.

    1. AI reviewP1

      The TypeScript build fails

      .default(false) makes assignToMe required in z.infer, which describes the parsed output. The modal leaves the field out, so its call no longer type-checks. Use z.input for the request type and keep the default.

    2. author

      Good spot. Switched to z.input: callers can leave it out, and the action still gets a boolean.

    1. reviewer

      Adding assign_to changes the idempotency key. If the case saves but the response is lost, and the advisor ticks or unticks the box before retrying, we’d create a second case. Do we care?

    2. author

      That needs the response to be lost in transit and the advisor to change their choice before retrying. It’s a very small edge case, so we’re not adding machinery for it.

    3. reviewer

      Agreed, both have to happen at once. Let’s note it on the ticket rather than build for it now. Approving.

We’d like to use PostHog to see how this site gets used. It sets cookies, so it stays off until you allow it; everything else works without. Privacy notice