Architecture: - Moved backend/app/ to diligence/ Python package - Dialect-agnostic models (Uuid + JSON, no PostgreSQL imports) - Auto-detect database: empty DATABASE_URL → SQLite at ~/.diligence/data.db - Cross-dialect migrations (inspector-based, no raw PostgreSQL DDL) - FastAPI serves pre-built React frontend for pip path - CLI entry point: diligence [--port] [--no-browser] [--data-dir] - pyproject.toml with optional deps: [postgres], [mcp], [dev] - Docker path unchanged: docker compose up -d pip install path: pip install . && diligence Docker path: ./setup.sh && docker compose up -d
36 lines
1.8 KiB
Python
36 lines
1.8 KiB
Python
from __future__ import annotations
|
|
|
|
import uuid
|
|
from datetime import datetime, date, timezone
|
|
from decimal import Decimal
|
|
from sqlalchemy import String, Numeric, Date, DateTime, Text, ForeignKey, Index, Uuid, JSON
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
from diligence.database import Base
|
|
|
|
|
|
class FoodLog(Base):
|
|
__tablename__ = "food_log"
|
|
|
|
id: Mapped[uuid.UUID] = mapped_column(Uuid, primary_key=True, default=uuid.uuid4)
|
|
user_id: Mapped[uuid.UUID] = mapped_column(Uuid, ForeignKey("users.id"), nullable=False)
|
|
meal_type: Mapped[str] = mapped_column(String(20), nullable=False)
|
|
food_name: Mapped[str] = mapped_column(String(300), nullable=False)
|
|
brand: Mapped[str | None] = mapped_column(String(200))
|
|
barcode: Mapped[str | None] = mapped_column(String(50))
|
|
serving_size: Mapped[str | None] = mapped_column(String(100))
|
|
servings: Mapped[Decimal] = mapped_column(Numeric(5, 2), default=1)
|
|
calories: Mapped[Decimal | None] = mapped_column(Numeric(7, 1))
|
|
protein_g: Mapped[Decimal | None] = mapped_column(Numeric(6, 1))
|
|
carbs_g: Mapped[Decimal | None] = mapped_column(Numeric(6, 1))
|
|
fat_g: Mapped[Decimal | None] = mapped_column(Numeric(6, 1))
|
|
fiber_g: Mapped[Decimal | None] = mapped_column(Numeric(6, 1))
|
|
sodium_mg: Mapped[Decimal | None] = mapped_column(Numeric(7, 1))
|
|
sugar_g: Mapped[Decimal | None] = mapped_column(Numeric(6, 1))
|
|
food_date: Mapped[date] = mapped_column(Date, nullable=False)
|
|
logged_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc))
|
|
off_product_id: Mapped[str | None] = mapped_column(String(50))
|
|
off_data: Mapped[dict] = mapped_column(JSON, default=dict)
|
|
|
|
__table_args__ = (
|
|
Index("idx_food_log_user_date", "user_id", "food_date"),
|
|
)
|