Initial curated projectbrain source from 8a7b1e0651dbdab97d744cbd2e653ab3970ac6c5
This commit is contained in:
commit
5aa3e8d685
700 files changed
+132801
No files matched your search
@@ -0,0 +1,83 @@
|
||||
#!/usr/bin/env node
|
||||
import { readFileSync, existsSync } from 'node:fs';
|
||||
|
||||
const checks = [];
|
||||
const fail = (message) => checks.push({ ok: false, message });
|
||||
const pass = (message) => checks.push({ ok: true, message });
|
||||
const read = (path) => readFileSync(path, 'utf8');
|
||||
|
||||
const boundaryPath = 'src/shared/components/RuntimeErrorBoundary.tsx';
|
||||
if (existsSync(boundaryPath)) {
|
||||
const boundary = read(boundaryPath);
|
||||
boundary.includes('componentDidCatch') ? pass('RuntimeErrorBoundary catches render crashes') : fail('RuntimeErrorBoundary must implement componentDidCatch');
|
||||
boundary.includes('Frontend runtime guard') ? pass('RuntimeErrorBoundary renders user-facing fallback') : fail('RuntimeErrorBoundary needs visible fallback copy');
|
||||
boundary.includes('Copy diagnostics') && boundary.includes('navigator.clipboard.writeText')
|
||||
? pass('RuntimeErrorBoundary can copy diagnostics')
|
||||
: fail('RuntimeErrorBoundary must support one-click diagnostic copy');
|
||||
} else {
|
||||
fail('RuntimeErrorBoundary component is missing');
|
||||
}
|
||||
|
||||
const app = read('src/App.tsx');
|
||||
app.includes('<RuntimeErrorBoundary>') ? pass('App wraps routes in RuntimeErrorBoundary') : fail('App must wrap routes in RuntimeErrorBoundary');
|
||||
const routes = read('src/app/routes.tsx');
|
||||
|
||||
const projectBrainClient = read('src/shared/api/projectBrainClient.ts');
|
||||
projectBrainClient.includes('const useRealClient = false')
|
||||
? pass('Synchronous projectBrainClient cannot call async realClient')
|
||||
: fail('projectBrainClient must not route sync selectors to async realClient');
|
||||
projectBrainClient.includes('Real HTTP calls are async')
|
||||
? pass('Sync/real client boundary is documented')
|
||||
: fail('Sync/real client boundary must be documented');
|
||||
|
||||
const projectContext = read('src/shared/contexts/ProjectContext.tsx');
|
||||
projectContext.includes('toProjectArray(getProjects())')
|
||||
? pass('ProjectContext normalizes project arrays')
|
||||
: fail('ProjectContext must normalize getProjects result before .map');
|
||||
projectContext.includes('toFeatureGroups(project)')
|
||||
? pass('ProjectContext guards featureGroups access')
|
||||
: fail('ProjectContext must guard featureGroups access');
|
||||
projectContext.includes('realClient.projects.listProjects()') && projectContext.includes('reloadProjectData')
|
||||
? pass('ProjectContext can hydrate projects from the real backend')
|
||||
: fail('ProjectContext must expose a real backend project hydration path');
|
||||
projectContext.includes('realClient.projects.createProject') && projectContext.includes('Project could not be saved to the backend')
|
||||
? pass('ProjectContext can create projects through the real backend')
|
||||
: fail('ProjectContext must create projects through the real backend in real mode');
|
||||
projectContext.includes('realClient.workspace.updateActiveContextPack') && projectContext.includes('Active context pack could not be saved to the backend')
|
||||
? pass('ProjectContext can persist active context pack changes')
|
||||
: fail('ProjectContext must persist active context pack changes in real mode');
|
||||
projectContext.includes('realClient.workspace.getWorkspaceState(projectId)') && projectContext.includes('realClient.projectDNA.getProjectDNA(projectId)')
|
||||
? pass('ProjectContext hydrates workspace and DNA with project data')
|
||||
: fail('ProjectContext must hydrate workspace and DNA in real project mode');
|
||||
projectContext.includes('projectDataMode: "local" | "real"') && projectContext.includes('projectDataLoading') && projectContext.includes('projectDataError')
|
||||
? pass('ProjectContext exposes data mode, loading and error state')
|
||||
: fail('ProjectContext must expose project data mode, loading and error state');
|
||||
routes.includes('ProjectRouteSync') && routes.includes('routeProjectExists') && routes.includes('setActiveProjectId(routeProjectId)')
|
||||
? pass('Project routes follow known project route changes')
|
||||
: fail('Project route sync must follow known project route changes without activating unknown slugs');
|
||||
|
||||
const projectsPage = read('src/features/projects/pages/Projects.tsx');
|
||||
projectsPage.includes('Array.isArray(project.featureGroups)')
|
||||
? pass('Projects page guards featureGroups before stats')
|
||||
: fail('Projects page must guard featureGroups before stats');
|
||||
projectsPage.includes('project.workspaceState?.focusAreas?.length')
|
||||
? pass('Projects page guards focusAreas length')
|
||||
: fail('Projects page must guard focusAreas length');
|
||||
projectsPage.includes('Database projects') && projectsPage.includes('Reload projects')
|
||||
? pass('Projects page exposes real data mode and reload affordance')
|
||||
: fail('Projects page must expose real data mode and reload affordance');
|
||||
|
||||
const workspacePage = read('src/features/projects/pages/Workspace.tsx');
|
||||
workspacePage.includes('Database-backed project context') && workspacePage.includes('Reload project')
|
||||
? pass('Workspace exposes real project context and reload affordance')
|
||||
: fail('Workspace must expose real project context and reload affordance');
|
||||
|
||||
const failures = checks.filter((check) => !check.ok);
|
||||
if (failures.length) {
|
||||
console.error('ProjectBrain frontend runtime readiness: FAIL');
|
||||
for (const check of checks) console.error(`${check.ok ? '✓' : '✗'} ${check.message}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log('ProjectBrain frontend runtime readiness: PASS');
|
||||
for (const check of checks) console.log(`✓ ${check.message}`);
|
||||
Reference in new issue
Block a user