Mar 04 2026: Implement customer's view functionalities - Phase 1
This commit is contained in:
@@ -3,3 +3,4 @@ from app.models.facility import Facility, Area
|
||||
from app.models.inspection import (InspectionTemplate, ChecklistItem,
|
||||
Inspection, InspectionResult)
|
||||
from app.models.issue import Issue
|
||||
from app.models.project import Project, CustomerAssignment
|
||||
|
||||
@@ -11,6 +11,10 @@ class Facility(db.Model):
|
||||
contact_phone = db.Column(db.String(20))
|
||||
active = db.Column(db.Boolean, default=True)
|
||||
|
||||
# Phase 1: link facility to a project (nullable for backward compatibility)
|
||||
project_id = db.Column(db.Integer, db.ForeignKey('projects.id', ondelete='SET NULL'),
|
||||
nullable=True, index=True)
|
||||
|
||||
# Relationships
|
||||
areas = db.relationship('Area', backref='facility', lazy='dynamic')
|
||||
inspections = db.relationship('Inspection', backref='facility', lazy='dynamic')
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
from app import db
|
||||
from app.utils.time_utils import now_eastern
|
||||
|
||||
|
||||
class Project(db.Model):
|
||||
"""Top-level grouping that contains one or more Facilities.
|
||||
|
||||
Each project may have an assigned project_manager (User) and one or more
|
||||
customer users linked via CustomerAssignment.
|
||||
"""
|
||||
__tablename__ = 'projects'
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
name = db.Column(db.String(255), nullable=False)
|
||||
description = db.Column(db.Text)
|
||||
project_manager_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=True)
|
||||
active = db.Column(db.Boolean, default=True, nullable=False)
|
||||
created_at = db.Column(db.DateTime, default=now_eastern, nullable=False)
|
||||
|
||||
# Relationships
|
||||
project_manager = db.relationship('User', foreign_keys=[project_manager_id],
|
||||
backref='managed_projects')
|
||||
facilities = db.relationship('Facility', backref='project', lazy='dynamic')
|
||||
customer_assignments = db.relationship('CustomerAssignment', back_populates='project',
|
||||
cascade='all, delete-orphan', lazy='dynamic')
|
||||
|
||||
def __repr__(self):
|
||||
return f'<Project {self.name}>'
|
||||
|
||||
|
||||
class CustomerAssignment(db.Model):
|
||||
"""Links a customer-role User to a Project and/or a specific Facility.
|
||||
|
||||
- project_id only → customer can view all facilities within that project
|
||||
- project_id + facility_id → customer is scoped to that specific facility
|
||||
"""
|
||||
__tablename__ = 'customer_assignments'
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
user_id = db.Column(db.Integer, db.ForeignKey('users.id', ondelete='CASCADE'),
|
||||
nullable=False, index=True)
|
||||
project_id = db.Column(db.Integer, db.ForeignKey('projects.id', ondelete='CASCADE'),
|
||||
nullable=False, index=True)
|
||||
facility_id = db.Column(db.Integer, db.ForeignKey('facilities.id', ondelete='CASCADE'),
|
||||
nullable=True, index=True)
|
||||
created_at = db.Column(db.DateTime, default=now_eastern, nullable=False)
|
||||
|
||||
__table_args__ = (
|
||||
db.UniqueConstraint('user_id', 'project_id', 'facility_id',
|
||||
name='uq_customer_assignment'),
|
||||
)
|
||||
|
||||
# Relationships
|
||||
user = db.relationship('User', foreign_keys=[user_id],
|
||||
backref=db.backref('customer_assignments', lazy='dynamic'))
|
||||
project = db.relationship('Project', foreign_keys=[project_id],
|
||||
back_populates='customer_assignments')
|
||||
facility = db.relationship('Facility', foreign_keys=[facility_id],
|
||||
backref=db.backref('customer_assignments', lazy='dynamic'))
|
||||
|
||||
def __repr__(self):
|
||||
return (f'<CustomerAssignment user={self.user_id} '
|
||||
f'project={self.project_id} facility={self.facility_id}>')
|
||||
+5
-2
@@ -14,7 +14,10 @@ class User(UserMixin, db.Model):
|
||||
username = db.Column(db.String(100), unique=True, nullable=False, index=True)
|
||||
email = db.Column(db.String(255), unique=True, nullable=False, index=True)
|
||||
password_hash = db.Column(db.String(255), nullable=False)
|
||||
role = db.Column(db.Enum('admin', 'supervisor', 'inspector'), nullable=False)
|
||||
role = db.Column(
|
||||
db.Enum('admin', 'supervisor', 'inspector', 'project_manager', 'customer'),
|
||||
nullable=False
|
||||
)
|
||||
created_at = db.Column(db.DateTime, default=now_eastern)
|
||||
active = db.Column(db.Boolean, default=True, nullable=False)
|
||||
|
||||
@@ -35,4 +38,4 @@ class User(UserMixin, db.Model):
|
||||
return check_password_hash(self.password_hash, password)
|
||||
|
||||
def __repr__(self):
|
||||
return f'<User {self.username}>'
|
||||
return f'<User {self.username}>'
|
||||
|
||||
Reference in New Issue
Block a user