first commit

This commit is contained in:
Koncept Kit
2025-12-05 16:43:37 +07:00
commit 6ef7685ade
26 changed files with 2191 additions and 0 deletions

141
models.py Normal file
View File

@@ -0,0 +1,141 @@
from sqlalchemy import Column, String, Boolean, DateTime, Enum as SQLEnum, Text, Integer, ForeignKey, JSON
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import relationship
from datetime import datetime, timezone
import uuid
import enum
from database import Base
class UserStatus(enum.Enum):
pending_email = "pending_email"
pending_approval = "pending_approval"
pre_approved = "pre_approved"
payment_pending = "payment_pending"
active = "active"
inactive = "inactive"
class UserRole(enum.Enum):
guest = "guest"
member = "member"
admin = "admin"
class RSVPStatus(enum.Enum):
yes = "yes"
no = "no"
maybe = "maybe"
class SubscriptionStatus(enum.Enum):
active = "active"
expired = "expired"
cancelled = "cancelled"
class User(Base):
__tablename__ = "users"
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
email = Column(String, unique=True, nullable=False, index=True)
password_hash = Column(String, nullable=False)
first_name = Column(String, nullable=False)
last_name = Column(String, nullable=False)
phone = Column(String, nullable=False)
address = Column(String, nullable=False)
city = Column(String, nullable=False)
state = Column(String, nullable=False)
zipcode = Column(String, nullable=False)
date_of_birth = Column(DateTime, nullable=False)
lead_sources = Column(JSON, default=list)
partner_first_name = Column(String, nullable=True)
partner_last_name = Column(String, nullable=True)
partner_is_member = Column(Boolean, default=False)
partner_plan_to_become_member = Column(Boolean, default=False)
referred_by_member_name = Column(String, nullable=True)
status = Column(SQLEnum(UserStatus), default=UserStatus.pending_email, nullable=False)
role = Column(SQLEnum(UserRole), default=UserRole.guest, nullable=False)
email_verified = Column(Boolean, default=False)
email_verification_token = Column(String, nullable=True)
newsletter_subscribed = Column(Boolean, default=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
events_created = relationship("Event", back_populates="creator")
rsvps = relationship("EventRSVP", back_populates="user")
subscriptions = relationship("Subscription", back_populates="user", foreign_keys="Subscription.user_id")
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)
start_at = Column(DateTime, nullable=False)
end_at = Column(DateTime, nullable=False)
location = Column(String, nullable=False)
capacity = Column(Integer, nullable=True)
created_by = Column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=False)
published = Column(Boolean, default=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", back_populates="events_created")
rsvps = relationship("EventRSVP", back_populates="event", cascade="all, delete-orphan")
class EventRSVP(Base):
__tablename__ = "event_rsvps"
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
event_id = Column(UUID(as_uuid=True), ForeignKey("events.id"), nullable=False)
user_id = Column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=False)
rsvp_status = Column(SQLEnum(RSVPStatus), default=RSVPStatus.maybe, nullable=False)
attended = Column(Boolean, default=False)
attended_at = Column(DateTime, 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))
# Relationships
event = relationship("Event", back_populates="rsvps")
user = relationship("User", back_populates="rsvps")
class SubscriptionPlan(Base):
__tablename__ = "subscription_plans"
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
name = Column(String, nullable=False)
description = Column(Text, nullable=True)
price_cents = Column(Integer, nullable=False) # Price in cents
billing_cycle = Column(String, default="yearly", nullable=False) # yearly, monthly, etc.
stripe_price_id = Column(String, nullable=True) # Stripe Price ID
active = Column(Boolean, default=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))
# Relationships
subscriptions = relationship("Subscription", back_populates="plan")
class Subscription(Base):
__tablename__ = "subscriptions"
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
user_id = Column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=False)
plan_id = Column(UUID(as_uuid=True), ForeignKey("subscription_plans.id"), nullable=False)
stripe_subscription_id = Column(String, nullable=True) # Stripe Subscription ID
stripe_customer_id = Column(String, nullable=True) # Stripe Customer ID
status = Column(SQLEnum(SubscriptionStatus), default=SubscriptionStatus.active, nullable=False)
start_date = Column(DateTime, nullable=False)
end_date = Column(DateTime, nullable=True)
amount_paid_cents = Column(Integer, nullable=True) # Amount paid in cents
# Manual payment fields
manual_payment = Column(Boolean, default=False, nullable=False) # Whether this was a manual offline payment
manual_payment_notes = Column(Text, nullable=True) # Admin notes about the payment
manual_payment_admin_id = Column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=True) # Admin who processed the payment
manual_payment_date = Column(DateTime, nullable=True) # Date payment was received
payment_method = Column(String, nullable=True) # Payment method: stripe, cash, bank_transfer, check, other
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
user = relationship("User", back_populates="subscriptions", foreign_keys=[user_id])
plan = relationship("SubscriptionPlan", back_populates="subscriptions")