AI Builder — Technical Documentation

Complete reference for architecture, standards, pipelines, and conventions  ·  v1.0

1. Project Overview

AI Builder is a personal developer productivity tool that combines the Claude API with a pre-wired server environment to generate, deploy, and manage complete PHP/MySQL web applications automatically. The developer describes what they want in plain language, and the system builds the entire application — database, config, auth, interfaces, modules — directly on the server within minutes.

Core Principle Python is the brain, the manager, and the executor. Claude is the specialist who only writes code. The server is the ground everything lands on. Claude never makes structural decisions — it only receives a fully baked package and writes code.

2. Vision & Goals

GoalDescription
SpeedBuild complete systems in minutes not weeks
ConsistencyEvery project follows identical standards automatically
PortfolioGenerate 50+ complete working projects for ~$100 in tokens
Freelance edgeDeliver client systems same day, charge premium rates
Self-healingAuto-detect and fix errors before deployment
Safe editingBackup before every patch, one-click rollback always available

3. Technology Stack

Orchestrator

Python 3.x — build pipeline, file management, API calls, validation

Generated Output

PHP 8.x + Bootstrap 5 + MySQL/MariaDB

AI Engine

Claude API (Anthropic) — code generation only

Server Access

ttyd — browser-accessible terminal, live visibility

Isolation

LXD container — single container for personal use

Web Server

Apache with .htaccess mod_rewrite enabled

4. LXD Container

A single LXD container serves as the complete environment. Everything runs inside it — the web server, database, Python orchestrator, ttyd terminal, and all generated projects.

Container Contents

ComponentPurposeStatus
Ubuntu/Debian baseOS layerPre-installed
PHP 8.x + ApacheWeb runtimePre-installed
Python 3.xOrchestrator runtimePre-installed
MySQL/MariaDBDatabase enginePre-installed
ttydBrowser terminalPre-installed
Bootstrap 5 assetsFrontend frameworkPre-installed
Python orchestrator scriptsBuild automationWe build this

5. Server Layout

/var/www/
├── projects/ # all generated projects live here
│ ├── school_management/ # project folder = project name
│ ├── hospital_system/
│ ├── hotel_booking/
│ └── school_management_backup/ # latest backup — one per project

└── builder/
# the builder UI itself (you manage separately)

/builder/ # orchestrator scripts
├── modules/
│ ├── builder.py # build pipeline
│ ├── patcher.py # patch pipeline
│ ├── backup.py # backup + rollback
│ ├── validator.py # PHP lint + HTTP check
│ ├── context.py # context package builder
│ ├── deployer.py # file writer + SQL executor
│ ├── downloader.py # ZIP generator
│ └── provisioner.py # new project setup
└── orchestrator.py # main entry point

6. Subdomain System

Every new project automatically gets its own subdomain. This reuses your existing subdomain generation command, extended to be project-aware.

# When project "school_management" is created:
provision_new_project("school_management")

# Automatically triggers:
school_management.yourserver.com      # web access
terminal.school_management.yourserver.com  # ttyd terminal

Each project stores its domain info in .project_config.json inside the project folder.

7. Standard File Structure

# Color key:
# Green = always generated
# Yellow = conditional (only when needed)
# Pink = custom (developer-added)

project_folder/
├── .htaccess # always — written by Python directly
├── 404.php # always — styled to design profile
├── 403.php # always — styled to design profile
├── 500.php # always — styled to design profile
├── database.sql # if DB needed
├── config.php # if DB needed
├── index.php # always except pure admin
├── indexsections/ # if landing page sections
├── user_auth.php # if user system
├── user_interface.php # if user system
├── user_header.php # if user system
├── user_sidebar.php # if user system
├── usersections/ # if user system
├── admin_auth.php # if admin system
├── admin.php # if admin system
├── admin_header.php # if admin system
├── admin_sidebar.php # if admin system
├── adminsections/ # if admin system
├── {role}_auth.php # if intermediate role requested
├── {role}.php # if intermediate role
├── {role}_header.php # if intermediate role
├── {role}_sidebar.php # if intermediate role
├── {role}sections/ # if intermediate role
├── integrations/ # only if API requested (mpesa, sms etc)
├── ajax/ # only if integrations exist
├── assets/ # only if files uploaded
│ ├── logo.png
│ ├── favicon.ico
│ ├── images/
│ └── uploads/
└── custom_files/ # developer-added files (staff.php etc)

