Skip to content

Latest commit

 

History

History
390 lines (316 loc) · 19.3 KB

File metadata and controls

390 lines (316 loc) · 19.3 KB

DevStackBox - Architecture Overview

Version: v0.1.7-dev
Last Updated: May 2026
Single Source of Truth: This file describes how all parts of DevStackBox connect. Update this file whenever you change the architecture.


Tech Stack at a Glance

Layer Technology Purpose
Frontend UI React 18 + Vite All visible UI
Styling Tailwind CSS + shadcn/ui All styles - NO custom CSS
Animation Framer Motion All transitions/animations
i18n i18next EN and HI translations
Backend Tauri 2 (Rust) Process management, file I/O, native OS ops
IPC Bridge Tauri Commands + Events Frontend <-> Backend communication
Service binaries httpd.exe, mysqld.exe (MySQL), php.exe The actual servers (always bundled in installer)

Directory Map (What Lives Where)

DevStackBox/
|
|-- src/                        # FRONTEND (React + Vite)
|   |-- App.tsx                 # Root component. Routing, layout, top-level state
|   |-- main.tsx                # React entry point (do not touch)
|   |-- globals.css             # Tailwind base imports only (do not add custom CSS here)
|   |
|   |-- pages/
|   |   |-- dashboard.tsx             # Dashboard page - service overview
|   |   |-- services.tsx             # Services page - start/stop controls + logs
|   |   |-- about.tsx                # About page with system info
|   |   |-- security.tsx             # Security analyzer page
|   |   |-- ssl.tsx                  # HTTPS / SSL management
|   |   |-- vhosts.tsx               # Virtual host management
|   |   |-- backup.tsx               # Full backup / restore
|   |   |-- mysql-users.tsx          # MySQL user management
|   |   |-- databases-list.tsx       # Databases overview
|   |   |-- settings-general.tsx     # App settings
|   |   |-- services/                # Per-service sub-pages (Apache/MySQL/PHP each have layout, index, logs, config)
|   |   |-- databases/               # Database sub-pages (index, users, backups)
|   |   |-- settings/                # Settings sub-pages (index, backup)
|   |   |-- logs/                    # Log sub-pages per service (apache, mysql, php)
|   |   |-- terminal/                # Embedded terminal sub-pages
|   |   |-- index.ts                 # Re-exports pages used by App.tsx
|   |
|   |-- components/
|   |   |-- ui/                      # shadcn/ui base components (DO NOT MODIFY)
|   |   |-- services/                # Service-specific components
|   |   |   |-- service-manager.tsx          # Polls status, handles start/stop for all services
|   |   |   |-- service-card.tsx             # UI card for a single service
|   |   |   |-- service-actions.tsx          # Buttons: Start, Stop, Open Browser
|   |   |   |-- status-badge.tsx             # Running/Stopped badge
|   |   |   |-- log-viewer.tsx               # Log display with search, auto-scroll, color coding
|   |   |   |-- php-version-selector.tsx     # PHP version picker with download progress
|   |   |   |-- php-extensions-dialog.tsx    # PHP extension enable/disable
|   |   |   |-- service-overflow-menu.tsx    # Three-dot overflow actions per service card
|   |   |   |-- index.ts                     # Re-exports all service components
|   |   |
|   |   |-- sidebar.tsx             # Main navigation sidebar (collapsible)
|   |   |-- breadcrumb.tsx          # Topbar breadcrumb matching current route
|   |   |-- command-palette.tsx     # Ctrl+P command palette
|   |   |-- auto-updater.tsx        # Auto-update UI (checks GitHub Releases)
|   |   |-- language-switcher.tsx   # EN/HI switcher
|   |   |-- theme-toggle.tsx        # Dark/Light toggle
|   |   |-- theme-provider.tsx      # Theme context wrapper
|   |   |-- onboarding-dialog.tsx   # First-launch welcome dialog
|   |   |-- bug-report-dialog.tsx   # Pre-filled GitHub Issue reporter
|   |   |-- error-log-preview.tsx   # Dashboard log tail widget
|   |   |-- terminal-panel.tsx      # xterm.js terminal panel
|   |   |-- system-tray/            # System tray helper components
|   |
|   |-- hooks/
|   |   |-- use-toast.ts            # Toast notification hook
|   |   |-- useSystemTray.ts        # System tray state hook
|   |
|   |-- lib/
|   |   |-- tauri.ts                # isTauri(), safeInvoke(), mock data helpers
|   |   |-- i18n.ts                 # i18next setup
|   |   |-- utils.ts                # cn() class merge helper (shadcn)
|   |   |-- version.ts              # APP_VERSION constant
|   |   |-- commands.ts             # TAURI_COMMANDS map (all command name strings)
|   |   |-- routes.ts               # ROUTES map (all frontend route paths)
|   |   |-- notify.ts               # Desktop notification helpers
|   |
|   |-- types/
|       |-- services.ts             # Shared TypeScript types (ServiceStatus, ServiceName, etc.)
|
|-- src-tauri/                  # BACKEND (Rust + Tauri)
|   |-- src/
|   |   |-- main.rs                  # Binary entry point (do not touch)
|   |   |-- lib.rs                   # Module declarations + run() only (~150 lines)
|   |   |-- types.rs                 # Shared Rust types (ServiceInfo, PHPVersionInfo, etc.)
|   |   |-- commands/
|   |   |   |-- apache.rs            # start_apache, stop_apache, get_apache_status, config gen
|   |   |   |-- mysql.rs             # start_mysql, stop_mysql, db/user management, backup
|   |   |   |-- php.rs               # get_php_versions, switch_php_version, download, patch_php_ini
|   |   |   |-- config.rs            # read_config, update_config, backup_config, restore
|   |   |   |-- logs.rs              # get_service_logs, log_crash_event
|   |   |   |-- system.rs            # check_binaries, get_system_info, start/stop_all, autostart
|   |   |   |-- tray.rs              # show_main_window, hide_to_tray, set_tray_tooltip, quit_app
|   |   |   |-- terminal.rs          # spawn_terminal, send_terminal_input, kill_terminal_session
|   |   |   |-- security.rs          # analyze_security
|   |   |   |-- ssl.rs               # get_ssl_status, generate_ssl_cert, enable_ssl, disable_ssl
|   |   |   |-- vhosts.rs            # list_vhosts, add_vhost, remove_vhost, toggle_vhost, hosts file
|   |   |   |-- fullbackup.rs        # create_full_backup, list/restore/delete_full_backup
|   |   |-- utils/
|   |   |   |-- paths.rs             # get_installation_path, user_config_dir, user_logs_dir, etc.
|   |   |   |-- process.rs           # create_hidden_command, find_our_processes, kill_pid
|   |
|   |-- tauri.conf.json         # App config: window size, bundle targets, resources
|   |-- Cargo.toml              # Rust dependencies
|   |-- build.rs                # Build script
|   |-- capabilities/           # Tauri permission definitions
|   |-- icons/                  # App icons
|   |-- wix/                    # MSI installer customization
|
|-- config/                     # Dev-only template configs (tracked in git)
|   |-- my.cnf                  # MySQL config template
|   |-- httpd.conf              # Apache config template
|   |-- phpmyadmin.conf         # phpMyAdmin config template
|
|-- locales/
|   |-- en.json                 # English translations
|   |-- hi.json                 # Hindi translations
|
|-- mysql/                      # MySQL binaries (bundled with app)
|-- apache/                     # Apache binaries (bundled with app)
|-- php/8.1/, 8.2/, 8.3/, 8.4/ # PHP binaries per version (8.3 bundled; others downloadable)
|-- php/current                 # Windows junction pointing to active PHP version (runtime only)
|-- phpmyadmin/                 # phpMyAdmin 5.2.1 PHP files (bundled)
|-- www/                        # Default web root seed files (copied to user data on first run)
|-- scripts/                    # Developer utility scripts (PowerShell / shell)
|-- docs/                       # THIS FOLDER - All project documentation
|
|-- (User Data - NOT in the repo)
    %LOCALAPPDATA%\DevStackBox\
      config/                   # Runtime configs generated by the app
      config-backups/           # Automatic config backups
      logs/                     # Apache, MySQL, PHP runtime logs
      mysql-data/               # MySQL data directory
      www/                      # User's PHP projects / web root
      backups/                  # Full backup zip files
      sessions/                 # PHP session files

