Writing Skills
writing-skills
效率与协作技能,来自 obra/superpowers,查看原文获取完整用途和操作说明。
sap-cap【部署与运维】SAP Cloud Application Programming Model (CAP) — CDS modeling, service definitions, custom handlers, OData V4, Fiori Elements, hybrid testing, MTA deployment. Use when building CAP apps, defining CDS models, writing service handlers, or deploying to SAP BTP.
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Full-stack framework for SAP BTP — CDS modeling, Node.js services, Fiori UIs.
@sap/cds-dk installed globally: npm i -g @sap/cds-dkcf) for deploymentnpm i -g mbtcds init my-cap-app --add sample,hana
cd my-cap-app
npm install
Project layout:
my-cap-app/
├── db/schema.cds # Data model
├── db/data/ # CSV seed data
├── srv/service.cds # Service definitions
├── srv/service.js # Custom handlers
├── app/ # Fiori Elements UIs + annotations
├── mta.yaml # MTA descriptor (cds add mta)
└── package.json
namespace sap.capire.risks;
entity Risks : cuid, managed {
title : String(100);
prio : String(5);
impact : Integer;
criticality : Integer;
miti : Composition of many Mitigations on miti.risk = $self;
}
entity Mitigations : cuid, managed {
description : String;
owner : String;
risk : Association to Risks;
}
using sap.capire.risks from '../db/schema';
service RiskService @(requires: 'authenticated-user') {
entity Risks as projection on risks.Risks;
entity Mitigations as projection on risks.Mitigations;
action analyzeRisks() returns Risks;
}
const cds = require('@sap/cds')
module.exports = class RiskService extends cds.ApplicationService {
async init() {
const { Risks } = this.entities
// Validate before create
this.before('CREATE', Risks, (req) => {
req.data.criticality = Math.ceil(req.data.impact / 20) * 20
})
// Custom action
this.on('analyzeRisks', async (req) => {
return UPDATE(req.subject).with({ title: { '=': req.data.title } })
})
// After-read enrichment
this.after('READ', Risks, (rows) => {
rows.forEach(r => { if (r.impact > 80) r.criticality = 1 })
})
return super.init()
}
}
using RiskService as service from '../../srv/risk-service';
annotate service.Risks with @(
UI: {
SelectionFields: [ title, prio ],
LineItem: [
{ $Type: 'UI.DataField', Value: title },
{ $Type: 'UI.DataField', Value: prio },
{ $Type: 'UI.DataField', Value: criticality, Criticality: criticality }
],
HeaderInfo: {
TypeName: 'Risk', TypeNamePlural: 'Risks',
Title: { Value: title }
}
}
);
cds watch # SQLite, auto-reload on file change
# Visit http://localhost:4004
cds add hana,xsuaa,mta --for production
cf deploy mta_archives/risks_1.0.0.mtar # deploy once to create services
cds bind -2 my-hdi,my-xsuaa # bind local dev to BTP services
cds watch --profile hybrid # local runtime + cloud backends
cds add mta # generate mta.yaml if not present
mbt build -t gen/mta.tar
cf deploy gen/mta.tar
# Or simplified: cds up (builds + deploys in one step)
cds run deprecated — Cause: cds 8+ removed the cds executable from @sap/cds. Solution: use cds-serve in npm scripts: npm pkg set scripts.start="cds-serve".
Cross-tenant data leak — Cause: caching request-scoped data in module-level variables. Solution: use cds.context or keep state inside the handler closure.
XSUAA scopes not updated — Cause: changing @requires annotations doesn't auto-update xs-security.json. Solution: re-run cds compile --to xsuaa after auth annotation changes.
cuid adds UUID key — Cause: :cuid aspect auto-generates a String(36) UUID key. Solution: don't manually define key ID when using cuid; it's already included.
@readonly blocks writes — Cause: @readonly restricts entity to GET only. Solution: remove annotation or use @insertonly / @updatable for partial access.
Hybrid profile missing bindings — Cause: cds bind saves to .cdsrc-private.json which isn't committed. Solution: re-run cds bind -2 <service> after cloning the repo.
# 1. Check model compiles
cds compile srv/risk-service.cds -2 edmx
# 2. Verify local server responds
curl http://localhost:4004/odata/v4/risk/Risks?$top=5
# 3. Check service endpoints
cds eval 'cds.served["RiskService"].endpoints'
# 4. Validate MTA descriptor
mbt build -t gen/mta.tar && cf deploy gen/mta.tar --dry-run
# 5. Confirm Fiori annotations render
# Open http://localhost:4004/risks/webapp/index.html