import { mutationSpec, parseWithAccount } from '../lib/api.ts' import { granolaRequest } from '../lib/client.ts' import { echo, mutationMode, preview } from '../lib/guard.ts' import { custodianInputs } from '../lib/holds.ts' /** * Place a named legal hold (`POST /v1/legal-holds`): Granola preserves the covered people's notes, * transcripts and attachments while the hold is active (custodians see no change). Scope is always * explicit: `coversEntireWorkspace` is required; custodians (emails or `usr_…` ids, ≤100) are optional. * WRITE: previews unless `confirm: true`. Needs a Legal hold API key (Enterprise). * * @param input.account - Account whose secret holds a Legal hold API key. Required. @param input.secretName - Secret override. * @param input.name - Unique among live holds (≤200 chars). Required. * @param input.description - ≤2000 chars. * @param input.coversEntireWorkspace - `true` = every current and future member. Required. * @param input.custodians - Member emails or user ids to name on the hold. * @param input.dryRun - Preview only. @param input.confirm - `true` to create. * @returns Preview `{ dryRun: true, request }`, or `{ executed: true, legalHold }` * * @example * import createHold from 'kody:@charlesmatte/granola/legal-holds/create' * * const preview = await createHold({ account: 'work-legal', name: 'Matter 2026-14', coversEntireWorkspace: false, custodians: ['person@example.com'] }) */ export default async function createGranolaLegalHold(input: unknown) { const p = parseWithAccount<{ name: string; description?: string; coversEntireWorkspace: boolean; custodians?: Array; dryRun?: boolean; confirm?: boolean }>( input, { name: { type: 'string', required: true, maxLength: 200 }, description: { type: 'string', maxLength: 2000 }, coversEntireWorkspace: { type: 'boolean', required: true }, custodians: { type: 'stringArray', maxItems: 100 }, ...mutationSpec, }, 'legal-holds/create', ) const body = { name: p.name, ...(p.description !== undefined ? { description: p.description } : {}), covers_entire_workspace: p.coversEntireWorkspace, ...(p.custodians?.length ? { custodians: custodianInputs(p.custodians) } : {}), } const mode = mutationMode(p) const target = `legal hold "${p.name}" (${p.coversEntireWorkspace ? 'entire workspace' : 'named custodians only'}${p.custodians?.length ? ` + ${p.custodians.length} custodian(s)` : ''})` if (!mode.execute) return preview(p.acct, 'legal-holds/create', target, mode, { method: 'POST', path: '/v1/legal-holds', body }) const res = await granolaRequest(p.acct, { method: 'POST', path: '/v1/legal-holds', json: body, retries: 1 }) return { dryRun: false, executed: true, echo: echo(p.acct, 'legal-holds/create', target, mode), legalHold: res.data } }