@linkup-ai/abap-ai 0.1.0

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.
Files changed (119) hide show
  1. package/README.md +389 -0
  2. package/dist/adt-client.js +383 -0
  3. package/dist/cli/activate.js +127 -0
  4. package/dist/cli/init.js +559 -0
  5. package/dist/cli/link.js +148 -0
  6. package/dist/cli/remove.js +83 -0
  7. package/dist/cli/status.js +231 -0
  8. package/dist/cli/systems.js +72 -0
  9. package/dist/cli.js +92 -0
  10. package/dist/index.js +1442 -0
  11. package/dist/knowledge/abap/abap-dictionary.md +199 -0
  12. package/dist/knowledge/abap/abap-sql.md +296 -0
  13. package/dist/knowledge/abap/amdp.md +273 -0
  14. package/dist/knowledge/abap/clean-code.md +293 -0
  15. package/dist/knowledge/abap/cloud-background-processing.md +250 -0
  16. package/dist/knowledge/abap/cloud-communication.md +265 -0
  17. package/dist/knowledge/abap/cloud-development.md +176 -0
  18. package/dist/knowledge/abap/cloud-extensibility.md +252 -0
  19. package/dist/knowledge/abap/cloud-released-apis.md +261 -0
  20. package/dist/knowledge/abap/constructor-expressions.md +289 -0
  21. package/dist/knowledge/abap/enhancements.md +232 -0
  22. package/dist/knowledge/abap/exceptions.md +271 -0
  23. package/dist/knowledge/abap/internal-tables.md +205 -0
  24. package/dist/knowledge/abap/object-orientation.md +298 -0
  25. package/dist/knowledge/abap/performance.md +216 -0
  26. package/dist/knowledge/abap/rap-abstract-entities.md +206 -0
  27. package/dist/knowledge/abap/rap-business-events.md +216 -0
  28. package/dist/knowledge/abap/rap-draft.md +191 -0
  29. package/dist/knowledge/abap/rap-eml.md +453 -0
  30. package/dist/knowledge/abap/rap-end-to-end.md +486 -0
  31. package/dist/knowledge/abap/rap-feature-control.md +185 -0
  32. package/dist/knowledge/abap/rap-numbering.md +280 -0
  33. package/dist/knowledge/abap/rap-service-exposure.md +163 -0
  34. package/dist/knowledge/abap/rap-unmanaged.md +468 -0
  35. package/dist/knowledge/abap/string-processing.md +180 -0
  36. package/dist/knowledge/abap/unit-testing.md +303 -0
  37. package/dist/knowledge/abap-cds/access-control.md +241 -0
  38. package/dist/knowledge/abap-cds/annotations.md +331 -0
  39. package/dist/knowledge/abap-cds/associations.md +254 -0
  40. package/dist/knowledge/abap-cds/expressions.md +230 -0
  41. package/dist/knowledge/abap-cds/functions.md +245 -0
  42. package/dist/knowledge/abap-cds/metadata-extensions.md +294 -0
  43. package/dist/knowledge/cap/authentication.md +278 -0
  44. package/dist/knowledge/cap/cdl-syntax.md +247 -0
  45. package/dist/knowledge/cap/cql-queries.md +266 -0
  46. package/dist/knowledge/cap/deployment.md +343 -0
  47. package/dist/knowledge/cap/event-handlers.md +287 -0
  48. package/dist/knowledge/cap/fiori-integration.md +303 -0
  49. package/dist/knowledge/cap/service-definitions.md +287 -0
  50. package/dist/knowledge/fiori/annotations.md +347 -0
  51. package/dist/knowledge/fiori/deployment.md +340 -0
  52. package/dist/knowledge/fiori/fiori-elements.md +332 -0
  53. package/dist/knowledge/fiori/fiori-side-effects.md +107 -0
  54. package/dist/knowledge/fiori/fiori-valuelist.md +144 -0
  55. package/dist/knowledge/fiori/ui5-controllers.md +358 -0
  56. package/dist/knowledge/fiori/ui5-data-binding.md +311 -0
  57. package/dist/knowledge/fiori/ui5-fragments-dialogs.md +330 -0
  58. package/dist/knowledge/fiori/ui5-manifest.md +411 -0
  59. package/dist/knowledge/fiori/ui5-routing.md +303 -0
  60. package/dist/knowledge/fiori/ui5-xml-views.md +294 -0
  61. package/dist/license-guard.js +81 -0
  62. package/dist/logger.js +114 -0
  63. package/dist/postinstall.js +165 -0
  64. package/dist/security-audit.js +136 -0
  65. package/dist/security-policy.js +322 -0
  66. package/dist/system-profile.js +207 -0
  67. package/dist/tools/abap-doc.js +72 -0
  68. package/dist/tools/abapgit.js +161 -0
  69. package/dist/tools/activate.js +71 -0
  70. package/dist/tools/atc-check.js +117 -0
  71. package/dist/tools/auth-object.js +56 -0
  72. package/dist/tools/breakpoints.js +76 -0
  73. package/dist/tools/call-hierarchy.js +84 -0
  74. package/dist/tools/cds-annotations.js +98 -0
  75. package/dist/tools/cds-dependencies.js +65 -0
  76. package/dist/tools/check.js +47 -0
  77. package/dist/tools/code-completion.js +70 -0
  78. package/dist/tools/code-coverage.js +111 -0
  79. package/dist/tools/create-amdp.js +111 -0
  80. package/dist/tools/create-dcl.js +81 -0
  81. package/dist/tools/create-transport.js +38 -0
  82. package/dist/tools/create.js +285 -0
  83. package/dist/tools/data-preview.js +37 -0
  84. package/dist/tools/delete.js +45 -0
  85. package/dist/tools/deploy-bsp.js +298 -0
  86. package/dist/tools/discovery.js +59 -0
  87. package/dist/tools/element-info.js +93 -0
  88. package/dist/tools/enhancements.js +186 -0
  89. package/dist/tools/extract-method.js +44 -0
  90. package/dist/tools/function-group.js +59 -0
  91. package/dist/tools/knowledge.js +275 -0
  92. package/dist/tools/lock-object.js +75 -0
  93. package/dist/tools/message-class.js +67 -0
  94. package/dist/tools/navigate.js +80 -0
  95. package/dist/tools/number-range.js +57 -0
  96. package/dist/tools/object-documentation.js +43 -0
  97. package/dist/tools/object-structure.js +78 -0
  98. package/dist/tools/object-versions.js +57 -0
  99. package/dist/tools/package-contents.js +60 -0
  100. package/dist/tools/pretty-printer.js +35 -0
  101. package/dist/tools/publish-binding.js +49 -0
  102. package/dist/tools/quick-fix.js +69 -0
  103. package/dist/tools/read.js +172 -0
  104. package/dist/tools/refactor-rename.js +60 -0
  105. package/dist/tools/release-transport.js +24 -0
  106. package/dist/tools/released-apis.js +51 -0
  107. package/dist/tools/repository-tree.js +90 -0
  108. package/dist/tools/scaffold-rap.js +642 -0
  109. package/dist/tools/search.js +73 -0
  110. package/dist/tools/shared/data-format.js +101 -0
  111. package/dist/tools/sql-console.js +17 -0
  112. package/dist/tools/system-info.js +271 -0
  113. package/dist/tools/traces.js +66 -0
  114. package/dist/tools/transport-contents.js +83 -0
  115. package/dist/tools/transports.js +68 -0
  116. package/dist/tools/unit-test.js +135 -0
  117. package/dist/tools/where-used.js +59 -0
  118. package/dist/tools/write.js +120 -0
  119. package/package.json +50 -0
