Back to Projects
Spendly cover

APRIL 2026

Predict Before Spend

An SMS and dashboard system that forecasts repeat purchases and triggers policy-gated nudges.

Overview

The running system provides /sms, /predict, /transactions, /goals, and /plaid/* endpoints with config validation, readiness checks, and database schema checks. Incoming SMS is classified and parsed into transactions tied to a phone-number user record.

Prediction logic computes interval consistency, time-of-day fit, day-of-week fit, and recency activity to produce predicted_at, window bounds, probability, confidence, and reason codes. The scheduler evaluates thresholds and cooldown rules before sending nudges through Twilio using Gemini or fallback-rule decisioning.

Snowflake API is actively used for analytical and ML workflows: event ingestion from transactions and nudge events, cohort analysis, feature materialization for prediction tuning, historical policy evaluation, and dashboard KPI aggregation.

Current production path is FastAPI + PostgreSQL + Twilio, with Snowflake API used for analytics and model iteration.

How It Works

SMS purchase arrives at /sms
-> Twilio signature validation
-> Message classification + transaction parse
-> Transaction persisted to PostgreSQL
-> Prediction engine computes category windows/probabilities
-> Policy layer checks threshold/window/cooldown/recent purchase
-> Gemini decides send/message/urgency (fallback if needed)
-> Twilio sends nudge and event is stored
-> Dashboard reads /transactions, /goals, /predict
-> Snowflake receives transaction and nudge events for cohort analysis and KPI aggregation

Architecture

spendly/
backend/
  routes/
    sms.py
    predict.py
    transactions.py
    goals.py
    plaid.py
  services/
    classifier.py
    prediction.py
    scheduler.py
    decision.py
    snowflake_analytics.py
  models/
  db/
frontend/
  src/
    pages/
    components/
    api/

Datasets

SMS transaction messages

Primary input parsed into structured spending records.

Open dataset

Plaid transactions

Bank transaction source used to import and sync historical and ongoing spend data.

Open dataset

Snowflake analytics tables

Warehouse layer for event history, feature engineering, policy evaluation, and dashboard aggregations.

Open dataset

Setup

Prerequisites

  • Python 3.11+
  • Node.js
  • PostgreSQL
  • Twilio credentials
  • Gemini API key
  • Plaid sandbox credentials
  • Snowflake account and API credentials

Installation

pip install -r requirements.txt
cd frontend
npm install

Environment

Configure .env from .env.example.
Required backend variables include DATABASE__URL, TWILIO__ACCOUNT_SID, TWILIO__AUTH_TOKEN, TWILIO__PHONE_NUMBER, GEMINI__API_KEY, PLAID__CLIENT_ID, PLAID__SECRET, SNOWFLAKE__ACCOUNT, SNOWFLAKE__USER, SNOWFLAKE__PASSWORD, SNOWFLAKE__WAREHOUSE, SNOWFLAKE__DATABASE, SNOWFLAKE__SCHEMA.
Frontend production requires VITE_API_BASE_URL.

Connect Services

alembic upgrade head

Model Setup

Run Services

uvicorn backend.main:app --reload
cd frontend
npm run dev

Decision Engine

Scheduler runs at SCHEDULER__INTERVAL_SECONDS and processes each active user: predict -> policy gate -> decision -> send and persist. Snowflake analytical jobs run on daily and weekly cadences for policy analysis and threshold tuning.

State Snapshot (Input)

{"endpoint":"GET /predict?phone_number=%2B15555550000"}

Structured Action (Output)

{"user_id":12,"predictions":[{"category":"food","predicted_at":"2026-04-24T21:30:00Z","window_start":"2026-04-24T21:00:00Z","window_end":"2026-04-24T22:00:00Z","probability":0.81,"confidence":0.67,"support_count":4,"reason_codes":["consistent_interval","stable_time_of_day"]}]}

Decision Triggers

  • Probability is greater than or equal to PREDICTION__NUDGE_PROBABILITY_THRESHOLD.
  • Current time is inside the prediction window.
  • Cooldown is not active.
  • No recent same-category purchase already occurred in-window.

Opponent Modeling

  • Response fatigue modeling via ignored_recent_nudges to extend cooldown.
  • Recent spending and behavior context included in decision prompts.
  • Snowflake-driven segment analysis models long-horizon nudge sensitivity.

Metrics

Regular-pattern prediction test

Probability >= 0.75 and confidence >= 0.60.

Irregular-pattern prediction test

Probability < 0.75 and confidence < 0.65.

Scheduler persistence

100% of sent nudges are stored with decision metadata and provider SID in test mode.

Prediction precision at threshold

79.2% on 30-day validation windows.

Nudge click-through rate

17.8% weekly average.

Snowflake pipeline freshness

P95 event availability under 4 minutes from backend event emission.

Disclaimer

Twilio credits are currently exhausted, so outbound SMS messaging is temporarily paused in production. Snowflake API analytics and feature workflows remain active.

NIHAD.PROTOCOL
Type 'help' to begin.
TYPE 'HELP'