# Lovable Clone - Kiến trúc Toàn diện > **Mục tiêu**: Xây dựng AI-powered code generation platform tương tự Lovable với chat interface, live preview, và agent system --- ## 📋 Tổng quan Hệ thống ### Tech Stack Core ``` Frontend: React 18 + TypeScript + Vite Styling: Tailwind CSS + shadcn/ui State Management: Zustand / Jotai Backend: Node.js + Express / Fastify Database: PostgreSQL + Prisma / Supabase AI/LLM: OpenAI GPT-4 / Anthropic Claude / Custom Model Real-time: WebSocket (Socket.io) Container: WebContainer (StackBlitz) hoặc Docker ``` --- ## 🏗️ I. AI LAYER (Lớp Trí tuệ Nhân tạo) ### 1. **Requirement Parser** (Phân tích Yêu cầu) **Chức năng:** - Parse user messages thành structured requirements - Phân loại intent: code generation, debugging, refactoring, explanation - Extract entities: components, features, technologies, design preferences **Tech Stack:** ```typescript // libraries - langchain / llamaindex: Orchestration - zod: Schema validation - natural: NLP utilities (optional) // AI Models - GPT-4-turbo / Claude 3.5 Sonnet (main) - GPT-3.5-turbo (classification) ``` **Implementation:** ```typescript interface ParsedRequirement { intent: 'generate' | 'modify' | 'debug' | 'explain'; entities: { components: string[]; features: string[]; techStack: string[]; designPreferences?: DesignTokens; }; complexity: 'simple' | 'medium' | 'complex'; dependencies: string[]; } class RequirementParser { async parse(userMessage: string, context: ConversationContext): Promise { // 1. Use LLM with structured output // 2. Extract entities // 3. Determine intent and complexity // 4. Return parsed structure } } ``` --- ### 2. **UI Section Generator** (Tạo UI Sections) **Chức năng:** - Generate semantic HTML structure - Create component hierarchy - Apply design system tokens - Ensure responsive layout **Tech Stack:** ```typescript // Core - AI Model với prompt engineering đặc biệt - Template system (handlebars/nunjucks) - AST parser (babel/typescript) ``` **Implementation:** ```typescript interface UISection { type: 'hero' | 'feature' | 'testimonial' | 'cta' | 'form' | 'gallery' | 'custom'; layout: 'grid' | 'flex' | 'stack'; components: ComponentSpec[]; designTokens: DesignTokens; responsive: ResponsiveConfig; } class UISectionGenerator { async generate(requirement: ParsedRequirement): Promise { // Use AI với specialized prompt const prompt = this.buildSectionPrompt(requirement); const sections = await this.llm.generate(prompt); return this.validateAndOptimize(sections); } private buildSectionPrompt(req: ParsedRequirement): string { // Reference: Lovable/Agent Prompt.txt lines 219-305 // Implement design system first approach } } ``` --- ### 3. **React Code Generator** (Tạo React Code) **Chức năng:** - Generate production-ready React components - Apply best practices (hooks, typescript, accessibility) - Implement design system - Generate tests (optional) **Tech Stack:** ```typescript // Code generation - AI Model (GPT-4 / Claude Sonnet) - AST manipulation (babel, recast) - Prettier (formatting) - ESLint (validation) // Template - React 18 + TypeScript - Vite hoặc Next.js - TailwindCSS + shadcn/ui ``` **Implementation:** ```typescript interface ComponentSpec { name: string; type: 'page' | 'component' | 'layout' | 'hook' | 'util'; props: PropDefinition[]; state: StateDefinition[]; imports: string[]; dependencies: string[]; } class ReactCodeGenerator { async generateComponent(spec: ComponentSpec, designSystem: DesignSystem): Promise { // 1. Generate component structure const template = this.selectTemplate(spec.type); // 2. Use AI to generate code const prompt = this.buildCodePrompt(spec, designSystem); const code = await this.llm.generate(prompt, { temperature: 0.2, // Lower for more consistent code max_tokens: 4000 }); // 3. Validate and format const formatted = await this.formatCode(code); const validated = await this.validateCode(formatted); return { code: validated, filePath: this.getFilePath(spec), imports: this.extractImports(validated) }; } private buildCodePrompt(spec: ComponentSpec, designSystem: DesignSystem): string { return ` Generate a React TypeScript component with: - Name: ${spec.name} - Type: ${spec.type} - Props: ${JSON.stringify(spec.props)} - Design System: ${JSON.stringify(designSystem)} Requirements: 1. Use semantic HTML and ARIA attributes 2. Follow design system tokens (no hardcoded colors) 3. Implement responsive design 4. Use React hooks best practices 5. Add TypeScript types for all props 6. NO emojis in code comments Design System: ${this.formatDesignSystem(designSystem)} `; } } ``` --- ### 4. **Code Fixer** (Sửa lỗi Code) **Chức năng:** - Detect and fix TypeScript errors - Fix build errors - Fix ESLint warnings - Optimize performance issues **Tech Stack:** ```typescript // Error detection - TypeScript Compiler API - ESLint programmatic API - Custom error parsers // Fixing - AI Model với error context - AST transformations ``` **Implementation:** ```typescript interface CodeError { type: 'typescript' | 'eslint' | 'build' | 'runtime'; file: string; line: number; message: string; code?: string; severity: 'error' | 'warning'; } class CodeFixer { async fixErrors(errors: CodeError[], fileTree: FileTree): Promise { const fixes: FixResult[] = []; for (const error of errors) { // 1. Read file context const fileContent = await this.readFile(error.file); // 2. Build fix prompt with error context const prompt = this.buildFixPrompt(error, fileContent); // 3. Generate fix const fix = await this.llm.generate(prompt); // 4. Apply and validate const applied = await this.applyFix(error.file, fix); fixes.push(applied); } return fixes; } async detectErrors(fileTree: FileTree): Promise { // Use TypeScript compiler API const tsErrors = await this.detectTypeScriptErrors(fileTree); const eslintErrors = await this.detectESLintErrors(fileTree); return [...tsErrors, ...eslintErrors]; } } ``` --- ### 5. **Project Memory Logic** (Bộ nhớ Dự án) **Chức năng:** - Store conversation context - Track file changes history - Remember user preferences - Maintain design system state - Cache common patterns **Tech Stack:** ```typescript // Storage - Redis (session cache) - PostgreSQL (persistent storage) - Vector DB (Pinecone/Weaviate) for semantic search // Context management - LangChain Memory modules - Custom context window management ``` **Implementation:** ```typescript interface ProjectMemory { projectId: string; conversationHistory: Message[]; fileChanges: FileChange[]; designSystem: DesignSystem; dependencies: string[]; userPreferences: UserPreferences; codePatterns: CodePattern[]; } class ProjectMemoryManager { private vectorStore: VectorStore; private cache: RedisClient; private db: PrismaClient; async remember(projectId: string, data: Partial): Promise { // 1. Store in cache for quick access await this.cache.set(`project:${projectId}`, data, 'EX', 3600); // 2. Store in database for persistence await this.db.projectMemory.upsert({ where: { projectId }, update: data, create: { projectId, ...data } }); // 3. Update vector store for semantic search if (data.conversationHistory) { await this.indexConversations(projectId, data.conversationHistory); } } async recall(projectId: string, query?: string): Promise { // Try cache first const cached = await this.cache.get(`project:${projectId}`); if (cached) return JSON.parse(cached); // Fall back to database const stored = await this.db.projectMemory.findUnique({ where: { projectId } }); return stored; } async searchSimilarCode(query: string, projectId: string): Promise { // Semantic search in vector store return await this.vectorStore.search(query, { filter: { projectId }, limit: 5 }); } } ``` --- ## 🔧 II. DEV LAYER (Lớp Phát triển) ### 1. **Next.js Project Template** **Structure:** ``` project-template/ ├── src/ │ ├── app/ # Next.js 14 App Router │ │ ├── layout.tsx │ │ ├── page.tsx │ │ └── globals.css │ ├── components/ │ │ ├── ui/ # shadcn/ui components │ │ └── custom/ # User components │ ├── lib/ │ │ ├── utils.ts │ │ └── hooks/ │ ├── styles/ │ │ └── tokens.ts # Design system tokens │ └── types/ ├── public/ ├── tailwind.config.ts ├── tsconfig.json ├── package.json └── vite.config.ts / next.config.js ``` **package.json template:** ```json { "name": "lovable-generated-app", "version": "0.1.0", "private": true, "scripts": { "dev": "next dev", "build": "next build", "start": "next start", "lint": "next lint", "type-check": "tsc --noEmit" }, "dependencies": { "react": "^18.3.0", "react-dom": "^18.3.0", "next": "^14.2.0", "@radix-ui/react-*": "latest", "class-variance-authority": "^0.7.0", "clsx": "^2.1.0", "tailwind-merge": "^2.2.0", "lucide-react": "^0.378.0", "zod": "^3.23.0", "zustand": "^4.5.0" }, "devDependencies": { "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", "typescript": "^5", "tailwindcss": "^3.4.0", "postcss": "^8", "autoprefixer": "^10.0.1", "eslint": "^8", "eslint-config-next": "14.2.0" } } ``` --- ### 2. **Code Writer Engine** **Chức năng:** - Write/update files in file system - Handle file conflicts - Batch operations - Rollback support **Implementation:** ```typescript interface WriteOperation { type: 'create' | 'update' | 'delete' | 'rename'; filePath: string; content?: string; newPath?: string; } class CodeWriterEngine { private fs: FileSystemAdapter; private history: OperationHistory; async executeOperations(operations: WriteOperation[]): Promise { const transaction = this.history.beginTransaction(); try { for (const op of operations) { switch (op.type) { case 'create': await this.createFile(op.filePath, op.content!); break; case 'update': await this.updateFile(op.filePath, op.content!); break; case 'delete': await this.deleteFile(op.filePath); break; case 'rename': await this.renameFile(op.filePath, op.newPath!); break; } transaction.record(op); } await transaction.commit(); return { success: true, operations }; } catch (error) { await transaction.rollback(); return { success: false, error }; } } async applyLineReplace( filePath: string, search: string, replace: string, startLine: number, endLine: number ): Promise { // Similar to Lovable's lov-line-replace tool const content = await this.fs.readFile(filePath); const lines = content.split('\n'); // Validate line range const searchContent = lines.slice(startLine - 1, endLine).join('\n'); if (!searchContent.includes(search)) { throw new Error('Search content not found at specified line range'); } // Replace const newContent = searchContent.replace(search, replace); lines.splice(startLine - 1, endLine - startLine + 1, ...newContent.split('\n')); await this.fs.writeFile(filePath, lines.join('\n')); } } ``` --- ### 3. **File Tree API** **Chức năng:** - Get project structure - Search files - Watch file changes - Manage dependencies **Implementation:** ```typescript interface FileNode { name: string; path: string; type: 'file' | 'directory'; children?: FileNode[]; size?: number; modified?: Date; } class FileTreeAPI { async getTree(rootPath: string, options?: TreeOptions): Promise { return await this.buildTree(rootPath, options); } async searchFiles(pattern: string, options?: SearchOptions): Promise { // Implement glob pattern matching return await this.glob(pattern, options); } async watchChanges(callback: (event: FileChangeEvent) => void): Promise { // Use chokidar or similar return this.watcher.watch('**/*', { ignored: ['node_modules/**', '.git/**'], persistent: true }).on('all', (event, path) => { callback({ event, path, timestamp: new Date() }); }); } async getDependencies(filePath: string): Promise { // Parse imports/requires const content = await this.fs.readFile(filePath); return this.parseImports(content); } } ``` --- ### 4. **Build & Preview Pipeline** **Chức năng:** - Hot Module Replacement (HMR) - Real-time compilation - Error reporting - Performance monitoring **Architecture:** ``` ┌─────────────┐ │ Editor │ │ Changes │ └──────┬──────┘ │ ▼ ┌─────────────────┐ │ Code Writer │ │ Engine │ └────────┬────────┘ │ ▼ ┌──────────────────┐ ┌────────────────┐ │ WebContainer / │──────▶│ Build Process │ │ Docker Runtime │ │ (Vite/Next) │ └────────┬─────────┘ └────────┬───────┘ │ │ │ ▼ │ ┌──────────────┐ │ │ Error Parser │ │ └──────┬───────┘ │ │ ▼ ▼ ┌──────────────────────────────────────┐ │ Live Preview (iframe) │ └──────────────────────────────────────┘ ``` **Implementation:** ```typescript class BuildPreviewPipeline { private container: WebContainerInstance; private buildProcess: ChildProcess; async initialize(projectPath: string): Promise { // Initialize WebContainer this.container = await WebContainer.boot(); // Mount file system await this.container.mount(projectPath); // Install dependencies const installProcess = await this.container.spawn('npm', ['install']); await installProcess.exit; // Start dev server this.buildProcess = await this.container.spawn('npm', ['run', 'dev']); // Listen for errors this.buildProcess.output.pipeTo(new WritableStream({ write: (data) => { this.parseOutput(data); } })); } async rebuild(): Promise { // Trigger rebuild (HMR will handle if available) const result = await this.waitForBuild(); return result; } private parseOutput(output: string): void { // Parse build errors/warnings const errors = this.extractErrors(output); if (errors.length > 0) { this.emit('build-error', errors); } } getPreviewUrl(): string { return this.container.url; } } ``` --- ## 🎨 III. UI TOOL LAYER (Lớp Giao diện) ### 1. **Chat Panel** **Features:** - Real-time messaging - Code syntax highlighting - Markdown support - File attachments - Image previews - Loading states **Tech Stack:** ```typescript // UI Components - React + TypeScript - TailwindCSS - shadcn/ui (Dialog, ScrollArea, Avatar) - react-markdown - prismjs / shiki (syntax highlighting) // Real-time - WebSocket / Server-Sent Events ``` **Component Structure:** ```typescript interface Message { id: string; role: 'user' | 'assistant' | 'system'; content: string; timestamp: Date; attachments?: Attachment[]; toolCalls?: ToolCall[]; } const ChatPanel: React.FC = () => { const [messages, setMessages] = useState([]); const [isStreaming, setIsStreaming] = useState(false); const sendMessage = async (content: string) => { const userMessage: Message = { id: nanoid(), role: 'user', content, timestamp: new Date() }; setMessages(prev => [...prev, userMessage]); // Stream response setIsStreaming(true); const stream = await api.chat.stream(content); let assistantMessage = ''; for await (const chunk of stream) { assistantMessage += chunk; setMessages(prev => [ ...prev.slice(0, -1), { id: nanoid(), role: 'assistant', content: assistantMessage, timestamp: new Date() } ]); } setIsStreaming(false); }; return (
); }; ``` --- ### 2. **Sidebar Controls** **Features:** - Add Section (hero, features, etc.) - Layout selector - Theme customization - Component library - File explorer **Implementation:** ```typescript interface SidebarTab { id: string; label: string; icon: React.ReactNode; panel: React.ComponentType; } const Sidebar: React.FC = () => { const tabs: SidebarTab[] = [ { id: 'sections', label: 'Sections', icon: , panel: SectionPanel }, { id: 'components', label: 'Components', icon: , panel: ComponentLibrary }, { id: 'theme', label: 'Theme', icon: , panel: ThemeCustomizer }, { id: 'files', label: 'Files', icon: , panel: FileExplorer } ]; return ( ); }; // Section Panel const SectionPanel: React.FC = () => { const sections = [ { id: 'hero', name: 'Hero Section', preview: HeroPreview }, { id: 'features', name: 'Features Grid', preview: FeaturesPreview }, { id: 'testimonials', name: 'Testimonials', preview: TestimonialsPreview }, { id: 'cta', name: 'Call to Action', preview: CTAPreview }, { id: 'pricing', name: 'Pricing Table', preview: PricingPreview } ]; const addSection = async (sectionId: string) => { await api.sections.add({ type: sectionId, position: 'end' }); }; return (
{sections.map(section => ( addSection(section.id)} /> ))}
); }; ``` --- ### 3. **Live Preview** **Features:** - iframe isolation - Responsive viewport controls - Device presets (mobile, tablet, desktop) - Interaction recording - Console log capture - Network request monitoring **Implementation:** ```typescript const LivePreview: React.FC = () => { const [viewport, setViewport] = useState('desktop'); const [url, setUrl] = useState(''); const iframeRef = useRef(null); const viewportSizes = { mobile: { width: 375, height: 667 }, tablet: { width: 768, height: 1024 }, desktop: { width: 1440, height: 900 } }; useEffect(() => { // Listen for build completion const unsubscribe = buildPipeline.on('build-complete', (newUrl) => { setUrl(newUrl); }); return unsubscribe; }, []); useEffect(() => { // Capture console logs from iframe if (iframeRef.current?.contentWindow) { const originalConsole = iframeRef.current.contentWindow.console; ['log', 'warn', 'error'].forEach(method => { iframeRef.current!.contentWindow!.console[method] = (...args) => { // Send to parent window.postMessage({ type: 'console', method, args }, '*'); // Call original originalConsole[method](...args); }; }); } }, [url]); return (