registration-tool-flow.sh 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. #!/usr/bin/env bash
  2. set -euo pipefail
  3. # Default demo backend URL. Override with:
  4. # BASE_URL=http://localhost:8080 ./scripts/demo-registration/registration-tool-flow.sh
  5. BASE_URL="${BASE_URL:-http://localhost:8080}"
  6. PROJECT_ID="${PROJECT_ID:-demo-registration}"
  7. TRACE_ID="${TRACE_ID:-trace-demo-registration-$(date +%Y%m%d%H%M%S)}"
  8. PATIENT_ID="${PATIENT_ID:-patient_demo_001}"
  9. PATIENT_PHONE="${PATIENT_PHONE:-13800000001}"
  10. PATIENT_ID_CARD="${PATIENT_ID_CARD:-110101199001010011}"
  11. PATIENT_NAME="${PATIENT_NAME:-张三}"
  12. DEPARTMENT_ID="${DEPARTMENT_ID:-dept_neurology}"
  13. DOCTOR_ID="${DOCTOR_ID:-doctor_neuro_001}"
  14. SCHEDULE_ID="${SCHEDULE_ID:-schedule_neuro_001_d1_am}"
  15. SCHEDULE_DATE="${SCHEDULE_DATE:-}"
  16. LOCK_ID="${LOCK_ID:-}"
  17. ORDER_ID="${ORDER_ID:-}"
  18. has_jq=false
  19. if command -v jq >/dev/null 2>&1; then
  20. has_jq=true
  21. fi
  22. json_quote() {
  23. if [ "$has_jq" = true ]; then
  24. jq -Rn --arg value "$1" '$value'
  25. return
  26. fi
  27. printf '"%s"' "$(printf '%s' "$1" | sed 's/\\/\\\\/g; s/"/\\"/g')"
  28. }
  29. extract_json_string() {
  30. local json="$1"
  31. local filter="$2"
  32. if [ "$has_jq" = false ]; then
  33. return 1
  34. fi
  35. printf '%s' "$json" | jq -er "$filter // empty"
  36. }
  37. request_body() {
  38. local tool_call_id="$1"
  39. local risk_level="$2"
  40. local input_json="$3"
  41. cat <<JSON
  42. {
  43. "toolCallId": "$tool_call_id",
  44. "context": {
  45. "projectId": "$PROJECT_ID",
  46. "traceId": "$TRACE_ID"
  47. },
  48. "input": $input_json,
  49. "riskLevel": "$risk_level"
  50. }
  51. JSON
  52. }
  53. get_catalog() {
  54. echo
  55. echo "GET ${BASE_URL}/tools/catalog"
  56. echo "Expected markers for invoke responses: mock=true, status=success"
  57. curl -sS \
  58. -H "Accept: application/json" \
  59. "${BASE_URL}/tools/catalog"
  60. echo
  61. }
  62. invoke_tool() {
  63. local tool_name="$1"
  64. local risk_level="$2"
  65. local input_json="$3"
  66. local idempotency_key="${4:-}"
  67. local tool_call_id="demo-${tool_name//./-}-$(date +%s)"
  68. local body
  69. body="$(request_body "$tool_call_id" "$risk_level" "$input_json")"
  70. echo >&2
  71. echo "POST ${BASE_URL}/tools/${tool_name}/invoke" >&2
  72. if [ -n "$idempotency_key" ]; then
  73. echo "X-Emoon-Idempotency-Key: ${idempotency_key}" >&2
  74. fi
  75. echo "Expected markers: mock=true, status=success" >&2
  76. case "$tool_name" in
  77. payment.*)
  78. echo "Expected payment marker: mockPayment=true" >&2
  79. ;;
  80. esac
  81. if [ -n "$idempotency_key" ]; then
  82. curl -sS \
  83. -H "Accept: application/json" \
  84. -H "Content-Type: application/json" \
  85. -H "X-Emoon-Idempotency-Key: ${idempotency_key}" \
  86. -d "$body" \
  87. "${BASE_URL}/tools/${tool_name}/invoke"
  88. else
  89. curl -sS \
  90. -H "Accept: application/json" \
  91. -H "Content-Type: application/json" \
  92. -d "$body" \
  93. "${BASE_URL}/tools/${tool_name}/invoke"
  94. fi
  95. echo >&2
  96. }
  97. require_dynamic_id() {
  98. local name="$1"
  99. local value="$2"
  100. local hint="$3"
  101. if [ -n "$value" ]; then
  102. return
  103. fi
  104. cat >&2 <<EOF
  105. Missing ${name}.
  106. Install jq to auto-extract dynamic IDs, or rerun with ${name}=... after copying it from the previous response.
  107. ${hint}
  108. EOF
  109. exit 1
  110. }
  111. echo "Demo registration tool flow"
  112. echo "BASE_URL=${BASE_URL}"
  113. echo "PROJECT_ID=${PROJECT_ID}"
  114. echo "TRACE_ID=${TRACE_ID}"
  115. echo "Seed values: patientId=${PATIENT_ID}, departmentId=${DEPARTMENT_ID}, doctorId=${DOCTOR_ID}, scheduleId=${SCHEDULE_ID}"
  116. if [ "$has_jq" = false ]; then
  117. echo "jq not found: the script will still issue fixed-ID reads/writes, but dynamic lockId/orderId extraction requires jq or LOCK_ID/ORDER_ID env overrides."
  118. fi
  119. get_catalog
  120. search_patient_response="$(invoke_tool \
  121. "his.searchPatient" \
  122. "L2_SENSITIVE_READ" \
  123. "{\"phone\":$(json_quote "$PATIENT_PHONE"),\"idCard\":$(json_quote "$PATIENT_ID_CARD")}")"
  124. printf '%s\n' "$search_patient_response"
  125. departments_response="$(invoke_tool \
  126. "his.queryDepartments" \
  127. "L1_QUERY" \
  128. "{}")"
  129. printf '%s\n' "$departments_response"
  130. doctors_response="$(invoke_tool \
  131. "his.queryDoctors" \
  132. "L1_QUERY" \
  133. "{\"departmentId\":$(json_quote "$DEPARTMENT_ID")}")"
  134. printf '%s\n' "$doctors_response"
  135. schedule_input="{\"doctorId\":$(json_quote "$DOCTOR_ID")}"
  136. if [ -n "$SCHEDULE_DATE" ]; then
  137. schedule_input="{\"doctorId\":$(json_quote "$DOCTOR_ID"),\"date\":$(json_quote "$SCHEDULE_DATE")}"
  138. fi
  139. schedules_response="$(invoke_tool \
  140. "his.querySchedules" \
  141. "L1_QUERY" \
  142. "$schedule_input")"
  143. printf '%s\n' "$schedules_response"
  144. lock_idempotency_key="demo-lock-${TRACE_ID}"
  145. lock_response="$(invoke_tool \
  146. "his.lockSchedule" \
  147. "L3_BUSINESS_WRITE" \
  148. "{\"scheduleId\":$(json_quote "$SCHEDULE_ID"),\"patientId\":$(json_quote "$PATIENT_ID")}" \
  149. "$lock_idempotency_key")"
  150. printf '%s\n' "$lock_response"
  151. if [ -z "$LOCK_ID" ] && [ "$has_jq" = true ]; then
  152. LOCK_ID="$(extract_json_string "$lock_response" '.data.result.lock.lockId')"
  153. fi
  154. require_dynamic_id "LOCK_ID" "$LOCK_ID" "Expected path with jq: .data.result.lock.lockId"
  155. order_idempotency_key="demo-payment-order-${TRACE_ID}"
  156. order_response="$(invoke_tool \
  157. "payment.createOrder" \
  158. "L4_FINANCIAL_ACTION" \
  159. "{\"lockId\":$(json_quote "$LOCK_ID")}" \
  160. "$order_idempotency_key")"
  161. printf '%s\n' "$order_response"
  162. if [ -z "$ORDER_ID" ] && [ "$has_jq" = true ]; then
  163. ORDER_ID="$(extract_json_string "$order_response" '.data.result.order.orderId')"
  164. fi
  165. require_dynamic_id "ORDER_ID" "$ORDER_ID" "Expected path with jq: .data.result.order.orderId"
  166. paid_idempotency_key="demo-mark-paid-${TRACE_ID}"
  167. paid_response="$(invoke_tool \
  168. "payment.markMockPaid" \
  169. "L4_FINANCIAL_ACTION" \
  170. "{\"orderId\":$(json_quote "$ORDER_ID")}" \
  171. "$paid_idempotency_key")"
  172. printf '%s\n' "$paid_response"
  173. registration_idempotency_key="demo-registration-${TRACE_ID}"
  174. registration_response="$(invoke_tool \
  175. "his.createRegistration" \
  176. "L3_BUSINESS_WRITE" \
  177. "{\"lockId\":$(json_quote "$LOCK_ID"),\"orderId\":$(json_quote "$ORDER_ID"),\"patientId\":$(json_quote "$PATIENT_ID"),\"patientName\":$(json_quote "$PATIENT_NAME"),\"patientIdCard\":$(json_quote "$PATIENT_ID_CARD"),\"patientPhone\":$(json_quote "$PATIENT_PHONE"),\"departmentId\":$(json_quote "$DEPARTMENT_ID"),\"doctorId\":$(json_quote "$DOCTOR_ID"),\"slotId\":$(json_quote "$SCHEDULE_ID")}" \
  178. "$registration_idempotency_key")"
  179. printf '%s\n' "$registration_response"
  180. echo
  181. echo "Flow complete. Expected final markers: mock=true, status=success"