mcpField
F
footprint-workflows

footprint-workflows

github.com/datex开发88 次安装
代码仓库

关于 footprint-workflows

Footprint Workflows 是用于在 Footprint 中编写和修改 Datex Studio footprint-workflow 配置的技能。它指导开发者将低代码 TypeScript 逻辑绑定到平台定义的扩展点,并在功能分支上验证和发布。

主要功能

  1. 01将工作流绑定到平台定义的扩展点
  2. 02通过元数据发现扩展点参数
  3. 03编写低代码 TypeScript 工作流主体
  4. 04使用 `dxs` 验证并写入配置

适用场景

  1. 01在 Footprint 处理扩展点实现自定义逻辑
  2. 02编辑工作流时保留配置内容和 GUID
  3. 03推送配置前检查工作流结构

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/datex/skills --skill footprint-workflows

安装后在 Claude Code 中输入/footprint-workflows确认已加载。

附带文件references/footprint-workflows.md

详细介绍

Footprint 工作流

在分支上编写或修改 Datex Studio footprint 工作流(configurationTypeId: 23)——这是一种低代码 TypeScript 实现,Footprint 平台会在其处理流程中的指定扩展点调用它(例如,在实体状态提交之前、装箱时、规划分配时、推荐位置时,等等)。它是旧版 XAML「Datex Workflow」活动的现代替代方案。平台负责扩展点、GUID 以及输入/输出契约;你负责实现主体。

参考资料

依赖项

  • requirements-gathering 技能 — 如果当前上下文中尚无需求简报,则调用该技能来生成需求简报(包括使用哪个扩展点、自定义行为是什么、要调度到什么目标,以及使用哪个包)。
  • action-creator 技能 — 调用该技能来编写工作流主体要调度到的包操作。工作流节点应保持为轻量调度器;实际逻辑放在操作中(同一 Footprint 服务层级)。
  • function-creator 技能 — 当将调度逻辑封装在操作后的函数中更合适时,调用该技能(工作流不能直接调用函数)。
  • datasource-creator 技能 — 当工作流通过 fpds_* footprint 数据源读取配置/状态时,调用该技能。
  • type-definition-creator 技能 — 当调度目标需要包接口/枚举时,调用该技能(FootPrintWorkflow.* 输入/结果类型由平台管理,应从 contexts 读取,而非自行编写)。
  • impact-analysis 技能 — 修改其他代码依赖的工作流之前,或重命名工作流调度到的操作/数据源之前,调用该技能;应追踪 $flows.<Package>.<action> 调用位置,而不是搜索内联代码。

CLI 生命周期

工作流编写通过 dxs configuration 完成——这是适用于所有平台配置类型的通用 CRUD 基元。没有 dxs workflow 子命令,也不支持字段级补丁;你需要构建(或获取并提取)完整的 JSON 正文,编辑后再将完整内容推送回去。CLI 类型标识符为 footprintworkflow(小写,与 ConfigurationEndpoints.normalize_type 的输出一致),映射到 configurationTypeId: 23。PublishedMain 配置的 readonly: true——请在功能分支上编写。

新建工作流——从元数据 API 中发现插槽,并分配一个新的 GUID(如果是要替换旧工作流,则复用其 GUID——参见步骤 2):

# 1. Discover the slot: id (= workflowDefinitionId), name, exact inParams/outParams
dxs api GET "/footPrintApiConnections/byName/<connectionName>/workflowsMetadata?applicationId=<branchId>" --raw -O meta.json
jq '.workflowsMetadataJson.workflowDefinitions[] | select(.name=="Cartonization")' meta.json
# 2. Generate a fresh workflowGUID for this new config (new capability; you point callers at it).
#    Superseding a legacy workflow on this slot? Reuse ITS GUID instead so existing callers keep working.
python3 -c "import uuid; print(uuid.uuid4())"
# 3. Build body.json: apiSettingName + workflowDefinitionId/Name (step 1) + your fresh GUID,
#    the slot's inParams/outParams verbatim, configurationTypeId:23, id:0, your referenceName/title/description/code
# 4. (Optional) read Input/result field shapes — contexts OR meta.json `types`
dxs configuration contexts footprintworkflow -b <branchId> -D body.json
# 5. Validate, THEN upsert — these are two steps, not one. Validate exits 1 when it finds
#    errors (read validation_errors, fix body.json, re-run); do not run the upsert on exit 1.
dxs configuration validate footprintworkflow -b <branchId> -D body.json
dxs configuration upsert  footprintworkflow -b <branchId> -D body.json

