# OpenAPI Design Guidelines

> Contract design, versioning, and documentation standards for Kingdee Enterprise APIs.

---

## Scope

Use this guide for REST/OpenAPI contracts exposed by Kingdee Enterprise projects or consumed by integration adapters. For implementation details, also read the platform-specific C# or Python guide.

---

## Contract Structure

Every published API document should include:

- API purpose and owning business domain
- Authentication and authorization requirements
- Path, method, tags, and operationId
- Request parameters and request body schema
- Response schema for success and known failures
- Error code table
- Pagination/filter/sort semantics for list endpoints
- Idempotency and retry behavior for write endpoints
- Examples for at least one success and one failure response

---

## Path and Naming Rules

| Concern | Rule |
| --- | --- |
| Resource names | Use stable nouns, not UI menu captions |
| Version | Prefer `/api/v1/...` unless the project already uses header versioning |
| Operation IDs | Use verb + resource, e.g. `createPayBill`, `listCustomers` |
| Field names | Use lower camelCase JSON fields unless existing project standard differs |
| IDs | Distinguish business numbers, platform IDs, and external IDs clearly |
| Booleans | Use positive names such as `enabled`, `submitted`, `hasMore` |

---

## Request Design

- Validate all required fields at the boundary.
- Whitelist filter and sort fields.
- Define max page size and default page size.
- Use explicit date/time timezone and precision.
- Avoid overloading one endpoint with many unrelated actions.
- Use idempotency keys for create/sync operations that callers may retry.

---

## Response Design

When the project has no existing envelope standard, use:

```json
{
  "success": true,
  "data": {},
  "message": ""
}
```

Failure response:

```json
{
  "success": false,
  "errorCode": "ENTERPRISE_VALIDATION_001",
  "message": "User-facing explanation",
  "details": []
}
```

Rules:

- Do not expose stack traces, SQL, internal class names, or secrets.
- Keep error codes stable; clients may branch on them.
- Preserve existing fields for backward compatibility.
- For partial batch success, return per-item status with stable item identifiers.

---

## Versioning

| Change | Compatibility | Required action |
| --- | --- | --- |
| Add optional request field | Compatible | Document default behavior |
| Add optional response field | Compatible | Add example if important |
| Add required request field | Breaking | New version or migration window |
| Rename/remove field | Breaking | New version |
| Change enum values | Breaking unless old values still accepted | Compatibility note |
| Change error code meaning | Breaking | New code or version |

---

## Error Codes

| Prefix | Meaning |
| --- | --- |
| `ENTERPRISE_VALIDATION_*` | Invalid request shape or field value |
| `ENTERPRISE_BIZ_*` | Business rule rejection |
| `ENTERPRISE_AUTH_*` | Authentication or permission failure |
| `ENTERPRISE_DATA_*` | Missing/inconsistent platform data |
| `ENTERPRISE_DEP_*` | External dependency failure |
| `ENTERPRISE_SYSTEM_*` | Unexpected server/platform failure |

---

## Documentation Checklist

- [ ] Schemas have required/optional fields marked correctly.
- [ ] Examples match the schema exactly.
- [ ] Pagination and sorting are documented.
- [ ] Error codes and HTTP statuses are documented.
- [ ] Compatibility impact is stated.
- [ ] Sensitive fields are excluded or masked.
- [ ] Implementation tests or contract tests cover success and failure examples.

---

## Minimal OpenAPI Example

For complete Enterprise integration flows, use the `kd-enterprise-openapi` skill snippets.

```yaml
openapi: 3.0.3
info:
  title: Kingdee Pay API
  version: 1.0.0
paths:
  /api/v1/pay-bills/{billNo}:
    get:
      operationId: getPayBill
      tags: [PayBill]
      parameters:
        - name: billNo
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Pay bill detail
          content:
            application/json:
              schema:
                type: object
                required: [success, data]
                properties:
                  success:
                    type: boolean
                  data:
                    $ref: '#/components/schemas/PayBill'
components:
  schemas:
    PayBill:
      type: object
      required: [billNo, status]
      properties:
        billNo:
          type: string
        status:
          type: string
          enum: [draft, submitted, audited]
```

