All skills
secondsky avatar

/sap-cap-capire

@620a19a
by Eddiesecondsky/sap-skills456 stars
120

SAP Cloud Application Programming Model (CAP) development skill using Capire documentation. Use when: building CAP applications, defining CDS models, implementing services, working with SAP HANA/SQLite/PostgreSQL databases, deploying to SAP BTP Cloud Foundry or Kyma, implementing Fiori UIs, handling authorization, multitenancy, or messaging. Covers CDL/CQL/CSN syntax, Node.js and Java runtimes, event handlers, OData services, and CAP plugins.

Use this Skill: https://skilld.dev/gh/secondsky/sap-skills/sap-cap-capire

This session only. Nothing lands on disk.

referenceslocalization-temporal.md

≈1.5k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Localization and Temporal Data Reference

Source: https://cap.cloud.sap/docs/guides/

Internationalization (i18n)

Text Bundle Structure

Text bundles use properties files with locale suffixes:

_i18n/
├── i18n.properties          # Default fallback
├── i18n_en.properties       # English
├── i18n_de.properties       # German
├── i18n_fr.properties       # French
└── i18n_zh_TW.properties    # Traditional Chinese

Properties File Format

# i18n_en.properties
Book = Book
Books = Books
Author = Author
title = Title
description = Description
stock = Stock
price = Price

# Error messages
error.title.required = Title is required
error.stock.negative = Stock cannot be negative

Using in CDS

entity Books {
  key ID : UUID;
  title  : String @title: '{i18n>title}';
  descr  : String @title: '{i18n>description}';
  stock  : Integer @title: '{i18n>stock}';
}

CSV Alternative

key;en;de;fr
Book;Book;Buch;Livre
Author;Author;Autor;Auteur
title;Title;Titel;Titre

Locale Determination (Priority Order)

  1. sap-locale URL parameter
  2. sap-language URL parameter
  3. Accept-Language HTTP header

Configuration

{
  "cds": {
    "i18n": {
      "default_language": "en",
      "folders": ["_i18n", "i18n"],
      "preserved_locales": ["zh_CN", "zh_TW", "en_GB", "fr_CA"]
    }
  }
}

Localized Data

Declaration

Mark fields that need translations:

entity Books {
  key ID : UUID;
  title  : localized String(111);
  descr  : localized String(1111);
  stock  : Integer;  // Not localized
}

Auto-Generated Entities

The compiler generates:

1. Texts Entity:

entity Books.texts {
  key locale : sap.common.Locale;  // e.g., 'en', 'de'
  key ID : UUID;
  title : String(111);
  descr : String(1111);
}

2. Association to Localized:

entity Books {
  // ... original fields
  texts : Composition of many Books.texts on texts.ID = ID;
  localized : Association to Books.texts on localized.ID = ID
              and localized.locale = $user.locale;
}

3. Localized View:

entity localized.Books as select from Books {
  *,
  coalesce(localized.title, title) as title,
  coalesce(localized.descr, descr) as descr
};

Reading Localized Data

// Returns data in user's locale (with fallback)
await SELECT.from('Books');

// Access all translations
await SELECT.from('Books').columns('*', { texts: ['*'] });

// Specific locale
await SELECT.from('Books.texts').where({ locale: 'de' });

Writing Localized Data

// Deep insert with translations
await INSERT.into('Books').entries({
  ID: 'book-1',
  title: 'Default Title',
  descr: 'Default Description',
  texts: [
    { locale: 'de', title: 'Deutscher Titel', descr: 'Deutsche Beschreibung' },
    { locale: 'fr', title: 'Titre Français', descr: 'Description Française' }
  ]
});

// Update specific translation
await UPDATE('Books.texts')
  .set({ title: 'Neuer Titel' })
  .where({ ID: bookId, locale: 'de' });

Initial Data (CSV)

Books.csv (default language):

ID;title;descr;stock
book-1;Wuthering Heights;A classic novel;100

Books_texts.csv (translations):

ID;locale;title;descr
book-1;de;Sturmhöhe;Ein klassischer Roman
book-1;fr;Les Hauts de Hurlevent;Un roman classique

Temporal Data

Declaration

Using Annotations:

entity WorkAssignments {
  key ID : UUID;
  employee : Association to Employees;
  role : String(100);
  validFrom : Date @cds.valid.from;
  validTo : Date @cds.valid.to;
}

Using Temporal Aspect:

using { temporal } from '@sap/cds/common';

entity WorkAssignments : temporal {
  key ID : UUID;
  employee : Association to Employees;
  role : String(100);
}
// Adds validFrom : Timestamp and validTo : Timestamp

Time Slice Keys

Primary key becomes: (ID, validFrom)

// Exposed as single key in OData
entity WorkAssignments {
  key ID : UUID;
  // validFrom is implicitly part of the key
}

Reading Temporal Data

Current Data (as of now):

GET /WorkAssignments

Time-Travel Query (historical snapshot):

GET /WorkAssignments?sap-valid-at=date'2022-01-01'

Time-Period Query (history since date):

GET /WorkAssignments?sap-valid-from=date'2020-01-01'

Programmatic Access

// Current time slices
await SELECT.from('WorkAssignments');

// Specific date
cds.context = { timestamp: new Date('2022-01-01') };
await SELECT.from('WorkAssignments');

// All time slices
await SELECT.from('WorkAssignments')
  .columns('*')
  .where`ID = ${id}`;

Writing Temporal Data

Temporal writes require custom handlers:

// Create new time slice
await INSERT.into('WorkAssignments').entries({
  ID: 'wa-1',
  employee_ID: 'emp-1',
  role: 'Developer',
  validFrom: '2023-01-01',
  validTo: '9999-12-31'
});

// End current slice and start new one
this.on('UPDATE', 'WorkAssignments', async (req) => {
  const { ID } = req.params[0];
  const today = new Date().toISOString().split('T')[0];

  // End current slice
  await UPDATE('WorkAssignments')
    .set({ validTo: today })
    .where({ ID, validTo: '9999-12-31' });

  // Create new slice
  await INSERT.into('WorkAssignments').entries({
    ID,
    ...req.data,
    validFrom: today,
    validTo: '9999-12-31'
  });
});

Temporal Aspect Definition

// From @sap/cds/common
aspect temporal {
  validFrom : Timestamp @cds.valid.from;
  validTo   : Timestamp @cds.valid.to;
}

Limitations

  • SQLite doesn't support sap-valid-at queries (no session context)
  • Temporal writes require custom implementation
  • Transitive temporal queries may produce redundant results

Source: SKILL.md on GitHub

1 alert16d5 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    The analyzed skill is a reference and template package providing guidance for SAP Cloud Application Programming Model (CAP) development, configuration, data privacy, and testing. It contains no executable scripts, hardcoded credentials, or malicious behavior.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer6mo

    12/34 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 620a19a. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 weeks ago.

Activeupdated 2 months ago
Other metadata
metadata
{
  "maintainer": "Eduard Jiglau",
  "maintainer_email": "hello@sap-ai-skills.com",
  "website": "https://sap-ai-skills.com",
  "version": "2.4.1",
  "last_verified": "2026-02-22",
  "cap_version": "@sap/cds 9.7.x",
  "mcp_version": "@cap-js/mcp-server 0.0.5",
  "lsp_version": "@sap/cds-lsp 9.7.x"
}

README badge

README badge for secondsky/sap-skills/sap-cap-capire