UI Layout

DevStackBox uses a fixed two-panel desktop app layout. Do not redesign this.

┌───────────────────┬──────────────────────────────────────┐
│  Top Bar          │  Top Bar (continued)                 │
│  DevStackBox      │  [Version] [Updates] [Lang] [Theme]  │
├───────────────────┼──────────────────────────────────────┤
│                   │                                      │
│  Sidebar          │  Main Content Area                   │
│  (220-260px)      │                                      │
│                   │  Current Page:                       │
│  Dashboard        │  Service cards / logs / settings     │
│  Services         │  Config editor / PHP versions        │
│  Projects         │                                      │
│  Logs             │  Clean, spacious, card-based.        │
│  Settings         │                                      │
│  About            │  NO crowded tables.                  │
│                   │                                      │
└───────────────────┴──────────────────────────────────────┘

Top Bar currently contains:

  • App title
  • Version badge
  • Auto updater entry point
  • Language switcher
  • Theme toggle (dark/light)

Current shortcut-driven controls:

  • Command palette opens with Ctrl+P
  • Tray controls exist in dedicated components and hooks, but are not mounted in the current top bar

Sidebar currently contains: Dashboard / Services (Apache / MySQL / PHP sub-navigation) / Databases / Logs / Terminal / Settings / About

All sidebar items are active. Each service has its own sub-pages: Overview, Logs, Config, and service-specific extras (PHP: Extensions, Versions; Apache: Virtual Hosts, SSL).

