import { defineLogicFunction } from 'twenty-sdk/define'; import { LOGIC_FUNCTION_CONSTANTS } from 'src/constants/universal-identifiers'; import { recordDecisionCore } from 'src/logic-functions/handlers/record-decision'; import { extractBody, extractUserWorkspaceId, normalizeRecordId, } from 'src/logic-functions/utils/route-input'; import { type DecisionValue } from 'src/types/contract-status'; import { type RecordDecisionInput, type RecordDecisionOutcome, } from 'src/types/logic-function-io'; // Route-only (isAuthRequired: true): the approval gate needs the invoking user's // identity, which only exists on an authenticated route — never in a workflow run. const handler = (input: unknown): Promise => { const body = extractBody(input as never); const contractId = normalizeRecordId(body?.contractId); const decision = body?.decision as DecisionValue | undefined; if (contractId === undefined || decision === undefined) { return Promise.resolve({ success: false, contractId: contractId ?? '', error: 'Missing contractId or decision.', }); } return recordDecisionCore({ input: { contractId, decision, comment: body?.comment }, eventUserWorkspaceId: extractUserWorkspaceId(input), }); }; export default defineLogicFunction({ universalIdentifier: LOGIC_FUNCTION_CONSTANTS.recordDecision.universalIdentifier, name: 'record-decision', description: 'Records a manager approve/reject decision on a Contract. Verifies the invoking user holds the Manager role before writing the audit record and updating status.', timeoutSeconds: 60, handler, httpRouteTriggerSettings: { path: LOGIC_FUNCTION_CONSTANTS.recordDecision.path, httpMethod: 'POST', isAuthRequired: true, }, });