Files
Fire-alarm-managment/DEVELOPMENT.md
2026-01-19 21:57:25 -05:00

9.3 KiB

Development Guide

This guide covers the architecture, code organization, and contribution guidelines for the Romanoff Fire Alarm Management System.

Architecture Overview

Application Structure

romanoff/
├── run.py                 # Entry point - starts Flask dev server
├── import_data.py         # Data import utility
├── requirements.txt       # Dependencies
├── app/
│   ├── __init__.py        # Flask app factory
│   ├── models.py          # SQLAlchemy models
│   ├── routes.py          # Web routes & API endpoints
│   ├── templates/         # Jinja2 templates
│   └── static/            # CSS, JavaScript assets
└── instance/              # SQLite database (auto-created)

Design Patterns

Flask App Factory

The application uses the factory pattern in app/__init__.py:

def create_app():
    app = Flask(__name__)
    # Configure app
    db.init_app(app)
    # Register blueprints
    app.register_blueprint(main_bp)
    app.register_blueprint(api_bp, url_prefix='/api')
    return app

Blueprint Organization

Routes are organized into two blueprints:

  • main_bp - Web routes serving HTML pages
  • api_bp - REST API endpoints (prefixed with /api)

Model-View Separation

  • Models (models.py) handle data persistence
  • Routes (routes.py) handle request/response logic
  • Templates (templates/) handle presentation

Data Flow

User Browser
     ↓
Flask Routes (routes.py)
     ↓
SQLAlchemy Models (models.py)
     ↓
SQLite Database (instance/romanoff.db)

Database Schema

Entity Relationship

┌─────────────┐
│    Job      │
├─────────────┤
│ id (PK)     │
│ job_number  │───────┐
│ job_name    │       │
│ ...         │       │
└─────────────┘       │
       │              │
       │ 1:N          │ 1:N
       ↓              ↓
┌─────────────┐ ┌─────────────┐
│   Phase     │ │  Material   │
├─────────────┤ ├─────────────┤
│ id (PK)     │ │ id (PK)     │
│ job_id (FK) │ │ job_id (FK) │
│ phase_type  │ │ part_number │
│ ...         │ │ ...         │
└─────────────┘ └─────────────┘

Models

Job - Core project entity

  • Contains budget, team assignments, milestones, dates
  • Has many phases and materials (cascade delete)

Phase - Project schedule phases

  • Types: rough_in, trim, commissioning, final, turnover
  • Tracks dates, completion status, man hours

Material - Inventory tracking

  • Tracks ordering, receipt, and delivery

Frontend Architecture

Template Hierarchy

base.html
├── dashboard.html    - Charts and statistics
├── jobs.html         - Job list with filters
├── job_detail.html   - Single job view
├── job_form.html     - Create/edit job
├── schedule.html     - Phase management
└── materials.html    - Material tracking

JavaScript Strategy

Shared Utilities (static/js/app.js)

// API helpers
async function apiGet(url) { ... }
async function apiPost(url, data) { ... }
async function apiPut(url, data) { ... }
async function apiDelete(url) { ... }

// Formatting
function formatCurrency(value) { ... }
function formatDate(dateString) { ... }

// UI helpers
function showToast(message, type) { ... }
function getProgressClass(percent) { ... }
function debounce(func, wait) { ... }
function confirmAction(message) { ... }

Page-Specific Scripts

Each template contains embedded <script> blocks for page-specific functionality:

  • Data fetching and rendering
  • Event handlers
  • Filter/search logic

CSS Organization

Bootstrap 5 provides the base styling. Custom styles in static/css/style.css add:

  • Card shadows and hover effects
  • Progress bar color states
  • Responsive table adjustments
  • Form styling enhancements

Development Setup

Prerequisites

  • Python 3.8+
  • pip

Local Development

  1. Create virtual environment:

    python -m venv .venv
    source .venv/bin/activate
    
  2. Install dependencies:

    pip install -r requirements.txt
    
  3. Run development server:

    python run.py
    
  4. Access at http://localhost:5000

Database

The SQLite database is automatically created on first run in instance/romanoff.db. Tables are created via db.create_all() in the app factory.

