Balanced Engineering Platform¶
Archived — describes the retired v1
This document describes the first-generation Balanced Engineering
Platform (Flask / SQLAlchemy / SQLite), which has been retired. The
current platform is the Rust / Rocket app under apps/be-platform.
Kept for historical reference only — do not treat as current design.
Project Overview¶
Balanced Engineering Platform is a comprehensive web application designed for civil engineering materials testing firms. It provides end-to-end management of projects, field work, lab testing, reporting, and staff scheduling for geotechnical and materials testing operations.
The platform supports the complete workflow from project intake through final report delivery, including: - Project and client management - Material test tracking and scheduling - Field work session coordination - Lab work scheduling and test assignment - Report generation and delivery - Staff scheduling and availability management - Invoice and billing workflows
Architecture¶
┌─────────────────────────────────────────────────────────────────────────────┐
│ Web Browser │
│ (Bootstrap 5 + Jinja2) │
└─────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ Flask Application │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Auth │ │ Projects │ │ Lab │ │ Reporting │ │
│ │ Blueprint │ │ Blueprint │ │ Blueprint │ │ Blueprint │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Clients │ │ Admin │ │ Main │ │ API │ │
│ │ Blueprint │ │ Blueprint │ │ Blueprint │ │ Blueprint │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ SQLAlchemy ORM │
│ (Models, Relationships, Queries) │
└─────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ SQLite Database │
│ (Development - PostgreSQL recommended for production) │
└─────────────────────────────────────────────────────────────────────────────┘
Tech Stack¶
| Layer | Technology |
|---|---|
| Backend Framework | Flask 2.x with Blueprints |
| Database ORM | SQLAlchemy with Flask-SQLAlchemy |
| Authentication | Flask-Login with bcrypt password hashing |
| Database | SQLite (dev) / PostgreSQL (production) |
| Frontend | Bootstrap 5, Jinja2 templates |
| Icons | Bootstrap Icons |
| Forms | Flask-WTF with WTForms |
| PDF Generation | ReportLab |
| Date Handling | Python datetime, dateutil |
| Type Checking | Mypy with SQLAlchemy type stubs |
| Formatting | Black |
Core Capabilities¶
Project Management¶
- Full project lifecycle tracking from intake to completion
- Project numbering with configurable prefixes
- Client association and contact management
- Project status workflow (pending, active, on_hold, completed, cancelled)
- Budget tracking and billing integration
Material Testing¶
- Test type catalog with ASTM/standard references
- Individual material test tracking per project
- Test scheduling with date ranges
- Engineer assignment and principal review workflow
- Status progression (pending → scheduled → in_progress → testing_complete → under_review → approved → delivered)
Field Work Management¶
- Field work session scheduling
- Technician assignment
- Session types (inspection, sampling, testing, observation, other)
- Vehicle assignment tracking
- Per diem and mileage tracking
- Test association with sessions
Lab Work Management¶
- Lab work session scheduling with calendar views
- Lab technician assignment
- Drag-and-drop test assignment to sessions
- Session types (concrete_testing, asphalt_analysis, soil_testing, mix_design, general)
- Week and day view scheduling interfaces
Staff Scheduling¶
- Shift type definitions (field_work, lab_work, office, pto, holiday)
- Staff schedule templates with recurring patterns
- Visual calendar view of staff availability
- Role-based scheduling assignments
Reporting¶
- Report generation per material test or field work session
- Report status tracking (draft, pending_review, approved, delivered)
- PDF generation with company branding
- Report type categorization
Administrative Features¶
- User management with roles (admin, principal_engineer, engineer, lab_technician, field_technician, office_staff)
- Client management with contact information
- Test type catalog management
- Audit history tracking for key entities
- Daily task management
Data Models¶
Core Entities¶
User¶
Primary user model for authentication and authorization.
| Field | Type | Description |
|---|---|---|
| id | String(36) | UUID primary key |
| String(120) | Unique email address | |
| password_hash | String(200) | Bcrypt hashed password |
| first_name | String(50) | User's first name |
| last_name | String(50) | User's last name |
| role | String(30) | User role for permissions |
| is_active | Boolean | Account active status |
| created_at | DateTime | Account creation timestamp |
Relationships:
- projects - Projects assigned to user
- field_work_sessions - Field sessions as technician
- lab_work_sessions - Lab sessions as technician
- schedule_templates - Recurring schedule assignments
Project¶
Represents a client project/job.
| Field | Type | Description |
|---|---|---|
| id | String(36) | UUID primary key |
| project_number | String(50) | Unique project identifier |
| name | String(200) | Project name |
| client_id | String(36) | FK to clients |
| project_manager_id | String(36) | FK to users |
| status | String(30) | Project status |
| start_date | Date | Project start |
| end_date | Date | Expected completion |
| budget | Numeric(12,2) | Project budget |
| description | Text | Project description |
| location | String(200) | Project site location |
Relationships:
- client - Associated client
- project_manager - Assigned project manager
- material_tests - Tests under this project
- field_work_sessions - Field work for project
- invoices - Project invoices
MaterialTest¶
Individual material test within a project.
| Field | Type | Description |
|---|---|---|
| id | String(36) | UUID primary key |
| project_id | String(36) | FK to projects |
| test_type_id | String(36) | FK to test_types |
| test_number | Integer | Sequential test number |
| assigned_engineer_id | String(36) | FK to users |
| lab_work_session_id | String(36) | FK to lab_work_sessions |
| requires_principal_review | Boolean | Needs principal sign-off |
| status | String(30) | Test status |
| scheduled_start | Date | Scheduled start date |
| scheduled_end | Date | Scheduled end date |
| scope_description | Text | Test scope details |
| findings | Text | Test findings |
| recommendations | Text | Engineer recommendations |
Relationships:
- project - Parent project
- test_type - Type of test being performed
- assigned_engineer - Engineer responsible
- lab_work_session - Associated lab session
- field_work_sessions - Associated field sessions
- reports - Generated reports
TestType¶
Catalog of available test types.
| Field | Type | Description |
|---|---|---|
| id | String(36) | UUID primary key |
| name | String(200) | Full test name |
| code | String(50) | Short code (e.g., CONC-COMP) |
| description | Text | Test description |
| standard_reference | String(100) | ASTM/standard reference |
| work_location | String(20) | field, lab, or both |
| is_active | Boolean | Available for use |
Properties:
- can_be_field - True if test can be done in field
- can_be_lab - True if test can be done in lab
Test¶
Individual test performed during a work session.
| Field | Type | Description |
|---|---|---|
| id | String(36) | UUID primary key |
| field_work_session_id | String(36) | FK to field_work_sessions (nullable) |
| lab_work_session_id | String(36) | FK to lab_work_sessions (nullable) |
| test_type_id | String(36) | FK to test_types |
| sample_id | String(100) | Sample identifier |
| pass_fail | String(20) | pass, fail, inconclusive |
| notes | Text | Test notes |
| tested_by_id | String(36) | FK to users |
Constraint: Exactly one of field_work_session_id or lab_work_session_id must be set.
Work Session Models¶
FieldWorkSession¶
Field work scheduling and tracking.
| Field | Type | Description |
|---|---|---|
| id | String(36) | UUID primary key |
| project_id | String(36) | FK to projects |
| material_test_id | String(36) | FK to material_tests |
| field_technician_id | String(36) | FK to users |
| date | Date | Session date |
| start_time | Time | Start time |
| end_time | Time | End time |
| session_type | String(50) | Type of field work |
| vehicle_id | String(36) | FK to vehicles |
| location | String(200) | Work location |
| per_diem | Boolean | Per diem applicable |
| mileage | Numeric(10,2) | Miles traveled |
| status | String(20) | Session status |
| notes | Text | Session notes |
LabWorkSession¶
Lab work scheduling and test assignment.
| Field | Type | Description |
|---|---|---|
| id | String(36) | UUID primary key |
| date | Date | Session date |
| start_time | Time | Start time |
| end_time | Time | End time |
| lab_technician_id | String(36) | FK to users |
| session_type | String(50) | Type of lab work |
| notes | Text | Session notes |
| status | String(20) | Session status |
Relationships:
- tests - Individual tests in session
- material_tests - Material tests assigned to session
Scheduling Models¶
ShiftType¶
Defines types of work shifts.
| Field | Type | Description |
|---|---|---|
| id | String(36) | UUID primary key |
| name | String(100) | Shift type name |
| code | String(20) | Short code |
| color | String(7) | Hex color for display |
| description | Text | Shift description |
| category | String(30) | field_work, lab_work, office, pto, holiday |
| is_active | Boolean | Available for scheduling |
StaffScheduleTemplate¶
Recurring schedule assignments.
| Field | Type | Description |
|---|---|---|
| id | String(36) | UUID primary key |
| user_id | String(36) | FK to users |
| shift_type_id | String(36) | FK to shift_types |
| day_of_week | Integer | 0=Monday through 6=Sunday |
| start_time | Time | Shift start |
| end_time | Time | Shift end |
| effective_from | Date | Template start date |
| effective_until | Date | Template end date |
| is_active | Boolean | Currently active |
Supporting Models¶
Client¶
Client/customer information.
| Field | Type | Description |
|---|---|---|
| id | String(36) | UUID primary key |
| name | String(200) | Company name |
| contact_name | String(100) | Primary contact |
| String(120) | Contact email | |
| phone | String(20) | Contact phone |
| address | Text | Mailing address |
| is_active | Boolean | Active client |
Report¶
Generated reports for tests/sessions.
| Field | Type | Description |
|---|---|---|
| id | String(36) | UUID primary key |
| material_test_id | String(36) | FK to material_tests |
| field_work_session_id | String(36) | FK to field_work_sessions |
| report_type | String(50) | Type of report |
| status | String(30) | draft, pending_review, approved, delivered |
| generated_by_id | String(36) | FK to users |
| approved_by_id | String(36) | FK to users |
| file_path | String(500) | Path to generated file |
| delivery_date | DateTime | When delivered to client |
Invoice¶
Project billing.
| Field | Type | Description |
|---|---|---|
| id | String(36) | UUID primary key |
| project_id | String(36) | FK to projects |
| invoice_number | String(50) | Invoice identifier |
| amount | Numeric(12,2) | Invoice amount |
| status | String(30) | draft, sent, paid, overdue, cancelled |
| due_date | Date | Payment due date |
| paid_date | Date | Actual payment date |
DailyTask¶
Daily task assignments.
| Field | Type | Description |
|---|---|---|
| id | String(36) | UUID primary key |
| title | String(200) | Task title |
| description | Text | Task details |
| assigned_to_id | String(36) | FK to users |
| task_date | Date | Task date |
| priority | String(20) | low, medium, high, urgent |
| status | String(20) | pending, in_progress, completed, cancelled |
| due_time | Time | Due time |
AuditHistory¶
Change tracking for auditable entities.
| Field | Type | Description |
|---|---|---|
| id | String(36) | UUID primary key |
| auditable_type | String(100) | Model class name |
| auditable_id | String(36) | Entity ID |
| action | String(50) | create, update, delete |
| changes | Text | JSON of field changes |
| user_id | String(36) | FK to users |
| created_at | DateTime | When change occurred |
Project Structure¶
balanced-engineering-platform/
├── app/
│ ├── __init__.py # Flask app factory
│ ├── config.py # Configuration classes
│ ├── models/ # SQLAlchemy models
│ │ ├── __init__.py # Model exports
│ │ ├── user.py # User model
│ │ ├── project.py # Project model
│ │ ├── client.py # Client model
│ │ ├── material_test.py # MaterialTest model
│ │ ├── test.py # Test model
│ │ ├── test_type.py # TestType model
│ │ ├── field_work_session.py
│ │ ├── lab_work_session.py
│ │ ├── shift_type.py
│ │ ├── staff_schedule_template.py
│ │ ├── report.py
│ │ ├── invoice.py
│ │ ├── daily_task.py
│ │ ├── vehicle.py
│ │ └── audit_history.py
│ │
│ ├── blueprints/ # Route blueprints
│ │ ├── auth/ # Authentication routes
│ │ │ ├── __init__.py
│ │ │ └── routes.py
│ │ ├── main/ # Main/dashboard routes
│ │ │ ├── __init__.py
│ │ │ └── routes.py
│ │ ├── projects/ # Project management
│ │ │ ├── __init__.py
│ │ │ └── routes.py
│ │ ├── lab/ # Lab management
│ │ │ ├── __init__.py
│ │ │ └── routes.py
│ │ ├── clients/ # Client management
│ │ │ ├── __init__.py
│ │ │ └── routes.py
│ │ ├── reporting/ # Report generation
│ │ │ ├── __init__.py
│ │ │ └── routes.py
│ │ ├── admin/ # Admin functions
│ │ │ ├── __init__.py
│ │ │ └── routes.py
│ │ └── api/ # API endpoints
│ │ ├── __init__.py
│ │ └── routes.py
│ │
│ ├── services/ # Business logic services
│ │ ├── pdf_generator.py # PDF report generation
│ │ └── audit_service.py # Audit logging
│ │
│ ├── templates/ # Jinja2 templates
│ │ ├── base.html # Base layout
│ │ ├── auth/ # Auth templates
│ │ ├── main/ # Dashboard templates
│ │ ├── projects/ # Project templates
│ │ ├── lab/ # Lab templates
│ │ ├── clients/ # Client templates
│ │ ├── reporting/ # Report templates
│ │ └── admin/ # Admin templates
│ │
│ └── static/ # Static assets
│ ├── css/
│ ├── js/
│ └── images/
│
├── migrations/ # Database migrations
├── scripts/
│ └── seed_data.py # Database seeding
├── tests/ # Test suite
├── instance/ # Instance-specific files
│ └── app.db # SQLite database
├── requirements.txt # Python dependencies
├── run.py # Application entry point
└── CLAUDE.md # Development guidelines
Blueprint Organization¶
auth¶
Authentication and user session management. - Login/logout - Password management - Session handling
main¶
Dashboard and home pages. - Main dashboard with metrics - Daily tasks view - Quick navigation
projects¶
Project lifecycle management. - Project CRUD operations - Project list and detail views - Material test management within projects - Status workflow
lab¶
Laboratory operations and scheduling. - Lab schedule (week/day views) - Lab session management - Test assignment (drag-and-drop) - Staff schedules - Shift type management - Staff calendar
clients¶
Client/customer management. - Client CRUD - Contact information - Project association
reporting¶
Report generation and delivery. - Report creation - PDF generation - Report status tracking - Delivery management
admin¶
Administrative functions. - User management - Test type catalog - System configuration
api¶
JSON API endpoints. - Test assignment API - AJAX operations - Data fetching
Key Features Implementation¶
Drag-and-Drop Test Assignment¶
The lab schedule supports dragging unassigned tests onto lab sessions:
// drag start on test badges
document.querySelectorAll('.draggable-test').forEach(test => {
test.addEventListener('dragstart', function(e) {
draggedTestId = this.getAttribute('data-test-id');
});
});
// drop zones on sessions
document.querySelectorAll('.drop-zone').forEach(zone => {
zone.addEventListener('drop', function(e) {
fetch('/lab/api/assign-test', {
method: 'POST',
body: JSON.stringify({
test_id: draggedTestId,
session_id: sessionId
})
}).then(() => window.location.reload());
});
});
Role-Based Access¶
User roles control feature access: - admin: Full system access - principal_engineer: Project oversight, report approval - engineer: Test management, reporting - lab_technician: Lab session execution - field_technician: Field work execution - office_staff: Administrative functions
Audit Trail¶
Key entities track change history:
@property
def audit_history(self):
return AuditHistory.query.filter_by(
auditable_type="MaterialTest",
auditable_id=self.id
).order_by(AuditHistory.created_at.desc()).all()
Development Guidelines¶
Code Style¶
- Use Black for Python formatting
- Use Pydantic for type safety where applicable
- Comments in statement format, not complete sentences
- Type hints using SQLAlchemy Mapped types
Database Operations¶
# model definition pattern
class Model(db.Model):
__tablename__ = "models"
id: Mapped[str] = db.Column(
db.String(36), primary_key=True, default=lambda: str(uuid4())
)
Running the Application¶
# set environment
export FLASK_APP=run.py
export FLASK_DEBUG=1
# initialize database
flask db upgrade
python scripts/seed_data.py
# run development server
flask run --port 5005
Testing¶
Type Checking¶
URL Routes Reference¶
Authentication¶
| Route | Method | Description |
|---|---|---|
/auth/login |
GET, POST | User login |
/auth/logout |
GET | User logout |
Projects¶
| Route | Method | Description |
|---|---|---|
/projects/ |
GET | Project list |
/projects/create |
GET, POST | Create project |
/projects/<id> |
GET | Project detail |
/projects/<id>/edit |
GET, POST | Edit project |
/projects/<id>/tests |
GET | Project tests |
Lab¶
| Route | Method | Description |
|---|---|---|
/lab/lab-schedule |
GET | Lab schedule view |
/lab/lab-session/create |
GET, POST | Create session |
/lab/lab-session/<id>/edit |
GET, POST | Edit session |
/lab/staff-schedules |
GET | Staff schedules |
/lab/staff-calendar |
GET | Staff calendar |
/lab/shift-types |
GET | Shift types |
/lab/api/assign-test |
POST | Assign test to session |
Clients¶
| Route | Method | Description |
|---|---|---|
/clients/ |
GET | Client list |
/clients/create |
GET, POST | Create client |
/clients/<id> |
GET | Client detail |
/clients/<id>/edit |
GET, POST | Edit client |
Database Schema Notes¶
UUID Primary Keys¶
All models use UUID strings as primary keys for better distribution and security:
Timestamps¶
Standard timestamp fields on all models:
created_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
updated_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow,
onupdate=datetime.utcnow)
Soft Deletes¶
Most entities use is_active boolean rather than hard deletes to preserve referential integrity and audit history.
Environment Variables¶
| Variable | Description | Default |
|---|---|---|
FLASK_APP |
Application entry point | run.py |
FLASK_DEBUG |
Debug mode | 0 |
SECRET_KEY |
Session secret key | Required |
DATABASE_URL |
Database connection string | sqlite:///app.db |
Future Considerations¶
- PostgreSQL migration for production
- Background job processing (Celery)
- Email notifications
- Document attachment storage
- Mobile-responsive improvements
- API authentication (JWT)
- Report template customization
- Integration with accounting systems