A Complete Guide: From First Prompt to Working Application
This tutorial documents the entire process of building the Sports Ground Booking Platform using AI assistance.
Follow along to learn how to work with AI to build a complete, functional web application.
"My project was a booking platform for games grounds like cricket and football turfs,
where user can compare prices and book them. Use a simple stack (html, css, php, javascript, ajax, etc mysql)."
Project Goals
Create a functional booking platform for sports grounds
Enable users to search, compare prices, and book time slots
Implement user authentication and admin dashboard
Include analytics and logging systems
Create a professional, modern design with theme management
Serve as a teaching example for AI-assisted development
Technology Stack
Backend: PHP 7.4+, MySQL
Frontend: HTML5, CSS3, JavaScript (Vanilla)
Database: MySQL with PDO
No Frameworks: Pure vanilla implementation
Current State: Starting Point
This is where we begin - just an idea and a blank canvas.
Empty Page - No Code Yet
This is where your application will be built...
2. Planning & Analysis
Before writing any code, we need to understand what we're building and plan how to build it.
This planning phase saves hours of rework later.
Step 1: Understanding Requirements
The first step was to analyze the user's request and understand what needed to be built:
Booking system for sports grounds (cricket and football)
Price comparison functionality
User registration and authentication
Search and filter capabilities
Admin dashboard for management
Beginner Breakdown: Understanding the Request
What the User Wants
The user wants a web application where people can:
Search for sports grounds (cricket and football fields)
Compare prices between different grounds
Book time slots at their chosen ground
Think of it like: A hotel booking website, but for sports facilities instead of hotel rooms.
Technology Requirements
The user specified a "simple stack" - this means:
HTML/CSS: For the visual interface
PHP: For server-side logic (handling requests, database operations)
JavaScript/AJAX: For dynamic interactions without page reloads
MySQL: For storing data (users, grounds, bookings)
Why "simple stack"? The user wants to learn, not get overwhelmed by complex frameworks.
This approach teaches fundamentals that apply everywhere.
Interactive Exercise: Choosing the Right Planning Approach
You're starting a new project. How should you approach planning and requirements gathering?
❌ Why this is wrong:
Starting to code without planning leads to:
Rework: You'll have to rewrite code when you realize you missed something
Technical Debt: Quick fixes become permanent problems
Incomplete Features: You'll forget important functionality
Poor Database Design: Without planning, your database structure will be inefficient
Real-world impact: Projects started this way often take 3x longer to complete
because of all the rework needed.
❌ Why this is wrong:
A quick list doesn't capture:
Relationships: How different parts connect (users → bookings → grounds)
Edge Cases: What happens when things go wrong?
Scalability: Will this work with 10 users? 10,000 users?
Security: How will you protect user data?
Result: You'll discover problems mid-development that require major changes.
⚠️ This works, but:
A basic plan is better than no plan, but it's missing critical details:
Database Schema: You haven't thought through table relationships
File Structure: Code organization isn't planned, leading to messy structure
Error Handling: No plan for how to handle errors gracefully
Security: Security considerations are often an afterthought
Security First: Security is built in from the start
Fewer Surprises: You've thought through edge cases
Time Investment: 1-2 hours of planning saves 10-20 hours of rework.
What we did: We analyzed requirements, designed the database schema, planned the file structure,
and identified security requirements before writing a single line of code.
Step 2: Database Planning
We identified the core entities needed:
Users: Store user accounts and authentication data
Each directory has a specific purpose. This makes it easy to find files and understand the codebase.
Reason 2: Security
By putting admin files in a separate directory, we can add extra security (like .htaccess protection)
to the entire admin folder.
Reason 3: Maintainability
When you need to update styles, you know they're in assets/css/.
When you need database functions, they're in includes/db.php.
Current State: Planning Complete
After planning, we have a clear structure. The page now has basic HTML structure.
Sports Booking Platform
Welcome
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore.
Basic page structure created
3. Database Design
The database is the foundation of your application. A well-designed database makes everything else easier.
A poorly designed database causes problems that are difficult to fix later. Let's see how we designed ours.
What We're Building
We need to store information about users, sports grounds, bookings, and system data.
Each piece of information needs its own table with carefully designed columns.
Why This Design
Reason 1: Normalization
We separate data into different tables to avoid duplication. For example, instead of storing
user information in every booking record, we store it once in the users table and reference it.
Reason 2: Data Integrity
Foreign keys ensure that bookings can only reference existing users and grounds.
This prevents "orphaned" data (bookings for deleted users).
Reason 3: Performance
Indexes on frequently queried columns (like user_id, sport_type)
make searches fast, even with thousands of records.
CREATE TABLE `example_001_users` (
`id` int(11) NOT NULL AUTO_INCREMENT, -- Unique identifier for each user
`username` varchar(50) NOT NULL, -- User's chosen username
`email` varchar(100) NOT NULL, -- User's email address
`password` varchar(255) NOT NULL, -- Hashed password (never store plain text!)
`full_name` varchar(100) DEFAULT NULL, -- Optional full name
`phone` varchar(20) DEFAULT NULL, -- Optional phone number
`role` enum('user','admin') DEFAULT 'user', -- User's permission level
`status` enum('active','inactive','suspended') DEFAULT 'active', -- Account status
`created_at` datetime DEFAULT CURRENT_TIMESTAMP, -- When account was created
`updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- Last update time
`last_login` datetime DEFAULT NULL, -- Last login timestamp
PRIMARY KEY (`id`), -- Primary key for fast lookups
UNIQUE KEY `username` (`username`), -- Username must be unique
UNIQUE KEY `email` (`email`), -- Email must be unique
KEY `idx_status` (`status`), -- Index for filtering by status
KEY `idx_role` (`role`) -- Index for filtering by role
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
Why This Design:
Security: Password is stored as a hash (bcrypt), never plain text.
Even if the database is compromised, passwords can't be recovered.
Performance: Indexes on username, email, status,
and role make queries fast.
Data Integrity: UNIQUE constraints prevent duplicate usernames/emails.
ENUM types ensure only valid values are stored.
Audit Trail:created_at, updated_at, and last_login
help track user activity and debug issues.
Interactive Exercise: Storing Passwords
You need to store user passwords in the database. Which approach should you use?
❌ Why this is wrong:
CRITICAL SECURITY FLAW: Storing passwords in plain text means:
If your database is hacked, attackers immediately have all passwords
If an employee has database access, they can see all passwords
If you accidentally log passwords, they're exposed
You're violating privacy laws and best practices
Real-world impact: Companies have been fined millions and lost customer trust
for storing passwords in plain text. Never do this!
❌ Why this is wrong:
OUTDATED AND INSECURE: MD5 and SHA1 are:
Fast to crack: Modern computers can try billions of hashes per second
No salt by default: Same password = same hash (easy to identify common passwords)
Vulnerable to rainbow tables: Pre-computed hash tables make cracking trivial
Deprecated: These algorithms are considered broken for password storage
Example: The password "password123" always produces the same MD5 hash.
Attackers can use lookup tables to instantly identify it.
⚠️ This works, but:
Bcrypt is good, but a fixed salt has problems:
Same passwords = same hashes: If two users have "password123",
they'll have identical hashes (security risk)
Manual salt management: You have to generate and store salts yourself
Error-prone: Easy to forget to use the salt or use it incorrectly
Better approach: Let PHP's password_hash() handle salt generation automatically.
✅ Perfect! Here's why:
PHP's password_hash() function:
Uses bcrypt: A slow, secure hashing algorithm designed for passwords
Automatic salt: Generates a unique salt for each password automatically
Cost factor: Adjustable difficulty (default is secure, can be increased for more security)
Future-proof: Can be updated to use newer algorithms (like Argon2) without code changes
Security benefits: Even if two users have the same password, they get different hashes.
Even if the database is compromised, passwords can't be recovered.
example_001_grounds
Stores sports ground information:
Name, location, address
Sport type (cricket/football/basketball/hockey/tennis/volleyball/both)
Pricing (price per hour)
Amenities, capacity, availability hours
File: install.sqlContext: Sports ground information storage
CREATE TABLE `example_001_grounds` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(200) NOT NULL, -- Ground name (e.g., "Wankhede Stadium")
`sport_type` enum('cricket','football','basketball','hockey','tennis','volleyball','both') DEFAULT 'both',
`location` varchar(200) NOT NULL, -- City/area (e.g., "Mumbai, Maharashtra")
`address` text, -- Full address
`price_per_hour` decimal(10,2) NOT NULL, -- Price (supports up to 99,999,999.99)
`description` text, -- Detailed description
`image` varchar(255) DEFAULT NULL, -- Image URL or path
`capacity` int(11) DEFAULT NULL, -- Maximum capacity
`amenities` text, -- JSON or comma-separated amenities
`availability_start` time DEFAULT '06:00:00', -- Opening time
`availability_end` time DEFAULT '22:00:00', -- Closing time
`status` enum('active','inactive') DEFAULT 'active',
`created_at` datetime DEFAULT CURRENT_TIMESTAMP,
`updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_sport_type` (`sport_type`), -- Fast filtering by sport
KEY `idx_location` (`location`), -- Fast location searches
KEY `idx_status` (`status`), -- Fast active/inactive filtering
KEY `idx_price` (`price_per_hour`) -- Fast price sorting
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
Why This Design:
ENUM for Sport Type: Ensures only valid sport types are stored.
Easy to add new sports later by altering the enum.
DECIMAL for Price: Using DECIMAL(10,2) instead of FLOAT prevents
rounding errors in financial calculations.
Indexes on Common Queries: Indexes on sport_type, location,
and price_per_hour make filtering and sorting fast.
Status Field: Allows "soft deletion" - grounds can be marked inactive
without deleting data (preserves booking history).
example_001_bookings
Manages user bookings:
Links user to ground
Booking date and time slots
Total hours and price calculation
Status tracking (pending/confirmed/cancelled/completed)
Payment status
File: install.sqlContext: User booking records
CREATE TABLE `example_001_bookings` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL, -- Links to users table
`ground_id` int(11) NOT NULL, -- Links to grounds table
`booking_date` date NOT NULL, -- Date of booking
`start_time` time NOT NULL, -- Booking start time
`end_time` time NOT NULL, -- Booking end time
`total_hours` decimal(4,2) NOT NULL, -- Calculated hours (e.g., 2.50)
`total_price` decimal(10,2) NOT NULL, -- Calculated price
`status` enum('pending','confirmed','cancelled','completed') DEFAULT 'pending',
`payment_status` enum('pending','paid','refunded') DEFAULT 'pending',
`notes` text, -- Optional notes
`created_at` datetime DEFAULT CURRENT_TIMESTAMP,
`updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_user_id` (`user_id`), -- Fast user booking lookups
KEY `idx_ground_id` (`ground_id`), -- Fast ground booking lookups
KEY `idx_booking_date` (`booking_date`), -- Fast date filtering
KEY `idx_status` (`status`), -- Fast status filtering
CONSTRAINT `fk_bookings_user` FOREIGN KEY (`user_id`)
REFERENCES `example_001_users` (`id`) ON DELETE CASCADE,
CONSTRAINT `fk_bookings_ground` FOREIGN KEY (`ground_id`)
REFERENCES `example_001_grounds` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
Why This Design:
Foreign Keys: Ensure data integrity. You can't create a booking for a non-existent user
or ground. ON DELETE CASCADE means if a user is deleted, their bookings are automatically deleted too.
Separate Date and Time: Using DATE and TIME types makes it easy to query "all bookings on a date"
or "all bookings at a time" without complex string parsing.
Calculated Fields:total_hours and total_price are stored
(not calculated on-the-fly) for performance and historical accuracy (prices might change).
Status Tracking: Separate status and payment_status allow
complex booking workflows (e.g., confirmed but not yet paid).
The database was installed using a secure installation script:
Created install.sql with all table definitions
Created install.php with security key protection
Included sample data for testing
Added default admin user
Key Takeaways: Database Design
Plan First: Design your database schema before writing code
Use Appropriate Types: ENUM for fixed options, DECIMAL for money, DATE/TIME for dates
Add Indexes: Index columns you'll frequently search or sort by
Use Foreign Keys: Ensure data integrity and prevent orphaned records
Never Store Plain Text Passwords: Always use password_hash()
Think About Queries: Design your schema to make common queries fast
Current State: Database Schema Designed
Database structure is planned. The page now shows a basic search form (though not functional yet).
Sports Booking Platform
Find Your Perfect Ground
Search form added (not functional yet - database not connected)
4. Backend Implementation
Core PHP Files Created
config.php
Application configuration:
Database connection settings
Application paths and URLs
Security settings
Booking configuration
Session management
includes/db.php
Database functions with conflict prevention:
PDO connection with security options
Prepared statement execution
CRUD operations (Create, Read, Update, Delete)
Function name prefixes to avoid conflicts
File: includes/db.phpContext: Database connection and query functions
<?php
/**
* Get database connection for Example 001
* Returns a PDO connection to the database
*
* @return PDO Database connection
*/
if (!function_exists('getExampleDbConnection')) {
function getExampleDbConnection() {
static $db = null; // Static variable: connection is reused, not recreated
if ($db !== null) {
return $db; // Return existing connection
}
try {
// DSN: Data Source Name - tells PDO how to connect
$dsn = "mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=utf8mb4";
// PDO options for security and performance
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // Throw exceptions on errors
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // Return associative arrays
PDO::ATTR_EMULATE_PREPARES => false, // Use real prepared statements (security)
PDO::ATTR_TIMEOUT => 5, // 5 second connection timeout
PDO::MYSQL_ATTR_MULTI_STATEMENTS => false, // Prevent SQL injection via multiple statements
PDO::ATTR_PERSISTENT => false, // Don't use persistent connections (security)
];
$db = new PDO($dsn, DB_USER, DB_PASS, $options);
// Set strict SQL mode for data integrity
$db->exec("SET SESSION sql_mode = 'STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'");
return $db;
} catch (PDOException $e) {
// Log error with full context
logError('Database connection failed', [
'file' => __FILE__,
'class' => __CLASS__,
'function' => __FUNCTION__,
'line' => __LINE__,
'error' => $e->getMessage()
]);
die("Database connection failed. Please try again later.");
}
}
}
/**
* Execute SQL query with prepared statements
*
* @param string $sql SQL query with placeholders (? or :name)
* @param array $params Parameters to bind (prevents SQL injection)
* @return PDOStatement|false Statement object or false on failure
*/
if (!function_exists('executeExampleQuery')) {
function executeExampleQuery($sql, $params = []) {
try {
$db = getExampleDbConnection();
$stmt = $db->prepare($sql); // Prepare statement (SQL injection protection)
$stmt->execute($params); // Execute with parameters
return $stmt;
} catch (PDOException $e) {
logError('Query execution failed', [
'file' => __FILE__,
'class' => __CLASS__,
'function' => __FUNCTION__,
'line' => __LINE__,
'sql' => $sql,
'error' => $e->getMessage()
]);
return false;
}
}
}
?>
Why This Approach:
Static Connection: The static $db variable means the connection is created once
and reused. This is more efficient than creating a new connection for every query.
PDO Instead of MySQLi: PDO supports multiple database types and has better error handling.
It's also more secure by default.
Prepared Statements:prepare() and execute() prevent SQL injection.
User input is never directly inserted into SQL queries.
Error Handling: Try-catch blocks catch database errors and log them with full context
(file, function, line) for debugging.
Security Options:ATTR_EMULATE_PREPARES => false ensures real prepared statements.
MULTI_STATEMENTS => false prevents injection attacks via multiple SQL statements.
Interactive Exercise: Preventing SQL Injection
You need to query the database for a user by their ID, which comes from user input.
Which approach should you use?
❌ Why this is wrong:
CRITICAL SECURITY VULNERABILITY: Direct string concatenation allows SQL injection:
// DANGEROUS CODE - NEVER DO THIS
$id = $_GET['id'];
$sql = "SELECT * FROM users WHERE id = " . $id;
// If user sends: id=1 OR 1=1
// Query becomes: SELECT * FROM users WHERE id = 1 OR 1=1
// This returns ALL users!
Attack Example: An attacker could send id=1; DROP TABLE users;--
and delete your entire users table!
Real-world impact: This is how many websites get hacked.
Never concatenate user input into SQL queries.
❌ Why this is wrong:
INSUFFICIENT PROTECTION: Escaping helps but has problems:
Easy to forget: You must remember to escape every single user input
Not foolproof: Complex injection attacks can bypass escaping
Database-specific: Different databases need different escaping functions
Error-prone: One missed escape = security vulnerability
Better approach: Use prepared statements - they're safer and easier.
⚠️ This works, but:
Prepared statements are good, but without error handling:
Silent failures: Errors might go unnoticed
No logging: Can't track what went wrong
Poor debugging: Hard to diagnose issues in production
User experience: Users see generic errors instead of helpful messages
Better approach: Always wrap database operations in try-catch blocks with proper error logging.
✅ Perfect! Here's why:
PDO Prepared Statements:
SQL Injection Protection: Parameters are bound separately from the SQL,
making injection impossible
Type Safety: PDO automatically handles data types correctly
Performance: Prepared statements can be cached and reused
Error Handling: Try-catch blocks catch and log errors properly
How we use it:
// SECURE CODE - This is what we do
try {
$db = getExampleDbConnection();
$stmt = $db->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$userId]); // Parameter is bound safely
$user = $stmt->fetch(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
logError('Query failed', [
'file' => __FILE__,
'function' => __FUNCTION__,
'line' => __LINE__,
'error' => $e->getMessage()
]);
return false;
}
Security benefits: Even if an attacker sends malicious input like
1; DROP TABLE users;--, it's treated as a literal value, not SQL code.
The query becomes: SELECT * FROM users WHERE id = '1; DROP TABLE users;--'
(which just looks for a user with that exact ID string - which doesn't exist).
includes/functions.php
Utility functions:
Input sanitization
Email validation
Password hashing and verification
Authentication checks
CSRF token management
Theme management
Booking validation
File: includes/functions.phpContext: Input sanitization and validation functions
<?php
/**
* Sanitize input string
* Removes HTML tags and escapes special characters
*
* @param string $input Input string
* @return string Sanitized string
*/
function sanitizeInput($input) {
if (!isset($input)) {
return ''; // Return empty string if input doesn't exist
}
// strip_tags: Removes HTML/PHP tags (prevents XSS)
// trim: Removes whitespace from start/end
// htmlspecialchars: Converts special chars to HTML entities (prevents XSS)
// ENT_QUOTES: Escapes both single and double quotes
// UTF-8: Ensures proper character encoding
return htmlspecialchars(strip_tags(trim($input)), ENT_QUOTES, 'UTF-8');
}
/**
* Validate email address
* Uses PHP's built-in filter for email validation
*
* @param string $email Email address
* @return bool True if valid
*/
function validateEmail($email) {
if (!isset($email)) {
return false; // Email is required
}
// FILTER_VALIDATE_EMAIL: PHP's built-in email validator
// Returns false if invalid, email string if valid
return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
}
/**
* Hash password using bcrypt
*
* @param string $password Plain password
* @return string Hashed password
*/
function hashPassword($password) {
// PASSWORD_BCRYPT: Uses bcrypt algorithm
// Automatically generates salt
// Cost factor is 10 by default (secure and fast enough)
return password_hash($password, PASSWORD_BCRYPT);
}
/**
* Verify password against hash
*
* @param string $password Plain password
* @param string $hash Hashed password from database
* @return bool True if matches
*/
function verifyPassword($password, $hash) {
// password_verify: Safely compares plain password to hash
// Handles timing attacks (takes same time regardless of where match fails)
return password_verify($password, $hash);
}
?>
Why This Approach:
Input Sanitization:strip_tags() removes HTML/PHP tags,
htmlspecialchars() escapes special characters. This prevents XSS (Cross-Site Scripting) attacks.
Email Validation: Uses PHP's built-in FILTER_VALIDATE_EMAIL which follows
RFC 5322 standards. More reliable than regex patterns.
Password Hashing:password_hash() uses bcrypt, which is designed for passwords.
It's slow (intentionally) to make brute force attacks impractical.
Password Verification:password_verify() is timing-safe, meaning it takes
the same amount of time whether the password is wrong at the first character or the last.
This prevents timing attacks.
includes/auth.php
Authentication system:
User login with password verification
User registration with validation
Session management
Role-based access control
File: includes/auth.phpContext: User login function
<?php
/**
* Login user
*
* @param string $username Username or email
* @param string $password Password
* @return array|false User data or false on failure
*/
function loginUser($username, $password) {
try {
// Find user by username or email
// Using prepared statement to prevent SQL injection
$user = fetchOne(
"SELECT * FROM " . TABLE_PREFIX . "users WHERE (username = ? OR email = ?) AND status = 'active'",
[$username, $username] // Same value for both username and email checks
);
if (!$user) {
// Log failed login attempt (security: track brute force attempts)
logWarning('Login attempt failed - user not found', [
'file' => __FILE__,
'function' => __FUNCTION__,
'line' => __LINE__,
'username' => $username // Log username for security monitoring
]);
return false;
}
// Verify password using password_verify (compares plain text to hash)
if (!verifyPassword($password, $user['password'])) {
logWarning('Login attempt failed - invalid password', [
'file' => __FILE__,
'function' => __FUNCTION__,
'line' => __LINE__,
'user_id' => $user['id'] // Log user_id to track failed attempts per user
]);
return false;
}
// Update last login timestamp
updateData('users', ['last_login' => date('Y-m-d H:i:s')], 'id = ?', [$user['id']]);
// Set session variables (user is now logged in)
$_SESSION['user_id'] = $user['id'];
$_SESSION['username'] = $user['username'];
$_SESSION['user_role'] = $user['role'];
$_SESSION['user_email'] = $user['email'];
// Track successful login for analytics
trackUserAction('login', ['user_id' => $user['id']]);
// Log successful login
logInfo('User logged in successfully', [
'file' => __FILE__,
'function' => __FUNCTION__,
'line' => __LINE__,
'user_id' => $user['id']
]);
return $user;
} catch (Exception $e) {
// Catch any unexpected errors
logError('Login error', [
'file' => __FILE__,
'function' => __FUNCTION__,
'line' => __LINE__,
'error' => $e->getMessage()
]);
return false;
}
}
Why This Approach:
Security: Uses prepared statements to prevent SQL injection.
Passwords are verified, not compared directly.
Logging: Failed login attempts are logged to detect brute force attacks.
Successful logins are also logged for audit trails.
Session Management: Session variables are set only after successful authentication.
This prevents unauthorized access.
Error Handling: Try-catch block ensures errors are caught and logged,
not exposed to users.
Status Check: Only active users can log in. Inactive or suspended accounts are blocked.
includes/logging.php
Comprehensive logging system:
Multiple log levels
File/class/function/line tracking
Context data storage
Stack trace capture
Recursion protection
Database and file logging
includes/analytics.php
Analytics tracking:
Event tracking with context
Page view tracking
User action tracking
Booking event tracking
Search event tracking
Analytics summary generation
Current State: Backend Functions Created
Backend functions are ready. Database connection works. The page now shows a login form (not functional yet).
Prepared statements (PDO) to prevent SQL injection
CSRF token protection
Input sanitization
Session security
Role-based access control
Theme Management
4 professional themes
CSS variable-based system
Persistent theme selection
Server-side theme tracking
Seamless theme switching
Current State: Complete Application
All features are implemented. The application is fully functional with themes, analytics, admin panel, and all advanced features.
Sports Booking Platform
Find • Compare • Book
Find Your Perfect Ground
Featured
CricketMumbai
Greenfield Stadium
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Perfect for cricket matches.
₹500/hr
FootballDelhi
City Sports Complex
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Great for football practice.
₹400/hr
✓ Complete Application: All features implemented - Search, Booking, User Dashboard, Admin Panel, Analytics, Themes, and more!
7. Production Improvements
After the initial implementation, the project underwent extensive improvements to make it production-ready.
This section documents all the enhancements, security hardening, performance optimizations, and feature additions.
7.1 Security Hardening (3 Phases)
Phase 1: Critical Security & Basic Optimization
Implemented comprehensive security measures:
Error Display Disabled in Production: Environment-based error reporting prevents information leakage
Database Credentials Secured: Environment variable support for sensitive data
Secure Session Configuration: HttpOnly, Secure, SameSite cookies with session regeneration
Security Headers: Content-Security-Policy, X-Frame-Options, X-XSS-Protection, and more
Password Complexity Requirements: Minimum 8 characters with uppercase, lowercase, number, and special character
These workflow examples show you how to structure your development process when working with AI.
Use these as templates and modify them to fit your own projects.
Workflow Example 1: Initial Project Setup
This workflow shows how to start a new project from scratch:
1. Analyze Requirements
- Read user request carefully
- Identify core features
- List all entities (users, products, etc.)
- Note technology requirements
2. Plan Database Schema
- Design tables for each entity
- Define relationships (foreign keys)
- Add indexes for common queries
- Plan for future expansion
3. Plan File Structure
- Create directory structure
- Plan include files
- Plan page files
- Plan asset organization
4. Create Configuration
- Database connection settings
- Application constants
- Security settings
- Path definitions
5. Build Core Functions
- Database functions
- Authentication functions
- Utility functions
- Validation functions
6. Build Pages
- Start with simple pages
- Add functionality incrementally
- Test each page
- Fix issues immediately
7. Add Advanced Features
- Analytics
- Logging
- Admin panel
- Theme system
8. Test and Deploy
- Test all functionality
- Fix bugs
- Deploy to server
- Verify everything works
Workflow Example 2: Adding a New Feature
When adding a new feature, follow this workflow:
1. Plan the Feature
- What does it do?
- What database changes are needed?
- What pages/files need to be created/modified?
- What security considerations are there?
2. Update Database (if needed)
- Create migration SQL
- Add new tables/columns
- Add indexes
- Test migration
3. Create Backend Functions
- Database functions
- Business logic functions
- Validation functions
- Error handling
4. Create Frontend Pages
- HTML structure
- CSS styling
- JavaScript functionality
- Form validation
5. Add Security
- CSRF protection
- Input validation
- Output sanitization
- Access control
6. Add Analytics
- Track feature usage
- Track errors
- Track user interactions
7. Test Thoroughly
- Test happy path
- Test error cases
- Test edge cases
- Test security
8. Document
- Update documentation
- Add code comments
- Update changelog
Workflow Example 3: Fixing a Bug
When encountering a bug, follow this systematic approach:
1. Reproduce the Bug
- Understand what triggers it
- Note exact steps to reproduce
- Check if it's consistent
2. Check Logs
- Review system logs
- Check error logs
- Look for related errors
- Check analytics for patterns
3. Identify Root Cause
- Trace through code
- Check database queries
- Verify data integrity
- Check for edge cases
4. Plan the Fix
- What needs to change?
- Will it affect other features?
- What testing is needed?
- Are there security implications?
5. Implement Fix
- Make minimal changes
- Add error handling
- Add logging
- Add comments
6. Test the Fix
- Test the specific bug
- Test related functionality
- Test edge cases
- Regression testing
7. Deploy and Monitor
- Deploy fix
- Monitor logs
- Check analytics
- Verify user reports
Key Takeaways: Workflow Examples
Plan Before Coding: Always plan before implementing
Test Incrementally: Test as you build, not just at the end
Document Changes: Keep documentation updated
Security Always: Consider security at every step
Iterate: Build, test, improve, repeat
9. Rule Examples
These rule examples show you how to create effective rules for AI-assisted development.
Use these as templates and customize them for your projects.
Rule Example 1: Database Function Naming
When creating database functions, follow these rules:
RULE: Database Function Naming Convention
1. All database functions must use the prefix "Example" to avoid conflicts
Example: getExampleDbConnection(), executeExampleQuery()
2. Create aliases for backward compatibility
Example: function getDbConnection() { return getExampleDbConnection(); }
3. Wrap all functions in function_exists() checks
Example: if (!function_exists('getExampleDbConnection')) { ... }
4. Use descriptive names that indicate purpose
Good: fetchUserById()
Bad: getUser()
5. Include comprehensive error handling
- Try-catch blocks
- Error logging with context
- User-friendly error messages
6. Always use prepared statements
- Never concatenate user input into SQL
- Use parameter binding
- Validate input before queries
Rule Example 2: Security Requirements
Security rules that must be followed:
RULE: Security Requirements
1. Password Storage
- MUST use password_hash() with PASSWORD_BCRYPT
- NEVER store plain text passwords
- NEVER use MD5 or SHA1 for passwords
2. SQL Queries
- MUST use prepared statements
- NEVER concatenate user input into SQL
- ALWAYS validate input before queries
3. Input Sanitization
- ALL user input must be sanitized
- Use htmlspecialchars() for output
- Use strip_tags() to remove HTML
4. CSRF Protection
- ALL forms must have CSRF tokens
- Tokens must be verified on submission
- Tokens must be unique per session
5. Session Security
- HttpOnly cookies
- Secure flag (HTTPS only)
- SameSite=Strict
- Session regeneration on login
6. Error Handling
- NEVER display errors to users in production
- Log all errors with full context
- Use try-catch blocks everywhere
Rule Example 3: Code Organization
Rules for organizing code:
RULE: Code Organization
1. File Structure
- Keep related files together
- Use descriptive directory names
- Separate concerns (admin, api, assets, includes)
2. Function Organization
- Group related functions together
- Use descriptive function names
- Include PHPDoc comments
3. Include Files
- config.php: Configuration only
- includes/db.php: Database functions only
- includes/auth.php: Authentication only
- includes/functions.php: Utility functions
4. Naming Conventions
- Functions: camelCase
- Constants: UPPER_SNAKE_CASE
- Variables: camelCase
- Classes: PascalCase
5. Code Comments
- Explain WHY, not WHAT
- Include parameter descriptions
- Include return value descriptions
- Document complex logic
Rule Example 4: Error Handling
Comprehensive error handling rules:
RULE: Error Handling Requirements
1. All Functions Must Have Error Handling
- Try-catch blocks for database operations
- Try-catch blocks for file operations
- Validation before processing
2. Error Logging
- Log ALL errors with context:
* File name
* Function name
* Line number
* Error message
* Stack trace (for exceptions)
* User ID (if available)
* Session ID
* IP address
3. User-Facing Errors
- Generic messages in production
- Detailed messages in development
- Never expose system details
- Provide helpful guidance
4. Error Recovery
- Graceful degradation
- Fallback options
- User-friendly messages
- Log for debugging
Key Takeaways: Rule Examples
Be Specific: Clear rules lead to better code
Be Consistent: Follow the same patterns throughout
Document Rules: Write down your rules for reference
Enforce Rules: Review code against rules
Update Rules: Refine rules as you learn
10. Planning Guide
This planning guide provides templates and examples for planning your own projects.
Use these as starting points and customize them to your needs.
DATABASE SCHEMA DESIGN
Project: [Project Name]
1. TABLES NEEDED
Table: [table_name]
Purpose: [What it stores]
Columns:
- id: INT PRIMARY KEY AUTO_INCREMENT
- [column_name]: [type] [constraints] -- [description]
- [column_name]: [type] [constraints] -- [description]
Indexes:
- [index_name] on ([columns])
Foreign Keys:
- [fk_name]: [column] REFERENCES [table]([column])
Relationships:
- One-to-many with [table]
- Many-to-many with [table] via [junction_table]
2. DATA TYPES
- Strings: VARCHAR(length) for short text, TEXT for long text
- Numbers: INT for integers, DECIMAL(10,2) for money
- Dates: DATE for dates, TIME for times, DATETIME for timestamps
- Booleans: TINYINT(1) or ENUM('yes','no')
- Enums: ENUM('value1','value2') for fixed options
3. INDEXES
- Primary keys: Always indexed
- Foreign keys: Always indexed
- Frequently searched columns: Add indexes
- Frequently sorted columns: Add indexes
4. CONSTRAINTS
- UNIQUE: For columns that must be unique
- NOT NULL: For required fields
- DEFAULT: For optional fields with defaults
- CHECK: For value range validation (if supported)
SECURITY CHECKLIST
Authentication:
[ ] Password hashing (bcrypt)
[ ] Password complexity requirements
[ ] Account lockout mechanism
[ ] Rate limiting on login
[ ] Session security (HttpOnly, Secure, SameSite)
[ ] Session regeneration on login
[ ] Password reset functionality
Input Validation:
[ ] All user input sanitized
[ ] Email validation
[ ] Phone number validation
[ ] File upload validation
[ ] Whitelist validation for known good values
SQL Security:
[ ] All queries use prepared statements
[ ] No string concatenation in SQL
[ ] Parameter binding for all user input
[ ] Error handling for database operations
Output Security:
[ ] All output escaped (htmlspecialchars)
[ ] XSS protection
[ ] Content Security Policy headers
[ ] X-Frame-Options header
CSRF Protection:
[ ] All forms have CSRF tokens
[ ] Tokens verified on submission
[ ] Tokens unique per session
Access Control:
[ ] Role-based access control
[ ] Admin pages protected
[ ] User data access restricted
[ ] API authentication (if needed)
Error Handling:
[ ] Errors not displayed to users in production
[ ] Comprehensive error logging
[ ] Stack traces logged (not displayed)
[ ] User-friendly error messages
Key Takeaways: Planning Guide
Use Templates: Start with templates, customize as needed
Be Thorough: Plan everything before coding
Think Ahead: Consider future expansion
Document Plans: Write down your plans for reference
Review Plans: Review and refine plans before starting
11. AI Agent Simulation
This interactive simulation lets you experience building the app step-by-step, just like working with an AI agent.
You'll make choices at each step and see the results, learning what works and what doesn't.
AI Agent Simulator
Experience building the app step-by-step with AI assistance
AI Agent: Ready to help you build your web application!
AI Agent: Let's start by understanding your requirements...
Key Takeaways: AI Agent Simulation
Learn from Mistakes: Wrong answers teach you what to avoid
Understand Why: Each answer explains the reasoning
See Results: Visual feedback shows the impact of choices
Practice: Try different scenarios to build understanding
Apply Learning: Use these lessons in your own projects
12. Testing & Deployment
Development Process
Local Development: Created all files locally
Syntax Validation: Checked all PHP files for syntax errors
Conflict Resolution: Fixed function name conflicts with main project
FTP Upload: Uploaded all files to server
Web Testing: Tested all pages via web requests
Database Installation: Created and tested installation script
Issues Encountered & Fixed
Issue 1: Function Name Conflicts
Problem: Main project had functions with same names (getDbConnection, getSetting, etc.)
Solution: Renamed functions with "Example" prefix and created aliases for backward compatibility
Issue 2: Constant Conflicts
Problem: Constants already defined in main project config
Solution: Added if (!defined()) checks before defining constants
Issue 3: Memory Exhaustion
Problem: Logging system caused infinite recursion
Solution: Added recursion protection flag in logging functions
Issue 4: Database Transaction Errors
Problem: Installation script had transaction issues
Error Handling: Comprehensive error tracking with context
Code Organization: Logical file structure and separation of concerns
Documentation: Comments and documentation throughout
User Experience: Responsive design, intuitive navigation
What Makes This Project Special
Complete implementation from scratch
No frameworks - pure vanilla code for learning
Comprehensive error handling and logging
Professional design with theme management
Full analytics and admin dashboard
Well-documented for teaching purposes
Next Steps for Learners
Study the code structure
Understand the database design
Review the error handling patterns
Examine the theme system
Try modifying features
Add new functionality
Build your own version
Conclusion
This project demonstrates that with clear requirements and AI assistance, you can build a complete,
functional web application from scratch. The key is to break down the project into manageable steps,
test frequently, and iterate based on results.
Every aspect of this application was built systematically, from database design to final deployment.
The code is well-organized, secure, and follows best practices.
We use cookies to enhance your browsing experience, analyze site traffic, and personalize content. By clicking "Accept All", you consent to our use of cookies. Learn more