Files
dingMCP/skills/dingtalk-approval/references/create-approval.md
T

25 lines
8.2 KiB
Markdown

# Create, submit, and revoke an approval
Create only XFT approvals and these DingTalk templates: `出差申请单_北极大`, `外出_北极大`, `业务招待申请_北极大`, `差旅费用报销_捷康`, `业务招待费用报销_捷康`, and `业务招待申请_捷康`. Other templates remain unsupported even when they are in the same DingTalk category; never attempt to construct or reuse a hidden template reference.
1. Call `approval_list_submission_templates` and use only its returned `templateId`.
2. Call `approval_get_submission_schema`. Compare every required field in `fields` and `inputContract` with information the user has already supplied. Never guess a missing value.
Use `inputContract.values.minimalExample` only as the exact JSON shape for `values`. Replace every angle-bracket placeholder from the user's business answer or the selected live option; never submit a placeholder literally. Continue to enforce the recursive `standardFields` constraints even when the example omits optional fields.
If `submissionCapability.status` is `client_only`, stop API construction and tell the user to start that template in its native client. All six current DingTalk candidates are client-only: five contain unsupported business suites, while live enterprise-API tests rejected the ordinary table form in `业务招待申请_北极大`. Supported XFT templates use their formal create APIs and are verified against live status after submission. XFT use-car applications are outside the MCP scope: they must not appear in the candidate list, and an old reference must be treated as unsupported rather than reconstructed.
Treat every XFT selection as a label-only user interaction. For a field with `optionSource`, call `approval_get_submission_options` with the same `templateId` and show only returned `label` values. After the user chooses a label, copy that exact item's `code` into the corresponding `values` field for prepare/submit; never put the label itself into a code-valued field. Keep its `code` only inside tool arguments and never repeat it in conversation. Apply the same rule to inline `options`; for an inline enum show only `enumLabels` values and internally use the matching enum key. Department results are restricted to the current signed-in user's member record. Never show, explain, or ask the user for a field code, city code, organization code, employee number, archive number, numeric cabin value, `expenseNumber`, `expenseTypeNumber`, `expTypeCode`, or other internal ID. If `selectionCapability.status=client_only`, do not ask for the internal value or guess it: a required field stops MCP creation and requires the native client; an optional field may be skipped, or the user may choose native-client completion. If a required option source cannot return readable labels, stop and offer retry or native-client completion.
For DingTalk, do not ask for or fill applicant and top-level department controls marked `serverManaged`; keep `deptId=-1` unless the user selected a department that the gateway can verify belongs to them. The gateway derives the default department from the authenticated user's live directory record.
3. While any required field is missing or ambiguous, ask the user for the missing information and repeat the check after each answer. Prefer one concise question at a time, grouping fields only when they naturally belong together. Do not call `approval_prepare_submission` until all required fields are complete.
4. Explicitly show the remaining user-visible, API-supported optional business fields with short explanations and ask whether the user wants to add any. Do not present fields marked `userVisible=false`, `serverManaged`, `internallyDerived`, or `selectionCapability.status=client_only` as ordinary questions. Briefly mention client-only optional capabilities only when they are relevant to the user's request. The user may choose to skip all optional fields; record that choice instead of silently omitting them.
5. Call `approval_prepare_submission` with `allowDuplicateInvoices=false`. It automatically checks invoice identifiers and expense signatures against the signed-in user's submitted DingTalk and XFT history for the most recent 30 days. If it reports another missing, invalid, unsupported, or selection-required field, return to the collection loop and ask until validation succeeds. Never work around validation.
6. If preparation returns `duplicate_confirmation_required` or `duplicate_check_unavailable`, no submit-capable `confirmationId` was created. Show the duplicate check's masked invoice evidence, matching source/business number/status, and coverage warning. Ask whether the user still wants to submit. Never infer consent from the original creation request. Only after the user explicitly accepts that exact risk, call prepare again with the same content and `allowDuplicateInvoices=true`. A rejected, revoked, or void prior bill is still a warning; a pending, approved, or unknown prior bill is blocking by default. If another active preparation reserved the same invoice, wait for or finish that preparation rather than overriding it.
7. Show the successful returned preview, including `duplicateCheck`, and obtain explicit final confirmation to create the approval. The preview is already converted back to business labels; repeat those labels exactly and never replace them with values retained from Schema construction. If the gateway cannot map any selection back to a current label, it will refuse to create a `confirmationId`; refresh the live options instead of exposing the unresolved value. Do not treat answers to field questions, the choice to skip optional fields, or the duplicate-risk acknowledgement as this final submission confirmation.
8. After final confirmation, call `approval_submit` once with the same `templateId`, `values`, department, selections, `allowDuplicateInvoices`, and returned `confirmationId`. Never modify the content or retry automatically.
If the user explicitly asks to undo a DingTalk or XFT approval just created through this MCP, call `approval_revoke_submission` once with the returned `revokeId`. Never use revoke to reject another person's todo, never accept a raw user ID, employee ID, or bill ID, and never automatically retry `failed` or `outcome_uncertain`. XFT recall is experimental in this release candidate: the current enterprise has returned `XFTSYS9999` for a real pending bill and no successful XFT recall has been observed. State this limitation when relevant and never report a recall as successful unless the tool returns `revoked` after live reconciliation.
For an XFT submission or recall result that needs reconciliation, call `approval_get_submission_status` with the `businessId` returned by `approval_submit`. It is read-only and revalidates that the bill belongs to the signed-in user's initiated bills. Report `statusName` and the compact flow history. `completed` means the workflow finished immediately under the enterprise's approval rules (for example, no other effective approver); do not retry it. A fresh short-lived `revokeId` is returned only while the live bill status is pending approval; it still requires the user's explicit authorization before one recall attempt. Never treat status lookup alone as permission to repeat a write, and never retry `completed`, `upstream_state_mismatch`, or `outcome_uncertain`.
Never ask for or pass an applicant user ID, employee number, owner, or approval status. The gateway derives them from the authenticated user. For XFT custom fields, keep live `fieldNumber`, option codes, table `titleCode`, and serialization details internal to the tool call. Departments must be selected by returned department names; person fields currently require the native client because the MCP has no safe name lookup. If a required field type is unsupported or XFT reports a missing employee profile or permission, explain the business requirement without exposing internal identifiers and stop.
Local file paths and file bytes are not valid attachment field values. When the live Schema requires an upstream attachment number but the MCP has no attachment-upload tool, preserve any local draft and direct the user to complete that form in the native client. Never pass a local path, base64 content, or an invented attachment number to `approval_prepare_submission`.