8. Build Rules — What Gets Generated

Project TypeFiles Generated
Landing page (no DB).htaccess, error pages, config.php, index.php, indexsections/
Landing page (with DB)Above + database.sql
User system onlyError pages, database.sql, config.php, index.php, user_auth, user_interface, user_header, user_sidebar, usersections/
Admin system onlyError pages, database.sql, config.php, index.php, admin_auth, admin.php, admin_header, admin_sidebar, adminsections/
Full systemAll of the above combined
With intermediate roleFull system + {role}_auth, {role}.php, {role}_header, {role}_sidebar, {role}sections/
IntegrationsOnly when explicitly requested by developer
Assets folderOnly when files are uploaded
Build Manifest First Python always generates and displays the complete build manifest before Claude writes a single line. Developer reviews and confirms before build begins.

9. Design Profile

Every project stores a .design_profile.json in its root folder. This is injected into every Claude request so all generated files are consistently styled.

{
  "theme": {
    "primary_color": "#1a73e8",
    "secondary_color": "#f4f4f4",
    "accent_color": "#ff5722"
  },
  "typography": {
    "font_family": "Poppins",
    "base_font_size": "15px",
    "heading_size": "24px"
  },
  "layout": {
    "sidebar_style": "dark",
    "navbar_style": "light",
    "card_style": "rounded"
  }
}

10. Coding Standards

StandardRule
CSS rule formatAlways single line per rule — .class{property:value;property:value}
Section CSSInherit from shell (admin.php / dashboard.php). Section-specific CSS allowed only for unique UI elements not covered by shell
Output bufferingob_start() at top, ob_end_flush() at bottom — always
APP_ACCESS guardEvery section file, header file, sidebar file starts with: <?php defined('APP_ACCESS') or die('Direct access not allowed'); ?>
MobileAlways considered — bottom nav, safe area insets, hamburger sidebar
Flash messagesAlways via set_message() + display_message() — never inline
IntegrationsLoaded conditionally in shell by $current_section — never globally
Input sanitizationsanitize_input() on all user input always
Output escapinge() / htmlspecialchars() on all output always

11. Config Pattern

All projects use the Database singleton class pattern. One connection per request, shared cleanly across all 3 shell files.

class Database {
    private static $instance = null;
    private $connection;

    private function __construct() {
        $dsn = "mysql:host=DB_HOST;dbname=DB_NAME;charset=utf8mb4";
        $this->connection = new PDO($dsn, DB_USER, DB_PASS, [
            PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            PDO::ATTR_EMULATE_PREPARES   => false
        ]);
    }

    public static function getInstance(): Database {
        if (self::$instance === null) {
            self::$instance = new Database();
        }
        return self::$instance;
    }

    public function getConnection(): PDO {
        return $this->connection;
    }
}

// Usage everywhere:
$db = Database::getInstance()->getConnection();

Standard Config Helper Functions — Always Present

FunctionPurpose
start_secure_session()Secure session initialization
redirect($url)Header redirect + exit
sanitize_input($input)Clean user input
e($value)XSS-safe output escaping
set_message($msg, $type)Set flash message
display_message()Render and clear flash message
log_activity($id, $action, $target, $notes)Audit trail logging
get_setting($key)Read from system_settings table (cached)
timeAgo($datetime)Human-readable time diff

12. Auth Pattern

Every role uses completely separate session variables. Admin and user can be logged in simultaneously without conflict. Each shell checks only its own session.

