Files
erp/docs/superpowers/plans/2026-04-19-shantou-zhijie-it-services-plugins-plan.md

13 KiB
Raw Blame History

汕头市智界科技 IT 服务插件 — 实施计划

For agentic workers: REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (- [ ]) syntax for tracking.

Goal: 为汕头市智界科技有限公司创建 freelance自由职业者工作台和 itopsIT 运维服务台)两个 WASM 插件,覆盖其全部 12 条经营范围。

Architecture: 两个独立的 WASM 插件 crate每个包含 Cargo.tomlcdylib、src/lib.rsGuest trait 实现、plugin.toml声明式 schema。通过插件安装 API 上传到系统平台自动创建动态表、注册权限、生成前端页面。itops 通过 ref_plugin 跨插件引用 freelance 的 client 实体。

Tech Stack: Rust (wit-bindgen 0.55, cdylib → WASM Component)、TOML manifest、Axum Host API

Spec: docs/superpowers/specs/2026-04-19-shantou-zhijie-it-services-plugins-design.md


Chunk 1: freelance 插件

Task 1: 创建 crate 目录和 Cargo.toml

Files:

  • Create: crates/erp-plugin-freelance/Cargo.toml

  • Create: crates/erp-plugin-freelance/src/lib.rs(空文件占位)

  • Step 1: 创建目录结构

mkdir -p crates/erp-plugin-freelance/src
  • Step 2: 编写 Cargo.toml

创建 crates/erp-plugin-freelance/Cargo.toml

[package]
name = "erp-plugin-freelance"
version = "0.1.0"
edition = "2024"
description = "自由职业者工作台 WASM 插件"

[lib]
crate-type = ["cdylib"]

[dependencies]
wit-bindgen = "0.55"
  • Step 3: 编写 src/lib.rs

创建 crates/erp-plugin-freelance/src/lib.rs

//! 自由职业者工作台 WASM 插件

wit_bindgen::generate!({
    path: "../erp-plugin-prototype/wit/plugin.wit",
    world: "plugin-world",
});

use crate::exports::erp::plugin::plugin_api::Guest;

struct FreelancePlugin;

impl Guest for FreelancePlugin {
    fn init() -> Result<(), String> {
        Ok(())
    }

    fn on_tenant_created(_tenant_id: String) -> Result<(), String> {
        Ok(())
    }

    fn handle_event(_event_type: String, _payload: Vec<u8>) -> Result<(), String> {
        Ok(())
    }
}

export!(FreelancePlugin);
  • Step 4: 注册到 workspace

编辑根 Cargo.toml,在 members 数组末尾添加:

    "crates/erp-plugin-freelance",
  • Step 5: 验证编译
cargo check -p erp-plugin-freelance

Expected: 编译通过,无错误

  • Step 6: Commit
git add crates/erp-plugin-freelance/ Cargo.toml
git commit -m "feat(freelance): 创建插件 crate 骨架"

Task 2: 编写 plugin.tomlfreelance

Files:

  • Create: crates/erp-plugin-freelance/plugin.toml

  • Step 1: 从设计规格文档复制完整 plugin.toml 内容

从设计规格 docs/superpowers/specs/2026-04-19-shantou-zhijie-it-services-plugins-design.md 中提取 2.1(元数据)+ 2.2(权限)+ 2.310 个实体)+ 2.4(编号规则)+ 2.5(页面声明)的所有 TOML 内容,合并为完整的 plugin.toml 文件。

文件结构:

  1. [metadata]
  2. [[permissions]] × 20
  3. [[schema.entities]] × 10client, opportunity, quote, quote_line, contract, project, task, time_entry, invoice, expense每个实体包含 fields 和 relations
  4. [[numbering]] × 3quote_number, contract_number, invoice_number
  5. [[ui.pages]] × 7dashboard, tabs+detail+kanban for client, crud+detail for project, tabs for finance, crud for expense

注意要点:

  • client 实体必须标记 is_public = true(被 itops 跨插件引用)

  • quote 到 quote_line 有 cascade 关系

  • project 到 task 和 time_entry 有 cascade 关系

  • 所有 uuid 引用字段使用 ui_widget = "entity_select" + ref_label_field + ref_search_fields

  • 所有 select 字段使用 options = [{ label = "X", value = "x" }] 格式

  • 长文本使用 field_type = "string" + ui_widget = "textarea"

  • 金额使用 field_type = "decimal"

  • 时间戳使用 field_type = "date_time"

  • Step 2: 验证 TOML 格式

cargo check -p erp-plugin-freelance
  • Step 3: Commit
git add crates/erp-plugin-freelance/plugin.toml
git commit -m "feat(freelance): 添加 plugin.toml — 10 实体/20 权限/7 页面"

Task 3: 编译 WASM 并安装

  • Step 1: 编译为 WASM
