SuperAPI AI Directory

code-review

Testing & quality

View repository

Updated 10-16 02:37

About this skill

Code Review — CAP Best Practices Checklist

Primary reference: Always consult https://cap.cloud.sap/docs first. For LLM-optimised CAP documentation, fetch https://cap.cloud.sap/docs/llms.txt or https://cap.cloud.sap/docs/llms-full.txt for deeper context.

How to conduct a CAP code review

Work through each section below. For every finding, state:

  • File and approximate line
  • Severity: 🔴 Critical | 🟠 Major | 🟡 Minor | 🔵 Suggestion
  • Finding and the corrected version

1. CDS Model Quality

Check for:

# Check Bad Good
1.1 UUID keys defined manually key ID : UUID @default: #uuidv4 entity Foo : cuid { ... }
1.2 Audit fields defined manually createdAt : Timestamp; createdBy : ... entity Foo : managed { ... }
1.3 DB entity exposed directly in service entity Foo as db.Foo entity Foo as projection on db.Foo { ... }
1.4 String without length on HANA name : String name : String(100)
1.5 No enum for status/type fields status : String status : StatusType enum { ... }
1.6 Inline annotations cluttering entity @UI.LineItem: [...] on entity Separate annotations.cds file
1.7 Unnecessary abstraction views (ABAP VDM style) C_MyView as select from I_MyView Direct projection on db.* entity
1.8 Composition vs. Association confusion address : Composition to Addresses Use Composition only if child can't exist without parent
1.9 Missing on clause for associations in service items : Association to many Items items : Association to many Items on items.order = $self
1.10 Calculated fields in where / filter where grossPrice > 100 (live calc) Add @Capabilities.FilterRestrictions annotation

2. Service Handler Quality

Check for:

# Check Bad Good
2.1 Missing return super.init() async init() { this.on(...) } async init() { ... return super.init() }
2.2 cds.connect.to() inside handler body Per-request connect Connect once in init(), store as this.S4 = ...
2.3 Missing return in on handler this.on('READ', ...) with no return Always return the result
2.4 N+1 query in after handler for (const x of list) await SELECT.from(...) Batch: one query with in clause
2.5 Raw req.query manipulation req.query.SELECT.where = [...] Use fluent CQL: SELECT.from(...).where(...)
2.6 Throwing new Error() throw new Error('...') req.reject(...) or throw new cds.error(...)
2.7 Mutating req.data in after phase after('READ', ..., results => results[0].x = ...) Understand: req.data is input, result is separate
2.8 cds.db.run() used where service API fits Raw DB run bypassing service logic Use this.run() or service-level queries
2.9 Direct console.log instead of cds.log console.log(...) const log = cds.log('myModule'); log.info(...)
2.10 Missing error handling for remote calls Unwrapped await S4.run(...) try/catch with specific status codes

3. Security & Authorization

Check for:

# Check Severity
3.1 Service has no @requires annotation 🔴 Critical
3.2 @requires: 'any' used (allows unauthenticated) 🔴 Critical (unless intentional)
3.3 Delete/write operations have no @restrict 🔴 Critical
3.4 Instance-based checks done only client-side 🔴 Critical
3.5 XSUAA scopes not matching @restrict role names 🟠 Major
3.6 No where: 'createdBy = $user' on user-owned data UPDATE 🟠 Major
3.7 xs-security.json has no role-templates 🟠 Major
3.8 Security annotation typo (now a compiler error in CDS 9+) 🔴 Critical

4. Error Handling

Check for:

# Check Bad Good
4.1 No HTTP status code on reject req.reject('Something failed') req.reject(422, 'REASON_KEY', [args])
4.2 Stack trace exposed to client req.reject(500, err.stack) Generic message; log internally
4.3 Status 500 for business errors req.reject(500, 'Order closed') req.reject(409, ...)
4.4 No target on field validation errors Generic rejection req.reject({ code: 400, target: 'price', message: '...' })
4.5 Errors swallowed in remote calls Empty catch {} At minimum re-throw or return 503

5. Performance

Check for:

# Check Why
5.1 SELECT * / no column projection Fetches all columns including large fields unnecessarily
5.2 Missing .limit() on potentially large result sets Can OOM or timeout under load
5.3 Remote service called without delegating req.query Fetches all remote data, filters locally
5.4 Calculated elements used in where / filter / order Live-calculated = no DB index; use @Capabilities annotations to restrict
5.5 Unnecessary abstraction views (extra JOINs) Every extra view layer adds a JOIN on HANA
5.6 after READ doing N individual DB queries Use batch fetch with in operator
5.7 Streaming query results not used for large datasets SELECT.pipeline() / SELECT.foreach() now available in CAP Node.js

6. Test Coverage

Check for:

# Check
6.1 No tests exist at all
6.2 Tests don't cover authorization (different user roles)
6.3 Tests use real HANA instead of SQLite :memory:
6.4 No test for error/rejection paths
6.5 External services not mocked (tests hit real systems)
6.6 No test for custom actions / functions

7. Deployment & Configuration

Check for:

# Check
7.1 Credentials hardcoded in package.json or committed .env
7.2 hdi-container used instead of service-manager in multitenant apps
7.3 Missing connectivity service for on-premise destinations
7.4 cds build not run before mbt build (stale gen/)
7.5 xs-security.json missing $ACCEPT_GRANTED_AUTHORITIES for MTX
7.6 No .cdsrc.json / package.json profile separation ([production] vs [development])

8. CDS 9 / Latest Version Checks (2025+)

Check for deprecated patterns:

# Deprecated Modern Replacement
8.1 @sap/cds-mtx (old MTX) @sap/cds-mtxs
8.2 cds.User.tokenInfo cds.User.authInfo
8.3 cds.security.draftProtection.enabled cds.security.authorization.draftProtection.enabled
8.4 @sap/xssec < v4 Upgrade to @sap/xssec v4
8.5 cds 7 or lower (@sap/cds < 8) Upgrade to @sap/cds 9 (cds 7 is EOL)
8.6 @cap-js/change-tracking without MTX multitenancy support Version supports it since April 2025
8.7 @protocols: [...] array syntax (Java) @odata service Foo { } annotation syntax
8.8 annotate Books:genres with @restrict without parentheses in expressions Now a compiler error; use ( )

Review output template

## CAP Code Review — <filename or PR title>
**Reviewed against**: capire (https://cap.cloud.sap/docs), CAP Node.js @sap/cds 9.x

### 🔴 Critical
- [2.6] `srv/order-service.js:45` — `throw new Error(...)` bypasses CAP error handling
  Fix: `req.reject(422, 'ORDER_VALIDATION_FAILED', [orderId])`

### 🟠 Major
- [3.1] `srv/catalog-service.cds:1` — Service has no `@requires` annotation
  Fix: Add `@requires: 'authenticated-user'` to CatalogService

### 🟡 Minor
- [5.1] `srv/product-service.js:22` — SELECT without column projection
  Fix: `.columns('ID', 'title', 'price', 'currency_code')`

### 🔵 Suggestions
- [6.1] No test file found. Consider adding `tests/catalog.test.js` using `cds.test('.')`