docs: align README with production runtime and coolify deployment steps
This commit is contained in:
105
README.md
105
README.md
@@ -310,40 +310,95 @@ If one credit pack gives `10` base articles and sells at `$9.99`, target:
|
|||||||
|
|
||||||
This repository now contains an implemented MVP aligned to this architecture.
|
This repository now contains an implemented MVP aligned to this architecture.
|
||||||
|
|
||||||
## Implemented MVP (current repo)
|
## Production App In This Repo
|
||||||
|
|
||||||
This repository now includes a runnable MVP server and tests for core flows.
|
This repository now contains a deployable production-style app (single container runtime) that implements the required flows from this spec.
|
||||||
|
|
||||||
### Stack in this repo
|
### Implemented capabilities
|
||||||
1. Node.js HTTP server (`src/server.js`).
|
1. Public landing page with product narrative and pricing logic.
|
||||||
2. Domain modules for credits, wallet ledger, article extraction, access grants, and webhook signatures.
|
2. Mobile-first authenticated dashboard (`/app`) with:
|
||||||
3. Mobile-first server-rendered UI using `daisyUI` stylesheet via CDN.
|
- credit top-up action
|
||||||
4. PWA basics (`/manifest.webmanifest`, `/sw.js`).
|
- mention simulation action (for testing the generation flow)
|
||||||
|
- audiobook history
|
||||||
|
3. Access-controlled audiobook pages (`/audio/:id`) with:
|
||||||
|
- owner access
|
||||||
|
- unauthenticated login prompt
|
||||||
|
- non-owner pay-to-unlock (same credit amount, permanent unlock)
|
||||||
|
4. Webhook-first ingestion and billing:
|
||||||
|
- `POST /api/webhooks/x` (HMAC verified)
|
||||||
|
- `POST /api/webhooks/polar` (HMAC verified)
|
||||||
|
5. Persistent state across restarts:
|
||||||
|
- all wallet/job/asset/access state is snapshotted and stored to `STATE_FILE_PATH`
|
||||||
|
6. Abuse protection:
|
||||||
|
- fixed-window rate limiting for webhook, auth, and action routes
|
||||||
|
7. PWA support:
|
||||||
|
- `manifest.webmanifest`
|
||||||
|
- `sw.js`
|
||||||
|
|
||||||
### Auth model in MVP
|
### Authentication model
|
||||||
1. API auth is represented by `x-user-id` request header.
|
1. Browser flow uses secure-ish HTTP-only cookie session (`xartaudio_user`) via `/auth/dev-login`.
|
||||||
2. This is a development placeholder for future `Login with X OAuth`.
|
2. API calls also support `x-user-id` header for scripted usage/testing.
|
||||||
|
3. This auth layer is intentionally replaceable with X OAuth in production rollout.
|
||||||
|
|
||||||
### Core endpoints
|
### Runtime endpoints
|
||||||
1. `POST /api/webhooks/x` -> mention webhook ingestion (HMAC verified).
|
1. Public:
|
||||||
2. `POST /api/webhooks/polar` -> credit top-up webhook (HMAC verified).
|
- `GET /`
|
||||||
3. `GET /api/me/wallet` -> caller wallet balance.
|
- `GET /login`
|
||||||
4. `GET /api/jobs/:id` -> caller job status.
|
- `GET /audio/:id`
|
||||||
5. `POST /api/audio/:id/unlock` -> pay same credits and unlock permanent access.
|
2. Browser actions:
|
||||||
6. `GET /audio/:id` -> playback access page (owner/grant/auth/payment states).
|
- `POST /auth/dev-login`
|
||||||
7. `GET /` -> mobile-first dashboard.
|
- `POST /auth/logout`
|
||||||
|
- `POST /app/actions/topup`
|
||||||
|
- `POST /app/actions/simulate-mention`
|
||||||
|
- `POST /audio/:id/unlock`
|
||||||
|
3. APIs:
|
||||||
|
- `POST /api/webhooks/x`
|
||||||
|
- `POST /api/webhooks/polar`
|
||||||
|
- `GET /api/me/wallet`
|
||||||
|
- `GET /api/jobs/:id`
|
||||||
|
- `POST /api/audio/:id/unlock`
|
||||||
|
- `GET /health`
|
||||||
|
|
||||||
### Local commands
|
### Local commands
|
||||||
1. `npm test` -> run full test suite.
|
1. `npm test`
|
||||||
2. `npm run start` -> start server (port from `PORT`, default `3000`).
|
2. `npm run start`
|
||||||
|
3. `npm run dev`
|
||||||
|
|
||||||
### Important environment notes
|
### Environment variables
|
||||||
1. Credit policy is configurable via env:
|
Use `.env.example` as the source of truth.
|
||||||
|
|
||||||
|
1. Runtime:
|
||||||
|
- `PORT`
|
||||||
|
- `STATE_FILE_PATH`
|
||||||
|
2. Secrets:
|
||||||
|
- `X_WEBHOOK_SECRET`
|
||||||
|
- `POLAR_WEBHOOK_SECRET`
|
||||||
|
3. Credit model:
|
||||||
- `BASE_CREDITS`
|
- `BASE_CREDITS`
|
||||||
- `INCLUDED_CHARS`
|
- `INCLUDED_CHARS`
|
||||||
- `STEP_CHARS`
|
- `STEP_CHARS`
|
||||||
- `STEP_CREDITS`
|
- `STEP_CREDITS`
|
||||||
- `MAX_CHARS_PER_ARTICLE`
|
- `MAX_CHARS_PER_ARTICLE`
|
||||||
2. Webhook secrets:
|
4. Rate limits:
|
||||||
- `X_WEBHOOK_SECRET`
|
- `WEBHOOK_RPM`
|
||||||
- `POLAR_WEBHOOK_SECRET`
|
- `AUTH_RPM`
|
||||||
|
- `ACTION_RPM`
|
||||||
|
|
||||||
|
## Coolify Deployment
|
||||||
|
|
||||||
|
1. Create a new service from this repository and select `Dockerfile` build mode.
|
||||||
|
2. Set container port to `3000`.
|
||||||
|
3. Add a persistent volume mounted at `/data`.
|
||||||
|
4. Set `STATE_FILE_PATH=/data/state.json`.
|
||||||
|
5. Configure all secrets and policy env vars from `.env.example`.
|
||||||
|
6. Expose HTTPS URL and point providers to:
|
||||||
|
- `https://<your-domain>/api/webhooks/x`
|
||||||
|
- `https://<your-domain>/api/webhooks/polar`
|
||||||
|
7. Verify deployment health with `GET /health`.
|
||||||
|
|
||||||
|
## Production Checklist
|
||||||
|
|
||||||
|
1. Replace dev-login cookie auth with X OAuth before public launch.
|
||||||
|
2. Connect real TTS generation worker and object storage (S3/R2/GCS).
|
||||||
|
3. Replace local state file with managed database for multi-replica scaling.
|
||||||
|
4. Add structured logging, tracing, and external alerting.
|
||||||
|
|||||||
Reference in New Issue
Block a user