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

418 lines
9.3 KiB
Markdown

# 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`:
```python
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`)
```javascript
// 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:
```bash
python -m venv .venv
source .venv/bin/activate
```
2. Install dependencies:
```bash
pip install -r requirements.txt
```
3. Run development server:
```bash
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:
```bash
rm instance/romanoff.db
python run.py
```
### Importing Test Data
```bash
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
```python
# 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
```python
# 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
```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`:
```python
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`:
```python
@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`:
```python
@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
```bash
pip install pytest pytest-flask
```
```python
# 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
```python
# 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
- [Flask Documentation](https://flask.palletsprojects.com/)
- [SQLAlchemy Documentation](https://docs.sqlalchemy.org/)
- [Bootstrap 5 Documentation](https://getbootstrap.com/docs/5.3/)
- [Chart.js Documentation](https://www.chartjs.org/docs/)