mirror of
https://github.com/Dvorinka/Bookra.git
synced 2026-10-28 23:51:17 +00:00
refactor(db): replace sqlc with handwritten pgx repos
- Finish Paddle-to-Stripe billing migration; drop paddle/stripe libs - Renumber migrations; add 00012 memberships+manage_token, 00013 location_type_capacity - Add tests: admin, auth, bookings customer service - Remove graphify-out artifacts and stale env files Authored By: TDvorak <[email protected]> Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
2039669e2c
commit
f2f7439050
93 files changed
+6987
-69060
No files matched your search
+37
-30
@@ -1,13 +1,13 @@
|
||||
# Bookra Backend
|
||||
|
||||
Go + Gin API for Bookra, designed for Railway deployment with Neon Auth, Neon Postgres, and Paddle billing.
|
||||
Go + Gin API for Bookra, designed for Railway deployment with Neon Auth, Neon Postgres, and Stripe billing.
|
||||
|
||||
## Commands
|
||||
|
||||
```bash
|
||||
go run ./cmd/api
|
||||
go build ./...
|
||||
npm run db:generate
|
||||
go test ./...
|
||||
npm run db:migrate:status
|
||||
npm run db:migrate:up
|
||||
```
|
||||
@@ -18,57 +18,64 @@ npm run db:migrate:up
|
||||
- `BOOKRA_DATABASE_URL` Neon pooled connection
|
||||
- `BOOKRA_DATABASE_DIRECT_URL` Neon direct connection for migrations/admin tasks
|
||||
- `BOOKRA_NEON_AUTH_URL` Neon Auth base URL used for JWKS verification
|
||||
- `BOOKRA_AUTH_JWT_SECRET` optional local JWT fallback when not using Neon Auth
|
||||
- `BOOKRA_JOB_RUNNER_KEY` shared secret for remote reminder dispatch calls
|
||||
- `BOOKRA_AUTH_JWT_SECRET` local JWT secret for the password-auth endpoints
|
||||
- `BOOKRA_JOB_RUNNER_KEY` shared secret for remote job-runner calls
|
||||
- `BOOKRA_EMAIL_FROM` sender identity for email reminders
|
||||
- `BOOKRA_PADDLE_ENV` billing environment: `sandbox` or `live`
|
||||
- `BOOKRA_PADDLE_API_KEY` Paddle API key
|
||||
- `BOOKRA_PADDLE_WEBHOOK_SECRET` Paddle notification destination secret
|
||||
- `BOOKRA_PADDLE_{STARTER,PRO,BUSINESS}_{CZK,USD}_PRICE_ID` Paddle price IDs
|
||||
- `BOOKRA_SMTP_*` optional SMTP transport for email delivery
|
||||
- `BOOKRA_STRIPE_API_KEY` Stripe secret API key
|
||||
- `BOOKRA_STRIPE_WEBHOOK_SECRET` Stripe webhook signing secret
|
||||
- `BOOKRA_STRIPE_{STARTER,PRO,BUSINESS}_{CZK,USD}_{MONTHLY,YEARLY}_PRICE_ID` Stripe price IDs
|
||||
- `BOOKRA_STRIPE_SMS_{CZK,USD,...}_PRICE_ID` Stripe SMS usage price IDs
|
||||
- `BOOKRA_SMSMANAGER_API_KEY` optional SMS Manager.cz key
|
||||
- `BOOKRA_UMAMI_API_URL` and `BOOKRA_UMAMI_API_KEY` optional analytics integration
|
||||
- `BOOKRA_ADMIN_EMAIL` and `BOOKRA_ADMIN_KEY` optional platform admin API credentials
|
||||
- `BOOKRA_SENTRY_DSN` optional error monitoring
|
||||
|
||||
See `.env.example` for the full list.
|
||||
|
||||
## Notes
|
||||
|
||||
- Auth verification is isolated in `internal/auth`.
|
||||
- OpenAPI lives in `openapi/bookra.openapi.yaml`.
|
||||
- SQL migrations live in `migrations/`.
|
||||
- `sqlc.yaml` is wired through `npm run db:generate`.
|
||||
- SQL migrations live in `migrations/` (goose).
|
||||
- Repositories are handwritten pgx in `internal/db/`; there is no generated query layer.
|
||||
- Goose migrations are wired through `npm run db:migrate:*` and use the Neon direct connection URL.
|
||||
- Reminder dispatch now runs through `POST /v1/internal/jobs/reminders/dispatch` with `X-Bookra-Job-Key`.
|
||||
- Reminder dispatch runs through `POST /v1/internal/jobs/reminders/dispatch` with `X-Bookra-Job-Key`.
|
||||
- `BOOKRA_DEMO_MODE=true` swaps the repository for deterministic in-memory demo data and authenticates all requests as `demo-owner`.
|
||||
|
||||
## Production Auth
|
||||
|
||||
Bookra production auth should use Neon Auth directly:
|
||||
Bookra production auth uses Neon Auth directly:
|
||||
|
||||
- frontend uses `VITE_NEON_AUTH_URL`
|
||||
- backend verifies Neon JWTs with `BOOKRA_NEON_AUTH_URL`
|
||||
- auth-service may stay deployed for standalone auth/admin workflows, but backend billing and app APIs do not depend on it
|
||||
|
||||
Trusted redirect domains in Neon Auth should include your frontend origin such as `https://bookra.eu`, plus local dev origins when needed.
|
||||
|
||||
## Paddle Setup
|
||||
## Stripe Setup
|
||||
|
||||
Get these values from Paddle dashboard:
|
||||
Get these values from the Stripe dashboard:
|
||||
|
||||
- `BOOKRA_PADDLE_ENV`: `sandbox` for testing, `live` for production
|
||||
- `BOOKRA_PADDLE_API_KEY`: Developer tools -> Authentication
|
||||
- `BOOKRA_PADDLE_WEBHOOK_SECRET`: Notification settings -> destination secret key
|
||||
- `BOOKRA_PADDLE_*_PRICE_ID`: Catalog -> each SaaS plan recurring price ID
|
||||
- `BOOKRA_STRIPE_API_KEY`: Developers -> API keys -> secret key
|
||||
- `BOOKRA_STRIPE_WEBHOOK_SECRET`: Developers -> Webhooks -> destination signing secret
|
||||
- `BOOKRA_STRIPE_*_PRICE_ID`: Product catalog -> recurring price IDs
|
||||
|
||||
Create one recurring price per plan/currency you support:
|
||||
Create one recurring price per plan/currency/interval you support:
|
||||
|
||||
- `starter` `czk`
|
||||
- `starter` `usd`
|
||||
- `pro` `czk`
|
||||
- `pro` `usd`
|
||||
- `business` `czk`
|
||||
- `business` `usd`
|
||||
- `starter` / `pro` / `business` × `czk` / `usd` × `monthly` / `yearly`
|
||||
|
||||
Set your webhook destination to:
|
||||
Set the webhook destination to:
|
||||
|
||||
```text
|
||||
POST /v1/webhooks/paddle
|
||||
POST /api/paddle_webhook
|
||||
POST /v1/webhooks/stripe
|
||||
```
|
||||
|
||||
Use Paddle webhook simulator for event testing.
|
||||
Subscribe to at least: `checkout.session.completed`, `customer.subscription.created`,
|
||||
`customer.subscription.updated`, `customer.subscription.deleted`,
|
||||
`invoice.payment_succeeded`, `invoice.payment_failed`.
|
||||
|
||||
For local testing:
|
||||
|
||||
```bash
|
||||
stripe listen --forward-to http://localhost:8080/v1/webhooks/stripe
|
||||
```
|
||||
Reference in new issue
Block a user