feat: evolve MetaBloom into full product foundation
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
import enum
|
||||
import uuid
|
||||
from datetime import date, datetime, timezone
|
||||
from sqlalchemy import Boolean, Date, DateTime, Enum, Float, ForeignKey, Integer, String, Text
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
from .db import Base
|
||||
|
||||
|
||||
def now() -> datetime:
|
||||
return datetime.now(timezone.utc)
|
||||
|
||||
|
||||
class EntryKind(str, enum.Enum):
|
||||
weight = "weight"
|
||||
glucose = "glucose"
|
||||
water = "water"
|
||||
activity = "activity"
|
||||
sleep = "sleep"
|
||||
mood = "mood"
|
||||
meal = "meal"
|
||||
|
||||
|
||||
class User(Base):
|
||||
__tablename__ = "users"
|
||||
id: Mapped[str] = mapped_column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
|
||||
email: Mapped[str] = mapped_column(String(320), unique=True, index=True)
|
||||
password_hash: Mapped[str] = mapped_column(String(255))
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now)
|
||||
profile: Mapped["Profile | None"] = relationship(back_populates="user", cascade="all, delete-orphan")
|
||||
entries: Mapped[list["Entry"]] = relationship(back_populates="user", cascade="all, delete-orphan")
|
||||
|
||||
|
||||
class Profile(Base):
|
||||
__tablename__ = "profiles"
|
||||
user_id: Mapped[str] = mapped_column(ForeignKey("users.id", ondelete="CASCADE"), primary_key=True)
|
||||
display_name: Mapped[str | None] = mapped_column(String(80))
|
||||
birth_date: Mapped[date | None] = mapped_column(Date)
|
||||
height_cm: Mapped[float | None] = mapped_column(Float)
|
||||
objective: Mapped[str | None] = mapped_column(String(120))
|
||||
health_context: Mapped[str | None] = mapped_column(Text)
|
||||
consent_health_data: Mapped[bool] = mapped_column(Boolean, default=False)
|
||||
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now, onupdate=now)
|
||||
user: Mapped[User] = relationship(back_populates="profile")
|
||||
|
||||
|
||||
class Entry(Base):
|
||||
__tablename__ = "entries"
|
||||
id: Mapped[str] = mapped_column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
|
||||
user_id: Mapped[str] = mapped_column(ForeignKey("users.id", ondelete="CASCADE"), index=True)
|
||||
kind: Mapped[EntryKind] = mapped_column(Enum(EntryKind))
|
||||
value: Mapped[float] = mapped_column(Float)
|
||||
unit: Mapped[str] = mapped_column(String(24))
|
||||
note: Mapped[str | None] = mapped_column(String(500))
|
||||
recorded_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now, index=True)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now)
|
||||
user: Mapped[User] = relationship(back_populates="entries")
|
||||
|
||||
Reference in New Issue
Block a user