Initial commit: Flask battery tracker app
- Flask + SQLAlchemy (MariaDB-compatible schema) battery tracking web app - 40 pre-seeded batteries (Eneloop, BONAI, Energizer NiMH) across 5 devices - Business rules: block retired assignment, brand-mix warnings, capacity checks - Mobile-friendly Jinja2 templates with inline CSS - waitress WSGI server via systemd user service (sbin/install-service.sh) - SQLite → MariaDB migration script (migrate_to_mariadb.py) - 26 passing acceptance tests (pytest + Flask test client) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
from sqlalchemy import Column, Integer, String, Text, ForeignKey
|
||||
from sqlalchemy.orm import declarative_base, relationship
|
||||
|
||||
Base = declarative_base()
|
||||
|
||||
|
||||
class Device(Base):
|
||||
__tablename__ = "device"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
name = Column(String(100), nullable=False, unique=True)
|
||||
battery_slots = Column(Integer, nullable=False, default=1)
|
||||
notes = Column(Text, nullable=True)
|
||||
|
||||
batteries = relationship("Battery", back_populates="device")
|
||||
|
||||
def installed_count(self):
|
||||
return sum(1 for b in self.batteries if b.status == "installed")
|
||||
|
||||
def installed_brands(self):
|
||||
return set(b.brand for b in self.batteries if b.status == "installed")
|
||||
|
||||
def has_mixed_brands(self):
|
||||
return len(self.installed_brands()) > 1
|
||||
|
||||
def __repr__(self):
|
||||
return f"<Device {self.name}>"
|
||||
|
||||
|
||||
class Battery(Base):
|
||||
__tablename__ = "battery"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
label = Column(String(50), nullable=False, unique=True)
|
||||
brand = Column(String(100), nullable=False)
|
||||
status = Column(String(20), nullable=False, default="available")
|
||||
device_id = Column(Integer, ForeignKey("device.id", ondelete="SET NULL"), nullable=True)
|
||||
notes = Column(Text, nullable=True)
|
||||
|
||||
device = relationship("Device", back_populates="batteries")
|
||||
|
||||
def is_available(self):
|
||||
return self.status == "available"
|
||||
|
||||
def is_retired(self):
|
||||
return self.status == "retired"
|
||||
|
||||
def is_installed(self):
|
||||
return self.status == "installed"
|
||||
|
||||
def __repr__(self):
|
||||
return f"<Battery {self.label}>"
|
||||
Reference in New Issue
Block a user