mirror of
https://github.com/DRYTRIX/TimeTracker.git
synced 2026-01-25 14:09:16 -06:00
Add client custom fields (JSON) for flexible data storage Implement link templates system for dynamic URL generation from custom fields Add client_id support to time entries for direct client billing (project_id now nullable) Implement user-level UI feature flags for customizable navigation visibility Add system-wide UI feature flags in settings for admin control Fix metadata column naming (user_badges.achievement_metadata, leaderboard_entries.entry_metadata) Update templates and routes to support new features Add comprehensive UI feature flag management in admin and user settings Enhance client views with custom fields and link template integration Update time entry forms to support client billing Add tests for system UI flags Migrations: 075-080 for custom fields, link templates, UI flags, client billing, and metadata fixes
46 lines
2.1 KiB
Python
46 lines
2.1 KiB
Python
from datetime import datetime
|
|
from app import db
|
|
|
|
|
|
class SavedReportView(db.Model):
|
|
"""Saved configurations for the custom report builder."""
|
|
|
|
__tablename__ = "saved_report_views"
|
|
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
name = db.Column(db.String(120), nullable=False)
|
|
owner_id = db.Column(db.Integer, db.ForeignKey("users.id"), nullable=False, index=True)
|
|
scope = db.Column(db.String(20), default="private", nullable=False) # private, team, public
|
|
config_json = db.Column(db.Text, nullable=False) # JSON for filters, columns, groupings
|
|
created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
|
|
updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
|
|
|
|
def __repr__(self):
|
|
return f"<SavedReportView {self.name} ({self.scope})>"
|
|
|
|
|
|
class ReportEmailSchedule(db.Model):
|
|
"""Schedules to email saved reports on a cadence."""
|
|
|
|
__tablename__ = "report_email_schedules"
|
|
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
saved_view_id = db.Column(db.Integer, db.ForeignKey("saved_report_views.id"), nullable=False, index=True)
|
|
recipients = db.Column(db.Text, nullable=False) # comma-separated
|
|
cadence = db.Column(db.String(20), nullable=False) # daily, weekly, monthly, custom-cron
|
|
cron = db.Column(db.String(120), nullable=True)
|
|
timezone = db.Column(db.String(50), nullable=True)
|
|
next_run_at = db.Column(db.DateTime, nullable=True)
|
|
last_run_at = db.Column(db.DateTime, nullable=True)
|
|
active = db.Column(db.Boolean, default=True, nullable=False)
|
|
created_by = db.Column(db.Integer, db.ForeignKey("users.id"), nullable=False)
|
|
created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
|
|
updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
|
|
|
|
# Relationships
|
|
saved_view = db.relationship("SavedReportView", backref="schedules")
|
|
creator = db.relationship("User", foreign_keys=[created_by])
|
|
|
|
def __repr__(self):
|
|
return f"<ReportEmailSchedule view={self.saved_view_id} cadence={self.cadence}>"
|