// user_auth.php — sets:
$_SESSION['user_logged_in'] = true;
$_SESSION['user_id']         = $user['id'];
$_SESSION['user_role']       = 'user';

// admin_auth.php — sets:
$_SESSION['admin_logged_in'] = true;
$_SESSION['admin_id']        = $admin['id'];
$_SESSION['admin_role']      = 'admin';

// receptionist_auth.php — sets:
$_SESSION['receptionist_logged_in'] = true;
$_SESSION['receptionist_id']        = $user['id'];
$_SESSION['receptionist_role']      = 'receptionist';
Rule Every new intermediate role Claude generates follows this exact same separate session pattern. Adding a role never risks breaking existing roles.

13. The 3-File Shell Pattern

Every primary interface splits into exactly 3 files. This allows quick customization of any part without touching the others.

admin.php

Shell + logic. Defines APP_ACCESS. Loads integrations conditionally. Includes header + sidebar. Dynamically loads adminsections/{section}.php

admin_header.php

Topbar only. Owns its CSS. Breadcrumb, user avatar, hamburger toggle, JS for mobile menu.

admin_sidebar.php

Navigation only. Owns its CSS. Dropdown nav, active states, mobile overlay, JS for dropdowns.

InterfaceShellHeaderSidebarSections Folder
Adminadmin.phpadmin_header.phpadmin_sidebar.phpadminsections/
Useruser_interface.phpuser_header.phpuser_sidebar.phpusersections/
Custom Role{role}.php{role}_header.php{role}_sidebar.php{role}sections/

14. Database Standards

Hard Rules — Never Violated No DELIMITER changes. No TRIGGERS. No STORED PROCEDURES. No EVENTS. No VIEWS. Every database.sql must import cleanly with a single command: mysql -u root -p db_name < database.sql
RuleStandard
Namingsnake_case always — tables and columns
TimestampsEvery table has created_at and updated_at
Charsetutf8mb4 always
EngineInnoDB always
Primary keysINT UNSIGNED AUTO_INCREMENT always
Foreign keysWith CASCADE rules always
Default dataPlain INSERT statements only
First filedatabase.sql always first in build order
MigrationSingle command import — no manual steps ever

15. Ajax Standard

Every ajax file follows an identical response structure. The frontend always knows exactly what to expect.

<?php
defined('APP_ACCESS') or die('Direct access not allowed');
header('Content-Type: application/json');

function ajax_response(bool $success, string $message, array $data = []): void {
    echo json_encode([
        'success' => $success,
        'message' => $message,
        'data'    => $data
    ]);
    exit;
}

// Success:
ajax_response(true, 'Payment initiated', ['ref' => $ref]);

// Error:
ajax_response(false, 'Invalid amount');

16. Error Handling

Every section file wraps all logic in try/catch. Development shows real errors, production shows safe messages.

try {
    // all database and logic operations
} catch (PDOException $e) {
    if (APP_ENV === 'development') {
        set_message($e->getMessage(), 'danger');
    } else {
        set_message('Database error. Please try again.', 'danger');
    }
} catch (Exception $e) {
    set_message($e->getMessage(), 'danger');
}

17. Security Standards

Security FeatureImplementation
CSRF protectionToken generated in config, validated on every POST
Login lockoutMAX_LOGIN_ATTEMPTS (5), LOCKOUT_DURATION (15 min)
Session fixationsession_regenerate_id(true) on every login
Password hashingPASSWORD_BCRYPT, cost 12
Direct file accessAPP_ACCESS guard on every section, header, sidebar
XSS preventione() on all output
SQL injectionPDO prepared statements always
Session securityhttponly, samesite strict, secure (production)
Directory listingOptions -Indexes in .htaccess always

18. Python Orchestrator Architecture

The orchestrator is the central brain. It handles all decision-making so Claude receives only a fully baked package and does nothing but write code.