Do not overload the sidebar with sub-items or collapsible trees.

Dashboard page structure:

Dashboard
├── Quick Actions (Start All / Stop All / Restart Apache)
├── Service Status Cards (Apache / PHP / MySQL)
├── Current PHP Version
├── Ports Overview
├── Recent Logs (last 10 lines)
└── Project Shortcuts (www/ folder links)

Service card structure (each card):

[ Apache ]       Running ●
Port: 80   PID: 1234
[ Start ]  [ Stop ]  [ Logs ]  [ Config ]

Progressive Disclosure Rule:
Default view shows: start / stop / running status only.
Expanded view shows: logs, config, ports, PID, arguments.
This keeps the UI approachable for beginners, powerful for advanced users.

Design Philosophy:
DevStackBox should feel like a native desktop utility (like Docker Desktop or GitHub Desktop), NOT like a web admin panel, analytics dashboard, or cPanel.

Reuse and Consistency Rules

These rules are architectural, not optional style preferences.

  1. Reuse existing shared components before creating new ones. Start with ServiceCard, ServiceActions, StatusBadge, LogViewer, ConfigEditor, and existing shadcn/ui primitives.
  2. Keep business logic in one owner. Polling stays in service-manager.tsx; command strings stay in src/lib/commands.ts; shared types stay in src/types/services.ts.
  3. Prefer composition over cloning. If two screens need the same card, toolbar, or dialog shell, add props or children to the shared component instead of copying markup.
  4. Keep visual language consistent. The same action should use the same component, label pattern, spacing scale, and variant wherever it appears.
  5. If a new reusable pattern is introduced, document it in docs/COMPONENTS.md immediately so future work can extend it instead of recreating it.

App/Data Directory Separation

This is critical for reliable auto-updates. Violating this causes update-related data loss.

Two separate roots - NEVER mix them

App Root (replaceable during updates):

C:\Program Files\DevStackBox\     (or C:\DevStackBox\ for portable)
  DevStackBox.exe
  apache/        <- Apache binaries
  php/           <- PHP binaries
  phpmyadmin/    <- phpMyAdmin PHP files
  resources/

User Data Root (NEVER touched during updates):

C:\dsb-data\                      (or %APPDATA%\DevStackBox\ for installed mode)
  www/           <- User's PHP projects
  mysql-data/    <- MySQL database files
  logs/          <- All service logs
  config/        <- Runtime configs (php.ini, httpd.conf, my.cnf)
  config-backups/
  certs/
  backups/

Rule: MySQL database files (mysql/data/) must NEVER live inside the app folder. A database inside the app folder will be destroyed or corrupted on update.

Current state (v0.1.6): This separation does not exist yet. Everything is in one directory. Fixing this is Phase 1.8 (see ROADMAP.md).

Config versioning: All config files should contain a version field:

{ "configVersion": 1 }

This allows migration scripts to transform old config formats when the app updates.


How Frontend Talks to Rust (IPC Pattern)

Every call from React to Rust goes through src/lib/tauri.ts:safeInvoke().

React Component
  --> safeInvoke("command_name", { param: value })   [src/lib/tauri.ts]
      --> Tauri invoke()                             [Tauri IPC bridge]
          --> #[tauri::command] fn command_name()   [src-tauri/src/lib.rs]
              --> Result<T, String>                 [returned to frontend]

