Step F first pass: 81/92 accepted; budget floor 60 calls; rejected slots moved for regeneration

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014aUaQeLnwbb1zTpN7kHeat
This commit is contained in:
Kral
2026-10-03 12:10:52 +02:00
parent d3250acfb8
commit 39769afce8
741 changed files with 40573 additions and 317 deletions

View File

@@ -0,0 +1,17 @@
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Machine readings per day'
define view entity {{P}}I_MACHINE_DAY
as select from {{p}}sensor as sen
left outer join {{p}}mach as mac on mac.machine_id = sen.machine_id
{
key sen.machine_id as machine_id,
key sen.reading_date as reading_date,
mac.machine_name as machine_name,
mac.plant as plant,
count( * ) as reading_count,
avg( sen.reading_value as abap.dec(15,2) ) as avg_value,
max( sen.reading_value ) as max_value,
sum( case when sen.reading_value > 80.00 then 1 else 0 end ) as alert_count
}
where sen.sensor = 'TEMP'
group by sen.machine_id, sen.reading_date, mac.machine_name, mac.plant

View File

@@ -0,0 +1,17 @@
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Machine readings per day'
define view entity {{P}}I_MACHINE_DAY
as select from {{p}}sensor as sen
inner join {{p}}mach as mac on mac.machine_id = sen.machine_id
{
key sen.machine_id as machine_id,
key sen.reading_date as reading_date,
mac.machine_name as machine_name,
mac.plant as plant,
count( * ) as reading_count,
avg( sen.reading_value as abap.dec(15,2) ) as avg_value,
max( sen.reading_value ) as max_value,
sum( case when sen.reading_value <= 80.00 then 1 else 0 end ) as alert_count
}
where sen.sensor = 'TEMP'
group by sen.machine_id, sen.reading_date, mac.machine_name, mac.plant

View File

@@ -0,0 +1,17 @@
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Machine readings per day'
define view entity {{P}}I_MACHINE_DAY
as select from {{p}}sensor as sen
inner join {{p}}mach as mac on mac.machine_id = sen.machine_id
{
key sen.machine_id as machine_id,
key sen.reading_date as reading_date,
mac.machine_name as machine_name,
mac.plant as plant,
count( * ) as reading_count,
avg( sen.reading_value as abap.dec(15,2) ) as avg_value,
max( sen.reading_value ) as max_value,
sum( case when sen.reading_value > 80.00 then 2 else 0 end ) as alert_count
}
where sen.sensor = 'TEMP'
group by sen.machine_id, sen.reading_date, mac.machine_name, mac.plant

View File

@@ -0,0 +1,17 @@
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Machine readings per day'
define view entity {{P}}I_MACHINE_DAY
as select from {{p}}sensor as sen
inner join {{p}}mach as mac on mac.machine_id = sen.machine_id
{
key sen.machine_id as machine_id,
key sen.reading_date as reading_date,
mac.machine_name as machine_name,
mac.plant as plant,
count( * ) as reading_count,
avg( sen.reading_value as abap.dec(15,2) ) as avg_value,
max( sen.reading_value ) as max_value,
sum( case when sen.reading_value > 80.00 then 1 else 0 end ) as alert_count
}
where sen.sensor = 'ZEMP'
group by sen.machine_id, sen.reading_date, mac.machine_name, mac.plant

View File

@@ -0,0 +1,29 @@
{
"id": "G0155",
"pool": "eval",
"object_type": "DDLS",
"category": "F",
"attempts": [
{
"stage": "validate",
"oracle": 0,
"null": 0
},
{
"stage": "validate",
"oracle": 0,
"null": 0
},
{
"stage": "validate",
"oracle": 100.0,
"null": 0,
"mutation": {
"valid": 4,
"killed": 4,
"ok": true
}
}
],
"accepted": true
}

View File

