Fix bin/publish: use correct .env path for rspade_system Fix bin/publish script: prevent grep exit code 1 from terminating script 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
364 lines
14 KiB
Plaintext
Executable File
364 lines
14 KiB
Plaintext
Executable File
NAME
|
|
coding_standards - RSX framework coding conventions and standards
|
|
|
|
SYNOPSIS
|
|
Naming conventions, code organization, and design philosophy for RSX development
|
|
|
|
DESCRIPTION
|
|
The RSX framework enforces specific coding standards to maintain consistency,
|
|
readability, and framework compatibility. These standards ensure code is
|
|
maintainable and follows the framework's architectural principles.
|
|
|
|
NAMING CONVENTIONS
|
|
Methods and Variables:
|
|
- Use underscore_case for all methods and variables
|
|
- Examples: user_name, calculate_total(), get_user_data()
|
|
|
|
Constants:
|
|
- Use UPPERCASE_WITH_UNDERSCORES
|
|
- Examples: MAX_UPLOAD_SIZE, DEFAULT_TIMEOUT
|
|
|
|
Classes in /rsx/ Directory:
|
|
- Use Like_This_With_Underscores format
|
|
- Examples: Index_Controller, User_Model, Frontend_Bundle
|
|
- Matches RSX naming patterns for auto-discovery
|
|
|
|
Classes in /system/app/RSpade/ (Framework):
|
|
- Use Like_This_With_Underscores where appropriate
|
|
- Exception: When extending Laravel classes, use Laravel's PascalCase
|
|
- Default for framework internals: PascalCase (existing Laravel convention)
|
|
|
|
Critical Rule - Case-Sensitive Files:
|
|
NEVER create files with same name but different case in same directory.
|
|
Examples to avoid: Helpers.php and helpers.php
|
|
This breaks Windows/macOS compatibility and triggers critical errors.
|
|
|
|
FILENAME CONVENTION EXCEPTIONS
|
|
@FILENAME-CONVENTION-EXCEPTION Marker:
|
|
Add this marker anywhere in a file to exempt it from filename matching rules.
|
|
The framework will skip all filename convention checks for that file.
|
|
|
|
Use cases:
|
|
- Legacy files being migrated that cannot be renamed yet
|
|
- Special cases that require non-standard naming
|
|
- Files with intentional naming that violates conventions
|
|
|
|
Example:
|
|
<?php
|
|
// @FILENAME-CONVENTION-EXCEPTION
|
|
// This file has a non-standard name for legacy reasons
|
|
|
|
class User_Model { ... }
|
|
|
|
Note: File must contain this exact text (case-sensitive) anywhere in contents.
|
|
|
|
AUTOMATIC FILE RENAMING (DEVELOPMENT)
|
|
Configuration (config/rsx.php):
|
|
'development' => [
|
|
// Auto-rename files to match RSX naming conventions
|
|
'auto_rename_files' => false, // Set to true to enable
|
|
|
|
// Globally disable all filename convention checks
|
|
'ignore_filename_convention' => false, // Set to true to disable
|
|
]
|
|
|
|
Auto-Rename Behavior (auto_rename_files = true):
|
|
- During manifest build, files in ./rsx are automatically renamed
|
|
- Only renames if target filename doesn't already exist
|
|
- Manifest rebuilds after rename to reflect new file paths
|
|
- Files with @FILENAME-CONVENTION-EXCEPTION are never renamed
|
|
|
|
Examples of auto-renaming:
|
|
- TestComponent1.jqhtml → test_component_1.jqhtml
|
|
- UserController.php → user_controller.php
|
|
- MyView.blade.php → my_view.blade.php
|
|
|
|
If target exists: Normal violation thrown (conflict detected)
|
|
|
|
Global Disable (ignore_filename_convention = true):
|
|
- Disables ALL filename convention checks
|
|
- No violations thrown for any files
|
|
- Useful for projects with existing non-standard naming
|
|
- More aggressive than @FILENAME-CONVENTION-EXCEPTION marker
|
|
|
|
RSPADE FRAMEWORK INTERNAL METHOD NAMING
|
|
For files in /system/app/RSpade/ only:
|
|
|
|
Private and Protected Methods:
|
|
- MUST start with underscore: _internal_method()
|
|
- Purpose: Immediately identifies framework-internal methods
|
|
- Application code prohibition: Never call methods starting with _
|
|
|
|
Public API Methods:
|
|
- Must NOT start with underscore
|
|
- These are stable public API for applications
|
|
- Safe for RSX applications to use
|
|
|
|
Example:
|
|
// In /system/app/RSpade/Core/Something.php
|
|
public static function public_api_method() { } // OK for apps
|
|
private static function _internal_helper() { } // Framework only
|
|
protected static function _process_data() { } // Framework only
|
|
|
|
Rationale:
|
|
- Methods starting with _ may change without notice in updates
|
|
- Clear separation between stable API and internal implementation
|
|
- Prevents applications from depending on internal methods
|
|
|
|
CLASS DESIGN PHILOSOPHY
|
|
Static by Default:
|
|
- All classes should be static unless specific reason to instantiate
|
|
- Classes are namespacing tools, not OOP for the sake of OOP
|
|
- Direct access from anywhere without instantiation
|
|
|
|
Exceptions for Instances:
|
|
- ORM/Model records (represent database rows)
|
|
- Resource handles (file handles, connections)
|
|
- Service connectors needing mocking (AWS, payment gateways)
|
|
- Artisan commands
|
|
|
|
Avoid Dependency Injection:
|
|
- No DI patterns or factory classes
|
|
- Exception: Service connectors that need mocking for tests
|
|
- Utility classes, helpers, managers, processors should be static
|
|
|
|
STRING MANIPULATION PHILOSOPHY
|
|
For Source Code Analysis: NO REGEX
|
|
- Never use regex to parse PHP, JavaScript, or any programming language
|
|
- Why regex fails for source code:
|
|
* Cannot distinguish code from comments
|
|
* Cannot understand syntactic context (strings, blocks, nesting)
|
|
* Breaks when code formatting changes
|
|
* Creates unmaintainable parsing logic
|
|
- Use AST parsers instead: Extend PHP/JS AST functionality in manifest
|
|
system to generate metadata for runtime analysis
|
|
|
|
For General String Operations: Prefer Verbose Clarity
|
|
- Default approach: Use explicit string functions over regex
|
|
- Prefer readable multi-line operations:
|
|
|
|
// ✅ GOOD - Clear and maintainable
|
|
$parts = explode('/', $path);
|
|
$filename = end($parts);
|
|
$extension = substr($filename, strrpos($filename, '.') + 1);
|
|
|
|
// ❌ AVOID - Unreadable regex
|
|
preg_match('/\/([^\/]+)\.([^.]+)$/', $path, $matches);
|
|
|
|
When Simple Regex IS Appropriate:
|
|
- Well-established validation patterns using proven libraries
|
|
- Very simple matching: single character classes, basic patterns
|
|
- Performance-critical operations where regex proven faster AND simple
|
|
|
|
Implementation Process:
|
|
1. Always propose solution to user first before implementing regex
|
|
2. Justify why string functions aren't sufficient
|
|
3. Document regex purpose in plain English
|
|
4. Prefer library solutions over custom regex patterns
|
|
|
|
Source Code Analysis Guidelines:
|
|
- Extend manifest AST parsers to capture needed metadata
|
|
- Add metadata to manifest cache for runtime analysis
|
|
- Use reflection and AST data instead of pattern matching
|
|
- Consult user before any source code parsing implementation
|
|
|
|
FUNCTION ORGANIZATION PHILOSOPHY
|
|
Prefer Inline Code with Comments:
|
|
- Comment above a few lines better than separate methods
|
|
- Readability from clear comments and logical flow
|
|
- Not arbitrary function boundaries
|
|
|
|
Long Functions Are Acceptable:
|
|
- When steps are sequential and single-purpose
|
|
- Clear comments explain the flow
|
|
- Related logic stays together
|
|
|
|
Create Sub-Functions Only When:
|
|
- Code called from multiple places or multiple times
|
|
- Operation is significantly complex logical subset
|
|
- Code needs independent unit testing
|
|
- Abstraction genuinely improves understanding
|
|
|
|
Avoid Functions for the Sake of Functions:
|
|
- Don't create method to wrap file_get_contents($file)
|
|
- Don't split sequential operations arbitrarily
|
|
- Goal: Keep related logic together, not create maze of methods
|
|
|
|
Sequential Operations Belong Together:
|
|
- If step B always follows step A, same function with comments
|
|
- Not arbitrarily split across multiple methods
|
|
|
|
FILE STRUCTURE RESTRICTIONS
|
|
PHP Files Without Classes (in ./rsx directory):
|
|
PHP utility files without classes may only contain at global scope:
|
|
- Function definitions
|
|
- define() calls for constants
|
|
- namespace declarations
|
|
- use statements
|
|
- declare() directives
|
|
- Comments
|
|
|
|
NOT allowed at global scope:
|
|
- Control structures (if, for, while, switch)
|
|
- Function calls (except define())
|
|
- Variable assignments
|
|
- Object instantiation (new)
|
|
- Include/require statements
|
|
- Echo/print statements
|
|
- Exit/die statements
|
|
|
|
Rationale: Classless files are loaded on every request and should
|
|
only define functions/constants, not execute code. Code that runs
|
|
on every request should be in Main::init(), pre_dispatch() methods,
|
|
or implemented in Laravel outside RSX.
|
|
|
|
Example Valid PHP Utility File:
|
|
<?php
|
|
namespace App\Utils;
|
|
use App\Models\User;
|
|
|
|
declare(strict_types=1);
|
|
|
|
define('MAX_LENGTH', 255);
|
|
|
|
function format_name(string $name): string {
|
|
return ucfirst(trim($name)); // Any code allowed inside functions
|
|
}
|
|
|
|
PHP Files With Classes (in ./rsx directory):
|
|
PHP files with classes may only contain at global scope:
|
|
- namespace declarations
|
|
- use statements
|
|
- Comments
|
|
- include/require statements with path restrictions:
|
|
* Allowed: paths not starting with rsx/
|
|
* Allowed: paths containing /resource/
|
|
* NOT allowed: paths starting with rsx/ without /resource/
|
|
|
|
NOT allowed at global scope:
|
|
- Function definitions
|
|
- define() calls for constants
|
|
|
|
Example Valid PHP Class File:
|
|
<?php
|
|
namespace Rsx\App;
|
|
use App\Models\User;
|
|
|
|
require_once 'vendor/autoload.php'; // OK
|
|
include 'rsx/app/resource/config.php'; // OK - has /resource/
|
|
|
|
class MyClass {
|
|
// Class implementation
|
|
}
|
|
|
|
JavaScript Files Without Classes:
|
|
JavaScript utility files without ES6 classes may only contain:
|
|
- Function declarations (standard or arrow)
|
|
- Const variables with static values (no function calls)
|
|
- Functions marked with @decorator
|
|
|
|
Static values include:
|
|
- Literals (strings, numbers, booleans, null)
|
|
- Binary/unary expressions (e.g., 3 * 365)
|
|
- Static arrays and objects with literal values
|
|
|
|
Example Valid JavaScript Utility File:
|
|
// Valid constants - static values only
|
|
const DAYS_IN_YEAR = 365;
|
|
const MILLISECONDS_IN_DAY = 24 * 60 * 60 * 1000;
|
|
|
|
// Valid function
|
|
function formatName(name) {
|
|
return name.trim().toUpperCase();
|
|
}
|
|
|
|
// Invalid - function call at global scope
|
|
const timestamp = Date.now(); // NOT ALLOWED
|
|
|
|
Enforcement:
|
|
- Validated at manifest build time
|
|
- Clear error messages with line numbers
|
|
- Build fails on violations
|
|
- Ensures clean, predictable code structure
|
|
|
|
TEMPORARY FILES CONVENTION
|
|
Always Suffix with -temp:
|
|
- Pattern: filename-temp.extension
|
|
- Examples: test-temp.php, debug-script-temp.js, migration-fix-temp.sql
|
|
|
|
Applies To:
|
|
- One-off scripts
|
|
- Test files not part of test suite
|
|
- Temporary implementations or workarounds
|
|
- Debug utilities
|
|
- Any file that should be removed later
|
|
|
|
Rules:
|
|
- Purpose: Easy identification of files needing cleanup
|
|
- Never commit -temp files unless explicitly requested
|
|
- Helps prevent temporary code from becoming permanent
|
|
|
|
ROUTING RULES
|
|
Restricted HTTP Methods:
|
|
- Only GET and POST methods allowed
|
|
- PUT, PATCH, DELETE, OPTIONS throw exceptions
|
|
- Keeps routing simple and explicit
|
|
|
|
No Resource Routes:
|
|
- Route::resource() and Route::apiResource() throw exceptions
|
|
- Explicit route definitions only
|
|
- Each route defined individually for clarity
|
|
|
|
GIT WORKFLOW
|
|
Staging:
|
|
- Always use: git add -A
|
|
- Never selective staging
|
|
- Ensures all changes are included
|
|
|
|
Submodules:
|
|
- Located in /internal-libs/
|
|
- Examples: jqhtml, rsx-scss-lint
|
|
|
|
EXAMPLES
|
|
Correct Naming:
|
|
class User_Profile_Controller {
|
|
public static function show_profile(Request $request) {
|
|
$user_data = static::_get_user_info($request->user_id);
|
|
return view('profile', compact('user_data'));
|
|
}
|
|
|
|
private static function _get_user_info($user_id) {
|
|
// Framework internal method
|
|
}
|
|
}
|
|
|
|
String Processing:
|
|
// Preferred approach
|
|
$parts = explode('/', $path);
|
|
$filename = end($parts);
|
|
$extension = substr($filename, strrpos($filename, '.') + 1);
|
|
|
|
// Avoid unless necessary
|
|
preg_match('/\/([^\/]+)\.([^.]+)$/', $path, $matches);
|
|
|
|
Function Organization:
|
|
// Good: Related steps together with comments
|
|
public static function process_upload($file) {
|
|
// Validate file type and size
|
|
if (!in_array($file->extension(), ['jpg', 'png'])) {
|
|
throw new Exception('Invalid file type');
|
|
}
|
|
|
|
// Generate unique filename
|
|
$filename = uniqid() . '.' . $file->extension();
|
|
|
|
// Store file and create database record
|
|
$path = $file->storeAs('uploads', $filename);
|
|
Upload_Model::create(['filename' => $filename, 'path' => $path]);
|
|
|
|
return $filename;
|
|
}
|
|
|
|
SEE ALSO
|
|
error_handling - Error handling patterns and shouldnt_happen()
|
|
config_rsx - Framework configuration standards |