From c14f186263b5acd58d5569d95cf7c47de70fcb22 Mon Sep 17 00:00:00 2001 From: mmabdalla <101379618+mmabdalla@users.noreply.github.com> Date: Sun, 28 Dec 2025 14:59:01 +0200 Subject: [PATCH] Initial project setup: Create directory structure and configuration files - Created manifest.yaml with Node.js runtime and routes - Set up package.json with React, TypeScript, Vite, and dependencies - Created TypeScript and Vite configuration files - Set up ESLint and Prettier - Created complete directory structure (frontend, backend, migrations) - Created initial database schema migration - Set up Express server with route handlers - Created frontend entry point files - Added version.txt with build 0.1.0.001 --- .eslintrc.json | 38 +++++++++ .gitignore | 1 - .prettierrc | 9 +++ frontend/editor/main.tsx | 22 ++++++ frontend/index.html | 13 ++++ index.html | 12 +++ manifest.yaml | 46 +++++++++++ migrations/001_initial_schema.sql | 68 +++++++++++++++++ package.json | 51 +++++++++++++ server.js | 123 ++++++++++++++++++++++++++++++ tsconfig.json | 37 +++++++++ version.txt | 17 +++++ vite.config.js | 34 +++++++++ 13 files changed, 470 insertions(+), 1 deletion(-) create mode 100644 .eslintrc.json create mode 100644 .prettierrc create mode 100644 frontend/editor/main.tsx create mode 100644 frontend/index.html create mode 100644 index.html create mode 100644 manifest.yaml create mode 100644 migrations/001_initial_schema.sql create mode 100644 package.json create mode 100644 server.js create mode 100644 tsconfig.json create mode 100644 version.txt create mode 100644 vite.config.js diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..87ff936 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,38 @@ +{ + "env": { + "browser": true, + "es2021": true, + "node": true + }, + "extends": [ + "eslint:recommended", + "plugin:react/recommended", + "plugin:react-hooks/recommended", + "plugin:@typescript-eslint/recommended", + "prettier" + ], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "module", + "ecmaFeatures": { + "jsx": true + } + }, + "plugins": [ + "react", + "react-hooks", + "@typescript-eslint" + ], + "rules": { + "react/react-in-jsx-scope": "off", + "react/prop-types": "off", + "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }] + }, + "settings": { + "react": { + "version": "detect" + } + } +} + diff --git a/.gitignore b/.gitignore index 6b77b79..0c8c102 100644 --- a/.gitignore +++ b/.gitignore @@ -48,4 +48,3 @@ temp/ # Deployment *.zip !builds/**/*.zip - diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..053c69d --- /dev/null +++ b/.prettierrc @@ -0,0 +1,9 @@ +{ + "semi": true, + "trailingComma": "es5", + "singleQuote": true, + "printWidth": 100, + "tabWidth": 2, + "useTabs": false +} + diff --git a/frontend/editor/main.tsx b/frontend/editor/main.tsx new file mode 100644 index 0000000..eb3a950 --- /dev/null +++ b/frontend/editor/main.tsx @@ -0,0 +1,22 @@ +// BP_WB Editor - Main Entry Point +// This file will be implemented in WB-002: Basic Editor UI Layout + +import React from 'react'; +import ReactDOM from 'react-dom/client'; + +function App() { + return ( +
+

BP_WB Editor

+

Editor will be implemented in WB-002

+
+ ); +} + +const root = ReactDOM.createRoot(document.getElementById('root')!); +root.render( + + + +); + diff --git a/frontend/index.html b/frontend/index.html new file mode 100644 index 0000000..950e058 --- /dev/null +++ b/frontend/index.html @@ -0,0 +1,13 @@ + + + + + + BP_WB - Website Builder + + +
+ + + + diff --git a/index.html b/index.html new file mode 100644 index 0000000..84badf1 --- /dev/null +++ b/index.html @@ -0,0 +1,12 @@ + + + + + + BP_WB - Website Builder + + +
+ + + diff --git a/manifest.yaml b/manifest.yaml new file mode 100644 index 0000000..b04bb32 --- /dev/null +++ b/manifest.yaml @@ -0,0 +1,46 @@ +name: bp_wb +version: 0.1.0 +description: BOSA Plugin Website Builder - Visual drag-and-drop page builder for BOSA apps +author: BOSA Team + +runtime: + type: nodejs + entry: server.js + +routes: + # Editor routes + - path: / + method: GET + handler: serveEditor + - path: /editor + method: GET + handler: serveEditor + + # API routes for pages + - path: /api/pages + method: GET + handler: listPages + - path: /api/pages + method: POST + handler: createPage + - path: /api/pages/:id + method: GET + handler: getPage + - path: /api/pages/:id + method: PUT + handler: updatePage + - path: /api/pages/:id + method: DELETE + handler: deletePage + + # Renderer route + - path: /preview/:id + method: GET + handler: previewPage + +events: + publish: + - page.created + - page.updated + - page.deleted + diff --git a/migrations/001_initial_schema.sql b/migrations/001_initial_schema.sql new file mode 100644 index 0000000..644983c --- /dev/null +++ b/migrations/001_initial_schema.sql @@ -0,0 +1,68 @@ +-- BP_WB Initial Database Schema +-- This migration creates all core tables for the Website Builder plugin + +-- Page configurations +CREATE TABLE IF NOT EXISTS wb_pages ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + app_name VARCHAR(255) NOT NULL, + route_path VARCHAR(500) NOT NULL, + page_config TEXT NOT NULL, -- JSON stored as TEXT (SQLite compatibility) + version INTEGER DEFAULT 1, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, + created_by INTEGER, + UNIQUE(app_name, route_path) +); + +-- Page versions (for history/rollback) +CREATE TABLE IF NOT EXISTS wb_page_versions ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + page_id INTEGER NOT NULL, + version INTEGER NOT NULL, + page_config TEXT NOT NULL, -- JSON stored as TEXT + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + created_by INTEGER, + FOREIGN KEY (page_id) REFERENCES wb_pages(id) ON DELETE CASCADE +); + +-- Templates (starting points) +CREATE TABLE IF NOT EXISTS wb_templates ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name VARCHAR(255) NOT NULL, + description TEXT, + category VARCHAR(100), + template_config TEXT NOT NULL, -- JSON stored as TEXT + preview_image VARCHAR(500), + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + created_by INTEGER +); + +-- Component registry (custom components from plugins) +CREATE TABLE IF NOT EXISTS wb_components ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + plugin_name VARCHAR(255) NOT NULL, + component_name VARCHAR(255) NOT NULL, + component_config TEXT NOT NULL, -- JSON stored as TEXT + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + UNIQUE(plugin_name, component_name) +); + +-- Asset library +CREATE TABLE IF NOT EXISTS wb_assets ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + filename VARCHAR(255) NOT NULL, + file_path VARCHAR(500) NOT NULL, + file_type VARCHAR(50), + file_size INTEGER, + uploaded_by INTEGER, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP +); + +-- Indexes for performance +CREATE INDEX IF NOT EXISTS idx_wb_pages_app_route ON wb_pages(app_name, route_path); +CREATE INDEX IF NOT EXISTS idx_wb_pages_created_by ON wb_pages(created_by); +CREATE INDEX IF NOT EXISTS idx_wb_page_versions_page_id ON wb_page_versions(page_id); +CREATE INDEX IF NOT EXISTS idx_wb_templates_category ON wb_templates(category); +CREATE INDEX IF NOT EXISTS idx_wb_components_plugin ON wb_components(plugin_name); +CREATE INDEX IF NOT EXISTS idx_wb_assets_file_type ON wb_assets(file_type); + diff --git a/package.json b/package.json new file mode 100644 index 0000000..0c0fb52 --- /dev/null +++ b/package.json @@ -0,0 +1,51 @@ +{ + "name": "bp_wb", + "version": "0.1.0", + "description": "BOSA Plugin Website Builder - Visual drag-and-drop page builder", + "main": "server.js", + "type": "module", + "scripts": { + "dev": "node --watch server.js", + "start": "node server.js", + "build": "tsc && vite build", + "build:frontend": "vite build", + "lint": "eslint . --ext .js,.jsx,.ts,.tsx", + "lint:fix": "eslint . --ext .js,.jsx,.ts,.tsx --fix", + "format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,md}\"", + "test": "jest", + "test:watch": "jest --watch" + }, + "keywords": [ + "bosa", + "plugin", + "website-builder", + "page-builder", + "visual-editor" + ], + "author": "BOSA Team", + "license": "MIT", + "dependencies": { + "bosa-sdk-node": "^1.0.0", + "express": "^4.18.2", + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "devDependencies": { + "@types/express": "^4.17.21", + "@types/node": "^20.10.0", + "@types/react": "^18.2.45", + "@types/react-dom": "^18.2.18", + "@typescript-eslint/eslint-plugin": "^6.15.0", + "@typescript-eslint/parser": "^6.15.0", + "@vitejs/plugin-react": "^4.2.1", + "eslint": "^8.56.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-react": "^7.33.2", + "eslint-plugin-react-hooks": "^4.6.0", + "jest": "^29.7.0", + "prettier": "^3.1.1", + "typescript": "^5.3.3", + "vite": "^5.0.8" + } +} + diff --git a/server.js b/server.js new file mode 100644 index 0000000..c40314c --- /dev/null +++ b/server.js @@ -0,0 +1,123 @@ +// BP_WB - BOSA Plugin Website Builder +// Main entry point for Node.js runtime + +import { BOSA } from 'bosa-sdk-node'; +import express from 'express'; +import path from 'path'; +import { fileURLToPath } from 'url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +// Initialize BOSA SDK +const bosa = new BOSA({ + kernelURL: process.env.BOSA_KERNEL_URL || 'http://localhost:3000', + pluginName: process.env.PLUGIN_NAME || 'bp_wb', + pluginToken: process.env.BOSA_KERNEL_TOKEN, +}); + +// Initialize Express app +const app = express(); +const port = process.env.PLUGIN_PORT || 3001; + +// Middleware +app.use(express.json()); +app.use(express.static(path.join(__dirname, 'dist'))); + +// Health check endpoint +app.get('/health', (req, res) => { + res.json({ status: 'ok', plugin: 'bp_wb' }); +}); + +// Route handlers (to be implemented in backend/api/) +app.get('/', serveEditor); +app.get('/editor', serveEditor); +app.get('/api/pages', listPages); +app.post('/api/pages', createPage); +app.get('/api/pages/:id', getPage); +app.put('/api/pages/:id', updatePage); +app.delete('/api/pages/:id', deletePage); +app.get('/preview/:id', previewPage); + +// Placeholder route handlers (to be implemented in Phase 1) +async function serveEditor(req, res) { + res.sendFile(path.join(__dirname, 'dist', 'index.html')); +} + +async function listPages(req, res) { + try { + // TODO: Implement in WB-006 + res.json({ pages: [] }); + } catch (error) { + bosa.log.error(`ListPages failed | Error: ${error.message}`); + res.status(500).json({ error: 'Internal server error' }); + } +} + +async function createPage(req, res) { + try { + // TODO: Implement in WB-006 + res.status(501).json({ error: 'Not implemented yet' }); + } catch (error) { + bosa.log.error(`CreatePage failed | Error: ${error.message}`); + res.status(500).json({ error: 'Internal server error' }); + } +} + +async function getPage(req, res) { + try { + // TODO: Implement in WB-006 + res.status(501).json({ error: 'Not implemented yet' }); + } catch (error) { + bosa.log.error(`GetPage failed | Page ID: ${req.params.id} | Error: ${error.message}`); + res.status(500).json({ error: 'Internal server error' }); + } +} + +async function updatePage(req, res) { + try { + // TODO: Implement in WB-006 + res.status(501).json({ error: 'Not implemented yet' }); + } catch (error) { + bosa.log.error(`UpdatePage failed | Page ID: ${req.params.id} | Error: ${error.message}`); + res.status(500).json({ error: 'Internal server error' }); + } +} + +async function deletePage(req, res) { + try { + // TODO: Implement in WB-006 + res.status(501).json({ error: 'Not implemented yet' }); + } catch (error) { + bosa.log.error(`DeletePage failed | Page ID: ${req.params.id} | Error: ${error.message}`); + res.status(500).json({ error: 'Internal server error' }); + } +} + +async function previewPage(req, res) { + try { + // TODO: Implement in WB-007 + res.status(501).json({ error: 'Not implemented yet' }); + } catch (error) { + bosa.log.error(`PreviewPage failed | Page ID: ${req.params.id} | Error: ${error.message}`); + res.status(500).json({ error: 'Internal server error' }); + } +} + +// Initialize BOSA and start server +async function init() { + try { + await bosa.init(); + bosa.log.info('BP_WB plugin initialized successfully'); + + app.listen(port, () => { + bosa.log.info(`BP_WB plugin server running on port ${port}`); + }); + } catch (error) { + console.error('Failed to initialize BP_WB plugin:', error); + process.exit(1); + } +} + +init(); + diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..fc3cbc6 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,37 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + + /* Path aliases */ + "baseUrl": ".", + "paths": { + "@/*": ["./frontend/*"], + "@editor/*": ["./frontend/editor/*"], + "@renderer/*": ["./frontend/renderer/*"], + "@components/*": ["./frontend/components/*"], + "@backend/*": ["./backend/*"], + "@api/*": ["./backend/api/*"] + } + }, + "include": ["frontend", "backend"], + "exclude": ["node_modules", "dist", "build"] +} + diff --git a/version.txt b/version.txt new file mode 100644 index 0000000..2d7108b --- /dev/null +++ b/version.txt @@ -0,0 +1,17 @@ +BP_WB Version 0.1.0.001 +Date: December 21, 2025 + +=== Latest Changes === +- [SETUP] Initial project structure and configuration + - Created manifest.yaml with Node.js runtime configuration + - Set up package.json with React, TypeScript, Vite, and build tools + - Created TypeScript configuration (tsconfig.json) + - Set up Vite build configuration + - Created ESLint and Prettier configuration files + - Created complete directory structure (frontend, backend, migrations) + - Created initial database schema migration (001_initial_schema.sql) + - Set up Express server with route handlers (server.js) + - Created frontend entry point (index.html, main.tsx) + - Created Linear issues document with all 71 features (WB-001 to WB-071) + - Initialized git repository and pushed to GitHub + diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 0000000..e51ae6f --- /dev/null +++ b/vite.config.js @@ -0,0 +1,34 @@ +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; +import path from 'path'; +import { fileURLToPath } from 'url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +export default defineConfig({ + plugins: [react()], + resolve: { + alias: { + '@': path.resolve(__dirname, './frontend'), + '@editor': path.resolve(__dirname, './frontend/editor'), + '@renderer': path.resolve(__dirname, './frontend/renderer'), + '@components': path.resolve(__dirname, './frontend/components'), + '@backend': path.resolve(__dirname, './backend'), + '@api': path.resolve(__dirname, './backend/api'), + }, + }, + build: { + outDir: 'dist', + sourcemap: true, + }, + server: { + port: 5173, + proxy: { + '/api': { + target: 'http://localhost:3001', + changeOrigin: true, + }, + }, + }, +});