Update New Features

This commit is contained in:
Koncept Kit
2025-12-10 17:52:32 +07:00
parent 005c56b43d
commit f051976881
20 changed files with 2776 additions and 57 deletions

View File

@@ -1,4 +1,4 @@
from sqlalchemy import Column, String, Boolean, DateTime, Enum as SQLEnum, Text, Integer, ForeignKey, JSON
from sqlalchemy import Column, String, Boolean, DateTime, Enum as SQLEnum, Text, Integer, BigInteger, ForeignKey, JSON
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import relationship
from datetime import datetime, timezone
@@ -82,6 +82,13 @@ class User(Base):
password_reset_expires = Column(DateTime, nullable=True)
force_password_change = Column(Boolean, default=False, nullable=False)
# Members Only - Profile Photo & Social Media
profile_photo_url = Column(String, nullable=True) # Cloudflare R2 URL
social_media_facebook = Column(String, nullable=True)
social_media_instagram = Column(String, nullable=True)
social_media_twitter = Column(String, nullable=True)
social_media_linkedin = Column(String, nullable=True)
created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
updated_at = Column(DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))
@@ -92,7 +99,7 @@ class User(Base):
class Event(Base):
__tablename__ = "events"
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
title = Column(String, nullable=False)
description = Column(Text, nullable=True)
@@ -102,12 +109,17 @@ class Event(Base):
capacity = Column(Integer, nullable=True)
created_by = Column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=False)
published = Column(Boolean, default=False)
# Members Only - Universal Calendar Export
calendar_uid = Column(String, nullable=True) # Unique iCalendar UID (UUID4-based)
created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
updated_at = Column(DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))
# Relationships
creator = relationship("User", back_populates="events_created")
rsvps = relationship("EventRSVP", back_populates="event", cascade="all, delete-orphan")
gallery_images = relationship("EventGallery", back_populates="event", cascade="all, delete-orphan")
class EventRSVP(Base):
__tablename__ = "event_rsvps"
@@ -167,3 +179,77 @@ class Subscription(Base):
# Relationships
user = relationship("User", back_populates="subscriptions", foreign_keys=[user_id])
plan = relationship("SubscriptionPlan", back_populates="subscriptions")
class EventGallery(Base):
__tablename__ = "event_galleries"
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
event_id = Column(UUID(as_uuid=True), ForeignKey("events.id"), nullable=False)
image_url = Column(String, nullable=False) # Cloudflare R2 URL
image_key = Column(String, nullable=False) # R2 object key for deletion
caption = Column(Text, nullable=True)
uploaded_by = Column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=False)
file_size_bytes = Column(Integer, nullable=False)
created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
# Relationships
event = relationship("Event", back_populates="gallery_images")
uploader = relationship("User")
class NewsletterArchive(Base):
__tablename__ = "newsletter_archives"
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
title = Column(String, nullable=False)
description = Column(Text, nullable=True)
published_date = Column(DateTime, nullable=False)
document_url = Column(String, nullable=False) # Google Docs URL or R2 URL
document_type = Column(String, default="google_docs") # google_docs, pdf, upload
file_size_bytes = Column(Integer, nullable=True) # For uploaded files
created_by = Column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=False)
created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
updated_at = Column(DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))
# Relationships
creator = relationship("User")
class FinancialReport(Base):
__tablename__ = "financial_reports"
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
year = Column(Integer, nullable=False)
title = Column(String, nullable=False) # e.g., "2024 Annual Report"
document_url = Column(String, nullable=False) # Google Drive URL or R2 URL
document_type = Column(String, default="google_drive") # google_drive, pdf, upload
file_size_bytes = Column(Integer, nullable=True) # For uploaded files
created_by = Column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=False)
created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
updated_at = Column(DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))
# Relationships
creator = relationship("User")
class BylawsDocument(Base):
__tablename__ = "bylaws_documents"
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
title = Column(String, nullable=False)
version = Column(String, nullable=False) # e.g., "v1.0", "v2.0"
effective_date = Column(DateTime, nullable=False)
document_url = Column(String, nullable=False) # Google Drive URL or R2 URL
document_type = Column(String, default="google_drive") # google_drive, pdf, upload
file_size_bytes = Column(Integer, nullable=True) # For uploaded files
is_current = Column(Boolean, default=True) # Only one should be current
created_by = Column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=False)
created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
# Relationships
creator = relationship("User")
class StorageUsage(Base):
__tablename__ = "storage_usage"
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
total_bytes_used = Column(BigInteger, default=0)
max_bytes_allowed = Column(BigInteger, nullable=False) # From .env
last_updated = Column(DateTime, default=lambda: datetime.now(timezone.utc))