mirror of
https://github.com/nestriness/nestri.git
synced 2026-09-19 09:15:19 +03:00
Every team now exists with the payment provider, free ones included. An upgrade then changes a subscription rather than inventing a customer, and there is one question to ask about anybody instead of two. A subscription at nothing a month needs no payment, so it is created outright rather than by sending somebody through a checkout to pay zero. It runs after the team rows are committed and cannot affect them. Signing up is not allowed to depend on a third party being reachable, so this cannot fail the call and does not retry — a team that misses it is free, which is what it would have been anyway, and the next call puts it right because the operation is idempotent. This broke the webhook mapping, which read the plan off the event type. A free subscription announces itself with the same `subscription.created` a paid one does, so every new signup would have landed on the paid allowance. The plan now comes from the product, and a product we do not sell is left alone rather than guessed at — somebody selling something else through the same account must not be able to change what a team may run by doing so. The external id stays the team. It is the billing subject, and keying on the user would collapse somebody with two teams into one customer with no way to say which subscription belonged to which.
51 lines
2.3 KiB
Plaintext
51 lines
2.3 KiB
Plaintext
# Copy to `.env` before `docker compose up`. Compose reads every credential
|
|
# from here and has no defaults of its own — it refuses to start naming the
|
|
# variable it wanted rather than falling back to a value that would be public.
|
|
|
|
# The local database. Throwaway values are fine; these three are what compose
|
|
# creates the container with and what it builds DATABASE_URL from.
|
|
POSTGRES_USER=postgres
|
|
POSTGRES_PASSWORD=postgres
|
|
POSTGRES_DB=nestri
|
|
|
|
# For anything run outside a container — `bun dev`, `bun run db:migrate`.
|
|
DATABASE_URL=postgres://postgres:postgres@localhost:5432/nestri
|
|
|
|
# The database the tests run against. Required — DB-backed tests refuse to run
|
|
# rather than fall back to a database nobody named.
|
|
#
|
|
# **Point it at the same database as DATABASE_URL above.** "Isolated" means
|
|
# isolated from anything you care about, not isolated from DATABASE_URL: route
|
|
# tests reach the database through the app and core tests reach it directly, so
|
|
# two different values put the fixtures in one database and the assertions in
|
|
# the other. That fails around forty tests, in neither half's own code, with
|
|
# nothing in the output pointing at this line.
|
|
TEST_DATABASE_URL=postgres://postgres:postgres@localhost:5432/nestri
|
|
|
|
# The issuer's public URL — the address a token's `iss` claim will carry.
|
|
AUTH_ISSUER_URL=http://localhost:1337
|
|
# Where to reach the issuer, if that is not where it lives. Unset unless the
|
|
# public name is unroutable from where the API runs; docker compose sets it.
|
|
AUTH_INTERNAL_URL=
|
|
|
|
# Mail delivery. All three together, or none of them plus EMAIL_DEV_LOG=true,
|
|
# which prints sign-in codes to the log instead of sending them. Printing them
|
|
# is a local-development convenience and nothing else.
|
|
EMAIL_SEND_URL=
|
|
EMAIL_API_KEY=
|
|
EMAIL_FROM=
|
|
EMAIL_DEV_LOG=true
|
|
|
|
# Billing. The provider's sandbox and production are separate servers with
|
|
# separate data, so a token from one is refused by the other and a product id
|
|
# from one means nothing to it. `POLAR_SERVER` says which you are talking to.
|
|
POLAR_SERVER=sandbox
|
|
POLAR_ACCESS_TOKEN=
|
|
POLAR_PRODUCT_ID=
|
|
# The product every team is put on at signup, priced at nothing. A free
|
|
# subscription needs no checkout, so it is created outright.
|
|
POLAR_FREE_PRODUCT_ID=
|
|
# Signs every webhook delivery. Without it the webhook route refuses everything,
|
|
# on purpose: nothing else stands in front of it.
|
|
POLAR_WEBHOOK_SECRET=
|