diff --git a/package-lock.json b/package-lock.json
index b357c14..4846868 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "apiops-cycles-method-data",
- "version": "3.4.1",
+ "version": "3.4.2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "apiops-cycles-method-data",
- "version": "3.4.1",
+ "version": "3.4.2",
"license": "Apache-2.0",
"workspaces": [
"packages/*"
diff --git a/package.json b/package.json
index 841fd16..4c07c35 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "apiops-cycles-method-data",
- "version": "3.4.1",
+ "version": "3.4.2",
"description": "APIOps Cycles Method data and canvases",
"license": "Apache-2.0",
"type": "module",
@@ -35,7 +35,7 @@
"release:create-apiops:publish": "npm publish --workspace packages/create-apiops --access public",
"check:packaging:skills": "node scripts/check-packaging-skills.mjs",
"check:package:contents": "node scripts/check-package-contents.mjs",
- "test:create-apiops": "node scripts/test-create-apiops-scaffold.mjs && node scripts/test-method-cli.mjs"
+ "test:create-apiops": "node scripts/test-create-apiops-scaffold.mjs && node scripts/test-method-cli.mjs && node scripts/test-run-design-audit.mjs"
},
"devDependencies": {
"@changesets/cli": "^2.29.7",
diff --git a/packages/create-apiops/package.json b/packages/create-apiops/package.json
index fc8755a..9dd365a 100644
--- a/packages/create-apiops/package.json
+++ b/packages/create-apiops/package.json
@@ -1,6 +1,6 @@
{
"name": "create-apiops",
- "version": "1.1.1",
+ "version": "1.1.2",
"description": "Scaffold a new APIOps project with an OpenAPI spec, audit scaffolding, and APIOps documentation templates.",
"license": "Apache-2.0",
"type": "module",
diff --git a/packages/create-apiops/template/package.json b/packages/create-apiops/template/package.json
index e7f2527..7898c3c 100644
--- a/packages/create-apiops/template/package.json
+++ b/packages/create-apiops/template/package.json
@@ -6,7 +6,7 @@
"node": ">=22"
},
"dependencies": {
- "apiops-cycles-method-data": "^3.4.1",
+ "apiops-cycles-method-data": "^3.4.2",
"canvascreator": "^1.7.3"
},
"devDependencies": {
diff --git a/packages/create-apiops/template/scripts/run-design-audit.js b/packages/create-apiops/template/scripts/run-design-audit.js
index 07988a0..7c33913 100644
--- a/packages/create-apiops/template/scripts/run-design-audit.js
+++ b/packages/create-apiops/template/scripts/run-design-audit.js
@@ -2,28 +2,40 @@ import fs from "node:fs";
import { createRequire } from "node:module";
import path from "node:path";
import { spawnSync } from "node:child_process";
+import { fileURLToPath } from "node:url";
import YAML from "yaml";
-const root = process.cwd();
const require = createRequire(import.meta.url);
-const profile = (process.argv[2] || "read-only").trim();
-
-if (!["read-only", "full-crud"].includes(profile)) {
- console.error(`Unknown audit profile: ${profile}`);
- process.exit(1);
+const __filename = fileURLToPath(import.meta.url);
+
+let root = process.cwd();
+let profile = "read-only";
+let auditSlug = profile;
+let openApiPath = path.join(root, "specs", "openapi", "api.yaml");
+let reportJsonPath = path.join(root, "specs", "audit", `design-audit.${auditSlug}.json`);
+let reportMarkdownPath = path.join(root, "specs", "audit", `design-audit.${auditSlug}.md`);
+let reportDocsPath = path.join(root, "docs", "api", "audit", `design-audit.${auditSlug}.md`);
+let reportHtmlPath = path.join(root, "docs", "api", "audit", `design-audit.${auditSlug}.html`);
+let reportJUnitPath = path.join(root, "reports", "junit", `design-audit.${auditSlug}.xml`);
+let legacyMarkdownPath = path.join(root, "specs", "audit", "design-audit.md");
+let legacyDocsPath = path.join(root, "docs", "api", "audit", "design-audit.md");
+let legacyHtmlPath = path.join(root, "docs", "api", "audit", "index.html");
+
+function configureRun(rootDir, selectedProfile) {
+ root = rootDir;
+ profile = selectedProfile;
+ auditSlug = profile;
+ openApiPath = path.join(root, "specs", "openapi", "api.yaml");
+ reportJsonPath = path.join(root, "specs", "audit", `design-audit.${auditSlug}.json`);
+ reportMarkdownPath = path.join(root, "specs", "audit", `design-audit.${auditSlug}.md`);
+ reportDocsPath = path.join(root, "docs", "api", "audit", `design-audit.${auditSlug}.md`);
+ reportHtmlPath = path.join(root, "docs", "api", "audit", `design-audit.${auditSlug}.html`);
+ reportJUnitPath = path.join(root, "reports", "junit", `design-audit.${auditSlug}.xml`);
+ legacyMarkdownPath = profile === "read-only" ? path.join(root, "specs", "audit", "design-audit.md") : null;
+ legacyDocsPath = profile === "read-only" ? path.join(root, "docs", "api", "audit", "design-audit.md") : null;
+ legacyHtmlPath = profile === "read-only" ? path.join(root, "docs", "api", "audit", "index.html") : null;
}
-const auditSlug = profile;
-const openApiPath = path.join(root, "specs", "openapi", "api.yaml");
-const reportJsonPath = path.join(root, "specs", "audit", `design-audit.${auditSlug}.json`);
-const reportMarkdownPath = path.join(root, "specs", "audit", `design-audit.${auditSlug}.md`);
-const reportDocsPath = path.join(root, "docs", "api", "audit", `design-audit.${auditSlug}.md`);
-const reportHtmlPath = path.join(root, "docs", "api", "audit", `design-audit.${auditSlug}.html`);
-const reportJUnitPath = path.join(root, "reports", "junit", `design-audit.${auditSlug}.xml`);
-const legacyMarkdownPath = profile === "read-only" ? path.join(root, "specs", "audit", "design-audit.md") : null;
-const legacyDocsPath = profile === "read-only" ? path.join(root, "docs", "api", "audit", "design-audit.md") : null;
-const legacyHtmlPath = profile === "read-only" ? path.join(root, "docs", "api", "audit", "index.html") : null;
-
function resolveChecklistSource() {
const localOverridePath = path.join(root, "specs", "audit", "api-audit-checklist.json");
if (fs.existsSync(localOverridePath)) {
@@ -315,10 +327,11 @@ function evaluateCheck(check, spec, item) {
return checkStandardizedValues(spec);
case "avoidAcronyms":
return checkAvoidAcronyms(spec);
- case "sectionCoverage": {
+ case "sectionCoverage":
+ case "stageCoverage": {
return {
ok: true,
- details: [check.sectionId]
+ details: [check.stageId || check.sectionId]
};
}
case "pathDepthMax":
@@ -346,6 +359,15 @@ function evaluateCheck(check, spec, item) {
}
}
+const DEFAULT_LIFECYCLE_STAGES = Object.freeze([
+ { id: "strategy", title: "Strategy", order: 1, readinessLabel: "Concept is Ready When..." },
+ { id: "architecture", title: "Architecture", order: 2, readinessLabel: "Architecture is Ready When..." },
+ { id: "design", title: "Design", order: 3, readinessLabel: "Design Prototype is Ready When..." },
+ { id: "delivery", title: "Delivery", order: 4, readinessLabel: "Delivery is Ready When..." },
+ { id: "publishing", title: "Publishing", order: 5, readinessLabel: "Production Ready for Publishing When..." },
+ { id: "improving", title: "Improving", order: 6, readinessLabel: "Improvement Loops are Ready When..." }
+]);
+
function normalizeStatus(item, evaluation) {
if (item.defaultStatus === "na") return "na";
if (item.kind === "manual") return item.defaultStatus || "partial";
@@ -367,9 +389,82 @@ function formatStatus(status) {
}
}
+function summarizeStatuses(items) {
+ const summary = { pass: 0, partial: 0, gap: 0, na: 0 };
+ for (const item of items) {
+ summary[item.currentStatus] += 1;
+ }
+ summary.total = summary.pass + summary.partial + summary.gap + summary.na;
+ return summary;
+}
+
+function formatStageSummary(summary) {
+ const parts = [`${summary.pass} pass`, `${summary.partial} partial`, `${summary.gap} gap`];
+ if (summary.na > 0) {
+ parts.push(`${summary.na} n/a`);
+ }
+ return parts.join(" | ");
+}
+
+function normalizeChecklistItem(item, primaryStage) {
+ return {
+ ...item,
+ primaryStage: item.primaryStage || primaryStage,
+ producedByStation: item.producedByStation || item.stationSource || [],
+ producedByStationCriteria: item.producedByStationCriteria || [],
+ guidelines: item.guidelines || item.guidelineRef || [],
+ expectedEvidenceTags: item.expectedEvidenceTags || item.evidenceType || [],
+ expectedEvidence: item.expectedEvidence || item.evidence || []
+ };
+}
+
+function normalizeChecklist(checklist) {
+ const lifecycleStages = (Array.isArray(checklist.lifecycleStages) && checklist.lifecycleStages.length
+ ? checklist.lifecycleStages
+ : DEFAULT_LIFECYCLE_STAGES
+ )
+ .slice()
+ .sort((left, right) => (left.order || 0) - (right.order || 0));
+
+ if (Array.isArray(checklist.stages)) {
+ const itemsByStage = new Map(checklist.stages.map((stage) => [stage.id, stage.items || []]));
+ return lifecycleStages.map((stage) => ({
+ ...stage,
+ items: (itemsByStage.get(stage.id) || []).map((item) => normalizeChecklistItem(item, stage.id))
+ }));
+ }
+
+ const legacyStageBySectionId = {
+ "concept-ready": "strategy",
+ "design-prototype-ready": "design",
+ "production-ready": "publishing"
+ };
+ const itemsByStage = new Map(lifecycleStages.map((stage) => [stage.id, []]));
+
+ for (const section of checklist.sections || []) {
+ const stageId = legacyStageBySectionId[section.id] || "design";
+ const items = itemsByStage.get(stageId) || [];
+ for (const item of section.items || []) {
+ items.push(normalizeChecklistItem(item, stageId));
+ }
+ itemsByStage.set(stageId, items);
+ }
+
+ return lifecycleStages.map((stage) => ({
+ ...stage,
+ items: itemsByStage.get(stage.id) || []
+ }));
+}
+
+function findExistingEvidence(paths) {
+ return (paths || [])
+ .filter(Boolean)
+ .filter((entry) => fs.existsSync(path.join(root, entry)));
+}
+
function buildChecklistResults(spec, checklist) {
- const sections = checklist.sections.map((section) => {
- const items = section.items
+ return normalizeChecklist(checklist).map((stage) => {
+ const items = stage.items
.filter((item) => item.applicableTo.includes(profile))
.map((item) => {
if (item.defaultStatus === "na") {
@@ -377,47 +472,56 @@ function buildChecklistResults(spec, checklist) {
id: item.id,
label: item.label,
kind: item.kind,
- status: "na",
- reason: item.reason || "Not applicable",
- evidence: item.evidence || []
+ primaryStage: item.primaryStage || stage.id,
+ producedByStation: item.producedByStation,
+ producedByStationCriteria: item.producedByStationCriteria,
+ guidelines: item.guidelines,
+ expectedEvidenceTags: item.expectedEvidenceTags,
+ expectedEvidence: item.expectedEvidence,
+ actualEvidenceFound: findExistingEvidence(item.expectedEvidence),
+ currentStatus: "na",
+ reason: item.reason || "Not applicable"
};
}
const evaluation = item.kind === "openapi" || item.kind === "aggregate"
? evaluateCheck(item.check, spec, item)
: { ok: false, details: [] };
+ const currentStatus = normalizeStatus(item, evaluation);
+ const actualEvidenceFound = evaluation.details?.length
+ ? evaluation.details
+ : (
+ findExistingEvidence(item.expectedEvidence).length
+ ? findExistingEvidence(item.expectedEvidence)
+ : (item.kind === "openapi" ? [path.relative(root, openApiPath)] : [])
+ );
- const status = normalizeStatus(item, evaluation);
return {
id: item.id,
label: item.label,
kind: item.kind,
- status,
- evidence: evaluation.details?.length ? evaluation.details : (item.evidence || []),
+ primaryStage: item.primaryStage || stage.id,
+ producedByStation: item.producedByStation,
+ producedByStationCriteria: item.producedByStationCriteria,
+ guidelines: item.guidelines,
+ expectedEvidenceTags: item.expectedEvidenceTags,
+ expectedEvidence: item.expectedEvidence,
+ actualEvidenceFound,
+ currentStatus,
reason: item.reason || "",
evaluation: item.kind === "openapi" || item.kind === "aggregate" ? evaluation.ok : undefined
};
});
return {
- id: section.id,
- title: section.title,
+ id: stage.id,
+ title: stage.title,
+ readinessLabel: stage.readinessLabel || "",
+ order: stage.order || 0,
+ summary: summarizeStatuses(items),
items
};
});
-
- return sections;
-}
-
-function summarizeChecklist(sections) {
- const summary = { pass: 0, partial: 0, gap: 0, na: 0 };
- for (const section of sections) {
- for (const item of section.items) {
- summary[item.status] += 1;
- }
- }
- summary.total = summary.pass + summary.partial + summary.gap + summary.na;
- return summary;
}
function buildReport() {
@@ -425,8 +529,8 @@ function buildReport() {
const checklist = readJson(checklistSource.filePath);
const spec = YAML.parse(readText(openApiPath));
const spectral = runSpectral();
- const sections = buildChecklistResults(spec, checklist);
- const summary = summarizeChecklist(sections);
+ const stages = buildChecklistResults(spec, checklist);
+ const summary = summarizeStatuses(stages.flatMap((stage) => stage.items));
return {
profile,
@@ -442,7 +546,12 @@ function buildReport() {
findings: spectral.findings
},
summary,
- sections
+ stageSummary: stages.map((stage) => ({
+ id: stage.id,
+ title: stage.title,
+ ...stage.summary
+ })),
+ stages
};
}
@@ -461,16 +570,36 @@ function renderMarkdown(report) {
lines.push(`- Gaps: ${report.summary.gap}`);
lines.push(`- Not applicable: ${report.summary.na}`);
lines.push("");
- lines.push("## Checklist Results");
+ lines.push("## Lifecycle Summary");
+ lines.push("");
+ for (const stage of report.stageSummary) {
+ lines.push(`- ${stage.title}: ${formatStageSummary(stage)}`);
+ }
+ lines.push("");
+ lines.push("## Stage Results");
lines.push("");
- for (const section of report.sections) {
- lines.push(`### ${section.title}`);
+ for (const stage of report.stages) {
+ lines.push(`### ${stage.title}`);
lines.push("");
- for (const item of section.items) {
- lines.push(`- [${formatStatus(item.status)}] ${item.label}`);
- if (item.evidence && item.evidence.length) {
- lines.push(` - Evidence: ${item.evidence.slice(0, 5).join(", ")}`);
+ if (stage.readinessLabel) {
+ lines.push(stage.readinessLabel);
+ lines.push("");
+ }
+ lines.push(`Summary: ${formatStageSummary(stage.summary)}`);
+ lines.push("");
+ for (const item of stage.items) {
+ lines.push(`- [${formatStatus(item.currentStatus)}] ${item.label}`);
+ if (item.producedByStation.length) {
+ lines.push(` - Stations: ${item.producedByStation.join(", ")}`);
+ }
+ if (item.guidelines.length) {
+ lines.push(` - Guidelines: ${item.guidelines.join(", ")}`);
+ }
+ if (item.actualEvidenceFound.length) {
+ lines.push(` - Actual evidence found: ${item.actualEvidenceFound.slice(0, 5).join(", ")}`);
+ } else if (item.expectedEvidence.length) {
+ lines.push(` - Expected evidence: ${item.expectedEvidence.slice(0, 5).join(", ")}`);
}
if (item.reason) {
lines.push(` - Reason: ${item.reason}`);
@@ -479,11 +608,6 @@ function renderMarkdown(report) {
lines.push("");
}
- lines.push("## Summary");
- lines.push("");
- lines.push("The current contract and canvases support a storefront product search API well enough for an initial design review.");
- lines.push("The remaining audit gaps are mostly operational: gateway policy, publishing integration, and production controls.");
- lines.push("");
return `${lines.join("\n")}\n`;
}
@@ -492,17 +616,31 @@ function statusClass(status) {
}
function renderHtml(report) {
- const itemsHtml = report.sections
- .map((section) => {
- const rows = section.items.map((item) => {
- const evidence = item.evidence && item.evidence.length ? `
${xmlEscape(item.evidence.slice(0, 5).join(", "))}
` : "";
- const reason = item.reason ? `${xmlEscape(item.reason)}
` : "";
+ const stageSummaryHtml = report.stageSummary
+ .map((stage) => `
+
+
${xmlEscape(stage.title)}
+
${xmlEscape(formatStageSummary(stage))}
+
`)
+ .join("\n");
+
+ const itemsHtml = report.stages
+ .map((stage) => {
+ const rows = stage.items.map((item) => {
+ const stations = item.producedByStation.length ? `Stations: ${xmlEscape(item.producedByStation.join(", "))}
` : "";
+ const guidelines = item.guidelines.length ? `Guidelines: ${xmlEscape(item.guidelines.join(", "))}
` : "";
+ const evidence = item.actualEvidenceFound.length
+ ? `Actual evidence: ${xmlEscape(item.actualEvidenceFound.slice(0, 5).join(", "))}
`
+ : (item.expectedEvidence.length ? `Expected evidence: ${xmlEscape(item.expectedEvidence.slice(0, 5).join(", "))}
` : "");
+ const reason = item.reason ? `Reason: ${xmlEscape(item.reason)}
` : "";
return `
-
+
- ${xmlEscape(formatStatus(item.status))}
+ ${xmlEscape(formatStatus(item.currentStatus))}
${xmlEscape(item.label)}
+ ${stations}
+ ${guidelines}
${evidence}
${reason}
`;
@@ -510,7 +648,13 @@ function renderHtml(report) {
return `
- ${xmlEscape(section.title)}
+
+
+
${xmlEscape(stage.title)}
+
${xmlEscape(stage.readinessLabel || "")}
+
+
${xmlEscape(formatStageSummary(stage.summary))}
+
`;
})
@@ -533,7 +677,6 @@ function renderHtml(report) {
--partial: #fff0b5;
--gap: #ffcdcd;
--na: #e8e4d2;
- --accent: #7dc9e7;
}
body {
margin: 0;
@@ -542,25 +685,37 @@ function renderHtml(report) {
color: var(--text);
}
.wrap {
- max-width: 1100px;
+ max-width: 1180px;
margin: 0 auto;
padding: 32px 20px 56px;
}
- .hero {
+ .hero, .section {
background: var(--card);
border: 1px solid var(--border);
border-radius: 18px;
- padding: 24px;
box-shadow: 0 12px 40px rgba(31, 41, 55, 0.08);
+ }
+ .hero {
+ padding: 24px;
margin-bottom: 24px;
}
- .meta {
+ .meta, .coverage, .stage-grid {
display: grid;
- grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
gap: 12px;
+ }
+ .meta {
+ grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
+ margin-top: 16px;
+ }
+ .coverage {
+ grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
+ margin-top: 16px;
+ }
+ .stage-grid {
+ grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
margin-top: 16px;
}
- .metric {
+ .metric, .stage-summary {
border: 1px solid var(--border);
border-radius: 14px;
padding: 14px;
@@ -571,12 +726,6 @@ function renderHtml(report) {
font-weight: 700;
margin-top: 6px;
}
- .coverage {
- display: grid;
- grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
- gap: 12px;
- margin: 20px 0 0;
- }
.pill {
border-radius: 999px;
padding: 10px 14px;
@@ -589,17 +738,31 @@ function renderHtml(report) {
.pill.partial { background: var(--partial); }
.pill.gap { background: var(--gap); }
.pill.na { background: var(--na); }
+ .stage-title {
+ font-weight: 700;
+ margin-bottom: 6px;
+ }
+ .stage-stats, .section-summary, .meta-row, .links a, .section-head p {
+ color: var(--muted);
+ }
.section {
- background: var(--card);
- border: 1px solid var(--border);
- border-radius: 18px;
padding: 20px 22px;
margin: 0 0 18px;
}
+ .section-head {
+ display: flex;
+ justify-content: space-between;
+ gap: 16px;
+ align-items: flex-start;
+ margin-bottom: 14px;
+ }
.section h2 {
- margin: 0 0 12px;
+ margin: 0 0 6px;
font-size: 1.2rem;
}
+ .section-head p {
+ margin: 0;
+ }
ul {
list-style: none;
padding: 0;
@@ -620,7 +783,7 @@ function renderHtml(report) {
display: flex;
align-items: center;
gap: 12px;
- margin-bottom: 6px;
+ margin-bottom: 8px;
}
.badge {
display: inline-block;
@@ -636,8 +799,7 @@ function renderHtml(report) {
.label {
font-weight: 600;
}
- .evidence, .reason {
- color: var(--muted);
+ .meta-row {
font-size: 0.95rem;
margin-top: 6px;
}
@@ -665,6 +827,9 @@ function renderHtml(report) {
Gap ${report.summary.gap}
NA ${report.summary.na}
+
+ ${stageSummaryHtml}
+
Markdown report
Canonical JSON
@@ -697,7 +862,7 @@ function renderTestcase(name, classname, status, details) {
function renderJUnit(report) {
const testSuites = [];
- const allCheckItems = report.sections.flatMap((section) => section.items.filter((item) => item.status !== undefined));
+ const allCheckItems = report.stages.flatMap((stage) => stage.items.filter((item) => item.currentStatus !== undefined));
const spectralCaseStatus = report.spectral.status === "pass" ? "pass" : "gap";
const spectralCase = renderTestcase(
@@ -717,22 +882,22 @@ function renderJUnit(report) {
``
);
- for (const section of report.sections) {
- const suiteTests = section.items.length;
- const suiteFailures = section.items.filter((item) => item.status === "gap").length;
- const suiteSkipped = section.items.filter((item) => item.status === "partial" || item.status === "na").length;
- const cases = section.items
- .map((item) => renderTestcase(item.label, `APIOps Cycles / ${section.title}`, item.status, item.evidence || []))
+ for (const stage of report.stages) {
+ const suiteTests = stage.items.length;
+ const suiteFailures = stage.items.filter((item) => item.currentStatus === "gap").length;
+ const suiteSkipped = stage.items.filter((item) => item.currentStatus === "partial" || item.currentStatus === "na").length;
+ const cases = stage.items
+ .map((item) => renderTestcase(item.label, `APIOps Cycles / ${stage.title}`, item.currentStatus, item.actualEvidenceFound || []))
.join("");
testSuites.push(
- `
` +
+ `` +
cases +
``
);
}
- const failures = (report.spectral.status === "pass" ? 0 : 1) + report.sections.reduce((acc, section) => acc + section.items.filter((item) => item.status === "gap").length, 0);
- const skipped = report.sections.reduce((acc, section) => acc + section.items.filter((item) => item.status === "partial" || item.status === "na").length, 0);
+ const failures = (report.spectral.status === "pass" ? 0 : 1) + report.stages.reduce((acc, stage) => acc + stage.items.filter((item) => item.currentStatus === "gap").length, 0);
+ const skipped = report.stages.reduce((acc, stage) => acc + stage.items.filter((item) => item.currentStatus === "partial" || item.currentStatus === "na").length, 0);
const tests = 1 + allCheckItems.length;
return [
@@ -748,30 +913,63 @@ function writeFile(filePath, content) {
fs.writeFileSync(filePath, content);
}
-const report = buildReport();
-const markdown = renderMarkdown(report);
-const html = renderHtml(report);
-const junit = renderJUnit(report);
-const reportJson = `${JSON.stringify(report, null, 2)}\n`;
+export function runDesignAudit(options = {}) {
+ const selectedRoot = options.rootDir || process.cwd();
+ const selectedProfile = String(options.profile || process.argv[2] || "read-only").trim();
+
+ if (!["read-only", "full-crud"].includes(selectedProfile)) {
+ throw new Error(`Unknown audit profile: ${selectedProfile}`);
+ }
-writeFile(reportJsonPath, reportJson);
-writeFile(reportMarkdownPath, markdown);
-writeFile(reportDocsPath, markdown);
-writeFile(reportHtmlPath, html);
-writeFile(reportJUnitPath, junit);
+ configureRun(selectedRoot, selectedProfile);
-if (legacyMarkdownPath) {
- writeFile(legacyMarkdownPath, markdown);
-}
-if (legacyDocsPath) {
- writeFile(legacyDocsPath, markdown);
-}
-if (legacyHtmlPath) {
- writeFile(legacyHtmlPath, html);
+ const report = buildReport();
+ const markdown = renderMarkdown(report);
+ const html = renderHtml(report);
+ const junit = renderJUnit(report);
+ const reportJson = `${JSON.stringify(report, null, 2)}\n`;
+
+ writeFile(reportJsonPath, reportJson);
+ writeFile(reportMarkdownPath, markdown);
+ writeFile(reportDocsPath, markdown);
+ writeFile(reportHtmlPath, html);
+ writeFile(reportJUnitPath, junit);
+
+ if (legacyMarkdownPath) {
+ writeFile(legacyMarkdownPath, markdown);
+ }
+ if (legacyDocsPath) {
+ writeFile(legacyDocsPath, markdown);
+ }
+ if (legacyHtmlPath) {
+ writeFile(legacyHtmlPath, html);
+ }
+
+ return {
+ report,
+ paths: {
+ reportJsonPath,
+ reportMarkdownPath,
+ reportDocsPath,
+ reportHtmlPath,
+ reportJUnitPath,
+ legacyMarkdownPath,
+ legacyDocsPath,
+ legacyHtmlPath
+ }
+ };
}
-console.log(`Wrote ${path.relative(root, reportJsonPath)}`);
-console.log(`Wrote ${path.relative(root, reportMarkdownPath)}`);
-console.log(`Wrote ${path.relative(root, reportDocsPath)}`);
-console.log(`Wrote ${path.relative(root, reportHtmlPath)}`);
-console.log(`Wrote ${path.relative(root, reportJUnitPath)}`);
+if (process.argv[1] && path.resolve(process.argv[1]) === __filename) {
+ try {
+ const result = runDesignAudit();
+ console.log(`Wrote ${path.relative(root, result.paths.reportJsonPath)}`);
+ console.log(`Wrote ${path.relative(root, result.paths.reportMarkdownPath)}`);
+ console.log(`Wrote ${path.relative(root, result.paths.reportDocsPath)}`);
+ console.log(`Wrote ${path.relative(root, result.paths.reportHtmlPath)}`);
+ console.log(`Wrote ${path.relative(root, result.paths.reportJUnitPath)}`);
+ } catch (error) {
+ console.error(error instanceof Error ? error.message : String(error));
+ process.exit(1);
+ }
+}
diff --git a/scripts/test-method-content-integrity.mjs b/scripts/test-method-content-integrity.mjs
index 96e3e64..9d8b077 100644
--- a/scripts/test-method-content-integrity.mjs
+++ b/scripts/test-method-content-integrity.mjs
@@ -10,6 +10,7 @@ const linesJson = readJson("src/data/method/lines.json");
const resourcesJson = readJson("src/data/method/resources.json");
const criteriaJson = readJson("src/data/method/criteria.json");
const stakeholdersJson = readJson("src/data/method/stakeholders.json");
+const stationCriteriaJson = readJson("src/data/method/station-criteria.json");
const canvasDataJson = readJson("src/data/canvas/canvasData.json");
const localizedCanvasDataJson = readJson("src/data/canvas/localizedData.json");
const knownResourceIds = new Set((resourcesJson.resources || []).map((resource) => resource.id));
@@ -23,6 +24,7 @@ const localeDirs = readdirSync("src/data/method", { withFileTypes: true })
.filter((entry) => entry.isDirectory())
.map((entry) => entry.name);
const findings = [];
+const lifecycleStages = new Set(["strategy", "architecture", "design", "delivery", "publishing", "improving"]);
function collectMatchingStringValues(node, pattern, results = new Set()) {
if (typeof node === "string") {
@@ -104,6 +106,22 @@ for (const station of stationGroups) {
);
}
}
+
+ if (station.group === "core-stations") {
+ if (!lifecycleStages.has(station.lifecycleStage)) {
+ findings.push(`Core station ${station.id} is missing a valid lifecycleStage.`);
+ }
+
+ const expectedCriteria = stationCriteriaJson[station.id] || [];
+ const actualCriteria = station.stationCriteria || [];
+ if (JSON.stringify(actualCriteria) !== JSON.stringify(expectedCriteria)) {
+ findings.push(`Core station ${station.id} stationCriteria does not match station-criteria.json.`);
+ }
+
+ if (!Array.isArray(station.expectedEvidenceTags) || station.expectedEvidenceTags.length === 0) {
+ findings.push(`Core station ${station.id} must define expectedEvidenceTags.`);
+ }
+ }
}
for (const line of linesJson.lines?.items || []) {
diff --git a/scripts/test-print-method-snippet.mjs b/scripts/test-print-method-snippet.mjs
index 375ffd5..1ec13ea 100644
--- a/scripts/test-print-method-snippet.mjs
+++ b/scripts/test-print-method-snippet.mjs
@@ -42,6 +42,8 @@ try {
const auditSnippet = renderSnippet("api-audit-checklist", "en", { forceUnicode: true });
assert(auditSnippet.includes("\"profiles\""), "Expected api-audit-checklist to render the JSON checklist snippet.");
assert(auditSnippet.includes("\"read-only\""), "Expected api-audit-checklist JSON snippet to include the read-only profile.");
+ assert(auditSnippet.includes("\"stages\""), "Expected api-audit-checklist JSON snippet to include lifecycle stages.");
+ assert(auditSnippet.includes("\"producedByStation\""), "Expected api-audit-checklist JSON snippet to include station ownership links.");
const styleSnippet = renderSnippet("api-design-principles", "en", { forceAscii: true });
assert(styleSnippet.includes("\"guidelines\""), "Expected api-design-principles to render the JSON style snippet.");
diff --git a/scripts/test-run-design-audit.mjs b/scripts/test-run-design-audit.mjs
new file mode 100644
index 0000000..26739ff
--- /dev/null
+++ b/scripts/test-run-design-audit.mjs
@@ -0,0 +1,354 @@
+import { fileURLToPath } from "node:url";
+import { dirname, resolve, join } from "node:path";
+import {
+ mkdtempSync,
+ readFileSync,
+ writeFileSync,
+ mkdirSync,
+ existsSync,
+ rmSync,
+ chmodSync
+} from "node:fs";
+import { tmpdir } from "node:os";
+
+const __filename = fileURLToPath(import.meta.url);
+const __dirname = dirname(__filename);
+const repoRoot = resolve(__dirname, "..");
+const starterContractPath = resolve(repoRoot, "src/snippets/api-contract-example.yaml");
+const canonicalChecklistPath = resolve(repoRoot, "src/snippets/api-audit-checklist.json");
+const tempYamlModulePath = join(repoRoot, "node_modules", "yaml");
+const keepResults = process.argv.includes("--keep-results");
+
+function assert(condition, message) {
+ if (!condition) {
+ throw new Error(message);
+ }
+}
+
+function writeText(filePath, content) {
+ mkdirSync(dirname(filePath), { recursive: true });
+ writeFileSync(filePath, content);
+}
+
+const tempRoot = mkdtempSync(join(tmpdir(), "run-design-audit-test-"));
+
+try {
+ if (!existsSync(tempYamlModulePath)) {
+ writeText(join(tempYamlModulePath, "package.json"), JSON.stringify({
+ name: "yaml",
+ type: "module",
+ exports: "./index.js"
+ }, null, 2));
+ writeText(join(tempYamlModulePath, "index.js"), `const parsedExampleContract = {
+ openapi: "3.0.3",
+ info: {
+ title: "Sample Catalog API",
+ version: "1.0.0",
+ description: "Starter example for a read-only APIOps Cycles API."
+ },
+ servers: [
+ { url: "/v1", description: "Versioned API base path" }
+ ],
+ tags: [
+ { name: "catalog", description: "Browse and search catalog items" }
+ ],
+ paths: {
+ "/items": {
+ get: {
+ tags: ["catalog"],
+ summary: "List catalog items",
+ description: "Returns a paginated list of public catalog items.",
+ operationId: "listItems",
+ parameters: [
+ { $ref: "#/components/parameters/searchTerm" },
+ { $ref: "#/components/parameters/categoryId" },
+ { $ref: "#/components/parameters/page" },
+ { $ref: "#/components/parameters/pageSize" }
+ ],
+ responses: {
+ "200": {
+ description: "Item list",
+ content: {
+ "application/json": {
+ schema: { $ref: "#/components/schemas/ItemListResponse" },
+ examples: {
+ default: {
+ value: {
+ data: [{ itemId: "item-123", slug: "blue-widget", name: "Blue Widget", status: "published" }],
+ page: { number: 1, size: 20, totalItems: 1 }
+ }
+ }
+ }
+ }
+ }
+ },
+ "400": { $ref: "#/components/responses/BadRequest" },
+ "429": { $ref: "#/components/responses/TooManyRequests" }
+ }
+ }
+ },
+ "/items/{itemId}": {
+ get: {
+ tags: ["catalog"],
+ summary: "Get item by id",
+ description: "Returns a single public catalog item by opaque identifier.",
+ operationId: "getItemById",
+ parameters: [{ $ref: "#/components/parameters/itemId" }],
+ responses: {
+ "200": {
+ description: "Item details",
+ content: {
+ "application/json": {
+ schema: { $ref: "#/components/schemas/ItemDetail" }
+ }
+ }
+ },
+ "400": { $ref: "#/components/responses/BadRequest" },
+ "404": { $ref: "#/components/responses/NotFound" }
+ }
+ }
+ },
+ "/items/by-slug/{slug}": {
+ get: {
+ tags: ["catalog"],
+ summary: "Get item by slug",
+ description: "Returns a single item by public slug.",
+ operationId: "getItemBySlug",
+ parameters: [{ $ref: "#/components/parameters/slug" }],
+ responses: {
+ "200": {
+ description: "Item details",
+ content: {
+ "application/json": {
+ schema: { $ref: "#/components/schemas/ItemDetail" }
+ }
+ }
+ },
+ "404": { $ref: "#/components/responses/NotFound" }
+ }
+ }
+ },
+ "/categories/{categoryId}/items": {
+ get: {
+ tags: ["catalog"],
+ summary: "List items in category",
+ description: "Returns public items in a category.",
+ operationId: "listItemsByCategory",
+ parameters: [{ $ref: "#/components/parameters/categoryId" }],
+ responses: {
+ "200": {
+ description: "Category item list",
+ content: {
+ "application/json": {
+ schema: { $ref: "#/components/schemas/ItemListResponse" }
+ }
+ }
+ },
+ "404": { $ref: "#/components/responses/NotFound" }
+ }
+ }
+ }
+ },
+ components: {
+ parameters: {
+ itemId: { name: "itemId", in: "path", required: true, schema: { type: "string", pattern: "^[a-z0-9][a-z0-9-]{1,63}$" }, example: "item-123" },
+ slug: { name: "slug", in: "path", required: true, schema: { type: "string", pattern: "^[a-z0-9]+(?:-[a-z0-9]+)*$" }, example: "blue-widget" },
+ categoryId: { name: "categoryId", in: "path", required: true, schema: { type: "string", pattern: "^[a-z0-9][a-z0-9-]{1,63}$" }, example: "home-goods" },
+ searchTerm: { name: "searchTerm", in: "query", required: false, schema: { type: "string", minLength: 1 }, example: "widget" },
+ page: { name: "page", in: "query", required: false, schema: { type: "integer", minimum: 1, default: 1 } },
+ pageSize: { name: "pageSize", in: "query", required: false, schema: { type: "integer", minimum: 1, maximum: 100, default: 20 } }
+ },
+ responses: {
+ BadRequest: {
+ description: "Validation failed",
+ content: {
+ "application/json": {
+ schema: { $ref: "#/components/schemas/ErrorResponse" },
+ examples: {
+ default: { value: { code: "BAD_REQUEST", message: "Invalid request" } }
+ }
+ }
+ }
+ },
+ NotFound: {
+ description: "Resource not found",
+ content: {
+ "application/json": {
+ schema: { $ref: "#/components/schemas/ErrorResponse" }
+ }
+ }
+ },
+ TooManyRequests: {
+ description: "Rate limit exceeded",
+ headers: {
+ "Retry-After": {
+ schema: { type: "integer" },
+ description: "Seconds until the next allowed request."
+ }
+ },
+ content: {
+ "application/json": {
+ schema: { $ref: "#/components/schemas/ErrorResponse" }
+ }
+ }
+ }
+ },
+ schemas: {
+ ItemListResponse: {
+ type: "object",
+ required: ["data", "page"],
+ properties: {
+ data: { type: "array", items: { $ref: "#/components/schemas/ItemSummary" } },
+ page: { $ref: "#/components/schemas/Page" }
+ }
+ },
+ ItemSummary: {
+ type: "object",
+ required: ["itemId", "slug", "name", "status"],
+ properties: {
+ itemId: { type: "string" },
+ slug: { type: "string" },
+ name: { type: "string" },
+ status: { type: "string", enum: ["published", "hidden"] }
+ }
+ },
+ ItemDetail: {
+ allOf: [
+ { $ref: "#/components/schemas/ItemSummary" },
+ {
+ type: "object",
+ properties: {
+ description: { type: "string" },
+ categories: { type: "array", items: { type: "string" } },
+ variants: { type: "array", items: { $ref: "#/components/schemas/Variant" } }
+ }
+ }
+ ]
+ },
+ Variant: {
+ type: "object",
+ required: ["variantId", "sku", "price", "inventory"],
+ properties: {
+ variantId: { type: "string" },
+ sku: { type: "string" },
+ price: { $ref: "#/components/schemas/Price" },
+ inventory: { $ref: "#/components/schemas/Inventory" }
+ }
+ },
+ Price: {
+ type: "object",
+ required: ["amount", "currency"],
+ properties: {
+ amount: { type: "number", format: "decimal" },
+ currency: { type: "string", example: "EUR" }
+ }
+ },
+ Inventory: {
+ type: "object",
+ required: ["available"],
+ properties: {
+ available: { type: "integer", minimum: 0 },
+ reserved: { type: "integer", minimum: 0 },
+ source: { type: "string" }
+ }
+ },
+ Page: {
+ type: "object",
+ required: ["number", "size", "totalItems"],
+ properties: {
+ number: { type: "integer" },
+ size: { type: "integer" },
+ totalItems: { type: "integer" }
+ }
+ },
+ ErrorResponse: {
+ type: "object",
+ required: ["code", "message"],
+ properties: {
+ code: { type: "string" },
+ message: { type: "string" }
+ }
+ }
+ }
+ }
+};
+
+export default {
+ parse(source) {
+ if (!String(source).includes("Sample Catalog API")) {
+ throw new Error("yaml test stub only supports api-contract-example.yaml");
+ }
+ return parsedExampleContract;
+ }
+};
+`);
+ }
+
+ const { runDesignAudit } = await import("../packages/create-apiops/template/scripts/run-design-audit.js");
+
+ const projectDir = join(tempRoot, "audit-fixture-project");
+ const openApiPath = join(projectDir, "specs", "openapi", "api.yaml");
+ const localChecklistPath = join(projectDir, "specs", "audit", "api-audit-checklist.json");
+ const spectralBinDir = join(projectDir, "node_modules", ".bin");
+ const spectralCmdPath = join(spectralBinDir, "spectral.cmd");
+ const spectralShPath = join(spectralBinDir, "spectral");
+
+ writeText(openApiPath, readFileSync(starterContractPath, "utf8"));
+ writeText(localChecklistPath, readFileSync(canonicalChecklistPath, "utf8"));
+ writeText(spectralCmdPath, "@echo []\r\n");
+ writeText(spectralShPath, "#!/bin/sh\nprintf '[]'\n");
+ chmodSync(spectralShPath, 0o755);
+
+ const { report, paths } = runDesignAudit({
+ rootDir: projectDir,
+ profile: "read-only"
+ });
+
+ for (const reportPath of [
+ paths.reportJsonPath,
+ paths.reportMarkdownPath,
+ paths.reportDocsPath,
+ paths.reportHtmlPath,
+ paths.reportJUnitPath
+ ]) {
+ assert(existsSync(reportPath), `Expected generated audit artifact: ${reportPath}`);
+ }
+
+ assert(report.profile === "read-only", "Expected read-only audit profile in JSON report.");
+ assert(Array.isArray(report.stages), "Expected lifecycle stage results in JSON report.");
+ assert(Array.isArray(report.stageSummary), "Expected lifecycle stage summary in JSON report.");
+ assert(report.stages.some((stage) => stage.id === "strategy"), "Expected strategy stage in JSON report.");
+ assert(report.stages.some((stage) => stage.id === "design"), "Expected design stage in JSON report.");
+ assert(
+ report.stages.flatMap((stage) => stage.items || []).some((item) => Array.isArray(item.producedByStation)),
+ "Expected audit items to include producedByStation."
+ );
+ assert(
+ report.stages.flatMap((stage) => stage.items || []).some((item) => Array.isArray(item.actualEvidenceFound)),
+ "Expected audit items to include actualEvidenceFound."
+ );
+
+ const markdown = readFileSync(paths.reportMarkdownPath, "utf8");
+ assert(markdown.includes("## Lifecycle Summary"), "Expected markdown report to include lifecycle summary.");
+ assert(markdown.includes("### Strategy"), "Expected markdown report to include strategy stage.");
+
+ const html = readFileSync(paths.reportHtmlPath, "utf8");
+ assert(html.includes("stage-summary"), "Expected HTML report to include stage summary cards.");
+ assert(html.includes("Strategy"), "Expected HTML report to include strategy stage title.");
+
+ const junit = readFileSync(paths.reportJUnitPath, "utf8");
+ assert(junit.includes('testsuite name="Strategy"'), "Expected JUnit report to include strategy testsuite.");
+
+ if (keepResults) {
+ console.log(`Preserved audit fixture at ${projectDir}`);
+ console.log(`Inspect JSON report at ${paths.reportJsonPath}`);
+ console.log(`Inspect HTML report at ${paths.reportHtmlPath}`);
+ }
+
+ console.log("run-design-audit regression test passed.");
+} finally {
+ rmSync(tempYamlModulePath, { recursive: true, force: true });
+ if (!keepResults) {
+ rmSync(tempRoot, { recursive: true, force: true });
+ }
+}
diff --git a/src/data/method/de/labels.resources.json b/src/data/method/de/labels.resources.json
index 5284cbb..9019b39 100644
--- a/src/data/method/de/labels.resources.json
+++ b/src/data/method/de/labels.resources.json
@@ -130,17 +130,17 @@
"resource.vendor-management-best-practices.steps": "Einrichtung von Prozessen zur Verwaltung von Anbietern, um Drittanbieter von APIs zu bewerten, einzubinden und zu überwachen.",
"resource.vendor-management-best-practices.tips": "Passen Sie die Best Practices für das Lieferantenmanagement für Ihren Bereich an",
"resource.api-audit-checklist.title": "API Audit Checkliste",
- "resource.api-audit-checklist.description": "Eine umfassende Checkliste zur Überprüfung der API-Bereitschaft vor der Veröffentlichung, die Design, Dokumentation, Sicherheit und die Einhaltung von Richtlinien abdeckt.",
+ "resource.api-audit-checklist.description": "Eine lebenszyklusbasierte Checkliste zur Überprüfung der API-Bereitschaft in den Bereichen Design, Bereitstellung, Veröffentlichung und Compliance anhand definierter Audit-Kriterien und Nachweise.",
"resource.api-audit-checklist.outcomes": "Besseres Verständnis der Grundsätze der API Audit Checkliste",
"resource.api-audit-checklist.steps": "Verwenden Sie die API Audit Checkliste, um sicherzustellen, dass der API-Entwurf die funktionalen und nicht-funktionalen Anforderungen erfüllt, einschließlich Sicherheit, Leistung und Compliance.",
- "resource.api-audit-checklist.tips": "Passen Sie die API Audit Checkliste für Ihre Domäne an",
+ "resource.api-audit-checklist.tips": "Jeder Audit-Punkt verknüpft Lebenszyklus-Arbeitsschritte (Stationen), maßgebliche Richtlinien und unterstützende Nachweise, um einen klaren Überblick über die API-Bereitschaft zu bieten.",
"resource.api-business-model-canvas.title": "API Business Model Canvas",
"resource.api-business-model-canvas.description": "Strategische Bewertung der API-Geschäftsfähigkeit durch Zuordnung von Wertangeboten, Kundensegmenten und Schlüsselressourcen.",
"resource.api-business-model-canvas.outcomes": "Klare Geschäftsstrategie für APIs",
"resource.api-business-model-canvas.steps": "Fassen Sie das Wertversprechen der API zusammen",
"resource.api-business-model-canvas.tips": "Beginnen Sie mit einer einzigen API, um Klarheit zu schaffen",
"resource.api-design-principles.title": "API Design Prinzipien",
- "resource.api-design-principles.description": "Ein präziser Leitfaden für die Benutzerfreundlichkeit, Auffindbarkeit und Konsistenz von APIs, der auf bewährten Designphilosophien und den Bedürfnissen der Benutzer basiert.",
+ "resource.api-design-principles.description": "Ein prägnanter Leitfaden zu API-Benutzerfreundlichkeit, Auffindbarkeit und Konsistenz, der auf gemeinsamen Designregeln und echten Kundenbedürfnissen basiert.",
"resource.api-design-principles.outcomes": "Besseres Verständnis der API-Gestaltungsgrundsätze",
"resource.api-design-principles.steps": "**Consumer-first design:** Wir beginnen jeden APIOps-Zyklus mit der Erfassung von Benutzerzielen und Fachbegriffen, damit APIs echte Probleme lösen.",
"resource.api-design-principles.tips": "Anpassen der API-Entwurfsprinzipien für Ihre Domäne",
@@ -308,9 +308,9 @@
"resource.vendor-management-best-practices.tips.1": "Gemeinsame Nutzung durch Geschäfts- und Technikfunktionen",
"resource.api-audit-checklist.outcomes.1": "Standardisierter Ansatz mit API Audit Checkliste",
"resource.api-audit-checklist.outcomes.2": "Verbesserte Umsetzung der entsprechenden API-Praktiken",
- "resource.api-audit-checklist.steps.1": "Führen Sie Audits durch, um sicherzustellen, dass APIs vor der Veröffentlichung organisatorische, technische und rechtliche Standards erfüllen.",
- "resource.api-audit-checklist.steps.2": "Stellen Sie sicher, dass die Sicherheitsmodelle, die Gateway-Konfiguration und die rechtlichen Bestimmungen für die Verbraucher klar und verständlich sind.",
- "resource.api-audit-checklist.tips.1": "Gemeinsame Nutzung durch Geschäfts- und Technikfunktionen",
+ "resource.api-audit-checklist.steps.1": "Führen Sie Audits durch, um die Abdeckung des Lebenszyklus zu bewerten und sicherzustellen, dass die API den geschäftlichen, gestalterischen und betrieblichen Standards entspricht.",
+ "resource.api-audit-checklist.steps.2": "Stellen Sie sicher, dass Dokumentation, Sicherheitsmodelle, Gateway-Konfiguration und gesetzliche Anforderungen klar definiert, validiert und durch Nachweise belegt sind.",
+ "resource.api-audit-checklist.tips.1": "Nutzen Sie die API-Audit-Checkliste gemeinsam in allen geschäftlichen und technischen Rollen",
"resource.api-business-model-canvas.outcomes.1": "Identifizierung der wichtigsten Ressourcen und Partner",
"resource.api-business-model-canvas.outcomes.2": "Abstimmung der API-Funktionen auf die Unternehmensziele",
"resource.api-business-model-canvas.steps.1": "Definition von Verbrauchersegmenten",
diff --git a/src/data/method/de/labels.stations.json b/src/data/method/de/labels.stations.json
index 4bf8b72..e60ba4b 100644
--- a/src/data/method/de/labels.stations.json
+++ b/src/data/method/de/labels.stations.json
@@ -24,9 +24,9 @@
"station.api-platform-architecture.outcomes": "Redundante APIs abbauen und die Kosten für die Cloud-Plattform senken",
"station.api-platform-architecture.how_it_works": "Das Business Impact Canvas hilft dabei, Risiken in Bezug auf API-Verfügbarkeit, -Sicherheit und -Funktionalität zu identifizieren und zu mindern, um fundierte Architekturentscheidungen zu unterstützen.",
"station.api-design.title": "API-Design - Entwerfen Sie APIs, die Wert liefern",
- "station.api-design.description": "Erstellen Sie durchdachte API-Entwürfe, die sich an den Bedürfnissen der Benutzer, den Produktzielen und konsistenten Spezifikationen orientieren.",
- "station.api-design.why_it_matters": "Beim Entwurf von APIs geht es nicht nur um die Benennung von Endpunkten. Ein gutes Design stellt sicher, dass APIs benutzbar und konsistent sind und mit den geschäftlichen und technischen Zielen übereinstimmen. Schlecht konzipierte APIs führen zu technischen Schulden, schlechter Akzeptanz und Nacharbeit in den Teams.",
- "station.api-design.apply_in_work": "Bereitstellung von wiederverwendbaren Vorlagen, Standards und Validierungstools für API-Spezifikationen. Sicherstellen, dass die Teams Design-Reviews befolgen und Feedback frühzeitig einbeziehen.",
+ "station.api-design.description": "Erstellen Sie API-Designs, die konsistent, wiederverwendbar und auf Geschäftszielen und gemeinsamen Standards basieren.",
+ "station.api-design.why_it_matters": "Beim Entwurf von APIs geht es nicht nur um die Benennung von Endpunkten. Gutes Design stellt sicher, dass APIs benutzerfreundlich, konsistent und auf Geschäfts- und technische Ziele ausgerichtet sind. Schlecht gestaltete APIs führen zu enger Kopplung, geringer Wiederverwendung und kostspieligen Nacharbeiten in den Teams.",
+ "station.api-design.apply_in_work": "Bereitstellung von wiederverwendbaren Designmustern, gemeinsamen Standards und Validierungstools für API-Spezifikationen. Sicherstellen, dass Designentscheidungen konsistent, frühzeitig überprüft und auf die Geschäftsabsicht ausgerichtet sind.",
"station.api-design.outcomes": "Gut dokumentierte und konsistente API-Designs",
"station.api-design.how_it_works": "Definieren Sie zentrale Entitäten, ihre Attribute und Beziehungen, um ein gemeinsames konzeptionelles Verständnis für alle APIs zu schaffen.",
"station.api-delivery.title": "API-Bereitstellung - Bereitstellung sicherer und zuverlässiger APIs",
@@ -36,9 +36,9 @@
"station.api-delivery.outcomes": "APIs, die mit getesteten Frameworks und Mustern implementiert werden",
"station.api-delivery.how_it_works": "Verwenden Sie Best Practices für die API-Entwicklung als Leitfaden für die Implementierung des validierten Vertrags mit etablierten Frameworks und Bibliotheken, um sicherzustellen, dass das Ergebnis wiederverwendbar und wartbar ist.",
"station.api-audit.title": "API-Audit - Prüfung von APIs auf Konformität und Qualität",
- "station.api-audit.description": "Überprüfen Sie vor der Veröffentlichung, ob APIs den organisatorischen, technischen und rechtlichen Standards entsprechen.",
- "station.api-audit.why_it_matters": "APIs sind langlebige Produkte und müssen die Erwartungen an Qualität, Konsistenz und Compliance erfüllen. Audits verringern Risiken, verhindern, dass Mängel in die Produktion gelangen, und unterstützen externe Zertifizierungen.",
- "station.api-audit.apply_in_work": "Schaffung von Governance-Frameworks und -Tools für die Validierung von API-Konformität, Leistung und Sicherheit. Überwachen Sie, dass APIs die Validierungskriterien erfüllen.",
+ "station.api-audit.description": "Stellen Sie sicher, dass APIs vor der Veröffentlichung und Bereitstellung den geschäftlichen, gestalterischen und betrieblichen Standards entsprechen.",
+ "station.api-audit.why_it_matters": "APIs sind langlebige Produkte und müssen den Erwartungen hinsichtlich Qualität, Konsistenz und Compliance entsprechen. Das Audit verbindet Designentscheidungen, Implementierung und Betriebsbereitschaft mit definierten Standards und reduziert so Risiken vor der Bereitstellung.",
+ "station.api-audit.apply_in_work": "Richten Sie einen konsistenten Audit-Prozess ein, der die API-Bereitschaft über alle Lebenszyklusphasen hinweg anhand definierter Kriterien, Nachweise und Standards bewertet. Stellen Sie sicher, dass Lücken frühzeitig erkannt und vor der Veröffentlichung behoben werden.",
"station.api-audit.outcomes": "APIs erfüllen interne und externe Standards",
"station.api-audit.how_it_works": "Führen Sie Audits durch, um sicherzustellen, dass APIs vor der Veröffentlichung organisatorische, technische und rechtliche Standards erfüllen.",
"station.api-publishing.title": "API-Veröffentlichung - Veröffentlichen Sie APIs mit Zuversicht",
@@ -223,7 +223,7 @@
"station.api-design.how_it_works.2": "Wenden Sie REST-Entwurfsmuster an, um konsistente, wiederverwendbare API-Verträge zu erstellen, die mit den Beteiligten validiert werden.",
"station.api-design.how_it_works.3": "Wenden Sie ereignisgesteuerte Entwurfsmuster an, um konsistente, wiederverwendbare API-Verträge zu erstellen, die mit den Beteiligten validiert werden.",
"station.api-design.how_it_works.4": "Wenden Sie GraphQL-Designmuster an, um konsistente, wiederverwendbare API-Verträge zu erstellen, die mit den Beteiligten validiert werden.",
- "station.api-design.how_it_works.5": "Nutzen Sie die Designprinzipien und die REST-API-Designrichtlinien, um das protokollspezifische Design so zu verfeinern, dass es nutzbar, verständlich und konsistent bleibt.",
+ "station.api-design.how_it_works.5": "Nutzen Sie die Designprinzipien und den API-Styleguide, um Ihre Designentscheidungen an gemeinsamen Regeln auszurichten und eine konsistente Audit-Validierung zu ermöglichen.",
"station.api-design.how_it_works.6": "Wenden Sie Contract-First- oder Design-First-Ansätze an, um den API-Vertrag vor der Implementierung zu erfassen und zu validieren.",
"station.api-design.how_it_works.7": "Verwenden Sie die API-Audit-Checkliste, um sicherzustellen, dass das API-Design funktionale und nicht-funktionale Anforderungen erfüllt, einschließlich Sicherheit, Leistung und Compliance.",
"station.api-delivery.outcomes.1": "Zuverlässige und automatisierte CI/CD-Pipelines",
diff --git a/src/data/method/en/labels.resources.json b/src/data/method/en/labels.resources.json
index dc4e829..8c185a8 100644
--- a/src/data/method/en/labels.resources.json
+++ b/src/data/method/en/labels.resources.json
@@ -247,15 +247,15 @@
"resource.vendor-management-best-practices.tips": "Customize the Vendor Management Best Practices for your domain",
"resource.vendor-management-best-practices.tips.1": "Use it collaboratively across business and tech roles",
"resource.api-audit-checklist.title": "API Audit Checklist",
- "resource.api-audit-checklist.description": "A comprehensive checklist to verify API readiness before publishing, covering design, documentation, security, and policy compliance.",
+ "resource.api-audit-checklist.description": "A lifecycle-based checklist to verify API readiness across design, delivery, publishing, and compliance using defined audit criteria and evidence.",
"resource.api-audit-checklist.outcomes": "Better understanding of API audit checklist principles",
"resource.api-audit-checklist.outcomes.1": "Standardized approach using API Audit Checklist",
"resource.api-audit-checklist.outcomes.2": "Improved implementation of related API practices",
"resource.api-audit-checklist.steps": "Use the API Audit Checklist to ensure the API design meets functional and non-functional requirements, including security, performance, and compliance.",
- "resource.api-audit-checklist.steps.1": "Conduct audits to ensure APIs meet organizational, technical, and legal standards before publishing.",
- "resource.api-audit-checklist.steps.2": "Ensure security models, gateway configuration, and legal terms are clear and accessible to consumers.",
- "resource.api-audit-checklist.tips": "Customize the API Audit Checklist for your domain",
- "resource.api-audit-checklist.tips.1": "Use it collaboratively across business and tech roles",
+ "resource.api-audit-checklist.steps.1": "Conduct audits to assess lifecycle coverage and verify that the API meets business, design, and operational standards.",
+ "resource.api-audit-checklist.steps.2": "Ensure that documentation, security models, gateway configuration, and legal requirements are clearly defined, validated, and supported by evidence.",
+ "resource.api-audit-checklist.tips": "Each audit item links lifecycle work (stations), governing guidelines, and supporting evidence to provide a clear view of API readiness.",
+ "resource.api-audit-checklist.tips.1": "Use the API Audit Checklist collaboratively across business and tech roles",
"resource.api-business-model-canvas.title": "API Business Model Canvas",
"resource.api-business-model-canvas.description": "Strategically assess API business viability by mapping value propositions, consumer segments, and key resources.",
"resource.api-business-model-canvas.outcomes": "Clear business strategy for APIs",
@@ -272,7 +272,7 @@
"resource.api-business-model-canvas.tips.1": "Use metrics like cost vs. benefit to prioritize opportunities",
"resource.api-business-model-canvas.tips.2": "Validate outputs with key stakeholders",
"resource.api-design-principles.title": "API Design Principles",
- "resource.api-design-principles.description": "A concise guide to API usability, discoverability, and consistency grounded in proven design philosophies and user needs.",
+ "resource.api-design-principles.description": "A concise guide to API usability, discoverability, and consistency grounded in shared design rules and real consumer needs.",
"resource.api-design-principles.outcomes": "Better understanding of API design principles principles",
"resource.api-design-principles.outcomes.1": "Standardized approach using API Design Principles",
"resource.api-design-principles.outcomes.2": "Improved implementation of related API practices",
diff --git a/src/data/method/en/labels.stations.json b/src/data/method/en/labels.stations.json
index 3f6aa9d..dc04c36 100644
--- a/src/data/method/en/labels.stations.json
+++ b/src/data/method/en/labels.stations.json
@@ -35,9 +35,9 @@
"station.api-platform-architecture.how_it_works.2": "The Capacity Canvas aligns business transaction patterns, future consumption trends, and technical solutions to ensure API scalability and performance.It provides critical input for scaling decisions and infrastructure planning.",
"station.api-platform-architecture.how_it_works.3": "Define and monitor performance metrics (e.g., API calls, latency, error rates) and adoption metrics (e.g., NPS).",
"station.api-design.title": "API Design - Design APIs That Deliver Value",
- "station.api-design.description": "Create thoughtful API designs that align with user needs, product goals, and consistent specifications.",
- "station.api-design.why_it_matters": "Designing APIs is not just about naming endpoints. Good design ensures APIs are usable, consistent, and aligned with business and technical goals. Poorly designed APIs result in technical debt, poor adoption, and rework across teams.",
- "station.api-design.apply_in_work": "Provide reusable templates, standards, and validation tools for API specifications. Ensure teams follow design reviews and incorporate feedback early.",
+ "station.api-design.description": "Create API designs that are consistent, reusable, and grounded in business intent and shared standards.",
+ "station.api-design.why_it_matters": "Designing APIs is not just about naming endpoints. Good design ensures APIs are usable, consistent, and aligned with business and technical goals. Poor design leads to tight coupling, low reuse, and costly rework across teams.",
+ "station.api-design.apply_in_work": "Provide reusable design patterns, shared standards, and validation tools for API specifications. Ensure design decisions are consistent, reviewed early, and aligned with business intent.",
"station.api-design.outcomes": "Well-documented and consistent API designs",
"station.api-design.outcomes.1": "Reusable and validated API contracts",
"station.api-design.outcomes.2": "Designs aligned with domain models and interaction patterns",
@@ -47,7 +47,7 @@
"station.api-design.how_it_works.2": "Apply REST design patterns to create consistent, reusable API contracts that are validated with stakeholders.",
"station.api-design.how_it_works.3": "Apply Event-driven design patterns to create consistent, reusable API contracts that are validated with stakeholders.",
"station.api-design.how_it_works.4": "Apply GraphQL design patterns to create consistent, reusable API contracts that are validated with stakeholders.",
- "station.api-design.how_it_works.5": "Use the design principles and REST API design guidance to refine the protocol-specific design so it stays usable, understandable, and consistent.",
+ "station.api-design.how_it_works.5": "Use the design principles and API style guide to align your design decisions with shared rules and enable consistent audit validation.",
"station.api-design.how_it_works.6": "Apply contract-first or design-first approaches to capture and validate the API contract before implementation.",
"station.api-design.how_it_works.7": "Use the API Audit Checklist to ensure the API design meets functional and non-functional requirements, including security, performance, and compliance.",
"station.api-delivery.title": "API Delivery - Deliver Secure and Reliable APIs",
@@ -65,9 +65,9 @@
"station.api-delivery.how_it_works.4": "Ensure APIs meet security and compliance requirements through automated checks and audits.",
"station.api-delivery.how_it_works.5": "Use the API Audit Checklist to ensure the API meets functional and non-functional requirements, including security, performance, and compliance.",
"station.api-audit.title": "API Audit - Audit APIs for Compliance and Quality",
- "station.api-audit.description": "Validate that APIs meet organizational, technical, and legal standards before publishing.",
- "station.api-audit.why_it_matters": "APIs are long-lived products and need to meet quality, consistency, and compliance expectations. Audits reduce risks, prevent defects from reaching production, and support external certifications.",
- "station.api-audit.apply_in_work": "Create governance frameworks and tools for validating API compliance, performance, and security. Monitor that APIs meet the validation criteria.",
+ "station.api-audit.description": "Validate that APIs meet business, design, and operational standards before publishing and exposure.",
+ "station.api-audit.why_it_matters": "APIs are long-lived products and must meet expectations for quality, consistency, and compliance. The audit connects design decisions, implementation, and operational readiness to defined standards, reducing risk before exposure.",
+ "station.api-audit.apply_in_work": "Establish a consistent audit process that evaluates API readiness across lifecycle stages using defined criteria, evidence, and standards. Ensure gaps are identified early and resolved before publishing.",
"station.api-audit.outcomes": "APIs meet internal and external standards",
"station.api-audit.outcomes.1": "Clear documentation of API design and implementation decisions",
"station.api-audit.outcomes.2": "Security, performance, and compliance validated",
diff --git a/src/data/method/fi/labels.resources.json b/src/data/method/fi/labels.resources.json
index 11b207e..cd88e3c 100644
--- a/src/data/method/fi/labels.resources.json
+++ b/src/data/method/fi/labels.resources.json
@@ -130,17 +130,17 @@
"resource.vendor-management-best-practices.steps": "Ota käyttöön toimittajahallintaprosessit kolmansien osapuolten API-toimittajien arviointia, käyttöönottoa ja seurantaa varten.",
"resource.vendor-management-best-practices.tips": "Mukauta myyjien hallinnan parhaat käytännöt omalle toimialueellesi.",
"resource.api-audit-checklist.title": "API-auditoinnin tarkistuslista",
- "resource.api-audit-checklist.description": "Kattava tarkistuslista API-valmiuden tarkistamiseksi ennen julkaisemista, joka kattaa suunnittelun, dokumentoinnin, tietoturvan ja käytäntöjen noudattamisen.",
+ "resource.api-audit-checklist.description": "Elinkaaripohjainen tarkistuslista, jolla varmistetaan APIn valmius suunnittelun, toimituksen, julkaisun ja vaatimustenmukaisuuden osalta määriteltyjen auditointikriteerien ja todisteiden avulla.",
"resource.api-audit-checklist.outcomes": "Parempi ymmärrys API-auditoinnin tarkistuslistan periaatteista",
"resource.api-audit-checklist.steps": "Varmista API-auditoinnin tarkistuslistan avulla, että API-suunnittelu täyttää toiminnalliset ja muut kuin toiminnalliset vaatimukset, mukaan lukien tietoturva, suorituskyky ja vaatimustenmukaisuus.",
- "resource.api-audit-checklist.tips": "Mukauta API-auditoinnin tarkistuslista toimialueellesi sopivaksi",
+ "resource.api-audit-checklist.tips": "Jokainen auditointikohta yhdistää elinkaaren työvaiheet (asemat), ohjaavat ohjeet ja tukevat todisteet, jotta APIn valmiudesta saadaan selkeä kuva.",
"resource.api-business-model-canvas.title": "API Business Model Canvas",
"resource.api-business-model-canvas.description": "Arvioi strategisesti API-liiketoiminnan elinkelpoisuutta kartoittamalla arvolupaukset, kuluttajasegmentit ja tärkeimmät resurssit.",
"resource.api-business-model-canvas.outcomes": "Selkeä liiketoimintastrategia sovellusrajapintoja varten",
"resource.api-business-model-canvas.steps": "Tiivistä APIn arvolupauksen tiivistelmä",
"resource.api-business-model-canvas.tips": "Aloita yhdestä sovellusrajapinnasta selkeyden varmistamiseksi",
"resource.api-design-principles.title": "APIn suunnitteluperiaatteet",
- "resource.api-design-principles.description": "Tiivis opas APIn käytettävyyteen, löydettävyyteen ja johdonmukaisuuteen, joka perustuu todistettuihin suunnittelufilosofioihin ja käyttäjien tarpeisiin.",
+ "resource.api-design-principles.description": "Tiivis opas APIn käytettävyyteen, löydettävyyteen ja johdonmukaisuuteen, joka perustuu yhteisiin suunnittelusääntöihin ja todellisiin kuluttajien tarpeisiin.",
"resource.api-design-principles.outcomes": "API-suunnittelun periaatteiden parempi ymmärtäminen",
"resource.api-design-principles.steps": "**Kuluttaja ensin -suunnittelu:** Aloita jokainen APIOps-sykli keräämällä käyttäjien tavoitteet ja toimialan ehdot, jotta APIt ratkaisevat todellisia ongelmia.",
"resource.api-design-principles.tips": "Mukauta API-suunnitteluperiaatteet omaan toimialueeseesi sopiviksi",
@@ -308,9 +308,9 @@
"resource.vendor-management-best-practices.tips.1": "Käytä sitä yhteistyössä eri liiketoiminta- ja teknisten roolien välillä",
"resource.api-audit-checklist.outcomes.1": "Standardoitu lähestymistapa API-auditoinnin tarkistuslistan avulla",
"resource.api-audit-checklist.outcomes.2": "Parannettu asiaan liittyvien API-käytäntöjen täytäntöönpano",
- "resource.api-audit-checklist.steps.1": "Suorita tarkastuksia varmistaaksesi, että sovellusrajapinnat täyttävät organisatoriset, tekniset ja oikeudelliset standardit ennen julkaisemista.",
- "resource.api-audit-checklist.steps.2": "Varmista, että turvamallit, yhdyskäytävän kokoonpano ja oikeudelliset ehdot ovat selkeitä ja kuluttajien saatavilla.",
- "resource.api-audit-checklist.tips.1": "Käytä sitä yhteistyössä eri liiketoiminta- ja teknisten roolien välillä",
+ "resource.api-audit-checklist.steps.1": "Suorita auditointeja elinkaaren kattavuuden arvioimiseksi ja varmista, että API täyttää liiketoiminta-, suunnittelu- ja toimintastandardit.",
+ "resource.api-audit-checklist.steps.2": "Varmista, että dokumentaatio, tietoturvamallit, gateway-konfiguraatio ja lakisääteiset vaatimukset on määritelty selkeästi, validoitu ja tuettu todisteilla.",
+ "resource.api-audit-checklist.tips.1": "Käytä API-auditointilistaa yhteistyössä liiketoiminta- ja teknologia-roolien välillä",
"resource.api-business-model-canvas.outcomes.1": "Keskeisten resurssien ja kumppaneiden tunnistaminen",
"resource.api-business-model-canvas.outcomes.2": "API-ominaisuuksien ja liiketoiminnan tavoitteiden yhteensovittaminen",
"resource.api-business-model-canvas.steps.1": "Kuluttajasegmenttien määrittely",
diff --git a/src/data/method/fi/labels.stations.json b/src/data/method/fi/labels.stations.json
index 71f1f4f..5b2b36f 100644
--- a/src/data/method/fi/labels.stations.json
+++ b/src/data/method/fi/labels.stations.json
@@ -24,9 +24,9 @@
"station.api-platform-architecture.outcomes": "Vähennä turhia API-rajapintoja ja vähennä pilvialustakustannuksia.",
"station.api-platform-architecture.how_it_works": "Business Impact Canvas auttaa tunnistamaan ja lieventämään APIn saatavuuteen, tietoturvaan ja toiminnallisuuteen liittyviä riskejä ja tukemaan tietoon perustuvia arkkitehtuuripäätöksiä.",
"station.api-design.title": "API-design - Suunnittele arvoa tuottavia rajapintoja",
- "station.api-design.description": "Luo harkittuja API-designeja, jotka vastaavat käyttäjien tarpeita, tuotetavoitteita ja johdonmukaisia määrityksiä.",
- "station.api-design.why_it_matters": "API-designissa ei ole kyse vain päätepisteiden nimeämisestä. Hyvällä suunnittelulla varmistetaan, että rajapinnat ovat käyttökelpoisia, johdonmukaisia ja linjassa liiketoiminnallisten ja teknisten tavoitteiden kanssa. Huonosti suunnitellut rajapinnat aiheuttavat teknistä velkaa, heikkoa hyväksyntää ja uudelleentyöstämistä tiimeissä.",
- "station.api-design.apply_in_work": "Tarjotaan uudelleenkäytettäviä malleja, standardeja ja validointityökaluja API-määrityksiä varten. Varmistetaan, että tiimit noudattavat suunnittelukatselmuksia ja ottavat palautteen huomioon varhaisessa vaiheessa.",
+ "station.api-design.description": "Luo API-suunnitelmia, jotka ovat johdonmukaisia, uudelleenkäytettäviä ja perustuvat liiketoiminnallisiin tavoitteisiin sekä yhteisiin standardeihin.",
+ "station.api-design.why_it_matters": "APIen suunnittelu ei tarkoita pelkästään päätepisteiden (endpoints) nimeämistä. Hyvä suunnittelu varmistaa, että APIt ovat käyttökelpoisia, johdonmukaisia ja linjassa liiketoiminnallisten ja teknisten tavoitteiden kanssa. Huono suunnittelu johtaa tiukkoihin riippuvuuksiin, heikkoon uudelleenkäytettävyyteen ja kalliiseen uudelleen toteutukseen eri tiimien välillä.",
+ "station.api-design.apply_in_work": "Tarjoa uudelleenkäytettäviä suunnittelumalleja, yhteisiä standardeja ja validointityökaluja API-määrityksille. Varmista, että suunnittelupäätökset ovat johdonmukaisia, tarkistettuja varhaisessa vaiheessa ja linjassa liiketoiminnallisten tavoitteiden kanssa.",
"station.api-design.outcomes": "Hyvin dokumentoidut ja johdonmukaiset API-mallit",
"station.api-design.how_it_works": "Määrittele keskeiset oliot, niiden attribuutit ja suhteet yhteisen käsitteellisen ymmärryksen luomiseksi eri rajapinnoille.",
"station.api-delivery.title": "API-kehitys - Kehitä turvalliset ja luotettavat rajapinnat",
@@ -36,9 +36,9 @@
"station.api-delivery.outcomes": "Rajapinnat, jotka on toteutettu testattujen kehysten ja mallien avulla.",
"station.api-delivery.how_it_works": "Käytä API-kehityksen parhaita käytäntöjä ohjeena validoidun sopimuksen toteuttamiseen vakiintuneilla kehysrakenteilla ja kirjastoilla varmistaen, että tulos on uudelleenkäytettävä ja ylläpidettävä.",
"station.api-audit.title": "API-auditointi - API-rajapintojen tarkastus vaatimustenmukaisuuden ja laadun varmistamiseksi",
- "station.api-audit.description": "Validoi, että rajapinnat täyttävät organisaation, tekniset ja oikeudelliset standardit ennen julkaisemista.",
- "station.api-audit.why_it_matters": "APIt ovat pitkäikäisiä tuotteita, ja niiden on täytettävä laatu-, johdonmukaisuus- ja vaatimustenmukaisuusodotukset. Auditoinnit vähentävät riskejä, estävät virheiden pääsyn tuotantoon ja tukevat ulkoisia sertifiointeja.",
- "station.api-audit.apply_in_work": "Luo hallintakehykset ja työkalut API-yhteensopivuuden, suorituskyvyn ja tietoturvan validointia varten. Varmistetaan, että APIt täyttävät validointikriteerit.",
+ "station.api-audit.description": "Varmista, että APIt täyttävät liiketoiminta-, suunnittelu- ja toimintastandardit ennen julkaisua ja käyttöönottoa.",
+ "station.api-audit.why_it_matters": "APIt ovat pitkäikäisiä tuotteita, ja niiden on täytettävä laatu-, johdonmukaisuus- ja vaatimustenmukaisuusodotukset. Auditointi yhdistää suunnittelupäätökset, toteutuksen ja toimintavalmiuden määriteltyihin standardeihin, mikä vähentää riskejä ennen käyttöönottoa.",
+ "station.api-audit.apply_in_work": "Luo johdonmukainen auditointiprosessi, joka arvioi APIn valmiutta elinkaaren eri vaiheissa määriteltyjen kriteerien, todisteiden ja standardien avulla. Varmista, että puutteet tunnistetaan varhaisessa vaiheessa ja korjataan ennen julkaisua.",
"station.api-audit.outcomes": "APIt täyttävät sisäiset ja ulkoiset standardit",
"station.api-audit.how_it_works": "Suorita tarkastuksia varmistaaksesi, että rajapinnat täyttävät organisatoriset, tekniset ja oikeudelliset standardit ennen julkaisemista.",
"station.api-publishing.title": "API-julkaiseminen - Julkaise APIt luotettavasti",
@@ -223,7 +223,7 @@
"station.api-design.how_it_works.2": "Sovellat REST-suunnittelumalleja luodaksesi johdonmukaisia, uudelleenkäytettäviä API-sopimuksia, jotka validoidaan sidosryhmien kanssa.",
"station.api-design.how_it_works.3": "Sovellat tapahtumapohjaisia suunnittelumalleja luodaksesi johdonmukaisia, uudelleenkäytettäviä API-sopimuksia, jotka validoidaan sidosryhmien kanssa.",
"station.api-design.how_it_works.4": "Sovellat GraphQL-suunnittelumalleja luodaksesi johdonmukaisia, uudelleenkäytettäviä API-sopimuksia, jotka validoidaan sidosryhmien kanssa.",
- "station.api-design.how_it_works.5": "Sovella contract-first- tai design-first-lähestymistapoja API-sopimuksen määrittämiseen ja validointiin ennen toteutusta.",
+ "station.api-design.how_it_works.5": "Käytä suunnitteluperiaatteita ja API-tyyliohjetta, jotta suunnittelupäätöksesi ovat linjassa yhteisten sääntöjen kanssa ja mahdollistavat johdonmukaisen auditoinnin ja validoinnin.",
"station.api-design.how_it_works.6": "Varmistetaan API-auditoinnin tarkistuslistan avulla, että API-suunnittelu täyttää toiminnalliset ja muut kuin toiminnalliset vaatimukset, mukaan lukien tietoturva, suorituskyky ja vaatimustenmukaisuus.",
"station.api-design.how_it_works.7": "Käytä API-tarkastuslistaa varmistaaksesi, että API-suunnittelu täyttää toiminnalliset ja ei-toiminnalliset vaatimukset, mukaan lukien turvallisuus, suorituskyky ja vaatimustenmukaisuus.",
"station.api-delivery.outcomes.1": "Luotettavat ja automatisoidut CI/CD-putket",
diff --git a/src/data/method/fr/labels.resources.json b/src/data/method/fr/labels.resources.json
index 4fef1ce..842b420 100644
--- a/src/data/method/fr/labels.resources.json
+++ b/src/data/method/fr/labels.resources.json
@@ -130,17 +130,17 @@
"resource.vendor-management-best-practices.steps": "Mettre en place des processus de gestion des fournisseurs afin d'évaluer, d'intégrer et de contrôler les fournisseurs d'API tiers.",
"resource.vendor-management-best-practices.tips": "Personnalisez les bonnes pratiques de gestion des fournisseurs pour votre domaine",
"resource.api-audit-checklist.title": "Liste de contrôle de l'audit de l'API",
- "resource.api-audit-checklist.description": "Une liste de contrôle complète pour vérifier l'état de préparation de l'API avant sa publication, couvrant la conception, la documentation, la sécurité et la conformité aux politiques.",
+ "resource.api-audit-checklist.description": "Une liste de contrôle basée sur le cycle de vie permettant de vérifier l'état de préparation de l'API à travers les phases de conception, de livraison, de publication et de conformité à l'aide de critères d'audit et de preuves définis.",
"resource.api-audit-checklist.outcomes": "Meilleure compréhension des principes de la liste de contrôle de l'audit de l'API",
"resource.api-audit-checklist.steps": "Utilisez la liste de contrôle de l'audit de l'API pour vous assurer que la conception de l'API répond aux exigences fonctionnelles et non fonctionnelles, notamment en matière de sécurité, de performances et de conformité.",
- "resource.api-audit-checklist.tips": "Personnalisez la liste de contrôle de l'audit de l'API pour votre domaine",
+ "resource.api-audit-checklist.tips": "Chaque élément d'audit relie les tâches du cycle de vie (étapes), les directives applicables et les preuves à l'appui afin de fournir une vision claire de l'état de préparation de l'API.",
"resource.api-business-model-canvas.title": "API Business Model Canvas",
"resource.api-business-model-canvas.description": "Évaluer stratégiquement la viabilité de l'activité API en établissant une cartographie des propositions de valeur, des segments de consommateurs et des ressources clés.",
"resource.api-business-model-canvas.outcomes": "Une stratégie commerciale claire pour les API",
"resource.api-business-model-canvas.steps": "Résumer la proposition de valeur de l'API",
"resource.api-business-model-canvas.tips": "Commencer par une seule API pour plus de clarté",
"resource.api-design-principles.title": "Principes de conception de l'API",
- "resource.api-design-principles.description": "Un guide concis sur l'utilisabilité, la découvrabilité et la cohérence des API, fondé sur des philosophies de conception éprouvées et sur les besoins des utilisateurs.",
+ "resource.api-design-principles.description": "Un guide concis sur l'ergonomie, la facilité de découverte et la cohérence des API, fondé sur des règles de conception communes et les besoins réels des consommateurs.",
"resource.api-design-principles.outcomes": "Meilleure compréhension des principes de conception des API",
"resource.api-design-principles.steps": "**Consumer-first design:** commencer chaque cycle APIOps en rassemblant les objectifs des utilisateurs et les termes du domaine afin que les APIs résolvent des problèmes réels.",
"resource.api-design-principles.tips": "Personnalisez les principes de conception de l'API pour votre domaine",
@@ -308,9 +308,9 @@
"resource.vendor-management-best-practices.tips.1": "L'utiliser en collaboration avec les entreprises et les techniciens",
"resource.api-audit-checklist.outcomes.1": "Approche normalisée à l'aide de la liste de contrôle de l'audit de l'API",
"resource.api-audit-checklist.outcomes.2": "Amélioration de la mise en œuvre des pratiques liées à l'API",
- "resource.api-audit-checklist.steps.1": "Mener des audits pour s'assurer que les API respectent les normes organisationnelles, techniques et juridiques avant d'être publiées.",
- "resource.api-audit-checklist.steps.2": "Veiller à ce que les modèles de sécurité, la configuration de la passerelle et les termes juridiques soient clairs et accessibles aux consommateurs.",
- "resource.api-audit-checklist.tips.1": "L'utiliser en collaboration avec les entreprises et les techniciens",
+ "resource.api-audit-checklist.steps.1": "Réalisez des audits pour évaluer la couverture du cycle de vie et vérifier que l'API respecte les normes métier, de conception et opérationnelles.",
+ "resource.api-audit-checklist.steps.2": "S'assurer que la documentation, les modèles de sécurité, la configuration de la passerelle et les exigences légales sont clairement définis, validés et étayés par des preuves.",
+ "resource.api-audit-checklist.tips.1": "Utilisez la liste de contrôle d'audit des API de manière collaborative entre les rôles métier et techniques",
"resource.api-business-model-canvas.outcomes.1": "Identification des ressources et des partenaires clés",
"resource.api-business-model-canvas.outcomes.2": "Alignement des fonctionnalités de l'API sur les objectifs de l'entreprise",
"resource.api-business-model-canvas.steps.1": "Définir les segments de consommateurs",
diff --git a/src/data/method/fr/labels.stations.json b/src/data/method/fr/labels.stations.json
index 6706694..f254579 100644
--- a/src/data/method/fr/labels.stations.json
+++ b/src/data/method/fr/labels.stations.json
@@ -24,9 +24,9 @@
"station.api-platform-architecture.outcomes": "Supprimer les API redondantes et réduire les coûts de la plateforme en nuage",
"station.api-platform-architecture.how_it_works": "Le Business Impact Canvas permet d'identifier et d'atténuer les risques liés à la disponibilité, à la sécurité et à la fonctionnalité de l'API afin de prendre des décisions éclairées en matière d'architecture.",
"station.api-design.title": "Conception d'API - Concevoir des API qui apportent de la valeur",
- "station.api-design.description": "Créer des conceptions d'API réfléchies qui s'alignent sur les besoins des utilisateurs, les objectifs du produit et les spécifications cohérentes.",
- "station.api-design.why_it_matters": "Concevoir des API ne consiste pas seulement à nommer des points d'extrémité. Une bonne conception garantit que les API sont utilisables, cohérentes et alignées sur les objectifs commerciaux et techniques. Des API mal conçues entraînent une dette technique, une adoption médiocre et des remaniements au sein des équipes.",
- "station.api-design.apply_in_work": "Fournir des modèles réutilisables, des normes et des outils de validation pour les spécifications de l'API. Veiller à ce que les équipes suivent les revues de conception et intègrent rapidement le retour d'information.",
+ "station.api-design.description": "Créer des architectures d'API cohérentes, réutilisables et fondées sur les objectifs métier et des normes communes.",
+ "station.api-design.why_it_matters": "La conception d'API ne se limite pas à nommer des points de terminaison. Une bonne conception garantit que les API sont utilisables, cohérentes et alignées sur les objectifs métier et techniques. Une mauvaise conception entraîne un couplage étroit, une faible réutilisation et des retouches coûteuses entre les équipes.",
+ "station.api-design.apply_in_work": "Fournir des modèles de conception réutilisables, des normes communes et des outils de validation pour les spécifications d'API. S'assurer que les décisions de conception sont cohérentes, examinées dès le début et alignées sur les objectifs métier.",
"station.api-design.outcomes": "Des conceptions d'API bien documentées et cohérentes",
"station.api-design.how_it_works": "Définir les entités de base, leurs attributs et leurs relations afin de créer une compréhension conceptuelle partagée entre les API.",
"station.api-delivery.title": "Livraison d'API - Fournir des API sécurisées et fiables",
@@ -36,9 +36,9 @@
"station.api-delivery.outcomes": "API mises en œuvre à l'aide de cadres et de modèles testés",
"station.api-delivery.how_it_works": "Utilisez les meilleures pratiques de développement d'API comme guide pour mettre en œuvre le contrat validé à l'aide de frameworks et de bibliothèques établis, en veillant à ce que le résultat soit réutilisable et maintenable.",
"station.api-audit.title": "Audit API - Audit de conformité et de qualité des API",
- "station.api-audit.description": "Valider que les API répondent aux normes organisationnelles, techniques et juridiques avant de les publier.",
- "station.api-audit.why_it_matters": "Les API sont des produits à longue durée de vie et doivent répondre aux attentes en matière de qualité, de cohérence et de conformité. Les audits réduisent les risques, empêchent les défauts d'atteindre la production et soutiennent les certifications externes.",
- "station.api-audit.apply_in_work": "Créer des cadres et des outils de gouvernance pour valider la conformité, les performances et la sécurité des API. Vérifier que les API répondent aux critères de validation.",
+ "station.api-audit.description": "Vérifiez que les API répondent aux normes métier, de conception et opérationnelles avant leur publication et leur mise à disposition.",
+ "station.api-audit.why_it_matters": "Les API sont des produits à longue durée de vie et doivent répondre aux attentes en matière de qualité, de cohérence et de conformité. L'audit relie les décisions de conception, la mise en œuvre et l'état de préparation opérationnelle à des normes définies, réduisant ainsi les risques avant la mise à disposition.",
+ "station.api-audit.apply_in_work": "Mettez en place un processus d'audit cohérent qui évalue l'état de préparation des API à toutes les étapes du cycle de vie à l'aide de critères, de preuves et de normes définis. Assurez-vous que les lacunes sont identifiées tôt et résolues avant la publication.",
"station.api-audit.outcomes": "Les API sont conformes aux normes internes et externes",
"station.api-audit.how_it_works": "Mener des audits pour s'assurer que les API respectent les normes organisationnelles, techniques et juridiques avant d'être publiées.",
"station.api-publishing.title": "Publication d'API - Publier des API en toute confiance",
@@ -223,7 +223,7 @@
"station.api-design.how_it_works.2": "Appliquer les modèles de conception REST pour créer des contrats d'API cohérents et réutilisables qui sont validés avec les parties prenantes.",
"station.api-design.how_it_works.3": "Appliquer des modèles de conception orientés événements pour créer des contrats d'API cohérents et réutilisables qui sont validés avec les parties prenantes.",
"station.api-design.how_it_works.4": "Appliquer les modèles de conception GraphQL pour créer des contrats d'API cohérents et réutilisables qui sont validés avec les parties prenantes.",
- "station.api-design.how_it_works.5": "Utilisez les principes de conception et les recommandations de conception des API REST pour affiner la conception spécifique au protocole afin qu'elle reste utilisable, compréhensible et cohérente.",
+ "station.api-design.how_it_works.5": "Utiliser les principes de conception et le guide de style des API pour aligner vos décisions de conception sur des règles communes et permettre une validation d'audit cohérente.",
"station.api-design.how_it_works.6": "Appliquez des approches « contract-first » ou « design-first » pour définir et valider le contrat de l'API avant sa mise en œuvre.",
"station.api-design.how_it_works.7": "Utilisez la liste de contrôle d'audit des API pour vous assurer que la conception de l'API répond aux exigences fonctionnelles et non fonctionnelles, notamment en matière de sécurité, de performances et de conformité.",
"station.api-delivery.outcomes.1": "Pipelines CI/CD fiables et automatisés",
diff --git a/src/data/method/pt/labels.resources.json b/src/data/method/pt/labels.resources.json
index 011090b..ef876d4 100644
--- a/src/data/method/pt/labels.resources.json
+++ b/src/data/method/pt/labels.resources.json
@@ -247,15 +247,15 @@
"resource.vendor-management-best-practices.tips": "Personalize as Melhores Práticas de Gestão de Fornecedores para o seu domínio",
"resource.vendor-management-best-practices.tips.1": "Utilize-o de forma colaborativa entre as funções comerciais e tecnológicas",
"resource.api-audit-checklist.title": "Lista de verificação de auditoria da API",
- "resource.api-audit-checklist.description": "Uma lista de verificação abrangente para verificar a prontidão da API antes da publicação, abrangendo o design, a documentação, a segurança e a conformidade com a política.",
+ "resource.api-audit-checklist.description": "Uma lista de verificação baseada no ciclo de vida para verificar a prontidão da API em design, entrega, publicação e conformidade usando critérios de auditoria e evidências definidos.",
"resource.api-audit-checklist.outcomes": "Melhor compreensão dos princípios da lista de controlo de auditoria da API",
"resource.api-audit-checklist.outcomes.1": "Abordagem padronizada usando a lista de verificação de auditoria da API",
"resource.api-audit-checklist.outcomes.2": "Melhoria da implementação das práticas de API relacionadas",
"resource.api-audit-checklist.steps": "Utilize a lista de verificação de auditoria da API para garantir que a conceção da API cumpre os requisitos funcionais e não funcionais, incluindo segurança, desempenho e conformidade.",
- "resource.api-audit-checklist.steps.1": "Realizar auditorias para garantir que as APIs cumprem as normas organizacionais, técnicas e legais antes da publicação.",
- "resource.api-audit-checklist.steps.2": "Garantir que os modelos de segurança, a configuração da porta de ligação e os termos legais sejam claros e acessíveis aos consumidores.",
- "resource.api-audit-checklist.tips": "Personalizar a lista de verificação de auditoria da API para o seu domínio",
- "resource.api-audit-checklist.tips.1": "Utilize-o de forma colaborativa entre as funções comerciais e tecnológicas",
+ "resource.api-audit-checklist.steps.1": "Realize auditorias para avaliar a cobertura do ciclo de vida e verificar se a API atende aos padrões de negócios, design e operacionais.",
+ "resource.api-audit-checklist.steps.2": "Certifique-se de que a documentação, os modelos de segurança, a configuração do gateway e os requisitos legais estejam claramente definidos, validados e comprovados por evidências.",
+ "resource.api-audit-checklist.tips": "Cada item de auditoria vincula o trabalho do ciclo de vida (etapas), as diretrizes regulatórias e as evidências de apoio para fornecer uma visão clara da prontidão da API.",
+ "resource.api-audit-checklist.tips.1": "Use a Lista de Verificação de Auditoria de API de forma colaborativa entre as funções de negócios e tecnologia",
"resource.api-business-model-canvas.title": "API Business Model Canvas",
"resource.api-business-model-canvas.description": "Avaliar estrategicamente a viabilidade do negócio de API, mapeando propostas de valor, segmentos de consumidores e recursos-chave.",
"resource.api-business-model-canvas.outcomes": "Estratégia comercial clara para APIs",
@@ -272,7 +272,7 @@
"resource.api-business-model-canvas.tips.1": "Utilizar métricas como custo vs. benefício para dar prioridade às oportunidades",
"resource.api-business-model-canvas.tips.2": "Validar os resultados com as principais partes interessadas",
"resource.api-design-principles.title": "Princípios de conceção da API",
- "resource.api-design-principles.description": "Um guia conciso para a usabilidade, descoberta e consistência da API, baseado em filosofias de design comprovadas e nas necessidades dos utilizadores.",
+ "resource.api-design-principles.description": "Um guia conciso sobre usabilidade, descobribilidade e consistência da API, baseado em regras de design compartilhadas e nas necessidades reais dos consumidores.",
"resource.api-design-principles.outcomes": "Melhor compreensão dos princípios de conceção das API",
"resource.api-design-principles.outcomes.1": "Abordagem normalizada utilizando os princípios de conceção da API",
"resource.api-design-principles.outcomes.2": "Melhoria da implementação das práticas de API relacionadas",
diff --git a/src/data/method/pt/labels.stations.json b/src/data/method/pt/labels.stations.json
index a800e61..91984de 100644
--- a/src/data/method/pt/labels.stations.json
+++ b/src/data/method/pt/labels.stations.json
@@ -35,9 +35,9 @@
"station.api-platform-architecture.how_it_works.2": "O Capacity Canvas alinha os padrões das transacções comerciais, as tendências de consumo futuro e as soluções técnicas para garantir a escalabilidade e o desempenho da API, fornecendo dados essenciais para as decisões de escalabilidade e o planeamento da infraestrutura.",
"station.api-platform-architecture.how_it_works.3": "Definir e monitorizar as métricas de desempenho (por exemplo, chamadas API, latência, taxas de erro) e as métricas de adoção (por exemplo, NPS).",
"station.api-design.title": "Conceção da API - Conceber APIs que proporcionem valor",
- "station.api-design.description": "Criar concepções de API bem pensadas que se alinhem com as necessidades do utilizador, os objectivos do produto e especificações consistentes.",
- "station.api-design.why_it_matters": "A conceção de APIs não se resume à nomeação de pontos de extremidade. Um bom design garante que as APIs sejam utilizáveis, consistentes e alinhadas com os objectivos comerciais e técnicos. APIs mal concebidas resultam em dívida técnica, fraca adoção e retrabalho entre equipas.",
- "station.api-design.apply_in_work": "Fornecer modelos reutilizáveis, normas e ferramentas de validação para especificações de API. Assegurar que as equipas seguem as revisões de design e incorporam o feedback atempadamente.",
+ "station.api-design.description": "Criar projetos de API que sejam consistentes, reutilizáveis e baseados na intenção de negócios e em padrões compartilhados.",
+ "station.api-design.why_it_matters": "Projetar APIs não se resume apenas a nomear endpoints. Um bom projeto garante que as APIs sejam utilizáveis, consistentes e alinhadas com os objetivos comerciais e técnicos. Um projeto inadequado leva a um acoplamento rígido, baixa reutilização e retrabalho dispendioso entre as equipes.",
+ "station.api-design.apply_in_work": "Forneça padrões de projeto reutilizáveis, padrões compartilhados e ferramentas de validação para especificações de API. Garanta que as decisões de projeto sejam consistentes, revisadas antecipadamente e alinhadas com a intenção de negócios.",
"station.api-design.outcomes": "Conceção de API bem documentada e coerente",
"station.api-design.outcomes.1": "Contratos API reutilizáveis e validados",
"station.api-design.outcomes.2": "Desenhos alinhados com modelos de domínio e padrões de interação",
@@ -47,7 +47,7 @@
"station.api-design.how_it_works.2": "Aplicar padrões de conceção REST para criar contratos de API consistentes e reutilizáveis que são validados com as partes interessadas.",
"station.api-design.how_it_works.3": "Aplicar padrões de conceção orientados para eventos para criar contratos de API consistentes e reutilizáveis que são validados com as partes interessadas.",
"station.api-design.how_it_works.4": "Aplicar padrões de design GraphQL para criar contratos de API consistentes e reutilizáveis que são validados com as partes interessadas.",
- "station.api-design.how_it_works.5": "Use os princípios de design e as orientações de design de API REST para refinar o design específico do protocolo, de modo que ele permaneça utilizável, compreensível e consistente.",
+ "station.api-design.how_it_works.5": "Use os princípios de projeto e o guia de estilo de API para alinhar suas decisões de projeto com regras compartilhadas e permitir uma validação de auditoria consistente.",
"station.api-design.how_it_works.6": "Aplique abordagens do tipo ‘contrato primeiro’ ou ‘design primeiro’ para capturar e validar o contrato da API antes da implementação.",
"station.api-design.how_it_works.7": "Use a Lista de Verificação de Auditoria da API para garantir que o design da API atenda aos requisitos funcionais e não funcionais, incluindo segurança, desempenho e conformidade.",
"station.api-delivery.title": "Entrega da API - Fornecer APIs seguras e fiáveis",
@@ -65,9 +65,9 @@
"station.api-delivery.how_it_works.4": "Garantir que as APIs cumprem os requisitos de segurança e conformidade através de verificações e auditorias automatizadas.",
"station.api-delivery.how_it_works.5": "Utilize a lista de verificação de auditoria da API para garantir que a API cumpre os requisitos funcionais e não funcionais, incluindo segurança, desempenho e conformidade.",
"station.api-audit.title": "Auditoria de API - Auditoria de APIs para conformidade e qualidade",
- "station.api-audit.description": "Validar se as APIs cumprem as normas organizacionais, técnicas e legais antes da publicação.",
- "station.api-audit.why_it_matters": "As APIs são produtos de longa duração e precisam de cumprir as expectativas de qualidade, consistência e conformidade. As auditorias reduzem os riscos, evitam que os defeitos cheguem à produção e apoiam as certificações externas.",
- "station.api-audit.apply_in_work": "Criar estruturas e ferramentas de governação para validar a conformidade, o desempenho e a segurança da API. Monitorizar se as APIs cumprem os critérios de validação.",
+ "station.api-audit.description": "Valide se as APIs atendem aos padrões de negócios, design e operacionais antes da publicação e exposição.",
+ "station.api-audit.why_it_matters": "As APIs são produtos de longa duração e devem atender às expectativas de qualidade, consistência e conformidade. A auditoria conecta as decisões de design, a implementação e a prontidão operacional a padrões definidos, reduzindo o risco antes da exposição.",
+ "station.api-audit.apply_in_work": "Estabeleça um processo de auditoria consistente que avalie a prontidão da API em todas as etapas do ciclo de vida usando critérios, evidências e padrões definidos. Garanta que as lacunas sejam identificadas antecipadamente e resolvidas antes da publicação.",
"station.api-audit.outcomes": "As APIs cumprem as normas internas e externas",
"station.api-audit.outcomes.1": "Documentação clara das decisões de conceção e implementação da API",
"station.api-audit.outcomes.2": "Segurança, desempenho e conformidade validados",
diff --git a/src/data/method/stations.json b/src/data/method/stations.json
index 7c8ae19..51bd44b 100644
--- a/src/data/method/stations.json
+++ b/src/data/method/stations.json
@@ -37,7 +37,20 @@
"resource": "apiBusinessModelCanvas"
}
],
- "apply_in_work": "station.api-product-strategy.apply_in_work"
+ "apply_in_work": "station.api-product-strategy.apply_in_work",
+ "lifecycleStage": "strategy",
+ "stationCriteria": [
+ "metrics-feedback-available",
+ "business-goals-defined",
+ "market-research-done",
+ "stakeholder-approval"
+ ],
+ "expectedEvidenceTags": [
+ "design-artifact",
+ "documentation",
+ "research",
+ "roadmap"
+ ]
},
{
"id": "api-consumer-experience",
@@ -67,7 +80,21 @@
"resource": "api-onboarding-best-practices"
}
],
- "apply_in_work": "station.api-consumer-experience.apply_in_work"
+ "apply_in_work": "station.api-consumer-experience.apply_in_work",
+ "lifecycleStage": "strategy",
+ "stationCriteria": [
+ "api-opportunity-documented",
+ "api-reusability",
+ "hide-backend-discrepancies",
+ "value-prop-validated",
+ "consumer-segments-identified",
+ "api-roadmap-defined"
+ ],
+ "expectedEvidenceTags": [
+ "design-artifact",
+ "documentation",
+ "consumer-feedback"
+ ]
},
{
"id": "api-platform-architecture",
@@ -100,7 +127,21 @@
"resource": "api-metrics-and-analytics"
}
],
- "apply_in_work": "station.api-platform-architecture.apply_in_work"
+ "apply_in_work": "station.api-platform-architecture.apply_in_work",
+ "lifecycleStage": "architecture",
+ "stationCriteria": [
+ "api-reusability",
+ "hide-backend-discrepancies",
+ "value-prop-validated",
+ "consumer-segments-identified",
+ "api-roadmap-defined"
+ ],
+ "expectedEvidenceTags": [
+ "architecture-decision",
+ "documentation",
+ "platform-config",
+ "metrics"
+ ]
},
{
"id": "api-design",
@@ -150,7 +191,20 @@
"resource": "api-audit-checklist"
}
],
- "apply_in_work": "station.api-design.apply_in_work"
+ "apply_in_work": "station.api-design.apply_in_work",
+ "lifecycleStage": "design",
+ "stationCriteria": [
+ "architecture-patterns-validated",
+ "hide-backend-discrepancies",
+ "design-reflects-business-value",
+ "api-consistency"
+ ],
+ "expectedEvidenceTags": [
+ "spec",
+ "contract",
+ "design-artifact",
+ "documentation"
+ ]
},
{
"id": "api-delivery",
@@ -192,7 +246,20 @@
"resource": "api-audit-checklist"
}
],
- "apply_in_work": "station.api-delivery.apply_in_work"
+ "apply_in_work": "station.api-delivery.apply_in_work",
+ "lifecycleStage": "delivery",
+ "stationCriteria": [
+ "architecture-patterns-validated",
+ "hide-backend-discrepancies",
+ "design-reflects-business-value",
+ "api-consistency"
+ ],
+ "expectedEvidenceTags": [
+ "implementation",
+ "pipeline-config",
+ "test-report",
+ "security-report"
+ ]
},
{
"id": "api-audit",
@@ -221,7 +288,21 @@
"step": "station.api-audit.how_it_works.2"
}
],
- "apply_in_work": "station.api-audit.apply_in_work"
+ "apply_in_work": "station.api-audit.apply_in_work",
+ "lifecycleStage": "publishing",
+ "stationCriteria": [
+ "architecture-patterns-validated",
+ "design-reflects-business-value",
+ "api-description-available",
+ "api-consistency",
+ "api-contract-tested"
+ ],
+ "expectedEvidenceTags": [
+ "audit-report",
+ "compliance-report",
+ "security-report",
+ "test-report"
+ ]
},
{
"id": "api-publishing",
@@ -251,7 +332,20 @@
"resource": "api-audit-checklist"
}
],
- "apply_in_work": "station.api-publishing.apply_in_work"
+ "apply_in_work": "station.api-publishing.apply_in_work",
+ "lifecycleStage": "publishing",
+ "stationCriteria": [
+ "audit-passed",
+ "audit-reports-shared",
+ "api-ready-for-publishing",
+ "api-documentation-ready"
+ ],
+ "expectedEvidenceTags": [
+ "gateway-config",
+ "developer-portal",
+ "documentation",
+ "release-record"
+ ]
},
{
"id": "monitoring-and-improving",
@@ -281,7 +375,19 @@
"resource": "apiops-CI-CD-for-apis"
}
],
- "apply_in_work": "station.monitoring-and-improving.apply_in_work"
+ "apply_in_work": "station.monitoring-and-improving.apply_in_work",
+ "lifecycleStage": "improving",
+ "stationCriteria": [
+ "api-documentation-ready",
+ "consumer-support-ready",
+ "legal-compliance-clear"
+ ],
+ "expectedEvidenceTags": [
+ "metrics",
+ "consumer-feedback",
+ "incident-report",
+ "roadmap"
+ ]
}
]
},
diff --git a/src/lib/method-engine.js b/src/lib/method-engine.js
index d98754a..8a03f9b 100644
--- a/src/lib/method-engine.js
+++ b/src/lib/method-engine.js
@@ -20,6 +20,14 @@ export const NOTE_COLOR_PALETTE = Object.freeze({
export const DEFAULT_NOTE_INTENT = "default";
export const DEFAULT_NOTE_COLOR = NOTE_COLOR_PALETTE.default;
export const CANVAS_CREATOR_BASE_URL = "https://canvascreator.apiopscycles.com/";
+export const LIFECYCLE_STAGES = Object.freeze([
+ { id: "strategy", title: "Strategy", order: 1 },
+ { id: "architecture", title: "Architecture", order: 2 },
+ { id: "design", title: "Design", order: 3 },
+ { id: "delivery", title: "Delivery", order: 4 },
+ { id: "publishing", title: "Publishing", order: 5 },
+ { id: "improving", title: "Improving", order: 6 }
+]);
export const NEW_API_STATIONS = ["api-product-strategy", "api-platform-architecture", "api-design"];
export const NOTE_INTENT_ALIASES = new Map([
["benefit", "benefit"],
@@ -237,6 +245,10 @@ export function getStations() {
.sort((left, right) => left.order - right.order);
}
+export function getLifecycleStages() {
+ return LIFECYCLE_STAGES.slice();
+}
+
export function getSupportedMethodLocales() {
if (!fs.existsSync(resolveMethodFile())) {
return [DEFAULT_LOCALE];
diff --git a/src/schemas/stations.schema.json b/src/schemas/stations.schema.json
index 83e2862..4859a78 100644
--- a/src/schemas/stations.schema.json
+++ b/src/schemas/stations.schema.json
@@ -31,6 +31,15 @@
"type": "array",
"items": {"type": "string"}
},
+ "lifecycleStage": {"type": "string"},
+ "stationCriteria": {
+ "type": "array",
+ "items": {"type": "string"}
+ },
+ "expectedEvidenceTags": {
+ "type": "array",
+ "items": {"type": "string"}
+ },
"how_it_works": {
"type": "array",
"items": {
@@ -77,6 +86,15 @@
"type": "array",
"items": {"type": "string"}
},
+ "lifecycleStage": {"type": "string"},
+ "stationCriteria": {
+ "type": "array",
+ "items": {"type": "string"}
+ },
+ "expectedEvidenceTags": {
+ "type": "array",
+ "items": {"type": "string"}
+ },
"how_it_works": {
"type": "array",
"items": {
@@ -97,4 +115,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/snippets/api-audit-checklist.json b/src/snippets/api-audit-checklist.json
index fa5463c..e1fbe3d 100644
--- a/src/snippets/api-audit-checklist.json
+++ b/src/snippets/api-audit-checklist.json
@@ -7,10 +7,50 @@
"description": "General API profile that allows create, update, and delete operations."
}
},
- "sections": [
+ "lifecycleStages": [
{
- "id": "concept-ready",
- "title": "Concept is Ready When...",
+ "id": "strategy",
+ "title": "Strategy",
+ "readinessLabel": "Strategy is Ready When...",
+ "order": 1
+ },
+ {
+ "id": "architecture",
+ "title": "Architecture",
+ "readinessLabel": "Architecture is Ready When...",
+ "order": 2
+ },
+ {
+ "id": "design",
+ "title": "Design",
+ "readinessLabel": "Design is Ready When...",
+ "order": 3
+ },
+ {
+ "id": "delivery",
+ "title": "Delivery",
+ "readinessLabel": "Delivery is Ready When...",
+ "order": 4
+ },
+ {
+ "id": "publishing",
+ "title": "Publishing",
+ "readinessLabel": "Publishing is Ready When...",
+ "order": 5
+ },
+ {
+ "id": "improving",
+ "title": "Improving",
+ "readinessLabel": "Improving is Ready When...",
+ "order": 6
+ }
+ ],
+ "stages": [
+ {
+ "id": "strategy",
+ "title": "Strategy",
+ "readinessLabel": "Strategy is Ready When...",
+ "order": 1,
"items": [
{
"id": "based-on-clear-business-needs",
@@ -21,61 +61,210 @@
],
"kind": "manual",
"defaultStatus": "partial",
- "guidelineRef": [
- "REST-DOMAIN-01"
- ],
"automationLevel": "manual",
- "stationSource": [
- "api-product-strategy",
- "business-goals"
+ "primaryStage": "strategy",
+ "producedByStation": [
+ "api-product-strategy"
+ ],
+ "producedByStationCriteria": [
+ "business-goals-defined",
+ "market-research-done",
+ "stakeholder-approval",
+ "metrics-feedback-available"
+ ],
+ "guidelines": [
+ "REST-DOMAIN-01"
],
"resourceSource": [
"apiBusinessModelCanvas",
"apiValuePropositionCanvas"
],
- "evidenceType": [
+ "expectedEvidenceTags": [
"design-artifact",
- "documentation"
+ "documentation",
+ "research"
],
- "evidence": [
- "specs/openapi/api.yaml",
- "docs/api/strategy/Canvas_apiBusinessModelCanvas_en.svg"
+ "expectedEvidence": [
+ "specs/canvases/api-product-strategy/apiValuePropositionCanvas.empty.json",
+ "specs/canvases/api-product-strategy/apiBusinessModelCanvas.empty.json"
]
},
{
- "id": "hides-raw-backend-data",
- "label": "API hides raw backend data and is designed for shared use",
+ "id": "concept-items-audited",
+ "label": "All concept checklist items are audited",
+ "applicableTo": [
+ "read-only",
+ "full-crud"
+ ],
+ "kind": "aggregate",
+ "check": {
+ "type": "stageCoverage",
+ "stageId": "strategy"
+ },
+ "automationLevel": "semi",
+ "primaryStage": "strategy",
+ "producedByStation": [
+ "api-product-strategy",
+ "api-consumer-experience"
+ ],
+ "producedByStationCriteria": [
+ "business-goals-defined",
+ "market-research-done",
+ "stakeholder-approval",
+ "metrics-feedback-available",
+ "api-opportunity-documented",
+ "api-reusability",
+ "value-prop-validated",
+ "consumer-segments-identified"
+ ],
+ "guidelines": [
+ "REST-AUDIT-02"
+ ],
+ "resourceSource": [
+ "api-audit-checklist"
+ ],
+ "expectedEvidenceTags": [
+ "report"
+ ],
+ "expectedEvidence": [
+ "audit/concept-review-report.json"
+ ]
+ }
+ ]
+ },
+ {
+ "id": "architecture",
+ "title": "Architecture",
+ "readinessLabel": "Architecture is Ready When...",
+ "order": 2,
+ "items": [
+ {
+ "id": "versioning-decided",
+ "label": "Versioning strategy decided and supported by gateway",
"applicableTo": [
"read-only",
"full-crud"
],
"kind": "manual",
"defaultStatus": "partial",
- "guidelineRef": [
- "REST-DOMAIN-01"
+ "automationLevel": "semi",
+ "primaryStage": "architecture",
+ "producedByStation": [
+ "api-platform-architecture",
+ "api-publishing"
],
- "automationLevel": "manual",
- "stationSource": [
- "api-design",
- "design-standards",
- "contract-design"
+ "producedByStationCriteria": [
+ "api-roadmap-defined",
+ "api-reusability",
+ "api-ready-for-publishing"
+ ],
+ "guidelines": [
+ "REST-VERSION-01"
],
"resourceSource": [
- "domainCanvas",
- "interactionCanvas",
"restCanvas",
- "api-design-principles",
- "contract-first-design"
+ "contract-first-design",
+ "api-versioning-best-practices",
+ "apiops-CI-CD-for-apis"
],
- "evidenceType": [
+ "expectedEvidenceTags": [
"spec",
- "design-artifact"
+ "ci-cd",
+ "gateway-config"
],
- "evidence": [
+ "expectedEvidence": [
"specs/openapi/api.yaml",
- "docs/api/design/Canvas_interactionCanvas_en.svg"
+ "docs/api/architecture/README.md",
+ "docs/api/publishing/README.md"
+ ]
+ },
+ {
+ "id": "only-via-gateway",
+ "label": "Only accessible via API gateway",
+ "applicableTo": [
+ "read-only",
+ "full-crud"
+ ],
+ "kind": "manual",
+ "defaultStatus": "gap",
+ "automationLevel": "semi",
+ "primaryStage": "architecture",
+ "producedByStation": [
+ "api-platform-architecture",
+ "api-publishing"
+ ],
+ "producedByStationCriteria": [
+ "api-reusability",
+ "api-ready-for-publishing",
+ "audit-passed"
+ ],
+ "guidelines": [
+ "REST-PUBLISH-02",
+ "REST-CAPACITY-02"
+ ],
+ "resourceSource": [
+ "businessImpactCanvas",
+ "locationsCanvas",
+ "api-security-best-practices",
+ "data-privacy-guidelines"
+ ],
+ "expectedEvidenceTags": [
+ "gateway-config",
+ "infra-config",
+ "security-config"
+ ],
+ "expectedEvidence": [
+ "docs/api/architecture/README.md",
+ "docs/api/publishing/README.md"
]
},
+ {
+ "id": "rate-limits-enforced",
+ "label": "Rate limits are enforced",
+ "applicableTo": [
+ "read-only",
+ "full-crud"
+ ],
+ "kind": "manual",
+ "defaultStatus": "partial",
+ "automationLevel": "semi",
+ "primaryStage": "architecture",
+ "producedByStation": [
+ "api-platform-architecture"
+ ],
+ "producedByStationCriteria": [
+ "api-roadmap-defined",
+ "api-reusability"
+ ],
+ "guidelines": [
+ "REST-CAPACITY-01",
+ "REST-OBS-01",
+ "REST-SEC-04"
+ ],
+ "resourceSource": [
+ "capacityCanvas",
+ "api-security-best-practices",
+ "scalable-infrastructure-best-practices",
+ "api-metrics-and-analytics"
+ ],
+ "expectedEvidenceTags": [
+ "gateway-config",
+ "runtime",
+ "monitoring"
+ ],
+ "expectedEvidence": [
+ "specs/canvases/api-platform-architecture/capacityCanvas.empty.json",
+ "docs/api/architecture/README.md"
+ ]
+ }
+ ]
+ },
+ {
+ "id": "design",
+ "title": "Design",
+ "readinessLabel": "Design is Ready When...",
+ "order": 3,
+ "items": [
{
"id": "endpoint-descriptions-present",
"label": "Endpoints have business value and feature descriptions",
@@ -87,14 +276,19 @@
"check": {
"type": "operationDescriptions"
},
- "guidelineRef": [
- "REST-CX-01"
- ],
"automationLevel": "auto",
- "stationSource": [
- "api-consumer-experience",
- "api-product-strategy",
- "contract-design"
+ "primaryStage": "design",
+ "producedByStation": [
+ "api-design",
+ "api-consumer-experience"
+ ],
+ "producedByStationCriteria": [
+ "design-reflects-business-value",
+ "value-prop-validated",
+ "api-opportunity-documented"
+ ],
+ "guidelines": [
+ "REST-CX-01"
],
"resourceSource": [
"apiValuePropositionCanvas",
@@ -102,10 +296,50 @@
"api-onboarding-best-practices",
"contract-first-design"
],
- "evidenceType": [
- "spec"
+ "expectedEvidenceTags": [
+ "spec",
+ "design-artifact"
+ ],
+ "expectedEvidence": [
+ "specs/openapi/api.yaml",
+ "specs/canvases/api-product-strategy/apiValuePropositionCanvas.empty.json"
+ ]
+ },
+ {
+ "id": "hides-raw-backend-data",
+ "label": "API hides raw backend data and is designed for shared use",
+ "applicableTo": [
+ "read-only",
+ "full-crud"
+ ],
+ "kind": "manual",
+ "defaultStatus": "partial",
+ "automationLevel": "manual",
+ "primaryStage": "design",
+ "producedByStation": [
+ "api-design"
+ ],
+ "producedByStationCriteria": [
+ "hide-backend-discrepancies",
+ "design-reflects-business-value"
+ ],
+ "guidelines": [
+ "REST-DOMAIN-01"
+ ],
+ "resourceSource": [
+ "domainCanvas",
+ "interactionCanvas",
+ "restCanvas",
+ "api-design-principles",
+ "contract-first-design"
],
- "evidence": [
+ "expectedEvidenceTags": [
+ "spec",
+ "design-artifact"
+ ],
+ "expectedEvidence": [
+ "specs/canvases/api-product-strategy/domainCanvas.empty.json",
+ "specs/canvases/api-design/interactionCanvas.empty.json",
"specs/openapi/api.yaml"
]
},
@@ -118,28 +352,33 @@
],
"kind": "manual",
"defaultStatus": "partial",
- "guidelineRef": [
- "REST-DOMAIN-02",
- "REST-CX-03"
- ],
"automationLevel": "manual",
- "stationSource": [
+ "primaryStage": "design",
+ "producedByStation": [
"api-design",
- "design-standards",
"api-platform-architecture"
],
+ "producedByStationCriteria": [
+ "api-consistency",
+ "architecture-patterns-validated",
+ "api-reusability"
+ ],
+ "guidelines": [
+ "REST-DOMAIN-02",
+ "REST-CX-03"
+ ],
"resourceSource": [
"restCanvas",
"api-design-principles",
"api-audit-checklist"
],
- "evidenceType": [
+ "expectedEvidenceTags": [
"documentation",
"design-artifact"
],
- "evidence": [
- "README.md",
- "docs/api/design/Canvas_restCanvas_en.svg"
+ "expectedEvidence": [
+ "specs/canvases/api-design/restCanvas.empty.json",
+ "docs/api/design/README.md"
]
},
{
@@ -153,14 +392,16 @@
"check": {
"type": "fieldNamesDescriptive"
},
- "guidelineRef": [
- "REST-NAMING-01"
- ],
"automationLevel": "auto",
- "stationSource": [
- "api-design",
- "design-standards",
- "contract-design"
+ "primaryStage": "design",
+ "producedByStation": [
+ "api-design"
+ ],
+ "producedByStationCriteria": [
+ "api-consistency"
+ ],
+ "guidelines": [
+ "REST-NAMING-01"
],
"resourceSource": [
"domainCanvas",
@@ -168,10 +409,10 @@
"api-design-principles",
"contract-first-design"
],
- "evidenceType": [
+ "expectedEvidenceTags": [
"spec"
],
- "evidence": [
+ "expectedEvidence": [
"specs/openapi/api.yaml"
]
},
@@ -186,23 +427,27 @@
"check": {
"type": "requiredFieldsPresent"
},
- "guidelineRef": [
- "REST-VALIDATION-01"
- ],
"automationLevel": "auto",
- "stationSource": [
- "api-design",
- "contract-design"
+ "primaryStage": "design",
+ "producedByStation": [
+ "api-design"
+ ],
+ "producedByStationCriteria": [
+ "architecture-patterns-validated",
+ "api-consistency"
+ ],
+ "guidelines": [
+ "REST-VALIDATION-01"
],
"resourceSource": [
"domainCanvas",
"contract-first-design"
],
- "evidenceType": [
+ "expectedEvidenceTags": [
"spec",
"contract"
],
- "evidence": [
+ "expectedEvidence": [
"specs/openapi/api.yaml"
]
},
@@ -217,24 +462,26 @@
"check": {
"type": "dateFormatTimezone"
},
- "guidelineRef": [
- "REST-DATA-01"
- ],
"automationLevel": "auto",
- "stationSource": [
- "api-design",
- "design-standards",
- "contract-design"
+ "primaryStage": "design",
+ "producedByStation": [
+ "api-design"
+ ],
+ "producedByStationCriteria": [
+ "api-consistency"
+ ],
+ "guidelines": [
+ "REST-DATA-01"
],
"resourceSource": [
"restCanvas",
"api-design-principles",
"contract-first-design"
],
- "evidenceType": [
+ "expectedEvidenceTags": [
"spec"
],
- "evidence": [
+ "expectedEvidence": [
"specs/openapi/api.yaml"
]
},
@@ -249,14 +496,17 @@
"check": {
"type": "standardizedEnumsOrPatterns"
},
- "guidelineRef": [
- "REST-DATA-02"
- ],
"automationLevel": "auto",
- "stationSource": [
- "api-design",
- "design-standards",
- "contract-design"
+ "primaryStage": "design",
+ "producedByStation": [
+ "api-design"
+ ],
+ "producedByStationCriteria": [
+ "api-consistency",
+ "design-reflects-business-value"
+ ],
+ "guidelines": [
+ "REST-DATA-02"
],
"resourceSource": [
"domainCanvas",
@@ -264,10 +514,10 @@
"api-design-principles",
"contract-first-design"
],
- "evidenceType": [
+ "expectedEvidenceTags": [
"spec"
],
- "evidence": [
+ "expectedEvidence": [
"specs/openapi/api.yaml"
]
},
@@ -282,14 +532,16 @@
"check": {
"type": "avoidAcronyms"
},
- "guidelineRef": [
- "REST-NAMING-02"
- ],
"automationLevel": "auto",
- "stationSource": [
- "api-design",
- "design-standards",
- "contract-design"
+ "primaryStage": "design",
+ "producedByStation": [
+ "api-design"
+ ],
+ "producedByStationCriteria": [
+ "api-consistency"
+ ],
+ "guidelines": [
+ "REST-NAMING-02"
],
"resourceSource": [
"domainCanvas",
@@ -297,10 +549,10 @@
"api-design-principles",
"contract-first-design"
],
- "evidenceType": [
+ "expectedEvidenceTags": [
"spec"
],
- "evidence": [
+ "expectedEvidence": [
"specs/openapi/api.yaml"
]
},
@@ -313,61 +565,31 @@
"kind": "n/a",
"defaultStatus": "na",
"reason": "This profile is read-only and does not create resources.",
- "guidelineRef": [
- "REST-RESP-201-01"
- ],
"automationLevel": "manual",
- "stationSource": [
+ "primaryStage": "design",
+ "producedByStation": [
"api-design",
- "api-consumer-experience",
- "contract-design"
+ "api-consumer-experience"
+ ],
+ "producedByStationCriteria": [
+ "design-reflects-business-value",
+ "api-consistency",
+ "value-prop-validated"
+ ],
+ "guidelines": [
+ "REST-RESP-201-01"
],
"resourceSource": [
"restCanvas",
"api-onboarding-best-practices",
"contract-first-design"
],
- "evidenceType": [
+ "expectedEvidenceTags": [
"spec"
],
- "evidence": [
+ "expectedEvidence": [
"specs/openapi/api.yaml"
]
- }
- ]
- },
- {
- "id": "design-prototype-ready",
- "title": "API Design Prototype is Ready When...",
- "items": [
- {
- "id": "concept-items-audited",
- "label": "All concept checklist items are audited",
- "applicableTo": [
- "read-only",
- "full-crud"
- ],
- "kind": "aggregate",
- "check": {
- "type": "sectionCoverage",
- "sectionId": "concept-ready"
- },
- "guidelineRef": [
- "REST-AUDIT-02"
- ],
- "automationLevel": "semi",
- "stationSource": [
- "api-audit"
- ],
- "resourceSource": [
- "api-audit-checklist"
- ],
- "evidenceType": [
- "report"
- ],
- "evidence": [
- "audit/concept-review-report.json"
- ]
},
{
"id": "paths-max-two-resources",
@@ -381,24 +603,26 @@
"type": "pathDepthMax",
"maxDepth": 2
},
- "guidelineRef": [
- "REST-PATH-01"
- ],
"automationLevel": "auto",
- "stationSource": [
- "api-design",
- "design-standards",
- "contract-design"
+ "primaryStage": "design",
+ "producedByStation": [
+ "api-design"
+ ],
+ "producedByStationCriteria": [
+ "api-consistency"
+ ],
+ "guidelines": [
+ "REST-PATH-01"
],
"resourceSource": [
"restCanvas",
"api-design-principles",
"contract-first-design"
],
- "evidenceType": [
+ "expectedEvidenceTags": [
"spec"
],
- "evidence": [
+ "expectedEvidence": [
"specs/openapi/api.yaml"
]
},
@@ -413,24 +637,28 @@
"check": {
"type": "examplesPresent"
},
- "guidelineRef": [
- "REST-CX-02"
- ],
"automationLevel": "auto",
- "stationSource": [
- "api-consumer-experience",
+ "primaryStage": "design",
+ "producedByStation": [
"api-design",
- "contract-design"
+ "api-consumer-experience"
+ ],
+ "producedByStationCriteria": [
+ "design-reflects-business-value",
+ "value-prop-validated"
+ ],
+ "guidelines": [
+ "REST-CX-02"
],
"resourceSource": [
"api-onboarding-best-practices",
"restCanvas",
"contract-first-design"
],
- "evidenceType": [
+ "expectedEvidenceTags": [
"spec"
],
- "evidence": [
+ "expectedEvidence": [
"specs/openapi/api.yaml"
]
},
@@ -443,25 +671,28 @@
"kind": "n/a",
"defaultStatus": "na",
"reason": "Read-only profile does not expose create or update operations.",
- "guidelineRef": [
+ "automationLevel": "manual",
+ "primaryStage": "design",
+ "producedByStation": [
+ "api-design"
+ ],
+ "producedByStationCriteria": [
+ "api-consistency",
+ "design-reflects-business-value"
+ ],
+ "guidelines": [
"REST-HTTP-POST-01",
"REST-HTTP-PUT-01"
],
- "automationLevel": "manual",
- "stationSource": [
- "api-design",
- "design-standards",
- "contract-design"
- ],
"resourceSource": [
"restCanvas",
"api-design-principles",
"contract-first-design"
],
- "evidenceType": [
+ "expectedEvidenceTags": [
"spec"
],
- "evidence": [
+ "expectedEvidence": [
"specs/openapi/api.yaml"
]
},
@@ -474,62 +705,29 @@
"kind": "n/a",
"defaultStatus": "na",
"reason": "Read-only profile does not expose delete operations.",
- "guidelineRef": [
- "REST-HTTP-DELETE-01"
- ],
"automationLevel": "manual",
- "stationSource": [
- "api-design",
- "design-standards",
- "contract-design"
+ "primaryStage": "design",
+ "producedByStation": [
+ "api-design"
+ ],
+ "producedByStationCriteria": [
+ "api-consistency"
+ ],
+ "guidelines": [
+ "REST-HTTP-DELETE-01"
],
"resourceSource": [
"restCanvas",
"api-design-principles",
"contract-first-design"
],
- "evidenceType": [
+ "expectedEvidenceTags": [
"spec"
],
- "evidence": [
+ "expectedEvidence": [
"specs/openapi/api.yaml"
]
},
- {
- "id": "versioning-decided",
- "label": "Versioning strategy decided and supported by gateway",
- "applicableTo": [
- "read-only",
- "full-crud"
- ],
- "kind": "manual",
- "defaultStatus": "partial",
- "guidelineRef": [
- "REST-VERSION-01"
- ],
- "automationLevel": "semi",
- "stationSource": [
- "api-design",
- "release-management",
- "api-publishing",
- "api-platform-architecture"
- ],
- "resourceSource": [
- "restCanvas",
- "contract-first-design",
- "api-versioning-best-practices",
- "apiops-CI-CD-for-apis"
- ],
- "evidenceType": [
- "spec",
- "ci-cd",
- "gateway-config"
- ],
- "evidence": [
- "specs/openapi/api.yaml",
- ".github/workflows/openapi-lint.yml"
- ]
- },
{
"id": "get-no-request-body",
"label": "GET has no request body and returns content",
@@ -541,25 +739,27 @@
"check": {
"type": "getNoRequestBody"
},
- "guidelineRef": [
+ "automationLevel": "auto",
+ "primaryStage": "design",
+ "producedByStation": [
+ "api-design"
+ ],
+ "producedByStationCriteria": [
+ "api-consistency"
+ ],
+ "guidelines": [
"REST-HTTP-GET-01",
"REST-RESP-200-01"
],
- "automationLevel": "auto",
- "stationSource": [
- "api-design",
- "design-standards",
- "contract-design"
- ],
"resourceSource": [
"restCanvas",
"api-design-principles",
"contract-first-design"
],
- "evidenceType": [
+ "expectedEvidenceTags": [
"spec"
],
- "evidence": [
+ "expectedEvidence": [
"specs/openapi/api.yaml"
]
},
@@ -573,24 +773,28 @@
"kind": "n/a",
"defaultStatus": "na",
"reason": "The current contract returns content for all GET operations.",
- "guidelineRef": [
- "REST-RESP-204-02"
- ],
"automationLevel": "manual",
- "stationSource": [
+ "primaryStage": "design",
+ "producedByStation": [
"api-design",
- "api-consumer-experience",
- "contract-design"
+ "api-consumer-experience"
+ ],
+ "producedByStationCriteria": [
+ "api-consistency",
+ "value-prop-validated"
+ ],
+ "guidelines": [
+ "REST-RESP-204-02"
],
"resourceSource": [
"restCanvas",
"api-onboarding-best-practices",
"contract-first-design"
],
- "evidenceType": [
+ "expectedEvidenceTags": [
"spec"
],
- "evidence": [
+ "expectedEvidence": [
"specs/openapi/api.yaml"
]
},
@@ -603,24 +807,28 @@
"kind": "n/a",
"defaultStatus": "na",
"reason": "Read-only profile does not expose POST updates.",
- "guidelineRef": [
- "REST-RESP-200-01"
- ],
"automationLevel": "manual",
- "stationSource": [
+ "primaryStage": "design",
+ "producedByStation": [
"api-design",
- "api-consumer-experience",
- "contract-design"
+ "api-consumer-experience"
+ ],
+ "producedByStationCriteria": [
+ "api-consistency",
+ "value-prop-validated"
+ ],
+ "guidelines": [
+ "REST-RESP-200-01"
],
"resourceSource": [
"restCanvas",
"api-onboarding-best-practices",
"contract-first-design"
],
- "evidenceType": [
+ "expectedEvidenceTags": [
"spec"
],
- "evidence": [
+ "expectedEvidence": [
"specs/openapi/api.yaml"
]
},
@@ -633,24 +841,28 @@
"kind": "n/a",
"defaultStatus": "na",
"reason": "Read-only profile does not expose POST creates.",
- "guidelineRef": [
- "REST-RESP-201-01"
- ],
"automationLevel": "manual",
- "stationSource": [
+ "primaryStage": "design",
+ "producedByStation": [
"api-design",
- "api-consumer-experience",
- "contract-design"
+ "api-consumer-experience"
+ ],
+ "producedByStationCriteria": [
+ "api-consistency",
+ "value-prop-validated"
+ ],
+ "guidelines": [
+ "REST-RESP-201-01"
],
"resourceSource": [
"restCanvas",
"api-onboarding-best-practices",
"contract-first-design"
],
- "evidenceType": [
+ "expectedEvidenceTags": [
"spec"
],
- "evidence": [
+ "expectedEvidence": [
"specs/openapi/api.yaml"
]
},
@@ -663,24 +875,28 @@
"kind": "n/a",
"defaultStatus": "na",
"reason": "Read-only profile does not expose DELETE operations.",
- "guidelineRef": [
- "REST-RESP-204-01"
- ],
"automationLevel": "manual",
- "stationSource": [
+ "primaryStage": "design",
+ "producedByStation": [
"api-design",
- "api-consumer-experience",
- "contract-design"
+ "api-consumer-experience"
+ ],
+ "producedByStationCriteria": [
+ "api-consistency",
+ "value-prop-validated"
+ ],
+ "guidelines": [
+ "REST-RESP-204-01"
],
"resourceSource": [
"restCanvas",
"api-onboarding-best-practices",
"contract-first-design"
],
- "evidenceType": [
+ "expectedEvidenceTags": [
"spec"
],
- "evidence": [
+ "expectedEvidence": [
"specs/openapi/api.yaml"
]
},
@@ -695,15 +911,19 @@
"check": {
"type": "errorResponsesSpecific"
},
- "guidelineRef": [
- "REST-ERROR-400-01"
- ],
"automationLevel": "auto",
- "stationSource": [
- "api-consumer-experience",
+ "primaryStage": "design",
+ "producedByStation": [
"api-design",
- "api-audit",
- "contract-design"
+ "api-consumer-experience"
+ ],
+ "producedByStationCriteria": [
+ "design-reflects-business-value",
+ "api-consistency",
+ "value-prop-validated"
+ ],
+ "guidelines": [
+ "REST-ERROR-400-01"
],
"resourceSource": [
"api-onboarding-best-practices",
@@ -711,10 +931,10 @@
"api-audit-checklist",
"contract-first-design"
],
- "evidenceType": [
+ "expectedEvidenceTags": [
"spec"
],
- "evidence": [
+ "expectedEvidence": [
"specs/openapi/api.yaml"
]
},
@@ -728,28 +948,32 @@
"kind": "n/a",
"defaultStatus": "na",
"reason": "The current public storefront contract is intentionally unauthenticated.",
- "guidelineRef": [
+ "automationLevel": "semi",
+ "primaryStage": "design",
+ "producedByStation": [
+ "api-design",
+ "api-publishing"
+ ],
+ "producedByStationCriteria": [
+ "api-consistency",
+ "api-ready-for-publishing"
+ ],
+ "guidelines": [
"REST-ERROR-401-01",
"REST-SEC-01",
"REST-SEC-03"
],
- "automationLevel": "semi",
- "stationSource": [
- "security-and-privacy",
- "api-platform-architecture",
- "api-publishing"
- ],
"resourceSource": [
"api-security-best-practices",
"data-privacy-guidelines",
"contract-first-design"
],
- "evidenceType": [
+ "expectedEvidenceTags": [
"spec",
"security-config",
"gateway-config"
],
- "evidence": [
+ "expectedEvidence": [
"specs/openapi/api.yaml"
]
},
@@ -763,285 +987,244 @@
"kind": "n/a",
"defaultStatus": "na",
"reason": "The current profile is public read-only and exposes no unauthorized operations.",
- "guidelineRef": [
- "REST-ERROR-403-01",
- "REST-SEC-03"
- ],
"automationLevel": "semi",
- "stationSource": [
- "security-and-privacy",
- "api-platform-architecture",
+ "primaryStage": "design",
+ "producedByStation": [
+ "api-design",
"api-publishing"
],
+ "producedByStationCriteria": [
+ "api-consistency",
+ "api-ready-for-publishing"
+ ],
+ "guidelines": [
+ "REST-ERROR-403-01",
+ "REST-SEC-03"
+ ],
"resourceSource": [
"api-security-best-practices",
"data-privacy-guidelines",
"contract-first-design"
],
- "evidenceType": [
+ "expectedEvidenceTags": [
"spec",
"security-config",
"gateway-config"
],
- "evidence": [
+ "expectedEvidence": [
"specs/openapi/api.yaml"
]
- }
- ]
- },
- {
- "id": "production-ready",
- "title": "API Is Maintainable in Production When...",
- "items": [
+ },
{
- "id": "design-items-audited",
- "label": "All prototype and design items are audited",
+ "id": "spec-contains-schemas",
+ "label": "Spec contains request and response schema",
"applicableTo": [
"read-only",
"full-crud"
],
- "kind": "aggregate",
+ "kind": "openapi",
"check": {
- "type": "sectionCoverage",
- "sectionId": "design-prototype-ready"
+ "type": "schemasPresent"
},
- "guidelineRef": [
- "REST-AUDIT-02"
+ "automationLevel": "auto",
+ "primaryStage": "design",
+ "producedByStation": [
+ "api-design"
],
- "automationLevel": "semi",
- "stationSource": [
- "api-audit"
+ "producedByStationCriteria": [
+ "architecture-patterns-validated",
+ "api-consistency"
+ ],
+ "guidelines": [
+ "REST-CONTRACT-01"
],
"resourceSource": [
- "api-audit-checklist"
+ "contract-first-design",
+ "restCanvas"
],
- "evidenceType": [
- "report"
+ "expectedEvidenceTags": [
+ "spec",
+ "contract"
],
- "evidence": [
- "audit/production-readiness-review.json"
+ "expectedEvidence": [
+ "specs/openapi/api.yaml"
]
},
{
- "id": "published-via-api-management",
- "label": "Published via API management",
+ "id": "pseudo-identifiers",
+ "label": "UUIDs or pseudo-identifiers instead of DB IDs",
"applicableTo": [
"read-only",
"full-crud"
],
- "kind": "manual",
- "defaultStatus": "gap",
- "guidelineRef": [
- "REST-PUBLISH-01"
+ "kind": "openapi",
+ "check": {
+ "type": "opaqueIdentifiers"
+ },
+ "automationLevel": "auto",
+ "primaryStage": "design",
+ "producedByStation": [
+ "api-design"
],
- "automationLevel": "semi",
- "stationSource": [
- "api-publishing",
- "api-platform-architecture",
- "ci-cd"
+ "producedByStationCriteria": [
+ "hide-backend-discrepancies",
+ "api-consistency"
+ ],
+ "guidelines": [
+ "REST-SEC-07"
],
"resourceSource": [
- "apiops-CI-CD-for-apis",
- "api-onboarding-best-practices",
- "api-audit-checklist"
+ "domainCanvas",
+ "contract-first-design",
+ "api-security-best-practices"
],
- "evidenceType": [
- "gateway-config",
- "ci-cd",
- "documentation"
+ "expectedEvidenceTags": [
+ "spec"
],
- "evidence": [
- ".github/workflows/openapi-lint.yml",
- "docs/api/publishing/README.md"
+ "expectedEvidence": [
+ "specs/openapi/api.yaml"
]
},
{
- "id": "visible-in-dev-portal",
- "label": "Visible in developer portal",
+ "id": "no-sensitive-data-in-urls",
+ "label": "No sensitive data in URLs",
"applicableTo": [
"read-only",
"full-crud"
],
- "kind": "manual",
- "defaultStatus": "gap",
- "guidelineRef": [
- "REST-PUBLISH-03"
+ "kind": "openapi",
+ "check": {
+ "type": "noSensitiveDataInPaths"
+ },
+ "automationLevel": "auto",
+ "primaryStage": "design",
+ "producedByStation": [
+ "api-design"
],
- "automationLevel": "semi",
- "stationSource": [
- "api-publishing",
- "api-consumer-experience",
- "api-consumer-adoption"
+ "producedByStationCriteria": [
+ "hide-backend-discrepancies",
+ "api-consistency"
+ ],
+ "guidelines": [
+ "REST-SEC-06",
+ "REST-SEC-04"
],
"resourceSource": [
- "api-onboarding-best-practices",
- "api-community-engagement-strategies"
+ "restCanvas",
+ "contract-first-design",
+ "api-security-best-practices",
+ "data-privacy-guidelines"
],
- "evidenceType": [
- "documentation",
- "runtime"
+ "expectedEvidenceTags": [
+ "spec"
],
- "evidence": [
- "docs/api/publishing/README.md"
+ "expectedEvidence": [
+ "specs/openapi/api.yaml"
]
},
{
- "id": "only-via-gateway",
- "label": "Only accessible via API gateway",
+ "id": "http-methods-match-resources",
+ "label": "HTTP methods only for intended resources",
"applicableTo": [
"read-only",
"full-crud"
],
- "kind": "manual",
- "defaultStatus": "gap",
- "guidelineRef": [
- "REST-PUBLISH-02",
- "REST-CAPACITY-02"
+ "kind": "openapi",
+ "check": {
+ "type": "methodResourceConsistency"
+ },
+ "automationLevel": "auto",
+ "primaryStage": "design",
+ "producedByStation": [
+ "api-design"
],
- "automationLevel": "semi",
- "stationSource": [
- "api-platform-architecture",
- "api-publishing",
- "security-and-privacy"
+ "producedByStationCriteria": [
+ "api-consistency"
+ ],
+ "guidelines": [
+ "REST-HTTP-GET-01",
+ "REST-HTTP-POST-01",
+ "REST-HTTP-PUT-01",
+ "REST-HTTP-DELETE-01"
],
"resourceSource": [
- "businessImpactCanvas",
- "locationsCanvas",
- "api-security-best-practices",
- "data-privacy-guidelines"
+ "restCanvas",
+ "api-design-principles",
+ "contract-first-design"
],
- "evidenceType": [
- "gateway-config",
- "infra-config",
- "security-config"
+ "expectedEvidenceTags": [
+ "spec"
],
- "evidence": [
+ "expectedEvidence": [
"specs/openapi/api.yaml"
]
- },
+ }
+ ]
+ },
+ {
+ "id": "delivery",
+ "title": "Delivery",
+ "readinessLabel": "Delivery is Ready When...",
+ "order": 4,
+ "items": [
{
- "id": "rate-limits-enforced",
- "label": "Rate limits are enforced",
+ "id": "design-items-audited",
+ "label": "All prototype and design items are audited",
"applicableTo": [
"read-only",
"full-crud"
],
- "kind": "manual",
- "defaultStatus": "partial",
- "guidelineRef": [
- "REST-CAPACITY-01",
- "REST-OBS-01",
- "REST-SEC-04"
- ],
+ "kind": "aggregate",
+ "check": {
+ "type": "stageCoverage",
+ "stageId": "design"
+ },
"automationLevel": "semi",
- "stationSource": [
- "api-platform-architecture",
- "monitoring-and-improving",
- "scalable-infrastructure",
- "security-and-privacy"
+ "primaryStage": "delivery",
+ "producedByStation": [
+ "api-design",
+ "api-delivery"
+ ],
+ "producedByStationCriteria": [
+ "architecture-patterns-validated",
+ "design-reflects-business-value",
+ "api-consistency"
+ ],
+ "guidelines": [
+ "REST-AUDIT-02"
],
"resourceSource": [
- "capacityCanvas",
- "api-security-best-practices",
- "scalable-infrastructure-best-practices",
- "api-metrics-and-analytics"
+ "api-audit-checklist"
],
- "evidenceType": [
- "gateway-config",
- "runtime",
- "monitoring"
+ "expectedEvidenceTags": [
+ "report"
],
- "evidence": [
- "specs/openapi/api.yaml",
- "spectral/read-only.yaml"
+ "expectedEvidence": [
+ "audit/production-readiness-review.json"
]
},
{
- "id": "docs-auto-generated",
- "label": "Docs auto-generated from spec and schema",
+ "id": "spec-validated-on-change",
+ "label": "Spec validated on every change",
"applicableTo": [
"read-only",
"full-crud"
],
- "kind": "manual",
- "defaultStatus": "partial",
- "guidelineRef": [
- "REST-CONTRACT-02",
- "REST-PUBLISH-03"
+ "kind": "openapi",
+ "check": {
+ "type": "validationWorkflowPresent"
+ },
+ "automationLevel": "auto",
+ "primaryStage": "delivery",
+ "producedByStation": [
+ "api-delivery"
],
- "automationLevel": "semi",
- "stationSource": [
- "api-publishing",
- "contract-design",
- "ci-cd"
- ],
- "resourceSource": [
- "contract-first-design",
- "apiops-CI-CD-for-apis",
- "api-onboarding-best-practices"
- ],
- "evidenceType": [
- "spec",
- "documentation",
- "ci-cd"
- ],
- "evidence": [
- "specs/openapi/api.yaml",
- "README.md"
- ]
- },
- {
- "id": "spec-auto-updated",
- "label": "Spec auto-updated to gateway and dev portal",
- "applicableTo": [
- "read-only",
- "full-crud"
- ],
- "kind": "manual",
- "defaultStatus": "gap",
- "guidelineRef": [
- "REST-CONTRACT-02"
- ],
- "automationLevel": "semi",
- "stationSource": [
- "api-publishing",
- "ci-cd",
- "api-platform-architecture"
- ],
- "resourceSource": [
- "apiops-CI-CD-for-apis",
- "contract-first-design",
- "api-onboarding-best-practices"
- ],
- "evidenceType": [
- "ci-cd",
- "gateway-config",
- "documentation"
- ],
- "evidence": [
- "specs/openapi/api.yaml"
- ]
- },
- {
- "id": "spec-validated-on-change",
- "label": "Spec validated on every change",
- "applicableTo": [
- "read-only",
- "full-crud"
- ],
- "kind": "openapi",
- "check": {
- "type": "validationWorkflowPresent"
- },
- "guidelineRef": [
- "REST-AUDIT-01"
- ],
- "automationLevel": "auto",
- "stationSource": [
- "api-audit",
- "contract-design",
- "ci-cd",
- "test-automation"
+ "producedByStationCriteria": [
+ "architecture-patterns-validated",
+ "api-consistency"
+ ],
+ "guidelines": [
+ "REST-AUDIT-01"
],
"resourceSource": [
"api-audit-checklist",
@@ -1049,47 +1232,16 @@
"apiops-CI-CD-for-apis",
"api-testing-best-practices"
],
- "evidenceType": [
+ "expectedEvidenceTags": [
"ci-cd",
"spec",
"test"
],
- "evidence": [
+ "expectedEvidence": [
".github/workflows/openapi-lint.yml",
"specs/openapi/api.yaml"
]
},
- {
- "id": "spec-contains-schemas",
- "label": "Spec contains request and response schema",
- "applicableTo": [
- "read-only",
- "full-crud"
- ],
- "kind": "openapi",
- "check": {
- "type": "schemasPresent"
- },
- "guidelineRef": [
- "REST-CONTRACT-01"
- ],
- "automationLevel": "auto",
- "stationSource": [
- "api-design",
- "contract-design"
- ],
- "resourceSource": [
- "contract-first-design",
- "restCanvas"
- ],
- "evidenceType": [
- "spec",
- "contract"
- ],
- "evidence": [
- "specs/openapi/api.yaml"
- ]
- },
{
"id": "schema-and-examples-pass",
"label": "Schema and examples pass validation",
@@ -1101,27 +1253,31 @@
"check": {
"type": "examplesPassValidation"
},
- "guidelineRef": [
+ "automationLevel": "auto",
+ "primaryStage": "delivery",
+ "producedByStation": [
+ "api-delivery",
+ "api-design"
+ ],
+ "producedByStationCriteria": [
+ "api-consistency",
+ "architecture-patterns-validated",
+ "api-contract-tested"
+ ],
+ "guidelines": [
"REST-AUDIT-01",
"REST-CONTRACT-01"
],
- "automationLevel": "auto",
- "stationSource": [
- "api-design",
- "api-audit",
- "contract-design",
- "test-automation"
- ],
"resourceSource": [
"contract-first-design",
"api-audit-checklist",
"api-testing-best-practices"
],
- "evidenceType": [
+ "expectedEvidenceTags": [
"spec",
"test"
],
- "evidence": [
+ "expectedEvidence": [
"specs/openapi/api.yaml"
]
},
@@ -1134,53 +1290,30 @@
],
"kind": "manual",
"defaultStatus": "gap",
- "guidelineRef": [
- "REST-SEC-05"
- ],
"automationLevel": "semi",
- "stationSource": [
- "security-and-privacy",
- "api-platform-architecture",
+ "primaryStage": "delivery",
+ "producedByStation": [
+ "api-delivery",
"api-publishing"
],
+ "producedByStationCriteria": [
+ "architecture-patterns-validated",
+ "api-ready-for-publishing"
+ ],
+ "guidelines": [
+ "REST-SEC-05"
+ ],
"resourceSource": [
"api-security-best-practices",
"data-privacy-guidelines",
"api-compliance-best-practices"
],
- "evidenceType": [
+ "expectedEvidenceTags": [
"security-config",
"gateway-config"
],
- "evidence": [
- "specs/openapi/api.yaml"
- ]
- },
- {
- "id": "official-domain",
- "label": "Published under official organization domain",
- "applicableTo": [
- "read-only",
- "full-crud"
- ],
- "kind": "manual",
- "defaultStatus": "gap",
- "guidelineRef": [
- "REST-PUBLISH-04"
- ],
- "automationLevel": "semi",
- "stationSource": [
- "api-publishing"
- ],
- "resourceSource": [
- "api-onboarding-best-practices",
- "api-audit-checklist"
- ],
- "evidenceType": [
- "documentation",
- "runtime"
- ],
- "evidence": [
+ "expectedEvidence": [
+ "docs/api/delivery/README.md",
"docs/api/publishing/README.md"
]
},
@@ -1193,27 +1326,33 @@
"kind": "n/a",
"defaultStatus": "na",
"reason": "This profile is intentionally public read-only.",
- "guidelineRef": [
- "REST-SEC-01",
- "REST-SEC-04"
- ],
"automationLevel": "semi",
- "stationSource": [
- "security-and-privacy",
- "api-platform-architecture",
+ "primaryStage": "delivery",
+ "producedByStation": [
+ "api-delivery",
"api-publishing"
],
+ "producedByStationCriteria": [
+ "architecture-patterns-validated",
+ "api-ready-for-publishing"
+ ],
+ "guidelines": [
+ "REST-SEC-01",
+ "REST-SEC-04"
+ ],
"resourceSource": [
"api-security-best-practices",
"data-privacy-guidelines",
"api-compliance-best-practices"
],
- "evidenceType": [
+ "expectedEvidenceTags": [
"security-config",
"gateway-config",
"spec"
],
- "evidence": [
+ "expectedEvidence": [
+ "docs/api/delivery/README.md",
+ "docs/api/publishing/README.md",
"specs/openapi/api.yaml"
]
},
@@ -1226,25 +1365,31 @@
"kind": "n/a",
"defaultStatus": "na",
"reason": "This profile is intentionally public read-only.",
- "guidelineRef": [
- "REST-SEC-02"
- ],
"automationLevel": "semi",
- "stationSource": [
- "security-and-privacy",
- "api-platform-architecture",
+ "primaryStage": "delivery",
+ "producedByStation": [
+ "api-delivery",
"api-publishing"
],
+ "producedByStationCriteria": [
+ "architecture-patterns-validated",
+ "api-ready-for-publishing"
+ ],
+ "guidelines": [
+ "REST-SEC-02"
+ ],
"resourceSource": [
"api-security-best-practices",
"data-privacy-guidelines",
"api-compliance-best-practices"
],
- "evidenceType": [
+ "expectedEvidenceTags": [
"security-config",
"spec"
],
- "evidence": [
+ "expectedEvidence": [
+ "docs/api/delivery/README.md",
+ "docs/api/publishing/README.md",
"specs/openapi/api.yaml"
]
},
@@ -1257,24 +1402,29 @@
"kind": "n/a",
"defaultStatus": "na",
"reason": "This profile is intentionally public read-only.",
- "guidelineRef": [
- "REST-SEC-08"
- ],
"automationLevel": "semi",
- "stationSource": [
- "security-and-privacy",
+ "primaryStage": "delivery",
+ "producedByStation": [
"api-delivery"
],
+ "producedByStationCriteria": [
+ "architecture-patterns-validated",
+ "api-consistency"
+ ],
+ "guidelines": [
+ "REST-SEC-08"
+ ],
"resourceSource": [
"api-security-best-practices",
"data-privacy-guidelines",
"api-development-best-practices"
],
- "evidenceType": [
+ "expectedEvidenceTags": [
"security-config",
"code"
],
- "evidence": [
+ "expectedEvidence": [
+ "docs/api/delivery/README.md",
"specs/openapi/api.yaml"
]
},
@@ -1287,27 +1437,31 @@
],
"kind": "manual",
"defaultStatus": "partial",
- "guidelineRef": [
- "REST-VALIDATION-01"
- ],
"automationLevel": "semi",
- "stationSource": [
- "api-delivery",
- "development",
- "contract-design"
+ "primaryStage": "delivery",
+ "producedByStation": [
+ "api-delivery"
+ ],
+ "producedByStationCriteria": [
+ "architecture-patterns-validated",
+ "api-consistency"
+ ],
+ "guidelines": [
+ "REST-VALIDATION-01"
],
"resourceSource": [
"api-development-best-practices",
"contract-first-design",
"api-testing-best-practices"
],
- "evidenceType": [
+ "expectedEvidenceTags": [
"code",
"test",
"spec"
],
- "evidence": [
- "specs/openapi/api.yaml"
+ "expectedEvidence": [
+ "specs/openapi/api.yaml",
+ "docs/api/delivery/README.md"
]
},
{
@@ -1320,25 +1474,28 @@
"kind": "n/a",
"defaultStatus": "na",
"reason": "JSON APIs do not typically require output escaping in the same way as HTML rendering.",
- "guidelineRef": [
- "REST-SEC-04"
- ],
"automationLevel": "manual",
- "stationSource": [
- "api-delivery",
- "development",
- "security-and-privacy"
+ "primaryStage": "delivery",
+ "producedByStation": [
+ "api-delivery"
+ ],
+ "producedByStationCriteria": [
+ "architecture-patterns-validated",
+ "api-consistency"
+ ],
+ "guidelines": [
+ "REST-SEC-04"
],
"resourceSource": [
"api-development-best-practices",
"api-security-best-practices",
"data-privacy-guidelines"
],
- "evidenceType": [
+ "expectedEvidenceTags": [
"code"
],
- "evidence": [
- "src/"
+ "expectedEvidence": [
+ "docs/api/delivery/README.md"
]
},
{
@@ -1350,15 +1507,19 @@
],
"kind": "manual",
"defaultStatus": "gap",
- "guidelineRef": [
- "REST-SEC-05"
- ],
"automationLevel": "semi",
- "stationSource": [
- "security-and-privacy",
- "api-platform-architecture",
- "api-publishing",
- "monitoring-and-improving"
+ "primaryStage": "delivery",
+ "producedByStation": [
+ "api-delivery",
+ "api-publishing"
+ ],
+ "producedByStationCriteria": [
+ "architecture-patterns-validated",
+ "api-ready-for-publishing",
+ "audit-passed"
+ ],
+ "guidelines": [
+ "REST-SEC-05"
],
"resourceSource": [
"api-security-best-practices",
@@ -1366,12 +1527,13 @@
"api-compliance-best-practices",
"api-metrics-and-analytics"
],
- "evidenceType": [
+ "expectedEvidenceTags": [
"security-config",
"infra-config",
"documentation"
],
- "evidence": [
+ "expectedEvidence": [
+ "docs/api/delivery/README.md",
"docs/api/publishing/README.md"
]
},
@@ -1384,133 +1546,231 @@
],
"kind": "manual",
"defaultStatus": "gap",
- "guidelineRef": [
+ "automationLevel": "semi",
+ "primaryStage": "delivery",
+ "producedByStation": [
+ "api-delivery"
+ ],
+ "producedByStationCriteria": [
+ "architecture-patterns-validated",
+ "api-consistency"
+ ],
+ "guidelines": [
"REST-OBS-01",
"REST-SEC-04"
],
- "automationLevel": "semi",
- "stationSource": [
- "security-and-privacy",
- "api-platform-architecture",
- "monitoring-and-improving"
- ],
"resourceSource": [
"api-security-best-practices",
"api-compliance-best-practices",
"api-metrics-and-analytics"
],
- "evidenceType": [
+ "expectedEvidenceTags": [
"security-config",
"monitoring",
"documentation"
],
- "evidence": [
+ "expectedEvidence": [
+ "docs/api/delivery/README.md",
+ "docs/api/architecture/README.md"
+ ]
+ }
+ ]
+ },
+ {
+ "id": "publishing",
+ "title": "Publishing",
+ "readinessLabel": "Publishing is Ready When...",
+ "order": 5,
+ "items": [
+ {
+ "id": "published-via-api-management",
+ "label": "Published via API management",
+ "applicableTo": [
+ "read-only",
+ "full-crud"
+ ],
+ "kind": "manual",
+ "defaultStatus": "gap",
+ "automationLevel": "semi",
+ "primaryStage": "publishing",
+ "producedByStation": [
+ "api-publishing"
+ ],
+ "producedByStationCriteria": [
+ "api-ready-for-publishing",
+ "audit-passed"
+ ],
+ "guidelines": [
+ "REST-PUBLISH-01"
+ ],
+ "resourceSource": [
+ "apiops-CI-CD-for-apis",
+ "api-onboarding-best-practices",
+ "api-audit-checklist"
+ ],
+ "expectedEvidenceTags": [
+ "gateway-config",
+ "ci-cd",
+ "documentation"
+ ],
+ "expectedEvidence": [
+ ".github/workflows/openapi-lint.yml",
"docs/api/publishing/README.md"
]
},
{
- "id": "pseudo-identifiers",
- "label": "UUIDs or pseudo-identifiers instead of DB IDs",
+ "id": "visible-in-dev-portal",
+ "label": "Visible in developer portal",
"applicableTo": [
"read-only",
"full-crud"
],
- "kind": "openapi",
- "check": {
- "type": "opaqueIdentifiers"
- },
- "guidelineRef": [
- "REST-SEC-07"
+ "kind": "manual",
+ "defaultStatus": "gap",
+ "automationLevel": "semi",
+ "primaryStage": "publishing",
+ "producedByStation": [
+ "api-publishing"
],
- "automationLevel": "auto",
- "stationSource": [
- "api-design",
- "contract-design",
- "security-and-privacy"
+ "producedByStationCriteria": [
+ "api-documentation-ready",
+ "api-ready-for-publishing"
+ ],
+ "guidelines": [
+ "REST-PUBLISH-03"
+ ],
+ "resourceSource": [
+ "api-onboarding-best-practices",
+ "api-community-engagement-strategies"
+ ],
+ "expectedEvidenceTags": [
+ "documentation",
+ "runtime"
+ ],
+ "expectedEvidence": [
+ "docs/api/publishing/README.md"
+ ]
+ },
+ {
+ "id": "docs-auto-generated",
+ "label": "Docs auto-generated from spec and schema",
+ "applicableTo": [
+ "read-only",
+ "full-crud"
+ ],
+ "kind": "manual",
+ "defaultStatus": "partial",
+ "automationLevel": "semi",
+ "primaryStage": "publishing",
+ "producedByStation": [
+ "api-publishing",
+ "api-delivery"
+ ],
+ "producedByStationCriteria": [
+ "api-documentation-ready",
+ "api-ready-for-publishing",
+ "api-consistency"
+ ],
+ "guidelines": [
+ "REST-CONTRACT-02",
+ "REST-PUBLISH-03"
],
"resourceSource": [
- "domainCanvas",
"contract-first-design",
- "api-security-best-practices"
+ "apiops-CI-CD-for-apis",
+ "api-onboarding-best-practices"
],
- "evidenceType": [
- "spec"
+ "expectedEvidenceTags": [
+ "spec",
+ "documentation",
+ "ci-cd"
],
- "evidence": [
- "specs/openapi/api.yaml"
+ "expectedEvidence": [
+ "specs/openapi/api.yaml",
+ "docs/api/publishing/README.md",
+ "docs/api/audit/design-audit.read-only.md"
]
},
{
- "id": "no-sensitive-data-in-urls",
- "label": "No sensitive data in URLs",
+ "id": "spec-auto-updated",
+ "label": "Spec auto-updated to gateway and dev portal",
"applicableTo": [
"read-only",
"full-crud"
],
- "kind": "openapi",
- "check": {
- "type": "noSensitiveDataInPaths"
- },
- "guidelineRef": [
- "REST-SEC-06",
- "REST-SEC-04"
+ "kind": "manual",
+ "defaultStatus": "gap",
+ "automationLevel": "semi",
+ "primaryStage": "publishing",
+ "producedByStation": [
+ "api-publishing",
+ "api-delivery"
],
- "automationLevel": "auto",
- "stationSource": [
- "api-design",
- "contract-design",
- "security-and-privacy",
- "api-publishing"
+ "producedByStationCriteria": [
+ "api-ready-for-publishing",
+ "audit-passed",
+ "api-consistency"
+ ],
+ "guidelines": [
+ "REST-CONTRACT-02"
],
"resourceSource": [
- "restCanvas",
+ "apiops-CI-CD-for-apis",
"contract-first-design",
- "api-security-best-practices",
- "data-privacy-guidelines"
+ "api-onboarding-best-practices"
],
- "evidenceType": [
- "spec"
+ "expectedEvidenceTags": [
+ "ci-cd",
+ "gateway-config",
+ "documentation"
],
- "evidence": [
+ "expectedEvidence": [
+ ".github/workflows/openapi-lint.yml",
+ "docs/api/publishing/README.md",
"specs/openapi/api.yaml"
]
},
{
- "id": "http-methods-match-resources",
- "label": "HTTP methods only for intended resources",
+ "id": "official-domain",
+ "label": "Published under official organization domain",
"applicableTo": [
"read-only",
"full-crud"
],
- "kind": "openapi",
- "check": {
- "type": "methodResourceConsistency"
- },
- "guidelineRef": [
- "REST-HTTP-GET-01",
- "REST-HTTP-POST-01",
- "REST-HTTP-PUT-01",
- "REST-HTTP-DELETE-01"
+ "kind": "manual",
+ "defaultStatus": "gap",
+ "automationLevel": "semi",
+ "primaryStage": "publishing",
+ "producedByStation": [
+ "api-publishing"
],
- "automationLevel": "auto",
- "stationSource": [
- "api-design",
- "design-standards",
- "contract-design"
+ "producedByStationCriteria": [
+ "api-ready-for-publishing",
+ "audit-passed"
+ ],
+ "guidelines": [
+ "REST-PUBLISH-04"
],
"resourceSource": [
- "restCanvas",
- "api-design-principles",
- "contract-first-design"
+ "api-onboarding-best-practices",
+ "api-audit-checklist"
],
- "evidenceType": [
- "spec"
+ "expectedEvidenceTags": [
+ "documentation",
+ "runtime"
],
- "evidence": [
- "specs/openapi/api.yaml"
+ "expectedEvidence": [
+ "docs/api/publishing/README.md"
]
}
]
+ },
+ {
+ "id": "improving",
+ "title": "Improving",
+ "readinessLabel": "Improving is Ready When...",
+ "order": 6,
+ "items": []
}
],
"guidelines": [
@@ -1916,4 +2176,4 @@
]
}
]
-}
\ No newline at end of file
+}