User Story: Create the Form Schema API
Opened this issue · 1 comments
manuelroemer commented
Description
As a user, I want the application to automatically use the newest CSRD report version. To achieve this, the frontend must be able to fetch the schemas from the backend.
This will be made possible via an OData service that provides a FormSchemaSet
entity that has the following attributes:
Id: string
- a GUIDType: string
- a unique type of the schema, e.g.,"csrd"
Version: number
- e.g.,1
,2
, ... Autoincremented.SchemaJson: string
- the form schema, formatted as JSON stringMetadataJson?: string
- arbitrary metadata used by the frontend, formatted as JSON stringCreatedAt: string
- the creation dateUpdatedAt: string
- the last modified date
The OData service must provide the following conceptual endpoints (the URLs might vary):
GET /FormSchemaSet('name')
- to get schemas by nameGET /FormSchemaSet('id')
- to get schemas by ID
Acceptance Criteria
- The OData service is functional
- The corresponding database tables exist
- The new endpoint is configured in the Postman collection (if present, see #16)
Additional Information
None.
manuelroemer commented
Done. ABAP code of this initial version (for reference and for the sake of backups - we really need a better way to organize this):
CLASS zcl_z_00_t1_ss23_csrd_dpc_ext DEFINITION
PUBLIC
INHERITING FROM zcl_z_00_t1_ss23_csrd_dpc
CREATE PUBLIC .
PUBLIC SECTION.
PROTECTED SECTION.
METHODS formschemaset_get_entityset REDEFINITION.
METHODS formschemaset_get_entity REDEFINITION.
METHODS formschemaset_create_entity REDEFINITION.
METHODS formschemaset_update_entity REDEFINITION.
METHODS formschemaset_delete_entity REDEFINITION.
PRIVATE SECTION.
METHODS get_key
IMPORTING
!it_key_tab TYPE /iwbep/t_mgw_name_value_pair
key TYPE string
RETURNING
VALUE(result) TYPE string.
METHODS find_current_version
IMPORTING
type TYPE z00t1_sstring
RETURNING VALUE(result) TYPE int4.
ENDCLASS.
CLASS zcl_z_00_t1_ss23_csrd_dpc_ext IMPLEMENTATION.
METHOD formschemaset_get_entityset.
DATA(filter) = io_tech_request_context->get_osql_where_clause( ).
SELECT id, createdAt, updatedAt, type, version, isDraft
FROM z00t1_fschema
WHERE (filter)
ORDER BY type, updatedat
INTO CORRESPONDING FIELDS OF TABLE @et_entityset.
ENDMETHOD.
METHOD formschemaset_get_entity.
DATA(id) = get_key( it_key_tab = it_key_tab key = 'Id' ).
SELECT SINGLE *
FROM z00t1_fschema
WHERE id = @id
INTO @er_entity.
ENDMETHOD.
METHOD formschemaset_create_entity.
io_data_provider->read_entry_data( IMPORTING es_data = er_entity ).
GET TIME STAMP FIELD DATA(now).
er_entity-mandt = sy-mandt.
er_entity-id = cl_system_uuid=>create_uuid_c36_static( ).
er_entity-createdat = now.
er_entity-updatedat = now.
IF er_entity-isdraft = abap_true.
" Draft schemas always have a version of -1.
" Once undrafted, they are assigned a real version number.
er_entity-version = -1.
ELSE.
" Otherwise the version is auto-calculated to overwrite the current highest version.
" Also explicitly reassign `isDraft` because the gateway, for whatever reason, allows null here.
er_entity-isdraft = abap_false.
er_entity-version = find_current_version( type = er_entity-type ) + 1.
ENDIF.
INSERT z00t1_fschema FROM er_entity.
ENDMETHOD.
METHOD formschemaset_update_entity.
io_data_provider->read_entry_data( IMPORTING es_data = er_entity ).
DATA(id) = get_key( it_key_tab = it_key_tab key = 'Id' ).
" It's only possible to update the JSON schema of draft form schema entities.
" Others are immutable.
UPDATE z00t1_fschema
SET schemajson = @er_entity-schemajson
WHERE id = @id AND
isdraft = @abap_true.
" It IS possible to update some other properties of every form schema, even if undrafted.
UPDATE z00t1_fschema
SET metadatajson = @er_entity-metadatajson
WHERE id = @id.
" It's only possible to undraft schemas.
" Once they are undrafted, that state cannot be reverted.
DATA(nextVersion) = find_current_version( type = er_entity-type ) + 1.
UPDATE z00t1_fschema
SET isdraft = @abap_false,
version = @nextVersion
WHERE id = @id AND
isdraft = @abap_true AND
@er_entity-isdraft = @abap_false.
" Finally, update `updatedAt`. Yes, this could have done in one of the above queries,
" but muh separation of concerns :^).
GET TIME STAMP FIELD DATA(now).
UPDATE z00t1_fschema
SET updatedat = @now
WHERE id = @id.
ENDMETHOD.
METHOD formschemaset_delete_entity.
DATA(id) = get_key( it_key_tab = it_key_tab key = 'Id' ).
DELETE FROM z00t1_fschema WHERE id = @id.
DELETE FROM z00t1_fschemares WHERE formschemaid = @id.
ENDMETHOD.
METHOD find_current_version.
SELECT MAX( version )
FROM z00t1_fschema
WHERE type = @type
INTO @result.
ENDMETHOD.
METHOD get_key.
DATA kvp TYPE /iwbep/s_mgw_name_value_pair.
READ TABLE it_key_tab INTO kvp WITH KEY name = key.
result = kvp-value.
ENDMETHOD.
ENDCLASS.
Postman Collection was updated:
Tables:
@EndUserText.label : 'Form Schemas of the CSRD application'
@AbapCatalog.enhancementCategory : #EXTENSIBLE_ANY
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #ALLOWED
define table z00t1_fschema {
key mandt : mandt not null;
key id : sysuuid_c36 not null;
type : z00t1_sstring not null;
@EndUserText.label : 'The actual schema, as JSON'
schemajson : abap.string(0);
@EndUserText.label : 'Arbitrary metadata to be used by the frontend, as JSON'
metadatajson : abap.string(0);
createdat : timestamp not null;
updatedat : timestamp not null;
@EndUserText.label : 'A version identifier, used to identify breaking changes'
version : abap.int4 not null;
isdraft : abap_boolean not null;
}
@EndUserText.label : 'Form Schema Results of the CSRD'
@AbapCatalog.enhancementCategory : #EXTENSIBLE_ANY
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #ALLOWED
define table z00t1_fschemares {
key mandt : mandt not null;
key id : sysuuid_c36 not null;
@AbapCatalog.foreignKey.screenCheck : true
formschemaid : sysuuid_c36
with foreign key z00t1_fschema
where mandt = z00t1_fschemares.mandt
and id = z00t1_fschemares.formschemaid;
}