# orchestrator.py — main entry point
def handle_request(project_name, request_type, user_message):

    if request_type == 'build':
        from modules.builder import build_project
        return build_project(project_name, user_message)

    elif request_type == 'patch':
        from modules.patcher import patch_project
        return patch_project(project_name, user_message)

    elif request_type == 'rollback':
        from modules.backup import rollback
        return rollback(project_name)

    elif request_type == 'download':
        from modules.downloader import download_project
        return download_project(project_name)

19. Context Builder

The context builder assembles the complete package Claude receives. Claude never sees a raw request — it always receives fully baked context.

def build_context(project_name, current_file, existing_files, next_file, patch_history=None):

    context = {
        # Layer 1 — Infrastructure (never changes)
        "server_path":    f"/var/www/projects/{project_name}",
        "database_name":  project_name,
        "stack":          "PHP 8.x, Bootstrap 5, MySQL/MariaDB",
        "conventions":    load_conventions(),    # your full standards

        # Layer 2 — Project context
        "project_name":   project_name,
        "design_profile": load_design_profile(project_name),
        "existing_files": read_existing_files(project_name, existing_files),

        # Layer 3 — Current task
        "current_file":   current_file,
        "next_file":      next_file,
        "instruction":    f"Build ONLY {current_file}. Return complete file. No explanation.",

        # Layer 4 — Patch history (only during patching)
        "patch_history":  patch_history if patch_history else []
    }

    return context

20. Build Pipeline

1.Developer types request + project name
2.Python reads request, determines project type
3.Python generates build manifest — shown to developer for confirmation
4.Python provisions project — folder, subdomain, ttyd
5.For each file in manifest — Python bakes full context package
6.Claude API receives package — returns file content only
7.Python writes file to server
8.Python runs php -l validation
PASS→ mark complete, move to next file
FAIL→ send error back to Claude for fix (max 3 attempts)
9.After all files — run curl -I HTTP check
200 OK→ build complete, system live
Error→ flag for manual review

Build File Order — Always Followed

OrderFileReason
1database.sqlFoundation — everything depends on this
2config.phpConnection — built second always
3.htaccessWritten by Python directly — no token cost
4404.php, 403.php, 500.phpError pages — always present
5index.phpEntry point
6indexsections/Landing page dependencies
7user_auth.phpUser foundation
8user_interface.php, user_header.php, user_sidebar.phpUser shell
9usersections/User features
10admin_auth.phpAdmin foundation
11admin.php, admin_header.php, admin_sidebar.phpAdmin shell
12adminsections/Admin features
13{role} filesIntermediate roles
14integrations/External connections
15ajax/Testing layer
16Custom filesDeveloper additions

21. Patch Pipeline

1.Developer selects project + describes patch
2.Python identifies affected files
3.Python creates backup BEFORE touching anything
4.Python reads current content of affected files
5.Python reads patch history for those files
6.Python bakes full patch package — context + current content + history + instruction
7.Claude returns patched file — only what changed, nothing else touched
8.Python writes patched file + validates with php -l
PASS→ update version number, log to patch_history table
FAIL→ auto-fix loop (max 3 attempts), then rollback if all fail

22. Validation & Auto-Fix

Every file is validated immediately after writing. Errors are automatically sent back to Claude for fixing before moving to the next file.

def validate_php_file(file_path):
    result = subprocess.run(['php', '-l', file_path], capture_output=True, text=True)
    if 'No syntax errors detected' in result.stdout:
        return {'valid': True}
    return {'valid': False, 'error': result.stdout + result.stderr}

def write_and_validate(file_path, content, context, attempt=1):
    MAX_ATTEMPTS = 3
    write_file(file_path, content)
    result = validate_php_file(file_path)

    if result['valid']:
        return True

    if attempt >= MAX_ATTEMPTS:
        notify_developer(f"Could not auto-fix {file_path}. Manual review needed.")
        return False

    # Send error back to Claude for fix
    fixed_content = send_fix_request(file_path, content, result['error'], context)
    return write_and_validate(file_path, fixed_content, context, attempt + 1)

