Files
AI Company ea8b5be058
MetaBloom CI / app (push) Canceled after 0s
MetaBloom CI / api (push) Canceled after 0s
feat: evolve MetaBloom into full product foundation
2026-07-21 19:24:59 +00:00

58 lines
2.4 KiB
Python

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")