@open-rap/compiler 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +21 -2
- package/dist/agent/server.d.ts +35 -0
- package/dist/agent/server.js +408 -0
- package/dist/agent/server.js.map +1 -0
- package/dist/authoring/abapgit.d.ts +38 -0
- package/dist/authoring/abapgit.js +242 -0
- package/dist/authoring/abapgit.js.map +1 -0
- package/dist/authoring/catalog.d.ts +48 -0
- package/dist/authoring/catalog.js +117 -0
- package/dist/authoring/catalog.js.map +1 -0
- package/dist/authoring/floorplan.d.ts +28 -0
- package/dist/authoring/floorplan.js +31 -0
- package/dist/authoring/floorplan.js.map +1 -0
- package/dist/authoring/generate.d.ts +57 -0
- package/dist/authoring/generate.js +630 -0
- package/dist/authoring/generate.js.map +1 -0
- package/dist/authoring/mcp.d.ts +15 -0
- package/dist/authoring/mcp.js +52 -0
- package/dist/authoring/mcp.js.map +1 -0
- package/dist/authoring/new.d.ts +35 -0
- package/dist/authoring/new.js +389 -0
- package/dist/authoring/new.js.map +1 -0
- package/dist/bdef/ast.d.ts +249 -0
- package/dist/bdef/ast.js +3 -0
- package/dist/bdef/ast.js.map +1 -0
- package/dist/bdef/lexer.d.ts +105 -0
- package/dist/bdef/lexer.js +148 -0
- package/dist/bdef/lexer.js.map +1 -0
- package/dist/bdef/parser.d.ts +22 -0
- package/dist/bdef/parser.js +1012 -0
- package/dist/bdef/parser.js.map +1 -0
- package/dist/build.d.ts +26 -0
- package/dist/build.js +62 -0
- package/dist/build.js.map +1 -0
- package/dist/cds/adapter.d.ts +91 -0
- package/dist/cds/adapter.js +381 -0
- package/dist/cds/adapter.js.map +1 -0
- package/dist/cds/expression-ast.d.ts +65 -0
- package/dist/cds/expression-ast.js +330 -0
- package/dist/cds/expression-ast.js.map +1 -0
- package/dist/cli.d.ts +9 -0
- package/dist/cli.js +485 -0
- package/dist/cli.js.map +1 -0
- package/dist/dcl/parser.d.ts +59 -0
- package/dist/dcl/parser.js +338 -0
- package/dist/dcl/parser.js.map +1 -0
- package/dist/ddic/catalog.d.ts +17 -0
- package/dist/ddic/catalog.js +211 -0
- package/dist/ddic/catalog.js.map +1 -0
- package/dist/ddic/cds-types.d.ts +47 -0
- package/dist/ddic/cds-types.js +131 -0
- package/dist/ddic/cds-types.js.map +1 -0
- package/dist/ddic/table-source.d.ts +70 -0
- package/dist/ddic/table-source.js +500 -0
- package/dist/ddic/table-source.js.map +1 -0
- package/dist/ddic/xml.d.ts +65 -0
- package/dist/ddic/xml.js +201 -0
- package/dist/ddic/xml.js.map +1 -0
- package/dist/dev.d.ts +128 -0
- package/dist/dev.js +434 -0
- package/dist/dev.js.map +1 -0
- package/dist/diagnostics.d.ts +33 -0
- package/dist/diagnostics.js +53 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/gen/abap/derived-types.d.ts +26 -0
- package/dist/gen/abap/derived-types.js +323 -0
- package/dist/gen/abap/derived-types.js.map +1 -0
- package/dist/gen/abap/eml.d.ts +118 -0
- package/dist/gen/abap/eml.js +362 -0
- package/dist/gen/abap/eml.js.map +1 -0
- package/dist/gen/abap/enums.d.ts +13 -0
- package/dist/gen/abap/enums.js +74 -0
- package/dist/gen/abap/enums.js.map +1 -0
- package/dist/gen/abap/framework-http.d.ts +14 -0
- package/dist/gen/abap/framework-http.js +1049 -0
- package/dist/gen/abap/framework-http.js.map +1 -0
- package/dist/gen/abap/framework-query.d.ts +14 -0
- package/dist/gen/abap/framework-query.js +225 -0
- package/dist/gen/abap/framework-query.js.map +1 -0
- package/dist/gen/abap/framework-utils.d.ts +29 -0
- package/dist/gen/abap/framework-utils.js +3707 -0
- package/dist/gen/abap/framework-utils.js.map +1 -0
- package/dist/gen/abap/framework.d.ts +12 -0
- package/dist/gen/abap/framework.js +480 -0
- package/dist/gen/abap/framework.js.map +1 -0
- package/dist/gen/abap/generate.d.ts +40 -0
- package/dist/gen/abap/generate.js +238 -0
- package/dist/gen/abap/generate.js.map +1 -0
- package/dist/gen/abap/rewrite.d.ts +82 -0
- package/dist/gen/abap/rewrite.js +957 -0
- package/dist/gen/abap/rewrite.js.map +1 -0
- package/dist/gen/abap/shadow.d.ts +25 -0
- package/dist/gen/abap/shadow.js +175 -0
- package/dist/gen/abap/shadow.js.map +1 -0
- package/dist/gen/abap/tokens.d.ts +33 -0
- package/dist/gen/abap/tokens.js +87 -0
- package/dist/gen/abap/tokens.js.map +1 -0
- package/dist/gen/app/index.d.ts +25 -0
- package/dist/gen/app/index.js +322 -0
- package/dist/gen/app/index.js.map +1 -0
- package/dist/gen/csdl.d.ts +11 -0
- package/dist/gen/csdl.js +562 -0
- package/dist/gen/csdl.js.map +1 -0
- package/dist/gen/deploy.d.ts +12 -0
- package/dist/gen/deploy.js +53 -0
- package/dist/gen/deploy.js.map +1 -0
- package/dist/gen/docs/index.d.ts +35 -0
- package/dist/gen/docs/index.js +267 -0
- package/dist/gen/docs/index.js.map +1 -0
- package/dist/gen/docs/markdown.d.ts +23 -0
- package/dist/gen/docs/markdown.js +187 -0
- package/dist/gen/docs/markdown.js.map +1 -0
- package/dist/gen/docs/site.d.ts +17 -0
- package/dist/gen/docs/site.js +106 -0
- package/dist/gen/docs/site.js.map +1 -0
- package/dist/gen/keycloak.d.ts +21 -0
- package/dist/gen/keycloak.js +90 -0
- package/dist/gen/keycloak.js.map +1 -0
- package/dist/gen/launchpad/index.d.ts +48 -0
- package/dist/gen/launchpad/index.js +302 -0
- package/dist/gen/launchpad/index.js.map +1 -0
- package/dist/gen/launchpad/ui.d.ts +14 -0
- package/dist/gen/launchpad/ui.js +350 -0
- package/dist/gen/launchpad/ui.js.map +1 -0
- package/dist/gen/mcp.d.ts +23 -0
- package/dist/gen/mcp.js +244 -0
- package/dist/gen/mcp.js.map +1 -0
- package/dist/gen/sql-expressions.d.ts +12 -0
- package/dist/gen/sql-expressions.js +136 -0
- package/dist/gen/sql-expressions.js.map +1 -0
- package/dist/gen/sql.d.ts +38 -0
- package/dist/gen/sql.js +612 -0
- package/dist/gen/sql.js.map +1 -0
- package/dist/gen/ui/index.d.ts +7 -0
- package/dist/gen/ui/index.js +27 -0
- package/dist/gen/ui/index.js.map +1 -0
- package/dist/gen/ui/layout.d.ts +230 -0
- package/dist/gen/ui/layout.js +511 -0
- package/dist/gen/ui/layout.js.map +1 -0
- package/dist/gen/ui/static.d.ts +55 -0
- package/dist/gen/ui/static.js +2901 -0
- package/dist/gen/ui/static.js.map +1 -0
- package/dist/gen/ui/views.d.ts +10 -0
- package/dist/gen/ui/views.js +511 -0
- package/dist/gen/ui/views.js.map +1 -0
- package/dist/gen/vendor.d.ts +23 -0
- package/dist/gen/vendor.js +68 -0
- package/dist/gen/vendor.js.map +1 -0
- package/dist/gen/xml.d.ts +9 -0
- package/dist/gen/xml.js +42 -0
- package/dist/gen/xml.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/input/project.d.ts +50 -0
- package/dist/input/project.js +128 -0
- package/dist/input/project.js.map +1 -0
- package/dist/ir/access-controls.d.ts +11 -0
- package/dist/ir/access-controls.js +148 -0
- package/dist/ir/access-controls.js.map +1 -0
- package/dist/ir/authorizations.d.ts +25 -0
- package/dist/ir/authorizations.js +178 -0
- package/dist/ir/authorizations.js.map +1 -0
- package/dist/ir/behaviors.d.ts +16 -0
- package/dist/ir/behaviors.js +548 -0
- package/dist/ir/behaviors.js.map +1 -0
- package/dist/ir/builder.d.ts +20 -0
- package/dist/ir/builder.js +505 -0
- package/dist/ir/builder.js.map +1 -0
- package/dist/ir/config.d.ts +25 -0
- package/dist/ir/config.js +130 -0
- package/dist/ir/config.js.map +1 -0
- package/dist/ir/dictionary.d.ts +54 -0
- package/dist/ir/dictionary.js +328 -0
- package/dist/ir/dictionary.js.map +1 -0
- package/dist/ir/entities.d.ts +58 -0
- package/dist/ir/entities.js +676 -0
- package/dist/ir/entities.js.map +1 -0
- package/dist/ir/expressions.d.ts +33 -0
- package/dist/ir/expressions.js +327 -0
- package/dist/ir/expressions.js.map +1 -0
- package/dist/ir/handlers.d.ts +63 -0
- package/dist/ir/handlers.js +398 -0
- package/dist/ir/handlers.js.map +1 -0
- package/dist/ir/number-ranges.d.ts +24 -0
- package/dist/ir/number-ranges.js +74 -0
- package/dist/ir/number-ranges.js.map +1 -0
- package/dist/ir/seed.d.ts +23 -0
- package/dist/ir/seed.js +78 -0
- package/dist/ir/seed.js.map +1 -0
- package/dist/ir/service.d.ts +21 -0
- package/dist/ir/service.js +96 -0
- package/dist/ir/service.js.map +1 -0
- package/dist/launchpad/config.d.ts +47 -0
- package/dist/launchpad/config.js +321 -0
- package/dist/launchpad/config.js.map +1 -0
- package/dist/launchpad/workspace.d.ts +48 -0
- package/dist/launchpad/workspace.js +166 -0
- package/dist/launchpad/workspace.js.map +1 -0
- package/dist/srvd/parser.d.ts +36 -0
- package/dist/srvd/parser.js +193 -0
- package/dist/srvd/parser.js.map +1 -0
- package/dist/standard/data.d.ts +18 -0
- package/dist/standard/data.js +534 -0
- package/dist/standard/data.js.map +1 -0
- package/dist/standard/index.d.ts +36 -0
- package/dist/standard/index.js +507 -0
- package/dist/standard/index.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.js +4 -0
- package/dist/version.js.map +1 -0
- package/docs/AGENTS.md +79 -0
- package/docs/ANNOTATIONS.md +76 -0
- package/docs/DECISIONS.md +1554 -0
- package/docs/DEPLOYMENT.md +113 -0
- package/docs/DIAGNOSTICS.md +116 -0
- package/docs/FEATURES.md +287 -0
- package/docs/GUIDE.md +560 -0
- package/docs/KNOWN_GAPS.md +216 -0
- package/docs/MCP.md +84 -0
- package/docs/PLAN.md +690 -0
- package/docs/README.md +148 -0
- package/docs/REMOTE_APIS.md +121 -0
- package/docs/ROADMAP.md +35 -0
- package/docs/UTILITIES.md +95 -0
- package/package.json +49 -3
package/docs/GUIDE.md
ADDED
|
@@ -0,0 +1,560 @@
|
|
|
1
|
+
# Open RAP Runtime guide
|
|
2
|
+
|
|
3
|
+
This guide describes everything Open RAP Runtime can do and how to use it. It is written for ABAP
|
|
4
|
+
developers and for AI agents who write a RAP business object (BO) with it: each section gives the
|
|
5
|
+
command, the file to write and the resulting behavior, with a link to the technical decision
|
|
6
|
+
(`Dxx`, in [DECISIONS.md](DECISIONS.md)) that gives the details.
|
|
7
|
+
|
|
8
|
+
- Status, feature by feature: [FEATURES.md](FEATURES.md)
|
|
9
|
+
- Diagnostic codes: [DIAGNOSTICS.md](DIAGNOSTICS.md)
|
|
10
|
+
- Known gaps: [KNOWN_GAPS.md](../KNOWN_GAPS.md) · Roadmap: [ROADMAP.md](ROADMAP.md)
|
|
11
|
+
|
|
12
|
+
## 1. The principle
|
|
13
|
+
|
|
14
|
+
You write a RAP BO as in the ABAP Development Tools (ADT): tables, CDS views, metadata
|
|
15
|
+
extensions, behavior definition (BDEF), behavior pool in ABAP, service definition and binding.
|
|
16
|
+
Open RAP Runtime compiles these sources (abapGit format) into a standalone Node.js application:
|
|
17
|
+
|
|
18
|
+
- an **OData V4** service identical to the one of SAP (same paths, `$metadata`, `$batch`, ETags);
|
|
19
|
+
- the **RAP managed runtime**: locks, numbering, authorizations, feature control,
|
|
20
|
+
determinations, validations, actions, messages, EML;
|
|
21
|
+
- the **ABAP behavior pool transpiled** to JavaScript (abaplint), run as is;
|
|
22
|
+
- a **PostgreSQL** database (or embedded PGlite in development);
|
|
23
|
+
- an **OpenUI5 UI** List Report / Object Page generated from the `@UI` annotations;
|
|
24
|
+
- a **launchpad**, an **MCP server** for AI agents, **deployment** files.
|
|
25
|
+
|
|
26
|
+
The sources stay activatable on SAP: the same abapGit repository is imported into an ABAP Cloud
|
|
27
|
+
or S/4HANA system (in `standard` mode, see §4).
|
|
28
|
+
|
|
29
|
+
## 2. Getting started
|
|
30
|
+
|
|
31
|
+
### With VS Code (recommended)
|
|
32
|
+
|
|
33
|
+
Install the `open-rap-runtime-vscode.vsix` extension (it contains rapt, OpenUI5 and PGlite:
|
|
34
|
+
nothing else to install), then in the command palette (`Ctrl+Shift+P`):
|
|
35
|
+
|
|
36
|
+
| Command | Effect |
|
|
37
|
+
|---|---|
|
|
38
|
+
| *RAP: New complete business object…* | `rapt new`: a complete managed BO (table, CDS, BDEF, behavior pool, service, binding), with initial data; possible in an empty folder |
|
|
39
|
+
| *RAP: New RAP object…* | create object by object with the wizard, like *New ABAP Repository Object* of ADT: the types by category (Dictionary, Core Data Services, Behavior, Business Services, Source Code Library), a filter, a description, the fields of the type (source object, exposed entities, binding type…) |
|
|
40
|
+
| *RAP: Choose the floorplan of the application…* | `rapt floorplan`: List Report, Worklist, Analytical List Page or Form Entry, with what each one needs; asked anyway before the first generation |
|
|
41
|
+
| *RAP: Show the intermediate representation* | `rapt ir`: the model (`model.json`) in an editor |
|
|
42
|
+
| *RAP: Build the launchpad (all the applications)…* | `rapt launchpad`: the launchpad of the workspace and all its applications ([D69](DECISIONS.md)) |
|
|
43
|
+
| *RAP: Start rapt dev* | builds, starts and opens the development launchpad; restarts on each save |
|
|
44
|
+
| *RAP: Check the BO* | `rapt check`: diagnostics in the Problems tab (also on each save) |
|
|
45
|
+
| *RAP: Build the application…* | either the **launchpad with all the applications** (`rapt launchpad`) or the **application alone** (`rapt build`, standalone) |
|
|
46
|
+
| *RAP: Generate the abapGit files* | `rapt abapgit`: the missing XML files for the import into SAP |
|
|
47
|
+
| *RAP: Generate the MCP server of the service* | `rapt mcp`: the tools for AI agents |
|
|
48
|
+
| *RAP: Choose the project mode* | `standard` or `enhanced` (`rapt/config.json`) |
|
|
49
|
+
| *RAP: Report a bug or request a feature…* | the feedback form of the website, with the version and the environment filled in ([D71](DECISIONS.md)) |
|
|
50
|
+
|
|
51
|
+
A right click on a folder of the explorer arranges these commands in three groups: **create**
|
|
52
|
+
(complete BO, object by object), **project** (check, abapGit), **application** (floorplan, rapt
|
|
53
|
+
dev, build). A command is greyed out as long as it is not possible: the project commands outside
|
|
54
|
+
an abapGit project, the application commands as long as the project has no service definition.
|
|
55
|
+
Before the application is built or started, the floorplan of each root entity must have been
|
|
56
|
+
chosen: the extension asks for it when it was not ([D66](DECISIONS.md)).
|
|
57
|
+
|
|
58
|
+
The **RAP Objects** view of the explorer arranges the objects of the project like the project
|
|
59
|
+
explorer of ADT (dictionary, data definitions, metadata extensions, access controls, behavior
|
|
60
|
+
definitions, services, classes); its title bar creates an object, checks the project and starts
|
|
61
|
+
`rapt dev` ([D61](DECISIONS.md)).
|
|
62
|
+
|
|
63
|
+
Syntax highlighting covers ABAP, CDS (DDLS, DDLX, DCL, SRVD, tables, types) and BDEF.
|
|
64
|
+
|
|
65
|
+
The integrated terminals of VS Code have the `rapt` command of the extension (setting
|
|
66
|
+
`rapt.terminal.addToPath`), and the agent mode of VS Code finds the MCP server of rapt (§13).
|
|
67
|
+
|
|
68
|
+
### On the command line
|
|
69
|
+
|
|
70
|
+
```sh
|
|
71
|
+
rapt new my-project Travel --prefix ZRT # a complete managed BO
|
|
72
|
+
rapt dev my-project # http://localhost:8080/: development launchpad
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Install it with `npm install -g open-rap-runtime` (Node.js 22): the package installs the `rapt`
|
|
76
|
+
command with everything it needs (runtime, OpenUI5, PGlite) ([D65](DECISIONS.md)). Without a
|
|
77
|
+
global installation: `npx open-rap-runtime <command>` (for example `npx open-rap-runtime check
|
|
78
|
+
my-project` in a CI), or `open-rap-runtime` as a `devDependency` of the project and `npx rapt …`.
|
|
79
|
+
The libraries `@open-rap/compiler`, `@open-rap/runtime` and `@open-rap/model`
|
|
80
|
+
are published separately too. From a clone of the repository: `pnpm install && pnpm build`,
|
|
81
|
+
then `node packages/compiler/dist/cli.js` instead of `rapt`.
|
|
82
|
+
|
|
83
|
+
## 3. The project
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
my-project/
|
|
87
|
+
.abapgit.xml folder of the sources (STARTING_FOLDER), written by rapt abapgit
|
|
88
|
+
src/ the objects, in abapGit format
|
|
89
|
+
zrt_travel.tabl.astabl table written as source (ADT "define table" syntax)
|
|
90
|
+
zrt_r_travel.ddls.asddls root CDS view
|
|
91
|
+
zrt_c_travel.ddls.asddls projection
|
|
92
|
+
zrt_c_travel.ddlx.asddlxs metadata extension (UI)
|
|
93
|
+
zrt_r_travel.bdef.asbdef behavior definition
|
|
94
|
+
zbp_rt_r_travel.clas.* behavior pool
|
|
95
|
+
zrt_ui_travel.srvd.srvdsrv service definition
|
|
96
|
+
*.xml abapGit metadata (generated by rapt abapgit)
|
|
97
|
+
rapt/ configuration of Open RAP Runtime (never imported into SAP)
|
|
98
|
+
config.json mode of the project (standard / enhanced)
|
|
99
|
+
seed.json, seed.sql initial data of rapt dev
|
|
100
|
+
authorizations.json roles → authorizations (authorization objects)
|
|
101
|
+
number-ranges.json number range intervals
|
|
102
|
+
mcp.json MCP tools and their descriptions
|
|
103
|
+
.rapt/ build of rapt dev (ignored by git)
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Tables are written as source (`.tabl.astabl`): `rapt abapgit` derives the XML abapGit expects
|
|
107
|
+
from them ([D42](DECISIONS.md)). The other XML files are generated when they are missing; an
|
|
108
|
+
existing XML file is never changed.
|
|
109
|
+
|
|
110
|
+
## 4. `standard` and `enhanced` modes
|
|
111
|
+
|
|
112
|
+
`rapt/config.json` ([D45](DECISIONS.md)):
|
|
113
|
+
|
|
114
|
+
```json
|
|
115
|
+
{ "mode": "enhanced" }
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
| | `standard` (default) | `enhanced` |
|
|
119
|
+
|---|---|---|
|
|
120
|
+
| Goal | As on SAP: what builds activates on SAP | Extensions of Open RAP Runtime |
|
|
121
|
+
| Managed BO + unmanaged save on a custom entity | refused (BDEF027) | allowed ([D43](DECISIONS.md)) |
|
|
122
|
+
| `field ( mandatory )` | a hint for the UI, as in RAP | checked on save, one message per field, without a validation to write |
|
|
123
|
+
| Exposed element of a CDS enumerated type | refused as on SAP (CDS021) | OData `EnumType`: `"Status": "OPEN"`, labels and choice list in the UI ([D55](DECISIONS.md)) |
|
|
124
|
+
|
|
125
|
+
`rapt check --mode enhanced` (or `build`, `dev`) overrides the mode of the file.
|
|
126
|
+
|
|
127
|
+
## 5. Writing the objects
|
|
128
|
+
|
|
129
|
+
### Creating an object: `rapt generate`
|
|
130
|
+
|
|
131
|
+
```sh
|
|
132
|
+
rapt generate . table zshop_order
|
|
133
|
+
rapt generate . view ZR_ShopOrder --from zshop_order --root
|
|
134
|
+
rapt generate . projection ZC_ShopOrder --from ZR_ShopOrder
|
|
135
|
+
rapt generate . metadata ZC_ShopOrder
|
|
136
|
+
rapt generate . behavior ZR_ShopOrder # managed BDEF, with the compositions
|
|
137
|
+
rapt generate . pool ZBP_R_SHOPORDER # handlers of the BDEF that names the class
|
|
138
|
+
rapt generate . behavior ZC_ShopOrder # projection BDEF
|
|
139
|
+
rapt generate . access ZC_ShopOrder # DCL
|
|
140
|
+
rapt generate . service ZUI_SHOPORDER --expose ZC_ShopOrder,ZC_ShopItem
|
|
141
|
+
rapt generate . binding ZUI_SHOPORDER_O4 --for ZUI_SHOPORDER
|
|
142
|
+
rapt generate . dataelement ZSHOP_ORDER_NO --type abap.numc(8)
|
|
143
|
+
rapt generate . domain ZSHOP_STATUS --type abap.char(1)
|
|
144
|
+
rapt generate . tableentity ZSHOP_ITEM --root # table entity: table and entity in one object
|
|
145
|
+
rapt generate . type ZSHOP_NAME # CDS simple type
|
|
146
|
+
rapt generate . enum ZSHOP_STATUS # CDS enumerated type
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
`rapt generate . ` without a type lists the types. Each object is derived from the previous one as
|
|
150
|
+
in the wizards of ADT; the abapGit XML is written with it ([D46](DECISIONS.md)).
|
|
151
|
+
|
|
152
|
+
### CDS
|
|
153
|
+
|
|
154
|
+
- `define [root] view entity … as select from <table>`, `as projection on`, `provider contract
|
|
155
|
+
transactional_query`, `composition`, `association to parent`, associations, `redirected to`.
|
|
156
|
+
- Metadata extensions (`@Metadata.allowExtensions: true`) merged with the view.
|
|
157
|
+
- Abstract entities (action parameters), custom entities (`@ObjectModel.query.implementedBy`,
|
|
158
|
+
`if_rap_query_provider` class).
|
|
159
|
+
- Access controls (DCL): `grant select … where`, `aspect pfcg_auth`, `aspect user`
|
|
160
|
+
([D35](DECISIONS.md)).
|
|
161
|
+
- Calculated elements in the select list ([D67](DECISIONS.md)): `CASE`, `CAST`, `+ - * /`,
|
|
162
|
+
literals, `$projection.Element`, `$session.system_date` and the common SQL functions
|
|
163
|
+
(`concat`, `concat_with_space`, `substring`, `upper`, `lower`, `length`, `left`, `right`,
|
|
164
|
+
`ltrim`, `rtrim`, `replace`, `coalesce`, `div`, `division`, `mod`, `abs`, `round`, `ceil`,
|
|
165
|
+
`floor`, `dats_days_between`, `dats_add_days`). PostgreSQL computes them in the view; they are
|
|
166
|
+
read-only (`Core.Computed`, ignored in the writes) and cannot be keys. A projection takes them
|
|
167
|
+
and can define its own:
|
|
168
|
+
|
|
169
|
+
```cds
|
|
170
|
+
case overall_status when 'A' then 'Accepted' else 'Open' end as StatusText,
|
|
171
|
+
booking_fee + total_price as TotalWithFee,
|
|
172
|
+
cast( dats_days_between( begin_date, end_date ) as abap.int4 ) as Duration,
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Without a `CAST`, the type is derived from the operands; when it cannot be derived (`NULL`
|
|
176
|
+
alone, calculation on a string), CDS022 asks for a `CAST`. In a draft, the value is computed on
|
|
177
|
+
the values of the draft; read with EML in the behavior pool, it is the one of the last save.
|
|
178
|
+
- Still refused (CDS002): association paths (`_Agency.Name`), `$session.user`,
|
|
179
|
+
`$session.client`, `$session.system_language`, `BETWEEN`, aggregates, other SQL functions.
|
|
180
|
+
|
|
181
|
+
#### Table entities and CDS types ([D55](DECISIONS.md))
|
|
182
|
+
|
|
183
|
+
A table entity combines the table and the entity; a managed BO is written directly on it, without
|
|
184
|
+
a `persistent table`:
|
|
185
|
+
|
|
186
|
+
```cds
|
|
187
|
+
@ClientHandling.type: #CLIENT_DEPENDENT
|
|
188
|
+
@AbapCatalog.deliveryClass: #APPLICATION_DATA
|
|
189
|
+
@AccessControl.authorizationCheck: #NOT_REQUIRED
|
|
190
|
+
@EndUserText.label: 'Orders'
|
|
191
|
+
define root table entity ZRT_ORDER
|
|
192
|
+
{
|
|
193
|
+
key OrderId : abap.numc(8);
|
|
194
|
+
Name : zrt_order_name; // CDS simple type
|
|
195
|
+
Status : zrt_order_status; // CDS enumerated type
|
|
196
|
+
Note : abap.string null;
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
CDS types are `<name>.drty.acds` sources (AFF format of abapGit, metadata `<name>.drty.json`
|
|
201
|
+
written by `rapt abapgit`):
|
|
202
|
+
|
|
203
|
+
```cds
|
|
204
|
+
@EndUserText.label: 'Order status'
|
|
205
|
+
define type ZRT_ORDER_STATUS : abap.char(1) enum
|
|
206
|
+
{
|
|
207
|
+
@EndUserText.label: 'New'
|
|
208
|
+
NEW = initial;
|
|
209
|
+
@EndUserText.label: 'Open'
|
|
210
|
+
OPEN = 'O';
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
The database keeps the base value (`'O'`); the behavior pool writes the constants as on SAP
|
|
215
|
+
(`Status = zrt_order_status-open`). SAP does not expose enumerated types in a RAP OData service:
|
|
216
|
+
in `standard` mode, CDS021; in `enhanced` mode, the `$metadata` has an `EnumType`, the JSON
|
|
217
|
+
carries the name of the member (`"Status": "OPEN"`) and `$filter=Status eq 'OPEN'` works.
|
|
218
|
+
Complete example: `fixtures/table-entity`.
|
|
219
|
+
|
|
220
|
+
### SAP standard views
|
|
221
|
+
|
|
222
|
+
`I_Currency`, `I_UnitOfMeasure`, `I_Country`, `I_Language`, `I_Region`, `I_TimeZone` and their
|
|
223
|
+
text views, `I_CalendarDate` (calendar 1990-2060), `I_BusinessUserBasic` (the users of the IdP,
|
|
224
|
+
recorded on their first request) and `I_ExchangeRate` (rates to load) exist as on SAP, with their
|
|
225
|
+
data: just name them ([D44](DECISIONS.md)).
|
|
226
|
+
|
|
227
|
+
```cds
|
|
228
|
+
@Consumption.valueHelpDefinition: [{ entity: { name: 'I_Currency', element: 'Currency' } }]
|
|
229
|
+
CurrencyCode,
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
The entity of the value help is exposed automatically (as in RAP); the UI opens a selection
|
|
233
|
+
dialog with the descriptions. `additionalBinding` (`#FILTER`, `#RESULT`),
|
|
234
|
+
`useForValidation: true` and an entity with `@ObjectModel.resultSet.sizeCategory: #XS`
|
|
235
|
+
(drop-down list) are supported ([D56](DECISIONS.md)).
|
|
236
|
+
|
|
237
|
+
### Behavior definition
|
|
238
|
+
|
|
239
|
+
A complete managed RAP BO, with or without draft: `strict ( 2 )`, `lock master` / `dependent`,
|
|
240
|
+
`etag master` / `dependent`, `global` / `instance` authorizations, managed, external or early
|
|
241
|
+
numbering, `create`/`update`/`delete` (internal, `precheck`, `features`), `readonly`,
|
|
242
|
+
`mandatory`, `readonly : update`, `features : instance` fields, `on modify` / `on save`
|
|
243
|
+
determinations, validations, actions (instance, static, factory, internal, with parameters and
|
|
244
|
+
results), functions, `with additional save`, `with unmanaged save`, `with privileged mode`,
|
|
245
|
+
projections (`use …`), side effects. Details and exceptions: [FEATURES.md](FEATURES.md).
|
|
246
|
+
|
|
247
|
+
**Draft** ([D54](DECISIONS.md)): `with draft;`, one `draft table` per entity (BDEF028
|
|
248
|
+
otherwise), `total etag`, `draft action Edit; draft action Activate optimized; draft action
|
|
249
|
+
Discard; draft action Resume; draft determine action Prepare;`. The draft table does not have to
|
|
250
|
+
exist: it is generated. The service has the `IsActiveEntity` key, `HasDraftEntity`,
|
|
251
|
+
`DraftAdministrativeData` and the actions of SAP; determinations and validations run on
|
|
252
|
+
activation. The UI follows Fiori Elements: *Editing Status* filter, *Locked by X*,
|
|
253
|
+
"Draft updated", *Keep Draft* when leaving the page ([D58](DECISIONS.md)).
|
|
254
|
+
|
|
255
|
+
**Collaborative draft** ([D59](DECISIONS.md)): `with collaborative draft;` and `draft action
|
|
256
|
+
Share;`; several users edit the same draft (*Invite* button, or *Edit* on an instance already in
|
|
257
|
+
draft).
|
|
258
|
+
|
|
259
|
+
### Behavior pool (ABAP)
|
|
260
|
+
|
|
261
|
+
The ABAP Cloud code of the handlers and of the saver is transpiled as is: complete EML
|
|
262
|
+
(`READ`/`MODIFY ENTITIES`, `IN LOCAL MODE`, `BY \_assoc`, `EXECUTE`), `failed`/`reported`/`mapped`,
|
|
263
|
+
messages (`new_message_with_text`, message classes, exception classes), `AUTHORITY-CHECK`, ABAP
|
|
264
|
+
SQL reads on the tables and entities of the project, writes in `save_modified`.
|
|
265
|
+
|
|
266
|
+
Available released classes: JSON (`/ui2/cl_json`, `xco_cp_json`), encodings, dates
|
|
267
|
+
(`cl_abap_tstmp`, `xco_cp_time`), numbering (`cl_numberrange_runtime`), application log
|
|
268
|
+
(`cl_bali_*`), hashing, random numbers, regular expressions, RTTS ([UTILITIES.md](UTILITIES.md)),
|
|
269
|
+
background processing (`cl_bgmc_process_factory`) and e-mail (`cl_bcs_mail_message`)
|
|
270
|
+
([D41](DECISIONS.md)), HTTP client and OData client proxy ([REMOTE_APIS.md](REMOTE_APIS.md)).
|
|
271
|
+
|
|
272
|
+
### The `rapt/` configuration
|
|
273
|
+
|
|
274
|
+
| File | Content | Decision |
|
|
275
|
+
|---|---|---|
|
|
276
|
+
| `config.json` | `{ "mode": "standard" \| "enhanced", "ui": { "floorplans": …, "overview": … } }` | [D45](DECISIONS.md), [D53](DECISIONS.md) |
|
|
277
|
+
| `seed.json` | `{ "table": [ { "field": "value" } ] }`: data loaded on the first start of `rapt dev` (`SEED=auto`); random UUID keys | [D42](DECISIONS.md) |
|
|
278
|
+
| `seed.sql` | data in SQL | [D42](DECISIONS.md) |
|
|
279
|
+
| `authorizations.json` | roles of the IdP → authorization objects and values (`{claim:agency}`: value read from the token) | [D34](DECISIONS.md) |
|
|
280
|
+
| `number-ranges.json` | intervals of `cl_numberrange_runtime` | [D40](DECISIONS.md) |
|
|
281
|
+
| `mcp.json` | MCP tools and their descriptions | [D47](DECISIONS.md) |
|
|
282
|
+
|
|
283
|
+
## 6. The generated UI
|
|
284
|
+
|
|
285
|
+
The List Report and the Object Page follow the `@UI` annotations: `headerInfo`, `lineItem`
|
|
286
|
+
(columns and table actions), `selectionField`, `identification` (header fields and actions),
|
|
287
|
+
`fieldGroup`, `facet` (sections, tables of the compositions, header), `dataPoint`,
|
|
288
|
+
`presentationVariant` (sorting), `hidden`, `multiLineText`, `textArrangement`, criticality,
|
|
289
|
+
`@Consumption.filter`. The complete list, annotation by annotation: [ANNOTATIONS.md](ANNOTATIONS.md).
|
|
290
|
+
|
|
291
|
+
- **Filters**: conditions as in SAP Fiori, several per field:
|
|
292
|
+
|
|
293
|
+
| Input | Meaning |
|
|
294
|
+
|---|---|
|
|
295
|
+
| `Rome` | text: contains "Rome" (case-insensitive); other types: equal |
|
|
296
|
+
| `=Rome`, `!=Rome` | equal, not equal |
|
|
297
|
+
| `>100`, `>=100`, `<100`, `<=100` | comparisons |
|
|
298
|
+
| `1...5` | range (bounds included) |
|
|
299
|
+
| `Ro*`, `*me`, `*om*` | starts with, ends with, contains |
|
|
300
|
+
| `<empty>` | empty (text: `''` or `null`) |
|
|
301
|
+
| `!(*om*)`, `!(1...5)`, `!(<empty>)` | exclusions: does not contain, outside the range, not empty… |
|
|
302
|
+
|
|
303
|
+
A string of digits (NUMC) is entered without its leading zeros (`3` finds `00000003`); a single
|
|
304
|
+
value looks for equality for a key or a field with a value help. Dates are entered in the
|
|
305
|
+
format of the language or in ISO (`Jun 1, 2026 - Jul 31, 2026`, `2026-06-01...2026-07-31`).
|
|
306
|
+
The icon of the field opens the dialog of SAP Fiori elements ([D68](DECISIONS.md)): *Search
|
|
307
|
+
and Select* (values of the value help, when the field has one) and *Define Conditions*
|
|
308
|
+
(operator and values per row: *equal to*, *contains*, *between*, *greater than*, *empty*, their
|
|
309
|
+
exclusions…, according to the type of the field and `@Consumption.filter.selectionType`); the
|
|
310
|
+
included conditions of a field are combined with "or", the exclusions with "and not". *Adapt
|
|
311
|
+
Filters* adds the columns as filters; *Clear* empties everything.
|
|
312
|
+
- **User views** (variants): the title of the List Report opens the view management: save the
|
|
313
|
+
filters, the visible columns and the sorting under a name, choose the default view. They are
|
|
314
|
+
saved per user in the database of the application ([D51](DECISIONS.md)).
|
|
315
|
+
- **Table settings** (gear icon): visible columns, sorting.
|
|
316
|
+
- **Object Page**: edit, create, delete, actions (parameter dialog), editable tables of the
|
|
317
|
+
compositions, value helps, breadcrumbs, messages of the BO.
|
|
318
|
+
- The buttons follow the authorizations and the feature control of the user.
|
|
319
|
+
- **Draft**: Create and Edit open a draft, each field is saved in it, Save activates, Cancel
|
|
320
|
+
discards; the list shows the instances being edited.
|
|
321
|
+
|
|
322
|
+
**Floorplans** ([D53](DECISIONS.md)): the List Report is the default on the command line. To
|
|
323
|
+
choose one: *RAP: Choose the floorplan of the application…* in VS Code (each floorplan is
|
|
324
|
+
described with the annotations it reads; the extension also asks for it before building or
|
|
325
|
+
starting an application whose floorplan was not chosen), or `rapt floorplan . Travel worklist`;
|
|
326
|
+
without arguments, `rapt floorplan .` lists the entity sets, their floorplan and whether it was
|
|
327
|
+
chosen. Both write `rapt/config.json` (the List Report too, once chosen):
|
|
328
|
+
|
|
329
|
+
```json
|
|
330
|
+
{
|
|
331
|
+
"ui": {
|
|
332
|
+
"floorplans": { "Travel": "analyticalListPage" },
|
|
333
|
+
"overview": {
|
|
334
|
+
"title": "Travel Overview",
|
|
335
|
+
"cards": [
|
|
336
|
+
{ "type": "kpi", "entitySet": "Travel", "title": "Revenue", "measure": "TotalPrice" },
|
|
337
|
+
{ "type": "list", "entitySet": "Travel", "title": "Open travels", "filter": "OverallStatus eq 'O'", "top": 4 },
|
|
338
|
+
{ "type": "chart", "entitySet": "Travel", "title": "By currency", "chart": "ByCurrency" }
|
|
339
|
+
]
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
| Floorplan | Annotations read |
|
|
346
|
+
|---|---|
|
|
347
|
+
| `listReport` | `lineItem`, `selectionField`, `presentationVariant` |
|
|
348
|
+
| `worklist` | one tab per qualified `@UI.selectionVariant` (`filter: 'OverallStatus EQ ''O'''`) |
|
|
349
|
+
| `analyticalListPage` | the first `@UI.chart` (dimension, measures, `#COLUMN`, `#BAR`, `#LINE`, `#PIE`, `#DONUT`), read with `$apply` |
|
|
350
|
+
| `formEntry` | the Object Page, for creation only |
|
|
351
|
+
| `overview` | `kpi`, `list`, `table`, `chart` cards of `rapt/config.json` |
|
|
352
|
+
|
|
353
|
+
## 7. Developing: `rapt dev`
|
|
354
|
+
|
|
355
|
+
```sh
|
|
356
|
+
rapt dev my-project [--port 8080] [--host 0.0.0.0] [--mode enhanced]
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
- Builds the application, starts it with an embedded PGlite database (`.rapt/dev/data`),
|
|
360
|
+
rebuilds it on each save; a build in error keeps the previous one running.
|
|
361
|
+
- `http://localhost:8080/`: the **development launchpad** — the application (with the number of
|
|
362
|
+
its instances), the **documentation** (this documentation, with search), the `$metadata` and,
|
|
363
|
+
with `rapt/mcp.json`, the MCP server ([D49](DECISIONS.md)).
|
|
364
|
+
- Data kept between builds; database reset when the schema changes.
|
|
365
|
+
- No sign-in (`AUTH_MODE=none`); `DEV_ROLES` and `DEV_ATTRIBUTES` simulate a user and their
|
|
366
|
+
authorizations.
|
|
367
|
+
|
|
368
|
+
## 8. AI agents: MCP server
|
|
369
|
+
|
|
370
|
+
`rapt mcp` writes `rapt/mcp.json`; the application then serves `/mcp`: one tool per operation of
|
|
371
|
+
the service (list, read, create, update, delete, actions), run with the checks of the BO. Guide:
|
|
372
|
+
[MCP.md](MCP.md).
|
|
373
|
+
|
|
374
|
+
## 9. Launchpad
|
|
375
|
+
|
|
376
|
+
`rapt launchpad launchpad.json --out out/launchpad` builds an OpenUI5 launchpad in front of
|
|
377
|
+
several applications: a single origin, a single OIDC sign-in, tiles by role, counters, intent
|
|
378
|
+
navigation ([D37](DECISIONS.md)).
|
|
379
|
+
|
|
380
|
+
**One launchpad per workspace** ([D69](DECISIONS.md)): `launchpad.json`, titled "Launchpad", is
|
|
381
|
+
created next to the projects with the first application, then each application is added to it
|
|
382
|
+
when it is created — `rapt new` (complete BO) and the choice of the floorplan
|
|
383
|
+
(`rapt floorplan <src> <Set> <floorplan>`), or on demand `rapt launchpad add <src>`. The CLI looks
|
|
384
|
+
for the file in the project then its parent folders (up to the root of the git repository), and
|
|
385
|
+
otherwise creates it in the parent folder of the project; `--launchpad <file>` designates
|
|
386
|
+
another one, `--no-launchpad` adds nothing. The VS Code extension puts it next to the
|
|
387
|
+
`.code-workspace` (or in the first folder of the workspace). An application already present is
|
|
388
|
+
never changed: titles, tiles and roles are edited by hand.
|
|
389
|
+
|
|
390
|
+
```
|
|
391
|
+
rap-apps/
|
|
392
|
+
launchpad.json the launchpad of the workspace
|
|
393
|
+
helpdesk-tickets/ an abapGit project
|
|
394
|
+
project-tracker/
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
```json
|
|
398
|
+
{
|
|
399
|
+
"title": "Launchpad",
|
|
400
|
+
"apps": [
|
|
401
|
+
{ "id": "helpdesk-tickets", "source": "helpdesk-tickets", "url": "http://localhost:8081/" },
|
|
402
|
+
{ "id": "project-tracker", "source": "project-tracker", "url": "http://localhost:8082/" }
|
|
403
|
+
],
|
|
404
|
+
"groups": [{ "title": "Applications", "tiles": [
|
|
405
|
+
{ "title": "Tickets", "app": "helpdesk-tickets", "intent": "Ticket-manage", "icon": "sap-icon://list", "count": "Ticket" }
|
|
406
|
+
] }]
|
|
407
|
+
}
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
An application referenced by its sources (`source`) is built with the launchpad, in
|
|
411
|
+
`out/launchpad/apps/<id>`; `build` rather designates the folder of a `rapt build` done
|
|
412
|
+
separately. The content is organized in groups, or in **spaces and pages** ([D48](DECISIONS.md)):
|
|
413
|
+
|
|
414
|
+
```json
|
|
415
|
+
{
|
|
416
|
+
"title": "Travel Agency",
|
|
417
|
+
"apps": [{ "id": "travel", "build": "out/travel", "url": "http://localhost:8080/" }],
|
|
418
|
+
"spaces": [{
|
|
419
|
+
"title": "Travels", "roles": ["travel_agent"],
|
|
420
|
+
"pages": [{ "title": "Management", "sections": [{
|
|
421
|
+
"title": "Travel Management",
|
|
422
|
+
"tiles": [{ "title": "Manage Travels", "app": "travel", "intent": "Travel-manage",
|
|
423
|
+
"icon": "sap-icon://flight", "count": "Travel" }]
|
|
424
|
+
}] }]
|
|
425
|
+
}]
|
|
426
|
+
}
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
## 10. Shipping
|
|
430
|
+
|
|
431
|
+
Two ways to deploy ([D69](DECISIONS.md)):
|
|
432
|
+
|
|
433
|
+
- **the launchpad with all its applications**: `rapt launchpad launchpad.json --out
|
|
434
|
+
out/launchpad`; `docker compose up` in this folder starts the launchpad, each application and
|
|
435
|
+
their databases;
|
|
436
|
+
- **one application alone** (standalone, without a launchpad): `rapt build my-project --out
|
|
437
|
+
out/travel` (Node.js, Docker, Cloud Foundry).
|
|
438
|
+
|
|
439
|
+
In VS Code, *Build the application…* asks which one.
|
|
440
|
+
|
|
441
|
+
- `rapt abapgit my-project`: the XML files to import the repository into SAP with abapGit
|
|
442
|
+
(`--check` in CI).
|
|
443
|
+
- Deployment (Docker, SAP BTP Cloud Foundry, local network, HTTPS): [DEPLOYMENT.md](DEPLOYMENT.md).
|
|
444
|
+
|
|
445
|
+
The folder of a generated application:
|
|
446
|
+
|
|
447
|
+
```
|
|
448
|
+
model/model.json intermediate representation read by the runtime
|
|
449
|
+
db/schema.sql PostgreSQL tables and views (reference data of the standard views included)
|
|
450
|
+
odata/metadata.xml $metadata (CSDL with the UI annotations)
|
|
451
|
+
abap/ transpiled behavior pool; abap/src/: the ABAP given to the transpiler
|
|
452
|
+
ui/ OpenUI5 UI (List Report, Object Pages)
|
|
453
|
+
mcp/tools.json MCP tools (with rapt/mcp.json)
|
|
454
|
+
package.json, server.mjs, vendor/ startup; vendor/ bundles the runtime
|
|
455
|
+
Dockerfile, docker-compose.yml, keycloak/, manifest.yml container, PostgreSQL, Keycloak, Cloud Foundry
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
## 11. CLI reference
|
|
459
|
+
|
|
460
|
+
`rapt` comes with the VS Code extension (on the PATH of its terminals) or from npm
|
|
461
|
+
(`npm install -g open-rap-runtime`, [D65](DECISIONS.md)).
|
|
462
|
+
|
|
463
|
+
|
|
464
|
+
| Command | Purpose |
|
|
465
|
+
|---|---|
|
|
466
|
+
| `rapt check <src>` | diagnostics (`file:line:column: severity CODE message`), exit code 1 on error |
|
|
467
|
+
| `rapt build <src> --out <dir>` | generated application |
|
|
468
|
+
| `rapt dev <src>` | development loop |
|
|
469
|
+
| `rapt new <src> <Entity> [--prefix ZRT] [--description …]` | complete BO, added to the launchpad of the workspace |
|
|
470
|
+
| `rapt generate <src> <type> <name> [--from X] [--for Y] [--expose A,B] [--root]` | one object |
|
|
471
|
+
| `rapt floorplan <src> [<EntitySet> <floorplan>]` | floorplan of a root entity set; the application is added to the launchpad |
|
|
472
|
+
| `rapt abapgit <src> [--check]` | missing abapGit XML files |
|
|
473
|
+
| `rapt mcp <src>` | MCP tools (`rapt/mcp.json`) |
|
|
474
|
+
| `rapt launchpad <launchpad.json> --out <dir>` | launchpad, and the applications of their sources (`source`) |
|
|
475
|
+
| `rapt launchpad add <src> [--launchpad f]` | adds the application to the launchpad of the workspace (created when missing) |
|
|
476
|
+
| `rapt ir <src> [--out f]` | intermediate representation (JSON) |
|
|
477
|
+
| `rapt agent [<workspace>]` | MCP server (stdio) of rapt for AI coding agents (§13) |
|
|
478
|
+
|
|
479
|
+
Common options: `--service <SRVD>` (several service definitions), `--mode`, `--json` (output for
|
|
480
|
+
tools: one JSON object; one event per line for `rapt dev`), `--warnings-as-errors`. `rapt new`
|
|
481
|
+
and `rapt floorplan`: `--launchpad <file>` (another launchpad) and `--no-launchpad` (add nothing).
|
|
482
|
+
|
|
483
|
+
## 12. Environment variables of the application
|
|
484
|
+
|
|
485
|
+
| Variable | Default | Purpose |
|
|
486
|
+
|---|---|---|
|
|
487
|
+
| `PORT`, `HOST` | 8080, 0.0.0.0 | listening |
|
|
488
|
+
| `PUBLIC_URL` | `http://localhost:<PORT>/` | public address (OIDC); Cloud Foundry route |
|
|
489
|
+
| `DATABASE_URL`, `DATABASE_CA` | — | PostgreSQL and certificate; bound Cloud Foundry service |
|
|
490
|
+
| `PGLITE_DIR` | — | embedded database (development) |
|
|
491
|
+
| `SCHEMA` | `apply` | `skip`: schema managed separately |
|
|
492
|
+
| `SEED` | — | `auto`: initial data on the first start |
|
|
493
|
+
| `AUTH_MODE` | `none` | `oidc`: bearer tokens and browser sessions |
|
|
494
|
+
| `DEV_USER`, `DEV_ROLES`, `DEV_ATTRIBUTES` | — | development user |
|
|
495
|
+
| `DEV_OAUTH`, `DEV_OAUTH_CLIENTS` | `on` in `rapt dev` | development OAuth 2.0 server under `/oauth` (D60) |
|
|
496
|
+
| `OIDC_ISSUER`, `OIDC_CLIENT_ID`, `OIDC_CLIENT_SECRET`, `OIDC_AUDIENCE`, `OIDC_REQUIRED_ROLE` | — | identity provider |
|
|
497
|
+
| `SESSION_SECRET` | — | signature of the sessions (shared with the launchpad) |
|
|
498
|
+
| `AUTHORIZATIONS_FILE` | — | roles replacing `rapt/authorizations.json` |
|
|
499
|
+
| `DESTINATION_<NAME>_URL`, `_USER`, `_PASSWORD`, `_TOKEN`, `_HEADERS` | — | remote APIs |
|
|
500
|
+
| `MAIL_SMTP_URL`, `MAIL_FROM` | — | e-mails |
|
|
501
|
+
| `MCP` | — | `off`: no MCP server |
|
|
502
|
+
| `UI` | — | `off`: no UI |
|
|
503
|
+
| `LOG_LEVEL` | `info` | log |
|
|
504
|
+
|
|
505
|
+
## 12b. Web APIs and OAuth 2.0
|
|
506
|
+
|
|
507
|
+
A service bound as *OData V4 - Web API* (`BINDING_TYPE_CATEGORY` 1 in the SRVB, or
|
|
508
|
+
`rapt generate . binding ZAPI_TRAVEL_O4 --for ZUI_TRAVEL --binding-type webapi`) has neither UI
|
|
509
|
+
nor UI annotations; a draft BO only exposes its active instances there ([D60](DECISIONS.md)).
|
|
510
|
+
|
|
511
|
+
In development, `rapt dev` serves an OAuth 2.0 server under `/oauth`:
|
|
512
|
+
|
|
513
|
+
```sh
|
|
514
|
+
# client credentials (machine to machine)
|
|
515
|
+
curl -u rapt-client:rapt-secret -d grant_type=client_credentials http://localhost:8080/oauth/token
|
|
516
|
+
curl -H "Authorization: Bearer <access_token>" http://localhost:8080/sap/opu/odata4/…/Travel
|
|
517
|
+
|
|
518
|
+
# authorization code + PKCE (Postman, Bruno…): client rapt-pkce, without a secret
|
|
519
|
+
# Auth URL http://localhost:8080/oauth/authorize Token URL http://localhost:8080/oauth/token
|
|
520
|
+
# Code challenge method SHA-256; the sign-in page asks for the user and their roles
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
In production (`AUTH_MODE=oidc`), the tokens come from the IdP, with either flow; a *client
|
|
524
|
+
credentials* token acts on behalf of its client (technical user), with the roles of the token
|
|
525
|
+
(`OIDC_ROLES_CLAIM=scope` to read the scopes).
|
|
526
|
+
|
|
527
|
+
## 13. For an AI agent writing a BO
|
|
528
|
+
|
|
529
|
+
An agent uses rapt in either of two ways ([D64](DECISIONS.md)):
|
|
530
|
+
|
|
531
|
+
- **Commands**: `rapt check <src> --json` and the other commands of §11. In VS Code, `rapt` is on
|
|
532
|
+
the PATH of the integrated terminals; elsewhere, `npm install -g open-rap-runtime`.
|
|
533
|
+
- **MCP server** `rapt agent`: in VS Code, the agent mode finds it by itself (*Open RAP Runtime*
|
|
534
|
+
extension, setting `rapt.agent.enabled`). Other clients start it:
|
|
535
|
+
`claude mcp add rapt -- rapt agent .` (Claude Code), or in a `.mcp.json` file
|
|
536
|
+
`{ "mcpServers": { "rapt": { "command": "rapt", "args": ["agent", "."] } } }`.
|
|
537
|
+
|
|
538
|
+
| Tool | Purpose |
|
|
539
|
+
|---|---|
|
|
540
|
+
| `rapt_projects` | the RAP projects of the workspace |
|
|
541
|
+
| `rapt_check` | diagnostics of a project (compiled, nothing written) |
|
|
542
|
+
| `rapt_object_types` | the object types of `rapt_generate` and the floorplans |
|
|
543
|
+
| `rapt_generate`, `rapt_new_business_object` | create an object, or a complete business object |
|
|
544
|
+
| `rapt_floorplan`, `rapt_abapgit` | floorplan of the UI, abapGit XML files |
|
|
545
|
+
| `rapt_docs_search`, `rapt_docs_read` | the documentation of Open RAP Runtime (this guide, codes, annotations, known gaps…) |
|
|
546
|
+
|
|
547
|
+
Then:
|
|
548
|
+
|
|
549
|
+
1. Read the project (`src/`, `rapt/`); `rapt check <src> --json` gives the diagnostics with
|
|
550
|
+
absolute paths, line and column.
|
|
551
|
+
2. Write the sources as in ADT; for a new object, prefer `rapt generate` (right file names and
|
|
552
|
+
XML); for a new BO, `rapt new`.
|
|
553
|
+
3. After each change: `rapt check` until there are zero errors; the codes are explained in
|
|
554
|
+
[DIAGNOSTICS.md](DIAGNOSTICS.md); what is not supported is in
|
|
555
|
+
[KNOWN_GAPS.md](../KNOWN_GAPS.md) with the workaround.
|
|
556
|
+
4. Check the behavior: `rapt dev <src> --json` (`ready` event), then the OData
|
|
557
|
+
(`/sap/opu/odata4/…`) or the MCP server (`/mcp`).
|
|
558
|
+
5. Stay in `standard` mode if the BO must activate on SAP; only switch to `enhanced` for its
|
|
559
|
+
extensions, explicitly.
|
|
560
|
+
6. Never edit `.rapt/` nor the `<standard>/…` files (generated).
|