Files
eamco_auto_api/app/models/auto.py
Edwin Eames c134c05947 feat: rewrite K-factor engine with history tracking and outlier detection
Replace simple exponential smoothing with a rolling-average K-factor
system backed by a new auto_kfactor_history table. Budget fills are
detected and excluded from calculations, outliers beyond 2-sigma are
flagged, and confidence scores track data quality per customer.
Adds backfill endpoint, auto-create for missing estimation records,
and manual house_factor PUT endpoints for both auto and regular customers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 17:54:27 -05:00

117 lines
3.4 KiB
Python

from sqlalchemy import (Column, Integer,
DECIMAL, TEXT, Boolean,
VARCHAR, DATE, INTEGER, Index)
from datetime import datetime
from database import Base
class Auto_Update(Base):
__tablename__ = 'auto_update'
id = Column(Integer,
primary_key=True,
autoincrement=True,
unique=False)
last_updated = Column(DATE())
class Auto_Temp(Base):
__tablename__ = 'auto_temp'
id = Column(Integer,
primary_key=True,
autoincrement=True,
unique=False)
todays_date = Column(DATE)
temp = Column(DECIMAL(5, 2))
temp_max = Column(DECIMAL(5, 2))
temp_min = Column(DECIMAL(5, 2))
temp_avg = Column(DECIMAL(5, 2))
degree_day = Column(INTEGER())
class Auto_Delivery(Base):
__tablename__ = 'auto_delivery'
id = Column(Integer,
primary_key=True,
autoincrement=True,
unique=False)
customer_id = Column(INTEGER())
account_number = Column(VARCHAR(25))
customer_town = Column(VARCHAR(140))
customer_state = Column(INTEGER)
customer_address = Column(VARCHAR(1000))
customer_zip = Column(VARCHAR(25))
customer_full_name = Column(VARCHAR(250))
last_fill = Column(DATE())
days_since_last_fill = Column(INTEGER())
last_updated = Column(DATE())
estimated_gallons_left = Column(DECIMAL(6, 2))
estimated_gallons_left_prev_day = Column(DECIMAL(6, 2))
tank_height = Column(VARCHAR(25))
tank_size = Column(VARCHAR(25))
house_factor = Column(DECIMAL(7, 4))
auto_status = Column(INTEGER())
open_ticket_id = Column(Integer, nullable=True)
hot_water_summer = Column(INTEGER())
confidence_score = Column(INTEGER(), default=20)
k_factor_source = Column(VARCHAR(20), default='default')
class Tickets_Auto_Delivery(Base):
__tablename__ = 'auto_tickets'
id = Column(Integer,
primary_key=True,
autoincrement=True,
unique=False)
customer_id = Column(INTEGER())
account_number = Column(VARCHAR(25))
customer_town = Column(VARCHAR(140))
customer_state = Column(Integer)
customer_address = Column(VARCHAR(1000))
customer_zip = Column(VARCHAR(25))
customer_full_name = Column(VARCHAR(250))
oil_prices_id = Column(INTEGER())
fill_date = Column(DATE())
gallons_delivered = Column(DECIMAL(6, 2))
price_per_gallon = Column(DECIMAL(6, 2))
total_amount_customer = Column(DECIMAL(6, 2))
payment_type = Column(Integer, nullable=True)
payment_card_id = Column(Integer, nullable=True)
payment_status = Column(Integer, nullable=True)
is_budget_fill = Column(Boolean, default=False)
class KFactorHistory(Base):
__tablename__ = 'auto_kfactor_history'
id = Column(Integer, primary_key=True, autoincrement=True)
customer_id = Column(INTEGER(), nullable=False, index=True)
ticket_id = Column(Integer, nullable=True)
fill_date = Column(DATE())
gallons_delivered = Column(DECIMAL(6, 2))
total_hdd = Column(DECIMAL(8, 2))
days_in_period = Column(Integer)
k_factor = Column(DECIMAL(7, 4))
is_budget_fill = Column(Boolean, default=False)
is_outlier = Column(Boolean, default=False)
created_at = Column(DATE())
__table_args__ = (
Index('ix_auto_kfactor_history_customer_fill', 'customer_id', fill_date.desc()),
)