DEVELOPMENT STANDARDS - AI PROMPT

PURPOSE OF THIS AI PROMPT

What This Document Does

The Debugging Reality

Why These Standards Matter

CRITICAL REQUIREMENTS - ALL MANDATORY
ERROR HANDLING AND CHANGE LOGS ARE NON-NEGOTIABLE
FILE LENGTH LIMITS ARE HARD LIMITS - CODE OVER 300 LINES WILL BE REJECTED

FILE LENGTH LIMITS (ABSOLUTELY MANDATORY)

Maximum File Sizes - NO EXCEPTIONS

Why 300 Lines Maximum

PYTHON CODING STANDARDS (CRITICAL)

NO CLASSES RULE

INDENTATION REQUIREMENTS

EARLY RETURN PATTERN (REQUIRED)

def good_function(user_id):
    if not user_id:
        print("ERROR: good_function - Missing user_id")
        return None
        
    conn = get_connection()
    if not conn:
        print("ERROR: good_function - No database connection")
        return None
        
    cur = conn.cursor()
    if not cur:
        print("ERROR: good_function - No cursor")
        return None
        
    cur.execute("SELECT * FROM users WHERE id = %s", (user_id,))
    result = cur.fetchone()
    
    if not result:
        print("ERROR: good_function - User not found")
        return None
        
    print("DEBUG: good_function - User found")
    return result

ERROR HANDLING REQUIREMENTS (NON-NEGOTIABLE)

ERROR HANDLING TEMPLATE - USE THIS PATTERN

def example_function_with_mandatory_error_handling():
    """
    MANDATORY ERROR HANDLING PATTERN
    Copy this pattern for every function in this module
    """
    # 1. Initialize all variables that need cleanup
    conn = None
    cur = None
    
    try:
        # 2. Add debug print at function start
        print(f"DEBUG: function_name - Starting at {datetime.now()}")
        
        # 3. Validate all inputs FIRST
        if not valid_input:
            print(f"ERROR: function_name - Invalid input: {input_value}")
            return default_value
        
        # 4. Get database connection
        conn = get_db_connection()
        if not conn:
            print(f"ERROR: function_name - Failed to get database connection")
            return default_value
            
        # 5. Your database operations here
        cur = conn.cursor(dictionary=True)
        # ... database operations ...
        
        # 6. Success debug message
        print(f"DEBUG: function_name - Operation successful")
        return result
        
    except MySQLError as e:
        # 7. Handle database-specific errors
        print(f"ERROR: function_name - MySQL error: {e}")
        if conn:
            conn.rollback()
        return default_value
        
    except Exception as e:
        # 8. Handle all other errors
        print(f"ERROR: function_name - Unexpected error: {e}")
        print(f"ERROR: function_name - Traceback: {traceback.format_exc()}")
        if conn:
            conn.rollback()
        return default_value
        
    finally:
        # 9. ALWAYS clean up resources
        if cur:
            cur.close()
            print(f"DEBUG: function_name - Database cursor closed")
        if conn:
            conn.close()
            print(f"DEBUG: function_name - Database connection closed")
        print(f"DEBUG: function_name - Function completed at {datetime.now()}")

CHANGE LOG REQUIREMENTS (MANDATORY FOR ALL FILES)

PURPOSE OF CHANGE LOGS

CHANGE LOG REQUIREMENTS

FILE NAMING CONVENTIONS

CHANGE LOG TEMPLATE FOR HTML FILES

<!--
CHANGE LOG
File: /templates/login.html
Document Type: HTML Template
Purpose: User login form with 2FA photo upload for area mapping system
Main App: area_mapping_app.py
Blueprint: auth_blueprint.py
Route: /login
Context: Federal grant application requires secure user authentication with photo verification
JavaScript Orchestrator: login-handler.js
CSS Dependencies: login.css
Version History:
2025-07-04 v1.1 - Added 2FA photo upload functionality for grant compliance
2025-07-01 v1.0 - Initial creation
-->

