-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(backend): frontend code generator #85
Changes from 79 commits
9d91437
5bbfdd9
bfda89c
da9ef45
ec2bb50
5bdd162
2c9ae0f
60a3098
a923bc5
fd2c639
66137f1
b7b809d
02ff300
3395501
8b6646e
2d610e9
cd4fe5f
09aeeea
c791fcc
74cfffd
98ea9c8
125576c
a6d713a
f708b9e
a22836f
e17a5ec
be118f0
e614d06
fabdf32
580f27d
e5cc2ed
74d4610
33f22d5
01bfedf
faabb88
d4a1d1e
eebffc6
7eecfe4
6f92d88
1cb1dda
5cda996
45895c8
4b1bab6
f42e486
2452140
a8a402b
9e63a90
9669af3
a4886ab
be2aa22
940119c
707d779
ba87f34
027765d
b5fb1a8
12f285a
7d3c56f
77fa4f3
67903f0
7a21de5
a8cc115
4cfb5b6
d2a57b7
6f3ede5
4a80f03
c475dc6
57737e6
55deed8
19af1ec
7bdfba9
b97e552
d632f10
407230d
dd0881c
c245b8c
67e2f83
e043c83
4fa4e0f
7345d6f
38bdf47
7aaf98e
46e13e2
4449b09
1fa9f47
1a0a2d7
42d9525
ce478e4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,19 @@ import { isIntegrationTest } from 'src/common/utils'; | |
import { BuildSequence } from '../types'; | ||
import { executeBuildSequence } from './utils'; | ||
import { Logger } from '@nestjs/common'; | ||
import { ProjectInitHandler } from '../handlers/project-init'; | ||
import { PRDHandler } from '../handlers/product-manager/product-requirements-document/prd'; | ||
import { UXSMDHandler } from '../handlers/ux/sitemap-document'; | ||
import { UXSMSHandler } from '../handlers/ux/sitemap-structure'; | ||
import { DBRequirementHandler } from '../handlers/database/requirements-document'; | ||
import { FileStructureHandler } from '../handlers/file-manager/file-structure'; | ||
import { UXSMSPageByPageHandler } from '../handlers/ux/sitemap-structure/sms-page'; | ||
import { DBSchemaHandler } from '../handlers/database/schemas/schemas'; | ||
import { FileFAHandler } from '../handlers/file-manager/file-arch'; | ||
import { BackendRequirementHandler } from '../handlers/backend/requirements-document'; | ||
import { BackendCodeHandler } from '../handlers/backend/code-generate'; | ||
import { BackendFileReviewHandler } from '../handlers/backend/file-review/file-review'; | ||
|
||
(isIntegrationTest ? describe : describe.skip)('Build Sequence Test', () => { | ||
it('should execute build sequence successfully', async () => { | ||
const sequence: BuildSequence = { | ||
|
@@ -10,140 +23,102 @@ import { Logger } from '@nestjs/common'; | |
name: 'Spotify-like Music Web', | ||
description: 'Users can play music', | ||
databaseType: 'SQLite', | ||
steps: [ | ||
nodes: [ | ||
{ | ||
handler: ProjectInitHandler, | ||
name: 'Project Folders Setup', | ||
}, | ||
{ | ||
handler: PRDHandler, | ||
name: 'Project Requirements Document Node', | ||
}, | ||
{ | ||
handler: UXSMDHandler, | ||
name: 'UX Sitemap Document Node', | ||
}, | ||
{ | ||
handler: UXSMSHandler, | ||
name: 'UX Sitemap Structure Node', | ||
// requires: ['op:UX:SMD'], | ||
}, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Codebase verification Uncomment dependencies and review two discrepancies The commented dependencies are necessary for build sequence validation and should be uncommented. However, please review:
🔗 Analysis chainUncomment required dependencies. The dependencies are commented out but appear to be necessary for proper build sequence validation. Consider uncommenting them to ensure correct dependency checking. Run this script to verify the dependencies: Also applies to: 47-48, 52-53, 57-59, 65-66, 70-71, 75-76, 80-81, 84-91 🏁 Scripts executedThe following scripts were executed for the analysis: Script: #!/bin/bash
# Check if the commented dependencies match the actual handler requirements
# Search for BuildNodeRequire decorators to find actual dependencies
rg -A 2 "@BuildNodeRequire" backend/src/build-system/handlers/
# Compare with commented dependencies in test file
cat backend/src/build-system/__tests__/fullstack-gen.spec.ts
Length of output: 8953 |
||
{ | ||
handler: DBRequirementHandler, | ||
name: 'Database Requirements Node', | ||
// requires: ['op:UX:DATAMAP:DOC'], | ||
}, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove duplicate handler nodes. There are multiple instances of the same handlers with identical configurations:
This duplication could lead to redundant operations and potential state conflicts. Remove the duplicate nodes to ensure each handler appears only once in the sequence. Also applies to: 63-65, 49-56, 68-73, 57-61, 76-78 |
||
{ | ||
handler: FileStructureHandler, | ||
name: 'File Structure Generation', | ||
// requires: ['op:UX:SMD', 'op:UX:DATAMAP:DOC'], | ||
options: { | ||
projectPart: 'frontend', | ||
}, | ||
}, | ||
{ | ||
handler: UXSMSPageByPageHandler, | ||
name: 'Level 2 UX Sitemap Structure Node details', | ||
// requires: ['op:UX:SMS'], | ||
}, | ||
{ | ||
id: 'step-0', | ||
name: 'Project Initialization', | ||
parallel: false, | ||
nodes: [ | ||
{ | ||
id: 'op:PROJECT::STATE:SETUP', | ||
name: 'Project Folders Setup', | ||
}, | ||
], | ||
handler: DBRequirementHandler, | ||
name: 'Database Requirements Node', | ||
// requires: ['op:UX:DATAMAP:DOC'], | ||
}, | ||
{ | ||
id: 'step-1', | ||
name: 'Initial Analysis', | ||
parallel: false, | ||
nodes: [ | ||
{ | ||
id: 'op:PRD', | ||
name: 'Project Requirements Document Node', | ||
}, | ||
], | ||
handler: FileStructureHandler, | ||
name: 'File Structure Generation', | ||
// requires: ['op:UX:SMD', 'op:UX:DATAMAP:DOC'], | ||
options: { | ||
projectPart: 'frontend', | ||
}, | ||
}, | ||
{ | ||
id: 'step-2', | ||
name: 'UX Base Document Generation', | ||
parallel: false, | ||
nodes: [ | ||
{ | ||
id: 'op:UX:SMD', | ||
name: 'UX Sitemap Document Node', | ||
requires: ['op:PRD'], | ||
}, | ||
], | ||
handler: UXSMSPageByPageHandler, | ||
name: 'Level 2 UX Sitemap Structure Node details', | ||
// requires: ['op:UX:SMS'], | ||
}, | ||
{ | ||
id: 'step-3', | ||
name: 'Parallel UX Processing', | ||
parallel: true, | ||
nodes: [ | ||
{ | ||
id: 'op:UX:SMS', | ||
name: 'UX Sitemap Structure Node', | ||
requires: ['op:UX:SMD'], | ||
}, | ||
{ | ||
id: 'op:UX:DATAMAP:DOC', | ||
name: 'UX DataMap Document Node', | ||
requires: ['op:UX:SMD'], | ||
}, | ||
], | ||
handler: DBSchemaHandler, | ||
name: 'Database Schemas Node', | ||
// requires: ['op:DATABASE_REQ'], | ||
}, | ||
{ | ||
id: 'step-4', | ||
name: 'Parallel Project Structure', | ||
parallel: true, | ||
nodes: [ | ||
{ | ||
id: 'op:DATABASE_REQ', | ||
name: 'Database Requirements Node', | ||
requires: ['op:UX:DATAMAP:DOC'], | ||
}, | ||
{ | ||
id: 'op:FILE:STRUCT', | ||
name: 'File Structure Generation', | ||
requires: ['op:UX:SMD', 'op:UX:DATAMAP:DOC'], | ||
options: { | ||
projectPart: 'frontend', | ||
}, | ||
}, | ||
{ | ||
id: 'op:UX:SMS:LEVEL2', | ||
name: 'Level 2 UX Sitemap Structure Node details', | ||
requires: ['op:UX:SMS'], | ||
}, | ||
], | ||
handler: FileFAHandler, | ||
name: 'File Arch', | ||
// requires: ['op:FILE:STRUCT', 'op:UX:DATAMAP:DOC'], | ||
}, | ||
{ | ||
id: 'step-5', | ||
name: 'Parallel Implementation', | ||
parallel: true, | ||
nodes: [ | ||
{ | ||
id: 'op:DATABASE:SCHEMAS', | ||
name: 'Database Schemas Node', | ||
requires: ['op:DATABASE_REQ'], | ||
}, | ||
{ | ||
id: 'op:FILE:ARCH', | ||
name: 'File Arch', | ||
requires: ['op:FILE:STRUCT', 'op:UX:DATAMAP:DOC'], | ||
}, | ||
{ | ||
id: 'op:BACKEND:REQ', | ||
name: 'Backend Requirements Node', | ||
requires: ['op:DATABASE_REQ', 'op:UX:DATAMAP:DOC', 'op:UX:SMD'], | ||
}, | ||
], | ||
handler: BackendRequirementHandler, | ||
name: 'Backend Requirements Node', | ||
// requires: ['op:DATABASE_REQ', 'op:UX:DATAMAP:DOC', 'op:UX:SMD'], | ||
}, | ||
{ | ||
id: 'step-6', | ||
name: 'Final Code Generation', | ||
parallel: false, | ||
nodes: [ | ||
{ | ||
id: 'op:BACKEND:CODE', | ||
name: 'Backend Code Generator Node', | ||
requires: [ | ||
'op:DATABASE:SCHEMAS', | ||
'op:UX:DATAMAP:DOC', | ||
'op:BACKEND:REQ', | ||
], | ||
}, | ||
], | ||
handler: BackendCodeHandler, | ||
name: 'Backend Code Generator Node', | ||
// requires: [ | ||
// 'op:DATABASE:SCHEMAS', | ||
// 'op:UX:DATAMAP:DOC', | ||
// 'op:BACKEND:REQ', | ||
// ], | ||
}, | ||
// TODO: code reviewer | ||
// { | ||
// handler:FrontendCodeHandler, | ||
// id: 'op:FRONTEND:CODE', | ||
// name: 'Frontend Code Generator Node', | ||
// }, | ||
{ | ||
id: 'step-7', | ||
name: 'Backend Code Review', | ||
parallel: false, | ||
nodes: [ | ||
{ | ||
id: 'op:BACKEND:FILE:REVIEW', | ||
name: 'Backend File Review Node', | ||
requires: ['op:BACKEND:CODE', 'op:BACKEND:REQ'], | ||
}, | ||
], | ||
handler: BackendFileReviewHandler, | ||
name: 'Backend File Review Node', | ||
// requires: ['op:BACKEND:CODE', 'op:BACKEND:REQ'], | ||
}, | ||
], | ||
}; | ||
|
||
const result = await executeBuildSequence('fullstack-code-gen', sequence); | ||
|
||
// Assertion: ensure the build sequence runs successfully | ||
expect(result.success).toBe(true); | ||
expect(result.metrics).toBeDefined(); | ||
Logger.log(`Logs saved to: ${result.logFolderPath}`); | ||
}, 300000); | ||
}, 300000); // Set timeout to 5 minutes | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
import { VirtualDirectory } from '../../virtual-dir'; | ||
import { readFileSync } from 'fs'; | ||
import { resolve } from 'path'; | ||
import * as path from 'path'; | ||
import { UXSMSHandler } from 'src/build-system/handlers/ux/sitemap-structure'; | ||
import { UXDMDHandler } from 'src/build-system/handlers/ux/datamap'; | ||
import { BackendRequirementHandler } from 'src/build-system/handlers/backend/requirements-document'; | ||
import { FileFAHandler } from 'src/build-system/handlers/file-manager/file-arch'; | ||
import { BuilderContext, GlobalDataKeys } from 'src/build-system/context'; | ||
import { v4 as uuidv4 } from 'uuid'; // UUID generator for unique identifiers | ||
import { | ||
BuildExecutionState, | ||
BuildHandlerConstructor, | ||
BuildSequence, | ||
ExtractHandlerReturnType, | ||
} from 'src/build-system/types'; | ||
import { buildProjectPath, copyProjectTemplate } from '../../utils/files'; | ||
|
||
export class MockBuilderContext extends BuilderContext { | ||
private mockNodeData: Map<BuildHandlerConstructor, any> = new Map(); | ||
private mockGlobalContext: Map<GlobalDataKeys | string, any> = new Map(); | ||
virtualDirectory: VirtualDirectory; | ||
|
||
constructor(sequence: BuildSequence, id: string) { | ||
super(sequence, id); // Call the parent constructor to initialize inherited properties | ||
this.virtualDirectory = new VirtualDirectory(); // Initialize the mock virtual directory | ||
const uuid = | ||
new Date().toISOString().slice(0, 10).replace(/:/g, '-') + '-' + uuidv4(); | ||
|
||
// Read mock data from files | ||
const uxSitemapStructure = this.readMockFile( | ||
path.join(__dirname, 'test_files', 'UX_Sitemap_Structure_Node.md'), | ||
); | ||
const uxDataMapDocument = this.readMockFile( | ||
path.join(__dirname, 'test_files', 'UX_DataMap_Document_Node.md'), | ||
); | ||
const backendRequirements = this.readMockFile( | ||
path.join(__dirname, 'test_files', 'Backend_Requirements_Node.md'), | ||
); | ||
const fileStructure = this.readMockFile( | ||
path.join(__dirname, 'test_files', 'File_Structure_Generation.md'), | ||
); | ||
const fileArchitecture = this.readMockFile( | ||
path.join(__dirname, 'test_files', 'File_Arch.md'), | ||
); | ||
|
||
this.mockNodeData.set(UXSMSHandler, uxSitemapStructure); | ||
this.mockNodeData.set(UXDMDHandler, uxDataMapDocument); | ||
this.mockNodeData.set(BackendRequirementHandler, backendRequirements); | ||
this.mockNodeData.set(FileFAHandler, fileArchitecture); | ||
this.buildVirtualDirectory(fileStructure); | ||
|
||
copyProjectTemplate( | ||
path.join(__dirname, '..', '..', '..', '..', 'template', 'react-ts'), | ||
uuid, | ||
'frontend', | ||
); | ||
|
||
// Set up mock data for globalContext | ||
this.mockGlobalContext.set( | ||
'frontendPath', | ||
buildProjectPath(uuid, 'frontend'), | ||
); | ||
} | ||
|
||
setGlobalContext<Key extends GlobalDataKeys | string>( | ||
key: Key, | ||
value: any, | ||
): void { | ||
this.mockGlobalContext.set(key, value); | ||
} | ||
|
||
setNodeData<T extends BuildHandlerConstructor>( | ||
handlerClass: T, | ||
data: ExtractHandlerReturnType<T>, | ||
): void { | ||
this.mockNodeData.set(handlerClass, data); | ||
} | ||
|
||
getExecutionState(): BuildExecutionState { | ||
return {} as BuildExecutionState; // Return a mock execution state | ||
} | ||
|
||
buildVirtualDirectory(jsonContent: string): boolean { | ||
return this.virtualDirectory.parseJsonStructure(jsonContent); | ||
} | ||
|
||
execute(): Promise<void> { | ||
return Promise.resolve(); // Mock a resolved promise for execution | ||
} | ||
|
||
getNodeData(handler: any): any { | ||
return this.mockNodeData.get(handler) || null; | ||
} | ||
|
||
getGlobalContext(key: string): any { | ||
return this.mockGlobalContext.get(key) || null; | ||
} | ||
|
||
// Helper method to read files | ||
private readMockFile(filePath: string): string { | ||
try { | ||
const absolutePath = resolve(filePath); // Resolve the file path | ||
return readFileSync(absolutePath, 'utf-8'); // Read the file content | ||
} catch (err) { | ||
console.error(`Error reading file at ${filePath}:`, err); | ||
return ''; // Return an empty string if file read fails | ||
} | ||
} | ||
|
||
// Add other methods as necessary for mocking | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Uncomment dependencies to enforce build sequence validation.
The dependencies are commented out but appear to be necessary for proper build sequence validation.
Uncomment all the dependencies to ensure proper dependency checking:
Also applies to: 52-52, 57-58, 65-65, 70-70, 75-75, 80-80