Now accepting guest editorial from SAP, Oracle, Workday and ServiceNow practitioners.Pitch a guide
The Sign-Off Table

Lesson 2 of 6

Modeling the domain with CDS

9 min

Listen to this lesson

0:00 / 6:34

The domain model describes the things your app owns. For the fleet app, SAP S/4HANA remains the system of record for sales orders and customers; the app owns only what SAP S/4HANA does not have: inquiries raised by the fleet desk, the notes added to them, and a small code list of inquiry topics. Keeping that boundary clear is the first modeling decision, and the most important one: never copy SAP master data into your own tables just because it is convenient.

Entities, types and reuse aspects

The model goes in db/schema.cds:
namespace com.contoso.fleet;
using { cuid, managed, sap.common.CodeList } from '@sap/cds/common';
entity Inquiries : cuid, managed {
salesOrder : String(10) @mandatory;
customer : String(10) @mandatory;
topic : Association to Topics;
priority : Integer @assert.range: [1, 3];
status : String(12) default 'New';
notes : Composition of many Notes on notes.inquiry = $self;
}
entity Notes : cuid, managed {
inquiry : Association to Inquiries;
text : String(1000);
}
entity Topics : CodeList {
key code : String(10);
}
The CodeList aspect gives Topics a localized name and descr and marks the entity as a value list.

Two reuse aspects from @sap/cds/common do a lot of work. cuid adds a UUID primary key, which CAP fills automatically on create. managed adds createdAt, createdBy, modifiedAt and modifiedBy, filled by the runtime from the current time and user. For testers that is free audit evidence: every inquiry records who created and last changed it. The common package also offers reuse types such as Country, Currency and Language with their code lists.

Associations and compositions

An association is a relationship between independent things: an inquiry refers to a topic, but the topic exists on its own. A managed to-one association such as topic : Association to Topics gets its foreign key generated (in the database you will see a column like topic_code). A to-many association needs an on condition pointing back to the to-one side. A composition models containment: notes belong to their inquiry and make no sense without it. CAP treats compositions as documents, with deep insert and update (create an inquiry and its notes in one request) and cascaded delete.

The fleet app's own model: Inquiries contain Notes (composition, cascaded delete) and refer to Topics (association), while sales orders stay in SAP S/4HANA.
The Sign-Off Table · thesignofftable.com/academy/sap-btp-202
AssociationComposition
MeaningRefers to something that exists on its ownContains parts that belong to the parent
Fleet app exampleInquiry → TopicInquiry → Notes
Delete parentTarget remainsChildren are deleted too
Create in one requestReference an existing target by keyDeep insert of parent and children
Test to writeReject an inquiry that points to a topic that does not existDeleting an inquiry removes its notes; deep insert creates both
Associations and compositions behave differently, and each needs its own tests.
The Sign-Off Table · thesignofftable.com/academy/sap-btp-202

Modeling conventions

  • Names: capitalized, plural entity names (Inquiries, Notes); lowercase element names; no repeated context (name, not topicName).
  • Flat models: prefer simple elements to nested structured types, which some consumers handle poorly.
  • Keys: a single technical key such as cuid; do not give UUIDs meaning.
  • Namespaces: reverse domain names such as com.contoso.fleet, not short-lived project code names.
  • Localized texts: mark text elements as localized (for example topic names) and CAP generates the texts tables.
  • Separation of concerns: put UI annotations and authorization in separate files that annotate or extend the core model.

Test data

CAP loads .csv files automatically when it bootstraps a database. Files are named after the namespace and entity, for example db/data/com.contoso.fleet-Topics.csv, and cds add data generates empty files with the right headers. Keep reference data needed in every environment (the topic list) apart from test data used only locally or in tests (sample inquiries); CAP supports a separate test/data folder for the latter. Contoso's test data uses the canonical fleet customer Great Lakes Fleet Services and product CMC-ALT-100, so local results look like what testers later see in CMQ.

SAP S/4HANA (system of record, read through APIs)Sales orders, deliveries, business partners, products such as CMC-ALT-100
Fleet app domain model (owned by the app)Inquiries (cuid, managed) with composed Notes; Topics code list with localized names
Reference data (all environments)db/data: topic codes such as LATE, CHANGE, DAMAGE
Test data (local and automated tests only)test/data: sample inquiries for Great Lakes Fleet Services orders
What the fleet app owns, what it only reads, and where its data comes from.
The Sign-Off Table · thesignofftable.com/academy/sap-btp-202

What would you do?

A developer proposes adding a Customers entity to the fleet app's model and loading all fleet customers from SAP S/4HANA into it every night, "so joins are easier". What should Priya, as test lead, push for?

Key points
  • Model only what the app owns; read SAP master and transactional data through APIs.
  • cuid adds a UUID key; managed adds created and modified by and at, filled automatically.
  • Associations relate independent entities; compositions contain parts with deep insert and cascaded delete.
  • Follow CAP naming conventions, flat models, single technical keys and reverse-domain namespaces.
  • Load reference data from db/data and test-only data from test/data, using canonical test values.

Check your understanding · not graded

Lesson check

  1. 1. What does the managed aspect add to an entity?

  2. 2. Notes only make sense inside their inquiry. How should they be modeled?

  3. 3. What happens to the notes when an inquiry is deleted?

  4. 4. Where should test-only sample inquiries be kept?