CHANGE LOG TEMPLATE FOR PYTHON FILES

# CHANGE LOG
# File: /routes/auth_blueprint.py
# Document Type: Flask Blueprint
# Purpose: Authentication routes for login/register with 2FA photo verification
# Main App: area_mapping_app.py
# Blueprint: auth_blueprint.py (this file)
# Routes: /login, /register, /logout
# Context: Secure authentication system for area mapping to support federal grant applications
# Dependencies: flask, bcrypt, mysql.connector, utils.image_processing
# Related Templates: login.html, register.html
# Version History:
# 2025-07-04 v1.1 - Added photo hash verification for enhanced security
# 2025-07-01 v1.0 - Initial creation

CHANGE LOG TEMPLATE FOR JAVASCRIPT FILES

/*
CHANGE LOG
File: /static/js/login-handler.js
Document Type: JavaScript Module (Orchestrator)
Purpose: Orchestrates login form submission and 2FA photo handling
Main App: area_mapping_app.py
Blueprint: auth_blueprint.py
Route: /login
Context: Handles client-side photo compression and form submission for secure authentication
Orchestrator Role: Coordinates photo-compression.js and login-api.js modules
HTML Template: login.html
Dependencies: photo-compression.js, login-api.js
Version History:
2025-07-04 v1.1 - Added photo compression integration
2025-07-01 v1.0 - Initial creation
*/

CHANGE LOG TEMPLATE FOR CSS FILES

/*
CHANGE LOG
File: /static/css/login.css
Document Type: CSS Stylesheet
Purpose: Styling for login and registration forms in area mapping system
Main App: area_mapping_app.py
Blueprint: auth_blueprint.py
Routes: /login, /register
Context: Simple black and white styling for professional appearance in grant documentation
HTML Templates: login.html, register.html
Dependencies: None
Version History:
2025-07-04 v1.1 - Added photo upload styling
2025-07-01 v1.0 - Initial creation
*/

INFORMATION GATHERING REQUIREMENTS (MANDATORY)

ASK FIRST - CODE SECOND

REQUIRED INFORMATION BEFORE CODING

SMART QUESTIONING PATTERN

MANDATORY: ASK BEFORE CODING
When information is missing or unclear - ASK FIRST
Never guess or assume - get exact specifications
"Don't do any coding yet" means STOP and gather information

ENDPOINT AND ROUTE ACCURACY

VARIABLE AND FUNCTION NAMING

AI HALLUCINATION PREVENTION

CRITICAL: ENDPOINT ACCURACY
Using wrong endpoint names causes hours of debugging
Always use EXACT routes and naming as provided
Never assume or "improve" naming conventions

MANDATORY RULES - NO EXCEPTIONS

COMPLEXITY EXAMPLES TO AVOID

SIMPLE EXAMPLES TO FOLLOW

FINAL CHECKLIST FOR EVERY FILE

PROJECT REFERENCE GENERATOR SCRIPT

PURPOSE

WHAT IT EXTRACTS

OUTPUT FORMAT EXAMPLE

=== PYTHON ROUTES ===
/routes/auth_blueprint.py:23: @blueprint.route('/login', methods=['POST'])
/routes/auth_blueprint.py:45: @blueprint.route('/upload-photos', methods=['POST'])
/routes/mapping_blueprint.py:12: @blueprint.route('/save-mapping', methods=['POST'])

=== PYTHON FUNCTIONS ===
/utils/auth_helpers.py:15: def login_user(email, password):
/utils/image_processing.py:8: def compress_image(file):
/routes/auth_blueprint.py:67: def verify_photo_hash(uploaded, stored):