@@ -0,0 +1,117 @@
CLASS {{p}}t41_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 counts_readings FOR TESTING.
METHODS average_value FOR TESTING.
METHODS max_value FOR TESTING.
METHODS alerts_counted FOR TESTING.
METHODS no_alert_at_limit FOR TESTING.
METHODS unknown_machine_ignored FOR TESTING.
METHODS name_and_plant FOR TESTING.
METHODS one_row_per_day FOR TESTING.
METHODS second_day_values FOR TESTING.
METHODS machine_without_readings FOR TESTING.
ENDCLASS.
CLASS {{p}}t41_hidden IMPLEMENTATION.
METHOD class_setup.
go_env = cl_cds_test_environment=>create( i_for_entity = '{{P}}I_MACHINE_DAY' ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD setup.
DATA lt_mach TYPE STANDARD TABLE OF {{p}}mach WITH EMPTY KEY.
DATA lt_sensor TYPE STANDARD TABLE OF {{p}}sensor WITH EMPTY KEY.
go_env->clear_doubles( ).
lt_mach = VALUE #(
( machine_id = 'M1' machine_name = 'Press 1' plant = '1000' )
( machine_id = 'M2' machine_name = 'Press 2' plant = '2000' )
( machine_id = 'M3' machine_name = 'Drill 3' plant = '1000' )
( machine_id = 'M4' machine_name = 'Drill 4' plant = '2000' ) ).
lt_sensor = VALUE #(
( machine_id = 'M1' reading_no = 1 reading_date = '20240101' sensor = 'TEMP' reading_value = '10.00' )
( machine_id = 'M1' reading_no = 2 reading_date = '20240101' sensor = 'TEMP' reading_value = '20.00' )
( machine_id = 'M1' reading_no = 3 reading_date = '20240101' sensor = 'TEMP' reading_value = '30.00' )
( machine_id = 'M1' reading_no = 4 reading_date = '20240101' sensor = 'VIBR' reading_value = '99.00' )
( machine_id = 'M1' reading_no = 5 reading_date = '20240102' sensor = 'TEMP' reading_value = '5.00' )
( machine_id = 'M1' reading_no = 6 reading_date = '20240102' sensor = 'TEMP' reading_value = '6.00' )
( machine_id = 'M2' reading_no = 1 reading_date = '20240101' sensor = 'TEMP' reading_value = '95.50' )
( machine_id = 'M2' reading_no = 2 reading_date = '20240101' sensor = 'TEMP' reading_value = '100.00' )
( machine_id = 'M4' reading_no = 1 reading_date = '20240101' sensor = 'TEMP' reading_value = '80.00' )
( machine_id = 'M9' reading_no = 1 reading_date = '20240101' sensor = 'TEMP' reading_value = '50.00' ) ).
go_env->insert_test_data( lt_mach ).
go_env->insert_test_data( lt_sensor ).
ENDMETHOD.
METHOD counts_readings.
SELECT SINGLE reading_count FROM {{p}}i_machine_day
WHERE machine_id = 'M1' AND reading_date = '20240101' INTO @DATA(lv_count).
cl_abap_unit_assert=>assert_equals( exp = 3 act = CONV i( lv_count ) ).
ENDMETHOD.
METHOD average_value.
SELECT SINGLE avg_value FROM {{p}}i_machine_day
WHERE machine_id = 'M1' AND reading_date = '20240101' INTO @DATA(lv_avg).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '20.00' ) act = CONV decfloat34( lv_avg ) ).
ENDMETHOD.
METHOD max_value.
SELECT SINGLE max_value FROM {{p}}i_machine_day
WHERE machine_id = 'M1' AND reading_date = '20240101' INTO @DATA(lv_max).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '30.00' ) act = CONV decfloat34( lv_max ) ).
ENDMETHOD.
METHOD alerts_counted.
SELECT SINGLE alert_count FROM {{p}}i_machine_day
WHERE machine_id = 'M2' AND reading_date = '20240101' INTO @DATA(lv_alerts).
cl_abap_unit_assert=>assert_equals( exp = 2 act = CONV i( lv_alerts ) ).
ENDMETHOD.
METHOD no_alert_at_limit.
SELECT SINGLE alert_count FROM {{p}}i_machine_day
WHERE machine_id = 'M4' AND reading_date = '20240101' INTO @DATA(lv_alerts).
cl_abap_unit_assert=>assert_equals( exp = 0 act = CONV i( lv_alerts ) ).
ENDMETHOD.
METHOD unknown_machine_ignored.
SELECT COUNT(*) FROM {{p}}i_machine_day
WHERE machine_id = 'M9' INTO @DATA(lv_rows).
cl_abap_unit_assert=>assert_equals( exp = 0 act = CONV i( lv_rows ) ).
ENDMETHOD.
METHOD name_and_plant.
SELECT COUNT(*) FROM {{p}}i_machine_day
WHERE machine_id = 'M2' AND machine_name = 'Press 2' AND plant = '2000'
INTO @DATA(lv_rows).
cl_abap_unit_assert=>assert_equals( exp = 1 act = CONV i( lv_rows ) ).
ENDMETHOD.
METHOD one_row_per_day.
SELECT COUNT(*) FROM {{p}}i_machine_day
WHERE machine_id = 'M1' INTO @DATA(lv_rows).
cl_abap_unit_assert=>assert_equals( exp = 2 act = CONV i( lv_rows ) ).
ENDMETHOD.
METHOD second_day_values.
SELECT SINGLE reading_count FROM {{p}}i_machine_day
WHERE machine_id = 'M1' AND reading_date = '20240102' INTO @DATA(lv_count).
SELECT SINGLE avg_value FROM {{p}}i_machine_day
WHERE machine_id = 'M1' AND reading_date = '20240102' INTO @DATA(lv_avg).
cl_abap_unit_assert=>assert_equals( exp = 2 act = CONV i( lv_count ) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '5.50' ) act = CONV decfloat34( lv_avg ) ).
ENDMETHOD.
METHOD machine_without_readings.
SELECT COUNT(*) FROM {{p}}i_machine_day
WHERE machine_id = 'M3' INTO @DATA(lv_rows).
cl_abap_unit_assert=>assert_equals( exp = 0 act = CONV i( lv_rows ) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,59 @@
{
"task": "G0155",
"mutants": [
{
"object": "{{P}}I_MACHINE_DAY",
"mutant": "line 5: inner join -> left outer join (join)",
"status": "killed",
"hidden": "9/10",
"failed_tests": [
"UNKNOWN_MACHINE_IGNORED"
]
},
{
"object": "{{P}}I_MACHINE_DAY",
"mutant": "line 12: avg( -> max( (agg)",
"status": "invalid",
"hidden": "0/0",
"failed_tests": []
},
{
"object": "{{P}}I_MACHINE_DAY",
"mutant": "line 14: > -> <= (rel)",
"status": "killed",
"hidden": "8/10",
"failed_tests": [
"ALERTS_COUNTED",
"NO_ALERT_AT_LIMIT"
]
},
{
"object": "{{P}}I_MACHINE_DAY",
"mutant": "line 14: 1 -> 2 (const)",
"status": "killed",
"hidden": "9/10",
"failed_tests": [
"ALERTS_COUNTED"
]
},
{
"object": "{{P}}I_MACHINE_DAY",
"mutant": "line 16: 'TEMP' -> 'ZEMP' (lit)",
"status": "killed",
"hidden": "3/10",
"failed_tests": [
"ALERTS_COUNTED",
"AVERAGE_VALUE",
"COUNTS_READINGS",
"MAX_VALUE",
"NAME_AND_PLANT",
"ONE_ROW_PER_DAY",
"SECOND_DAY_VALUES"
]
}
],
"valid": 4,
"killed": 4,
"kill_rate": 1.0,
"ok": true
}

View File

@@ -0,0 +1,17 @@
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Machine readings per day'
define view entity {{P}}I_MACHINE_DAY
as select from {{p}}sensor as sen
inner join {{p}}mach as mac on mac.machine_id = sen.machine_id
{
key sen.machine_id as machine_id,
key sen.reading_date as reading_date,
mac.machine_name as machine_name,
mac.plant as plant,
count( * ) as reading_count,
avg( sen.reading_value as abap.dec(15,2) ) as avg_value,
max( sen.reading_value ) as max_value,
sum( case when sen.reading_value > 80.00 then 1 else 0 end ) as alert_count
}
where sen.sensor = 'TEMP'
group by sen.machine_id, sen.reading_date, mac.machine_name, mac.plant

View File

@@ -0,0 +1,44 @@
CLASS {{p}}t41_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 day_profile FOR TESTING.
ENDCLASS.
CLASS {{p}}t41_test IMPLEMENTATION.
METHOD class_setup.
go_env = cl_cds_test_environment=>create( i_for_entity = '{{P}}I_MACHINE_DAY' ).
ENDMETHOD.
METHOD class_teardown.
go_env->destroy( ).
ENDMETHOD.
METHOD setup.
DATA lt_mach TYPE STANDARD TABLE OF {{p}}mach WITH EMPTY KEY.
DATA lt_sensor TYPE STANDARD TABLE OF {{p}}sensor WITH EMPTY KEY.
go_env->clear_doubles( ).
lt_mach = VALUE #( ( machine_id = 'A1' machine_name = 'Mill' plant = '3000' ) ).
lt_sensor = VALUE #(
( machine_id = 'A1' reading_no = 1 reading_date = '20240201' sensor = 'TEMP' reading_value = '60.00' )
( machine_id = 'A1' reading_no = 2 reading_date = '20240201' sensor = 'TEMP' reading_value = '90.00' ) ).
go_env->insert_test_data( lt_mach ).
go_env->insert_test_data( lt_sensor ).
ENDMETHOD.
METHOD day_profile.
SELECT SINGLE reading_count FROM {{p}}i_machine_day
WHERE machine_id = 'A1' AND reading_date = '20240201' INTO @DATA(lv_count).
SELECT SINGLE max_value FROM {{p}}i_machine_day
WHERE machine_id = 'A1' AND reading_date = '20240201' INTO @DATA(lv_max).
SELECT SINGLE alert_count FROM {{p}}i_machine_day
WHERE machine_id = 'A1' AND reading_date = '20240201' INTO @DATA(lv_alerts).
cl_abap_unit_assert=>assert_equals( exp = 2 act = CONV i( lv_count ) ).
cl_abap_unit_assert=>assert_equals( exp = CONV decfloat34( '90.00' ) act = CONV decfloat34( lv_max ) ).
cl_abap_unit_assert=>assert_equals( exp = 1 act = CONV i( lv_alerts ) ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,11 @@
@EndUserText.label : 'Machine master'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table {{p}}mach {
key client : abap.clnt not null;
key machine_id : abap.char(10) not null;
machine_name : abap.char(40);
plant : abap.char(4);
}

View File

@@ -0,0 +1,13 @@
@EndUserText.label : 'Sensor readings'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table {{p}}sensor {
key client : abap.clnt not null;
key machine_id : abap.char(10) not null;
key reading_no : abap.int4 not null;
reading_date : abap.dats;
sensor : abap.char(10);
reading_value : abap.dec(15,2);
}

View File

@@ -0,0 +1,44 @@
# 1. Goal
Show the daily temperature profile of each machine in a factory. A dashboard and an
OData service read the profile, so the aggregation must run in the database, in a
CDS view.
# 2. Open questions
None.
# 3. Context
- Table {{P}}MACH in package $TMP holds the master data of the machines.
- Table {{P}}SENSOR in package $TMP holds the raw sensor readings of the machines.
- The two tables are seed objects. Their column names and their types are not part
of this specification. Read the two table definitions in the system before you
write the view.
# 4. Contract
- Create the CDS view entity {{P}}I_MACHINE_DAY in package $TMP.
- Elements, with these names: MACHINE_ID (key), READING_DATE (key), MACHINE_NAME,
PLANT, READING_COUNT, AVG_VALUE, MAX_VALUE, ALERT_COUNT.
- No authorization check (#NOT_REQUIRED).
# 5. Business rules
1. Only readings of the temperature sensor count. In the raw table, the temperature
sensor is identified by the value 'TEMP'. Ignore all readings of other sensors.
2. Show one row for each machine and each day on which the machine has at least one
temperature reading. Do not show a machine on a day without temperature readings.
3. Show only machines that exist in the machine master table.
4. READING_COUNT is the number of temperature readings of the machine on that day.
5. AVG_VALUE is the average of the values of these readings, with 2 decimals.
6. MAX_VALUE is the highest value of these readings.
7. ALERT_COUNT is the number of these readings with a value greater than 80.00.
A reading with the value 80.00 is not an alert.
8. MACHINE_NAME is the name of the machine. PLANT is the plant of the machine.
Both values come from the machine master table.
# 6. Constraints
- Release target: ABAP Platform 2025 (SAP_BASIS 8.16).
- Coding standards: Clean ABAP.
- Out of scope: do not change the tables {{P}}MACH and {{P}}SENSOR.
# 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,69 @@
{
"id": "G0155",
"category": "F",
"object_type": "DDLS",
"difficulty": 2,
"release_target": "v816",
"expected_outcome": "implement",
"budget": {
"max_tool_calls": 40,
"max_activations": 10
},
"seed": [
{
"type": "TABL",
"name": "{{P}}MACH",
"file": "seed/mach.tabl.asabap",
"description": "Machine master data"
},
{
"type": "TABL",
"name": "{{P}}SENSOR",
"file": "seed/sensor.tabl.asabap",
"description": "Raw sensor readings"
}
],
"contract": [
{
"type": "DDLS",
"name": "{{P}}I_MACHINE_DAY",
"fields": [
"MACHINE_ID",
"READING_DATE",
"MACHINE_NAME",
"PLANT",
"READING_COUNT",
"AVG_VALUE",
"MAX_VALUE",
"ALERT_COUNT"
]
}
],
"out_of_scope": [
"{{P}}MACH",
"{{P}}SENSOR"
],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}T41_HIDDEN",
"file": "hidden/t41_hidden.clas.abap",
"description": "T41 hidden tests"
}
],
"reference": [
{
"type": "DDLS",
"name": "{{P}}I_MACHINE_DAY",
"file": "reference/i_machine_day.ddls.asddls",
"description": "Daily temperature profile of each machine"
},
{
"type": "CLAS",
"name": "{{P}}T41_TEST",
"file": "reference/t41_test.clas.abap",
"description": "T41 own tests"
}
],
"craft_checks": []
}