117 lines
4.6 KiB
Markdown
117 lines
4.6 KiB
Markdown
# SOURCE_ADD / 对码幂等 / Alias 唯一态 Implementation Plan
|
|
|
|
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
|
|
|
**Goal:** 让 `SOURCE_ADD` 有明确触发源,让 `PRODUCT_MATCH` 可重复跑且不重复落库,让 alias 沉淀成唯一当前态。
|
|
|
|
**Architecture:** 对码仍然留在 `app/main.py` 的状态中心内执行,但把“判定缺货源 / 对码执行 / 人工确认”拆成稳定的写入边界。`product_match` 以 `(job_id, order_item_id)` 作为幂等键,`mapping_config` 只保留一个 active alias 当前态,`job.needs_source_add` 作为 `SOURCE_ADD` 的唯一触发开关。
|
|
|
|
**Tech Stack:** Python, FastAPI, MySQL, pymysql, pytest/unittest
|
|
|
|
---
|
|
|
|
### Task 1: 让对码重跑幂等
|
|
|
|
**Files:**
|
|
- Modify: `/Users/yuuuu/Documents/AutoRpa/state_center/sql/schema.sql`
|
|
- Modify: `/Users/yuuuu/Documents/AutoRpa/state_center/app/main.py`
|
|
- Test: `/Users/yuuuu/Documents/AutoRpa/state_center/tests/test_match_engine.py` or a new focused test file
|
|
|
|
- [ ] **Step 1: Write the failing test**
|
|
|
|
```python
|
|
def test_match_run_replay_does_not_duplicate_product_match_rows():
|
|
...
|
|
```
|
|
|
|
- [ ] **Step 2: Run test to verify it fails**
|
|
|
|
Run: `python3 -m pytest /Users/yuuuu/Documents/AutoRpa/state_center/tests -q`
|
|
Expected: fail because `product_match` lacks a stable dedupe key or the code still inserts duplicates.
|
|
|
|
- [ ] **Step 3: Write minimal implementation**
|
|
|
|
Add a unique key on `(job_id, order_item_id)`, switch `match_run` to upsert by that key, and keep `user_task` creation tied to `product_match_id`.
|
|
|
|
- [ ] **Step 4: Run test to verify it passes**
|
|
|
|
Run: `python3 -m pytest /Users/yuuuu/Documents/AutoRpa/state_center/tests -q`
|
|
Expected: pass for the replay case.
|
|
|
|
- [ ] **Step 5: Commit**
|
|
|
|
```bash
|
|
git add /Users/yuuuu/Documents/AutoRpa/state_center/sql/schema.sql /Users/yuuuu/Documents/AutoRpa/state_center/app/main.py /Users/yuuuu/Documents/AutoRpa/state_center/tests
|
|
git commit -m "fix: make product match replay idempotent"
|
|
```
|
|
|
|
### Task 2: 让 SOURCE_ADD 有明确触发源
|
|
|
|
**Files:**
|
|
- Modify: `/Users/yuuuu/Documents/AutoRpa/state_center/app/main.py`
|
|
- Modify: `/Users/yuuuu/Documents/AutoRpa/state_center/sql/schema.sql`
|
|
- Modify: `/Users/yuuuu/Documents/AutoRpa/state_center/给Trae的开发交接.md`
|
|
|
|
- [ ] **Step 1: Write the failing test**
|
|
|
|
```python
|
|
def test_source_add_only_triggers_when_job_flag_is_set():
|
|
...
|
|
```
|
|
|
|
- [ ] **Step 2: Run test to verify it fails**
|
|
|
|
Run: `python3 -m pytest /Users/yuuuu/Documents/AutoRpa/state_center/tests -q`
|
|
Expected: fail because `needs_source_add` is not yet driven by a concrete write path.
|
|
|
|
- [ ] **Step 3: Write minimal implementation**
|
|
|
|
Introduce a single write path for `job.needs_source_add`, use it in `match_run` / confirm flow, and only let `_next_node()` expose `SOURCE_ADD` when that flag is set.
|
|
|
|
- [ ] **Step 4: Run test to verify it passes**
|
|
|
|
Run: `python3 -m pytest /Users/yuuuu/Documents/AutoRpa/state_center/tests -q`
|
|
Expected: pass for both the flagged and skipped cases.
|
|
|
|
- [ ] **Step 5: Commit**
|
|
|
|
```bash
|
|
git add /Users/yuuuu/Documents/AutoRpa/state_center/app/main.py /Users/yuuuu/Documents/AutoRpa/state_center/sql/schema.sql /Users/yuuuu/Documents/AutoRpa/state_center/给Trae的开发交接.md
|
|
git commit -m "fix: make source add trigger explicit"
|
|
```
|
|
|
|
### Task 3: 让 alias 沉淀成唯一当前态
|
|
|
|
**Files:**
|
|
- Modify: `/Users/yuuuu/Documents/AutoRpa/state_center/app/main.py`
|
|
- Modify: `/Users/yuuuu/Documents/AutoRpa/state_center/sql/schema.sql`
|
|
- Modify: `/Users/yuuuu/Documents/AutoRpa/state_center/README.md`
|
|
|
|
- [ ] **Step 1: Write the failing test**
|
|
|
|
```python
|
|
def test_alias_confirm_replaces_existing_active_alias_for_same_key():
|
|
...
|
|
```
|
|
|
|
- [ ] **Step 2: Run test to verify it fails**
|
|
|
|
Run: `python3 -m pytest /Users/yuuuu/Documents/AutoRpa/state_center/tests -q`
|
|
Expected: fail because multiple active aliases for the same `config_key` are still possible.
|
|
|
|
- [ ] **Step 3: Write minimal implementation**
|
|
|
|
Make confirm flow deactivate the previous active alias for the same key before inserting the new one, and make alias loading deterministic by reading only the latest active row per key.
|
|
|
|
- [ ] **Step 4: Run test to verify it passes**
|
|
|
|
Run: `python3 -m pytest /Users/yuuuu/Documents/AutoRpa/state_center/tests -q`
|
|
Expected: pass with one active alias per key.
|
|
|
|
- [ ] **Step 5: Commit**
|
|
|
|
```bash
|
|
git add /Users/yuuuu/Documents/AutoRpa/state_center/app/main.py /Users/yuuuu/Documents/AutoRpa/state_center/sql/schema.sql /Users/yuuuu/Documents/AutoRpa/state_center/README.md
|
|
git commit -m "fix: keep alias mapping deterministic"
|
|
```
|