fix: per-site attribution needs its own column, not pickuplocationid

Caught by testing the previous commit against production: creating a booking
with a resolved site failed with

  pickupbookings_pickuplocationid_fkey
  FOREIGN KEY (pickuplocationid) REFERENCES appcustomerlocations(...)

pickuplocationid is the *customer's* saved address, a B2C concept. It never
referred to the client company's own kitchens or branches. The pre-existing
code that validated an incoming pickuplocationid against TenantLocation was
wrong on the same point and would have 500'd for any caller that used it — it
had simply never been called with a value.

Adds tenantlocationid to pickupbookings and consignments (nullable, indexed,
additive via AutoMigrate), carried across at pickup, and points the reporting
filter, the by_location breakdown and the Unattributed bucket at it.

The booking request accepts tenantlocationid, and still accepts
pickuplocationid as an alias so anything written against the earlier docs
starts working instead of failing.

Also gofmt on the two model files touched; booking.go was already failing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Suriya
2026-08-06 13:08:57 +05:30
parent 0c407e5b27
commit 90fa4fbb74
6 changed files with 108 additions and 70 deletions

View File

@@ -98,13 +98,17 @@ Two jupiter bugs that do not carry over, by construction:
`/admin/reports` now carries a `by_location` block alongside `by_hub`,
`by_tenant` and `by_rider`.
**Attribution caveat.** Per-site figures depend on `pickuplocationid` being set
on the booking. Every booking created before 2026-08-06 has it null, and the
console sends a kitchen's *address*, not its id. So `createExpressBooking` now
resolves the site itself — nearest stored location within 150m, falling back to
an address match — and unattributed bookings are reported as their own
`"Unattributed"` row rather than dropped, so the per-site rows still add up to
the summary total. Sending `pickuplocationid` explicitly is still better and
**Attribution caveat.** Per-site figures group by `tenantlocationid` on the
booking — a column added 2026-08-06. The pre-existing `pickuplocationid` column
is *not* it: that one foreign-keys to `appcustomerlocations`, the B2C customer's
saved address, so writing a client-site id into it fails the insert. Every
booking created before 2026-08-06 has no site at all.
Since the console sends a kitchen's *address* rather than its id,
`createExpressBooking` resolves the site itself — nearest stored location within
150m, falling back to an address match. Bookings with no site are reported as
their own `"Unattributed"` row rather than dropped, so per-site rows still add
up to the summary total. Sending `tenantlocationid` explicitly is exact and
always wins.
**`applocationid` (city) is still not a report parameter.** jupiter had it;
@@ -121,7 +125,7 @@ than one city.
| ~ tenant create/edit | `POST /admin/tenants`, `PUT /admin/tenants/:id` | **Done** |
| ~ location create/edit | `POST /admin/tenants/:id/locations`, `PUT /admin/tenantlocations/:id` | **Done** |
| ~ `getbranches` | `GET /admin/hubs` — *jupiter "branches" ≈ Doormile hubs; verify this is the same concept before relying on it* | **Built** |
| ~ `getlocationsummary` | **Gap** — no per-site rollup, same missing piece as `locationid` above | **Gap** |
| ~ `getlocationsummary` | `GET /admin/locations/summary` — see §2.3 | **Done** |
Doormile adds `locationname` on a tenant location. jupiter identified a site by
its address alone, which does not distinguish two branches on one street.