编辑现有工作流(往返流程——绝不能跳过 jq 提取):

dxs configuration get footprintworkflow <configId> -b <branchId> -O envelope.json
jq .json envelope.json > body.json          # EXTRACT THE INNER BODY (round-trip footgun guard)
# ... edit nodes[0].stepConfig.executeCodeConfig.code ...
dxs configuration validate footprintworkflow -b <branchId> -D body.json   # exit 1 = errors found; fix, do not push
dxs configuration upsert  footprintworkflow -b <branchId> -D body.json
往返规则(至关重要)

绝不能将 envelope.json 直接传入 dxs configuration upsert——这会静默破坏配置内容(信封包含 id/jsonString/version/…,而 upsert -D 不接受这些字段)。务必先运行 jq .json envelope.json > body.json。信封还包含 application.applicationDefinition 中的 Azure 应用注册机密——jq .json 提取会将其丢弃;绝不要提交 envelope.json。参见 ../datex-studio-shared/configuration-roundtrip.md。

工作流

[Phase 1: Setup + Requirements]
Follow branch-setup.md for branch/connection selection (feature branch — main is readonly)
        |
[requirements brief in context?]
  YES -> use it     NO -> invoke `requirements-gathering`
        |
[Phase 2: Identify the platform slot]
Pick the extension point (Cartonization, Entity Status Change (Before Commit),
Allocation Strategy, Recommend* , Barcode Parser, ...). Consult
references/footprint-workflows.md -> Extension-Point Catalog.
If nothing in the platform *calls* the slot -> a workflow config is inert; stop.
        |
[Phase 3: Bind to the slot]
Pull the workflowsMetadata API for the connection/branch -> copy the slot's
id (=workflowDefinitionId), name, and inParams/outParams VERBATIM. Never
invent the id/name. workflowGUID is NOT in the metadata — it is the code callers
pass: generate fresh for a NEW workflow, preserve it on edits, and reuse the
legacy GUID when shipping a drop-in replacement for an existing workflow.
        |
[Phase 4: Author the body]
Build body.json:
  - Slot binding (Phase 3): apiSettingName + workflowDefinitionId/Name +
    your workflowGUID + configurationTypeId:23 + start:"step1"
  - Fixed param contract: single Input: FootPrintWorkflow.<Slot>InputBaseWL;
    out-params exactly as the slot dictates (or [] for before-commit mutation)
  - Single ExecuteCodeActivity node; code is a THIN DISPATCHER to package
    actions ($flows.<Pkg>.<action>) and fpds reads; map results into
    $flow.outParams; action-tier rules (no $db, no functions)
  - id:0, accessModifier:public, description <=100 chars, vars/events null
        |
[Phase 5: Discover types + validate]
dxs configuration contexts footprintworkflow -b <branchId> -D body.json
  -> confirm $types.FootPrintWorkflow.<X>InputBaseWL + result fields you use
dxs configuration validate footprintworkflow -b <branchId> -D body.json
        |
[Phase 6: Push]
   CREATE -> dxs configuration upsert footprintworkflow -b <branchId> -D body.json
   MODIFY -> get -O envelope -> jq .json -> edit -> upsert (round-trip)
        |
[Phase 7: Verify (optional)]
Exercise the slot in the running platform; confirm the workflow is invoked and
the result/mutation lands. Re-fetch (jq .json) and diff against body.json.
        |
[invoke `post-edit-verification`; then `component-validator`]

阶段详情

阶段 1:设置 + 需求
  1. 遵循 ../datex-studio-shared/branch-setup.md。绝不要假定分支 ID——请与用户确认。在功能分支上编写;PublishedMain 工作流配置的 readonly: true。
  2. 检查上下文中是否有需求简报。简报应说明:使用哪个平台插槽、自定义行为、要分派到哪些软件包操作/数据源,以及目标软件包。若没有简报 → 调用 requirements-gathering。
阶段 2:确定平台插槽

