{
  "$schema": "https://dashilee.com/schemas/service-engine.catalog.schema.json",
  "schemaVersion": "dashilee-api-catalog@1",
  "id": "dashilee-service-engine",
  "title": "大势历服务引擎 API",
  "summary": "一个无状态执行入口，统一提供四柱个人盘、四柱合盘、紫微个人盘和紫微双人合参。",
  "audiences": [
    "web",
    "ios",
    "android",
    "desktop",
    "game-backend",
    "ai-agent"
  ],
  "contract": {
    "format": "OpenAPI 3.1",
    "yaml": "/docs/api/openapi.yaml",
    "json": "/docs/api/openapi.json",
    "humanDocs": "/api-docs.html",
    "llmIndex": "/llms.txt",
    "llmFullContext": "/llms-full.txt",
    "catalogSchema": "/docs/api/service-engine.catalog.schema.json"
  },
  "transport": {
    "protocol": "HTTPS",
    "mediaType": "application/json",
    "errorMediaType": "application/problem+json",
    "characterEncoding": "UTF-8",
    "productionAuthentication": "Authorization: Bearer <token>",
    "localAuthentication": "本地验收服务当前不强制令牌；生产部署必须在网关启用 Bearer 或 API Key。",
    "requestIdHeader": "X-Request-Id",
    "idempotency": "统一无状态执行入口不要求 Idempotency-Key；持久化资源创建接口要求 UUID 格式的 Idempotency-Key。"
  },
  "integrationFlow": [
    {
      "step": 1,
      "name": "discover",
      "description": "启动时读取能力、语言、版本与限制，不在前端硬编码能力。",
      "method": "GET",
      "path": "/v1/engine/capabilities",
      "operationId": "getEngineCapabilities"
    },
    {
      "step": 2,
      "name": "resolve-place",
      "description": "通过行政区或全球城市搜索取得版本化 placeId。",
      "method": "GET",
      "path": "/v1/places/search",
      "operationId": "searchPlaces",
      "optionalAlternatives": [
        "/v1/places/china-divisions",
        "/v1/places/market-cities"
      ]
    },
    {
      "step": 3,
      "name": "confirm-time-basis",
      "description": "靠近时柱或换日边界时比较民用时与真太阳时，并向用户展示确认。",
      "method": "POST",
      "path": "/v1/time/calibrations",
      "operationId": "calculateTimeCalibration",
      "optional": true
    },
    {
      "step": 4,
      "name": "execute",
      "description": "提交 feature、input 与 options，直接取得 facts、report 或 full 响应。",
      "method": "POST",
      "path": "/v1/engine/executions",
      "operationId": "executeEngine"
    }
  ],
  "responseViews": {
    "facts": "返回 subjects、charts、analysis 与 claims，不生成报告章节。",
    "report": "返回 subjects 与 report，适合只渲染报告的客户端。",
    "full": "同时返回事实、claims 与报告，适合开发、审核和游戏内容映射。"
  },
  "reportModes": {
    "template": "默认模式；确定性模板，无需 LLM。",
    "llm_enhanced": "可选受约束白话增强；模型不能修改排盘事实或 claims，失败时安全回退完整模板。"
  },
  "sharedInput": {
    "birthDataRequired": [
      "gender",
      "localDateTime",
      "timePrecision",
      "placeId",
      "calendarPolicy"
    ],
    "gender": [
      "male",
      "female"
    ],
    "calendar": [
      "gregorian",
      "lunar"
    ],
    "timeBasis": [
      "civil",
      "true_solar"
    ],
    "timePrecision": [
      "minute",
      "double_hour",
      "range",
      "unknown"
    ],
    "calendarPolicy": {
      "yearBoundary": "li_chun",
      "monthBoundary": "jie",
      "dayBoundary": "zi_early_23"
    },
    "supportedDateRange": [
      1800,
      2200
    ],
    "relationshipType": [
      "married",
      "partners",
      "dating",
      "other"
    ],
    "compatibilityConsent": "合盘与合参必须提交 input.consent.confirmed=true。"
  },
  "features": [
    {
      "id": "bazi.personal",
      "label": "四柱个人命盘",
      "method": "bazi",
      "subjectCount": 1,
      "description": "直接计算一人的四柱事实、规则 claims 与个人报告。",
      "defaults": {
        "timeBasis": "true_solar",
        "contentLocale": "zh-Hans",
        "formatLocale": "zh-Hans-CN",
        "interpretationProfileId": "ziping-zh-Hans@1"
      },
      "requestExample": {
        "feature": "bazi.personal",
        "input": {
          "subject": {
            "birthData": {
              "displayName": "示例用户",
              "gender": "male",
              "localDateTime": {
                "date": {
                  "calendar": "gregorian",
                  "year": 1990,
                  "month": 5,
                  "day": 12,
                  "isLeapMonth": false
                },
                "time": "14:30"
              },
              "timePrecision": "minute",
              "placeId": "local:enshi-cn",
              "calendarPolicy": {
                "yearBoundary": "li_chun",
                "monthBoundary": "jie",
                "dayBoundary": "zi_early_23"
              }
            },
            "timeBasis": "true_solar"
          }
        },
        "options": {
          "responseView": "full",
          "reportMode": "template",
          "contentLocale": "zh-Hans",
          "formatLocale": "zh-Hans-CN",
          "interpretationProfileId": "ziping-zh-Hans@1",
          "reportReferenceAt": "2026-09-01T12:00:00+08:00"
        }
      }
    },
    {
      "id": "bazi.compatibility",
      "label": "四柱夫妻／情侣合盘",
      "method": "bazi_compatibility",
      "subjectCount": 2,
      "requiresConsent": true,
      "description": "直接提交双方资料生成合盘，不要求预先生成个人报告。",
      "defaults": {
        "timeBasis": "true_solar",
        "contentLocale": "zh-Hans",
        "formatLocale": "zh-Hans-CN",
        "interpretationProfileId": "ziping-zh-Hans@1"
      },
      "requestExample": {
        "feature": "bazi.compatibility",
        "input": {
          "memberA": {
            "birthData": {
              "displayName": "成员甲",
              "gender": "male",
              "localDateTime": {
                "date": {
                  "calendar": "gregorian",
                  "year": 1990,
                  "month": 5,
                  "day": 12,
                  "isLeapMonth": false
                },
                "time": "14:30"
              },
              "timePrecision": "minute",
              "placeId": "local:enshi-cn",
              "calendarPolicy": {
                "yearBoundary": "li_chun",
                "monthBoundary": "jie",
                "dayBoundary": "zi_early_23"
              }
            },
            "timeBasis": "true_solar"
          },
          "memberB": {
            "birthData": {
              "displayName": "成员乙",
              "gender": "female",
              "localDateTime": {
                "date": {
                  "calendar": "gregorian",
                  "year": 1992,
                  "month": 8,
                  "day": 24,
                  "isLeapMonth": false
                },
                "time": "09:15"
              },
              "timePrecision": "minute",
              "placeId": "local:jingzhou-cn",
              "calendarPolicy": {
                "yearBoundary": "li_chun",
                "monthBoundary": "jie",
                "dayBoundary": "zi_early_23"
              }
            },
            "timeBasis": "true_solar"
          },
          "relationshipType": "partners",
          "consent": {
            "confirmed": true,
            "basis": "both_people_present"
          },
          "referenceYear": 2026
        },
        "options": {
          "responseView": "full",
          "reportMode": "template",
          "contentLocale": "zh-Hans",
          "formatLocale": "zh-Hans-CN",
          "interpretationProfileId": "ziping-zh-Hans@1",
          "reportReferenceAt": "2026-09-01T12:00:00+08:00"
        }
      }
    },
    {
      "id": "ziwei.personal",
      "label": "紫微斗数个人盘",
      "method": "ziwei",
      "subjectCount": 1,
      "description": "直接计算一人的十二宫、星曜、生年四化、结构 claims 与繁体报告。出生地不限台湾。",
      "defaults": {
        "timeBasis": "civil",
        "contentLocale": "zh-Hant",
        "formatLocale": "zh-Hant-TW",
        "interpretationProfileId": "ziwei-tw-sanhe@1"
      },
      "requestExample": {
        "feature": "ziwei.personal",
        "input": {
          "subject": {
            "birthData": {
              "displayName": "示例命主",
              "gender": "female",
              "localDateTime": {
                "date": {
                  "calendar": "gregorian",
                  "year": 1991,
                  "month": 3,
                  "day": 18,
                  "isLeapMonth": false
                },
                "time": "10:00"
              },
              "timePrecision": "minute",
              "placeId": "local:taipei-tw",
              "calendarPolicy": {
                "yearBoundary": "li_chun",
                "monthBoundary": "jie",
                "dayBoundary": "zi_early_23"
              }
            },
            "timeBasis": "civil",
            "calculationProfileId": "ziwei-tw-sanhe@1"
          }
        },
        "options": {
          "responseView": "full",
          "reportMode": "template",
          "contentLocale": "zh-Hant",
          "formatLocale": "zh-Hant-TW",
          "interpretationProfileId": "ziwei-tw-sanhe@1",
          "reportReferenceAt": "2026-09-01T12:00:00+08:00"
        }
      }
    },
    {
      "id": "ziwei.compatibility",
      "label": "紫微夫妻／情侣双人合参",
      "method": "ziwei_compatibility",
      "subjectCount": 2,
      "requiresConsent": true,
      "description": "直接建立双方紫微命盘并合参，不要求个人盘或个人报告前置。",
      "defaults": {
        "timeBasis": "civil",
        "contentLocale": "zh-Hant",
        "formatLocale": "zh-Hant-TW",
        "interpretationProfileId": "ziwei-tw-compat-sanhe@1"
      },
      "requestExample": {
        "feature": "ziwei.compatibility",
        "input": {
          "memberA": {
            "birthData": {
              "displayName": "成員甲",
              "gender": "male",
              "localDateTime": {
                "date": {
                  "calendar": "gregorian",
                  "year": 1988,
                  "month": 6,
                  "day": 6,
                  "isLeapMonth": false
                },
                "time": "08:20"
              },
              "timePrecision": "minute",
              "placeId": "local:taipei-tw",
              "calendarPolicy": {
                "yearBoundary": "li_chun",
                "monthBoundary": "jie",
                "dayBoundary": "zi_early_23"
              }
            },
            "timeBasis": "civil",
            "calculationProfileId": "ziwei-tw-sanhe@1"
          },
          "memberB": {
            "birthData": {
              "displayName": "成員乙",
              "gender": "female",
              "localDateTime": {
                "date": {
                  "calendar": "gregorian",
                  "year": 1990,
                  "month": 10,
                  "day": 20,
                  "isLeapMonth": false
                },
                "time": "19:40"
              },
              "timePrecision": "minute",
              "placeId": "tw:kaohsiung",
              "calendarPolicy": {
                "yearBoundary": "li_chun",
                "monthBoundary": "jie",
                "dayBoundary": "zi_early_23"
              }
            },
            "timeBasis": "civil",
            "calculationProfileId": "ziwei-tw-sanhe@1"
          },
          "relationshipType": "married",
          "consent": {
            "confirmed": true,
            "basis": "both_people_present"
          }
        },
        "options": {
          "responseView": "full",
          "reportMode": "template",
          "contentLocale": "zh-Hant",
          "formatLocale": "zh-Hant-TW",
          "interpretationProfileId": "ziwei-tw-compat-sanhe@1",
          "reportReferenceAt": "2026-09-01T12:00:00+08:00"
        }
      }
    }
  ],
  "responseEnvelope": {
    "service": "服务标识、服务版本与 API 版本。",
    "execution": "执行 ID、feature、视图、状态、输入哈希与生成时间。",
    "result.subjects": "一至两位主体的标准化资料摘要。",
    "result.charts": "facts/full 视图中的命盘结构事实。",
    "result.analysis": "合盘或合参的跨盘结构分析；个人盘为 null。",
    "result.claims": "带证据、限制、置信和规则 ID 的结论。",
    "result.report": "report/full 视图中的章节化报告。",
    "warnings": "边界、回退或数据质量提示。",
    "versions": "排盘、规则、模板和数据源版本。"
  },
  "stableErrorCodes": [
    {
      "code": "ENGINE_REQUEST_REQUIRED",
      "status": 422,
      "recovery": "提交 JSON 对象。"
    },
    {
      "code": "ENGINE_FEATURE_UNSUPPORTED",
      "status": 422,
      "recovery": "先读取 capabilities，并使用返回的 feature ID。"
    },
    {
      "code": "ENGINE_BIRTH_DATA_REQUIRED",
      "status": 422,
      "recovery": "补齐对应 subject/member 的 birthData。"
    },
    {
      "code": "PLACE_NOT_FOUND",
      "status": 404,
      "recovery": "重新调用地点接口取得有效 placeId。"
    },
    {
      "code": "CONSENT_REQUIRED",
      "status": 422,
      "recovery": "取得双方授权后提交 consent.confirmed=true。"
    },
    {
      "code": "INVALID_RESPONSE_VIEW",
      "status": 422,
      "recovery": "使用 facts、report 或 full。"
    },
    {
      "code": "ZIWEI_LOCALE_UNSUPPORTED",
      "status": 422,
      "recovery": "当前紫微报告使用 zh-Hant 与 zh-Hant-TW。"
    }
  ],
  "frontendRules": [
    "启动时缓存 capabilities，但每次发布后按版本重新读取。",
    "不要在前端复制历法、真太阳时、四柱或紫微算法。",
    "以 execution.inputHash 和 versions 作为缓存与回归标识，不使用生成时间判断事实是否一致。",
    "合盘和合参是独立功能；前端可直接提交两人资料，不应强制先生成个人报告。",
    "生产 Web 与游戏客户端不得内嵌长期 API 密钥，应通过自有后端网关调用。",
    "将 Problem.code 作为程序分支依据；title/detail 只用于展示或日志。",
    "传统文化报告不得替代医疗、法律、投资、心理或婚恋专业判断。"
  ],
  "sdk": {
    "javascript": {
      "package": "@dashilee/engine-client",
      "source": "/docs/sdk/engine-client.js",
      "methods": [
        "capabilities",
        "execute",
        "baziPersonal",
        "baziCompatibility",
        "ziweiPersonal",
        "ziweiCompatibility"
      ]
    },
    "unity": {
      "example": "/docs/sdk/DashileeEngineClient.cs",
      "security": "Unity 客户端仅调用游戏自有网关，不保存大势历生产密钥。"
    }
  },
  "release": {
    "platformVersion": "2.10.0",
    "serviceVersion": "dashilee-service-engine@1.1.0",
    "apiVersion": "1",
    "openapiVersion": "1.6.0"
  },
  "capabilitiesContract": {
    "transport": {
      "protocol": "https",
      "mediaType": "application/json",
      "contract": "OpenAPI 3.1"
    },
    "executionEndpoint": "/v1/engine/executions",
    "responseViews": [
      "facts",
      "report",
      "full"
    ],
    "stateModes": [
      "ephemeral"
    ],
    "deterministicCore": true,
    "llmRequired": false,
    "llm": {
      "role": "optional_constrained_report_rewrite",
      "fallback": "deterministic_template",
      "runtimeStatusEndpoint": "/v1/engine/capabilities"
    },
    "features": [
      {
        "id": "bazi.personal",
        "label": "四柱个人命盘",
        "subjectCount": 1,
        "contentLocales": [
          "zh-Hans",
          "zh-Hant",
          "ja",
          "ko"
        ],
        "calculationProfiles": [
          "core-default@1"
        ],
        "reportSections": {
          "zh-Hans": 17,
          "localizedCompact": 6
        }
      },
      {
        "id": "bazi.compatibility",
        "label": "四柱夫妻／情侣合盘",
        "subjectCount": 2,
        "contentLocales": [
          "zh-Hans",
          "zh-Hant",
          "ja",
          "ko"
        ],
        "calculationProfiles": [
          "core-default@1"
        ],
        "reportSections": {
          "zh-Hans": 16,
          "localizedCompact": 6
        },
        "requiresConsent": true
      },
      {
        "id": "ziwei.personal",
        "label": "台湾紫微斗数个人盘",
        "subjectCount": 1,
        "contentLocales": [
          "zh-Hant"
        ],
        "calculationProfiles": [
          "ziwei-tw-sanhe@1"
        ],
        "reportSections": {
          "zh-Hant": 18
        }
      },
      {
        "id": "ziwei.compatibility",
        "label": "台湾紫微斗数夫妻／情侣双人合参",
        "subjectCount": 2,
        "contentLocales": [
          "zh-Hant"
        ],
        "calculationProfiles": [
          "ziwei-tw-compat-sanhe@1"
        ],
        "reportSections": {
          "zh-Hant": 16
        },
        "requiresConsent": true
      }
    ],
    "limits": {
      "requestBodyBytes": 1048576,
      "supportedDateRange": [
        1800,
        2200
      ]
    }
  }
}
