from flask_sqlalchemy import SQLAlchemy from flask_login import UserMixin from datetime import datetime import json from extensions import db class User(UserMixin, db.Model): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) discord_id = db.Column(db.String(50), unique=True, nullable=False) username = db.Column(db.String(100), nullable=False) minecraft_uuid = db.Column(db.String(36), unique=True, nullable=True) minecraft_username = db.Column(db.String(16), nullable=True) is_admin = db.Column(db.Boolean, default=False) created_at = db.Column(db.DateTime, default=datetime.utcnow) class Event(db.Model): __tablename__ = 'events' id = db.Column(db.Integer, primary_key=True) event_type = db.Column(db.String(50), nullable=False) # CHAT, JOIN, QUIT, DEATH, TELEPORT player_uuid = db.Column(db.String(36), nullable=True) player_name = db.Column(db.String(16), nullable=True) content = db.Column(db.Text, nullable=True) # Chat message, death message, etc. location = db.Column(db.String(100), nullable=True) # Serialized location timestamp = db.Column(db.DateTime, default=datetime.utcnow) def to_dict(self): return { 'type': self.event_type, 'player': self.player_name, 'uuid': self.player_uuid, 'content': self.content, 'location': self.location, 'timestamp': self.timestamp.isoformat() if self.timestamp else None, 'inventory': json.loads(self.inventory.items) if self.inventory else None } class Inventory(db.Model): __tablename__ = 'inventories' id = db.Column(db.Integer, primary_key=True) event_id = db.Column(db.Integer, db.ForeignKey('events.id'), nullable=False) player_uuid = db.Column(db.String(36), nullable=False) items = db.Column(db.Text, nullable=False) # JSON serialized inventory timestamp = db.Column(db.DateTime, default=datetime.utcnow) event = db.relationship('Event', backref=db.backref('inventory', uselist=False)) class Ticket(db.Model): __tablename__ = 'tickets' id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False) # Creator title = db.Column(db.String(200), nullable=False) description = db.Column(db.Text, nullable=False) status = db.Column(db.String(20), default='OPEN') # OPEN, CLOSED, IN_PROGRESS closing_reason = db.Column(db.Text, nullable=True) closed_by_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=True) created_at = db.Column(db.DateTime, default=datetime.utcnow) creator = db.relationship('User', backref='created_tickets', foreign_keys=[user_id]) closed_by = db.relationship('User', foreign_keys=[closed_by_id]) assignments = db.relationship('TicketAssignment', backref='ticket', cascade="all, delete-orphan") comments = db.relationship('TicketComment', backref='ticket', cascade="all, delete-orphan", order_by='TicketComment.created_at') class TicketAssignment(db.Model): __tablename__ = 'ticket_assignments' user_id = db.Column(db.Integer, db.ForeignKey('users.id'), primary_key=True) ticket_id = db.Column(db.Integer, db.ForeignKey('tickets.id'), primary_key=True) assigned_at = db.Column(db.DateTime, default=datetime.utcnow) user = db.relationship('User', backref='assignments') class TicketComment(db.Model): __tablename__ = 'ticket_comments' id = db.Column(db.Integer, primary_key=True) ticket_id = db.Column(db.Integer, db.ForeignKey('tickets.id'), nullable=False) user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False) content = db.Column(db.Text, nullable=False) is_hidden = db.Column(db.Boolean, default=False) created_at = db.Column(db.DateTime, default=datetime.utcnow) user = db.relationship('User', backref='comments') class LinkCode(db.Model): __tablename__ = 'link_codes' id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False) code = db.Column(db.String(10), unique=True, nullable=False) created_at = db.Column(db.DateTime, default=datetime.utcnow) expires_at = db.Column(db.DateTime, nullable=False) user = db.relationship('User', backref=db.backref('link_code', uselist=False, cascade="all, delete-orphan")) class Application(db.Model): __tablename__ = 'applications' id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False) position = db.Column(db.String(50), nullable=False) # MODERATOR, DEVELOPER content = db.Column(db.Text, nullable=False) status = db.Column(db.String(20), default='PENDING') # PENDING, ACCEPTED, REJECTED created_at = db.Column(db.DateTime, default=datetime.utcnow) user = db.relationship('User', backref='applications')