# Mid-Platform Development Rules

## 一、变更范围规范

- 中台代码只允许修改 `src/init/initScript.ts`、`src/services/`，以及在 `src/local-lib` 添加代码

## 二、服务文件规范

- services文件夹下的 每个服务必须包含三个文件：
  - `Xxx.ts` - 服务实现文件
  - `XxxDeclare.ts` - 接口声明文件（服务文件名 + Declare 后缀）
  - `Xxx.test.ts` - 测试文件（服务文件名 + .test 后缀）
- 服务文件与声明文件以及测试文件必须放在同一目录下
- 创建新服务时，必须同时创建声明文件和测试文件
- 声明文件必须与服务实现保持同步，字段定义一致
- 服务文件必须从声明文件导入类型，禁止在服务文件中重复定义接口

## 三、声明文件规范

- 文件命名规则：服务文件名为 `Xxx.ts`，声明文件必须命名为 `XxxDeclare.ts`
  - 示例：`LeisureOrderService.ts` → `LeisureOrderServiceDeclare.ts`
- 顶层必须是 `export namespace XxxDeclare { ... }`
- 命名空间内必须包含：
  - `export namespace $parameters { ... }`
  - `export namespace $results { ... }`
  - `export type Parameters = ...`
  - `export type Result = ...`
- 文件末尾必须包含：
  - `export type Parameters = XxxDeclare.Parameters`
  - `export type Result = XxxDeclare.Result`
- 入参优先统一放在 `$parameters.JsonParam`
- `*Declare.ts` 内禁止使用 `any` 作为入参或出参字段类型
- 涉及 `formData`、`data` 等复合字段时，必须拆为独立 `FormDataParam`、`DataParam` 等类型后再引用
- 入参和出参必须根据业务实际使用的字段完整声明，不能使用空对象占位

## 四、类型规范

- 推荐使用：`string`、`number`、`boolean`、`Date`、`dayjs.Dayjs`、`interface`、`type = {}`、`T[]`、`Array<T>`、`File`、`Array<File>`
- 允许使用同命名空间引用：`$parameters.Xxx`、`$results.Xxx`、`type A = B`
- 字段需结构化表达时，优先使用 `interface/type/array/file`，不要退化成 `any`
- 字面量联合类型如 `'上' | '下' | '左' | '右'` 按字符串语义设计
- 不建议使用：交叉类型、元组、映射类型、条件类型、复杂工具类型、跨文件复杂类型引用

## 五、单元测试规范

- 测试文件命名：`Xxx.test.ts`，与服务文件放在同一目录

## 六、推荐模板

### 声明文件模板

```ts
export namespace BarcodePaymentDeclare {
  export namespace $parameters {
    export interface OtherConfigParam {
    }

    export interface WxMPPaySpecialParametersParam {
    }

    export interface AliUnifiedPaySpecialParametersParam {
    }

    export interface CustomParametersParam {
    }

    export interface ThirdPartyPayConfigParam {
      code?: string
      merNo?: string
      merKey?: string
      otherConfig?: OtherConfigParam
    }

    export interface JsonParam {
      outOrderNo?: string
      productionName?: string
      productionDescription?: string
      amount?: number
      clientIp?: string
      returnUrl?: string
      expiredTime?: string
      wxMPPaySpecialParameters?: WxMPPaySpecialParametersParam
      aliUnifiedPaySpecialParameters?: AliUnifiedPaySpecialParametersParam
      thirdPartyPayConfig?: ThirdPartyPayConfigParam
      authCode?: string
      customParameters?: CustomParametersParam
      sign?: string
    }
  }

  export namespace $results {
    export interface ResultData {
      responseCode?: string
      responseMsg?: string
      resultCode?: string
      resultMsg?: string
      tradeState?: string
      thirdPartyTransNo?: string
      gmtPaidTime?: string
      outOrderNo?: string
    }
  }

  export type Parameters = $parameters.JsonParam
  export type Result = $results.ResultData
}

export type Parameters = BarcodePaymentDeclare.Parameters
export type Result = BarcodePaymentDeclare.Result
```