=== JAVASCRIPT FUNCTIONS ===
/static/js/login-handler.js:23: function handlePhotoUpload() {
/static/js/login-api.js:15: function submitLoginForm(data) {
/static/js/photo-compression.js:8: function compressImage(file) {

=== AJAX ENDPOINTS ===
/static/js/login-api.js:25: fetch('/login', {
/static/js/photo-upload.js:12: fetch('/upload-photos', {
/static/js/mapping-api.js:18: fetch('/save-mapping', {

USAGE

SCRIPT TEMPLATE

# CHANGE LOG
# File: /endpoints.py
# Document Type: Python Utility Script
# Purpose: Extract all routes, functions, and AJAX calls from project files recursively
# Main App: Any Flask project (portable script)
# Dependencies: pathlib, re, os, datetime
# Context: Creates complete project reference for AI assistants to prevent endpoint mismatches
# Version History:
# 2025-07-04 v1.1 - Fixed virtual environment scanning, suppressed zero results, show actual endpoints
# 2025-07-04 v1.0 - Initial creation with full error handling and extraction logic

#!/usr/bin/env python3
"""
Project Reference Generator
Drop in project root and run to extract all callable items
Creates project_reference.txt with complete API/function inventory
"""

import os
import re
import traceback
from pathlib import Path
from datetime import datetime

def extract_python_routes(file_path):
    """
    Extract @app.route and @blueprint.route decorators from Python file
    """
    routes = []
    
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            lines = f.readlines()
            
        for line_num, line in enumerate(lines, 1):
            line = line.strip()
            
            # Match @app.route or @blueprint.route patterns
            route_pattern = r'@(?:app|blueprint|[\w_]+)\.route\([\'"]([^\'"]+)[\'"](?:.*methods\s*=\s*\[(.*?)\])?.*\)'
            match = re.search(route_pattern, line)
            
            if match:
                route_path = match.group(1)
                methods = match.group(2) if match.group(2) else 'GET'
                routes.append(f"{file_path}:{line_num}: @route('{route_path}', methods=[{methods}])")
                
        # Only show debug message if routes found
        if routes:
            print(f"DEBUG: extract_python_routes - Found {len(routes)} routes in {file_path}")
        return routes
        
    except FileNotFoundError:
        print(f"ERROR: extract_python_routes - File not found: {file_path}")
        return []
    except UnicodeDecodeError:
        print(f"ERROR: extract_python_routes - Cannot decode file: {file_path}")
        return []
    except Exception as e:
        print(f"ERROR: extract_python_routes - Error processing {file_path}: {e}")
        print(f"ERROR: extract_python_routes - Traceback: {traceback.format_exc()}")
        return []

def extract_python_functions(file_path):
    """
    Extract function definitions from Python file
    """
    functions = []
    
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            lines = f.readlines()
            
        for line_num, line in enumerate(lines, 1):
            line = line.strip()
            
            # Match function definitions
            func_pattern = r'^def\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*\('
            match = re.match(func_pattern, line)
            
            if match:
                func_name = match.group(1)
                # Skip private functions starting with _
                if not func_name.startswith('_'):
                    functions.append(f"{file_path}:{line_num}: def {func_name}()")
                    
        # Only show debug message if functions found
        if functions:
            print(f"DEBUG: extract_python_functions - Found {len(functions)} functions in {file_path}")
        return functions
        
    except FileNotFoundError:
        print(f"ERROR: extract_python_functions - File not found: {file_path}")
        return []
    except UnicodeDecodeError:
        print(f"ERROR: extract_python_functions - Cannot decode file: {file_path}")
        return []
    except Exception as e:
        print(f"ERROR: extract_python_functions - Error processing {file_path}: {e}")
        print(f"ERROR: extract_python_functions - Traceback: {traceback.format_exc()}")
        return []

def extract_javascript_functions(file_path):
    """
    Extract JavaScript function declarations and assignments
    """
    functions = []
    
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            lines = f.readlines()
            
        for line_num, line in enumerate(lines, 1):
            line = line.strip()
            
            # Match function declarations
            func_patterns = [
                r'function\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*\(',
                r'const\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*function',
                r'let\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*function',
                r'var\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*function',
                r'const\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*\(',
                r'([a-zA-Z_][a-zA-Z0-9_]*)\s*:\s*function\s*\('
            ]
            
            for pattern in func_patterns:
                match = re.search(pattern, line)
                if match:
                    func_name = match.group(1)
                    functions.append(f"{file_path}:{line_num}: function {func_name}()")
                    break
                    
        # Only show debug message if functions found
        if functions:
            print(f"DEBUG: extract_javascript_functions - Found {len(functions)} functions in {file_path}")
        return functions
        
    except FileNotFoundError:
        print(f"ERROR: extract_javascript_functions - File not found: {file_path}")
        return []
    except UnicodeDecodeError:
        print(f"ERROR: extract_javascript_functions - Cannot decode file: {file_path}")
        return []
    except Exception as e:
        print(f"ERROR: extract_javascript_functions - Error processing {file_path}: {e}")
        print(f"ERROR: extract_javascript_functions - Traceback: {traceback.format_exc()}")
        return []

def extract_ajax_calls(file_path):
    """
    Extract AJAX calls and fetch requests from JavaScript files
    """
    ajax_calls = []
    
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            lines = f.readlines()
            
        for line_num, line in enumerate(lines, 1):
            line = line.strip()
            
            # Match fetch() calls and similar AJAX patterns
            ajax_patterns = [
                r'fetch\s*\(\s*[\'"]([^\'"]+)[\'"]',
                r'\.get\s*\(\s*[\'"]([^\'"]+)[\'"]',
                r'\.post\s*\(\s*[\'"]([^\'"]+)[\'"]',
                r'\.put\s*\(\s*[\'"]([^\'"]+)[\'"]',
                r'\.delete\s*\(\s*[\'"]([^\'"]+)[\'"]',
                r'XMLHttpRequest.*open\s*\(\s*[\'"][A-Z]+[\'"],\s*[\'"]([^\'"]+)[\'"]'
            ]
            
            for pattern in ajax_patterns:
                match = re.search(pattern, line)
                if match:
                    endpoint = match.group(1)
                    ajax_calls.append(f"{file_path}:{line_num}: AJAX call to '{endpoint}'")
                    break
                    
        # Only show debug message if AJAX calls found
        if ajax_calls:
            print(f"DEBUG: extract_ajax_calls - Found {len(ajax_calls)} AJAX calls in {file_path}")
        return ajax_calls
        
    except FileNotFoundError:
        print(f"ERROR: extract_ajax_calls - File not found: {file_path}")
        return []
    except UnicodeDecodeError:
        print(f"ERROR: extract_ajax_calls - Cannot decode file: {file_path}")
        return []
    except Exception as e:
        print(f"ERROR: extract_ajax_calls - Error processing {file_path}: {e}")
        print(f"ERROR: extract_ajax_calls - Traceback: {traceback.format_exc()}")
        return []

def extract_project_reference():
    """
    Main function to recursively scan project and extract all callable items
    """
    output_file = None
    
    try:
        print(f"DEBUG: extract_project_reference - Starting at {datetime.now()}")
        
        # Validate current directory
        if not os.path.exists('.'):
            print("ERROR: extract_project_reference - Current directory not accessible")
            return False
            
        # File patterns to scan - exclude virtual environments and common non-project directories
        python_files = []
        js_files = []
        
        # Get all Python and JS files while excluding unwanted directories
        for py_file in Path('.').rglob('*.py'):
            if not any(pattern in str(py_file) for pattern in ['venv', 'env', '.git', '__pycache__', 'build', 'dist', '.egg-info']):
                python_files.append(py_file)
                
        for js_file in Path('.').rglob('*.js'):
            if not any(pattern in str(js_file) for pattern in ['venv', 'env', '.git', 'node_modules', 'build', 'dist']):
                js_files.append(js_file)
        
        print(f"DEBUG: extract_project_reference - Found {len(python_files)} Python files")
        print(f"DEBUG: extract_project_reference - Found {len(js_files)} JavaScript files")
        
        if not python_files and not js_files:
            print("ERROR: extract_project_reference - No Python or JavaScript files found")
            return False
        
        results = []
        
        # Add header with timestamp
        results.append("=" * 60)
        results.append(f"PROJECT REFERENCE GENERATED: {datetime.now()}")
        results.append("=" * 60)
        results.append("")
        
        # Extract Python routes and show them immediately
        print("\n=== EXTRACTING PYTHON ROUTES ===")
        results.append("=== PYTHON ROUTES ===")
        route_count = 0
        for py_file in python_files:
            routes = extract_python_routes(py_file)
            if routes:
                for route in routes:
                    print(route)  # Show route immediately
                    results.append(route)
                route_count += len(routes)
        results.append(f"Total routes found: {route_count}")
        results.append("")
        
        # Extract Python functions
        print(f"\n=== EXTRACTING PYTHON FUNCTIONS ===")
        results.append("=== PYTHON FUNCTIONS ===")
        func_count = 0
        for py_file in python_files:
            functions = extract_python_functions(py_file)
            results.extend(functions)
            func_count += len(functions)
        results.append(f"Total functions found: {func_count}")
        results.append("")
        
        # Extract JavaScript functions
        print(f"\n=== EXTRACTING JAVASCRIPT FUNCTIONS ===")
        results.append("=== JAVASCRIPT FUNCTIONS ===")
        js_func_count = 0
        for js_file in js_files:
            js_functions = extract_javascript_functions(js_file)
            results.extend(js_functions)
            js_func_count += len(js_functions)
        results.append(f"Total JavaScript functions found: {js_func_count}")
        results.append("")
        
        # Extract AJAX calls and show them immediately
        print(f"\n=== EXTRACTING AJAX ENDPOINTS ===")
        results.append("=== AJAX ENDPOINTS ===")
        ajax_count = 0
        for js_file in js_files:
            ajax_calls = extract_ajax_calls(js_file)
            if ajax_calls:
                for ajax in ajax_calls:
                    print(ajax)  # Show AJAX call immediately
                    results.append(ajax)
                ajax_count += len(ajax_calls)
        results.append(f"Total AJAX calls found: {ajax_count}")
        results.append("")
        
        # Write to project_reference.txt
        output_file = open('project_reference.txt', 'w', encoding='utf-8')
        output_file.write('\n'.join(results))
        
        total_items = route_count + func_count + js_func_count + ajax_count
        print(f"DEBUG: extract_project_reference - Generated project_reference.txt with {total_items} items")
        print(f"DEBUG: extract_project_reference - Routes: {route_count}, Functions: {func_count}, JS Functions: {js_func_count}, AJAX: {ajax_count}")
        
        return True
        
    except PermissionError:
        print("ERROR: extract_project_reference - Permission denied writing project_reference.txt")
        return False
    except Exception as e:
        print(f"ERROR: extract_project_reference - Unexpected error: {e}")
        print(f"ERROR: extract_project_reference - Traceback: {traceback.format_exc()}")
        return False
        
    finally:
        if output_file:
            output_file.close()
            print("DEBUG: extract_project_reference - Output file closed")
        print(f"DEBUG: extract_project_reference - Function completed at {datetime.now()}")

if __name__ == '__main__':
    print("=" * 60)
    print("PROJECT REFERENCE EXTRACTOR")
    print("Scanning project for routes, functions, and AJAX calls...")
    print("=" * 60)
    
    success = extract_project_reference()
    
    if success:
        print("\nSUCCESS: project_reference.txt created!")
        print("Copy the contents to your AI assistant for complete project context.")
    else:
        print("\nFAILED: Could not generate project reference.")
        print("Check error messages above for details.")
AI ASSISTANT BENEFIT:
When user provides project_reference.txt content, AI has complete context
No more guessing endpoint names or function signatures
Debugging becomes nearly instantaneous with full project inventory
REMINDERS:
Change logs MUST be visible in browser view-source
NO hidden characters or formatting that browsers can't display
Include ALL relevant information for troubleshooting
Both error handling AND change logs are MANDATORY
SIMPLICITY OVER CLEVERNESS - Simple code is maintainable code