- Created complete documentation in docs/ directory - Added PROJECT_OVERVIEW.md with feature highlights and getting started guide - Added ARCHITECTURE.md with system design and technical details - Added SECURITY.md with comprehensive security implementation guide - Added DEVELOPMENT.md with development workflows and best practices - Added DEPLOYMENT.md with production deployment instructions - Added API.md with complete REST API documentation - Added CONTRIBUTING.md with contribution guidelines - Added CHANGELOG.md with version history and migration notes - Reorganized all documentation files into docs/ directory for better organization - Updated README.md with proper documentation links and quick navigation - Enhanced project structure with professional documentation standards
13 KiB
13 KiB
Development Guide
This guide covers development workflows, coding standards, and best practices for EasyStream development.
Development Environment Setup
Local Development with Docker
# Clone the repository
git clone <repository-url>
cd easystream
# Copy environment configuration
cp .env.example .env
# Start development environment
docker-compose up -d --build
# Access the application
open http://localhost:8083
Native PHP Development
# Install PHP 8.2+ with required extensions
# - pdo_mysql
# - gd
# - curl
# - mbstring
# - xml
# - zip
# Install Composer dependencies (if any)
composer install
# Configure database connection
cp f_core/config.database.php.example f_core/config.database.php
# Edit database settings
# Set up web server (Apache/Nginx)
# Point document root to project directory
Project Structure Deep Dive
Core Framework (f_core/)
f_core/
├── config.*.php # Configuration files
├── f_classes/ # Core business logic classes
├── f_functions/ # Utility functions
└── f_workers/ # Background workers
Modules (f_modules/)
f_modules/
├── m_frontend/ # User-facing modules
├── m_backend/ # Admin modules
└── api/ # API endpoints
Templates (f_templates/)
f_templates/
├── tpl_frontend/ # User interface templates
├── tpl_backend/ # Admin interface templates
└── frontend/ # Static frontend assets
Jobs (f_jobs/)
f_jobs/
├── BaseJob.php # Base job class
├── VideoProcessingJob.php
├── NotificationJob.php
└── CleanupJob.php
Coding Standards
PHP Standards
Follow PSR-12 coding standards with EasyStream-specific conventions:
<?php
/**
* Class description
*
* @author Your Name
* @version 1.0
*/
class VExampleClass
{
/**
* Method description
*
* @param string $param Parameter description
* @return bool Return value description
*/
public function exampleMethod(string $param): bool
{
// Implementation
return true;
}
}
Naming Conventions
- Classes: PascalCase with 'V' prefix for core classes (
VDatabase,VSecurity) - Methods: camelCase (
getUserById,validateInput) - Variables: camelCase (
$userId,$videoData) - Constants: UPPER_SNAKE_CASE (
MAX_FILE_SIZE,DEFAULT_TIMEOUT) - Files: lowercase with underscores (
class.database.php,functions.security.php)
Database Conventions
- Tables: lowercase with underscores (
user_sessions,video_metadata) - Columns: lowercase with underscores (
user_id,created_at) - Primary keys:
id(auto-increment) - Foreign keys:
{table}_id(user_id,video_id) - Timestamps:
created_at,updated_at
Development Workflows
Feature Development
-
Create Feature Branch
git checkout -b feature/new-feature-name -
Create Spec (Optional)
# For complex features, create a spec mkdir -p .kiro/specs/feature-name # Create requirements.md, design.md, tasks.md -
Implement Feature
- Follow the task list if using specs
- Write tests alongside implementation
- Update documentation
-
Test Implementation
# Run all tests ./run-tests.sh # Run specific test suite phpunit tests/Unit/NewFeatureTest.php -
Create Pull Request
- Ensure all tests pass
- Update CHANGELOG.md
- Request code review
Bug Fix Workflow
-
Reproduce Issue
- Create test case that demonstrates the bug
- Document expected vs actual behavior
-
Fix Implementation
- Make minimal changes to fix the issue
- Ensure fix doesn't break existing functionality
-
Verify Fix
- Run test suite
- Manual testing of affected areas
- Performance impact assessment
Testing Guidelines
Unit Testing
<?php
use PHPUnit\Framework\TestCase;
class VSecurityTest extends TestCase
{
public function testValidateInput()
{
$result = VSecurity::validateInput('test@example.com', 'email');
$this->assertEquals('test@example.com', $result);
}
public function testValidateInputInvalid()
{
$this->expectException(ValidationException::class);
VSecurity::validateInput('invalid-email', 'email');
}
}
Integration Testing
<?php
class AuthIntegrationTest extends TestCase
{
public function testUserLoginFlow()
{
// Test complete login process
$user = $this->createTestUser();
$result = VAuth::authenticate($user['username'], 'password');
$this->assertTrue($result);
$this->assertTrue(VAuth::isLoggedIn());
}
}
Test Data Management
<?php
// tests/fixtures/test_data.sql
INSERT INTO users (username, email, password_hash) VALUES
('testuser', 'test@example.com', '$2y$10$...');
// In test classes
protected function setUp(): void
{
$this->loadFixtures('test_data.sql');
}
Database Development
Migration Pattern
<?php
// __install/updatedb_feature.sql
-- Add new table
CREATE TABLE IF NOT EXISTS feature_data (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
data TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id)
);
-- Add index
CREATE INDEX idx_feature_user ON feature_data(user_id);
Query Development
<?php
// Always use prepared statements
class VFeatureRepository
{
public function getFeatureData(int $userId): array
{
global $class_database;
$sql = "SELECT * FROM feature_data WHERE user_id = ? ORDER BY created_at DESC";
return $class_database->execute($sql, [$userId])->getRows();
}
public function createFeatureData(int $userId, string $data): bool
{
global $class_database;
$sql = "INSERT INTO feature_data (user_id, data) VALUES (?, ?)";
return $class_database->execute($sql, [$userId, $data])->rowCount() > 0;
}
}
Frontend Development
Template Development
{* f_templates/tpl_frontend/feature.tpl *}
<div class="feature-container">
<h2>{$feature_title|escape}</h2>
{if $user_logged_in}
<form method="post" action="{$form_action}">
{csrf_field('feature_form')}
<input type="text" name="feature_input" value="{$feature_value|escape}">
<button type="submit">Submit</button>
</form>
{else}
<p>Please <a href="/login">login</a> to use this feature.</p>
{/if}
</div>
JavaScript Development
// f_templates/frontend/js/feature.js
class FeatureManager {
constructor() {
this.initializeEventListeners();
}
initializeEventListeners() {
document.addEventListener('DOMContentLoaded', () => {
this.setupFeatureForm();
});
}
setupFeatureForm() {
const form = document.getElementById('feature-form');
if (form) {
form.addEventListener('submit', this.handleFormSubmit.bind(this));
}
}
async handleFormSubmit(event) {
event.preventDefault();
const formData = new FormData(event.target);
try {
const response = await fetch('/api/feature', {
method: 'POST',
body: formData
});
const result = await response.json();
this.handleResponse(result);
} catch (error) {
console.error('Feature submission failed:', error);
}
}
}
// Initialize when DOM is ready
new FeatureManager();
API Development
RESTful API Structure
<?php
// api/feature.php
require_once '../f_core/config.core.php';
class FeatureAPI
{
public function handleRequest()
{
$method = $_SERVER['REQUEST_METHOD'];
switch ($method) {
case 'GET':
return $this->getFeature();
case 'POST':
return $this->createFeature();
case 'PUT':
return $this->updateFeature();
case 'DELETE':
return $this->deleteFeature();
default:
http_response_code(405);
return ['error' => 'Method not allowed'];
}
}
private function getFeature()
{
$id = get_param('id', 'int');
if (!$id) {
http_response_code(400);
return ['error' => 'Feature ID required'];
}
// Implementation
return ['feature' => $featureData];
}
}
// Handle the request
$api = new FeatureAPI();
header('Content-Type: application/json');
echo json_encode($api->handleRequest());
Background Jobs
Job Implementation
<?php
// f_jobs/FeatureProcessingJob.php
class FeatureProcessingJob extends BaseJob
{
protected string $jobType = 'feature_processing';
public function execute(array $data): bool
{
try {
$featureId = $data['feature_id'] ?? null;
if (!$featureId) {
throw new InvalidArgumentException('Feature ID required');
}
$this->processFeature($featureId);
return true;
} catch (Exception $e) {
$this->logError('Feature processing failed', [
'error' => $e->getMessage(),
'data' => $data
]);
return false;
}
}
private function processFeature(int $featureId): void
{
// Implementation
}
}
Job Queue Management
<?php
// Queue a job
$queueManager = new VQueueManager();
$queueManager->addJob('feature_processing', [
'feature_id' => $featureId,
'priority' => 'high'
]);
// Process jobs (in worker)
$worker = new QueueWorker();
$worker->processJobs();
Security Development
Input Validation
<?php
// Always validate input
$username = post_param('username', 'alphanum');
$email = post_param('email', 'email');
$age = post_param('age', 'int');
// Custom validation
$customValue = VSecurity::validateInput($input, [
'type' => 'custom',
'pattern' => '/^[A-Z]{2,5}$/',
'required' => true
]);
CSRF Protection
<?php
// In forms
echo csrf_field('form_action');
// Validation
if (!validate_csrf('form_action')) {
throw new SecurityException('CSRF validation failed');
}
Rate Limiting
<?php
// Check rate limit
if (!check_rate_limit('api_' . $userId, 100, 3600)) {
http_response_code(429);
exit('Rate limit exceeded');
}
Performance Optimization
Database Optimization
- Use appropriate indexes
- Optimize query structure
- Implement query caching
- Use connection pooling
Caching Strategy
<?php
// Application-level caching
$cacheKey = "user_data_{$userId}";
$userData = $cache->get($cacheKey);
if (!$userData) {
$userData = $this->loadUserData($userId);
$cache->set($cacheKey, $userData, 3600); // 1 hour
}
Template Optimization
- Enable Smarty template caching
- Minimize template complexity
- Use template inheritance
- Optimize asset loading
Debugging and Troubleshooting
Debug Mode
<?php
// Enable debug mode in development
$cfg['debug_mode'] = true;
// Debug logging
VLogger::debug('Debug information', [
'variable' => $value,
'context' => $context
]);
Error Handling
<?php
try {
// Risky operation
$result = $this->performOperation();
} catch (Exception $e) {
VLogger::error('Operation failed', [
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);
// Handle gracefully
return $this->handleError($e);
}
Log Analysis
# View recent errors
tail -f f_data/logs/error_$(date +%Y-%m-%d).log
# Search for specific issues
grep "CRITICAL" f_data/logs/*.log
# Monitor performance
grep "SLOW_QUERY" f_data/logs/*.log
Deployment Preparation
Pre-deployment Checklist
- All tests passing
- Security review completed
- Performance testing done
- Database migrations ready
- Configuration updated
- Documentation updated
Production Considerations
- Disable debug mode
- Configure proper logging levels
- Set up monitoring and alerts
- Implement backup procedures
- Configure SSL/TLS properly
Code Review Guidelines
Review Checklist
- Code follows project standards
- Security best practices implemented
- Tests cover new functionality
- Documentation updated
- Performance impact considered
- Error handling implemented
- Logging added where appropriate
Common Issues to Check
- SQL injection vulnerabilities
- XSS vulnerabilities
- Missing input validation
- Improper error handling
- Performance bottlenecks
- Missing tests
- Inadequate logging