Files
alist-serve-resource/docs/DATABASE_SCHEMA.md
T

153 lines
6.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# NocoDB 数据结构(Phase 2b — 重建,7 表最终模型)
> Source of Truth = NocoDB。AList 只做 enforcement,不存业务授权数据。
> 本 schema 按《Hermes 调整指导》最终业务模型重建(2026-08-22)。
> 通过 NocoDB API 自动建表,无需手动点 UI。
- **Base**: `AlistAccess`(id `p3lzkresswyowqg`),独立新 base,与旧 `accessDB` 隔离。
- **MySQL source**: mysql-server 上的 `alistaccess` schema(由 NocoDB 自动管理)。
- **API token**: workspace token(`nc_api_tokens` 表内 `n8n` token),`xc-token` header。
## 表 model_id(n8n v2 API 硬编码用)
| 表 | model_id |
|---|---|
| Customers | `maqb9zgvza2te3k` |
| Products | `molyb3pxv81l75g` |
| Resources | `m6cm7tkxzd8m18c` |
| CustomerProducts | `mvyqbv8ao7u6bct` |
| AccessGrants | `mxdx3yhfcyej3ao` |
| AccessLogs | `ml12zcyzlehgi21` |
| Purchases | `mwp12z9lcohhsuk` |
> ⚠ ID 是本次重建生成的。若再次删库重建,ID 会变,需同步更新 n8n 节点 + 本文档。
## 关系(LinkToAnotherRecord)
| 子表 | 字段 | 方向 | 指向 | 说明 |
|---|---|---|---|---|
| CustomerProducts | `customer` | bt | Customers | |
| CustomerProducts | `product` | bt | Products | |
| Products | `Resources` | **mm** | Resources | M2M link,列 id `c4ko4x8kwi16swg` |
| Resources | `Products` | mm (reverse) | Products | 列 id `cfxi44n9ixkimqc` |
| AccessGrants | `customer` | bt | Customers | |
| AccessGrants | `resource` | bt | Resources | |
| AccessLogs | `customer` | bt | Customers | |
| Purchases | `customer` | bt | Customers | |
| Purchases | `product` | bt | Products | |
> M2M 读写方式(已实测):`GET/POST /api/v2/tables/{products}/links/c4ko4x8kwi16swg/records/{productId}`,
> POST body `{"Id": <resourceId>}`。反向用 Resources 的 `cfxi44n9ixkimqc`。
## 表结构
### 1. Customers
| 字段 | 类型 | 说明 |
|---|---|---|
| Id | number (PK) | |
| username | SingleLineText | AList 登录名(唯一) |
| password | SingleLineText | **plaintext**(规格 §2 已确认,勿 hash) |
| display_name | SingleLineText | |
| email | Email | |
| notes | LongText | |
| alist_user_id | Number | AList 用户 ID(n8n 回填) |
| alist_role_id | Number | AList role ID(n8n 回填) |
| status | SingleSelect | pending/active/suspended/expired/disabled/deleted |
| sync_status | SingleSelect | pending/syncing/synced/error/unknown |
| sync_required | Checkbox | 系统维护,管理员勿手改 |
| last_sync | DateTime | |
| last_sync_error | LongText | |
### 2. Products
| 字段 | 类型 | 说明 |
|---|---|---|
| Id | number (PK) | |
| name | SingleLineText | 如 "Python Basic" |
| description | LongText | |
| default_duration_days | Number | 默认有效期天数 |
| status | SingleSelect | active/inactive |
| Resources | link (mm) | 该产品包含的 Resources |
### 3. Resources
| 字段 | 类型 | 说明 |
|---|---|---|
| Id | number (PK) | |
| name | SingleLineText | 如 "Python 01" |
| alist_path | SingleLineText | 真实 AList path,如 "/Class/Python/01" |
| description | LongText | |
| status | SingleSelect | active/inactive |
| Products | link (mm, reverse) | |
### 4. CustomerProducts(核心新表)
| 字段 | 类型 | 说明 |
|---|---|---|
| Id | number (PK) | |
| customer | link bt → Customers | |
| product | link bt → Products | |
| start_at | Date | |
| expires_at | Date | 实际到期(可 override default_duration) |
| status | SingleSelect | scheduled/active/expired/revoked/suspended |
| sync_status | SingleSelect | pending/syncing/synced/error/unknown |
| sync_required | Checkbox | |
| last_sync | DateTime | |
| last_sync_error | LongText | |
### 5. AccessGrants(最终实际权限,n8n 计算维护)
| 字段 | 类型 | 说明 |
|---|---|---|
| Id | number (PK) | |
| customer | link bt → Customers | |
| resource | link bt → Resources | |
| permission | SingleSelect | read/readwrite |
| start_at | Date | |
| expires_at | Date | effective expiry(多来源取 max) |
| status | SingleSelect | pending/active/revoked/expired |
| source | SingleSelect | product/manual |
| sync_status | SingleSelect | pending/syncing/synced/error/unknown |
| sync_required | Checkbox | |
| last_sync | DateTime | |
| last_sync_error | LongText | |
| revoked_at | DateTime | |
| revoke_reason | LongText | |
### 6. AccessLogs(审计)
| 字段 | 类型 |
|---|---|
| Id | number (PK) |
| customer | link bt → Customers |
| username | SingleLineText |
| resource_path | SingleLineText |
| file_path | SingleLineText |
| action | SingleSelect (login/view/download/preview/logout) |
| ip_address | SingleLineText |
| user_agent | LongText |
| result | SingleSelect (success/denied) |
| bytes | Number |
| timestamp | DateTime |
### 7. Purchases(纯记录,不参与权限)
| 字段 | 类型 |
|---|---|
| Id | number (PK) |
| customer | link bt → Customers |
| product | link bt → Products |
| purchase_date | Date |
| amount | Decimal |
| payment_method | SingleLineText |
| order_id | SingleLineText |
| notes | LongText |
## 建表 API recipe(实测 2026-08-22,复用见 nocodb-selfhosted skill)
- 建 base:`POST /api/v2/meta/bases/ {"title"}`
- 建表(内联非 select 列):`POST /api/v2/meta/bases/{baseId}/tables {"title","table_name","type":"table","columns":[{"title","uidt"}]}`
- 可用 uidt:`SingleLineText`,`LongText`,`Number`,`Decimal`,`Date`,`DateTime`,`Email`,`Checkbox`
- SingleSelect 两段式:
1. 建空列 `POST /api/v1/db/meta/tables/{tid}/columns {"title","uidt":"SingleSelect"}`
2. 设选项 **必须同时传 `dtxp`**(逗号枚举串):
`PATCH /api/v1/db/meta/columns/{colid} {"colOptions":{"options":[{"title","order","color":null}]},"dtxp":"'opt1','opt2'"}`
⚠ 只传 `colOptions` 不传 `dtxp` 会静默失败(options 空)。
- Link:`POST /api/v1/db/meta/tables/{childTid}/columns {"title","uidt":"LinkToAnotherRecord","parentId","childId","type":"bt"}`
- M2M:`type":"mm"`,然后走 `/api/v2/tables/{t}/links/{colId}/records/{rowId}` 读写。
- 删记录:`DELETE /api/v2/tables/{tid}/records` body `[{"Id":N},...]`(不是 `/records/{id}`)。