d36bb954d1
Baseline before backporting wp-data-optimizer v3.0.1-v3.4.6. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TbG1keQQ7XBa7qMQY16KCY
131 lines
4.4 KiB
Markdown
131 lines
4.4 KiB
Markdown
# DESIGN — 2meet Data Optimizer 架構決策
|
||
|
||
## 設計目標(pillars)
|
||
|
||
1. **Zero-side-effect**:未啟用任何 zone 的站台應感受不到此外掛存在
|
||
2. **Non-destructive**:所有操作可 rollback(snapshot + 7-state FSM)
|
||
3. **Schema-first**:所有欄位需明確 register,禁止隱式 mapping
|
||
4. **Hook-bus only**:所有寫入必經 Hook Bus;禁止繞過 interceptor 直 SQL
|
||
5. **Anti-EAV strict**:紅線禁止 `SELECT FROM wp_*meta`(除一次性 migration / cron)
|
||
|
||
---
|
||
|
||
## 七態 FSM 模組生命週期
|
||
|
||
```
|
||
┌──────────────────────────────────────────────┐
|
||
│ │
|
||
v │
|
||
idle ──→ dual_write ──→ backfill ──→ verify ──→ cutover ──→ cleanup ──→ complete
|
||
│ │
|
||
└─ rollback ─┘
|
||
```
|
||
|
||
| 態 | 寫 | 讀 | 可逆 |
|
||
|---|---|---|---|
|
||
| idle | wp_*meta | wp_*meta | ✓ |
|
||
| dual_write | wp_*meta + zone | wp_*meta | ✓ |
|
||
| backfill | wp_*meta + zone | wp_*meta | ✓ |
|
||
| verify | wp_*meta + zone | wp_*meta | ✓ |
|
||
| cutover | wp_*meta + zone | zone | ✓ (rollback to verify) |
|
||
| cleanup | zone only | zone | ✗ (postmeta 已 DROP) |
|
||
| complete | zone only | zone | ✗ |
|
||
|
||
---
|
||
|
||
## 四象限分配原則
|
||
|
||
| Zone | 條件 | 範例 |
|
||
|---|---|---|
|
||
| Hot | 同欄位被 meta_query 過濾或 ORDER BY 排序 | `_price`, `hp_featured` |
|
||
| Warm | 高頻寫入 / 短 TTL / 弱一致性 | view counter, hourly flag |
|
||
| Cold | 長文本 / 不被搜尋 / 顯示用 | `_description`, social links JSON |
|
||
| Archive | 過期資料 / gzip 壓縮 | expired listings 歷史欄位 |
|
||
|
||
`TMDO_Zone_Classifier` 自動分析(transient 1h),但人工 register 永遠優先。
|
||
|
||
---
|
||
|
||
## Hook Bus 架構
|
||
|
||
Hook Bus 是寫入唯一真理之源。任何外掛要參與反 EAV 必須:
|
||
|
||
```php
|
||
// 註冊
|
||
add_action( 'tmdo_register_entity_fields', function ( $registry_class ) {
|
||
$registry_class::register_group( 'user', 'my_group', [...] );
|
||
} );
|
||
|
||
// 訂閱事件
|
||
add_action( 'tmdo_after_write', function ( $type, $id, $key, $value, $result ) {
|
||
// ... cross-domain logic
|
||
} );
|
||
```
|
||
|
||
禁止直接 hook `update_user_meta` / `add_post_meta`(會與 Hook Bus 衝突,CI gate 偵測)。
|
||
|
||
---
|
||
|
||
## Schema Registry 雙軌
|
||
|
||
- **`TMDO_Schema_Registry`**:post entity 的 zone 欄位(HP listing 模式)
|
||
- **`TMDO_Entity_Registry`**:4 entity 通用 group(user/post/term/comment)
|
||
|
||
兩者並存原因:post zone 模式較成熟,user/term/comment 較新;最終 v0.3.0 會收斂為單一 registry。
|
||
|
||
---
|
||
|
||
## Custom Table Registry
|
||
|
||
第三方外掛的自訂表可註冊到 `TMDO_Custom_Table_Registry` 享有:
|
||
- `wp tmdo doctor` 表結構檢查
|
||
- Schema drift 偵測(CREATE 與 DROP 對齊)
|
||
- Benchmark 整合(可選 `benchmark_callback`)
|
||
- 衝突偵測
|
||
|
||
僅限 schema 監控,不會被 Hook Bus 攔截寫入。
|
||
|
||
---
|
||
|
||
## 為什麼資料表沿用 `wp_wpdo_*` 不 rename 為 `wp_tmdo_*`
|
||
|
||
- 避免 v2.16.0 → v0.1.0 資料遷移的成本與風險
|
||
- 兩外掛同時存在時 schema 完全相容(互斥啟動)
|
||
- v0.2.0 後若決定 rename 再做(屆時提供 `wp tmdo migrate-from-wpdo`)
|
||
|
||
---
|
||
|
||
## 為什麼公開 API 同時暴露 `TMDO_API` + `WPDO_API` (alias)
|
||
|
||
- `class_alias( 'TMDO_API', 'WPDO_API' )` 確保 hub-core / spoke-sso / 其他 consumer 零修改可用
|
||
- `wpdo_*` hook 與 `tmdo_*` hook 並存 dual-fire
|
||
- 過渡期 ≥ 2 個 minor 版本後加 `_doing_it_wrong` deprecation notice
|
||
|
||
---
|
||
|
||
## CSS 設計系統
|
||
|
||
承襲父環境奶油莫蘭迪設計系統(見 `wp-local-dev/CLAUDE.md` § 設計系統):
|
||
- 顏色:`var(--color-*)`,禁止 HEX 硬編碼
|
||
- 間距:`var(--space-*)` 8px 倍數
|
||
- 圓角:`var(--radius-*)`
|
||
- 按鈕最小高度 44px
|
||
- 過渡:`var(--ease-default) + var(--duration-normal)`
|
||
|
||
詳見 `admin/assets/wpdo-admin.css`(從 wp-data-optimizer v2.16.0 搬入)。
|
||
|
||
---
|
||
|
||
## 反 EAV 8 維評分(自評)
|
||
|
||
承襲 wp-data-optimizer 8 維 anti-EAV 評分標準,目標 v0.1.0 達 9.5+/10:
|
||
|
||
1. ✅ Schema-first registration
|
||
2. ✅ Hook Bus single source of truth
|
||
3. ✅ No direct `wp_*meta` SELECT in app code
|
||
4. ✅ Custom table registry 全覆蓋
|
||
5. ✅ Sync Bridge dual-write + cutover
|
||
6. ✅ Query Router pre_get_posts 改寫
|
||
7. ✅ Snapshot + rollback 機制
|
||
8. ✅ Conflict detection + CI gate
|