@@ -0,0 +1,273 @@
1
+ # AMDP — ABAP Managed Database Procedures (HANA SQLScript)
2
+
3
+ ## Basic AMDP Method
4
+
5
+ ```abap
6
+ CLASS zcl_order_amdp DEFINITION PUBLIC FINAL CREATE PUBLIC.
7
+ PUBLIC SECTION.
8
+ INTERFACES if_amdp_marker_hdb. " marks class as AMDP-enabled for HANA
9
+
10
+ TYPES: BEGIN OF ty_order_summary,
11
+ customer_id TYPE kunnr,
12
+ order_count TYPE i,
13
+ total_amount TYPE netwr,
14
+ currency_code TYPE waers,
15
+ END OF ty_order_summary.
16
+
17
+ METHODS get_order_summary
18
+ IMPORTING VALUE(iv_min_amount) TYPE netwr
19
+ EXPORTING VALUE(et_result) TYPE STANDARD TABLE OF ty_order_summary.
20
+
21
+ ENDCLASS.
22
+
23
+ CLASS zcl_order_amdp IMPLEMENTATION.
24
+
25
+ METHOD get_order_summary BY DATABASE PROCEDURE FOR HDB
26
+ LANGUAGE SQLSCRIPT OPTIONS READ-ONLY
27
+ USING ztab_order.
28
+
29
+ et_result = SELECT customer_id,
30
+ COUNT(*) AS order_count,
31
+ SUM( total_amount ) AS total_amount,
32
+ currency_code
33
+ FROM ztab_order
34
+ WHERE total_amount >= :iv_min_amount
35
+ GROUP BY customer_id, currency_code
36
+ ORDER BY total_amount DESC;
37
+
38
+ ENDMETHOD.
39
+
40
+ ENDCLASS.
41
+ ```
42
+
43
+ ## AMDP Function (Table Function for CDS)
44
+
45
+ ```abap
46
+ CLASS zcl_order_amdp DEFINITION PUBLIC FINAL CREATE PUBLIC.
47
+ PUBLIC SECTION.
48
+ INTERFACES if_amdp_marker_hdb.
49
+
50
+ CLASS-METHODS get_ranked_orders
51
+ FOR TABLE FUNCTION ZTF_RankedOrders.
52
+ ENDCLASS.
53
+
54
+ CLASS zcl_order_amdp IMPLEMENTATION.
55
+
56
+ METHOD get_ranked_orders BY DATABASE FUNCTION FOR HDB
57
+ LANGUAGE SQLSCRIPT OPTIONS READ-ONLY
58
+ USING ztab_order ztab_customer.
59
+
60
+ RETURN SELECT o.order_id,
61
+ o.customer_id,
62
+ c.name AS customer_name,
63
+ o.total_amount,
64
+ o.currency_code,
65
+ ROW_NUMBER() OVER (
66
+ PARTITION BY o.customer_id
67
+ ORDER BY o.total_amount DESC
68
+ ) AS rank
69
+ FROM ztab_order AS o
70
+ INNER JOIN ztab_customer AS c
71
+ ON o.customer_id = c.customer_id;
72
+
73
+ ENDMETHOD.
74
+
75
+ ENDCLASS.
76
+ ```
77
+
78
+ ### CDS Table Function
79
+
80
+ ```abap
81
+ @EndUserText.label: 'Ranked Orders'
82
+ define table function ZTF_RankedOrders
83
+ returns
84
+ {
85
+ key order_id : abap.numc(10);
86
+ customer_id : kunnr;
87
+ customer_name : abap.char(40);
88
+ total_amount : abap.curr(17,2);
89
+ currency_code : abap.cuky(5);
90
+ rank : abap.int4;
91
+ }
92
+ implemented by method zcl_order_amdp=>get_ranked_orders;
93
+ ```
94
+
95
+ ### Consume in CDS View
96
+
97
+ ```abap
98
+ define view entity ZI_RankedOrders as select from ZTF_RankedOrders
99
+ {
100
+ key order_id as OrderID,
101
+ customer_id as CustomerID,
102
+ customer_name as CustomerName,
103
+ @Semantics.amount.currencyCode: 'CurrencyCode'
104
+ total_amount as TotalAmount,
105
+ currency_code as CurrencyCode,
106
+ rank as Rank
107
+ }
108
+ where rank <= 10
109
+ ```
110
+
111
+ ## SQLScript Patterns
112
+
113
+ ### Variables and Control Flow
114
+
115
+ ```sql
116
+ DECLARE lv_count INTEGER;
117
+ DECLARE lv_threshold DECIMAL(17,2) := 1000.00;
118
+
119
+ SELECT COUNT(*) INTO lv_count FROM ztab_order;
120
+
121
+ IF lv_count > 0 THEN
122
+ -- process
123
+ ELSEIF lv_count = 0 THEN
124
+ -- empty
125
+ END IF;
126
+
127
+ WHILE lv_count > 0 DO
128
+ lv_count := lv_count - 1;
129
+ END WHILE;
130
+
131
+ FOR i IN 1..10 DO
132
+ -- loop body
133
+ END FOR;
134
+ ```
135
+
136
+ ### Temporary Tables (Table Variables)
137
+
138
+ ```sql
139
+ lt_filtered = SELECT * FROM ztab_order WHERE status = 'O';
140
+
141
+ lt_enriched = SELECT f.order_id,
142
+ f.customer_id,
143
+ c.name AS customer_name,
144
+ f.total_amount
145
+ FROM :lt_filtered AS f
146
+ INNER JOIN ztab_customer AS c
147
+ ON f.customer_id = c.customer_id;
148
+
149
+ et_result = SELECT * FROM :lt_enriched WHERE total_amount > :iv_min;
150
+ ```
151
+
152
+ ### Window Functions
153
+
154
+ ```sql
155
+ et_result = SELECT order_id,
156
+ customer_id,
157
+ total_amount,
158
+ ROW_NUMBER() OVER (ORDER BY total_amount DESC) AS row_num,
159
+ RANK() OVER (ORDER BY total_amount DESC) AS ranking,
160
+ SUM(total_amount) OVER () AS grand_total,
161
+ SUM(total_amount) OVER (PARTITION BY customer_id) AS customer_total,
162
+ AVG(total_amount) OVER (
163
+ ORDER BY created_at
164
+ ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
165
+ ) AS moving_avg_3
166
+ FROM ztab_order;
167
+ ```
168
+
169
+ ### String Functions
170
+
171
+ ```sql
172
+ CONCAT(first_name, ' ', last_name)
173
+ UPPER(name)
174
+ LOWER(name)
175
+ LENGTH(description)
176
+ SUBSTR(text, 1, 10)
177
+ REPLACE(phone, '-', '')
178
+ LPAD(order_id, 10, '0')
179
+ TRIM(BOTH ' ' FROM name)
180
+ LOCATE(email, '@') -- position of @ (0 if not found)
181
+ ```
182
+
183
+ ### Date Functions
184
+
185
+ ```sql
186
+ CURRENT_DATE
187
+ CURRENT_TIMESTAMP
188
+ ADD_DAYS(order_date, 7)
189
+ ADD_MONTHS(order_date, 1)
190
+ DAYS_BETWEEN(start_date, end_date)
191
+ EXTRACT(YEAR FROM order_date)
192
+ TO_DATE('2026-03-15', 'YYYY-MM-DD')
193
+ ```
194
+
195
+ ## AMDP with OUT Parameter (Scalar)
196
+
197
+ ```abap
198
+ METHODS get_order_count
199
+ IMPORTING VALUE(iv_status) TYPE char1
200
+ EXPORTING VALUE(ev_count) TYPE i.
201
+
202
+ METHOD get_order_count BY DATABASE PROCEDURE FOR HDB
203
+ LANGUAGE SQLSCRIPT OPTIONS READ-ONLY
204
+ USING ztab_order.
205
+
206
+ SELECT COUNT(*) INTO ev_count
207
+ FROM ztab_order
208
+ WHERE status = :iv_status;
209
+
210
+ ENDMETHOD.
211
+ ```
212
+
213
+ ## AMDP with Multiple Results
214
+
215
+ ```abap
216
+ METHODS get_order_report
217
+ IMPORTING VALUE(iv_year) TYPE numc4
218
+ EXPORTING VALUE(et_summary) TYPE tt_summary
219
+ VALUE(et_detail) TYPE tt_detail.
220
+
221
+ METHOD get_order_report BY DATABASE PROCEDURE FOR HDB
222
+ LANGUAGE SQLSCRIPT OPTIONS READ-ONLY
223
+ USING ztab_order ztab_order_item.
224
+
225
+ et_summary = SELECT customer_id, COUNT(*) AS cnt, SUM(total_amount) AS total
226
+ FROM ztab_order
227
+ WHERE EXTRACT(YEAR FROM created_at) = :iv_year
228
+ GROUP BY customer_id;
229
+
230
+ et_detail = SELECT o.order_id, o.customer_id, i.material, i.quantity, i.amount
231
+ FROM ztab_order AS o
232
+ INNER JOIN ztab_order_item AS i ON o.order_id = i.order_id
233
+ WHERE EXTRACT(YEAR FROM o.created_at) = :iv_year;
234
+
235
+ ENDMETHOD.
236
+ ```
237
+
238
+ ## Calling AMDP from ABAP
239
+
240
+ ```abap
241
+ DATA(lo_amdp) = NEW zcl_order_amdp( ).
242
+
243
+ lo_amdp->get_order_summary(
244
+ EXPORTING iv_min_amount = 1000
245
+ IMPORTING et_result = DATA(lt_summary) ).
246
+
247
+ LOOP AT lt_summary INTO DATA(ls_sum).
248
+ " process
249
+ ENDLOOP.
250
+ ```
251
+
252
+ ## Rules
253
+ - Class MUST implement `if_amdp_marker_hdb`
254
+ - Method signature: `BY DATABASE PROCEDURE FOR HDB LANGUAGE SQLSCRIPT`
255
+ - `OPTIONS READ-ONLY` for read operations (enables parallel execution)
256
+ - `USING <table1> <table2>` — list ALL DB tables accessed (mandatory)
257
+ - Table function methods must be `CLASS-METHODS` (static)
258
+ - Parameters: always `VALUE(...)` (pass by value required)
259
+ - Use `:param_name` to reference ABAP parameters in SQLScript
260
+ - Use `:lt_variable` to reference table variables
261
+ - AMDP runs on HANA only — not available on other databases
262
+
263
+ ## Anti-Patterns
264
+ | Anti-Pattern | Correct |
265
+ |---|---|
266
+ | Missing `if_amdp_marker_hdb` interface | Required for all AMDP classes |
267
+ | Missing `USING` clause for accessed tables | List every table accessed |
268
+ | `OPTIONS READ-ONLY` on methods that modify data | Remove for write operations |
269
+ | Complex logic that could be CDS | Use CDS for simple joins/aggregations |
270
+ | AMDP for simple SELECT | Use ABAP SQL — AMDP only for HANA-specific features |
271
+ | Instance method for table function | Must be `CLASS-METHODS` (static) |
272
+ | Passing internal table by reference | AMDP requires `VALUE(...)` |
273
+ | Using AMDP on non-HANA system | AMDP is HANA-only |
@@ -0,0 +1,293 @@
1
+ # ABAP Clean Code — naming, conventions, structure, readability
2
+
3
+ ## Naming Conventions — Prefixes
4
+
5
+ ### Objects (Repository)
6
+
7
+ | Prefix | Object Type | Example |
8
+ |--------|-------------|---------|
9
+ | `Z` or `Y` | Customer namespace | `ZORDER`, `YHR_PAYROLL` |
10
+ | `ZCL_` | Class | `ZCL_ORDER_PROCESSOR` |
11
+ | `ZIF_` | Interface | `ZIF_ORDER_SERVICE` |
12
+ | `ZCX_` | Exception class | `ZCX_ORDER_ERROR` |
13
+ | `ZCM_` | RAP message class (behavior) | `ZCM_ORDER` |
14
+ | `ZBP_` | RAP behavior pool | `ZBP_I_ORDER` |
15
+ | `ZBP_BX_` | RAP behavior extension pool | `ZBP_BX_I_SALESORDER` |
16
+ | `ZI_` | CDS Interface view (RAP) | `ZI_ORDER` |
17
+ | `ZC_` | CDS Projection/Consumption view | `ZC_ORDER` |
18
+ | `ZA_` | CDS Abstract entity | `ZA_REJECT_PARAMS` |
19
+ | `ZR_` | CDS Restricted reuse view | `ZR_ORDER_BASE` |
20
+ | `ZUI_` | Service Definition | `ZUI_ORDER` |
21
+ | `ZTAB_` or `Z` | Database table | `ZTAB_ORDER` |
22
+ | `ZS_` | Structure type (DDIC) | `ZS_ORDER_ITEM` |
23
+ | `ZTT_` | Table type (DDIC) | `ZTT_ORDER_ITEMS` |
24
+ | `ZDOM_` | Domain | `ZDOM_ORDER_STATUS` |
25
+ | `ZDTEL_` | Data element | `ZDTEL_ORDER_ID` |
26
+
27
+ ### Variables (Local)
28
+
29
+ | Prefix | Scope | Example |
30
+ |--------|-------|---------|
31
+ | `lv_` | Local variable | `lv_order_id` |
32
+ | `lt_` | Local table | `lt_orders` |
33
+ | `ls_` | Local structure | `ls_order` |
34
+ | `lr_` | Local reference | `lr_data` |
35
+ | `lo_` | Local object reference | `lo_processor` |
36
+ | `lx_` | Local exception reference | `lx_error` |
37
+
38
+ ### Variables (Method Parameters)
39
+
40
+ | Prefix | Direction | Example |
41
+ |--------|-----------|---------|
42
+ | `iv_` | IMPORTING value | `iv_order_id` |
43
+ | `ir_` | IMPORTING reference | `ir_data` |
44
+ | `io_` | IMPORTING object | `io_service` |
45
+ | `ev_` | EXPORTING value | `ev_result` |
46
+ | `et_` | EXPORTING table | `et_items` |
47
+ | `es_` | EXPORTING structure | `es_header` |
48
+ | `cv_` | CHANGING value | `cv_counter` |
49
+ | `ct_` | CHANGING table | `ct_items` |
50
+ | `rv_` | RETURNING value | `rv_success` |
51
+ | `rt_` | RETURNING table | `rt_items` |
52
+ | `rs_` | RETURNING structure | `rs_result` |
53
+ | `ro_` | RETURNING object | `ro_instance` |
54
+
55
+ ### Variables (Class Attributes)
56
+
57
+ | Prefix | Scope | Example |
58
+ |--------|-------|---------|
59
+ | `mv_` | Instance attribute (value) | `mv_order_id` |
60
+ | `mt_` | Instance attribute (table) | `mt_items` |
61
+ | `ms_` | Instance attribute (structure) | `ms_config` |
62
+ | `mo_` | Instance attribute (object) | `mo_logger` |
63
+ | `gv_` | Static attribute (value) | `gv_counter` |
64
+ | `gt_` | Static attribute (table) | `gt_cache` |
65
+ | `go_` | Static attribute (object) | `go_singleton` |
66
+
67
+ ### Constants
68
+
69
+ | Prefix | Example |
70
+ |--------|---------|
71
+ | `c_` or `mc_` | `c_status_open`, `mc_max_retries` |
72
+ | `gc_` | Static constant `gc_version` |
73
+
74
+ ### Field Symbols and Data References
75
+
76
+ | Prefix | Example |
77
+ |--------|---------|
78
+ | `<ls_>` or `<fs_>` | `<ls_order>`, `<fs_item>` |
79
+ | `lr_` | Data reference `lr_data` |
80
+
81
+ ## CDS Naming Conventions
82
+
83
+ ```
84
+ Interface views: ZI_OrderHeader, ZI_OrderItem
85
+ Projection views: ZC_OrderHeader, ZC_OrderItem
86
+ Abstract entities: ZA_RejectParams, ZA_OrderResult
87
+ Service Definition: ZUI_ORDER
88
+ Service Binding: ZUI_ORDER_O4 (V4), ZUI_ORDER_O2 (V2)
89
+ Metadata Extension: ZC_OrderHeader (same name as projection)
90
+ Access Control: ZI_OrderHeader (same name as CDS view)
91
+
92
+ Field names: CamelCase in CDS → OrderID, CustomerName, TotalAmount
93
+ Association prefix: _Customer, _Items, _Currency (underscore prefix)
94
+ ```
95
+
96
+ ## Method Design
97
+
98
+ ```abap
99
+ " GOOD: focused, single responsibility, < 30 lines
100
+ METHOD validate_customer.
101
+ IF iv_customer_id IS INITIAL.
102
+ RAISE EXCEPTION TYPE zcx_order_error
103
+ EXPORTING textid = zcx_order_error=>customer_required.
104
+ ENDIF.
105
+ IF NOT customer_exists( iv_customer_id ).
106
+ RAISE EXCEPTION TYPE zcx_order_error
107
+ EXPORTING textid = zcx_order_error=>customer_not_found
108
+ mv_customer_id = iv_customer_id.
109
+ ENDIF.
110
+ ENDMETHOD.
111
+
112
+ " BAD: doing too much
113
+ METHOD process_order.
114
+ " 200 lines: validates, calculates, saves, sends email, logs...
115
+ ENDMETHOD.
116
+ ```
117
+
118
+ ```abap
119
+ " Prefer RETURNING over EXPORTING for single outputs (enables chaining)
120
+ " GOOD:
121
+ METHODS get_status RETURNING VALUE(rv_status) TYPE char1.
122
+ DATA(lv_status) = lo_order->get_status( ).
123
+
124
+ " AVOID for single output:
125
+ METHODS get_status EXPORTING ev_status TYPE char1.
126
+ lo_order->get_status( IMPORTING ev_status = DATA(lv_status) ).
127
+ ```
128
+
129
+ ## Boolean Handling
130
+
131
+ ```abap
132
+ " Use abap_bool / abap_true / abap_false
133
+ DATA lv_valid TYPE abap_bool.
134
+ lv_valid = abap_true.
135
+
136
+ IF lv_valid = abap_true.
137
+ " Or simply:
138
+ IF lv_valid IS NOT INITIAL.
139
+
140
+ " AVOID:
141
+ DATA lv_flag TYPE c LENGTH 1 VALUE 'X'.
142
+ IF lv_flag = 'X'.
143
+ ```
144
+
145
+ ## Modern ABAP Patterns
146
+
147
+ ```abap
148
+ " Inline declarations — ALWAYS for local variables
149
+ DATA(lv_count) = lines( lt_items ).
150
+ DATA(lo_proc) = NEW zcl_processor( ).
151
+ LOOP AT lt_items ASSIGNING FIELD-SYMBOL(<ls_item>).
152
+
153
+ " NOT:
154
+ DATA lv_count TYPE i.
155
+ lv_count = lines( lt_items ).
156
+ DATA lo_proc TYPE REF TO zcl_processor.
157
+ CREATE OBJECT lo_proc.
158
+
159
+ " Constructor expressions over imperative
160
+ DATA(lt_filtered) = FILTER #( lt_items WHERE status = 'A' ).
161
+ DATA(lv_label) = COND string( WHEN lv_type = 'A' THEN 'Active' ELSE 'Other' ).
162
+ DATA(ls_copy) = CORRESPONDING zs_target( ls_source ).
163
+
164
+ " NOT:
165
+ LOOP AT lt_items INTO ls_item WHERE status = 'A'.
166
+ APPEND ls_item TO lt_filtered.
167
+ ENDLOOP.
168
+
169
+ " String templates over CONCATENATE
170
+ DATA(lv_msg) = |Order { lv_id } for { lv_customer }|.
171
+ " NOT:
172
+ CONCATENATE 'Order' lv_id 'for' lv_customer INTO lv_msg SEPARATED BY space.
173
+ ```
174
+
175
+ ## Error Handling
176
+
177
+ ```abap
178
+ " Specific exceptions, never cx_root
179
+ TRY.
180
+ lo_service->process( iv_data ).
181
+ CATCH zcx_order_error INTO DATA(lx_order).
182
+ " Handle business error
183
+ CATCH cx_sy_move_cast_error INTO DATA(lx_cast).
184
+ " Handle technical error
185
+ ENDTRY.
186
+
187
+ " Never empty CATCH
188
+ " BAD:
189
+ TRY.
190
+ lo_service->process( ).
191
+ CATCH cx_root. " Swallows everything silently
192
+ ENDTRY.
193
+ ```
194
+
195
+ ## Class Structure
196
+
197
+ ```abap
198
+ CLASS zcl_order_service DEFINITION PUBLIC FINAL CREATE PUBLIC.
199
+ PUBLIC SECTION.
200
+ " 1. Interfaces
201
+ INTERFACES zif_order_service.
202
+
203
+ " 2. Types and constants
204
+ TYPES ty_order_id TYPE numc10.
205
+ CONSTANTS c_max_items TYPE i VALUE 999.
206
+
207
+ " 3. Constructor
208
+ METHODS constructor IMPORTING io_repo TYPE REF TO zif_order_repo.
209
+
210
+ " 4. Public methods (business API)
211
+ METHODS create_order
212
+ IMPORTING is_order TYPE zs_order_data
213
+ RETURNING VALUE(rv_id) TYPE ty_order_id
214
+ RAISING zcx_order_error.
215
+
216
+ PRIVATE SECTION.
217
+ " 5. Instance attributes
218
+ DATA mo_repo TYPE REF TO zif_order_repo.
219
+
220
+ " 6. Private methods (internal helpers)
221
+ METHODS validate IMPORTING is_order TYPE zs_order_data RAISING zcx_order_error.
222
+ METHODS calculate_total IMPORTING it_items TYPE ztt_items RETURNING VALUE(rv_total) TYPE netwr.
223
+ ENDCLASS.
224
+ ```
225
+
226
+ ## RAP Naming
227
+
228
+ ```abap
229
+ " Handler methods — match BDEF names
230
+ METHODS validateDates FOR VALIDATE ON SAVE IMPORTING keys FOR Travel~validateDates.
231
+ METHODS setTravelID FOR DETERMINE ON MODIFY IMPORTING keys FOR Travel~setTravelID.
232
+ METHODS acceptTravel FOR MODIFY IMPORTING keys FOR ACTION Travel~acceptTravel.
233
+ METHODS get_instance_features FOR INSTANCE FEATURES IMPORTING keys ... FOR Travel RESULT result.
234
+ METHODS get_global_authorizations FOR GLOBAL AUTHORIZATION IMPORTING REQUEST ... FOR Travel RESULT result.
235
+
236
+ " Local handler class naming
237
+ CLASS lhc_travel DEFINITION INHERITING FROM cl_abap_behavior_handler.
238
+ " lhc_ = local handler class
239
+ " lsc_ = local saver class
240
+
241
+ CLASS lsc_travel DEFINITION INHERITING FROM cl_abap_behavior_saver.
242
+ ```
243
+
244
+ ## Comments
245
+
246
+ ```abap
247
+ " Comment WHAT, not HOW (code should be self-documenting)
248
+
249
+ " GOOD:
250
+ " Check credit limit before order confirmation
251
+ IF ls_order-total > get_credit_limit( ls_order-customer ).
252
+
253
+ " BAD:
254
+ " If total is greater than credit limit
255
+ IF ls_order-total > get_credit_limit( ls_order-customer ).
256
+
257
+ " GOOD: explain WHY for non-obvious decisions
258
+ " RFC module returns status in legacy format (1=open, 2=closed)
259
+ " Must map to our domain values
260
+ DATA(lv_status) = SWITCH #( lv_rfc_status WHEN 1 THEN 'O' WHEN 2 THEN 'C' ).
261
+
262
+ " No comments needed for self-evident code:
263
+ DATA(lv_total) = REDUCE netwr( INIT s = 0 FOR wa IN lt_items NEXT s = s + wa-amount ).
264
+ ```
265
+
266
+ ## Rules
267
+ - BEFORE modifying existing objects, check version history (abap_object_versions) to verify alignment with PRD and detect pending transports from other developers
268
+ - ALWAYS use Hungarian notation prefixes (lv_, lt_, iv_, mv_, etc.)
269
+ - ALWAYS use `FINAL` on classes unless inheritance is explicitly needed
270
+ - ALWAYS use inline declarations: `DATA( )`, `FIELD-SYMBOL( )`
271
+ - ALWAYS use constructor expressions over imperative statements
272
+ - ALWAYS use string templates `| |` over CONCATENATE
273
+ - Methods: max ~30 lines, single responsibility
274
+ - Prefer RETURNING over EXPORTING for single output
275
+ - Prefer interfaces over concrete class references (dependency injection)
276
+ - Use `abap_bool` / `abap_true` / `abap_false` for booleans
277
+ - CDS: CamelCase fields, _Underscore associations
278
+
279
+ ## Anti-Patterns
280
+ | Anti-Pattern | Correct |
281
+ |---|---|
282
+ | `DATA lv_x TYPE string. lv_x = 'hello'.` | `DATA(lv_x) = 'hello'.` |
283
+ | `CREATE OBJECT lo_ref TYPE zcl_class` | `DATA(lo_ref) = NEW zcl_class( )` |
284
+ | `MOVE-CORRESPONDING src TO tgt` | `tgt = CORRESPONDING #( src )` |
285
+ | `CONCATENATE a b INTO c` | `c = \|{ a }{ b }\|` |
286
+ | `IF lv_flag = 'X'` | `IF lv_flag = abap_true` |
287
+ | Variable name `lv_x`, `lv_tmp`, `lv_data` | Descriptive: `lv_order_status`, `lv_total_amount` |
288
+ | Method with 200+ lines | Split into focused helper methods |
289
+ | Public attributes modified externally | Private attributes + getter/setter methods |
290
+ | `CATCH cx_root` silently | Catch specific exceptions, always handle |
291
+ | Comments describing WHAT code does | Comment WHY for non-obvious decisions |
292
+ | `DATA lo_ref TYPE REF TO zcl_concrete` | `DATA lo_ref TYPE REF TO zif_interface` |
293
+ | Class without FINAL | Add FINAL unless subclassing is explicitly needed |