Add Workshop MVP

This commit is contained in:
for_rest
2026-08-13 00:01:54 +03:00
parent 71fbefad55
commit c089d5372a
6 changed files with 571 additions and 0 deletions

58
database.py Normal file
View File

@@ -0,0 +1,58 @@
import os
from pathlib import Path
from dotenv import load_dotenv
from sqlalchemy import Boolean, ForeignKey, Integer, LargeBinary, String, Text, create_engine, text
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship
load_dotenv(Path(__file__).with_name(".evn"), override=True)
DATABASE_URL = os.getenv("DATABASE_URL")
if not DATABASE_URL:
raise RuntimeError("DATABASE_URL is not configured")
engine = create_engine(DATABASE_URL, pool_pre_ping=True)
class Base(DeclarativeBase):
pass
class Service(Base):
__tablename__ = "services"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(100))
description: Mapped[str] = mapped_column(Text, default="")
category: Mapped[str] = mapped_column(String(50))
author: Mapped[str] = mapped_column(String(100), default="anonymous")
selected: Mapped[bool] = mapped_column(Boolean, default=False, server_default="false")
archive_key: Mapped[str | None] = mapped_column(String(500), nullable=True)
files: Mapped[list["ServiceFile"]] = relationship(
back_populates="service", cascade="all, delete-orphan"
)
class ServiceFile(Base):
__tablename__ = "service_files"
id: Mapped[int] = mapped_column(primary_key=True)
service_id: Mapped[int] = mapped_column(ForeignKey("services.id"))
path: Mapped[str] = mapped_column(String(500))
content: Mapped[bytes] = mapped_column(LargeBinary)
service: Mapped[Service] = relationship(back_populates="files")
def init_db() -> None:
Base.metadata.create_all(engine)
# Short MVP migration: existing hackathon databases may lack this new field.
with engine.begin() as connection:
connection.execute(
text(
"ALTER TABLE services "
"ADD COLUMN IF NOT EXISTS selected BOOLEAN NOT NULL DEFAULT FALSE"
)
)
connection.execute(
text("ALTER TABLE services ADD COLUMN IF NOT EXISTS archive_key VARCHAR(500)")
)