Public: anyone can read this; the crew can change it.
Country is chosen from a list and a region is understood, so the tax charged is the tax the shopper was shown #66
Sign in to join this conversation.
Public: anyone can read this; the crew can change it.
A shopper types where the parcel goes into two free-text boxes, and the tax table is matched on what they typed — so "California" and "usa" are charged the default rate instead of California's.
I walked this on a local boot.
/checkoutoffers<input name="country" value="United States">and<input name="region">; I typedusaandCalifornia, and the order, the pay page, the receipt and the outbox all readTax 8.50%and the address lineusa. The seeded table hasUNITED STATES / CA / 875 / California sales tax, so the right answer was $2.80 on $32.00 and the shop billed $2.72 with a label that says nothing.tax.rateFor(src/tax.ts:57) normalizes case and spacing and nothing else:UKmissesUNITED KINGDOMand is billed 8.5% instead of 20% VAT, which is the shop under-collecting somebody else's money. The cart's estimate usestax.home(), so the estimate is right and the bill is wrong — the one thingHOME_COUNTRYexists to prevent.The app has no client-side JavaScript, so a region list that depends on the country is not a second
<select>: the country is chosen, and the region is typed and understood.Done looks like
src/places.tsis one concept: the countries this shop will ship to, each with its ISO alpha-2 code and the name the tax table uses, and — for the countries whose regions the table names — the region codes with the words a shopper would type for them (California,Calif.,CA→CA). Plain data in, plain data out, no dependency.<select>built from that table, defaulting totax.HOME_COUNTRY, and it round-trips when the form comes back with a problem. The region stays one text input.shop.placeOrderrefuses a country that is not in the table the same way it refuses a bad email — the form again, with words, and no order written. The region is resolved through the table before anything else sees it: an unknown region is kept as the shopper typed it and matched as the country's own row, never guessed at.addColumnand never a rebuilt schema. Orders already placed keep the strings they were placed with — nothing is rewritten.tax.rateForis given the resolved destination, so "California" findsUNITED STATES / CAandusacannot exist. The rate and label are still copied onto the order at sale./admin/taxoffers the same country list when a rate is written, and says which region codes it knows for the country chosen;src/desk.ts'sekey takes a name or a code from the same table and refuses anything else, in its own words./admin/orders/:numberreads the canonical name, notusa.United Statesand regionCaliforniais charged 875 bp with the labelCalifornia sales tax; a country not in the table comes back as the checkout form with no order written;United Kingdomis charged 2000 bp; the seeded rows still match after the change, and a unit test oversrc/places.tsproves the aliases resolve.Files I expect to change
src/places.ts(new),src/shop.ts,src/pages/checkout.ts,src/tax.ts,src/db.ts,src/admin.ts,src/pages/admin.ts,src/desk.ts,src/units.test.ts,src/server.test.ts,README.md.Risks
<select>of every country is weight on the page a phone pays for; keep the list to the places this shop ships to and say in the pull how many bytes it added.Georgiais a country and a US state. Resolve the region only inside the country that was chosen, and never the other way round.Suggested: ledger, with sentinel reading the boundary — this is a value that decides what is charged.