🎉 init: 小龙的工作空间
This commit is contained in:
@@ -0,0 +1,195 @@
|
||||
/**
|
||||
* PR-37 Delivery Planning — Entry Point
|
||||
*
|
||||
* Parts F, G, H, I:
|
||||
* - F: Sprint Planner
|
||||
* - G: Release Planner
|
||||
* - H: Batch Planner
|
||||
* - I: Capacity Planner
|
||||
*
|
||||
* Consumes SF-02 Requirement Package output and generates delivery
|
||||
* planning artifacts. Compatible with PR-36 Factory Registry.
|
||||
*
|
||||
* @module pr-37-delivery-planning
|
||||
* @since PR-37
|
||||
*/
|
||||
|
||||
import { generateSprintPlan, defaultSprintConfig } from "./sprint-planner.mjs";
|
||||
import { generateReleasePlan } from "./release-planner.mjs";
|
||||
import { generateBatchPlan } from "./batch-planner.mjs";
|
||||
import { generateCapacityPlan, defaultCapacityConfig } from "./capacity-planner.mjs";
|
||||
|
||||
import { alignRoadmapWithPlans } from "./roadmap-aligner.mjs";
|
||||
|
||||
// ═══════════════════════════════════════════════════════
|
||||
// PR-37 Artifact Constants
|
||||
// ═══════════════════════════════════════════════════════
|
||||
|
||||
export const PR37_ARTIFACTS = Object.freeze({
|
||||
SPRINT_PLAN: "sprint-plan",
|
||||
RELEASE_PLAN: "release-plan",
|
||||
BATCH_PLAN: "batch-plan",
|
||||
CAPACITY_PLAN: "capacity-plan",
|
||||
ALIGNMENT_REPORT: "alignment-report",
|
||||
});
|
||||
|
||||
// ═══════════════════════════════════════════════════════
|
||||
// Factory Integration
|
||||
// ═══════════════════════════════════════════════════════
|
||||
|
||||
/**
|
||||
* Create a delivery planning factory that consumes SF-02 upstream artifacts
|
||||
* and produces all 4 delivery plans.
|
||||
*
|
||||
* The factory accepts a PR-36 FactoryInput object (or a simplified upstream
|
||||
* artifacts object) and returns all plans bundled as a FactoryOutput.
|
||||
*
|
||||
* @param {object} upstreamArtifacts — SF-02 output containing:
|
||||
* - epics: object[]
|
||||
* - features: object[]
|
||||
* - userStories: object[]
|
||||
* - dependencies / graph: dependency graph
|
||||
* - priorities: priority matrix entries
|
||||
* - mvpScope: MVP scope definition
|
||||
* @param {object} [config] — Optional config overrides
|
||||
* @param {object} [config.sprint] — Sprint planner config
|
||||
* @param {object} [config.capacity] — Capacity planner config
|
||||
* @returns {object} FactoryOutput with all delivery plans
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* const factory = createDeliveryPlanningFactory();
|
||||
* const output = factory(sf02Output, {
|
||||
* sprint: { teamVelocity: 20, maxStoryPointsPerSprint: 25 },
|
||||
* capacity: { teamSize: 5, availabilityFactor: 0.8 },
|
||||
* });
|
||||
* // output.sprintPlan, output.releasePlan, output.batchPlan, output.capacityPlan
|
||||
* ```
|
||||
*/
|
||||
export function createDeliveryPlanningFactory(upstreamArtifacts, config = {}) {
|
||||
if (!upstreamArtifacts) {
|
||||
return {
|
||||
factoryId: "PR-37",
|
||||
status: "failed",
|
||||
error: "No upstream artifacts provided. Provide SF-02 output.",
|
||||
};
|
||||
}
|
||||
|
||||
const warnings = [];
|
||||
|
||||
// ── 1. Extract SF-02 artifacts ──
|
||||
const stories = upstreamArtifacts.userStories || upstreamArtifacts.stories || [];
|
||||
const epics = upstreamArtifacts.epics || [];
|
||||
const features = upstreamArtifacts.features || [];
|
||||
|
||||
// Support both { graph: { nodes, edges } } and flat { nodes, edges }
|
||||
const dependencies = upstreamArtifacts.dependencies
|
||||
|| upstreamArtifacts.graph
|
||||
|| { nodes: [], edges: [] };
|
||||
|
||||
const priorities = upstreamArtifacts.priorities || [];
|
||||
const mvpScope = upstreamArtifacts.mvpScope || null;
|
||||
|
||||
// ── 2. Validate data ──
|
||||
if (stories.length === 0) {
|
||||
warnings.push("No user stories found in upstream artifacts");
|
||||
}
|
||||
|
||||
// ── 3. Generate Sprint Plan (Part F) ──
|
||||
const sprintConfig = defaultSprintConfig(config.sprint || {});
|
||||
const sprintPlan = generateSprintPlan({
|
||||
stories,
|
||||
dependencies,
|
||||
priorities,
|
||||
config: sprintConfig,
|
||||
});
|
||||
|
||||
if (sprintPlan.warnings && sprintPlan.warnings.length > 0) {
|
||||
warnings.push(...sprintPlan.warnings.map(w => `[Sprint] ${w}`));
|
||||
}
|
||||
|
||||
// ── 4. Generate Release Plan (Part G) ──
|
||||
const releasePlan = generateReleasePlan({
|
||||
mvpScope,
|
||||
priorities,
|
||||
dependencies,
|
||||
stories,
|
||||
epics,
|
||||
features,
|
||||
});
|
||||
|
||||
if (releasePlan.warnings && releasePlan.warnings.length > 0) {
|
||||
warnings.push(...releasePlan.warnings.map(w => `[Release] ${w}`));
|
||||
}
|
||||
|
||||
// ── 5. Generate Batch Plan (Part H) ──
|
||||
const batchPlan = generateBatchPlan({
|
||||
stories,
|
||||
dependencies,
|
||||
priorities,
|
||||
sprints: sprintPlan,
|
||||
releases: releasePlan,
|
||||
});
|
||||
|
||||
if (batchPlan.warnings && batchPlan.warnings.length > 0) {
|
||||
warnings.push(...batchPlan.warnings.map(w => `[Batch] ${w}`));
|
||||
}
|
||||
|
||||
// ── 6. Generate Capacity Plan (Part I) ──
|
||||
const capacityConfig = defaultCapacityConfig(config.capacity || {});
|
||||
const capacityPlan = generateCapacityPlan({
|
||||
sprints: sprintPlan,
|
||||
releases: releasePlan,
|
||||
config: capacityConfig,
|
||||
});
|
||||
|
||||
if (capacityPlan.warnings && capacityPlan.warnings.length > 0) {
|
||||
warnings.push(...capacityPlan.warnings.map(w => `[Capacity] ${w}`));
|
||||
}
|
||||
|
||||
// ── 7. Align with Roadmap (Part J) ──
|
||||
const roadmap = upstreamArtifacts.roadmap || mvpScope?.phases;
|
||||
const alignmentReport = roadmap
|
||||
? alignRoadmapWithPlans({
|
||||
roadmap: { phases: Array.isArray(roadmap) ? roadmap : (roadmap.phases || []) },
|
||||
sprintPlan,
|
||||
releasePlan,
|
||||
batchPlan,
|
||||
mvpScope,
|
||||
})
|
||||
: null;
|
||||
|
||||
// ── 8. Assemble output ──
|
||||
const output = {
|
||||
factoryId: "PR-37",
|
||||
status: warnings.length > 0 && stories.length === 0 ? "blocked" : "passed",
|
||||
sprintPlan,
|
||||
releasePlan,
|
||||
batchPlan,
|
||||
capacityPlan,
|
||||
alignmentReport,
|
||||
warnings: warnings.length > 0 ? warnings : undefined,
|
||||
metadata: {
|
||||
factoryId: "PR-37",
|
||||
upstreamArtifactId: upstreamArtifacts.id || "SF-02",
|
||||
generatedAt: new Date().toISOString(),
|
||||
totalStories: stories.length,
|
||||
totalEpics: epics.length,
|
||||
totalFeatures: features.length,
|
||||
totalSprints: sprintPlan.metrics.totalSprints,
|
||||
totalReleases: releasePlan.releases ? releasePlan.releases.length : 0,
|
||||
},
|
||||
};
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════
|
||||
// Barrel Re-exports
|
||||
// ═══════════════════════════════════════════════════════
|
||||
|
||||
export { generateSprintPlan, defaultSprintConfig } from "./sprint-planner.mjs";
|
||||
export { generateReleasePlan } from "./release-planner.mjs";
|
||||
export { generateBatchPlan } from "./batch-planner.mjs";
|
||||
export { generateCapacityPlan, defaultCapacityConfig } from "./capacity-planner.mjs";
|
||||
export { alignRoadmapWithPlans } from "./roadmap-aligner.mjs";
|
||||
Reference in New Issue
Block a user