mcpField
C
convert-ui5-to-fiori-elements

convert-ui5-to-fiori-elements

github.com/arc-mcp开发239236 次安装2 天前更新
代码仓库

关于 convert-ui5-to-fiori-elements

此工作流技能从旧版 UI5 JavaScript 应用提取界面特征,生成 Fiori Elements V4 注解及列表报表和对象页。适用于迁移到注解驱动界面的场景,并可用扩展实现模板无法表达的行为。

主要功能

  1. 01从旧应用特征推导 UI 注解
  2. 02将注解应用于 RAP 投影
  3. 03生成列表报表和对象页
  4. 04用扩展实现自定义行为
  5. 05查询 SAP 注解参考资料

适用场景

  1. 01将旧版 UI5 应用重建为 Fiori Elements V4
  2. 02复现旧界面的列、搜索、排序和操作

MCP 相关

该技能使用 SAP Fiori MCP server 生成 Fiori Elements 项目,并介绍使用 sap-docs MCP 查询注解模式。

安装

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

$npx skills add https://github.com/arc-mcp/arc-1 --skill convert-ui5-to-fiori-elements

安装后在 Claude Code 中输入/convert-ui5-to-fiori-elements确认已加载。

详细介绍

将旧版 UI5 JS 应用转换为 Fiori Elements V4(注解优先)

生成一个由 RAP CDS 投影上的 @UI.* 注解驱动的 Fiori Elements V4 列表报表 + 对象页面应用。后端注解根据旧版 UI5 应用的实际功能(列、搜索、排序、格式化程序、操作按钮、标签页结构)生成,使 FE 应用复现用户可见的功能约定。FE 模板无法表达的自定义行为通过扩展 API 接入。

此技能是 RAP 后端就绪后两条并行 UI 路径中的一条。如果目标架构是 Fiori Elements V4(注解驱动;自定义代码最少),请选择此路径。如果目标架构是自由式 TypeScript(自定义控制器、手动绑定),请改用 modernize-ui5-app.md。两条路径都从同一个旧版 JS 应用和同一个 V4 RAP 服务开始。

                  migrate-segw-to-rap.md  (backend: SEGW V2 → RAP V4)
                            │
              ┌─────────────┴─────────────┐
              ▼                           ▼
    modernize-ui5-app.md      convert-ui5-to-fiori-elements.md
        (freestyle TS)               (Fiori Elements V4)

此技能依赖于:

  • migrate-segw-to-rap.md 已生成一个可用的 V4 RAP 服务(CDS 根视图和投影、BDEF、SRVD、SRVB 已发布,且已在 /n/IWFND/MAINT_SERVICE 中注册 V4 路由组)。
  • 旧版应用(<source_app>/)仍可读取——第 1 阶段会梳理其功能,但不会修改旧版应用本身。

独立于 modernize-ui5-app.md。 此技能不要求现代 TS 应用已经存在。旧版应用是用户可见功能的唯一事实来源;FE 应用通过注解和扩展直接复现这些功能。

领域示例。 注解模板使用示例领域 Project → Tasks → TimeEntries。请在各处替换为用户的实体——LLM 会重写每个投影、实体和字段标识符,使其与 V4 服务相符。

