关于 generate-rap-service-researched
面向 SAP RAP OData 服务开发的研究优先型技能,可从业务需求形成实现方案。它先调查目标系统能力、现有代码模式和 SAP 文档,再等待用户批准后编写代码。
主要功能
- 01调查系统能力与版本
- 02分析现有 RAP 模式
- 03查阅 SAP 文档
- 04先规划再实施
- 05获批后才编写代码
适用场景
- 01根据业务需求设计 RAP 服务
- 02使服务设计符合现有 SAP 模式
- 03实施前核实系统支持情况
MCP 相关
该技能通过 SAP 系统访问和 SAP 文档 MCP 工具研究系统能力、现有对象与最佳实践,再提出或创建 RAP 服务。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ arc-mcp/ arc-1 --skill generate-rap-service-researched安装后在 Claude Code 中输入/generate-rap-service-researched确认已加载。
详细介绍
生成 RAP OData 服务 — 研究优先
在编写任何代码之前,通过深入研究系统、分析最佳实践并进行迭代规划,生成可用于生产环境的 RAP OData 服务。
此技能会根据目标 SAP 系统的实际功能、现有代码模式、SAP 文档和用户需求制定实施计划,然后仅在获得用户明确批准后执行。
智能默认值(静默应用,研究前不要提问)
| 设置 | 默认值 | 原因 |
|---|---|---|
| Package | 用户的 Z* package,带传输请求 | 可用于生产环境;仅在用户明确要求时使用 $TMP |
| Key strategy | UUID(sysuuid_x16),托管编号 | 最简单,不存在冲突风险 |
| Behavior scenario | 托管 | 框架负责 CRUD,最常见 |
| OData version | V4 | 当前 SAP 标准 |
| Draft | 对事务型 Fiori Elements UI 服务优先使用;根据系统版本和 BO 约束进行验证 | 对可编辑的 FE 应用而言是最佳默认值,但并非每个 RAP 服务都需要草稿 |
| Strict mode | 除非系统模式或 SAP 限制有充分理由,否则使用 strict ( 2 ) | 当前 RAP 最佳实践,但并非通用方案 |
| Naming | SAP 标准(参见参考部分) | 如果发现现有系统模式,则优先采用 |
| Admin fields | 适合系统的字段(syuname/timestampl 或 abp_*) | 根据系统类型检测 |
| Service exposure | 默认使用 OData V4 UI provider contract | 最适合 Fiori Elements,除非用例是 API 优先的服务 |
这些默认值只是起点——第 1 阶段的研究可能会根据现有系统模式进行调整。
输入
用户以自然语言描述业务需求。内容可以很笼统(“我需要跟踪维护订单”),也可以很详细(“用于工厂维护的 REST API,包含设备层级、工单和工时记录”)。
只需提供业务需求。收集初步上下文即可——此阶段不要过度询问。研究会在之后提出合适的问题。
用户也可以选择指定:
- Package(必需——如果未提供则询问;仅当用户明确提出时,才默认使用
$TMP) - Transport request(仅非
$TMPpackage 需要——在第 1-pre 阶段解析) - 任何已知约束(例如,“必须使用现有表 ZMAINT_ORDER”“需要与 PM 模块集成”)
如果用户只提供了描述,请直接开始研究。研究完成后再提问,届时你已掌握足够信息,可以提出恰当的问题。
第 1-pre 阶段:解析 Package 和 Transport
如果用户未提供目标 package,请询问用户。然后解析传输请求(仅当 package 为 $TMP 时跳过):
SAPTransport(action="check", objectType="DDLS", objectName="<placeholder_name>", package="<package>")
此步骤会检查是否需要传输请求,并返回该 package 的现有传输请求。如果需要传输请求:
- 用户提供了传输请求:所有创建操作均使用此请求
- 找到了现有传输请求:列出这些请求并请用户选择一个
- 没有可用的传输请求:创建一个:
SAPTransport(action="create", description="RAP Service: <Entity>", package="<package>")
如果需要传输请求但无法获取,请停止——对于非 $TMP package,没有有效的传输请求,所有写入操作都会失败。
第 1 阶段:深入研究系统
在设计任何内容之前,彻底研究目标系统。每项发现都会影响计划。
1a. 系统能力与版本
检测系统支持的功能 — 这决定了可用的 RAP 功能、语法、命名方式和安全默认值。
如果 ./system-info.md 已由 bootstrap-system-context 创建,请将其用作输入。否则,请在此处直接执行关键读取操作:
SAPRead(type="SYSTEM")
SAPRead(type="COMPONENTS")
SAPManage(action="probe")
SAPLint(action="list_rules")
注意: 探测响应中的 rap.available 仅供参考 — 它表示是否检测到了 DDL 源端点,但 RAP 仍可能可用。请继续创建,并在出现错误时进行处理。
提取并记录:
- 系统类型:BTP ABAP Environment 还是本地部署(以及发行版本:7.52、7.54、7.57、S/4HANA 2020+ 等)
- ABAP 语言版本:Cloud(严格模式,仅允许使用已发布的 API)还是 Standard(完整 ABAP)
- RAP 支持级别:托管式、非托管式、抽象 BO?支持草稿?延迟编号?修改时还是保存时执行判定?
- CDS 功能:视图实体还是传统视图?表实体?元数据扩展?访问控制?
- 可用功能:ATC、语法检查、单元测试运行器、传输管理、FLP 自定义、abapGit/gCTS、版本历史
- FLP 支持:如果
flp功能可用,则可在创建后将服务注册到 Fiori Launchpad - Lint 配置:cloud 还是 on-prem 预设、当前 ABAP 版本、格式化工具样式
1b. 现有 RAP 项目 — 模式挖掘
搜索现有 RAP 工件,了解系统中已确立的模式。这对保持一致性至关重要。
SAPSearch(query="BDEF Z*", maxResults=20)
SAPSearch(query="SRVD Z*", maxResults=20)
SAPSearch(query="SRVB Z*", maxResults=20)
SAPSearch(query="DCLS Z*", maxResults=20)
SAPSearch(query="DDLX Z*", maxResults=20)
如果未找到任何 Z BDEF*,在编写任何代码之前,仍必须至少参考一个系统中的真实示例。请使用以下确定性回退方案:
SAPRead(type="TABL", name="SCARR")
这会展示系统中实际的 TABL 注解模式(增强类别、交付类别、数据维护、客户端处理)。然后读取一个已激活的 CDS 视图:
SAPSearch(query="DDLS I_*", maxResults=5)
SAPRead(type="DDLS", name="<first_result>")
这会展示 CDS 约定(客户端字段处理、别名样式、注解模式)。**在至少将一个真实系统表和一个 CDS 视图纳入上下文之前,不要进入阶段 4。**仅凭文档记忆编写代码,是导致反复重试、浪费时间的头号原因。
如果找到结果,请读取 2-3 个有代表性的 RAP 技术栈,以提取团队的模式:
SAPRead(type="BDEF", name="<found_bdef>")
SAPRead(type="DDLS", name="<found_interface_view>")
SAPRead(type="DDLS", name="<found_projection_view>")
SAPRead(type="DDLX", name="<found_metadata_ext>")
SAPRead(type="SRVB", name="<found_service_binding>")
SAPContext(type="DDLS", name="<found_interface_view>", action="impact")
SAPRead(type="VERSIONS", name="<found_interface_view>", objectType="DDLS")
SAPRead(type="SKTD", name="<found_interface_view>")
从中提取:
- 命名约定:使用什么前缀模式?
ZI_/ZC_/ZR_?实体后缀模式?表命名方式? - 架构风格:托管式还是非托管式?是否启用草稿?使用
strict ( 2 )还是strict? - 注解模式:采用哪种
@UI注解样式?标题信息模式?Facet 结构? - 字段命名:CamelCase 别名?下划线样式?缩写模式?
- 管理字段模式:使用哪种时间戳/用户字段类型?(
syuname还是abp_creation_user,timestampl还是abp_creation_tstmpl) - 键策略:UUID(
sysuuid_x16)?语义键?编号范围? - 行为模式:哪些判定/验证是标准做法?授权模式?
- 草稿处理:是否存在
with draft?草稿表命名方式?是否包含草稿操作? - OData 暴露方式:UI 还是 Web API 绑定?V2 还是 V4?服务定义/提供方契约风格?
- 近期演变:修订历史是否显示出稳定模式,还是正在进行迁移?
- 文档情况:重要 RAP 工件是否附有 SKTD 说明?
1b2. 可选的 Git / 交付上下文
如果 SAPManage(action="probe") 显示支持 abapGit 或 gCTS,且目标包可能已属于基于代码仓库的工作流,请在创建新工件之前检查该上下文:
SAPGit(action="list_repos")
SAPGit(action="objects", repoId="<repo_id>")
SAPGit(action="history", repoId="<repo_id>", limit=20)
借此了解:
- 目标包是否已由代码仓库管理
- 当前采用哪些命名/分支约定
- 该包是否处于活跃交付中,以及是否应与现有代码仓库布局保持一致
1c. 现有数据库表和领域对象
如果用户提到了现有表或业务对象,请读取:
SAPSearch(query="<mentioned_table_or_object>")
SAPRead(type="TABL", name="<found_table>")
SAPContext(type="TABL", name="<found_table>")
另请搜索该领域中的相关 SAP 标准对象:
SAPSearch(query="<domain_keyword>", maxResults=10)
检查是否有新服务应基于其构建而非重复存储数据的现有 CDS 视图或表。
如果要在 BTP 系统上基于现有对象构建,请检查其 API 发布状态,以确保符合 Clean Core 要求:
SAPRead(type="API_STATE", name="<found_table_or_view>", objectType="TABL")
如果对象已弃用(C2)或尚未发布,请避免基于它构建,并搜索其已发布的后继对象。
要了解现有依赖于已找到 CDS 对象的内容,请使用 CDS 专用的影响分析,而不是通用的使用位置分析:
SAPContext(type="DDLS", name="<found_view>", action="impact")
仅对非 DDLS 对象使用通用反向依赖关系:
SAPContext(type="CLAS", name="<found_class>", action="usages")
1d. 代码指南和质量标准
检查系统是否配置了 ATC 或自定义检查变体,以了解代码质量标准:
SAPDiagnose(action="atc", type="CLAS", name="<any_existing_class>", variant="DEFAULT")
如果在 1b 中找到了现有 RAP 类,请阅读其中一个类,并运行 lint 和格式化工具发现,以了解基准情况:
SAPRead(type="CLAS", name="<found_bp_class>")
SAPLint(action="lint", source="<class_source>", name="<found_bp_class>")
SAPLint(action="get_formatter_settings")
这有助于了解已强制执行的 lint 规则、严格级别以及关键字和缩进偏好。
1e. 最佳实践调研 — SAP 文档
请有针对性地使用 SAP 文档 MCP 服务,不要将其当作通用的关键词搜索工具。
- 从官方/参考类查询开始:
includeSamples=false- 在 BTP/ABAP Cloud 系统上使用
abapFlavor="cloud" - 在相关的经典本地部署系统上使用
abapFlavor="standard"
- 然后运行示例类查询:
includeSamples=true
- 使用
fetch(...)获取你实际依赖的首选搜索结果。 - 只有在官方文档不足时,才使用
sap_community_search(...)搜索边缘情况、未记录的错误或解决方法。
以下搜索词仅为初步建议——请根据用户的具体业务需求和需要做出的架构决策进行调整。设计搜索查询时,应针对你对这一特定服务尚不清楚的内容。
架构和分层:
search(query="RAP projection BO vs RAP BO interface", includeSamples=false, abapFlavor="<cloud|standard>")
search(query="RAP service definition provider contracts odata_v4_ui odata_v4_webapi", includeSamples=false, abapFlavor="<cloud|standard>")
特定领域——根据用户的业务领域调整:
search(query="<business_domain> RAP example SAP", includeSamples=true, abapFlavor="<cloud|standard>")
例如,如果用户想要开发旅行应用:search("RAP travel booking managed scenario example")
架构决策——仅搜索与此服务相关的主题:
search(query="RAP managed vs unmanaged scenario when to use", includeSamples=false, abapFlavor="<cloud|standard>")
search(query="RAP draft handling total etag draft-enabled associations", includeSamples=false, abapFlavor="<cloud|standard>")
search(query="RAP compositions parent child entity", includeSamples=true, abapFlavor="<cloud|standard>")
UI/服务行为——如果服务面向 UI,则进行搜索:
search(query="RAP value help metadata extension additional binding OData V4", includeSamples=false, abapFlavor="<cloud|standard>")
search(query="RAP feature control side effects authorization control", includeSamples=false, abapFlavor="<cloud|standard>")
search(query="metadata-driven UI metadata extension RAP Fiori Elements", includeSamples=false, abapFlavor="<cloud|standard>")
Clean Core/已发布 API——适用于 BTP 或复用已发布对象的场景:
search(query="ABAP API release RAP business object interface C1 C0", includeSamples=false, abapFlavor="cloud")
边缘情况/故障排查——仅在官方文档无法解决问题后进行:
sap_community_search(query="<exact error text or obscure RAP symptom>")
**重要提示:**不要照搬这些搜索词进行搜索。请分析用户的规范,并设计有针对性的查询,以弥补具体的知识缺口。如果用户提出了不常见的需求(例如,与特定 SAP 模块集成、特定字段类型、自定义编号、协作式草稿或使用已发布 BO 接口),请搜索这些具体内容。
无需在运行时调研命名约定——“SAP 官方命名约定”参考部分已记录 SAP 官方命名方案。请直接将其用作默认方案。
1f. 调研总结
继续之前,请整理结构化的调研总结并呈现给用户:
## System Research Summary
### System Profile
- Type: [BTP / On-Prem S/4HANA 20XX / ECC with ABAP Platform]
- ABAP Version: [Cloud / Standard ABAP 7.5X]
- RAP Support: [Full managed+draft / Managed only / Basic]
### Existing Code Patterns Found
- Naming: [e.g., "ZI_ prefix for interface views, ZC_ for projections, Z prefix + _D suffix for tables"]
- Architecture: [e.g., "All existing BOs use managed with draft, strict(2), UUID keys"]
- Field Style: [e.g., "CamelCase aliases, abp_ admin field types on BTP"]
- Annotation Style: [e.g., "Metadata extensions for all UI annotations, facet-based layout"]
- Service exposure: [e.g., "projection view + OData V4 UI binding, provider contract aligned"]
- N existing RAP services found: [list names]
### Domain Research
- Related existing objects: [tables, views, classes found]
- SAP standard objects in domain: [relevant standard CDS views, BAPIs]
- Clean core posture: [released APIs confirmed / successor required / custom tables only]
- Best practices from docs: [key findings]
### Quality Baseline
- ATC variant: [DEFAULT / custom]
- Lint findings: [clean / N issues on existing code]
- Strictness: [strict(2) / strict / none]
- Formatter settings: [keywordUpper / keywordLower / keywordAuto, indentation on/off]
第 2 阶段:澄清问题
根据调研结果提出有针对性的问题。只询问调研无法解答的内容。请按类别对问题分组,并根据调研结果给出建议。
架构问题
对于每个问题,先根据用户的规范和调研结果给出具体建议并说明原因,然后列出其他方案及其优缺点。**这些都是基础性决策——创建之后若要更改,就需要重建大部分产物。**请确保用户理解其中的权衡。 1. 实现方案
根据你的规范[引用相关内容],我建议采用托管式,因为[原因——例如:“这是一个全新的业务对象,没有现有持久化逻辑可供封装”]。
你有以下选项:
选项 优点 缺点 托管式 框架会自动处理 CRUD,代码更少,构建速度更快 对持久化的控制较少,必须遵循 RAP 约定 非托管式 可完全控制持久化,也可封装现有的 BAPI/FM 必须自行实现所有 CRUD,代码量会显著增加 托管式并采用非托管保存 兼具托管式的便利性和自定义保存功能(例如,在保存阶段调用 BAPI) 更复杂,需要理解保存顺序 托管式是否适合,还是你需要封装现有逻辑?
2. 实体结构
根据你的规范[引用相关内容],我建议采用**[单一实体 / 组合关系]**,因为[原因——例如:“你的描述提到了行项目,这是典型的父子关系模式”]。
你有以下选项:
选项 优点 缺点 单一根实体 最简单,只有一张表和一个 CDS 堆栈 无法建模层次结构 组合关系(父级 → 子级) 可建模真实的业务层次结构(订单 → 项目),草稿会级联到子级 每个子实体都需要自己的表、草稿表和 CDS 堆栈 关联 对相关实体的轻量级引用(例如,查询客户) 不存在生命周期依赖,也不会级联删除 你需要多少个实体?它们之间是什么关系?
3. 键策略
根据你的规范,我建议采用UUID(内部早期编号),因为[原因——例如:“没有提到用户可见的业务键,而 UUID 是最简单、最可靠的方案”]。
你有以下选项:
选项 优点 缺点 UUID(内部早期编号) 自动生成,无需用户输入,没有冲突风险,最简单 键不便于人类阅读 语义键 由用户提供且有实际含义的键(例如,订单号) 需要进行唯一性校验,用户必须事先知道该键 编号范围 由服务端分配连续编号,便于人类阅读 需要配置编号范围对象,设置工作更多 哪种键策略适合你的使用场景?
4. 服务公开 / 提供者契约
如果这是面向 Fiori Elements 的服务,我建议使用 OData V4 UI;如果主要面向编程方式的使用者,我建议使用 OData V4 Web API。服务定义的提供者契约必须与服务绑定类型匹配。
服务公开的重要背景:
- OData V4 UI:最适合 Fiori Elements 列表报表 / 对象页面应用。
- OData V4 Web API:当主要使用者是集成代码、测试或外部应用时更合适。
- OData V2:仅在有硬性遗留系统 / UI 客户端要求时使用。
主要使用者是哪种:Fiori UI 还是 API / 集成?
4b. 草稿模型
对于事务型 Fiori Elements 应用,我建议启用草稿,除非你的使用场景明确不需要草稿、仅面向 API,或受系统 / 版本实际情况限制。
SAP 文档中的重要限制:
- 草稿需要专用的草稿表和总 ETag。
- 启用了草稿的组合层次结构中的每个子级都必须在 BDEF 中声明。
- OData / Fiori 的部分行为在 V2 和 V4 之间有所不同。
此服务是否应启用草稿? 4c. 授权模型 我建议使用
@AccessControl.authorizationCheck: #MANDATORY+ DCLS,这样服务从一开始就具备明确的行级授权。SAP 的 RAP 文档建议 RAP BO 使用#MANDATORY,而不是#CHECK。你有以下选项:
选项 优点 缺点 #MANDATORY + DCLS 符合 RAP 基准,授权模型可用于生产环境 需要做出访问控制设计决策 #NOT_ALLOWED / #NOT_REQUIRED 原型开发更快 不适用于生产环境授权 要我现在生成一个严格的基准 DCLS(包含继承条件),并将特定于领域的规则标记为后续任务吗?
数据模型问题
5. 字段和类型
根据你的描述,我已确定以下业务字段:
字段 建议类型 备注 ... ... ... 这些是否正确?是否需要添加、删除字段或更改类型?
6. 值帮助/固定值
哪些字段需要下拉列表或值帮助?
- 状态字段 → 固定值(例如:新建/打开/已完成)?
- 引用字段 → 来自其他 CDS 视图的值帮助?
7. 现有数据源
[如果研究中发现了表/视图] 此服务应读取现有表
<TABLE>,还是创建新表?
7b. 规范的 DDIC 类型定义(生产服务)
对于生产级服务,我可以创建规范的域(DOMA)和数据元素(DTEL),而不是使用内联类型。这样可以实现:
- 在多个表/视图之间重复使用字段类型
- 在域上设置固定值列表(例如,状态域包含 A=活动、I=非活动)
- 在所有 UI 中使用一致的字段标签(短/中/长/标题)
- 为数据元素附加搜索帮助
对于
$TMP原型,内联类型即可。对于可传输的软件包,建议使用规范的 DOMA/DTEL。 要我为这些业务字段创建专用域和数据元素吗?
命名问题
8. 实体命名
我使用的是 SAP 官方命名约定(参见下方参考部分)。以名为
Travel的实体为例:
构件 SAP 约定 建议名称 活动持久化表 A_前缀ZA_TRAVEL草稿表 D_前缀ZD_TRAVEL基础/接口 CDS 视图 R_或I_前缀,TP后缀ZR_TravelTP投影 CDS 视图 C_前缀ZC_Travel接口 BDEF 与根实体相同 ZR_TravelTP投影 BDEF 与投影视图相同 ZC_Travel元数据扩展 与其注解的 CDS 实体相同 ZC_Travel服务定义 UI_前缀(如果是 UI 服务)ZUI_Travel服务绑定 UI_前缀,_O4后缀ZUI_Travel_O4行为池类 BP_前缀ZBP_R_TravelTP[如果系统中发现了不同的模式]:注意:我发现你的系统上有现有的 RAP 项目使用了不同的约定(
<pattern found>)。我默认采用 SAP 标准命名;如果你更倾向于遵循系统范围内现有的约定,或者使用完全不同的约定,请告诉我。需要更改任何名称吗?
UI / 服务问题
9. Fiori Elements 前端
此服务会由 Fiori Elements 应用使用吗(通过注解自动生成 UI)?
如果会,计划中的元数据扩展(DDLX)和 UI 注解将针对 Fiori Elements 列表报表 + 对象页(最常见的模式)进行优化。
注意:ARC-1 目前不会生成 Fiori Elements 前端应用本身,只会生成带有适当注解的后端 OData 服务。可以从 ADT(在服务绑定上选择“Create Fiori Project...”)或通过 VS Code 中的 SAP Fiori 工具生成 Fiori 应用。计划会将相关指导作为后续步骤列出。
如果不会(自由形式 UI5 应用或非 UI 使用方),我们可以简化注解。
9b. 后端驱动的 UI 功能
如果这是一个 Fiori Elements 应用,是否应从一开始就规划以下任何功能?
- 字段级只读 / 必填行为
- 值帮助
- 副作用
- 操作或更新的功能控制
注意:功能控制和副作用属于 RAP 概念,但主要由 Fiori Elements UI 使用。
10. 可搜索字段
哪些字段应支持搜索(显示在搜索栏中)?
业务逻辑问题(如适用)
12. 所需验证
应强制执行哪些业务规则?
- 必填字段?
- 跨字段验证(例如,开始日期 < 结束日期)?
- 状态转换规则?
13. 所需推导
应自动计算哪些值?
- 创建时的默认值?
- 派生字段(例如,总计 = 价格 × 数量)?
14. 自定义操作
除了标准 CRUD,是否还需要“批准”“发布”“取消”等操作?
重要:不要问完全部 14 个问题。研究应该已经解答了其中许多问题。只询问确实需要的问题。将其余问题归类并简洁呈现。针对每个问题提供建议。
等待用户回答后再继续。
第 3 阶段:实施计划
根据研究结果和用户回答,制定详细的实施计划。
3a. 设计完整的制品栈
创建一张全面的设计表:
## RAP Service Implementation Plan: <Service Name>
### Architecture Decisions
| Decision | Choice | Rationale |
|----------|--------|-----------|
| Scenario | Managed / Unmanaged | [why] |
| Service exposure | OData V4 UI / OData V4 Web API / OData V2 | [why] |
| Draft | Yes / No | [why] |
| Key strategy | UUID / Semantic / NumberRange | [why] |
| Provider contract | `odata_v4_ui` / `odata_v4_webapi` / `odata_v2_*` | [why] |
| Strict mode | strict(2) / strict | [system dependent] |
| Admin fields | syuname+timestampl / abp_* types | [system dependent] |
| Authorization | `#MANDATORY + DCLS` / prototype-only | [why] |
| Build engine | ARC-1 (manual stack) / SAP `abap-mcp` generator (single-root seed) | [generator only if it's connected AND the model is a single root, managed+draft] |
### Entity Model
| Entity | Role | Key Fields | Business Fields |
|--------|------|-----------|-----------------|
| <Root> | Root entity | key_uuid | field1, field2, ... |
| <Child> | Composition of Root | key_uuid, parent_uuid | field_a, field_b, ... |
### Artifact Stack
| # | Type | Name | Description | Dependencies |
|---|------|------|-------------|-------------|
| 1 | DDLS | <table> | Database table entity | — |
| 2 | DDLS | <draft_table> | Draft table (if draft) | — |
| 3 | DDLS | ZI_<Entity> | Interface CDS view | #1 |
| 4 | DCLS | ZI_<Entity>_DCL | Access control for interface CDS view | #3 |
| 5 | CLAS | ZBP_I_<Entity> | Behavior pool class | #3 |
| 6 | BDEF | ZI_<Entity> | Interface behavior definition | #3, #5 |
| 7 | DDLS | ZC_<Entity> | Projection CDS view | #3 |
| 8 | BDEF | ZC_<Entity> | Projection behavior definition | #6, #7 |
| 9 | DDLX | ZC_<Entity> | Metadata extension | #7 |
| 10 | SRVD | ZSD_<Entity> | Service definition | #7 |
| 11 | SRVB | ZSB_<Entity>_V4 | Service binding | #10 |
### Field Definitions
| Field | DB Column | CDS Alias | Type | Annotations | Notes |
|-------|-----------|-----------|------|-------------|-------|
| Key | key_uuid | KeyUuid | sysuuid_x16 | @Semantics | Internal numbering |
| ... | ... | ... | ... | ... | ... |
### Behavior Definition Spec
- Scenario: managed
- Draft: with draft / without draft
- ETag: LocalLastChangedAt
- Lock: master [total etag LastChangedAt]
- Numbering: managed (KeyUuid)
- Read-only fields: KeyUuid, CreatedBy, CreatedAt, LastChangedBy, LastChangedAt, LocalLastChangedAt
- Draft actions: Resume, Edit, Activate (optimized), Discard, Prepare
- Determinations (Phase 1): [list with triggers]
- Validations (Phase 1): [list with triggers]
- Custom actions (Phase 1): [list or "none — add later"]
### UI Annotations Spec
- Header: typeName="<Entity>", title=<MainField>, description=<SecondaryField>
- Facets: [list facet structure]
- List columns: [ordered list with position, importance]
- Selection fields: [filter bar fields]
- Search fields: [searchable fields]
### Naming Convention Used
<Document which convention was followed and why — matches existing code / SAP standard / user preference>
### Quality Checks Planned
- Lint validation before each write (automatic via arc-1)
- PrettyPrint of ABAP sources using SAP formatter settings before CLAS writes
- Syntax check after each activation
- ATC check after full stack activation
- Revision/history readback if iterating on pre-existing artifacts
- [If behavior logic]: Unit test skeleton
3b. 提交计划以供批准
清楚地呈现计划并征求批准。强调创建后再更改会困难得多:
实施计划已就绪
我设计了一个包含 [N] 个实体、[带 / 不带] 草稿、使用 [命名约定] 的[托管 / 非托管] RAP 服务。
[展示制品栈表和字段定义表]
⚠️ 重要:请在批准前仔细审核。 在 SAP 系统上创建制品后,要更改基本决策(托管还是非托管、键策略、实体结构、是否使用草稿),就需要删除并重新创建大部分制品。**现在更改计划远比创建后重新构建容易。**如果有任何不清楚之处或不确定的决策,请现在提问。
请审核:
- 制品名称是否正确?
- 字段是否完整,类型是否正确?
- 架构(托管 / 草稿 / 键)是否符合需求?
- 对设计决策有任何疑问吗?
- 开始创建前还有任何更改吗?
回复“approve”以继续,或提出问题 / 告诉我需要更改的内容。
在用户明确批准前,不要继续。
第 4 阶段:实施
获得批准后,创建制品。尽可能使用批量创建。
**快速失败:**如果首次 DDLS/BDEF 写入因 415 或 500 失败,立即停止后续所有 CDS 写入。不要尝试改用其他类型重试——根本问题在系统层面,而非对象本身。运行 SAPManage(action="probe") 以验证 rap.available 状态。
强制要求:错误恢复协议
发生任何保存失败(400、007、语法错误)时,必须遵循此协议,不得例外:
- 停止。 不要稍作修改后重试。不要删除并重新创建。
- 先阅读完整错误文本。 ARC-1 现在会返回结构化的 DDIC 诊断信息(
SBD...消息 ID、V1..V4变量和带行号的详细信息;对于基于源代码的 DDIC 创建,还可能附加非活动语法检查结果)。利用这些信息找出确切失败的字段或注释。 - 读回对象,查看实际保存的内容:
SAPRead(type=X, name=Y) - 通过尝试最精简的源代码来隔离原因(仅包含键字段和所有必需注释)。如果最精简版本可行 → 逐个添加字段。如果最精简版本失败 → 问题在于注释或对象类型,而非字段。
- 每次重试只更改一项。 切勿同时更改注释和字段。
- 同一对象失败 3 次后:停止。向用户报告确切的错误文本并寻求指导。不要继续自行尝试。
关键原则: 问题几乎总是出在源代码内容上,而非对象状态。用相同源代码删除并重新创建仍会产生相同错误。先修复源代码。
强制要求:先使用 batch_create
始终先尝试 batch_create。 不要从依次创建开始。batch_create 会在一次调用中创建所有对象——按依赖顺序放入数组(表 → 视图 → DCLS → 类 → BDEF → 服务定义)。
SAPWrite(action="batch_create", objects=[...], package="<package>", transport="<transport>")
对于组合关联的 DDLS 或其他相互依赖的同级对象(父对象的 composition [0..*] of ZR_CHILD 中,子对象也在同一批次中),请传入 activateAtEnd: true,这样 ARC-1 会先为每个对象写入非活动草稿,然后再发出一次最终的 activateBatch。SAP 激活器会一次性看到整个依赖图,并解析同级对象之间的交叉引用。逐个对象内联激活会导致父对象失败,错误为 "data source ZR_CHILD does not exist or is not active",因为激活父对象时,子对象仍处于非活动状态。
SAPWrite(action="batch_create", activateAtEnd: true, objects=[...], package="<package>", transport="<transport>")
如果某些生成的对象需要显式的单项路由,请在各个对象上设置 package 和 transport。单项级别的值会覆盖批次顶层的值;当恢复的计划混用了多个包时,必须使用这些值:
SAPWrite(action="batch_create", objects=[
{type: "TABL", name: "<table>", package: "<package>", transport: "<transport>", source: "<ddl>"},
{type: "DDLS", name: "ZI_<entity>", package: "<package>", transport: "<transport>", source: "<ddl>"}
])
只有当 batch_create 返回错误时,才回退到依次创建(第 4b 阶段)。如果批次失败:读取错误,修复具体失败对象的源代码,然后重试 batch_create。一次批次失败后,不要切换到依次创建模式。
4-pre. 实现前检查
创建构件前,可选择检查是否有残留的非活动对象可能造成冲突:
SAPRead(type="INACTIVE_OBJECTS")
注意: 在某些系统中,如果 /sap/bc/adt/activation/inactive 端点不可用,此检查可能会返回 404。如果出现这种情况,请跳过此检查并继续——这是方便性检查,并非必需步骤。
如果存在名称冲突的非活动对象,请先解决这些冲突(激活或删除)。
对于需要确认目标名称是否存在于存储库任意位置的重置/创建预检,请使用精确的对象目录查找,而不是针对 TADIR 执行冗长的 SAPQuery:
SAPSearch(searchType="tadir_lookup",
names=["<table>","ZI_<entity>","ZC_<entity>","ZSB_<entity>_V4"],
objectTypes=["TABL","DDLS","BDEF","SRVD","SRVB","CLAS"])
该查找会按请求的名称归类精确匹配项,并返回 missing;此检查不要构建大型的 WHERE OBJ_NAME IN (...) SQL 列表。
清理后,请确认这些名称确实已不存在——默认的 ADT 信息系统端点会筛除无法解析为工作台资源的 TADIR 行,因此孤立的“幽灵对象”(由中止的创建/删除操作遗留的 TADIR 行)不可见。使用 source: "both" 重新运行查找,以检测幽灵对象。此操作需要 sql 范围(管理员必须设置 SAP_ALLOW_FREE_SQL=true):
SAPSearch(searchType="tadir_lookup",
names=["<table>","ZI_<entity>","ZC_<entity>","ZSB_<entity>_V4"],
source: "both")
如果响应包含 splitBrain 数组,则其中列出的名称存在于 TADIR 中,但 ADT 无法解析它们——请先通过 SE03 / RS_DD_TADIR_CLEANUP 清理,然后再重试创建。
4-doma. 创建域和数据元素(如果在阶段 2 中获批)
如果用户选择了规范的 DDIC 类型,请先于表实体创建域和数据元素:
SAPWrite(action="create", type="DOMA", name="Z<DOMAIN>", package="<package>", transport="<transport>",
dataType="CHAR", length=1, fixedValues=[{low:"A", description:"Active"}, {low:"I", description:"Inactive"}])
SAPWrite(action="create", type="DTEL", name="Z<DATAELEMENT>", package="<package>", transport="<transport>",
typeKind="domain", dataType="Z<DOMAIN>", labels={short:"Status", medium:"Object Status", long:"Object Status", heading:"Status"})
SAPActivate(objects=[{type:"DOMA", name:"Z<DOMAIN>"}, {type:"DTEL", name:"Z<DATAELEMENT>"}])
然后在表实体 DDL 中引用数据元素,而不是使用内联类型(例如,使用 status : z<dataelement>,而不是 status : abap.char(1))。
4-gen.(可选)将单根构建委托给 SAP 官方生成器
如果已连接 SAP 官方 ABAP MCP 服务,且该服务与 ARC-1 并行运行(即随 VS Code 的 ABAP Development Tools / Eclipse ADT 3.60+ 捆绑的 abap-mcp 服务),并且获批计划的 构建引擎 是生成器,则将单根构建交给 SAP 的 Generate ABAP Repository Objects 框架处理,然后返回此处处理其无法完成的工作。仅适用于单个根实体(生成器执行“最多一个实体,不支持组合”),且该实体必须是托管型 + 草稿型,表中包含 last_changed : abp_lastchange_tstmpl + local_last_changed : abp_locinst_lastchange_tstmpl(或使用从零开始生成表的变体)。这属于一次性操作,不适用于生成后的处理。其他情况 → 使用 4a/4b。
- 探测并解析 ID(因版本而异,切勿硬编码)。 如果没有
abap_generators-list_generators工具 → 使用 4a/4b。否则调用该工具,并按显示名称匹配 "OData UI Service"(或 "OData Web API Service"),使用返回的id(在 SAP_BASIS 758 上为uiservice/webapiservice;在 816 上为ui-service/webapi-service/x-ui-service)。 - 架构 → 生成。 调用
abap_generators-get_schema(generatorId, packageName, referencedObjectType="TABL", referencedObjectName="<table>")→ 根据返回的架构填写所有必填字段 → 调用abap_generators-generate_objects(generatorId, …),将对象生成到计划的包和传输请求中(这是一次变更操作 — 遵循与 4a 相同的防护措施)。 - 继续使用 ARC-1。 进行验证(4d),然后使用 ARC-1 添加字段 / 子项 / 操作 / 逻辑并运行质量检查 — 生成器不会扩展自身的输出。在摘要(阶段 5)中记录哪些制品由生成器创建,哪些由 ARC-1 创建。
4a. 批量创建(首选)
如果系统支持且制品堆栈简单明了:
SAPWrite(action="batch_create", objects=[
{type: "TABL", name: "<table>", description: "<desc>", source: "<ddl>"},
{type: "DDLS", name: "ZI_<entity>", description: "<desc>", source: "<ddl>"},
{type: "DCLS", name: "ZI_<entity>_DCL", description: "<desc>", source: "<dcl>"},
{type: "DDLS", name: "ZC_<entity>", description: "<desc>", source: "<ddl>"},
{type: "BDEF", name: "ZI_<entity>", description: "<desc>", source: "<bdef>"},
{type: "BDEF", name: "ZC_<entity>", description: "<desc>", source: "<bdef>"},
{type: "DDLX", name: "ZC_<entity>", description: "<desc>", source: "<ddlx>"},
{type: "SRVD", name: "ZSD_<entity>", description: "<desc>", source: "<srvd>"},
{type: "CLAS", name: "ZBP_I_<entity>", description: "<desc>", source: "<class>"},
{type: "SRVB", name: "ZSB_<entity>_V4", description: "<desc>", serviceDefinition: "ZSD_<entity>", bindingType: "ODataV4-UI"}
], package="<package>", transport="<transport>")
对象按数组顺序创建 — 请先放置依赖项。
4b. 顺序回退
如果批量创建失败,或技术栈较复杂(组合、多个实体),请分 两轮 按顺序创建。这样可以避免 BDEF 与行为池死锁,并减少本地部署 7.5x 上的重试。
第 1 轮 — 最小可用 BO(CRUD + 组合):
- 仅创建活动表 → 逐个创建并激活。暂缓创建草稿表。
- 子接口 CDS 视图 → 创建并激活。
- 带组合的根接口 CDS 视图(
composition [0..*])→ 创建并激活。 - 空行为池类(不声明
METHODS ... FOR ...)→ 创建并激活。 - 接口 BDEF,仅包含 CRUD 和组合创建。不添加操作、判定或验证,也暂不进行严格模式/授权强化。
- 带重定向的投影 CDS 视图 → 创建并激活。
- 投影 BDEF(仅使用
projection;标头和 use 子句)→ 创建并激活。 - 服务定义 + 服务绑定 → 创建、激活并发布。
此时服务可预览且稳定。
第 2 轮 — 业务逻辑 + 强化:
- 在接口 BDEF 中添加操作/判定/验证并激活。
- 生成缺失的行为处理程序签名:
- 首选:使用
SAPWrite(action="scaffold_rap_handlers", type="CLAS", name="ZBP_I_<entity>", bdefName="ZI_<entity>")列出缺失的签名。 - 然后使用
autoApply=true重新运行;条件允许时,会在类的各个部分(main、definitions、implementations)中插入声明和空实现桩。 - 接下来可回退到:如果有可用的建议,则使用
SAPDiagnose(action="quickfix", ...)+SAPDiagnose(action="apply_quickfix", ...)。 - 最后可回退到:如果没有公开 MCP 快速修复建议,则在编辑器中使用 ADT 快速修复。
- 使用
SAPWrite(action="edit_method", ...)实现方法体(行为池不稳定时,避免重写整个类)。 - 仅在签名和方法体均已激活后,添加
strict ( 2 )和授权处理程序。 - 最后添加草稿。优先使用生成的草稿表(ADT 快速修复),而不是手动编写草稿表定义。
- BO 逻辑通过检查后,再创建/激活 DCLS 和 DDLX。
第 2 轮更改完成后,批量激活相互依赖的对象:
SAPActivate(objects=[
{type: "CLAS", name: "ZBP_I_<entity>"},
{type: "BDEF", name: "ZI_<entity>"},
{type: "BDEF", name: "ZC_<entity>"}
])
注意: 激活会返回结构化响应,其中包含详细的错误/警告消息,包括行号和 URI。错误会阻止激活;警告不会阻止激活,但应进行检查。请利用这些信息定位确切问题,而不是重新阅读完整源代码。
4c. 源代码模板
使用计划中的源代码模板,并根据调研结果进行调整:
- BTP 系统:使用
abp_*管理字段类型、ABAP Cloud 语法和strict ( 2 ) - 本地部署系统:使用
syuname/timestampl类型,并根据现有代码使用经典语法或 Cloud 语法 - 遵循现有模式:如果现有 RAP 项目使用特定的注解风格或字段命名模式,请完全遵照
- 草稿:包含草稿表、接口 BDEF 中的草稿操作,以及投影 BDEF 中的
use draft - 服务公开:确保服务定义的提供者契约与计划中的绑定类型相匹配
- ABAP 格式:如需 SAP 原生关键字大小写/缩进格式,可在写入生成的 ABAP 类之前,对其运行
SAPLint(action="format", source="<abap_source>", name="<class_name>")
4d. 创建后验证
创建并激活所有构件后:
-
语法检查行为池:
SAPRead(type="SYNTAX", objectType="CLAS", name="ZBP_I_<entity>") -
如果 ATC 可用,则对整个技术栈进行 ATC 检查:
SAPDiagnose(action="atc", type="BDEF", name="ZI_<entity>") -
确认没有未激活对象(某些系统可能返回 404;如遇此情况则跳过):
SAPRead(type="INACTIVE_OBJECTS") -
读回关键构件以确认其正确:
SAPRead(type="BDEF", name="ZI_<entity>") SAPRead(type="DDLS", name="ZI_<entity>") SAPRead(type="SRVD", name="ZSD_<entity>") -
Lint + 格式化程序检查行为池:
SAPRead(type="CLAS", name="ZBP_I_<entity>") SAPLint(action="lint", source="<behavior_pool_source>", name="ZBP_I_<entity>") SAPLint(action="get_formatter_settings")
修复发现的问题。必要时重新激活。
4e. 创建并发布服务绑定
创建服务绑定:
SAPWrite(action="create", type="SRVB", name="ZSB_<entity>_V4", package="<package>", transport="<transport>",
serviceDefinition="ZSD_<entity>", bindingType="ODataV4-UI", description="<Entity> OData V4 Service")
激活服务绑定:
SAPActivate(type="SRVB", name="ZSB_<entity>_V4")
发布服务绑定(使 OData 服务可用):
SAPActivate(action="publish_srvb", name="ZSB_<entity>_V4")
验证发布状态和服务 URL:
SAPRead(type="SRVB", name="ZSB_<entity>_V4")
⚠️ 检查点:确认 SRVB 读取结果显示 published: true、预期的绑定类型以及服务 URL。对于 OData V4 绑定,发布/取消发布针对整个绑定,而非单个服务版本。
4f. 预览服务
发布服务绑定后,可以直接预览 RAP 服务。在 ADT 中,用户可以打开服务绑定,选择一个实体(例如“Root”),然后点击“Preview...”在浏览器中启动 Fiori Elements 预览。这会通过 ADT business services 端点生成预览 URL。
告知用户:
您的服务已上线! 在 ADT 中打开服务绑定
ZSB_<ENTITY>_V4,选择根实体,然后点击“Preview...”即可查看自动生成的 Fiori Elements 列表报告 + 对象页面。
阶段 5:验证与总结
5a. 最终验证清单
RAP Service Generation Complete!
## Architecture
- Scenario: [managed/unmanaged]
- Draft: [enabled/disabled]
- Key strategy: [UUID/semantic/number range]
- OData version: [V4/V2]
- Followed conventions from: [existing code / SAP standard]
## Created Artifacts
[x] Database table entity: <table_name>
[x] Draft table entity: <draft_table> (if applicable)
[x] Interface CDS view: ZI_<Entity>
[x] Interface behavior definition: ZI_<Entity>
[x] Projection CDS view: ZC_<Entity>
[x] Projection behavior definition: ZC_<Entity>
[x] Metadata extension: ZC_<Entity>
[x] Service definition: ZSD_<Entity>
[x] Behavior pool class: ZBP_I_<Entity>
[x] Service binding: ZSB_<Entity>_V4
[x] Service binding published
## Quality Checks
[x] All artifacts activated successfully
[x] Syntax check: clean
[x] Lint check: clean
[x] ATC check: [clean / N findings noted]
## Consistency with Existing Code
[x] Naming matches existing convention: [pattern]
[x] Annotation style matches: [pattern]
[x] Admin fields match: [pattern]
5b. 后续步骤
根据计划提供后续操作:
## Recommended Next Steps
1. **Preview the service** in Fiori Elements (ADT → Service Binding → select entity → Preview...)
2. **Add business logic** → use `generate-rap-logic` skill:
- Determinations: [list from plan]
- Validations: [list from plan]
3. **Add value helps** for reference fields
4. **Add custom actions** if needed (e.g., Approve, Release)
5. **Generate unit tests** → use `generate-abap-unit-test` skill
6. **Add compositions** for child entities (if multi-entity scenario planned for Phase 2)
7. **Register in FLP** (if FLP feature available) → use SAPManage:
- `SAPManage(action="flp_create_catalog", catalogId="Z_<ENTITY>_C", title="<Entity> Catalog")`
- `SAPManage(action="flp_create_tile", catalogId="Z_<ENTITY>_C", tile={id:"Z_<ENTITY>_T", title:"<Entity>", semanticObject:"<Entity>", semanticAction:"manage"})`
- `SAPManage(action="flp_create_group", groupId="Z_<ENTITY>_G", title="<Entity>")`
- `SAPManage(action="flp_add_tile_to_group", groupId="Z_<ENTITY>_G", catalogId="Z_<ENTITY>_C", tileId="Z_<ENTITY>_T")`
8. **Create DOMA/DTEL** (if not done in Phase 4) for proper reusable typing
9. **Release transport** (if transportable package) → use `SAPTransport(action="release_recursive", transport="<TR>")` to release tasks and parent in one step
10. **Attach generated documentation** (optional) → use `SAPWrite(action="create", type="SKTD", refObjectType="SRVD", name="<service_doc_name>", source="<architecture_summary_markdown>")`
11. **Review current assignment + revision context on later iterations** → use `SAPTransport(action="history", type="SRVD", name="ZSD_<ENTITY>")` for the current lock/assignment status and `SAPRead(type="VERSIONS", name="ZSD_<ENTITY>", objectType="SRVD")` for actual revision history. Candidate requests from `history` are assignment choices, not historical membership.
12. **If the package is repo-managed** → use `SAPGit` (`list_repos`, `objects`, `history`) before changing naming or branch conventions
本地部署 7.5x RAP 快速参考(阶段 4 前阅读)
本节介绍在本地部署的 ABAP 7.5x 系统上导致反复保存失败的常见问题。这里的每条规则都来自实际故障经验——违反其中任何一条都常常会返回 SBD_MESSAGES 007 保存错误。ARC-1 现在会显示更多详细信息,但这些问题仍是根本原因。
TABL(透明表)——必需的注解
缺少以下任意注解,表保存必定会失败,并返回 007:
@EndUserText.label : '<description>'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table <name> {
key client : abap.clnt not null;
key <uuid_key> : sysuuid_x16 not null;
...
}
TABL 字段类型——使用限定名称
| 正确 | 错误(会导致 007 / 激活失败) |
|---|---|
abap.int4 | int4 |
abap.char(N) | char(N) |
abap.numc(N) | numc(N) |
abap.dec(N,M) | dec(N,M) |
abap.clnt | clnt |
sysuuid_x16 | UUID 应使用 raw(16) |
timestampl | TABL 中使用 abap.utclong |
syuname | TABL 中使用 abap.uname |
abap.cuky | cuky |
abap.curr(N,M) | 未带引用注解的 curr(N,M) |
abap.char(1)(X/空格布尔值) | TABL 中使用 abap.boolean |
客户端处理
- TABL:将
key client : abap.clnt not null;作为第一个键字段 - CDS 视图实体:在选择列表中省略客户端。SAP 会隐式处理客户端筛选。不要添加
@ClientHandling注解——视图实体不接受此注解。
组合与关联规则
- 组合:不要使用
on子句。写作composition [0..*] of ChildView as _Child——框架会根据键自动解析。添加on会导致错误:“组合中不允许使用 On 条件。” - 关联
on条件:使用选择列表中的 CamelCase 别名,而非数据库列名。写作$projection.ClubUuid = _Club.ClubUuid,而不是$projection.club_uuid。使用数据库列名会导致错误:“引用的选择列表名称被别名遮蔽。” - 外键关系:通过视图实体中的 CDS 组合/关联来表示。不要在 TABL 定义中添加
foreign key子句——表应保持简单。
父子对象的激活顺序
先激活子视图实体,再激活根视图。根视图中的 composition 引用了子视图,因此子视图必须处于激活状态。使用批量激活同时激活两者:SAPActivate(objects=[{type:"DDLS",name:"<child>"},{type:"DDLS",name:"<root>"}])——激活引擎会解析顺序。
Lint 检查和非 ABAP 类型
默认情况下,ABAP 源码和 DDLS 会在写入前运行 lint 检查。BDEF/SRVD/SRVB/DDLX/TABL/DOMA/DTEL 仍需激活或进行 RAP 预检验证,才能完成大多数语义检查。默认情况下请保持启用 RAP 预检;只有在了解要绕过的具体规则时,才在范围有限的恢复场景中使用 preflightBeforeWrite: false。如果 lint 检查阻止了已知有效的情况,请仅对该次写入使用 lintBeforeWrite: false,并将覆盖设置限制在局部。
错误恢复
如果调研未发现现有 RAP 项目
这很正常——系统可能刚开始使用 RAP。请改为遵循 SAP 标准命名约定和文档中的最佳实践,并在计划中注明:
"系统上未发现现有 RAP 项目。将采用 SAP 标准命名约定以及文档中的当前最佳实践。"
如果系统不支持所需功能
如果调研发现系统缺少用户需要的功能(例如,较旧的本地部署系统不支持草稿、7.55 之前的版本不支持表实体):
- 告知用户这一限制
- 提出替代方案(例如,使用经典 DDIC 表而非表实体,并且不使用草稿)
- 相应地调整计划
如果批量创建失败
请回退为按顺序创建(阶段 4b)。报告哪些对象创建成功、哪些失败。修复失败的对象后重试。
常见问题
| 错误 | 原因 | 解决方法 |
|---|---|---|
| DDLS/BDEF 上出现 415 Unsupported Media Type | RAP/CDS 端点的响应不符合预期 | 检查 SAPManage(action="probe") 获取系统信息。确认 ICF 服务已激活。尝试在 ADT 中创建对象,以确认系统支持该功能。 |
创建时出现 Resource X does already exist | 之前创建了存根,或名称冲突 | 立即切换到 SAPWrite(action="update", ...) 并重新发送完整源代码。不要使用相同负载重试 create。 |
| 不支持该功能 | 系统版本过旧 | 根据可用功能调整计划 |
| 激活错误 | 依赖项顺序错误 | 使用批量激活,或按依赖顺序逐个激活 |
| Lint 阻止写入 | 代码不符合 Lint 规则 | 调整生成的代码以通过 Lint,或检查 Lint 配置是否过于严格 |
| BDEF 语法错误 | 字段别名或实体引用错误 | 对照 BDEF 字段引用检查 CDS 别名 |
| 需要传输请求 | 非 $TMP 包未关联传输请求 | 使用 SAPTransport(action="check") 查找或创建传输请求 — 参见阶段 1-pre |
| 创建时发生锁定冲突 | 对象被其他用户或传输请求锁定 | 等待或使用其他名称;检查 SAPTransport(action="list") 中是否存在冲突的传输请求 |
Annotation with reference to currency code for field X is missing | abap.curr 字段没有货币引用 | 在每个金额字段正上方添加 @Semantics.amount.currencyCode;并配对使用 abap.cuky 字段。 |
"global or instance" was expected, not "none" | 7.5x 上的 BDEF 授权枚举值无效 | 使用 ( global ) 或 ( instance ),或者等处理程序存在后再添加授权。 |
dependent entity cannot have the identically named field ... as the etag master entity | 根实体和子实体的 etag 名称冲突 | 为根实体和依赖实体使用不同的 etag 字段名称。 |
投影 BDEF 中出现 "draft or side" was expected, not "etag" | 7.5x 上的 use etag 标头无效 | 投影标头仅保留 projection;。 |
not a suitable draft persistency ... there is no "X" field | 手写草稿表的列名不匹配 | 使用快速修复生成草稿表(首选),或严格遵循 CDS 名称派生规则。 |
DDLX 中出现 Annotation 'UI.headerInfo.X' used at wrong position | 7.5x 上的 DDLX 不支持该注解作用域 | 将 @UI.headerInfo、@Search.searchable、@ObjectModel.* 移到投影 DDLS 源代码中。 |
DDLX 中出现 Multiple entries with same name 'X' not allowed | 同一字段存在重复注解块 | 将字段注解合并到一个块中。 |
更新行为池类时出现 [?/011] | 对于 METHODS ... FOR ...,完整类行为池写入路径不稳定 | 先使用 SAPWrite(action="scaffold_rap_handlers", ...)(可选设置 autoApply=true),然后使用快速修复作为后备方案,最后使用 SAPWrite(action="edit_method", ...) 修补方法体。 |
备注
理念
这项技能将正确性和一致性置于速度之上。额外的研究时间(5-10 分钟)能带来以下好处:
- 避免与现有代码发生命名冲突
- 自动遵循既定的团队规范
- 在遇到错误之前发现系统限制
- 生成符合代码库风格的代码
- 让用户在提交前对架构充满信心
这项技能目前不会做的事情
- 在单次运行中处理非常庞大的多 BO 格局 — 每次执行专注于一种业务能力
- 实现非托管保存(规划实现方案,实现托管包装器,并将保存处理程序记为后续工作)
- 自定义 CDS 函数/操作(规划实现方案,实现标准 CRUD,并将其列为后续工作)
- 生成 Fiori 应用(生成 OData 服务;Fiori Elements 应用会根据注解自动生成)
与其他技能的关系
| 技能 | 关系 |
|---|---|
generate-rap-service | Vibe 编码版本——更快、不够全面,适合原型 |
generate-rap-logic | 自然的后续步骤——实现计划中确定的判定/验证逻辑 |
generate-abap-unit-test | 后续步骤——为行为池生成测试 |
explain-abap-code | 可在研究期间使用,以了解在系统中发现的现有 RAP 项目 |
implement-feature | 用于在 arc-1 代码库本身中实现非 RAP 功能 |
参考:SAP 官方 RAP 工件命名约定
通用规则
[/<namespace>/][<prefix>]_<object_name>_[<suffix>]
- 使用为组织保留的自有命名空间(客户对象使用 Z* 或 Y*)
/DMO/命名空间仅供 SAP 演示使用——切勿在生产开发中使用- 前缀用于传达同一对象类型中不同类型之间的语义差异
- 后缀用于补充区分信息(例如,OData 版本、开发指南变体)
ABAP Dictionary 对象
| 对象 | 约定 | 示例(客户命名空间) |
|---|---|---|
| 活动持久化表 | A_ 前缀 | ZA_TRAVEL |
| 草稿表 | D_ 前缀 | ZD_TRAVEL |
CDS 对象
| 对象 | 约定 | 备注 | 示例 |
|---|---|---|---|
| 基础/根 CDS 视图实体 | R_ 前缀 | 基础业务对象实体。使用 TP 后缀表示与事务处理相关 | ZR_TravelTP |
| 接口 CDS 视图 | I_ 前缀 | 可复用的接口视图层(某些模式中可替代 R_) | ZI_Travel |
| 投影 CDS 视图 | C_ 前缀 | C = 消费层。如果存在多个投影,名称应体现投影的角色 | ZC_Travel |
| 扩展包含视图 | E_ 前缀 | 用于可扩展性 | ZE_Travel |
| 行为定义 | 与根实体同名 | BDEF 始终与其所属 CDS 视图同名 | ZR_TravelTP(接口),ZC_Travel(投影) |
| 元数据扩展 | 与 CDS 实体同名 | 如果同一实体有多个扩展,则添加编号后缀 | ZC_Travel、ZC_Travel_2 |
业务服务
| 对象 | 约定 | 备注 | 示例 |
|---|---|---|---|
| 服务定义 | 无强制前缀 | 如果不在 UI/API 之间复用,可使用 UI_ 或 API_ 前缀 | ZUI_Travel 或 Z_Travel |
| 服务绑定(UI) | UI_ 前缀 | 用于 Fiori Elements / UI 消费 | ZUI_Travel_O4 |
| 服务绑定(Web API) | API_ 前缀 | 用于程序化/集成消费 | ZAPI_Travel_O4 |
| OData V2 后缀 | _O2 | ZUI_Travel_O2 | |
| OData V4 后缀 | _O4 | ZUI_Travel_O4 |
源代码对象
| 对象 | 约定 | 备注 | 示例 |
|---|---|---|---|
| 行为池类 | BP_ 前缀 | 实现业务对象行为的全局类 | ZBP_R_TravelTP |
| 本地处理程序类 | LHC_ 前缀 | 行为池中的本地类 | LHC_Travel_Create |
| 本地保存器类 | LSC_ 前缀 | 行为池中的本地类 | LSC_Travel |
完整示例:“Travel”实体(V4、UI、草稿、托管)
| # | 对象类型 | SAP 命名 | 名称 |
|---|---|---|---|
| 1 | 数据库表(活动) | A_ 前缀 | ZA_TRAVEL |
| 2 | 数据库表(草稿) | D_ 前缀 | ZD_TRAVEL |
| 3 | 基础 CDS 视图实体 | R_ 前缀 + TP 后缀 | ZR_TravelTP |
| 4 | 投影 CDS 视图 | C_ 前缀 | ZC_Travel |
| 5 | 接口 BDEF | = 根实体名称 | ZR_TravelTP |
| 6 | 投影 BDEF | = 投影视图名称 | ZC_Travel |
| 7 | 元数据扩展 | = 投影视图名称 | ZC_Travel |
| 8 | 服务定义 | UI_ 前缀(可选) | ZUI_Travel |
| 9 | 服务绑定 | UI_ 前缀 + _O4 后缀 | ZUI_Travel_O4 |
| 10 | 行为池类 | BP_ 前缀 | ZBP_R_TravelTP |
关于 R_ 与 I_ 前缀的说明
R_(基础/根视图实体):用于 SAP 标准 RAP 开发指南(托管、非托管、草稿)。这是 SAP 当前对新 RAP 开发的建议。I_(接口视图):过去使用,如今仍很常见。它表示可复用的接口层。许多现有教程和较早的项目使用I_而不是R_。- 两者都有效。遵循 SAP 最新指南的新项目默认使用
R_。如果系统上的现有代码使用I_,则应保持一致。
关于表命名的说明
- SAP 分别使用
A_和D_前缀命名活动表和草稿表 - 一些较早的教程和社区惯例使用
_D作为表后缀、_DD作为草稿表后缀——这不是 SAP 官方约定,但在实践中很常见 - SAP 的 “OData UI Service from Scratch” 向导会自动为表生成这些前缀