To reset the database:

rm instance/romanoff.db
python run.py

Importing Test Data

python import_data.py

Imports from Excel files (if present):

  • Raleigh jobs FIRE ALARM INFORMATION.xlsx
  • schedule_updated.xlsm

Code Guidelines

Python Style

  • Follow PEP 8 style guidelines
  • Use type hints where helpful
  • Keep functions focused and small
  • Document complex logic with comments

Database Operations

# Reading data
jobs = Job.query.all()
job = Job.query.get_or_404(job_id)

# Creating records
job = Job(job_number='JOB-001', job_name='New Job')
db.session.add(job)
db.session.commit()

# Updating records
job.percent_complete = 0.5
db.session.commit()

# Deleting records
db.session.delete(job)
db.session.commit()

API Response Patterns

# Success with data
return jsonify(job.to_dict())

# Success with created resource
return jsonify(job.to_dict()), 201

# Success with no content
return '', 204

# Error
return jsonify({'error': 'Not found'}), 404

Frontend JavaScript

// Fetch pattern
try {
  const data = await apiGet('/api/jobs');
  renderJobs(data);
} catch (error) {
  showToast('Error loading jobs', 'danger');
}

// Event handling
document.getElementById('searchInput')
  .addEventListener('input', debounce(filterJobs, 300));

Adding New Features

Adding a New Model

  1. Define model in models.py:

    class NewModel(db.Model):
        __tablename__ = 'new_models'
        id = db.Column(db.Integer, primary_key=True)
        # ... fields
    
        def to_dict(self):
            return { ... }
    
  2. Add API routes in routes.py

  3. Create template if needed

  4. Restart server (tables auto-create)

Adding a New Page

  1. Create template in templates/
  2. Add web route in routes.py:
    @main_bp.route('/newpage')
    def new_page():
        return render_template('newpage.html')
    
  3. Add navigation link in base.html

Adding API Endpoints

  1. Add route function in routes.py:

    @api_bp.route('/newresource', methods=['GET'])
    def get_new_resource():
        # ... logic
        return jsonify(data)
    
  2. Document in API.md

Testing

Currently no automated tests are implemented. Recommended testing approach:

Manual Testing

  • Test all CRUD operations through UI
  • Verify API responses with curl or Postman
  • Test edge cases (empty data, invalid input)

Future Testing Setup

pip install pytest pytest-flask
# tests/test_api.py
def test_get_jobs(client):
    response = client.get('/api/jobs')
    assert response.status_code == 200

Deployment Considerations

Production Checklist

  • Set SECRET_KEY environment variable
  • Configure production database (PostgreSQL recommended)
  • Use production WSGI server (Gunicorn, uWSGI)
  • Enable HTTPS
  • Add authentication/authorization
  • Configure logging
  • Set up database backups

Environment Variables

Variable Description Required
SECRET_KEY Flask secret key Yes
DATABASE_URL Database connection string No (defaults to SQLite)

Example Production Config

# config.py
import os

class ProductionConfig:
    SECRET_KEY = os.environ['SECRET_KEY']
    SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL')
    SQLALCHEMY_TRACK_MODIFICATIONS = False

Contributing

Workflow

  1. Create a feature branch from main
  2. Make changes following code guidelines
  3. Test thoroughly
  4. Submit pull request with description

Commit Messages

Use clear, descriptive commit messages:

  • Add material delivery tracking feature
  • Fix job completion percentage calculation
  • Update dashboard chart colors

Code Review

Before merging:

  • Code follows style guidelines
  • No obvious bugs or security issues
  • Documentation updated if needed
  • Changes tested manually

Troubleshooting

Common Issues

Database locked error

  • Stop any other processes accessing the database
  • Delete .db file and restart if corrupted

Import errors

  • Ensure virtual environment is activated
  • Run pip install -r requirements.txt

Template not found

  • Check file name matches route
  • Verify file is in templates/ directory

API returns 404

  • Check URL matches route definition
  • Verify blueprint prefix (/api)

Debug Mode

Debug mode is enabled by default in development. Check Flask output for:

  • Request/response logging
  • SQL queries (if enabled)
  • Stack traces on errors

Resources