MedBridge Sales Ops JSON SOP
Produce only the final JSON object requested by the prompt. Read the task prompt and input/payloads/answer_template.json, fetch facts from the MedBridge Sales Ops API, calculate the requested totals/statuses, and return JSON with exactly the template's keys, nesting, ordering style, enum values, numeric types, and null conventions.
API Workflow
- Resolve the API base URL from the task prompt or runner environment. Prompts may name it
API_BASE_URL,BASE_URL, or showhttp://127.0.0.1:<PORT>. - Use
GET {BASE_URL}/apiif you need the route index. Common routes:GET /api/search?q=<id-or-text>GET /api/customers/<customer_id>GET /api/products/<product_code>GET /api/rfqs/<rfq_id>GET /api/quotes/<quote_id>GET /api/opportunities/<opportunity_id>- Collections:
/api/freight-quotes,/api/invoices,/api/payments,/api/revenue-journals,/api/events,/api/vouchers,/api/policies
- Prefer targeted lookups:
- Search by the quote, RFQ, opportunity, event, voucher, product, and customer IDs named in the prompt.
- Fetch product records directly for every requested product/module.
- Fetch the customer directly when a customer name, segment, payment profile, or contact must be verified.
- Treat records returned by search as candidates, not automatic inclusions. Keep only records whose IDs and linkage fields match the task:
quote_id,rfq_id,opportunity_id,customer_id,invoice_id,event_id, orvoucher_code.
Output Rules
- Return valid JSON only. No markdown, comments, or explanatory text.
- Preserve the answer template shape. Do not add fields that are not in the template.
- Use JSON numbers for money and quantities, not strings. Use cents when the template requests two-decimal USD values.
- Use ISO dates (
YYYY-MM-DD) andnullwhere the template allows null. - Convert enums exactly to the template's controlled values. Usually API lowercase status/mode values become uppercase output values.
- Use the business date, quote date, or as-of date named in the prompt. If none is supplied, use the relevant API record date, not the real-world current date.
- If the prompt supplies a display name or contact that differs slightly from the API customer/contact record, use the prompt's explicit name in human-facing output fields and keep stable IDs from the API.
Quote and RFQ Pricing
Use this flow for quote revisions, RFQs, module quotes, freight comparisons, and payment/quote-control packages.
- Identify the commercial source:
- Quote revisions use
/api/quotes/<quote_id>. - Indicative module requests use
/api/rfqs/<rfq_id>.
- Quote revisions use
- Confirm customer, quote/RFQ date, currency, product codes, and quantities from the API and prompt. Prompt-confirmed quantities override prior or superseded values.
- For each product, fetch
/api/products/<product_code>. - Select the price tier where
min_qty <= quantityand eitherquantity <= max_qtyormax_qtyis null. Never useprior_unit_price_usdor older RFQ quantities for a revised quote. - Compute:
line_total = quantity * unit_priceexw_total = sum(line_total)grand_total = exw_total + freight_costwhen freight is included
- Copy product facts from the product record:
article_number, selected tierlead_time_days, productshelf_life_months, and selected tier bounds when requested. - For module-level RFQs, quote the requested modules only. Do not explode
componentsorcomponent_composition_distractorsinto line items. - If the task says destination is pending or asks for EXW only, set freight-excluded fields to true and do not invent freight.
Freight Decisions
- Search by quote ID to get linked freight records. Include freight only when
record.quote_idexactly matches the task quote. - Exclude distractors:
- IDs or RFQs marked as distractors, superseded, draft, closed-lost, or stale benchmarks unrelated to the requested route.
- Freight with a mismatched route, destination, shipment size, product family, or quote/RFQ linkage.
- Include stale/expired freight only when it is one of the task's requested current-mode comparisons and the prompt asks for source-validity, stale-source, or route-risk concerns. Mark it stale rather than silently dropping it.
- Validity:
- Valid when
statusis active andvalid_until >= quote_date. - Stale/expired when
statusis stale orvalid_until < quote_date. source_is_staleis true for stale/expired records.all_freight_options_valid_on_quote_dateis true only when every included option is valid on the quote date.
- Valid when
- Risk fields:
risk_levelusually comes fromroute_riskuppercased.risk_flagisNONEfor low risk,MEDIUM_BORDER_RISKfor medium border/customs risk, and the template's high-risk equivalent for high border/customs risk.- If the output asks specifically for customs or border risk, read
risk_notes; default toLOWunless the notes mention medium/high customs or border risk.
- Transit days:
- Use
transit_days_textif the template expects text such as"4-6 days". - Use a min-max string without the word "days" only if the template examples or field style show that convention.
- Use
- Recommended mode:
- Prefer the lowest-cost valid freight option that satisfies stated constraints and avoids medium/high border risk when a comparable valid low-risk option exists.
- Do not recommend stale or expired freight unless the prompt explicitly asks to accept it.
- When the cheapest option is stale/high-risk, recommend the next valid practical mode.
freight_reconfirmation_requiredis true when freight options are included and the policy/prompt requires reconfirmation, or when any included option is stale, expired, medium/high risk, or near expiry.
Payment and Quote Policies
Use customer segment, customer_type, is_recurring, and payment_profile, plus /api/policies or targeted policy search when needed.
- New NGO or new-client-review profiles: payment terms are
PREPAY_100; set new-client controls such aswho_documentation_requiredwhen the template asks for them. - Recurring approved NGO/commercial/government accounts with
NET_30_AFTER_PO: useNET_30_AFTER_POunless a policy or prompt says the grant restricts credit. - EXW-only module quotes use quote basis values like
EXW_ONLY. - Quote revisions with freight options use the template's EXW-plus-freight basis value, often
EXW_PLUS_FREIGHT_OPTIONS; quote summary fields may simply useEXW. - Offer validity is commonly a policy/template field; use the policy value if available, otherwise use the task/template convention.
Opportunity Reconciliation
Use this flow for CRM/account reconciliation, milestone invoices, payments, revenue recognition, and follow-up actions.
- Search by
opportunity_id; collect the opportunity, linked invoices, payments, revenue journals, events, and vouchers. Fetch the customer record forcustomer_nameand contact validation. - Keep only records linked to the requested
opportunity_idandcustomer_id. - Convert opportunity stage:
closed_won->WON- open pipeline stages such as negotiation/open ->
OPEN - lost/closed_lost ->
LOST
- Sort milestones by opportunity phase order. If the template uses
MS1,MS2,MS3, assign those labels by sorted phase order even when API phase IDs have account-specific prefixes. - Match each phase to its invoice by
invoice_id. Compute:phase_total_amount = sum(phase.amount_usd)opportunity_matches_phase_total = won_amount_usd == phase_total_amounttotal_paid_amount = sum(invoice.paid_amount_usd)outstanding_balance = sum(invoice.outstanding_amount_usd)or the opportunity outstanding amount when the template wants account status.
- Invoice/payment status:
- Paid in full:
PAID - Partial payment:
PARTIAL - No payment and outstanding amount:
UNPAID - For invoice-state templates, map paid invoices to
PAID, unpaid/open invoices toOPEN, void toVOID, and missing/unclear records toUNKNOWN.
- Paid in full:
- Revenue recognition:
- A paid, complete milestone requires a posted revenue journal.
- If a matching posted journal exists by invoice, phase, or opportunity:
RECOGNIZED. - If paid and complete but no matching posted journal: use the template's missing value, such as
MISSING_REVENUE_JOURNALorREQUIRED_MISSING. - Unpaid milestones are
NOT_REQUIRED_UNPAID. - Overall recognition is complete only when every paid complete milestone has a journal; otherwise use the template's missing-for-paid-milestones value.
- Recognized amount is the sum of posted revenue journals for the requested opportunity's paid recognized milestones.
Follow-up Actions
Fit actions to the enums in the answer template.
- Missing revenue journal for a paid complete milestone:
- Primary action:
RECORD_REVENUE_MS<n>if the template provides milestone-specific enums. - Accounting action amount: the milestone/invoice amount.
- Debit:
DEFERRED_REVENUE. - Credit:
IMPLEMENTATION_SERVICES_REVENUE. - Owner queue:
ACCOUNTING.
- Primary action:
- Unpaid milestone:
- If due date is in the future relative to the as-of date, use monitoring-style values such as
MONITOR_UNPAID_NOT_DUEwhen available. - If due or overdue, use collection-style values such as
SEND_COLLECTION_NOTICEorCOLLECT_UNPAID_MILESTONE. - Use the invoice due date unless the prompt names a separate business follow-up due date.
- If due date is in the future relative to the as-of date, use monitoring-style values such as
- Event/voucher:
- Include the event named in the prompt, or the opportunity-linked event when the template asks for event actions.
- Map event statuses to the template's uppercase enum; scheduled/confirmed events generally become
SCHEDULEDunless the template has a more specific value. - Use voucher
codeasvoucher_code,discount_percentas the template's discount numeric value, andmax_redemptionsas max uses. - If an invite should be sent and the event/voucher are active or scheduled, use the send-invite enum from the template and set owner queue to account management when the event owner is Account Management.
Common Pitfalls
- Do not solve from memory or training examples. Always call the API for the task IDs.
- Do not include API search distractors just because they share a customer, product, or payment profile.
- Do not use old RFQs, draft records, superseded records, prior quote quantities, or prior unit prices for current revised pricing.
- Do not split kit/module products into components when the prompt asks for product or module-level pricing.
- Do not omit a stale freight option if the prompt explicitly asks to report stale/source-validity concerns for the requested transport comparison.
- Do not recommend a stale, expired, or high-border-risk freight mode merely because it is cheapest.
- Do not recognize revenue for unpaid milestones, and do not mark paid complete milestones as fully covered unless a matching posted revenue journal exists.
- Do not invent contacts, event IDs, voucher codes, or due dates; take them from the prompt or linked API records and use
nullwhere the template permits no value.