Build sales-api REST + MCP layers (Layer 3), full build in one pass
14 routes: Order (single key, full CRUD + order-details sub-resource) and Orderdetail (composite key ordernumber+productcode, own top-level resource, mirrors backend's own URL structure). MCP layer built with the corrected single-route pattern from the start (STATUS.md section 18) — 7 tools, list/get read-only for all 5 roles, create-order/create-orderdetail for admin+customer+support (verified against OrderPermission/OrderScopedPermission.check() — support gets an unconditional class-level pass, the status-only restriction is object-level and doesn't apply to create). Keycloak (local): sales-api-audience + mcp-sales-audience client scopes, sales-api + mcp-sales resource clients, attached to the broker and librechat respectively. Deploy key and broker secret reused/mirrored from catalog-api and the live broker client, same pattern as customers-api/payments-api.
This commit is contained in:
@@ -0,0 +1,223 @@
|
||||
apiVersion: configuration.konghq.com/v1
|
||||
kind: KongPlugin
|
||||
metadata:
|
||||
name: ${NAME}-sales-mcp-ai-mcp-proxy
|
||||
namespace: ${NAMESPACE}
|
||||
plugin: ai-mcp-proxy
|
||||
config:
|
||||
mode: conversion-listener
|
||||
include_consumer_groups: true
|
||||
tools:
|
||||
- name: list-orders
|
||||
description: Retrieves a paginated list of orders in the classic-models CRM.
|
||||
annotations:
|
||||
title: List all orders
|
||||
read_only_hint: true
|
||||
idempotent_hint: true
|
||||
destructive_hint: false
|
||||
open_world_hint: false
|
||||
acl:
|
||||
allow:
|
||||
- admin
|
||||
- read_only
|
||||
- product_manager
|
||||
- customer
|
||||
- support
|
||||
method: GET
|
||||
scheme: http
|
||||
host: ${REST_HOSTNAME}
|
||||
path: /sales/v1/orders/
|
||||
- name: get-order
|
||||
description: Retrieves a single order by order number.
|
||||
annotations:
|
||||
title: Get an order
|
||||
read_only_hint: true
|
||||
idempotent_hint: true
|
||||
destructive_hint: false
|
||||
open_world_hint: false
|
||||
acl:
|
||||
allow:
|
||||
- admin
|
||||
- read_only
|
||||
- product_manager
|
||||
- customer
|
||||
- support
|
||||
method: GET
|
||||
scheme: http
|
||||
host: ${REST_HOSTNAME}
|
||||
path: /sales/v1/orders/{ordernumber}/
|
||||
parameters:
|
||||
- name: ordernumber
|
||||
in: path
|
||||
required: true
|
||||
description: The order's unique number.
|
||||
schema: {}
|
||||
- name: get-order-orderdetails
|
||||
description: Retrieves all line items for a specific order.
|
||||
annotations:
|
||||
title: Get order line items
|
||||
read_only_hint: true
|
||||
idempotent_hint: true
|
||||
destructive_hint: false
|
||||
open_world_hint: false
|
||||
acl:
|
||||
allow:
|
||||
- admin
|
||||
- read_only
|
||||
- product_manager
|
||||
- customer
|
||||
- support
|
||||
method: GET
|
||||
scheme: http
|
||||
host: ${REST_HOSTNAME}
|
||||
path: /sales/v1/orders/{ordernumber}/order-details/
|
||||
parameters:
|
||||
- name: ordernumber
|
||||
in: path
|
||||
required: true
|
||||
description: The order's unique number.
|
||||
schema: {}
|
||||
- name: create-order
|
||||
description: Creates a new order in the CRM.
|
||||
annotations:
|
||||
title: Create an order
|
||||
read_only_hint: false
|
||||
idempotent_hint: false
|
||||
destructive_hint: false
|
||||
open_world_hint: false
|
||||
# Verified against OrderPermission.check() (authentication/permissions.py):
|
||||
# admin always passes; customer passes if get_customer_number(user) is
|
||||
# not None; support passes unconditionally at this class-level check
|
||||
# (object-level restricts support to status-only on *existing* orders,
|
||||
# which doesn't apply to create — no object yet). read_only/
|
||||
# product_manager only pass for SAFE_METHODS, excluded here.
|
||||
acl:
|
||||
allow:
|
||||
- admin
|
||||
- customer
|
||||
- support
|
||||
method: POST
|
||||
scheme: http
|
||||
host: ${REST_HOSTNAME}
|
||||
path: /sales/v1/orders/
|
||||
request_body:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
ordernumber:
|
||||
type: integer
|
||||
orderdate:
|
||||
type: string
|
||||
requireddate:
|
||||
type: string
|
||||
shippeddate:
|
||||
type: string
|
||||
status:
|
||||
type: string
|
||||
comments:
|
||||
type: string
|
||||
customernumber:
|
||||
type: integer
|
||||
required:
|
||||
- ordernumber
|
||||
- orderdate
|
||||
- requireddate
|
||||
- status
|
||||
- customernumber
|
||||
- name: list-orderdetails
|
||||
description: Retrieves a paginated list of order line items in the classic-models CRM.
|
||||
annotations:
|
||||
title: List all order line items
|
||||
read_only_hint: true
|
||||
idempotent_hint: true
|
||||
destructive_hint: false
|
||||
open_world_hint: false
|
||||
acl:
|
||||
allow:
|
||||
- admin
|
||||
- read_only
|
||||
- product_manager
|
||||
- customer
|
||||
- support
|
||||
method: GET
|
||||
scheme: http
|
||||
host: ${REST_HOSTNAME}
|
||||
path: /sales/v1/orderdetails/
|
||||
- name: get-orderdetail
|
||||
description: Retrieves a single order line item by order number and product code.
|
||||
annotations:
|
||||
title: Get an order line item
|
||||
read_only_hint: true
|
||||
idempotent_hint: true
|
||||
destructive_hint: false
|
||||
open_world_hint: false
|
||||
acl:
|
||||
allow:
|
||||
- admin
|
||||
- read_only
|
||||
- product_manager
|
||||
- customer
|
||||
- support
|
||||
method: GET
|
||||
scheme: http
|
||||
host: ${REST_HOSTNAME}
|
||||
path: /sales/v1/orderdetails/{ordernumber}/{productcode}/
|
||||
parameters:
|
||||
- name: ordernumber
|
||||
in: path
|
||||
required: true
|
||||
description: The order's unique number.
|
||||
schema: {}
|
||||
- name: productcode
|
||||
in: path
|
||||
required: true
|
||||
description: The product's unique code.
|
||||
schema: {}
|
||||
- name: create-orderdetail
|
||||
description: Adds a new line item to an order.
|
||||
annotations:
|
||||
title: Create an order line item
|
||||
read_only_hint: false
|
||||
idempotent_hint: false
|
||||
destructive_hint: false
|
||||
open_world_hint: false
|
||||
# Verified against OrderScopedPermission.check() (Orderdetail's base
|
||||
# permission class) — same shape as create-order above: admin,
|
||||
# customer (if get_customer_number is not None), support (class-level
|
||||
# unconditional pass) allowed; read_only/product_manager excluded
|
||||
# (SAFE_METHODS only).
|
||||
acl:
|
||||
allow:
|
||||
- admin
|
||||
- customer
|
||||
- support
|
||||
method: POST
|
||||
scheme: http
|
||||
host: ${REST_HOSTNAME}
|
||||
path: /sales/v1/orderdetails/
|
||||
request_body:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
ordernumber:
|
||||
type: integer
|
||||
productcode:
|
||||
type: string
|
||||
quantityordered:
|
||||
type: integer
|
||||
priceeach:
|
||||
type: string
|
||||
orderlinenumber:
|
||||
type: integer
|
||||
required:
|
||||
- ordernumber
|
||||
- productcode
|
||||
- quantityordered
|
||||
- priceeach
|
||||
- orderlinenumber
|
||||
Reference in New Issue
Block a user