backend/main.py
2025-05-01 01:22:39 +03:00

121 lines
3.6 KiB
Python

from fastapi import FastAPI
from pydantic import BaseModel, Field, EmailStr
from sqlalchemy import (
Column, Integer, String, DateTime, Enum, ForeignKey, Text, Float, Boolean, create_engine
)
from sqlalchemy.orm import declarative_base, relationship, sessionmaker
from sqlalchemy.dialects.postgresql import JSONB
from enum import Enum as PyEnum
import datetime
app = FastAPI()
Base = declarative_base()
# Enums
class Role(str, PyEnum):
admin = "admin"
user = "user"
mod = "mod"
class Status(str, PyEnum):
active = "active"
banned = "banned"
suspended = "suspended"
class ItemType(str, PyEnum):
text = "text"
image = "image"
class VoteType(str, PyEnum):
up = "up"
down = "down"
# SQLAlchemy Models
class User(Base):
__tablename__ = "users"
user_id = Column(Integer, primary_key=True, index=True)
username = Column(String, unique=True, nullable=False)
name = Column(String)
surname = Column(String)
email = Column(String, unique=True, nullable=False)
role = Column(Enum(Role), default=Role.user)
status = Column(Enum(Status), default=Status.active)
bio = Column(String(144))
created_date = Column(DateTime, default=datetime.datetime.utcnow)
collections = relationship("Collection", back_populates="user")
items = relationship("Item", back_populates="user")
class Collection(Base):
__tablename__ = "collections"
collection_id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey("users.user_id"))
visibility = Column(Boolean, default=True) # True = public, False = private
collection_name = Column(String, nullable=False)
collection_bio = Column(String)
user = relationship("User", back_populates="collections")
items = relationship("Item", back_populates="collection")
class Item(Base):
__tablename__ = "items"
item_id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey("users.user_id"))
date = Column(DateTime, default=datetime.datetime.utcnow)
location_x = Column(Float)
location_y = Column(Float)
item_type = Column(Enum(ItemType))
content_text = Column(Text, nullable=True)
content_image_path = Column(String, nullable=True)
collection_id = Column(Integer, ForeignKey("collections.collection_id"))
score = Column(Integer, default=0)
user = relationship("User", back_populates="items")
collection = relationship("Collection", back_populates="items")
votes = relationship("Vote", back_populates="item")
class Vote(Base):
__tablename__ = "votes"
vote_id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey("users.user_id"))
item_id = Column(Integer, ForeignKey("items.item_id"))
vote_type = Column(Enum(VoteType))
date = Column(DateTime, default=datetime.datetime.utcnow)
item = relationship("Item", back_populates="votes")
# Pydantic Schemas
class UserCreate(BaseModel):
username: str
name: str
surname: str
email: EmailStr
bio: str = Field(max_length=144)
class ItemCreate(BaseModel):
location_x: float
location_y: float
item_type: ItemType
content_text: str | None = None
content_image_path: str | None = None
collection_id: int
class CollectionCreate(BaseModel):
collection_name: str
collection_bio: str
visibility: bool = True
class VoteCreate(BaseModel):
item_id: int
vote_type: VoteType
# DB Setup (edit with your DB credentials)
DATABASE_URL = "postgresql://username:password@localhost:5432/mydatabase"
engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(bind=engine)
Base.metadata.create_all(bind=engine)