Files
sproutly/backend/models.py
derekc 1bed02ebb5 Add ntfy authentication support (username/password and API key)
- Settings table gets ntfy_username, ntfy_password, ntfy_api_key columns
- Backend applies Basic or Bearer auth header when sending notifications
- Settings page UI lets you toggle between no auth, basic, or token auth
- Masked credential display on load to avoid exposing stored secrets
- README updated with auth modes documentation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 23:49:54 -07:00

102 lines
3.1 KiB
Python

import enum
from sqlalchemy import Column, Integer, String, Date, Boolean, Text, DateTime, Enum, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy.sql import func
from database import Base
class Category(str, enum.Enum):
vegetable = "vegetable"
herb = "herb"
flower = "flower"
fruit = "fruit"
class SunRequirement(str, enum.Enum):
full_sun = "full_sun"
part_shade = "part_shade"
full_shade = "full_shade"
class WaterNeeds(str, enum.Enum):
low = "low"
medium = "medium"
high = "high"
class BatchStatus(str, enum.Enum):
planned = "planned"
germinating = "germinating"
seedling = "seedling"
potted_up = "potted_up"
hardening = "hardening"
garden = "garden"
harvested = "harvested"
failed = "failed"
class Variety(Base):
__tablename__ = "varieties"
id = Column(Integer, primary_key=True, index=True)
name = Column(String(100), nullable=False)
variety_name = Column(String(100))
category = Column(Enum(Category), default=Category.vegetable)
weeks_to_start = Column(Integer)
weeks_to_greenhouse = Column(Integer)
weeks_to_garden = Column(Integer)
days_to_germinate = Column(Integer, default=7)
direct_sow_ok = Column(Boolean, default=False)
frost_tolerant = Column(Boolean, default=False)
sun_requirement = Column(Enum(SunRequirement), default=SunRequirement.full_sun)
water_needs = Column(Enum(WaterNeeds), default=WaterNeeds.medium)
color = Column(String(7), default="#52b788")
notes = Column(Text)
created_at = Column(DateTime, server_default=func.now())
batches = relationship("Batch", back_populates="variety", cascade="all, delete-orphan")
class Batch(Base):
__tablename__ = "batches"
id = Column(Integer, primary_key=True, index=True)
variety_id = Column(Integer, ForeignKey("varieties.id"), nullable=False)
label = Column(String(100))
quantity = Column(Integer, default=1)
sow_date = Column(Date)
germination_date = Column(Date)
greenhouse_date = Column(Date)
garden_date = Column(Date)
status = Column(Enum(BatchStatus), default=BatchStatus.planned)
notes = Column(Text)
created_at = Column(DateTime, server_default=func.now())
variety = relationship("Variety", back_populates="batches")
class Settings(Base):
__tablename__ = "settings"
id = Column(Integer, primary_key=True, default=1)
last_frost_date = Column(Date)
first_frost_fall_date = Column(Date)
ntfy_topic = Column(String(200))
ntfy_server = Column(String(200), default="https://ntfy.sh")
notification_time = Column(String(5), default="07:00")
timezone = Column(String(50), default="UTC")
location_name = Column(String(100))
ntfy_username = Column(String(200))
ntfy_password = Column(String(200))
ntfy_api_key = Column(String(200))
class NotificationLog(Base):
__tablename__ = "notification_log"
id = Column(Integer, primary_key=True, index=True)
sent_at = Column(DateTime, server_default=func.now())
message = Column(Text)
status = Column(String(20))
error = Column(Text)