feat(KB-504): add migration and first-run experience for multi-project support
- Add MigrationOrchestrator with filesystem scanning and auto-registration - Add FirstRunExperience with setup wizard state management - CLI integration with automatic migration hook on first run - Backward-compatible single-project mode support - \"--project\" flag support for CLI multi-project targeting - KB_SKIP_MIGRATION environment variable for recovery - Graceful fallback when central database unavailable - New fn init command to initialize kb projects - Interactive first-run setup wizard API in dashboard
This commit is contained in:
@@ -76,7 +76,7 @@ import {
|
||||
fetchTasks,
|
||||
type ProjectInfo,
|
||||
type DetectedProject,
|
||||
} from "../../app/api";
|
||||
} from "../../app/api.js";
|
||||
|
||||
function mockFetchResponse(
|
||||
ok: boolean,
|
||||
|
||||
@@ -1075,18 +1075,28 @@ export function createApiRoutes(store: TaskStore, options?: ServerOptions): Rout
|
||||
*/
|
||||
router.get("/setup-state", async (_req, res) => {
|
||||
try {
|
||||
const { FirstRunDetector } = await import("@fusion/core");
|
||||
const { CentralCore } = await import("@fusion/core");
|
||||
const { createFirstRunExperience, CentralCore } = await import("@fusion/core");
|
||||
const { createMigrationOrchestrator } = await import("@fusion/core");
|
||||
|
||||
const detector = new FirstRunDetector();
|
||||
const state = await detector.detectFirstRunState();
|
||||
const detectedProjects = await detector.detectExistingProjects(process.cwd());
|
||||
const central = new CentralCore();
|
||||
await central.init();
|
||||
|
||||
res.json({
|
||||
state,
|
||||
detectedProjects,
|
||||
hasCentralDb: detector.hasCentralDb(),
|
||||
});
|
||||
try {
|
||||
const migration = createMigrationOrchestrator(central);
|
||||
const firstRun = createFirstRunExperience(central);
|
||||
|
||||
const needsMigration = await migration.needsMigration();
|
||||
const state = await firstRun.getSetupState();
|
||||
const detectedProjects = state.detectedProjects || [];
|
||||
|
||||
res.json({
|
||||
state: needsMigration ? "needs-migration" : state.isFirstRun ? "setup-wizard" : "normal-operation",
|
||||
detectedProjects,
|
||||
hasCentralDb: true,
|
||||
});
|
||||
} finally {
|
||||
await central.close();
|
||||
}
|
||||
} catch (err: any) {
|
||||
res.status(500).json({ error: err.message });
|
||||
}
|
||||
@@ -1106,19 +1116,19 @@ export function createApiRoutes(store: TaskStore, options?: ServerOptions): Rout
|
||||
return;
|
||||
}
|
||||
|
||||
const { CentralCore, MigrationCoordinator } = await import("@fusion/core");
|
||||
const { CentralCore, createFirstRunExperience } = await import("@fusion/core");
|
||||
|
||||
const central = new CentralCore();
|
||||
await central.init();
|
||||
|
||||
try {
|
||||
const coordinator = new MigrationCoordinator(central);
|
||||
const result = await coordinator.completeSetup(projects);
|
||||
const firstRun = createFirstRunExperience(central);
|
||||
const result = await firstRun.completeSetup(projects);
|
||||
|
||||
res.json({
|
||||
success: result.success,
|
||||
registered: result.projectsRegistered,
|
||||
errors: result.errors,
|
||||
registered: result.projects.map(p => p.id),
|
||||
errors: [],
|
||||
});
|
||||
} finally {
|
||||
await central.close();
|
||||
|
||||
Reference in New Issue
Block a user