def validate_http_response(subdomain):
    result = subprocess.run(
        ['curl', '-I', '-s', f'https://{subdomain}'],
        capture_output=True, text=True
    )
    status = result.stdout.split('\n')[0].split(' ')[1]
    return {'valid': status.startswith(('2', '3')), 'status': status}

23. Backup & Rollback

Golden Rule Backup is created BEFORE every patch. No exceptions. Old backup is deleted first, fresh backup from live is created, then and only then Claude proceeds.
def backup_project(project_name):
    live   = f"/var/www/projects/{project_name}"
    backup = f"/var/www/projects/{project_name}_backup"

    # Delete previous backup
    if os.path.exists(backup):
        shutil.rmtree(backup)

    # Create fresh backup from live
    shutil.copytree(live, backup)
    return "backup_complete"

def rollback(project_name):
    live   = f"/var/www/projects/{project_name}"
    backup = f"/var/www/projects/{project_name}_backup"

    shutil.rmtree(live)                   # wipe broken version
    shutil.copytree(backup, live)          # restore backup
    log("Rollback complete")

Server always maintains exactly two copies — live + one latest backup. Nothing more, no disk bloat.

24. Token Management

The system builds file-by-file so token limits are never a crisis — they are a natural pause in a pipeline that always knows where it is.

# .build_state.json — tracked per project
{
  "project_id":   "hospital_system",
  "status":       "in_progress",       // "complete" | "paused" | "error"
  "completed":    ["database.sql", "config.php", "index.php"],
  "pending":      ["user_auth.php", "user_interface.php", "admin.php"],
  "current_file": "user_auth.php",
  "last_updated": "2026-01-04 10:23:00"
}

When tokens run out — Python saves exact state, notifies developer, waits. When developer clicks Continue, Python reads build state and resumes exactly where it stopped. Nothing repeated, nothing lost.

25. Claude API Integration

Claude receives a fully baked JSON package every request. It has zero decisions to make — it only writes code.

26. System Prompt Structure

You are a PHP developer working on a production server.

SERVER PATH:    /var/www/projects/{project_name}/
DATABASE:       {project_name} on localhost
STACK:          PHP 8.x, Bootstrap 5, MySQL/MariaDB
WEB SERVER:     Apache with mod_rewrite

CODING STANDARDS:
- CSS: always single line per rule
- Every section file starts with: defined('APP_ACCESS') or die(...)
- Database class: Database::getInstance()->getConnection()
- Auth: separate session variables per role
- CSRF: validate on every POST
- Output buffering: ob_start() top, ob_end_flush() bottom
- Error handling: try/catch always, set_message() for user feedback
- Ajax: always return ajax_response(success, message, data)
- Mobile: always consider responsive design

DESIGN PROFILE: {design_profile_json}

EXISTING FILES ALREADY BUILT:
{existing_file_contents}

YOUR TASK:
Build ONLY this file: {current_file}
Next file after this: {next_file}

RULES:
- Return ONLY the complete file content
- No explanation, no commentary, no markdown
- Stay consistent with existing files above
- Follow all coding standards above exactly

27. Structured Output Format

Claude is instructed to return structured JSON so Python can parse and execute reliably.

{
  "file":    "user_auth.php",
  "content": "<?php\nob_start();\ndefined('APP_ACCESS')...",
  "sql":     [],          // SQL statements if any (database.sql only)
  "notes":   ""           // optional: anything Python should know
}

28. API Key Storage

The Claude API key is stored in the system_settings table. Change it from the UI — no file editing ever.

-- system_settings table
INSERT INTO system_settings (setting_key, setting_value, is_encrypted)
VALUES ('claude_api_key', 'your-key-here', 1);

-- Retrieved and cached in config.php:
function get_setting(string $key): string {
    static $settings = [];
    if (!isset($settings[$key])) {
        $db = Database::getInstance()->getConnection();
        $stmt = $db->prepare("SELECT setting_value FROM system_settings WHERE setting_key = :key");
        $stmt->execute([':key' => $key]);
        $settings[$key] = $stmt->fetchColumn() ?? '';
    }
    return $settings[$key];
}

