feat(docs): add production readiness runbook and enhanced TODO scan
Add comprehensive production readiness checklist and improve TODO scanning. Changes: - Production Readiness Runbook (docs/progress/PRODUCTION-READINESS-RUNBOOK.md) - Complete mechanical execution checklist for TypeScript, Android, iOS - File anchors and search commands for verification - Cross-platform behavior consistency checks - Logging and observability requirements - Release packaging sanity checks - Troubleshooting guide - Quick reference for expected file anchors - Enhanced TODO Scan Script (scripts/todo-scan.js) - Split reporting: core code vs docs/test-apps - Core code count (should be 0) - Docs/test-apps count (expected to be large) - Enhanced JSON output with summary statistics - Improved console output with visual indicators - Clear separation of production code vs planning artifacts Implementation Details: - Core code detection: ios/Plugin/, android/src/main/, src/, packages/, lib/ - Docs/test-apps detection: docs/, test-apps/, tests/, *Tests/ - JSON output includes summary with coreCount, docsTestCount, otherCount - Markdown output includes summary section with split counts - Console output shows visual indicators (✅/⚠️) for quick assessment Benefits: - Clear visibility into production code TODOs (should be 0) - Acceptable TODOs in docs/test-apps are clearly separated - Production readiness checklist provides deterministic verification - File anchors enable quick verification of implementation completeness Verification: - TODO scan runs successfully - JSON output includes summary statistics - Markdown output includes split summary - Console output shows visual indicators
This commit is contained in:
+59
-3
@@ -94,6 +94,29 @@ function bucketForPath(rel) {
|
||||
return "Other";
|
||||
}
|
||||
|
||||
function isCoreCode(rel) {
|
||||
// Core code directories (production code)
|
||||
return (
|
||||
rel.startsWith("ios/Plugin/") ||
|
||||
rel.startsWith("android/src/main/") ||
|
||||
rel.startsWith("src/") ||
|
||||
rel.startsWith("packages/") ||
|
||||
rel.startsWith("lib/") ||
|
||||
(rel.startsWith("scripts/") && !rel.includes("test"))
|
||||
);
|
||||
}
|
||||
|
||||
function isDocsOrTestApp(rel) {
|
||||
// Documentation and test harness directories
|
||||
return (
|
||||
rel.startsWith("docs/") ||
|
||||
rel.startsWith("test-apps/") ||
|
||||
rel.startsWith("ios/Tests/") ||
|
||||
rel.startsWith("android/src/test/") ||
|
||||
rel.startsWith("tests/")
|
||||
);
|
||||
}
|
||||
|
||||
function main() {
|
||||
const results = [];
|
||||
for (const d of TARGET_DIRS) {
|
||||
@@ -113,7 +136,27 @@ function main() {
|
||||
a.line - b.line
|
||||
);
|
||||
|
||||
fs.writeFileSync(path.join(ROOT, "docs/todo-scan.json"), JSON.stringify(results, null, 2), "utf8");
|
||||
// Split core vs docs/test-apps
|
||||
const coreResults = results.filter(r => isCoreCode(r.file));
|
||||
const docsTestResults = results.filter(r => isDocsOrTestApp(r.file));
|
||||
const otherResults = results.filter(r => !isCoreCode(r.file) && !isDocsOrTestApp(r.file));
|
||||
|
||||
// Enhanced JSON output with split counts
|
||||
const jsonOutput = {
|
||||
summary: {
|
||||
total: results.length,
|
||||
coreCount: coreResults.length,
|
||||
docsTestCount: docsTestResults.length,
|
||||
otherCount: otherResults.length,
|
||||
generatedAt: new Date().toISOString()
|
||||
},
|
||||
core: coreResults,
|
||||
docsTest: docsTestResults,
|
||||
other: otherResults,
|
||||
all: results
|
||||
};
|
||||
|
||||
fs.writeFileSync(path.join(ROOT, "docs/todo-scan.json"), JSON.stringify(jsonOutput, null, 2), "utf8");
|
||||
|
||||
// markdown
|
||||
const byBucket = new Map();
|
||||
@@ -125,7 +168,13 @@ function main() {
|
||||
let md = "";
|
||||
md += `# TODO Classification (auto-generated)\n\n`;
|
||||
md += `Generated by \`scripts/todo-scan.js\`\n\n`;
|
||||
md += `Total markers: **${results.length}**\n\n`;
|
||||
md += `## Summary\n\n`;
|
||||
md += `- **Total markers:** ${results.length}\n`;
|
||||
md += `- **Core code (production):** ${coreResults.length} ⚠️\n`;
|
||||
md += `- **Docs/test-apps:** ${docsTestResults.length} ✅ (expected)\n`;
|
||||
md += `- **Other:** ${otherResults.length}\n\n`;
|
||||
md += `> **Note:** Core code TODOs should be near zero. Docs/test-app TODOs are expected and acceptable.\n\n`;
|
||||
md += `---\n\n`;
|
||||
|
||||
for (const [bucket, items] of byBucket.entries()) {
|
||||
md += `## ${bucket} (${items.length})\n\n`;
|
||||
@@ -146,7 +195,14 @@ function main() {
|
||||
|
||||
fs.writeFileSync(path.join(ROOT, "docs/TODO-CLASSIFICATION.md"), md, "utf8");
|
||||
|
||||
console.log(`todo-scan complete: ${results.length} markers`);
|
||||
// Console output with split summary
|
||||
console.log(`\n📊 TODO Scan Complete`);
|
||||
console.log(`━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`);
|
||||
console.log(`Total markers: ${results.length}`);
|
||||
console.log(`Core code: ${coreResults.length} ${coreResults.length === 0 ? '✅' : '⚠️ (should be 0)'}`);
|
||||
console.log(`Docs/test-apps: ${docsTestResults.length} ✅ (expected)`);
|
||||
console.log(`Other: ${otherResults.length}`);
|
||||
console.log(`━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`);
|
||||
}
|
||||
|
||||
main();
|
||||
|
||||
Reference in New Issue
Block a user