docs(README): 约定按作用域分层(全局 vs 条件)

shrimp 不是单体协议而是可拼装件集合,每个件有自己的契约。
作用域 = 你用了哪个件就遵守哪个件的契约,不用不必遵守。

- 🌐 全局约定:IModuleInfo / IFieldConfig / Shrimp 树 / Power-Role / ILabel
- 🔌 条件约定:按宿主件分组(ShrimpTable / ShrimpServer / MongoShrimp /
  OperationLogModule / 默认 Field*.vue / 子模块机制)

这一层概念是 shrimp-admin 抽包前要先共识的:shrimp-admin 不是框架,
是"消费 ShrimpServer + ShrimpTable 这两套条件契约"的经典前端实现。
This commit is contained in:
2026-05-23 20:47:35 +08:00
parent ca283c6733
commit 652b31052e
+27
View File
@@ -96,6 +96,33 @@ import type { IFieldConfig, IMenuItem, IMeResult } from "shrimp-server/types"
## 约定 ## 约定
shrimp 不是铁板一块的协议,它是**一组可选拼装件**。每个件对外有自己的契约,你用了哪个件就被哪个件的契约绑住,不用就不必遵守。盘点时按**作用域**分两层。
### 🌐 全局约定(只要你说"我在写 shrimp",就跑不掉)
| 契约 | 说明 |
|---|---|
| `IModuleInfo` 形状 | 任何模块声明都得这么写 — 见 [src/IShrimpType.ts](src/IShrimpType.ts) `IModuleInfo` |
| `IFieldConfig` 形状 | 字段就这样描述(`name` / `label` / `type` / `relation` / `rules` …) |
| Shrimp 树结构 | `parent`/`children` 嵌套、`getFullPath()` 路径语义 |
| Power / Role 声明 | `power` 树形 + `role` 持 `powers[]` |
| `ILabel` 多语言形态 | 见下方 §国际化 — 6 选 1 的标签类型 |
### 🔌 条件约定(用了某个件,才被它的契约绑住)
| 启用前提 | 它的契约 |
|---|---|
| **使用 `ShrimpTable`(前端表格组件)** | • list 响应必须是 `IPageResult` = `{ list, total, page, pageSize, totalPages }`<br>• 字段 `type` 必须落在内置枚举:`string` / `number` / `boolean` / `date` / `select` / `textarea` / `password` / `relation` / `json` / `tab` —— 或自行注册 `IFieldTypeHandler`<br>• populate 字段旁挂 `${key}_label`(数组关联挂数组) |
| **使用 `buildShrimpRouter` / `ShrimpServer`** | • HTTP 路由形状:`GET /config`、`POST /login`、`GET /me`、`POST /<modulePath>/<event>`<br>• JWT 携带:`Authorization: Bearer <token>`<br>• 后端需实现 `IUserAccessor`(getJwtPayload / isUserActive / getUserRoleIds / isRoleSuperAdmin / getRolePowers / getUserDisplayName) — 见 [src/forExpress/types.ts](src/forExpress/types.ts) |
| **使用 `MongoShrimp`** | • User/Role/OperationLog 的 mongoose Schema 形状<br>• `onDbConnected` 钩子时序:连接就绪后才能注册需要 DB 的模块 |
| **挂 `OperationLogModule`** | • CRUD 动作自动写日志的字段集(operator / module / action / target / time) |
| **使用默认 `Field*.vue` 渲染**(前端) | • 字段 `type` 必须是内置枚举之一,否则需注册 `typeHandler` 才能渲染 |
| **使用 Shrimp 子模块机制** | • 子表 `ownerKey` 是后端注册侧独占,**不进 fields[]**<br>• 前端只发通用 `ownerId`,不感知 `ownerKey` 的实际字段名 |
> 替换某个件,这个件的条件契约自动失效。例如:你换掉 `ShrimpTable` 用 AG-Grid,list 响应格式和字段 type 枚举两条对你都不再生效;你不挂 `OperationLogModule`,日志契约就不存在。
---
### 国际化 (ILabel) ### 国际化 (ILabel)
所有前端可见文本字段(`label` / `tip` / `menu.label` / `power.label` / `field.label` / `rule.message` …)统一类型 `ILabel`。**用哪种形态取决于你写在哪一层**。 所有前端可见文本字段(`label` / `tip` / `menu.label` / `power.label` / `field.label` / `rule.message` …)统一类型 `ILabel`。**用哪种形态取决于你写在哪一层**。