只有 Footprint 平台调用相应插槽时,footprint-workflow 才会运行。请查阅 references/footprint-workflows.md → 用途与适用场景 和扩展点目录。如果所需行为不是由某个已命名的工作流插槽触发,那么此处使用的组件类型就不对——需要的是普通操作/函数/数据源。如果签名应由你来设计,那就应使用函数/操作,而不是工作流。

阶段 3:绑定到插槽

插槽绑定包含两个相互独立的部分:

  1. 插槽标识 + 签名(来自平台)。 获取 Footprint 连接和分支对应的 workflowsMetadata API:
    dxs api GET "/footPrintApiConnections/byName/<connectionName>/workflowsMetadata?applicationId=<branchId>" --raw -O meta.json
    jq '.workflowsMetadataJson.workflowDefinitions[] | {id, name, inParams, outParams}' meta.json
    
    将插槽的 id 复制到 workflowDefinitionId,将 name 复制到 workflowDefinitionName,并逐字复制其 inParams/outParams。<connectionName> 是实际的 Footprint 连接(例如 DSV),不是 apiSettingName 的值。根据分支的 Footprint 设置来设置 apiSettingName。绝不要自行编造 id/name。
  2. workflowGUID(调用方传入的代码)。 元数据中不包含它,因此目录中没有任何内容规定该值——但调用方会使用它:该值会以 ProcessingStrategyWorkflowCode / AllocationStrategyWorkflowId 的形式传到服务器,用于选择运行该插槽的哪个实现。对于真正的新工作流,生成一个新的 v4 UUID(python3 -c "import uuid; print(uuid.uuid4())"),然后让调用方指向它;编辑时保留现有 GUID,不作更改(jq .json 往返会保留它);如果配置是现有实现的直接替代品,且调用方不得更改,则复用旧 GUID。编辑时绝不要重新生成。
第 4 阶段:编写主体

根据 references/footprint-workflows.md → Minimal Valid Skeleton 构建 body.json。要点:

  1. 文件基础信息遵循下方的预检清单和通用清单:configurationTypeId: 23、id: 0、description 不超过 100 个字符、设置 accessModifier,包与功能相匹配。
  2. 参数契约由平台规定,而非由你决定。 单个 Input 入参,类型为 FootPrintWorkflow.<Slot>InputBaseWL;出参严格按槽位要求设置(单个对象、集合,或用于提交前修改的 [])。不要重命名 Input、添加参数或更改出参形状。
  3. 单个 ExecuteCodeActivity 节点。 start: "step1"、节点 id: "step1"、decisionConfig: null。虽然可以使用多节点图,但此库中没有使用——除非有明确理由,否则只用一个步骤。
  4. 代码是精简的分发器。 将 $flow.inParams.Input 转换为 $flows.<Package>.<action> 调用和 fpds 读取;将结果映射到 $flow.outParams.<Name>。操作层级规则:不使用 $db,不直接调用函数,使用 fpds(而非云端 -datasource.json)。声明了 outParams 的槽位使用 return $flow.outParams;,不要只写 return;。参见 references/footprint-workflows.md → Code Patterns。
  5. vars / events / fromBaseConfiguration 保持为 null。
第 5 阶段:发现类型并验证
dxs configuration contexts footprintworkflow -b <branchId> -D body.json
dxs configuration validate footprintworkflow -b <branchId> -D body.json

contexts 会返回 $types.FootPrintWorkflow.* IntelliSense 类型界面;其 flowContext 会将你声明的签名回显为类型化的 IFlow,可用于快速检查 $flow.inParams.Input / $flow.outParams.* 是否解析为该槽位的类型。确认你引用的每个字段都存在(不要自行编写平台类型)。根据需要使用以下三种类型发现来源(参见 references → Discovering the type surface):

  • FootPrintWorkflow.* 平台类型(Input / 结果形状)——使用 contexts,或使用 workflowsMetadata API 的 types 数组(结构化 JSON,更易查询)。
  • 分发代码使用的 $types.<Package>.* 包类型(例如 $types.Utilities.e_awi_scopes.Cartonization)——使用 dxs configuration nomenclature -b <branchId>(可使用 --package / --kind enum / --search 进行筛选;枚举成员列于 constantValues 中)。

validate 可以捕获结构性错误和必填字段错误,但无法发现错误的槽位绑定(workflowDefinitionId / 名称)、与槽位不匹配的签名或违反操作层级规则的问题——请逐项检查预检清单。