cargo build -p erp-plugin-freelance --target wasm32-unknown-unknown --release

Expected: 编译成功,产出 target/wasm32-unknown-unknown/release/erp_plugin_freelance.wasm

  • Step 2: 转换为 Component
wasm-tools component new target/wasm32-unknown-unknown/release/erp_plugin_freelance.wasm -o target/erp_plugin_freelance.component.wasm
  • Step 3: 检查产物大小
ls -la target/erp_plugin_freelance.component.wasm

Expected: < 100KBCRM 约 22KB

  • Step 4: 启动后端服务
cd crates/erp-server && cargo run

等待服务启动完成(看到 "listening on 0.0.0.0:3000" 日志)

  • Step 5: 登录获取 Token
curl -s -X POST http://localhost:3000/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"admin123"}' | jq -r '.data.access_token'

保存输出的 token。

  • Step 6: 上传安装插件
TOKEN="<上一步的 token>"
MANIFEST=$(cat crates/erp-plugin-freelance/plugin.toml)

curl -s -X POST http://localhost:3000/api/v1/admin/plugins/upload \
  -H "Authorization: Bearer $TOKEN" \
  -F "wasm=@target/erp_plugin_freelance.component.wasm" \
  -F "manifest=$MANIST"

Expected: 返回插件 ID状态为 installed

  • Step 7: 启用插件

使用上一步返回的插件 ID

PLUGIN_ID="<返回的插件 ID>"
curl -s -X POST "http://localhost:3000/api/v1/admin/plugins/$PLUGIN_ID/enable" \
  -H "Authorization: Bearer $TOKEN"

Expected: 状态变为 running

  • Step 8: Commit
git add -A
git commit -m "feat(freelance): 编译 WASM 并验证安装"

Task 4: 浏览器验证 freelance 插件

Expected: 看到"自由职业者工作台"菜单组,包含:工作台、客户管理、商机看板、项目管理、项目详情、财务中心、支出管理

  • Step 3: 测试客户 CRUD

进入客户管理 → 新增客户(填写名称、联系人、电话、行业等)→ 保存 → 列表中可见

  • Step 4: 测试项目 → 任务级联

进入项目管理 → 新增项目 → 进入项目详情 → 新增任务 → 验证任务关联到项目

  • Step 5: 测试报价 → 报价明细级联

进入财务中心 → 报价管理 tab → 新增报价 → 验证明细行可添加

  • Step 6: 测试商机看板

进入商机看板 → 新增商机 → 拖拽改变阶段 → 验证数据更新

  • Step 7: 验证数据库表创建
PGPASSWORD=123123 "D:\postgreSQL\bin\psql.exe" -U postgres -h localhost -d erp -c "\dt plugin_erp_freelance_*"

Expected: 看到 10 张动态表


Chunk 2: itops 插件

Task 5: 创建 itops 插件 crate

Files:

  • Create: crates/erp-plugin-itops/Cargo.toml

  • Create: crates/erp-plugin-itops/src/lib.rs

  • Create: crates/erp-plugin-itops/plugin.toml

  • Step 1: 创建目录结构

mkdir -p crates/erp-plugin-itops/src
  • Step 2: 编写 Cargo.toml

创建 crates/erp-plugin-itops/Cargo.toml

[package]
name = "erp-plugin-itops"
version = "0.1.0"
edition = "2024"
description = "IT 运维服务台 WASM 插件"

[lib]
crate-type = ["cdylib"]

[dependencies]
wit-bindgen = "0.55"
  • Step 3: 编写 src/lib.rs

创建 crates/erp-plugin-itops/src/lib.rs

//! IT 运维服务台 WASM 插件

wit_bindgen::generate!({
    path: "../erp-plugin-prototype/wit/plugin.wit",
    world: "plugin-world",
});

use crate::exports::erp::plugin::plugin_api::Guest;

struct ItopsPlugin;

impl Guest for ItopsPlugin {
    fn init() -> Result<(), String> {
        Ok(())
    }

    fn on_tenant_created(_tenant_id: String) -> Result<(), String> {
        Ok(())
    }

    fn handle_event(_event_type: String, _payload: Vec<u8>) -> Result<(), String> {
        Ok(())
    }
}

export!(ItopsPlugin);
  • Step 4: 编写 plugin.toml

从设计规格文档 Section 3 提取完整内容:

  1. [metadata] — id="erp-itops",无 dependencies松耦合
  2. [[permissions]] × 8
  3. [[schema.entities]] × 4service_contract, ticket, check_plan, check_record每个实体包含 fields 和 relations
  4. [[numbering]] × 1contract_number
  5. [[ui.pages]] × 4crud+detail for service_contract, tabs for ticket center

