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,
+ },
+ },
+ },
+});