29. Project Management

Every project is a folder. The folder name is everything — it tells Python and Claude which project is active.

Project Config — .project_config.json

{
  "project_name":  "hospital_system",
  "created_at":    "2026-01-04",
  "subdomain":     "hospital_system.yourserver.com",
  "ttyd":          "terminal.hospital_system.yourserver.com",
  "project_path":  "/var/www/projects/hospital_system",
  "project_type":  "full_system",
  "status":        "live"
}

Three Ways A Project Starts

MethodWhat Happens
Fresh buildType project name → Claude builds everything from scratch following build order
Upload existing filesUpload files → Python validates structure → Claude can immediately read, edit, patch
Partial upload + continueUpload what exists → Python scans missing files → Claude continues from where upload left off

30. Upload Existing Projects

Any project built previously — even manually — becomes Claude-editable immediately after upload, as long as it follows the standard structure.

def validate_structure(uploaded_files):
    standard = [
        'database.sql', 'config.php', 'index.php',
        'user_auth.php', 'user_interface.php',
        'admin_auth.php', 'admin.php'
    ]
    found   = [f for f in standard if f in uploaded_files]
    missing = [f for f in standard if f not in uploaded_files]
    custom  = [f for f in uploaded_files if f not in standard]
    return found, missing, custom  # custom files accepted regardless

31. Download as ZIP

Every project can be downloaded as a clean ZIP with files in the correct order. Database first, config second, then everything else.

hospital_system.zip
├── database.sql          # always first
├── config.php            # always second
├── .htaccess
├── 404.php / 403.php / 500.php
├── index.php
├── user_auth.php
├── user_interface.php
├── user_header.php / user_sidebar.php
├── admin_auth.php
├── admin.php
├── admin_header.php / admin_sidebar.php
├── usersections/
├── adminsections/
├── integrations/
├── ajax/
└── assets/
Excluded From ZIP .design_profile.json, .project_config.json, .build_state.json, project_backup/ — these are builder metadata, not project files.

32. Build State Tracking

Python maintains a build state file per project. If tokens run out mid-build, the state is saved and the build resumes exactly where it stopped on next run.

StatusMeaning
in_progressBuild currently running
pausedToken limit reached — awaiting continuation
completeAll files built and validated
errorAuto-fix failed after 3 attempts — manual review needed

33. Patch History

Every patch is logged. Old versions are never deleted. Rollback is always one click away.

-- patch_history table tracks every change
patch_history (
    id               INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    project_id       VARCHAR(100)  NOT NULL,
    file_path        VARCHAR(255)  NOT NULL,
    patch_description TEXT         NOT NULL,  -- what was requested
    content_before   LONGTEXT      NOT NULL,  -- full file before patch
    content_after    LONGTEXT      NOT NULL,  -- full file after patch
    version_number   INT UNSIGNED  NOT NULL,
    status           ENUM('applied','rolled_back') DEFAULT 'applied',
    patched_at       TIMESTAMP     NOT NULL DEFAULT CURRENT_TIMESTAMP
)

34. Builder Database Schema

