"""Knowledge Base model. Non-asset plugin model. The `knowledgebase` table lives in the core Alembic chain (bundled-plugin schema is folded into core, ADR-004); this class just maps it and is registered via the plugin's get_models hook. The appid FK references the core applications table by name, which resolves at mapper config time without importing the core model. """ from datetime import datetime, timezone from shopdb.api import db, BaseModel def _utcnow(): # naive UTC to match the other DB DateTime columns (stored without tzinfo) return datetime.now(timezone.utc).replace(tzinfo=None) class KnowledgeBase(BaseModel): """Knowledge Base article linking to external resources.""" __tablename__ = 'knowledgebase' linkid = db.Column(db.Integer, primary_key=True) appid = db.Column(db.Integer, db.ForeignKey('applications.appid')) shortdescription = db.Column(db.String(500), nullable=False) linkurl = db.Column(db.String(2000)) keywords = db.Column(db.String(500)) clicks = db.Column(db.Integer, default=0) lastupdated = db.Column(db.DateTime, default=_utcnow, onupdate=_utcnow) # Relationship to the core Application model (resolved by class name). application = db.relationship('Application', backref=db.backref('knowledgebase_articles', lazy='dynamic')) def __repr__(self): return f"" def increment_clicks(self): """Increment click counter.""" self.clicks = (self.clicks or 0) + 1