Generator: pilot analysis and fixes; G0002-G0021 tasks; handover notes merged

- Static bundle checks (name length, seed type, reserved words, contract test classes,
  testclasses_file), local abaplint parser check before SAP, max_tokens, robust JSON parse
- Runner: G2 for CDS views with parameters, contract_check detail in report
- G0020 and G0013 fixed by review and revalidated (oracle 100, null 0)
- Pilot results in docs/faz1-tasarim.md 11e; handover notes merged into CLAUDE.md and docs

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kral
2026-10-03 05:04:23 +02:00
parent 15eb9f1bb2
commit 5de5e2851c
162 changed files with 9943 additions and 23 deletions

View File

@@ -0,0 +1,19 @@
{
"id": "G0019",
"pool": "eval",
"object_type": "DDLS",
"category": "B",
"attempts": [
{
"stage": "validate",
"oracle": 0,
"null": 0
},
{
"stage": "validate",
"oracle": 100.0,
"null": 0
}
],
"accepted": true
}

View File

@@ -0,0 +1,109 @@
CLASS {{p}}t20_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
CLASS-DATA go_env TYPE REF TO if_cds_test_environment.
CLASS-METHODS class_setup.
CLASS-METHODS class_teardown.
METHODS setup.
METHODS small_count FOR TESTING.
METHODS medium_count FOR TESTING.
METHODS large_count FOR TESTING.
METHODS item_count FOR TESTING.
METHODS total_amount FOR TESTING.
METHODS cancelled_items_ignored FOR TESTING.
METHODS regions_in_result FOR TESTING.
METHODS class_boundaries FOR TESTING.
ENDCLASS.
CLASS {{p}}t20_hidden IMPLEMENTATION.
METHOD class_setup.
go_env = cl_cds_test_environment=>create( i_for_entity = '{{P}}I_SALES_CLASS' ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD setup.
DATA lt_sale TYPE STANDARD TABLE OF {{p}}sale WITH EMPTY KEY.
go_env->clear_doubles( ).
lt_sale = VALUE #(
( sale_id = 'S1' item_no = 1 region = 'AA' amount = '0.01' status = 'A' )
( sale_id = 'S1' item_no = 2 region = 'AA' amount = '99.99' status = 'A' )
( sale_id = 'S1' item_no = 3 region = 'AA' amount = '100.00' status = 'A' )
( sale_id = 'S1' item_no = 4 region = 'AA' amount = '999.99' status = 'A' )
( sale_id = 'S1' item_no = 5 region = 'AA' amount = '1000.00' status = 'A' )
( sale_id = 'S2' item_no = 1 region = 'BB' amount = '10.00' status = 'A' )
( sale_id = 'S2' item_no = 2 region = 'BB' amount = '20.00' status = 'X' )
( sale_id = 'S3' item_no = 1 region = 'CC' amount = '500.00' status = 'X' ) ).
go_env->insert_test_data( lt_sale ).
ENDMETHOD.
METHOD small_count.
SELECT SINGLE small_count FROM {{p}}i_sales_class WHERE region = 'AA' INTO @DATA(lv_aa).
SELECT SINGLE small_count FROM {{p}}i_sales_class WHERE region = 'BB' INTO @DATA(lv_bb).
cl_abap_unit_assert=>assert_equals( exp = CONV int8( 2 ) act = CONV int8( lv_aa ) ).
cl_abap_unit_assert=>assert_equals( exp = CONV int8( 1 ) act = CONV int8( lv_bb ) ).
ENDMETHOD.
METHOD medium_count.
SELECT SINGLE medium_count FROM {{p}}i_sales_class WHERE region = 'AA' INTO @DATA(lv_aa).
SELECT SINGLE medium_count FROM {{p}}i_sales_class WHERE region = 'BB' INTO @DATA(lv_bb).
cl_abap_unit_assert=>assert_equals( exp = CONV int8( 2 ) act = CONV int8( lv_aa ) ).
cl_abap_unit_assert=>assert_equals( exp = CONV int8( 0 ) act = CONV int8( lv_bb ) ).
ENDMETHOD.
METHOD large_count.
SELECT SINGLE large_count FROM {{p}}i_sales_class WHERE region = 'AA' INTO @DATA(lv_aa).
SELECT SINGLE large_count FROM {{p}}i_sales_class WHERE region = 'BB' INTO @DATA(lv_bb).
cl_abap_unit_assert=>assert_equals( exp = CONV int8( 1 ) act = CONV int8( lv_aa ) ).
cl_abap_unit_assert=>assert_equals( exp = CONV int8( 0 ) act = CONV int8( lv_bb ) ).
ENDMETHOD.
METHOD item_count.
SELECT SINGLE item_count FROM {{p}}i_sales_class WHERE region = 'AA' INTO @DATA(lv_aa).
SELECT SINGLE item_count FROM {{p}}i_sales_class WHERE region = 'BB' INTO @DATA(lv_bb).
cl_abap_unit_assert=>assert_equals( exp = CONV int8( 5 ) act = CONV int8( lv_aa ) ).
cl_abap_unit_assert=>assert_equals( exp = CONV int8( 1 ) act = CONV int8( lv_bb ) ).
ENDMETHOD.
METHOD total_amount.
SELECT SINGLE total_amount FROM {{p}}i_sales_class WHERE region = 'AA' INTO @DATA(lv_aa).
SELECT SINGLE total_amount FROM {{p}}i_sales_class WHERE region = 'BB' INTO @DATA(lv_bb).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '2199.99' )
act = CONV decfloat34( lv_aa ) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '10.00' )
act = CONV decfloat34( lv_bb ) ).
ENDMETHOD.
METHOD cancelled_items_ignored.
SELECT SINGLE item_count, total_amount FROM {{p}}i_sales_class
WHERE region = 'BB' INTO (@DATA(lv_count), @DATA(lv_total)).
cl_abap_unit_assert=>assert_equals( exp = CONV int8( 1 ) act = CONV int8( lv_count ) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '10.00' )
act = CONV decfloat34( lv_total ) ).
ENDMETHOD.
METHOD regions_in_result.
SELECT COUNT(*) FROM {{p}}i_sales_class INTO @DATA(lv_rows).
cl_abap_unit_assert=>assert_equals( exp = CONV int8( 2 ) act = CONV int8( lv_rows ) ).
SELECT SINGLE region FROM {{p}}i_sales_class WHERE region = 'CC' INTO @DATA(lv_region).
cl_abap_unit_assert=>assert_initial( act = lv_region ).
ENDMETHOD.
METHOD class_boundaries.
DATA lt_sale TYPE STANDARD TABLE OF {{p}}sale WITH EMPTY KEY.
go_env->clear_doubles( ).
lt_sale = VALUE #(
( sale_id = 'B1' item_no = 1 region = 'AA' amount = '99.99' status = 'A' )
( sale_id = 'B1' item_no = 2 region = 'AA' amount = '100.00' status = 'A' )
( sale_id = 'B1' item_no = 3 region = 'AA' amount = '1000.00' status = 'A' ) ).
go_env->insert_test_data( lt_sale ).
SELECT SINGLE small_count, medium_count, large_count FROM {{p}}i_sales_class
WHERE region = 'AA' INTO (@DATA(lv_small), @DATA(lv_medium), @DATA(lv_large)).
cl_abap_unit_assert=>assert_equals( exp = CONV int8( 1 ) act = CONV int8( lv_small ) ).
cl_abap_unit_assert=>assert_equals( exp = CONV int8( 1 ) act = CONV int8( lv_medium ) ).
cl_abap_unit_assert=>assert_equals( exp = CONV int8( 1 ) act = CONV int8( lv_large ) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,14 @@
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Sales items by region and size class'
define view entity {{P}}I_SALES_CLASS
as select from {{p}}sale
{
key region as region,
count( * ) as item_count,
sum( case when amount < 100 then 1 else 0 end ) as small_count,
sum( case when amount >= 100 and amount < 1000 then 1 else 0 end ) as medium_count,
sum( case when amount >= 1000 then 1 else 0 end ) as large_count,
sum( amount ) as total_amount
}
where status <> 'X'
group by region

View File

@@ -0,0 +1,50 @@
CLASS {{p}}t20_test DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
CLASS-DATA go_env TYPE REF TO if_cds_test_environment.
CLASS-METHODS class_setup.
CLASS-METHODS class_teardown.
METHODS setup.
METHODS class_counts FOR TESTING.
METHODS cancelled_region FOR TESTING.
ENDCLASS.
CLASS {{p}}t20_test IMPLEMENTATION.
METHOD class_setup.
go_env = cl_cds_test_environment=>create( i_for_entity = '{{P}}I_SALES_CLASS' ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD setup.
DATA lt_sale TYPE STANDARD TABLE OF {{p}}sale WITH EMPTY KEY.
go_env->clear_doubles( ).
lt_sale = VALUE #(
( sale_id = 'A1' item_no = 1 region = 'AA' amount = '50.00' status = 'A' )
( sale_id = 'A1' item_no = 2 region = 'AA' amount = '100.00' status = 'A' )
( sale_id = 'A1' item_no = 3 region = 'AA' amount = '1000.00' status = 'A' )
( sale_id = 'A2' item_no = 1 region = 'BB' amount = '25.00' status = 'X' ) ).
go_env->insert_test_data( lt_sale ).
ENDMETHOD.
METHOD class_counts.
SELECT SINGLE item_count, small_count, medium_count, large_count, total_amount
FROM {{p}}i_sales_class
WHERE region = 'AA'
INTO @DATA(ls_row).
cl_abap_unit_assert=>assert_equals( exp = CONV int8( 3 ) act = CONV int8( ls_row-item_count ) ).
cl_abap_unit_assert=>assert_equals( exp = CONV int8( 1 ) act = CONV int8( ls_row-small_count ) ).
cl_abap_unit_assert=>assert_equals( exp = CONV int8( 1 ) act = CONV int8( ls_row-medium_count ) ).
cl_abap_unit_assert=>assert_equals( exp = CONV int8( 1 ) act = CONV int8( ls_row-large_count ) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '1150.00' )
act = CONV decfloat34( ls_row-total_amount ) ).
ENDMETHOD.
METHOD cancelled_region.
SELECT COUNT(*) FROM {{p}}i_sales_class WHERE region = 'BB' INTO @DATA(lv_rows).
cl_abap_unit_assert=>assert_equals( exp = CONV int8( 0 ) act = CONV int8( lv_rows ) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,13 @@
@EndUserText.label : 'Sales item'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table {{p}}sale {
key client : abap.clnt not null;
key sale_id : abap.char(10) not null;
key item_no : abap.int4 not null;
region : abap.char(2);
amount : abap.dec(15,2);
status : abap.char(1) not null;
}

View File

@@ -0,0 +1,44 @@
# 1. Goal
Show how many sales items and how much sales value each region has, split into
three size classes. A report reads the result. The calculation must run in the
database, in a CDS view.
# 2. Open questions
None.
# 3. Context
- Table {{P}}SALE (sales item), package $TMP.
Key: SALE_ID (CHAR 10), ITEM_NO (INT4).
Fields: REGION (CHAR 2), AMOUNT (DEC 15,2), STATUS (CHAR 1).
- STATUS 'X' means that the item is cancelled.
# 4. Contract
- Create the CDS view entity {{P}}I_SALES_CLASS in package $TMP.
- Elements, with these names: REGION (key), ITEM_COUNT, SMALL_COUNT,
MEDIUM_COUNT, LARGE_COUNT, TOTAL_AMOUNT.
- No authorization check (#NOT_REQUIRED).
# 5. Business rules
1. Ignore every item with STATUS 'X'. Do not count it and do not add its
amount.
2. Show one row for each region that has at least one item that is not
cancelled. Do not show a region without such an item.
3. An item is small if its amount is less than 100.00.
4. An item is medium if its amount is 100.00 or more and less than 1000.00.
5. An item is large if its amount is 1000.00 or more.
6. ITEM_COUNT is the number of items of the region that are not cancelled.
7. SMALL_COUNT, MEDIUM_COUNT and LARGE_COUNT are the numbers of items of the
region in the three size classes.
8. TOTAL_AMOUNT is the sum of the amounts of all items of the region that are
not cancelled, with 2 decimals.
# 6. Constraints
- Release target: ABAP Platform 2025 (SAP_BASIS 816).
- Coding standards: Clean ABAP. Keep methods below 40 statements. Do not
create ATC findings of priority 1 or 2.
- Out of scope: do not change {{P}}SALE.
# 7. Acceptance
- The view is active and has no syntax error.
- The hidden tests pass.
- Write ABAP Unit tests with CL_CDS_TEST_ENVIRONMENT in a global test class.

View File

@@ -0,0 +1,60 @@
{
"id": "G0019",
"category": "B",
"object_type": "DDLS",
"difficulty": 2,
"release_target": "v816",
"expected_outcome": "implement",
"budget": {
"max_tool_calls": 40,
"max_activations": 10
},
"seed": [
{
"type": "TABL",
"name": "{{P}}SALE",
"file": "seed/sale.tabl.asabap",
"description": "Sales item"
}
],
"contract": [
{
"type": "DDLS",
"name": "{{P}}I_SALES_CLASS",
"fields": [
"REGION",
"ITEM_COUNT",
"SMALL_COUNT",
"MEDIUM_COUNT",
"LARGE_COUNT",
"TOTAL_AMOUNT"
]
}
],
"out_of_scope": [
"{{P}}SALE"
],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}T20_HIDDEN",
"file": "hidden/t20_hidden.clas.abap",
"description": "T20 hidden tests"
}
],
"reference": [
{
"type": "DDLS",
"name": "{{P}}I_SALES_CLASS",
"file": "reference/i_sales_class.ddls.asddls",
"description": "Sales items grouped by region with size classes"
},
{
"type": "CLAS",
"name": "{{P}}T20_TEST",
"file": "reference/t20_test.clas.abap",
"description": "T20 own tests"
}
],
"craft_checks": []
}