Rules:

  • Always use safeInvoke (not raw invoke) so it works in browser dev mode too
  • Shared command names live in src/lib/commands.ts:TAURI_COMMANDS; expand that file instead of creating new scattered constants
  • Current gap: some older components still hardcode command strings and should be migrated into TAURI_COMMANDS
  • All commands are in src-tauri/src/lib.rs - do NOT use service_manager.rs
  • Commands return Result<T, String> - errors are caught in the component

How Rust Talks Back to Frontend (Events)

For real-time data (log streaming, service status changes), Rust uses Tauri events:

Rust (lib.rs)
  --> app_handle.emit("event-name", payload)
      --> Frontend listener
          --> listen("event-name", callback)         [Tauri event API]

This pattern is used for progress and app-shell events such as PHP download progress, full backup/restore progress, terminal output, and tray actions. Service status and log refresh still use frontend polling for now.


Service Path Resolution

This is a critical and error-prone area. Path helpers live in src-tauri/src/utils/paths.rs. get_installation_path() determines where MySQL, Apache, PHP, and phpMyAdmin binaries live. It checks in this order:

  1. current_dir if it contains apache/bin/httpd.exe
  2. exe_parent (installed app location)
  3. exe_grandparent
  4. Production fallbacks: C:\dsb, C:\Program Files\DevStackBox, C:\DevStackBox
  5. current_dir as final fallback

In development: The app runs from src-tauri/, so paths resolve to c:\xampp\htdocs\DevStackBox\
In production (installed): The app resolves relative to the installer output directory

Runtime data is separate from binaries and lives under %LOCALAPPDATA%\DevStackBox\ unless DEVSTACKBOX_DATA_DIR is set.

Rule: Never hardcode paths in the frontend. Always let the Rust backend resolve paths.


State Management

There is no global state manager (no Redux, Zustand, etc.). State is managed:

  • Local component state: useState in each page/component
  • Service status polling: ServiceManager component polls every 5 seconds via safeInvoke
  • Theme: React context via ThemeProvider
  • Rust-side state: Runtime process truth comes from OS process checks, not a service status cache. Terminal sessions and other command-specific state stay inside their owning backend modules.

Rule: Do not add a global state manager unless shared state between 3+ unrelated components becomes unmanageable.


Build Pipeline

pnpm tauri:build
  --> npm run build (tsc && vite build)  --> dist/
  --> cargo build --release              --> src-tauri/target/release/
  --> tauri bundle                       --> MSI + NSIS installers

Resources bundled into the installer are declared in tauri.conf.json:

"resources": ["../mysql/**/*", "../php/**/*", "../phpmyadmin/**/*", "../www/**/*", "../config/**/*"]

Adding a New Feature: Checklist

  1. Rust backend command (if needed): Add #[tauri::command] async fn my_command() to the owning module in src-tauri/src/commands/, then register it in the invoke_handler in src-tauri/src/lib.rs.
  2. Frontend constant: Add the command name to TAURI_COMMANDS in src/lib/commands.ts.
  3. TypeScript types: Add any new types to src/types/services.ts.
  4. React component: Create component in appropriate folder. Style with Tailwind + shadcn/ui only.
  5. Translation keys: Add EN and HI strings to locales/en.json and locales/hi.json.
  6. Update this doc: Update ARCHITECTURE.md and FEATURE_STATUS.md.

Key Design Decisions

Decision Reason
Commands split by domain Keeps lib.rs small and places service logic in src-tauri/src/commands/
safeInvoke wrapper Allows frontend to run in browser during development
No custom CSS Tailwind + shadcn/ui covers all needs; custom CSS causes theming bugs
Polling for service status Simple and reliable for current service cards; events are used for progress flows
User data root for runtime configs Keeps source and runtime config separate under %LOCALAPPDATA%\DevStackBox\
config-backups/ auto-backup Auto-backup before every config save prevents data loss
Two-panel layout (sidebar + main) Standard desktop utility pattern; do not redesign
Progressive disclosure in service UI Beginners see start/stop; experts expand for logs, config, PID
App/data directory separation Required for safe auto-updates; see docs/UPDATES_AND_MIGRATIONS.md
Installed mode only (no portable in v1) Portable mode cannot support auto-updates reliably; adds architectural conflict