CREATE TABLE projects (
    id           INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    project_name VARCHAR(100) NOT NULL UNIQUE,
    project_type ENUM('landing','user_only','admin_only','full_system') NOT NULL,
    status       ENUM('building','paused','live','error') DEFAULT 'building',
    subdomain    VARCHAR(255),
    ttyd_url     VARCHAR(255),
    created_at   TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at   TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

CREATE TABLE project_files (
    id             INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    project_id     INT UNSIGNED NOT NULL,
    file_path      VARCHAR(255) NOT NULL,
    version_number INT UNSIGNED NOT NULL DEFAULT 1,
    last_updated   TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE
);

CREATE TABLE patch_history (
    id                INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    project_id        INT UNSIGNED NOT NULL,
    file_path         VARCHAR(255) NOT NULL,
    patch_description TEXT NOT NULL,
    content_before    LONGTEXT NOT NULL,
    content_after     LONGTEXT NOT NULL,
    version_number    INT UNSIGNED NOT NULL,
    status            ENUM('applied','rolled_back') DEFAULT 'applied',
    patched_at        TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE
);

CREATE TABLE build_logs (
    id           INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    project_id   INT UNSIGNED NOT NULL,
    file_path    VARCHAR(255),
    action       ENUM('build','validate','fix','patch','rollback','error'),
    status       ENUM('pass','fail','fixed'),
    message      TEXT,
    created_at   TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE
);

CREATE TABLE system_settings (
    id            INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    setting_key   VARCHAR(100) NOT NULL UNIQUE,
    setting_value TEXT NOT NULL,
    is_encrypted  TINYINT(1) NOT NULL DEFAULT 0,
    updated_at    TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

INSERT INTO system_settings (setting_key, setting_value, is_encrypted)
VALUES
  ('claude_api_key', 'YOUR_KEY_HERE', 1),
  ('claude_model',   'claude-sonnet-4-20250514', 0),
  ('max_fix_attempts', '3', 0),
  ('app_env',         'development', 0);

35. Builder UI Panels

PanelPurpose
DashboardOverview — active projects count, builds count, token spend, server status (PHP, MySQL, ttyd all green)
Create AppChat UI — type project name, select/create design profile, describe system, review build manifest, confirm & build
Edit AppChat UI — select existing project, see file versions, describe patch, system auto-backs up then patches
ProjectsAll project folders — subdomain link, ttyd link, status badge, download ZIP, delete
Connect DomainYour existing script — extended to search and link projects to external domains
Build HistoryEvery build run — project, files built, token usage, pass/fail per file, timestamps
Patch HistoryPer project — all patches, before/after content, version numbers, rollback button
Design ProfilesCreate and save named profiles — reuse across projects
Token UsagePer project token consumption, monthly total, cost estimate
SettingsClaude API key, model selection, server paths, conventions editor, environment toggle
🏠  Dashboard
────────────────────
⚡  Create App         (chat ui — fresh build)
✏️   Edit App           (chat ui — patch existing)
────────────────────
📁  Projects
🌐  Connect Domain
────────────────────
📊  Build History
🔄  Patch History
────────────────────
🎨  Design Profiles
⚙️   Settings
────────────────────
📖  Documentation
────────────────────
💰  Token Usage
────────────────────
🚪  Logout

37. End-to-End Journey

PhaseWhat Happens
1. Open builderNavigate to builder.yourserver.com — login — dashboard shows server status all green
2. Create projectClick Create App — type project name — select design profile — describe system in plain language
3. Build manifestPython determines project type, generates file list — shown to developer for review — confirm
4. ProvisioningPython creates folder, generates subdomain, spins up ttyd instance — all automatic
5. Build runsFile by file — Python bakes context, Claude writes code, Python validates, progress shown live alongside ttyd terminal
6. Token pauseIf tokens run out — build state saved — Continue button resumes exactly where stopped
7. Build completeHTTP 200 confirmed — system live at subdomain — open link shown
8. Review systemOpen subdomain — all interfaces working — styled correctly — all CRUD functional
9. Patch requestClick Edit App — select project — describe change — Python backs up — Claude patches affected files only
10. RollbackIf patch breaks something — one click — Python restores backup instantly
11. DownloadClick Download — Python generates ordered ZIP — database.sql first — clean for deployment anywhere
The Result One developer. One LXD container. ~$100 in tokens. 50+ complete, working, validated, deployable web applications. Each built in minutes. Each patchable, rollback-safe, and downloadable. Portfolio ready. Client delivery same day.

AI Builder Technical Documentation v1.0  ·  All standards and conventions locked  ·  Ready to build