规范注解参考。 此技能将 ABAP RAP Fiori Feature Showcase(SAP-samples/abap-platform-fiori-feature-showcase)作为 @UI.*、@ObjectModel.* 和 @Common.* 注解模式的权威来源。当不确定如何将旧版 UI 功能表示为注解时,请使用该功能的搜索词(例如 #OPHeaderAction、#LineItemHighlight、#HeaderInfo、#ActionInLineItem)通过 mcp__sap-docs__search 搜索 showcase。showcase 是本技能中每个注解所对应的权威目录。


使用 mcp__sap-docs__search 查找注解(请先阅读)

此技能在文中列出了一些规范注解模式。请将其视为起点,而非完整目录。 对于未明确涵盖的内容——其他可视化表示、动态功能控制、图表、值帮助、语义键、多级 OP 路由、草稿专属 UI 行为,或 7.58 特定语法问题——请先通过 mcp__sap-docs__search 查询,再做判断。该 MCP 会索引 SAP 维护的权威参考资料,提供最新的 showcase 标签,并包含特定版本的文档(758 新功能、云端差异等);本技能文本无法自行保持这些内容的时效性。

值得了解的标准库
库 ID内容
/abap-fiori-showcaseSAP-samples/abap-platform-fiori-feature-showcase — 本地部署的 RAP + FE V4 目录。每种模式都带有一个 Search Term 标签,例如 #HeaderInfo、#LineItemHighlight、#OPHeaderAction、#OPTable、#DataFieldForAction、#SemanticKey。这是此技能以 7.58 为准的基线。
/cap-fiori-showcaseSAP-samples/fiori-elements-feature-showcase — CAP/CDS V4 对应目录。包含 CAP 侧的相同概念模式;当 ABAP 展示库标签未包含所需变体时很有用,尤其是 FE 清单布局(layouts_ChildEntities*.cds、#Subpages、#InboundNav)。
/abap-docs-standard官方 ABAP 关键字文档(本地部署)。是语法(FOR BEHAVIOR OF、虚拟元素、投影 BDEF 规则)、特定版本功能(ABENNEWS-758-RESTFUL,用于确认 7.58 提供的功能)以及 RAP 构造深层理论的权威资料。
/abap-docs-cloud云/BTP 版的同类文档。遇到看似仅适用于云的内容时很有用 — 在用于本地部署的 7.58 之前,请先核实。
/sap-help(在线)SAP Help 全部内容。最适用于 SAPUI5 清单配置、FE 模板运行时细节和 配置内部导航。需要 includeOnline=true。
/abap-cheat-sheets包含当前语法变体的实用 RAP / ABAP 代码片段。
搜索方法 — 每个注解问题都按此操作
  1. 确认用户看到的内容:“带颜色标记的状态”、“点击行 → 子级详情页”、“使用固定值筛选”。
  2. 按主题标签搜索展示库 — 大多数模式都在 Markdown 中使用字面标签:
    mcp__sap-docs__search(query="#TagName")           // exact tag lookup
    mcp__sap-docs__search(query="<visual description>")  // semantic fallback
    
  3. 获取最相关结果的完整模式:
    mcp__sap-docs__fetch(id="/abap-fiori-showcase/<section>#<tag>")
    
  4. 适配用户的实体 — 展示库使用 /DMO/FSA_R_RootTP 等;请替换为用户的投影名称。
  5. 如果目标版本不接受本地部署模式,请换个方向重新搜索:
    • 搜索 /abap-docs-standard/ABENCDS_PROJ_VIEW_VIRTUAL_ELEMENT(以及示例 ABENCDS_PROJ_VIEW_VIRTEL_ABEXA),查找通过 ABAP 类计算的虚拟元素
    • 搜索 /abap-docs-standard/ABENNEWS-<release>-RESTFUL,查找特定版本的功能(例如 ABENNEWS-758-RESTFUL)
    • 搜索 /cap-fiori-showcase,查找相同概念的 CAP 替代表述
    • 如果 DDLS 投影不接受实体级注解,可将 DDLX annotate view 作为后备方案(Run 7 证据:7.58 通过 DDLX 处理 @UI.facet、@UI.selectionFields 和标头 FOR_ACTION)
入门标签指引(非穷尽,欢迎继续搜索)

可解析到展示示例中具体注解模式的搜索词参考。每项都是入口;请获取完整内容,以了解适用于你所用版本的规范语法。

需求起始搜索词 / 文档
列表行上的彩色状态 / 关键性#LineItemHighlight、criticality: 'CriticalityCode'、@UI.Criticality
带计算逻辑的关键性(非真实列)/abap-docs-standard/ABENCDS_PROJ_VIEW_VIRTUAL_ELEMENT;示例 ABENCDS_PROJ_VIEW_VIRTEL_ABEXA。另见 @ObjectModel.virtualElementCalculatedBy: 'ABAP:<class>'
标题数据点 / 状态指示器#HeaderFacet、#KeyValue、#DataPointProgress、@UI.dataPoint
子实体的对象页表格#OPTable、子投影上的 @UI.lineItem、含 type: #LINEITEM_REFERENCE 和 targetElement: '_AssocName' 的 @UI.facet
从一个对象页跳转到另一个对象页(例如 Project → Task → TimeEntry)#OPTable(入口);cap-fiori-showcase/app/listreport-objectpage/layouts_ChildEntities1.cds 等(子页面布局);SAPUI5 “Configuring Internal Navigation”(sap-help),了解清单路由结构
分面之间的页内导航#InboundNav、targetSections、@UI.facet 上的 navigation 属性
操作按钮 — 对象页标题#OPHeaderAction、type: #FOR_ACTION、DataFieldForAction
操作按钮 — 列表报告表格工具栏#ActionInLineItem、#WithAction
排序 + 筛选栏#SelectionFields、#PresentationVariant、@UI.selectionFields
跨字段搜索#Search、@Search.searchable、@Search.defaultSearchElement
语义键(在表格中突出显示 / 加粗)#SemanticKey、@ObjectModel.semanticKey
值帮助 / 固定值列表#ValueHelp、@Consumption.valueHelpDefault、@ObjectModel.text.element
动态 CRUD(按行状态隐藏 / 显示编辑 / 删除)#DynamicCRUD、@UI.updateHidden、@UI.deleteHidden、BDEF features: instance
草稿 + UI 细节#DraftHandling、@UI.lineItem 可编辑限定符、操作关键字 ( precheck )
副作用 / 操作后重新读取#SideEffects、@Common.SideEffects
BDEF 操作签名变体(预检查、工厂、复制)/abap-docs-standard/ABENBDL_ACTION、#OPCopyAction、action ( precheck ) <name>
7.58 功能边界/abap-docs-standard/ABENNEWS-758-RESTFUL + ABENNEWS-758-CDS_BDL
反模式
  • 不要把本技能中的示例代码奉为圭臬。 这只是一个特定时期编写的教学示例。展示示例才是事实依据。
  • 未经验证,不要直接套用其他版本的展示示例。 来自 BTP-Cloud 分支的 #DataFieldForAction 示例可能会使用仅适用于云端的关键字;对于 7.58,on-prem main 分支是安全的基准。
  • 查阅 SAPUI5 内部导航文档之前,不要手动编写 FE 路由 / 清单条目。 结构因模板和版本而异;从 sap-help 推导比根据运行时故障反向推理更容易。
  • 不要把首次激活失败的症状当作最终答案。 第 7 次运行中,一个润色项在四个不同层面遇到了四种不同的阻碍;每次只要再通过 mcp__sap-docs__search 搜索一次,就能在回滚之前找到替代方案。多搜一次只需 5 秒;不必要的回滚则要耗费 10 分钟以上。

为什么它是一项独立技能

Fiori Elements 并不是代码转换,而是删除 + 迁移。大部分自由样式应用都会被 FE 模板取代,这些模板会解析 CDS 注解。这项技能实际有三项工作:

  1. 根据旧版应用中用户可见的功能,推导出合适的 @UI.* 注解,让 FE 呈现等效的用户体验。
  2. 将这些注解应用到 RAP CDS 投影中(即 SRVB 暴露的服务)。
  3. 通过 SAP Fiori MCP 服务 (@sap-ux/fiori-mcp-server)生成 FE 列表报表 + 对象页项目,并为 FE 模板无法表达的内容接入扩展。

智能默认值(静默应用——研究前不要询问)

设置默认值原因
旧版应用<source_app>/自由样式 JS 应用——只读;在阶段 1 中用于提取功能清单。它是 FE 应用必须复现的所有用户可见行为的权威来源。
目标 FE 应用<fe_app>/——如果用户未提供路径,默认名称为 modern-fe-app/(遵循工作区模式 legacy-ui5-app/ → modern-ui5-app/ → modern-fe-app/)Fiori MCP 会在此处生成项目;该文件夹必须存在且为空(或仅包含空子文件夹)
FE 页面布局当 BO 具有明确的根节点和子节点分面时,使用列表报表 + 对象页(LROP V4)与典型的 RAP 组合根节点 + 子节点映射清晰。仅在用户明确要求时使用 OVP。
模板lropv4默认值,除非用户另有要求
生成器通过 list_functionalities → get_functionality_details → execute_functionality 调用 SAP Fiori MCP 服务(@sap-ux/fiori-mcp-server)SAP 官方工具;原生支持 FE V4 模式
应用命名空间<source_namespace>.fe便于区分旧版应用与 FE 应用(如果也运行了 modernize-ui5-app 作为替代路径,也能区分现代 TS 应用)
UI5 版本最新的 1.x 版本(例如 1.147.2),除非用户另行指定LTS 轨道;可用最新的 FE V4 功能
语言TypeScript现代默认选项;扩展文件使用类型安全的 API
OData V4 服务 URL优先使用系统 HTTPS 端口上的 SRVD 直连路径:https://<host>:<https-port>/sap/opu/odata4/sap/<srvb>/srvd/sap/<srvb>/0001(例如 https://a4h.marianzeis.de:50001/sap/opu/odata4/sap/zui_dm_projects_o4/srvd/sap/zui_dm_projects_o4/0001)。仅当 SRVD 直连不可达时,才回退到 Gateway 中心路径 http://<host>:<http-port>/sap/opu/odata4/sap/<srvb>/srvd_a2x/sap/<service>/0001。第 5 次和第 6 次运行已验证,在 7.5x 系统上,SRVD 直连路径无需通过 /n/IWFND/MAINT_SERVICE 注册即可工作。中心路径需要手动设置路由组。
主实体SRVB 暴露的根实体别名(例如 define root view entity ... alias <X> 中的别名)LR+OP 页面布局以单个实体为根
注解位置通过 SAPWrite update DDLS 在 CDS 中定义——不要放在 FE 应用的本地注解文件中注解属于服务;FE 应用通过 $metadata 读取注解。本地注解文件不适用于绑定 RAP 的应用。
扩展语言TypeScript(控制器扩展)与链路的其余部分保持一致
验证mcp__SAPUI5_MCP_Server__run_ui5_linter + run_manifest_validation + tsc --noEmit 全部通过硬性验收标准
验收标准FE 应用能够端到端地对接 V4 服务并运行。浏览器冒烟测试覆盖阶段 1 中清点的每项功能——通过注解或扩展钩子复现。明确的交付成果

输入

用户提供:

  • 用于挖掘功能的旧版应用路径(默认:<source_app>/)。只读。
  • FE 应用的路径 / 名称(默认:<fe_app>/)。
  • OData V4 服务 URL——从 migrate-segw-to-rap 的 SRVB 输出中获取。必填。
  • 根实体别名(例如:Project)。默认:从 SRVB 的 $metadata 推断。
  • 应用命名空间(默认:<source_namespace>.fe)。
  • 传输,用于写入 CDS 注解(默认:与 migrate-segw-to-rap 使用相同的传输,或通过 SAPTransport(action="create") 自动创建)。
  • UI5 版本(默认:最新的 1.x)。

如果只提供旧版应用路径和 V4 URL,则应用智能默认值,并在第 3 阶段向用户展示计划,等待用户确认 ok 后再进行任何写入。


阶段 0 — 预检

0a. RAP V4 服务处于运行状态且可绑定
SAPManage(action="probe")

断言 rap.available == true。

SAPRead(type="SRVB", name="<V4_SRVB>")

断言 SRVB 存在且处于激活状态。否则,停止并提示 "V4 服务绑定 <V4_SRVB> 缺失或未激活——请先运行 migrate-segw-to-rap.md。"

Bash: curl -s -o /tmp/svc_metadata.xml -w "%{http_code}\n" "<V4_service_URL>/\$metadata?sap-client=<client>"

断言返回 200 OK。先尝试 SRVD 直连路径(HTTPS 端口 + /srvd/sap/<srvb>/0001/)。

如果返回 403,且错误为 IWBEP/CM_V4_COS/136,则说明 URL 使用的是 Gateway 集线器路径,且路由组尚未注册。停止前切换到 SRVD 直连 URL 格式——直连路径可绕过集线器注册。只有两种 URL 格式都失败时,才回退到 "通过 /n/IWFND/MAINT_SERVICE 注册服务组"。

如果返回 503,且错误为 IWBEP/CM_V4_RUNTIME/000("服务别名缓存已过期"),则重试一次——这是暂时的 Gateway 缓存问题。如果重试后仍然存在,则按 403 处理并切换 URL 格式。

0b. CDS 投影可读写
SAPRead(type="DDLS", name="<root_projection>")

断言返回活动版本。否则,停止并提示 "缺少根投影——请重新运行 migrate-segw-to-rap.md 阶段 6 步骤 3。"

0c. 旧版应用存在且可读
Bash: ls <source_app>/webapp/controller/ <source_app>/webapp/view/

断言两个文件夹均已填充内容。如果任一文件夹缺失,则说明具体原因并停止——旧版应用是注解计划(阶段 1 + 2)和扩展列表(阶段 2b)的唯一事实来源。

0d. SAP Fiori MCP 服务可访问
mcp__fiori-mcp__list_functionalities

如果此调用失败,说明此聊天中未配置 Fiori MCP 服务。展示配置代码块并停止:

// .cursor/mcp.json (or equivalent)
{
  "mcpServers": {
    "fiori-mcp": {
      "type": "stdio",
      "timeout": 600,
      "command": "npx",
      "args": ["--yes", "@sap-ux/fiori-mcp-server@latest", "fiori-mcp"]
    }
  }
}

(来源:GitHub 上 @sap-ux/fiori-mcp-server 的 README。)

可选配套服务:用于生成后的 lint 检查和 manifest 验证的 mcp__SAPUI5_MCP_Server__*。

0e. Connection Manager(可选)

对于使用已保存的 BTP / 本地系统连接,而非直接服务 URL 的场景,Fiori MCP 服务依赖 SAP Systems Connection Manager VS Code 扩展。对于此技能使用的直连 URL 流程,该扩展并非必需——服务 URL 会直接传递给 execute_functionality。


阶段 1 — 清点旧版应用中用户可见的功能

这是注解计划的核心。FE 应用必须复现旧版应用中所有用户可见的行为。读取所有相关旧版文件,并生成一份功能清单。

1a. 读取旧版 manifest
Read: <source_app>/webapp/manifest.json

提取:sap.ui5.routing.routes(用户可访问的 URL)、sap.ui5.rootView、sap.app.dataSources、i18n。路由可帮助你了解导航树;数据源则会告诉你旧版应用预期的服务结构。

1b. 阅读每个旧版视图
Bash: ls <source_app>/webapp/view/
Read: <source_app>/webapp/view/<each>.view.xml

对于每个视图,盘点:

  • 页面标题(来自 <Page title=...>)。
  • 页眉内容 — 按钮及其条件(例如 enabled="{= ${Status} === 'D'}")。
  • 列表/表格列 — 每个 <Column> 的绑定字段、排序方向和对齐方式。
  • 搜索字段 — 带有 liveChange 和 placeholder 的 <SearchField>。
  • 默认排序 — 列表绑定上的 sorter 子句(路径 + 升序/降序)。
  • 条目结构 — ObjectListItem/ColumnListItem/ObjectHeader 及其属性、状态字段和格式化器调用。
  • 标签页结构 — IconTabBar + IconTabFilter 条目(哪些实体以标签页形式展示、每个标签页是否有计数器)。
  • 导航处理器 — press/selectionChange 回调(点击行 → 导航)。
  • 计数器、页脚 — 信息性组件(条目数、总计)。
1c. 阅读每个旧版控制器
Bash: ls <source_app>/webapp/controller/
Read: <source_app>/webapp/controller/<each>.controller.js

对于每个控制器,盘点:

  • 操作处理器 — 每个 on<Action> 方法执行什么操作?(调用 OData 函数导入?筛选?重新绑定?显示 MessageBox?)
  • 筛选/搜索逻辑 — 使用哪些字段、FilterOperator 和绑定路径?
  • 函数导入调用 — oModel.callFunction(...) 调用及其参数结构。
  • 自定义验证 — 函数导入/提交前的检查。
  • 自定义导航 — 任何绕过 manifest 路由器的操作。
  • 自定义客户端状态 — 为纯 UI 状态创建的 JSONModels(例如从非 OData 来源获取的标签页计数器)。
1d. 阅读每个旧版格式化器
Read: <source_app>/webapp/model/formatter.js

对于每个格式化器函数,盘点:

  • 格式化内容 — 状态代码 → 文本、状态代码 → 语义状态(Success/Warning/Error)、日期 → 短格式、小时 → 小数等。
  • 代码→文本映射 — 记录确切的值(例如 D → "Draft"、A → "Active"、C → "Closed")。

这些可直接映射到 CDS 注解模式 — @Common.Text + @UI.TextArrangement、@UI.Criticality、值帮助集合等。

1e. 构建功能清单

向用户输出结构化清单:

Feature inventory — <source_app>:

ROOT ENTITY (Project):
  Display name (header):    Title
  Description (sub):        ProjectId
  Status (criticality):     Status field — values D=Draft (Warning) / A=Active (Success) / C=Closed (Neutral)
  Sort default:             StartDate descending
  Search (master):          ProjectId, Title (Contains, OR-joined)
  Audit fields:             Erdat (Created), Ernam (Created by), Aedat (Changed), Aenam (Changed by)
  Header button:            Approve — enabled when Status == 'D', calls /ApproveProject(ProjectId)
  Count footer:             "<n> projects" displayed below the list

CHILD ENTITY (Task):
  Tab in detail:            "Tasks"
  Counter:                  from binding length
  Columns:                  TaskId, Title+Description, Status, Priority, DueDate, AssignedTo, EstimatedHours
  Status criticality:       Status: D/IP/D/C (Draft/InProgress/Done/Cancelled) — see formatter
  Priority criticality:     L/M/H (Low/Medium/High) — see formatter
  Click behavior:           Selecting a task populates the TimeEntries tab

CHILD-OF-CHILD ENTITY (TimeEntry):
  Tab in detail:            "Time Entries"
  Counter:                  from selected task's TimeEntries length
  Columns:                  EntryId, TaskId, WorkDate, WorkHours, Description, Username

FORMATTERS:
  statusText:       D → "Draft", A → "Active", C → "Closed"
  statusState:      D → Warning, A → Success, C → Neutral
  taskStatusText:   D → "Draft", IP → "In Progress", DN → "Done", CN → "Cancelled"
  taskStatusState:  same scheme
  priorityText:     L → "Low", M → "Medium", H → "High"
  priorityState:    L → Neutral, M → Warning, H → Error
  dateShort:        custom YYYY-MM-DD
  hoursDecimal:     two decimal places

FUNCTION IMPORT (V2):
  ApproveProject(ProjectId) → translates to RAP action approve_project (already in BDEF)

此清单是第 2 阶段的约定。


第 2 阶段 — 将功能映射到注解和扩展

将清单中的每项归类为以下类别之一:

  • STANDARD — FE 模板可原生呈现(分页、行点击导航、按键搜索、基本编辑、基本创建、基本删除、草稿支持)。
  • ANNOTATION — 需要在 CDS 投影上使用特定的 @UI.*/@Common.*/@ObjectModel.* 注解。大多数旧版功能都归入此类。
  • EXTENSION — FE 模板无法表达的真正自定义行为;需要在 FE 应用端使用控制器扩展。
2a. 注解对照表——入门参考(通过 sap-docs 验证各模式)

下表是速查参考,并非权威目录。请按照上文“使用 mcp__sap-docs__search”一节中的搜索步骤,确认适用于你所用版本的当前规范语法,尤其是以下标记为 ⚠ 的内容。

旧版功能入门注解 + 示例标签
标题 = Title@UI.HeaderInfo.title.value: 'Title' — #HeaderInfo
标题描述 = ProjectId@UI.HeaderInfo.description.value: 'ProjectId' — #HeaderInfo
标题类型标签@UI.HeaderInfo.typeName: 'Project', typeNamePlural: 'Projects' — #HeaderInfo
列表列(主列表)每个字段使用 @UI.lineItem: [{ position: N, importance: #HIGH }] — 含关键性属性的变体请参见 #LineItemHighlight
⚠ 状态代码 → 文本 + 颜色有多种有效模式,请根据版本和草稿限制选择。 搜索 #LineItemHighlight,查找通过实际列设置关键性的路径。若要在没有持久化列的情况下计算关键性,请参见 /abap-docs-standard/ABENCDS_PROJ_VIEW_VIRTUAL_ELEMENT + @ObjectModel.virtualElementCalculatedBy: 'ABAP:<class>'。在 7.58 + 草稿场景中,两种方式都存在已知限制(Run 7 §1 中有详细说明)。采用前请先搜索。
默认排序@UI.presentationVariant.sortOrder: [{ by: '<field>', direction: #DESC }] — #PresentationVariant
跨字段搜索在视图级别设置 @Search.searchable: true,并对每个字段设置 @Search.defaultSearchElement: true — #Search
筛选栏@UI.selectionFields: [...] — #SelectionFields
审计字段显示@UI.fieldGroup + #FIELDGROUP_REFERENCE 的 @UI.facet — #HeaderFieldGroup
批准按钮(标题栏)@UI.identification: [{ type: #FOR_ACTION, dataAction: 'approve_project', label: 'Approve', criticality: 3, criticalityRepresentation: #WITH_ICON }] — #OPHeaderAction。该操作不会根据 BDEF 自动呈现。 投影 BDEF 必须已公开 use action approve_project;。
LR 工具栏操作在 @UI.lineItem 上使用相同形式 — #ActionInLineItem、#WithAction
子实体的 OP 表格在父实体上设置 @UI.facet: [{ type: #LINEITEM_REFERENCE, targetElement: '_AssocName', label: '...' }],并在子投影上设置 @UI.lineItem — #OPTable
⚠ 多级导航(Project → Task → TimeEntry)有两种有效形式——选择前先调研。(a) 从根投影引用 _Tasks._TimeEntries 的嵌套 LineItem facet(取决于版本的 FE 支持情况)。(b) 单独的 Task OP 路由——为 ZC_DM_TASK 添加 @UI.headerInfo 和其自身的 _TimeEntries facet,然后在 FE 应用的 manifest 中添加 Task 路由目标。请搜索 #OPTable、#Subpages、#InboundNav(cap-fiori-showcase);另请参阅 SAPUI5(sap-help)中的 “Configuring Internal Navigation”,了解 manifest 路由形式。
语义键加粗显示@ObjectModel.semanticKey: ['ProjectId'] — #SemanticKey
动态 CRUD(根据行状态隐藏按钮)将 @UI.updateHidden + @UI.deleteHidden 绑定到字段 — #DynamicCRUD

7.58 上 DDLS 与 DDLX 的适用范围。 在 Run 7 中,若干实体级注解 (@UI.facet、@UI.selectionFields、通过 @UI.identification 设置的标题栏 FOR_ACTION)在投影 DDLS 中 会报错,但移至 DDLX 元数据扩展(annotate view <ZC_*> with @UI.facet: [...] 等)后则可成功。如果 DDLS 实体级注解报错,提示“wrong scope” / “unknown”,请改用 DDLX。 请通过 /abap-fiori-showcase 中对应的 #Tag 确认——在需要支持本地部署版本的地方,示例模式已 分别放在 DDLS 和 DDLX 中。

2b. 扩展映射(典型情况)
旧功能扩展挂钩
Approve 上的 Status === 'D' 守卫FE 的 BDEF 操作按钮会根据 BDEF 的 precheck 启用。如果旧应用的启用规则与 BDEF 不同,请在 BDEF 上添加 precheck(步骤 2c),而不是在 JS 中覆盖。
Approve 前的自定义验证(例如要求填写 Description)ObjectPage 上的 editFlow.onBeforeAction 控制器扩展
自定义客户端计数页脚措辞跳过 — FE 列表报表会显示原生计数
自定义导航模式几乎不需要;FE 的行 → OP 导航是默认行为
审批失败时显示 MessageBoxFE 原生错误提示已会处理此情况
2c. BDEF 侧准备(在 2b 之后、Phase 4 之前运行)

如果清单中发现类似“仅当 Status === 'D' 时才显示 Approve 按钮”的守卫,这属于 前置条件,而非 UI 关注点。请在 BDEF 侧通过操作的 precheck 子句对其进行编码,然后重新激活。(此步骤属于 migrate-segw-to-rap.md 的步骤 5,但当旧守卫尚未迁移时,请在此处明确指出。)示例:

action approve_project precheck result [1] $self;

在行为池中使用 precheck 方法填充 %cid / %key,并断言 Status == 'D'。如有需要,技能会将实际的 precheck 方法体交由 edit_method 处理。


Phase 3 — 制定计划并获得用户批准

请按以下确切格式打印计划,然后暂停,等待用户回复 ok / edit / 提问:

Plan — generate FE app at <fe_app>:

Floorplan:           List Report + Object Page (LROP V4)
Namespace:           <source_namespace>.fe
UI5 version:         <user-provided, default latest 1.x>
V4 service:          <V4_service_URL>
Main entity:         <root_alias> (alias on the root projection)
Generator:           SAP Fiori MCP server (@sap-ux/fiori-mcp-server)

Backend annotation writes (via SAPWrite update DDLS on the projection):
  <root_projection>:
    @UI.HeaderInfo, @UI.SelectionFields, @UI.LineItem (root columns),
    @UI.Identification, @UI.PresentationVariant.SortOrder,
    @UI.FieldGroup.Audit, @UI.Facet (Identification + Tasks)
    @Common.Text + virtual <field>Criticality (Status)

  <child_projection_task>:
    @UI.LineItem (Task columns), @UI.HeaderInfo,
    @UI.Facet (Task identification + TimeEntries),
    @Common.Text + virtual fields for Status, Priority

  <child_projection_timeentry>:
    @UI.LineItem (TimeEntry columns), @UI.HeaderInfo

BDEF-side adjustments (via SAPWrite update BDEF / edit_method):
  <list precheck additions, if any>

FE app generation (via Fiori MCP):
  Step 1: list_functionalities      → enumerate supported FE app creations
  Step 2: get_functionality_details → "create FE V4 list-report+OP for external OData service"
  Step 3: execute_functionality     → pass service URL, root entity, namespace, target folder

Extension scaffold (post-generation):
  - <controller-extension list per Phase 2b>

Validation:
  - ui5-linter clean
  - manifest validation clean
  - tsc --noEmit clean
  - browser smoke against every Phase 1 inventory item

Type `ok` to proceed, `edit` to revise, or ask any question.

在获得 ok 之前,请勿修改 SAP 系统中的任何内容,也不要生成 FE 应用。


Phase 4 — 将 @UI.* 注解写入 CDS 投影(后端准备)

这一步是“在后端准备注解”。请在调用 Fiori MCP 生成器之前完成所有 CDS 写入——生成器会读取带注解的 $metadata,因此运行生成器前,注解必须处于激活状态,且 SRVB 必须已重新发布。

4a. 为根投影添加注解
SAPRead(type="DDLS", name="<root_projection>")

插入规划好的注解。具体形式如下(替换为你的实体):

@Metadata.allowExtensions: true

@UI.headerInfo: {
  typeName:       'Project',
  typeNamePlural: 'Projects',
  title:          { value: 'Title' },
  description:    { value: 'ProjectId' }
}
@UI.selectionFields: [ 'ProjectId', 'Title', 'Status' ]
@UI.presentationVariant: [{
  qualifier: 'DefaultSort',
  sortOrder: [{ by: 'StartDate', direction: #DESC }]
}]
@UI.facet: [
  { id: 'GeneralInfo',  purpose: #STANDARD, type: #IDENTIFICATION_REFERENCE, label: 'General' },
  { id: 'AuditInfo',    purpose: #STANDARD, type: #FIELDGROUP_REFERENCE, label: 'Audit',
    targetQualifier: 'Audit' },
  { id: 'Tasks',        purpose: #STANDARD, type: #LINEITEM_REFERENCE, label: 'Tasks',
    targetElement: '_Tasks' }
]
// Header action — renders as an "Approve" button on the OP header (showcase #OPHeaderAction).
// criticality 3 = green (success), 0 = neutral, 1 = red.
@UI.identification: [
  { type: #FOR_ACTION,
    dataAction: 'approve_project',
    label: 'Approve',
    criticality: 3,
    criticalityRepresentation: #WITH_ICON }
]
@Search.searchable: true
define root view entity <root_projection>
  provider contract transactional_query
  as projection on <root_view>
{
  key   @UI.lineItem:       [{ position: 10, importance: #HIGH }]
        @UI.identification: [{ position: 10 }]
        @UI.selectionField: [{ position: 10 }]
        @Search.defaultSearchElement: true
        ProjectId,

        @UI.lineItem:       [{ position: 20, importance: #HIGH }]
        @UI.identification: [{ position: 20 }]
        @UI.selectionField: [{ position: 20 }]
        @Search.defaultSearchElement: true
        Title,

        @UI.lineItem:       [{ position: 30, criticality: 'StatusCriticality' }]
        @UI.identification: [{ position: 30 }]
        @UI.selectionField: [{ position: 30 }]
        Status,

        @UI.lineItem:       [{ position: 40 }]
        @UI.identification: [{ position: 40 }]
        StartDate,

        @UI.lineItem:       [{ position: 50 }]
        @UI.identification: [{ position: 50 }]
        EndDate,

        @UI.identification: [{ position: 60 }]
        Description,

        @UI.fieldGroup: [{ qualifier: 'Audit', position: 10, label: 'Created at' }]
        Erdat,
        @UI.fieldGroup: [{ qualifier: 'Audit', position: 20, label: 'Created by' }]
        Ernam,
        @UI.fieldGroup: [{ qualifier: 'Audit', position: 30, label: 'Changed at' }]
        Aedat,
        @UI.fieldGroup: [{ qualifier: 'Audit', position: 40, label: 'Changed by' }]
        Aenam,

        // virtual criticality field (computed from Status code)
        @ObjectModel.virtualElementCalculatedBy: 'ABAP:<root_class>'  // OR via case-when below
        virtual StatusCriticality : abap.int1,

        /* associations */
        _Tasks
}

对于虚拟关键性,跨 7.58 版本兼容性最简单的选项是在投影中直接使用 case-when:

case Status
  when 'D' then 2    // Critical (Warning)
  when 'A' then 3    // Positive (Success)
  when 'C' then 0    // Neutral
  else          0
end as StatusCriticality,

写入插入后的源代码:

SAPWrite(action="update", type="DDLS", name="<root_projection>",
         source="<spliced source>", transport="<transport>")
SAPActivate(type="DDLS", name="<root_projection>")
4b. 为每个子投影添加注解

对每个 <child_projection_X> 重复此模式。每个子项都需要:

  • @UI.headerInfo(标题/描述)
  • 为旧视图显示的每一列添加 @UI.lineItem
  • 如果该子项还有子项,则添加 @UI.facet(例如 Task 下的 _TimeEntries)
  • 为清单中列出的任何带颜色代码字段添加虚拟关键性字段
4c. 发布 SRVB

需要重新发布 SRVB,才能在 $metadata 中显示新增注解:

SAPWrite(action="publish_srvb", name="<V4_SRVB>")
4d. 验证注解是否写入 $metadata
Bash: curl -s "<base>/<V4_service_URL>/$metadata" | grep -oE 'UI\.(LineItem|HeaderInfo|Facets|SelectionFields|PresentationVariant|FieldGroup|Identification)' | sort -u

预期输出:你编写的每种注解都应出现在列表中。如果列表为空,说明 SRVB 未获取到更改——请重新运行 publish_srvb。如果只显示部分注解,说明投影未能正确重新激活——请运行 SAPDiagnose(action="object_state", type="DDLS", name="<root_projection>") 进行检查。


第 5 阶段 — 通过 SAP Fiori MCP 服务生成 FE 应用

这是“使用 Fiori MCP 创建应用”这一步。Fiori MCP 服务提供了一套由三个工具组成的流程——list_functionalities → get_functionality_details → execute_functionality。 每一步都会缩小范围。即使你认为自己知道参数,也不要跳过任何步骤。

参考:

编写此技能时,Fiori MCP 服务仍处于实验性阶段。工具签名可能会发生变化。如果 list_functionalities 返回的结构与预期不同,请遵循实时响应——以上 README 是权威信息来源。

5a. 了解服务的功能
mcp__fiori-mcp__list_functionalities

检查响应,寻找与“为外部 OData V4 服务创建新的 Fiori elements 应用”匹配的功能。响应中的确切名称取决于服务版本——查找 create、fiori-elements、list-report、lropv4、external-service 等关键词。

如果服务没有匹配的功能:

  • 它可能需要 CAP 项目。在这种情况下,请通过旧版备用方案生成(@sap/generator-fiori CLI——见 5d),并将这一缺口记录为下一次迭代的运行记录。
  • 或者,用户的 Fiori MCP 版本可能比预期的旧。再次运行以下命令进行检查:
    Bash: npx --yes @sap-ux/fiori-mcp-server@latest --version
    
    并指导用户更新 MCP 配置,以固定到最新版本。
5b. 获取所选功能的参数要求
mcp__fiori-mcp__get_functionality_details(name="<the-functionality-name-from-5a>")

响应会列出必需参数和可选参数。对于面向外部服务的 LROP 流程,典型的必需参数包括:

  • serviceUrl — <V4_service_URL>(第 0a 阶段中由 $metadata 支持的端点)
  • mainEntity 或 entitySet — SRVB 中的根实体别名(例如 Project)
  • targetPath — <fe_app>/(用于生成应用的文件夹)
  • namespace — <source_namespace>.fe
  • appId / appName — 应用标识符
  • ui5Version — 用户提供(默认值:最新的 1.x)
  • language — typescript

将用户提供的输入映射到必需参数。如果某个必需参数没有对应值,请停止并询问用户。不要编造值。

5c. 执行生成器
mcp__fiori-mcp__execute_functionality(
  name="<the-functionality-name-from-5a>",
  parameters={
    serviceUrl: "<V4_service_URL>",
    mainEntity: "<root_alias>",
    targetPath: "<fe_app>",
    namespace:  "<source_namespace>.fe",
    appName:    "<short-app-id>",
    ui5Version: "<ui5-version>",
    language:   "typescript"
  }
)

等待生成器完成。验证目录结构:

Bash: ls <fe_app>/webapp/ && cat <fe_app>/webapp/manifest.json | head -40

预期内容:

  • webapp/Component.ts
  • webapp/manifest.json,其中包含 sap.ui.generic.app / sap.fe.templates 配置
  • webapp/i18n/i18n.properties
  • webapp/ext/(扩展文件夹,可能为空)
  • package.json / ui5.yaml / tsconfig.json
5d. MCP 服务无法完成生成时的备用方案

如果 list_functionalities 没有提供外部服务路径,请改用 @sap/generator-fiori CLI:

Bash: cd <workspace> && npx --yes @sap/generator-fiori --no-deploy

依次完成提示步骤(或使用明确的参数传入 --skip-install)。MCP 服务封装的正是这个生成器——由于需要交互操作,速度较慢,但始终可用。

5e. 已知的 Fiori MCP 问题(跟踪上游进展)

Fiori MCP 服务处于实验阶段。请注意以下两个已知问题,并采取相应的规避措施:

  • 当 @sap-ux/store 中没有目标系统的条目时,fetch-service-metadata 会返回 MCP 框架错误,而不是结构化响应。规避方法:自行使用 curl $metadata 将元数据下载到本地文件(例如 <fe_app>/metadata.xml),然后让 execute_functionality 使用该文件。上游跟踪: SAP/open-ux-tools#4652 — 此问题关闭后,即可不再使用 curl 规避方法。
  • fetch-service-metadata 要求配置 Connection Manager,才能使用已存储的系统条目;将 URL 直接传给 execute_functionality 则可绕过这一要求。技能的 Phase 0e 已说明直接使用 URL 的方式。

请将任何新发现的问题记录在 RUN-NOTES.md 中,以便下一轮迭代能够采取规避措施,或向上游提交后续问题。


Phase 6 — 为 Phase 2b 中的 EXTENSION 列表配置扩展

对于 Phase 2b 扩展映射中的每一行,搭建一个 TS 控制器扩展。FE V4 扩展有两种形式:

  • 控制器扩展 — 通过 editFlow / routing / appComponent API 扩展 LR 或 OP 控制器。
  • 扩展点 — 在指定位置(页眉、页脚、某个分区之前或之后)插入自定义 XML/Fragment。

对于演示中常见的扩展(审批前进行 BDEF 尚未实现的预检查):

Write: <fe_app>/webapp/ext/ObjectPageExt.ts
import ControllerExtension from "sap/ui/core/mvc/ControllerExtension";
import MessageBox from "sap/m/MessageBox";

/**
 * @namespace <source_namespace>.fe.ext
 */
export default class ObjectPageExt extends ControllerExtension {
  public static overrides = {
    editFlow: {
      onBeforeAction: async function (
        this: ObjectPageExt,
        mParameters: { actionName: string; context: any }
      ) {
        if (!mParameters.actionName.endsWith(".approve_project")) return;
        const description = mParameters.context.getProperty("Description");
        if (!description) {
          MessageBox.error("Cannot approve a project without a description.");
          throw new Error("Approval blocked by extension");
        }
      }
    }
  };
}

在 <fe_app>/webapp/manifest.json 中注册扩展:

"sap.ui5": {
  "extends": {
    "extensions": {
      "sap.ui.controllerExtensions": {
        "sap.fe.templates.ObjectPage.ObjectPageController": {
          "controllerName": "<source_namespace>.fe.ext.ObjectPageExt"
        }
      }
    }
  }
}

每搭建一个扩展后,都运行一次代码检查工具:

mcp__SAPUI5_MCP_Server__run_ui5_linter(files=["<fe_app>/webapp/ext/ObjectPageExt.ts"])

对扩展映射中的每个条目重复以上步骤。扩展应保持精简——每个类只处理一项职责。

如果功能分类不明确(注解?扩展?),请使用 Fiori MCP 的文档搜索功能进行确认:

mcp__fiori-mcp__search_docs(query="custom validation before action Fiori elements V4")

这会获取 SAP 的权威指导,避免凭空推测。


Phase 7 — 验证与冒烟测试

7a. 静态检查
mcp__SAPUI5_MCP_Server__run_ui5_linter
mcp__SAPUI5_MCP_Server__run_manifest_validation
Bash: cd <fe_app> && npx tsc --noEmit

这三项检查都必须通过。

7b. 开发服务器

在空闲端口上重启开发服务器(默认端口为 8082;如果旧应用的开发服务器或其他正在运行的工具已占用该端口,请选择其他端口):

Bash: cd <fe_app> && pkill -f "ui5 serve" ; (npm start -- --port 8082 &)

等待约 5 秒,让服务器启动。检查入口点:

Bash: curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8082/index.html
7c. 对照 Phase 1 清单进行浏览器冒烟测试

在浏览器中打开 http://localhost:8082,验证 Phase 1 清单中的每一项。验收标准:FE 应用通过注解或扩展,复现旧应用中所有用户可见的功能。

参考检查清单(根据用户的清单调整):

  1. 列表报表能够渲染,且列顺序与 @UI.LineItem 中的定义一致。
  2. 筛选栏显示 @UI.SelectionFields 中的字段。
  3. 搜索可在标记为 @Search.defaultSearchElement 的字段上正常工作。
  4. 默认排序与 @UI.PresentationVariant.SortOrder 一致。
  5. 单击行会打开 OP。
  6. OP 页眉显示来自 @UI.HeaderInfo 的正确标题和说明。
  7. 行中的状态字段显示正确的颜色(criticality)。
  8. 选项卡/切面会渲染每个由 @UI.Facet 引用的关联。
  9. 嵌套切面可以逐级查看孙级实体(例如 Tasks 下的 TimeEntries)。
  10. 操作按钮会针对 BDEF 操作进行渲染(来自 @UI.identification DataFieldForAction);单击后会通过框架的标准 CSRF/etag 流程执行,无需扩展即可完成往返操作。
  11. 对于 Phase 2b 中列出的情况,扩展钩子会触发(验证、自定义提示词)。
  12. 审计字段会显示在 OP 的审计切面中。
  13. 列表报表页眉中的原生 FE 计数与旧应用页脚的表述相符(允许存在“X 个项目”与“正在显示 X 个,共 Y 个”之间的用户体验差异)。
7c.1 — V4 草稿场景的实际情况(已在 Run 6 中验证)

在草稿场景下,V4 服务会将 IsActiveEntity 作为每个实体键的一部分公开。 这会对测试产生两种影响:

  • 带键读取必须包含 IsActiveEntity:Project(ProjectId='PRJ-0001',IsActiveEntity=true) 返回 200;旧式的 Project('PRJ-0001') 返回 400。
  • 调用操作需要完整的 CSRF 流程:先通过 X-CSRF-Token: Fetch 获取 <service-root>/?sap-client=<n> → 再使用返回的 X-CSRF-Token、会话 Cookie 和 If-Match: <etag> POST 到操作 URL。省略 If-Match 会返回 428(CX_OD_PRECOND_REQUIRED)。

任何 V4 + 草稿服务都会有这些正常行为;FE 模板会在运行时自动处理。这里的说明仅供手动执行 curl 冒烟测试时参考。

如果任何步骤失败:

  • 对于注解问题,返回 Phase 4 并调整 CDS,重新激活,执行 publish_srvb, 然后重新运行冒烟测试步骤。
  • 对于扩展问题,通过浏览器 DevTools 调试控制器扩展。
  • 对于看起来像工具错误的 FE 渲染问题,运行 mcp__fiori-mcp__search_docs(query="<exact symptom>") 查找权威参考。
7d. 最终报告
Fiori Elements conversion complete — <fe_app>

Floorplan:        LROP V4 (TS)
UI5:              <version>
V4 service:       <V4_service_URL>
Annotations:      <n> @UI.* annotations written across <m> projections
Extensions:       <n> controller extensions
Linter:           clean
Manifest:         clean
TypeCheck:        clean
Browser smoke:    <12+/12+> inventory items reproduced

What just happened (3 sentences):
  - Mined the legacy app's user-visible feature set (columns, sort, search, actions,
    tab structure, formatters).
  - Wrote the equivalent @UI.* / @Common.* / @Search.* annotations onto the RAP CDS
    projections via ARC-1.
  - Generated the FE app on top of the now-annotated $metadata via the SAP Fiori MCP
    server, with extension hooks for the few cases FE templates can't express natively.

ARC-1 calls used:
  - SAPManage(action=probe)
  - SAPRead(type=DDLS, name=<root_projection>)
  - SAPRead(type=SRVB, name=<V4_SRVB>)
  - SAPWrite(action=update, type=DDLS, ...) × <m> projections
  - SAPActivate(type=DDLS, ...)
  - SAPWrite(action=publish_srvb, name=<V4_SRVB>)
  - (Optional) SAPWrite(action=update, type=BDEF, ...) + SAPActivate for BDEF precheck

Fiori MCP calls used:
  - mcp__fiori-mcp__list_functionalities
  - mcp__fiori-mcp__get_functionality_details(name=<chosen>)
  - mcp__fiori-mcp__execute_functionality(...)
  - mcp__fiori-mcp__search_docs(...) × <n> (during extension scaffolding)

UI5 MCP calls used:
  - mcp__SAPUI5_MCP_Server__run_ui5_linter × <n>
  - mcp__SAPUI5_MCP_Server__run_manifest_validation

错误处理 — 已知情况

症状原因修复方法
SAPWrite update DDLS 后,$metadata 中没有注解DDLS 已重新激活,但 SRVB 未重新发布SAPWrite(action="publish_srvb", name="<V4_SRVB>")
mcp__fiori-mcp__list_functionalities 返回空结果 / 失败服务未注册,或 npx 缓存已过时检查 .cursor/mcp.json;在新的 Shell 中,npx --yes @sap-ux/fiori-mcp-server@latest fiori-mcp 应输出服务就绪日志
生成器因“service unreachable”而失败由于 V4 路由组限制,<V4_service_URL> 被 403 拒绝访问按照 migrate-segw-to-rap.md Phase 6,执行 /n/IWFND/MAINT_SERVICE 手动步骤
生成器成功,但 FE 应用显示空白外壳传入的 mainEntity 没有关联带注解的 CDS重新检查 Phase 4——@UI.Facet 链中的每个实体都至少需要 @UI.LineItem,且(对于 OP 根实体)需要 @UI.HeaderInfo
列表报表没有显示列@UI.LineItem 注解位于根视图,而非投影中将注解移到投影中;FE 会从 SRVB 公开的投影中读取注解
操作按钮不可见操作未在投影 BDEF 上公开,或投影 BDEF 缺少 use action approve_project检查投影 BDEF(define behavior for <root_projection> { ... use action approve_project; })并重新发布
筛选栏为空缺少 @UI.SelectionFields 注解,或其指向的字段在视图级别未标记为 @Search.searchable在视图级别添加 @Search.searchable: true,并在正确的字段上添加 @Search.defaultSearchElement: true
状态字段没有颜色未绑定重要性在 @UI.LineItem 条目中添加 criticality: '<field>Criticality' 引用,并添加一个虚拟的 <field>Criticality 投影字段,将代码映射到 FE 重要性(0=中性,1=负面,2=关键,3=正面)
未渲染嵌套区段(Tasks 下的 TimeEntries)某些 7.5x 版本不支持 _Tasks._TimeEntries LineItem 区段路径如果必须使用,将 TimeEntries 渲染为单独的 OP——从 Task LineItem 进入;请在用户使用的版本上验证
控制器扩展抛出“Override target not found”manifest 中的控制器路径错误LR:sap.fe.templates.ListReport.ListReportController;OP:sap.fe.templates.ObjectPage.ObjectPageController
MCP server timed out缓慢的 $metadata 获取阻塞了长时间运行的 execute_functionality增大 .cursor/mcp.json 中的 MCP timeout(目前为 600s);对于 talk-demo 的服务规模,默认值通常已足够
生成器停在确认提示上MCP 服务尝试以交互方式确认覆盖操作重新运行前预先删除 <fe_app>/,或在 functionality details 中列出该选项时传入 overwrite: true

此技能明确不涵盖的内容

  • 多楼层平面图组合(Overview Page + LRO + ALP)。单个 LRO+OP 是演示的范围。组合功能将在后续实现。
  • 确实无法用 FE 构建块实现的复杂自定义渲染。如果用户有此需求,应改用自由形式路径(modernize-ui5-app.md)。
  • 模拟/本地服务模式。 此技能面向实时 V4 RAP 服务。Fiori MCP 可以为 CAP 项目生成应用,但那是另一种流程。
  • 授权策略。 FE 按照服务授权内容进行渲染。PFCG / S_DEVELOP 的更改发生在 SAP 端,与此技能无关。
  • 超出 CDS @EndUserText.label 所提供内容的翻译/本地化。 FE 从服务元数据中读取标签;其他 i18n 内容存放在 FE 应用的 i18n 文件中。
  • CAP 端生成。 此技能假设后端使用 RAP;对于仅使用 CAP 的流程,请直接使用 Fiori MCP 服务面向 CAP 的提示词。

使用此技能的 LLM 注意事项

  • 注解优先是此技能的核心原则。绝不要让 FE 生成器针对未添加注解的 $metadata 运行——结果只会是一个无用的空壳。
  • Fiori MCP 服务仍处于实验阶段。自编写此技能以来,工具名称和参数结构可能已有变化。始终先调用 list_functionalities,再据此调整。
  • 注解应放在投影上,而不是根视图上。SRVB 暴露的是投影;FE 从那里读取数据。
  • 每次 CDS 更改影响已暴露的注解后,都要重新发布 SRVB。ADT 不会自动执行此操作。
  • “分面引用关联”模式最棘手:只有当 _Tasks 是投影上已暴露的关联时,类型为 #LINEITEM_REFERENCE 且 targetElement: '_Tasks' 的分面才有效。请检查投影中的 use association _Tasks { ... } 块。
  • 控制器扩展是应急手段——不确定某项功能是否需要扩展时,请询问用户。FE 模板能表达的内容比很多人预想的更多;只有在确实必要时才升级处理。
  • 在猜测注解语法之前,请先查阅 mcp__fiori-mcp__search_docs(或使用 topic="fiori-elements" 调用 mcp__sap-docs__search)。SAP 的注解参考文档是权威来源。
  • 如果 mcp__fiori-mcp__list_functionalities 返回了意料之外的能力(例如“向现有应用添加页面”“修改 manifest”),请在计划中说明——它们可能简化第 6 阶段的扩展工作。
  • 如果 Fiori MCP 可以通过 execute_functionality 添加页面或更改路由,不要手动编辑 manifest.json。MCP 的编辑能识别架构,并且在重新生成后仍会保留;手动编辑则可能被覆盖。

资料来源

评论

支持 Markdown