第 6 阶段:推送
# New
dxs configuration upsert footprintworkflow -b <branchId> -D body.json
# Modify-existing (round-trip — never skip the jq extract)
dxs configuration get footprintworkflow <configId> -b <branchId> -O envelope.json
jq .json envelope.json > body.json
# ... edit ...
dxs configuration upsert footprintworkflow -b <branchId> -D body.json
第 7 阶段:验证(可选)

在运行中的平台上测试该槽位——触发实体状态变更 / 箱盒化 / 分配 / 库位推荐,并确认工作流已调用,且结果或提交前修改按预期生效。如果应用不可用,则重新获取配置(使用 jq .json 提取),并与 body.json 比较差异,以确认推送已生效。

上线前检查清单

请完整查看 references/footprint-workflows.md → 上线前检查清单。快速版:

  1. configurationTypeId: 23;常用后缀为 -footprintWorkflow.json。
  2. 槽位绑定真实有效 — 从 workflowsMetadata 目录中复制 workflowDefinitionId + workflowDefinitionName;apiSettingName 与分支的 Footprint 设置一致。
  3. workflowGUID 正确 — 使用新的 v4 UUID(新建工作流,调用方改为指向新工作流)、保留原有值(编辑),或使用旧工作流的 GUID(有意进行直接替换)。编辑时绝不重新生成。
  4. 参数契约与槽位一致 — 单个 Input,类型与槽位的输入类型一致(通常为 FootPrintWorkflow.<Slot>InputBaseWL);输出参数严格遵循槽位定义(或为 [])。
  5. description 不超过 100 个字符且非空; 设置 accessModifier;全新配置使用 id: 0。
  6. 单个 ExecuteCodeActivity 节点; start 指向其 id;vars/events/fromBaseConfiguration 为 null。
  7. 代码符合 Action 层规范 — $flows.<Pkg>.<action>(不使用函数或 $db)、使用 fpds 读取、$types.FootPrintWorkflow.*、$utils.isDefined;声明了 outParams 时 → return $flow.outParams;。
  8. 根据 contexts 或元数据中的 types 验证类型。
  9. 针对该分支完成验证。

常见错误

错误修复方法
臆造或混用 workflowDefinitionId / workflowDefinitionName从 workflowsMetadata API 获取槽位的 id/name 和 inParams/outParams,并原样复制。id 和 name 错误或混用时,验证虽能通过,但不会正确绑定。
编辑时重新生成 workflowGUID,或从不相关的配置中克隆一个 GUID调用方通过 GUID 选择此工作流(它不属于槽位绑定)。新建工作流时使用新的 v4 UUID(python3 -c "import uuid; print(uuid.uuid4())");编辑时保持原值不变。只有一种情况可以复制 GUID——直接替换拥有该 GUID 的工作流。
重命名 Input、添加输入参数,或更改输出参数结构签名由槽位定义。保持单个 Input: FootPrintWorkflow.<Slot>InputBaseWL,并使用槽位规定的精确输出参数(或 [])。不匹配时验证虽能通过,但调用会失败。
手动编写 Input/结果的接口使用 dxs configuration contexts footprintworkflow -D body.json 读取真实结构;引用 $types.FootPrintWorkflow.*。
在工作流中调用函数或使用 $dbAction 层规范:通过 $flows.<Pkg>.<action> 调用操作;将函数/$db 逻辑封装在操作后面;使用 fpds,不要使用云数据源。
在声明了 outParams 的槽位中使用裸 return;使用 return $flow.outParams; — 裸 return; 会破坏生成的正文;Validate 检测不到,但 Preview 可以发现。
将 get -O envelope.json 的输出直接传给 upsert -D先运行 jq .json envelope.json > body.json — 信封会覆盖内容并携带密钥。
对压缩后的 code 字符串直接查找替换使用 Python json.load/json.dump 编辑;使用 \r\n 拼接;绝不要调整周围的 JSON 结构。
在节点中内联复杂业务逻辑让节点只负责轻量调度到包操作;这样既符合库中的模式,也便于维护。
基于 PublishedMain 编写Main 的 readonly: true。请在已确认的功能分支上编写(绝不要猜测 id)。

编辑后,调用 post-edit-verification,以发现描述、JSON 或架构违规。最终审查时,调用 component-validator。

评论

支持 Markdown