## Why The product model (docs/PRODUCT-MODEL.md) makes SMS the only real variable cost, metered per plan. This change delivers the two revenue-critical pieces: **SMS credit metering** (allocated vs used per tag, admin top-ups, block when exhausted) and the **location-link flow** (alert SMS carries a short URL → a map page with the finder's location + details). This is the slice that makes the $5/10-SMS plans enforceable and gives owners the "where is my dog" page. ## What Changes - **Metering schema**: `tags` gains `sms_allocated`, `sms_used`, `sms_period_start` (idempotent ALTERs). **`sms_allocated = 0` means unmetered/transitional** (existing tags keep working); a positive allocation is enforced. - **Metering in the alert path**: when an alert or finder-contact SMS is about to be sent, `sms_used < sms_allocated` is required (only when allocation > 0). Successful sends increment `sms_used`. Exhausted → scans recorded, no SMS (unlock/renewal messaging is a follow-up slice — needs email). - **Short URLs**: `url_shortened` table (code → scan_id). Alert SMS with a location now links `https://where-woof.com/s/{code}` instead of the full maps URL (keeps SMS in budget, hides raw coords). - **Location page**: `GET /s/{code}` renders the owner's location page — embedded Google Map of the finder's position, finder's phone (if left), tag-page link, timestamp. Keyed by the unguessable code. - **Admin**: TagResource gains SMS credit fields (edit `sms_allocated` = manual top-up; view `sms_used`). ## Capabilities ### New Capabilities - `sms-metering`: per-tag credit allocation/usage, enforcement in the alert path, admin top-up. - `location-link`: short URLs + owner location page (map embed + finder details). ### Modified Capabilities - `sms-alerting`: ADDED — credits required; sent-SMS counter; SMS message uses the short link. - `database`: ADDED — tags credit columns + `url_shortened` table. ## Impact - **Go**: scan.go (credit checks + counter + short-link in message), new `shortlink.go` handler + `location` template set, queries (GetShortCode, InsertShortCode, GetScanByID, AddSmsUsed), config none. - **Schema**: idempotent ALTERs + `url_shortened` table; `make db-up`. - **Admin**: TagResource fields. - **SMS message change**: location line becomes the short link.