"""Application tracking models.""" from shopdb.extensions import db from .base import BaseModel class AppOwner(BaseModel): """Application owner/contact.""" __tablename__ = 'appowners' appownerid = db.Column(db.Integer, primary_key=True) appowner = db.Column(db.String(100), nullable=False) sso = db.Column(db.String(50)) email = db.Column(db.String(100)) # Relationships supportteams = db.relationship('SupportTeam', back_populates='owner', lazy='dynamic') def __repr__(self): return f"" class SupportTeam(BaseModel): """Application support team.""" __tablename__ = 'supportteams' supportteamid = db.Column(db.Integer, primary_key=True) teamname = db.Column(db.String(100), nullable=False) teamurl = db.Column(db.String(255)) appownerid = db.Column(db.Integer, db.ForeignKey('appowners.appownerid')) # Relationships owner = db.relationship('AppOwner', back_populates='supportteams') applications = db.relationship('Application', back_populates='supportteam', lazy='dynamic') def __repr__(self): return f"" class Application(BaseModel): """Application catalog.""" __tablename__ = 'applications' appid = db.Column(db.Integer, primary_key=True) appname = db.Column(db.String(100), unique=True, nullable=False) appdescription = db.Column(db.String(255)) supportteamid = db.Column(db.Integer, db.ForeignKey('supportteams.supportteamid')) isinstallable = db.Column(db.Boolean, default=False) applicationnotes = db.Column(db.Text) installpath = db.Column(db.String(255)) applicationlink = db.Column(db.String(512)) documentationpath = db.Column(db.String(512)) ishidden = db.Column(db.Boolean, default=False) isprinter = db.Column(db.Boolean, default=False) islicenced = db.Column(db.Boolean, default=False) image = db.Column(db.String(255)) # Relationships supportteam = db.relationship('SupportTeam', back_populates='applications') versions = db.relationship('AppVersion', back_populates='application', lazy='dynamic') installed_on = db.relationship('InstalledApp', back_populates='application', lazy='dynamic') def __repr__(self): return f"" class AppVersion(BaseModel): """Application version tracking.""" __tablename__ = 'appversions' appversionid = db.Column(db.Integer, primary_key=True) appid = db.Column(db.Integer, db.ForeignKey('applications.appid'), nullable=False) version = db.Column(db.String(50), nullable=False) releasedate = db.Column(db.Date) notes = db.Column(db.String(255)) dateadded = db.Column(db.DateTime, default=db.func.now()) # Relationships application = db.relationship('Application', back_populates='versions') installations = db.relationship('InstalledApp', back_populates='appversion', lazy='dynamic') # Unique constraint on app + version __table_args__ = ( db.UniqueConstraint('appid', 'version', name='uq_app_version'), ) def __repr__(self): return f"" class InstalledApp(db.Model): """Junction table for applications installed on machines (PCs).""" __tablename__ = 'installedapps' id = db.Column(db.Integer, primary_key=True) machineid = db.Column(db.Integer, db.ForeignKey('machines.machineid'), nullable=False) appid = db.Column(db.Integer, db.ForeignKey('applications.appid'), nullable=False) appversionid = db.Column(db.Integer, db.ForeignKey('appversions.appversionid')) isactive = db.Column(db.Boolean, default=True, nullable=False) installeddate = db.Column(db.DateTime, default=db.func.now()) # Relationships machine = db.relationship('Machine', back_populates='installedapps') application = db.relationship('Application', back_populates='installed_on') appversion = db.relationship('AppVersion', back_populates='installations') # Unique constraint - one app per machine (can have different versions over time) __table_args__ = ( db.UniqueConstraint('machineid', 'appid', name='uq_machine_app'), ) def to_dict(self): """Convert to dictionary.""" return { 'id': self.id, 'machineid': self.machineid, 'appid': self.appid, 'appversionid': self.appversionid, 'isactive': self.isactive, 'installeddate': self.installeddate.isoformat() + 'Z' if self.installeddate else None, 'application': { 'appid': self.application.appid, 'appname': self.application.appname, 'appdescription': self.application.appdescription, } if self.application else None, 'version': self.appversion.version if self.appversion else None } def __repr__(self): return f""