# RSpade Framework - AI/LLM Development Guide **PURPOSE**: Essential directives for AI/LLM assistants developing RSX applications with RSpade. ## What is RSpade? **Visual Basic-like development for PHP/Laravel.** Think: VB6 apps → VB6 runtime → Windows = RSX apps → RSpade runtime → Laravel. **Philosophy**: Modern anti-modernization. While JavaScript fragments into complexity and React demands quarterly paradigm shifts, RSpade asks: "What if coding was easy again?" Business apps need quick builds and easy maintenance, not bleeding-edge architecture. **Important**: RSpade is built on Laravel but diverges significantly. Do not assume Laravel patterns work in RSX without verification. **Terminology**: **RSpade** = Complete framework | **RSX** = Your application code in `/rsx/` --- ## CRITICAL RULES ### 🔴 Framework Updates ```bash php artisan rsx:framework:pull # 5-minute timeout required ``` Updates take 2-5 minutes. Includes code pull, manifest rebuild, bundle recompilation. **For AI: Always use 5-minute timeout.** ### 🔴 Fail Loud - No Silent Fallbacks **ALWAYS fail visibly.** No redundant fallbacks, silent failures, or alternative code paths. ```php // ❌ CATASTROPHIC try { $clean = Sanitizer::sanitize($input); } catch (Exception $e) { $clean = $input; } // DISASTER // ✅ CORRECT $clean = Sanitizer::sanitize($input); // Let it throw ``` **SECURITY-CRITICAL**: If sanitization/validation/auth fails, NEVER continue. Always throw immediately. ### 🔴 No Defensive Coding Core classes ALWAYS exist. Never check. ```javascript // ❌ BAD: if (typeof Rsx !== 'undefined') { Rsx.Route(...) } // ✅ GOOD: Rsx.Route(...) ``` ### 🔴 Static-First Philosophy Classes are namespacing tools. Use static unless instances needed (models, resources). Avoid dependency injection. ### 🔴 Git Workflow - Framework is READ-ONLY **NEVER modify `/var/www/html/system/`** - It's like node_modules or the Linux kernel. - **App repo**: `/var/www/html/.git` (you control) - **Framework**: `/var/www/html/system/` (submodule, don't touch) - **Your code**: `/var/www/html/rsx/` (all changes here) **Commit discipline**: ONLY commit when explicitly asked. Commits are milestones, not individual changes. ### 🔴 DO NOT RUN `rsx:clean` **RSpade's cache auto-invalidates on file changes.** Running `rsx:clean` causes 30-60 second rebuilds with zero benefit. **When to use**: Only on catastrophic corruption, after framework updates (automatic), or when explicitly instructed. **Correct workflow**: Edit → Save → Reload browser → See changes (< 1 second) --- ## NAMING CONVENTIONS **Enforced by `rsx:check`**: | Context | Convention | Example | |---------|------------|---------| | PHP Methods/Variables | `underscore_case` | `user_name` | | PHP Classes | `Like_This` | `User_Controller` | | JavaScript Classes | `Like_This` | `User_Card` | | Files | `lowercase_underscore` | `user_controller.php` | | Database Tables | `lowercase_plural` | `users` | | Constants | `UPPERCASE` | `MAX_SIZE` | **Critical**: Never create same-name different-case files. --- ## DIRECTORY STRUCTURE ``` /var/www/html/ ├── rsx/ # YOUR CODE │ ├── app/ # Modules │ ├── models/ # Database models │ ├── public/ # Static files (web-accessible) │ ├── resource/ # Framework-ignored │ └── theme/ # Global assets └── system/ # FRAMEWORK (read-only) ``` ### Special Directories (Path-Agnostic) **`resource/`** - ANY directory named this is framework-ignored. Store helpers, docs, third-party code. Exception: `/rsx/resource/config/` IS processed. **`public/`** - ANY directory named this is web-accessible, framework-ignored. 5min cache, 30d with `?v=`. ### Path-Agnostic Loading Classes found by name, not path. No imports needed. ```php $user = User_Model::find(1); // Framework finds it // NOT: use Rsx\Models\User_Model; // Auto-generated ``` --- ## CONFIGURATION **Two-tier system**: - **Framework**: `/system/config/rsx.php` (never modify) - **User**: `/rsx/resource/config/rsx.php` (your overrides) Merged via `array_merge_deep()`. Common overrides: `development.auto_rename_files`, `bundle_aliases`, `console_debug`. --- ## ROUTING & CONTROLLERS ```php class Frontend_Controller extends Rsx_Controller_Abstract { #[Auth('Permission::anybody()')] #[Route('/', methods: ['GET'])] public static function index(Request $request, array $params = []) { return rsx_view('Frontend_Index', [ 'bundle' => Frontend_Bundle::render() ]); } } ``` **Rules**: Only GET/POST allowed. Use `:param` syntax. All routes MUST have `#[Auth]`. ### #[Auth] Attribute ```php #[Auth('Permission::anybody()')] // Public #[Auth('Permission::authenticated()')] // Require login #[Auth('Permission::has_role("admin")')] // Custom ``` **Controller-wide**: Add to `pre_dispatch()`. Multiple attributes = all must pass. ### Type-Safe URLs ```php // PHP Rsx::Route('User_Controller', 'show')->url(['id' => 123]); // JavaScript (identical) Rsx.Route('User_Controller', 'show').url({id: 123}); ``` --- ## BLADE & VIEWS ```blade @rsx_id('Frontend_Index') {{-- Every view starts with this --}}
{{-- Adds view class --}} @rsx_include('Component_Name') {{-- Include by name, not path --}} ``` ### SCSS Pairing ```scss /* frontend_index.scss - Same directory as view */ .Frontend_Index { /* Matches @rsx_id */ .content { padding: 20px; } } ``` --- ## JAVASCRIPT ### Auto-Initialization ```javascript class Frontend_Index { static async on_app_ready() { // DOM ready } static async on_jqhtml_ready() { // Components ready } } ``` **CRITICAL**: JavaScript only executes when bundle rendered. --- ## BUNDLE SYSTEM **One bundle per page required.** ```php class Frontend_Bundle extends Rsx_Bundle_Abstract { public static function define(): array { return [ 'include' => [ 'jquery', // Required 'lodash', // Required 'rsx/theme/variables.scss', // Order matters 'rsx/app/frontend', // Directory 'rsx/models', // For JS stubs ], ]; } } ``` Auto-compiles on page reload in development. ```blade {!! Frontend_Bundle::render() !!} ``` --- ## JQHTML COMPONENTS ### Philosophy For mechanical thinkers who see structure, not visuals. Write `