关键注意点:

  • 4 个实体的 client_id 字段都使用 ref_plugin = "erp-freelance" + ref_fallback_label = "外部客户"

  • filterable 只用于 string 类型的 status/type/category 字段,不用于 uuid 字段

  • check_itemsitems_data 使用 field_type = "json"

  • responded_at / resolved_at / closed_at 使用 field_type = "date_time"

  • Step 5: 注册到 workspace

编辑根 Cargo.toml,在 members 数组末尾添加:

    "crates/erp-plugin-itops",
  • Step 6: 验证编译
cargo check -p erp-plugin-itops
  • Step 7: Commit
git add crates/erp-plugin-itops/ Cargo.toml
git commit -m "feat(itops): 创建 IT 运维服务台插件 — 4 实体/8 权限/4 页面"

Task 6: 编译 WASM 并安装 itops

  • Step 1: 编译为 WASM
cargo build -p erp-plugin-itops --target wasm32-unknown-unknown --release
  • Step 2: 转换为 Component
wasm-tools component new target/wasm32-unknown-unknown/release/erp_plugin_itops.wasm -o target/erp_plugin_itops.component.wasm
  • Step 3: 上传安装插件
TOKEN="<之前获取的 token>"
MANIFEST=$(cat crates/erp-plugin-itops/plugin.toml)

curl -s -X POST http://localhost:3000/api/v1/admin/plugins/upload \
  -H "Authorization: Bearer $TOKEN" \
  -F "wasm=@target/erp_plugin_itops.component.wasm" \
  -F "manifest=$MANIFEST"
  • Step 4: 启用插件
PLUGIN_ID="<返回的插件 ID>"
curl -s -X POST "http://localhost:3000/api/v1/admin/plugins/$PLUGIN_ID/enable" \
  -H "Authorization: Bearer $TOKEN"

Task 7: 浏览器验证 itops 插件

  • Step 1: 检查侧边栏

Expected: 看到"IT 运维服务台"菜单组,包含:合同管理、合同详情、工单中心

  • Step 2: 测试维保合同 CRUD

进入合同管理 → 新增维保合同(选择客户时验证:如 freelance 已安装,客户下拉显示 freelance 的客户列表)

  • Step 3: 测试跨插件引用

场景 Afreelance 已安装):创建工单时 client_id 字段显示为下拉选择器,可搜索 freelance.client 场景 Bfreelance 未安装client_id 降级为文本输入,显示"外部客户"

  • Step 4: 测试合同 → 工单 → 巡检级联

进入合同详情 → 工单 tab → 新增工单 → 巡检计划 tab → 新增巡检计划 → 巡检记录 tab → 新增巡检记录

  • Step 5: 验证数据库表
PGPASSWORD=123123 "D:\postgreSQL\bin\psql.exe" -U postgres -h localhost -d erp -c "\dt plugin_erp_itops_*"

Expected: 看到 4 张动态表


Chunk 3: 集成验证

Task 8: 全链路端到端验证

  • Step 1: 创建客户

freelance → 客户管理 → 新增客户"汕头市XX科技有限公司"

  • Step 2: 创建商机

商机看板 → 新增商机 → 选择客户 → 填写"官网开发"→ 拖拽到"成交"阶段

  • Step 3: 创建报价单

财务中心 → 报价管理 → 新增报价 → 选择客户 → 添加明细行 → 保存

  • Step 4: 创建合同

财务中心 → 合同管理 → 新增合同 → 选择客户 → 填写金额和日期 → 保存

  • Step 5: 创建项目

项目管理 → 新增项目 → 选择客户和合同 → 填写"官网开发项目" → 添加任务 → 记录工时

  • Step 6: 创建发票

财务中心 → 发票/收款 → 新增发票 → 选择客户和项目 → 填写金额 → 标记已收款

  • Step 7: 创建运维工单

itops → 合同管理 → 新增维保合同 → 选择客户(验证跨插件引用)→ 保存 itops → 工单中心 → 新增工单 → 选择客户和合同 → 保存

  • Step 8: 记录支出

freelance → 支出管理 → 新增支出 → 选择类别"云服务" → 填写金额 → 保存

  • Step 9: 提交并推送
git add -A
git commit -m "feat(freelance,itops): 汕头市智界科技 IT 服务行业插件验证通过"
git push

关键参考文件

文件 用途
crates/erp-plugin-crm/Cargo.toml Cargo.toml 模板参考
crates/erp-plugin-crm/src/lib.rs lib.rs 代码模式参考
crates/erp-plugin-crm/plugin.toml plugin.toml 格式参考(同插件内引用)
crates/erp-plugin-inventory/plugin.toml 跨插件引用格式参考ref_plugin
crates/erp-plugin/src/manifest.rs PluginField/PluginFieldType 完整定义
crates/erp-plugin-prototype/wit/plugin.wit WIT 接口定义
wiki/infrastructure.md 数据库连接、端口、登录凭据
wiki/wasm-plugin.md 插件制作完整流程