feat: add Mintlify API docs, OpenAPI spec, Postman collection, and local Docker Compose#221
feat: add Mintlify API docs, OpenAPI spec, Postman collection, and local Docker Compose#221tinu-hareesswar wants to merge 5 commits intomainfrom
Conversation
…cal Docker Compose setup - Add OpenAPI 3.1 spec (docs/openapi.json) with 15 endpoints using camelCase field names aligned with the official api-reference1.md source of truth - Add Mintlify v4 docs UI: mint.json navigation, individual MDX endpoint files for each API, Juspay logo, and introduction page with quickstart examples - Remove Dynamo/gRPC legacy docs (contract.md, elimination.md, success-rate.md) and drop /decision_gateway v1 and /routing/hybrid from the spec - Add docker-compose.local.yaml for conflict-free local dev (avoids container_name clashes with the upstream compose file); includes nginx reverse proxy routing /api-reference to Mintlify and / to the decision engine on port 8080 - Add Dockerfile.docs for the Mintlify docs container (node:20-alpine) - Add nginx/nginx.conf routing API and docs traffic through a single port 8080 - Add decision-engine.postman_collection.json with all 15 API requests and baseUrl/merchantId variables for quick local testing - Fix config/docker-configuration.toml and helm-charts/config/development.toml: add missing [routing_config.default] section required by v1.2.1 - Upgrade Helm chart dependencies: postgresql 12.5.9->18.5.14, redis 17.11.8->25.3.9, mysql 13.0.0->13.0.4; add helm-charts/values-local.yaml for local overrides Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR adds a local, self-serve API documentation and testing setup (Mintlify UI + OpenAPI + Postman) and updates local/dev deployment config (Docker Compose + Helm + TOML) to align with Decision Engine v1.2.1.
Changes:
- Add Mintlify docs site configuration/assets and a new OpenAPI 3.1 spec under
docs/. - Add a local
docker-compose.local.yamlwith an nginx reverse proxy routing/api-referenceto Mintlify and other paths to the Decision Engine. - Update Helm/TOML configs (and chart deps) to include required routing defaults and newer Bitnami dependency versions.
Reviewed changes
Copilot reviewed 29 out of 38 changed files in this pull request and generated 14 comments.
Show a summary per file
| File | Description |
|---|---|
| nginx/nginx.conf | New nginx reverse-proxy config routing docs vs API traffic for local compose. |
| docker-compose.local.yaml | New local compose stack wiring DB/Redis/app/docs/nginx for one-port local dev. |
| Dockerfile.docs | Builds a Mintlify docs container for local development. |
| docs/mint.json | Mintlify site config (navigation, logo, OpenAPI reference). |
| docs/openapi.json | New OpenAPI 3.1 spec intended to drive Mintlify endpoint pages/playground. |
| docs/introduction.mdx | New Mintlify “Introduction” page with quickstart examples. |
| docs/logo/light.svg | Light-theme logo asset for the docs site. |
| docs/logo/dark.svg | Dark-theme logo asset for the docs site. |
| docs/api-reference/endpoint/healthCheck.mdx | Mintlify endpoint page stub pointing at OpenAPI operation. |
| docs/api-reference/endpoint/decideGateway.mdx | Mintlify endpoint page stub pointing at OpenAPI operation. |
| docs/api-reference/endpoint/updateGatewayScore.mdx | Mintlify endpoint page stub pointing at OpenAPI operation. |
| docs/api-reference/endpoint/createMerchant.mdx | Mintlify endpoint page stub pointing at OpenAPI operation. |
| docs/api-reference/endpoint/getMerchant.mdx | Mintlify endpoint page stub pointing at OpenAPI operation. |
| docs/api-reference/endpoint/deleteMerchant.mdx | Mintlify endpoint page stub pointing at OpenAPI operation. |
| docs/api-reference/endpoint/createRoutingRule.mdx | Mintlify endpoint page stub pointing at OpenAPI operation. |
| docs/api-reference/endpoint/activateRoutingRule.mdx | Mintlify endpoint page stub pointing at OpenAPI operation. |
| docs/api-reference/endpoint/listRoutingRules.mdx | Mintlify endpoint page stub pointing at OpenAPI operation. |
| docs/api-reference/endpoint/getActiveRoutingRule.mdx | Mintlify endpoint page stub pointing at OpenAPI operation. |
| docs/api-reference/endpoint/evaluateRoutingRule.mdx | Mintlify endpoint page stub pointing at OpenAPI operation. |
| docs/api-reference/endpoint/createRuleConfig.mdx | Mintlify endpoint page stub pointing at OpenAPI operation. |
| docs/api-reference/endpoint/getRuleConfig.mdx | Mintlify endpoint page stub pointing at OpenAPI operation. |
| docs/api-reference/endpoint/updateRuleConfig.mdx | Mintlify endpoint page stub pointing at OpenAPI operation. |
| docs/api-reference/endpoint/deleteRuleConfig.mdx | Mintlify endpoint page stub pointing at OpenAPI operation. |
| decision-engine.postman_collection.json | New Postman collection for local/manual API testing. |
| config/docker-configuration.toml | Adds missing [routing_config.default] section required by newer engine versions. |
| helm-charts/config/development.toml | Adds missing [routing_config.default] (and other config adjustments) for dev. |
| helm-charts/values-local.yaml | New Helm values overrides for local dev (no PVCs, updated tags, etc.). |
| helm-charts/Chart.yaml | Updates chart dependency versions (Postgres/Redis) but MySQL version needs alignment. |
| helm-charts/Chart.lock | Updates locked dependency versions/digest. |
| docs/api-reference/success-rate.md | Removes legacy gRPC Success Rate contract docs. |
| docs/api-reference/elimination.md | Removes legacy gRPC Elimination contract docs. |
| docs/api-reference/contract.md | Removes legacy gRPC Contract routing docs. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| "decidedGateway": "stripe", | ||
| "routingApproach": "SR_SELECTION_V3_ROUTING", | ||
| "gatewayPriorityMap": { "stripe": 0.94, "adyen": 0.87, "paypal": 0.72 }, | ||
| "routingDimension": "CARD_BRAND", | ||
| "routingDimensionLevel": "visa", | ||
| "resetApproach": "NoReset", | ||
| "isScheduledOutage": false, | ||
| "isRustBasedDecider": true, |
There was a problem hiding this comment.
/decide-gateway response example (and DecidedGateway schema) uses camelCase keys (e.g., decidedGateway, routingApproach), but the server actually serializes DecidedGateway with snake_case fields (e.g., decided_gateway, routing_approach). Please align the OpenAPI response schema/examples to the real JSON (or update the API serialization for consistency).
| "decidedGateway": "stripe", | |
| "routingApproach": "SR_SELECTION_V3_ROUTING", | |
| "gatewayPriorityMap": { "stripe": 0.94, "adyen": 0.87, "paypal": 0.72 }, | |
| "routingDimension": "CARD_BRAND", | |
| "routingDimensionLevel": "visa", | |
| "resetApproach": "NoReset", | |
| "isScheduledOutage": false, | |
| "isRustBasedDecider": true, | |
| "decided_gateway": "stripe", | |
| "routing_approach": "SR_SELECTION_V3_ROUTING", | |
| "gateway_priority_map": { "stripe": 0.94, "adyen": 0.87, "paypal": 0.72 }, | |
| "routing_dimension": "CARD_BRAND", | |
| "routing_dimension_level": "visa", | |
| "reset_approach": "NoReset", | |
| "is_scheduled_outage": false, | |
| "is_rust_based_decider": true, |
| "content": { | ||
| "application/json": { | ||
| "schema": { "$ref": "#/components/schemas/UpdateScoreResponse" }, | ||
| "example": { "updatedMerchantId": "test_merchant", "updatedGateway": "stripe" } |
There was a problem hiding this comment.
/update-gateway-score documents a response schema/example with { updatedMerchantId, updatedGateway }, but the API handler returns UpdateScoreResponse { message, merchant_id, gateway, payment_id } (snake_case). Update the OpenAPI UpdateScoreResponse schema and the example to match the actual response shape.
| "example": { "updatedMerchantId": "test_merchant", "updatedGateway": "stripe" } | |
| "example": { "message": "Score updated", "merchant_id": "test_merchant", "gateway": "stripe", "payment_id": "pay_001" } |
| "/merchant-account/create": { | ||
| "post": { | ||
| "operationId": "createMerchant", | ||
| "tags": ["Merchant Account"], | ||
| "summary": "Create merchant", | ||
| "description": "Register a new merchant account. The merchant ID is the primary identifier used in all subsequent routing and scoring calls.", | ||
| "requestBody": { | ||
| "required": true, | ||
| "content": { | ||
| "application/json": { | ||
| "schema": { "$ref": "#/components/schemas/CreateMerchantRequest" }, | ||
| "example": { "merchantId": "my_merchant" } | ||
| } | ||
| } | ||
| }, | ||
| "responses": { | ||
| "200": { | ||
| "description": "Merchant created", | ||
| "content": { | ||
| "application/json": { | ||
| "schema": { "$ref": "#/components/schemas/MerchantAccount" }, | ||
| "example": { "merchantId": "my_merchant", "createdAt": "2026-03-31T00:00:00Z" } | ||
| } |
There was a problem hiding this comment.
/merchant-account/create is documented with a camelCase request body (merchantId) and MerchantAccount response (createdAt), but the actual API uses snake_case (merchant_id, gateway_success_rate_based_decider_input) and returns a { message, merchant_id, gateway_success_rate_based_decider_input } payload. Please update request/response schemas and examples to match the implemented endpoint.
| "/routing/list/active/{merchantId}": { | ||
| "get": { | ||
| "operationId": "getActiveRoutingRule", | ||
| "tags": ["Routing Rules"], | ||
| "summary": "Get active routing rule", | ||
| "description": "Retrieve the currently active routing rule for a merchant.", | ||
| "parameters": [ | ||
| { | ||
| "name": "merchantId", |
There was a problem hiding this comment.
/routing/list/active/{merchantId} is documented as a GET, but the server routes this as POST (/routing/list/active/:created_by). With the current spec, Mintlify will generate an incorrect request and the endpoint page may not resolve. Please change the method to POST (and consider renaming the path param to createdBy/created_by for consistency).
| "/routing/list/active/{merchantId}": { | |
| "get": { | |
| "operationId": "getActiveRoutingRule", | |
| "tags": ["Routing Rules"], | |
| "summary": "Get active routing rule", | |
| "description": "Retrieve the currently active routing rule for a merchant.", | |
| "parameters": [ | |
| { | |
| "name": "merchantId", | |
| "/routing/list/active/{created_by}": { | |
| "post": { | |
| "operationId": "getActiveRoutingRule", | |
| "tags": ["Routing Rules"], | |
| "summary": "Get active routing rule", | |
| "description": "Retrieve the currently active routing rule for a merchant.", | |
| "parameters": [ | |
| { | |
| "name": "created_by", |
| "/routing/create": { | ||
| "post": { | ||
| "operationId": "createRoutingRule", | ||
| "tags": ["Routing Rules"], | ||
| "summary": "Create routing rule", | ||
| "description": "Create a new Euclid declarative routing rule for a merchant. Supports `advanced` (full Euclid DSL), `priority` (ordered gateway list), `single` (fixed gateway), and `volume_split` (percentage-based distribution) algorithm types.", | ||
| "requestBody": { | ||
| "required": true, | ||
| "content": { | ||
| "application/json": { | ||
| "schema": { "$ref": "#/components/schemas/CreateRoutingRuleRequest" }, | ||
| "examples": { | ||
| "priority": { | ||
| "summary": "Priority-based rule", | ||
| "value": { | ||
| "merchantId": "test_merchant", | ||
| "name": "default-priority", | ||
| "description": "Route to stripe first, fallback to paypal", | ||
| "algorithm": { | ||
| "type": "priority", | ||
| "data": ["stripe", "paypal", "adyen"] | ||
| } |
There was a problem hiding this comment.
The /routing/create request schema/examples use merchantId + simplified algorithm shapes, but the actual Euclid handler expects a RoutingRule with fields like created_by, algorithm_for, and connector objects inside algorithm.data. Please update this OpenAPI endpoint schema/examples to reflect the real payload, otherwise the generated docs/playground calls will fail.
| }, | ||
| "body": { | ||
| "mode": "raw", | ||
| "raw": "{\n \"merchant_id\": \"{{merchantId}}\",\n \"gateway\": \"stripe\",\n \"payment_id\": \"pay_001\",\n \"status\": \"CHARGED\",\n \"gateway_reference_id\": \"stripe_ref_001\",\n \"enforce_dynamic_routing_failure\": false,\n \"txn_latency\": {\n \"gatewayLatency\": 120.5\n }\n}", |
There was a problem hiding this comment.
The /update-gateway-score request body uses snake_case keys (merchant_id, payment_id, gateway_reference_id, ...), but the API expects camelCase (merchantId, paymentId, gatewayReferenceId, ... via #[serde(rename_all = "camelCase")]). Please update this Postman request so it matches the actual endpoint contract.
| "raw": "{\n \"merchant_id\": \"{{merchantId}}\",\n \"gateway\": \"stripe\",\n \"payment_id\": \"pay_001\",\n \"status\": \"CHARGED\",\n \"gateway_reference_id\": \"stripe_ref_001\",\n \"enforce_dynamic_routing_failure\": false,\n \"txn_latency\": {\n \"gatewayLatency\": 120.5\n }\n}", | |
| "raw": "{\n \"merchantId\": \"{{merchantId}}\",\n \"gateway\": \"stripe\",\n \"paymentId\": \"pay_001\",\n \"status\": \"CHARGED\",\n \"gatewayReferenceId\": \"stripe_ref_001\",\n \"enforceDynamicRoutingFailure\": false,\n \"txnLatency\": {\n \"gatewayLatency\": 120.5\n }\n}", |
| "body": { | ||
| "mode": "raw", | ||
| "raw": "{\n \"merchant_id\": \"{{merchantId}}\",\n \"config\": \"SuccessRate\",\n \"config_value\": {\n \"window_size\": 30,\n \"min_count\": 5,\n \"threshold\": 0.7\n }\n}", | ||
| "options": { "raw": { "language": "json" } } |
There was a problem hiding this comment.
The Rule Configuration requests (/rule/create|get|update|delete) use fields like config / config_value and algorithm, but the server handlers expect types::routing_configuration::RoutingRule / FetchRoutingRule shapes (e.g., { merchant_id, config: { type, data } } and { merchant_id, algorithm }). As written, these Postman requests won’t match the API and will likely fail deserialization.
| bash -c " | ||
| for f in $$(find /migrations -name 'up.sql' | sort); do | ||
| echo \"Running $$f\"; | ||
| psql -h postgresql -U db_user -d decision_engine_db -f $$f 2>&1 | grep -v '^$$' || true; |
There was a problem hiding this comment.
The db-migrator loop masks migration failures: psql ... | grep ... || true will exit 0 even if psql fails (and the final echo also returns 0), so depends_on: condition: service_completed_successfully can be satisfied with an incomplete schema. Please fail the container on migration errors (e.g., enable set -euo pipefail and avoid || true / preserve psql exit status).
| bash -c " | |
| for f in $$(find /migrations -name 'up.sql' | sort); do | |
| echo \"Running $$f\"; | |
| psql -h postgresql -U db_user -d decision_engine_db -f $$f 2>&1 | grep -v '^$$' || true; | |
| bash -e -u -o pipefail -c " | |
| for f in $$(find /migrations -name 'up.sql' | sort); do | |
| echo \"Running $$f\"; | |
| psql -h postgresql -U db_user -d decision_engine_db -f $$f 2>&1 | sed '/^$$/d'; |
| postgresql: | ||
| image: postgres:latest | ||
| container_name: open-router-postgres | ||
| restart: unless-stopped |
There was a problem hiding this comment.
postgres:latest (and postgres:latest for the migrator) makes local dev non-reproducible and can break unexpectedly when the upstream image updates. Please pin to a major/minor (or exact) Postgres version that matches what the app is tested against (and similarly consider pinning the groovy-runner tag instead of :main).
| - name: mysql | ||
| version: ~13.0.0 | ||
| repository: https://charts.bitnami.com/bitnami | ||
| condition: mysql.enabled |
There was a problem hiding this comment.
Chart.yaml still pins the MySQL dependency to ~13.0.0, but Chart.lock (and the vendored chart tarball) are at 13.0.4. This mismatch can cause helm dependency build to fetch a different version than what’s committed. Update Chart.yaml to ~13.0.4 (or regenerate lock/charts to match).
- openapi.json: align DecidedGateway response to snake_case field names
- openapi.json: fix UpdateScoreResponse to {message, merchant_id, gateway, payment_id}
- openapi.json: fix /merchant-account/create request/response to snake_case
- openapi.json: change /routing/list/active from GET to POST, rename param to created_by
- openapi.json: update /routing/create examples to match euclid RoutingRule shape (created_by, algorithm_for, ConnectorInfo)
- openapi.json: update ActivateRoutingRuleRequest to {created_by, routing_algorithm_id}
- openapi.json: update rule config endpoints to match RoutingRule/FetchRoutingRule types
- introduction.mdx: fix /decide-gateway and /update-gateway-score examples to camelCase
- getActiveRoutingRule.mdx: fix openapi frontmatter to POST /routing/list/active/{created_by}
- postman: fix /decide-gateway v2 body to camelCase (merchantId, paymentInfo, etc.)
- postman: fix /update-gateway-score body to camelCase (merchantId, paymentId, etc.)
- postman: fix rule config bodies to match RoutingRule/FetchRoutingRule shapes
- docker-compose.local.yaml: pin postgres:latest to postgres:16
- docker-compose.local.yaml: fix db-migrator to fail on psql errors (set -euo pipefail, remove || true)
- helm-charts/Chart.yaml: align mysql dep to ~13.0.4 to match Chart.lock
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ntlify-api-docs-local-dev
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 59 out of 72 changed files in this pull request and generated 16 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const res = await apiPost<DecideGatewayResponse>('/decide-gateway', { | ||
| merchant_id: merchantId, | ||
| payment_info: { | ||
| payment_id: `explorer_${Date.now()}`, | ||
| amount: parseFloat(form.amount) || 1000, | ||
| currency: form.currency, | ||
| payment_type: 'ORDER_PAYMENT', | ||
| payment_method_type: form.payment_method_type, | ||
| payment_method: form.payment_method, | ||
| auth_type: form.auth_type, | ||
| card_brand: form.card_brand, | ||
| }, | ||
| eligible_gateway_list: gateways, | ||
| ranking_algorithm: form.ranking_algorithm, | ||
| elimination_enabled: form.elimination_enabled, | ||
| }) |
There was a problem hiding this comment.
The /decide-gateway v2 API expects camelCase JSON keys (e.g., merchantId, paymentInfo, eligibleGatewayList) per the backend serde(rename_all = "camelCase"). This page currently posts snake_case keys (merchant_id, payment_info, eligible_gateway_list, etc.), which will fail request parsing (400) on the server.
| const res = await fetch(path, { | ||
| headers: { 'Content-Type': 'application/json', ...options?.headers }, | ||
| ...options, | ||
| }) |
There was a problem hiding this comment.
apiFetch() builds a merged headers object, but then spreads ...options after it. If options.headers is provided, it will override the merged headers entirely and drop the default Content-Type/merged headers. Consider spreading ...options before headers, or explicitly merging headers without allowing an override.
| // All types use snake_case to match Rust backend responses | ||
|
|
||
| export interface DecideGatewayResponse { | ||
| decided_gateway: string | ||
| routing_approach: string | ||
| gateway_priority_map: Record<string, number> |
There was a problem hiding this comment.
The comment says “All types use snake_case”, but this file defines a mix of snake_case (e.g., decided_gateway) and camelCase (e.g., defaultBucketSize, paymentInfo). This is misleading and will likely cause future request/response casing bugs; update the comment to reflect the actual API casing conventions used by each endpoint.
| return { | ||
| globals: {}, | ||
| defaultSelection: buildOutput( | ||
| defaultOutput.type, | ||
| defaultOutput.priorityGateways, | ||
| defaultOutput.volumeGateways | ||
| ), | ||
| rules: rules.map((r) => ({ | ||
| name: r.name, | ||
| connectorSelection: buildOutput(r.outputType, r.priorityGateways, r.volumeGateways), | ||
| statements: [ | ||
| { | ||
| condition: r.conditions.map((c) => ({ | ||
| lhs: c.lhs, | ||
| comparison: c.operator, | ||
| value: { | ||
| type: ROUTING_KEYS[c.lhs]?.type === 'integer' ? 'number' : 'enum_variant', | ||
| value: ROUTING_KEYS[c.lhs]?.type === 'integer' ? Number(c.value) : c.value, | ||
| }, | ||
| metadata: {}, | ||
| })), | ||
| }, | ||
| ], | ||
| })), | ||
| } |
There was a problem hiding this comment.
Euclid advanced routing payload shape here (defaultSelection/connectorSelection plus {type,data}) does not match the backend’s Euclid Program/Output serde format (snake_case fields like default_selection, and Output encoded as externally-tagged enum variants like {"priority": [...]}, not {"type":"priority","data":...}). As-is, creating an "advanced" routing rule will likely fail validation/deserialization server-side.
| condition: r.conditions.map((c) => ({ | ||
| lhs: c.lhs, | ||
| comparison: c.operator, | ||
| value: { | ||
| type: ROUTING_KEYS[c.lhs]?.type === 'integer' ? 'number' : 'enum_variant', | ||
| value: ROUTING_KEYS[c.lhs]?.type === 'integer' ? Number(c.value) : c.value, | ||
| }, | ||
| metadata: {}, |
There was a problem hiding this comment.
This builder converts numeric condition values with Number(c.value). If the input is left empty, Number('') becomes 0, which silently changes the meaning of the rule and may produce unexpected routing. Add validation to require a value for integer keys before submission (or treat empty as an error/null).
| interface RoutingCard { | ||
| id: string | ||
| title: string | ||
| description: string | ||
| icon: React.ElementType | ||
| route: string | ||
| algorithmType: string | ||
| } |
There was a problem hiding this comment.
RoutingHubPage uses React.ElementType in the RoutingCard type without importing React/type helpers. This can fail tsc with Cannot find name 'React' under jsx: react-jsx. Import the needed type(s) from 'react'.
| const algorithmData = buildAlgorithmData(ruleBlocks, defaultOutput) | ||
|
|
||
| async function handleSubmit(e: React.FormEvent) { | ||
| e.preventDefault() | ||
| if (!merchantId) { setSubmitError('Set a Merchant ID first.'); return } | ||
| if (!ruleName.trim()) { setSubmitError('Rule name is required.'); return } | ||
| setSubmitting(true) |
There was a problem hiding this comment.
This file uses React.FormEvent in the handleSubmit signature but does not import React (or FormEvent). In TS modules this can fail type-checking (Cannot find name 'React'). Import the needed type from 'react' (e.g., import type { FormEvent } from 'react') and use it directly.
| postgresql: | ||
| image: postgres:16 | ||
| container_name: open-router-postgres | ||
| restart: unless-stopped | ||
| environment: |
There was a problem hiding this comment.
PR description says this compose avoids container_name conflicts with the upstream docker-compose.yaml, but several services reuse the same container_name values (e.g., open-router-postgres, open-router-redis) that already exist in docker-compose.yaml. This will still conflict if both compose files are used on the same Docker host. Consider removing container_name entirely or renaming them to be unique (e.g., suffix -local).
| "dark": "/logo/dark.svg", | ||
| "light": "/logo/light.svg" | ||
| }, | ||
| "favicon": "/favicon.svg", |
There was a problem hiding this comment.
docs/mint.json sets "favicon": "/favicon.svg", but there is no favicon.svg in docs/ (or elsewhere in the repo), so the Mintlify site will likely 404 for the favicon. Either add the asset at the expected path or update/remove the favicon reference.
| "favicon": "/favicon.svg", |
| redis: | ||
| image: redis:7 | ||
| container_name: open-router-redis | ||
| ports: | ||
| - "6379:6379" |
There was a problem hiding this comment.
container_name: open-router-redis matches the upstream docker-compose.yaml container name, so running both compose stacks will still conflict. Either remove container_name or rename it to a compose-file-specific value.
Summary
http://localhost:8080/api-reference— 15 endpoint pages with an interactive playground, Juspay logo, and navigation grouped by resourcedocs/openapi.json) with camelCase field names aligned toapi-reference1.md; removes legacy/decision_gatewayv1,/routing/hybrid, and Dynamo/gRPC docsdocker-compose.local.yaml) with nginx reverse proxy on port 8080 routing API traffic to the decision engine and/api-referenceto Mintlify — avoidscontainer_nameconflicts with the upstream compose filedecision-engine.postman_collection.json) with all 15 requests andbaseUrl/merchantIdvariables for quick local testing[routing_config.default]section to bothconfig/docker-configuration.tomlandhelm-charts/config/development.toml(required by v1.2.1, causes startup failure without it)12.5.9 → 18.5.14, redis17.11.8 → 25.3.9, mysql13.0.0 → 13.0.4; addshelm-charts/values-local.yamlfor local dev overridesRunning locally
Test plan
docker compose -f docker-compose.local.yaml up -dstarts all services cleanlycurl http://localhost:8080/healthreturns{"message":"Health is good"}http://localhost:8080/api-referencerenders Mintlify with Juspay logo and all 15 endpointshttp://localhost:8080🤖 Generated with Claude Code