feat(products): improve replenishment-aware shopping suggestions
Replace product weight and repurchase intent fields with per-package remaining levels and inventory-first restock signals. Enrich shopping suggestions with usage-aware replenishment scoring so the frontend and LLM can prioritize real gaps and near-empty staples more reliably.
This commit is contained in:
parent
bb5d402c15
commit
d91d06455b
18 changed files with 587 additions and 210 deletions
|
|
@ -0,0 +1,69 @@
|
|||
"""replace product weights with inventory remaining level
|
||||
|
||||
Revision ID: 9f3a2c1b4d5e
|
||||
Revises: 7e6f73d1cc95
|
||||
Create Date: 2026-03-08 12:00:00.000000
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
import sqlalchemy as sa
|
||||
|
||||
from alembic import op
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "9f3a2c1b4d5e"
|
||||
down_revision: Union[str, Sequence[str], None] = "7e6f73d1cc95"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
bind = op.get_bind()
|
||||
remaining_level_enum = sa.Enum(
|
||||
"HIGH",
|
||||
"MEDIUM",
|
||||
"LOW",
|
||||
"NEARLY_EMPTY",
|
||||
name="remaininglevel",
|
||||
)
|
||||
remaining_level_enum.create(bind, checkfirst=True)
|
||||
|
||||
op.add_column(
|
||||
"product_inventory",
|
||||
sa.Column("remaining_level", remaining_level_enum, nullable=True),
|
||||
)
|
||||
op.drop_column("product_inventory", "last_weighed_at")
|
||||
op.drop_column("product_inventory", "current_weight_g")
|
||||
op.drop_column("products", "personal_repurchase_intent")
|
||||
op.drop_column("products", "empty_weight_g")
|
||||
op.drop_column("products", "full_weight_g")
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
bind = op.get_bind()
|
||||
remaining_level_enum = sa.Enum(
|
||||
"HIGH",
|
||||
"MEDIUM",
|
||||
"LOW",
|
||||
"NEARLY_EMPTY",
|
||||
name="remaininglevel",
|
||||
)
|
||||
|
||||
op.add_column(
|
||||
"products",
|
||||
sa.Column("personal_repurchase_intent", sa.Boolean(), nullable=True),
|
||||
)
|
||||
op.add_column(
|
||||
"product_inventory",
|
||||
sa.Column("current_weight_g", sa.Float(), nullable=True),
|
||||
)
|
||||
op.add_column(
|
||||
"product_inventory",
|
||||
sa.Column("last_weighed_at", sa.Date(), nullable=True),
|
||||
)
|
||||
op.add_column("products", sa.Column("full_weight_g", sa.Float(), nullable=True))
|
||||
op.add_column("products", sa.Column("empty_weight_g", sa.Float(), nullable=True))
|
||||
op.drop_column("product_inventory", "remaining_level")
|
||||
remaining_level_enum.drop(bind, checkfirst=True)
|
||||
Loading…
Add table
Add a link
Reference in a new issue