Add freemium access economy and token store

This commit is contained in:
hz
2026-07-27 22:20:21 -05:00
parent 1d5d03a4f6
commit 4bbac27b84
40 changed files with 1807 additions and 37 deletions
+82
View File
@@ -0,0 +1,82 @@
# Access economy
RanaZe is free to install and use on the public web client and on Steam. An
account is required. The server is authoritative for quotas, credits, token
inventory, prices, and grants.
## QBank limits and credits
- Standard QBank use includes 20 completed questions in a rolling 24-hour
window. An answer or skip consumes one slot.
- An eligible first answer in the current QBank cycle earns one credit,
regardless of correctness. Skips and repeat answers earn no credit.
- A user can earn at most 20 credits in a rolling 24-hour window, including
while an unlimited pass is active.
- 100 earned credits can be redeemed for 24 hours of unlimited standard QBank
use. Credits cannot be purchased.
- Paid access tokens stay in inventory until manually activated. Activation
extends from the later of the current time or the current pass expiration.
Other study tools remain free. An unlimited QBank pass changes only the standard
QBank completion limit.
## Product catalog
| SKU | Grant | Price |
| --- | --- | ---: |
| `access_day_1` | one manually activated 24-hour QBank token | $1.00 |
| `access_week_1` | one manually activated 168-hour QBank token | $5.00 |
| `access_month_1` | one manually activated 720-hour QBank token | $20.00 |
| `exam_token_1` | one exam simulation | $1.99 |
| `qbank_reset_1` | one QBank reset | $4.99 |
A reset requires explicit confirmation and is blocked while an exam simulation
is active. It starts a new personal QBank cycle, resets personal QBank rating
and current-cycle performance, and makes questions eligible as new samples.
Existing global aggregate samples are not removed. Bookmarks, notes, and review
content remain.
Existing accounts begin with zero credits and no tokens. Historical attempts
are not backfilled into credits.
## Web checkout
Web purchases use Stripe-hosted Checkout. Configure:
```text
Stripe__SecretKey
Stripe__AccessWebhookSecret
Stripe__AccessSuccessUrl
Stripe__AccessCancelUrl
```
Create separate access webhook endpoints:
- UAT test mode: `https://us3q.ranaze.com/api/access/stripe-webhook`
- production live mode: `https://s3q.ranaze.com/api/access/stripe-webhook`
Each endpoint has a distinct signing secret. Store them as
`UAT_STRIPE_ACCESS_WEBHOOK_SECRET` and
`PRD_STRIPE_ACCESS_WEBHOOK_SECRET` in Gitea. Subscribe both endpoints to
`checkout.session.completed`, `checkout.session.async_payment_succeeded`,
`checkout.session.async_payment_failed`, and `checkout.session.expired`.
Prices and grants are selected from the API catalog; the client never supplies
an amount. Webhook signatures, expected amount, currency, session, and purchase
ownership are verified before an idempotent grant is applied.
## Steam checkout
The Windows Steam export has the `steam` feature flag and routes purchase
requests to the disabled Steam checkout endpoint. It does not expose Stripe
checkout. The endpoint intentionally returns 503 until the Steamworks AppID,
Microtransactions product catalog, server credentials, callbacks,
reconciliation, refund handling, and sandbox tests are implemented.
## Operational checks
Before release, verify all products in Stripe test mode and then live mode.
Exercise duplicate webhook delivery and concurrent quota submissions. Confirm
that data export/deletion includes `UserAccessAccounts` and `AccessPurchases`.
Monitor rejected checkouts, webhook verification failures, unmatched payments,
grant failures, and quota conflicts.
+275
View File
@@ -0,0 +1,275 @@
# Steam alpha release checklist
Use this as the go/no-go record for the first external Windows alpha of
**RanaZe: Step 3 Trainer**. Put the owner, completion date, and a link to the
evidence beside each checked item. An unchecked **BLOCKER** means do not admit
testers.
## Release decision
- [x] **BLOCKER — Choose the release vehicle.** **Decision: release the app
free on Steam and keep the existing public web client available. Both clients
use the same account access model. QBank passes and study tokens are optional
in-app purchases; Steam purchases remain disabled until Steamworks
Microtransactions are configured.**
- [ ] Record the decision, target date, tester count, supported countries,
tester-selection method, feedback channel, and person with final go/no-go
authority.
- [ ] Define alpha success and stop conditions: minimum completed sessions,
acceptable crash/error rate, critical defect threshold, support response
time, server-capacity ceiling, and the date results will be reviewed.
- [ ] Define the advertised alpha scope. List working features, known
limitations, expected resets or breaking changes, and features explicitly
excluded from this test.
Decision: Free Steam alpha plus the existing public web client; shared freemium access model
Target date/time and time zone: ____________________
Release owner: ____________________
Build commit SHA: ____________________
Steam base AppID: ____________________
Steam Playtest AppID (if used): ____________________
## Steamworks account and application
- [ ] **BLOCKER — Complete Steamworks onboarding.** Verify the legal business
name, bank and tax details, identity verification, Steam Distribution
Agreement, and team permissions.
- [ ] Pay and activate the Steam Direct app credit for the base application
(currently USD 100 per product, subject to tax).
- [ ] Create the base application and save its AppID above.
- [ ] For a Playtest, create the child Playtest app from **Associated Packages
& DLC**, choose its public name carefully, and save its AppID above. The
public Playtest name cannot be changed after release.
- [ ] Restrict Steamworks permissions to the people who need them; require
Steam Guard and make sure at least two trusted people can handle a release.
- [ ] Decide whether the main store page will be public. A Playtest can instead
use keys without making signups or the store page public, but testers should
not be promised confidentiality merely because access is limited.
## Content, legal, and privacy clearance
- [ ] **BLOCKER — Complete the repository's outstanding originality review for
every released question and explanation.** Retain reviewer, date, sources,
revisions, and disposition.
- [ ] **BLOCKER — Complete the outstanding copyright/license audit for every
image-bearing question.** Remove or replace anything whose reuse rights
cannot be established.
- [ ] **BLOCKER — Complete the duplicate-question review and authoritative
reference verification described in `README.md`.** Release only published,
unflagged, cleared content.
- [ ] Review all other shipped assets—branding, fonts, icons, audio, code,
screenshots, trailer footage, and third-party notices—and retain a license
inventory.
- [ ] Have qualified counsel/ownership review the Terms of Service, Privacy
Policy, educational/medical disclaimer, trademark claims, refund/customer
terms, and the handling of study notes or other user-entered data.
- [ ] Confirm the Steam store description and screenshots never imply medical
advice, clinical certification, guaranteed exam performance, or affiliation
with USMLE, NBME, FSMB, or a licensing authority.
- [ ] Complete Steam's Content Survey honestly and make its answers consistent
with both the build and store page.
- [ ] Verify `[email protected]` is monitored and that account data export,
permanent deletion, provider unlinking, and privacy requests work end to end.
- [ ] Publish and test the production legal pages:
`https://step3.ranaze.com/terms.html` and
`https://step3.ranaze.com/privacy.html`.
## Production service readiness
- [ ] **BLOCKER — Complete the initial PRD launch and question promotion in
`ENVIRONMENTS.md`, including dry run, approval, apply, and post-promotion
verification.**
- [ ] Confirm PRD uses a unique JWT key, PRD Mongo database, production host
names, production legal versions, and production secrets; no UAT data or
credentials may be present.
- [ ] Configure and test the live Steam callbacks, including:
`https://s3q.ranaze.com/api/Auth/steam/callback` and
`https://s3q.ranaze.com/api/Auth/external/steam/callback`.
- [ ] From a clean Steam account, test create-account, link-existing-account,
sign-out/sign-in, expired/cancelled authentication, unlinking, and account
deletion. Confirm the app never asks for or receives a Steam password.
- [ ] **BLOCKER — Configure and test Stripe access purchases on the web** at
both `https://us3q.ranaze.com/api/access/stripe-webhook` in test mode and
`https://s3q.ranaze.com/api/access/stripe-webhook` in live mode. Use distinct
signing secrets, subscribe the required Checkout events, and test all five
fixed-price products. Keep the separate contribution flow only if wanted.
- [ ] **BLOCKER — Keep Stripe checkout unavailable in the Steam build.** Before
enabling purchases there, configure Steamworks Microtransactions, product
IDs, callbacks, reconciliation, refunds, and sandbox tests. Confirm the
desktop export carries the `steam` feature flag.
- [ ] Exercise production readiness endpoints and dashboards, and configure
alerts for API unavailability, elevated 5xx responses, authentication
failures, database capacity, and certificate expiry.
- [ ] Load-test the API at the planned tester count plus headroom. Document a
tester-admission cap and who can stop new admissions.
- [ ] Take and restore-test a production database backup. Record retention,
rollback, incident-response, and credential-rotation procedures.
## Windows release build
- [ ] Install the required Godot 4.6.x release export templates and confirm the
pinned engine version used for the release.
- [ ] Update all visible versions from `pre-alpha`/`0.1.0` to the approved alpha
version in `project.godot`, `export_presets.cfg`, the UI, and release notes.
- [ ] Decide whether to disable the Windows console wrapper
(`debug/export_console_wrapper=1`) for tester-facing builds.
- [ ] Decide whether to Authenticode-sign `RanaZe.exe`; if signing, protect the
certificate, timestamp the executable, and verify the signature.
- [ ] Export only from the reviewed release commit, with a clean working tree,
using Git Bash:
```bash
GODOT_BIN=/absolute/path/to/Godot_v4.6.x-stable_win64_console.exe \
./tools/export_steam_release.sh build/windows/RanaZe.exe
```
- [ ] **BLOCKER — Verify the export reports `deployment_environment="prd"`,
the exact release commit in `build_revision`, and only `s3q.ranaze.com`
production API endpoints.**
- [ ] Confirm the upload directory contains `RanaZe.exe`, `RanaZe.pck`, and all
runtime dependencies, but no source, secrets, `.env` files, export backup,
debug symbols not intended for testers, or test data.
- [ ] Virus-scan the staged files and archive a manifest containing SHA-256
hashes, build command, Godot version, commit SHA, build time, and builder.
## SteamPipe and Steam configuration
- [ ] Download the current Steamworks SDK. The SDK is required to upload with
SteamPipe; integrating the Steamworks runtime API is optional for this app's
existing browser-based Steam OpenID flow.
- [ ] Create the Windows depot and default package for the selected AppID.
- [ ] Create version-controlled SteamPipe app/depot VDF templates with AppIDs
but no Steam credentials. Point the depot content root at the staged Windows
directory.
- [ ] Upload through `steamcmd`, add a human-readable build description with
the alpha version and commit SHA, and first assign it to a password-protected
`alpha` branch.
- [ ] Configure the Windows launch option to run `RanaZe.exe` from the depot
root. Verify OS is Windows and architecture is 64-bit.
- [ ] Set supported language(s) to match what is actually available in the
build. Do not claim interface, audio, or subtitle support that has not been
tested.
- [ ] Configure install/uninstall behavior and required redistributables, if
any. Confirm uninstall does not remove cloud/server account data and that
locally generated sensitive files are understood.
- [ ] If using a Playtest, upload and configure the build on the **Playtest
AppID**, not merely the base game's depot.
- [ ] Test installation, launch, update, rollback, file verification, uninstall,
and reinstall entirely through the Steam client—never only by running the
local export.
## Store and tester communication
- [ ] Prepare truthful short and long descriptions, developer/publisher names,
tags, platform/language support, system requirements, support contact, and
privacy-policy URL.
- [ ] Create required store, library, community, and client graphical assets at
Steam's current dimensions. Use actual alpha screenshots and clearly label
footage or features that are not representative of the current build.
- [ ] Check all asset rights and Steam's graphical asset rules. Localize text
appearing in graphical assets for every language the game claims to support.
- [ ] For Early Access only, complete the Early Access questionnaire, describe
the current state and update plan without promises the team cannot guarantee,
set a price justified by the current build, and use required Early Access
branding wherever keys are sold.
- [ ] Draft tester instructions covering scope, known issues, medical
disclaimer, feedback/bug-report format, log/screenshot handling, privacy,
support hours, update/reset expectations, and test end date.
- [ ] Draft the launch announcement, first patch notes, outage message, and
alpha-ending message before admitting testers.
## Release-candidate acceptance
- [ ] Promote the exact uploaded build to the protected `alpha` branch and have
at least two people test it independently on clean Windows 10 and Windows 11
user profiles.
- [ ] Test at 1920×1080 plus a smaller supported resolution and at 100%, 125%,
and 150% Windows scaling. Check keyboard/mouse navigation, text clipping,
external browser transitions, focus return, and readable error states.
- [ ] Run the complete learning journey: registration and legal consent,
practice question, randomized choices, answer/explanation/reference,
dashboard, review queue, notes/bookmarks, flashcards, CCS, feedback/report,
data export, and account deletion.
- [ ] Run the access journey on web: questions 1–20, rolling-window exhaustion,
one credit per eligible first attempt, no credit for skips/repeats, the
20-credit earning cap, 100-credit redemption, purchase and manual activation
of each pass, exam-token consumption, reset confirmation, and retained
bookmarks/notes after reset.
- [ ] Test offline start, connection loss during a session, API timeout, expired
token, server maintenance, malformed response, and recovery without corrupting
learner progress.
- [ ] Run automated API/Godot tests and the production-equivalent smoke suite;
attach results to the release record. Do not rely only on the web UAT smoke
suite for the Windows Steam build.
- [ ] Verify every feature and claim shown on the store page exists in the
submitted build.
- [ ] Triage all findings. Zero unresolved critical issues; every accepted
non-critical issue has an owner, rationale, workaround, and target release.
- [ ] Obtain written sign-off from engineering, content/medical review, legal/
privacy, operations, and the release owner.
## Valve review and scheduling
- [ ] Complete the selected app's Steamworks store-presence checklist and submit
it for review. Valve advises allowing at least seven business days even though
reviews commonly take three to five business days.
- [ ] After store presence is submitted, complete the game-build checklist,
place a mostly final build on the default branch for Valve, and submit the
build for review.
- [ ] Resolve every Valve review note and repeat the relevant acceptance tests
against any changed build or store material.
- [ ] If publishing the main Coming Soon page, allow at least the current
Steam-required visibility period before an Early Access/full release. Confirm
the exact eligible release date shown in Steamworks rather than calculating
it from memory.
- [ ] For a Playtest, choose limited or open signup, batch size/countries, or
key distribution. Never charge for Playtest access or sell Playtest keys.
- [ ] Schedule the release while the release owner, backend operator, and
support contact are available for the initial monitoring window.
## Launch day
- [ ] Freeze unrelated PRD and client changes; confirm the approved commit,
Steam build ID, depot manifest, store copy, tester count, and rollback build.
- [ ] Re-run public health/readiness checks, login, one question flow, feedback,
legal links, database backup status, alerts, and Steam callback.
- [ ] Set the approved build live on the intended Steam branch.
- [ ] For a Playtest, set the app **Playable**, then admit only the planned
first batch or enable the approved signup mode.
- [ ] Install and launch from a tester account with no developer permissions.
Verify download size, executable, version/SHA, production environment, and
end-to-end authentication.
- [ ] Publish tester instructions/announcement and open the staffed feedback
channel.
- [ ] Record release time, Steam build ID, admitted tester count, incidents,
decisions, and changes in the release log.
## Monitoring, rollback, and alpha close
- [ ] Monitor API/error/auth rates, capacity, reports, support inbox, Steam
discussions, and content-safety feedback at the defined cadence.
- [ ] Acknowledge critical medical-accuracy or copyright reports immediately;
unpublish affected content while it is reviewed.
- [ ] Stop admissions for capacity or support overload. Set the Playtest to
**Not Playable** or roll back its live branch when a stop condition is met,
and communicate the impact to testers.
- [ ] Patch from a reviewed commit, repeat affected acceptance tests, upload to
the protected branch, test through Steam, then promote the exact build.
- [ ] At alpha end, announce the deadline, stop signups, communicate account/
progress retention, and set the Playtest to **Not Playable** when appropriate.
- [ ] Export metrics without exposing personal data; triage feedback into owned
work; hold a retrospective; document the next test's entry criteria.
- [ ] Retain build manifests, approvals, test evidence, incidents, content
review records, and the final release log according to the team's policy.
## Official Steam references
- [Steam Playtest](https://partner.steamgames.com/doc/features/playtest)
- [Steam release process](https://partner.steamgames.com/doc/store/releasing)
- [Steam review process](https://partner.steamgames.com/doc/store/review_process)
- [Uploading to Steam / SteamPipe](https://partner.steamgames.com/doc/sdk/uploading)
- [Steam Direct fee](https://partner.steamgames.com/doc/gettingstarted/appfee)
- [Steamworks onboarding](https://partner.steamgames.com/doc/gettingstarted/onboarding)
- [Content Survey](https://partner.steamgames.com/doc/gettingstarted/contentsurvey)
- [Early Access](https://partner.steamgames.com/doc/store/earlyaccess)
- [Store graphical assets](https://partner.steamgames.com/doc/store/assets/standard)
+11 -8
View File
@@ -7,9 +7,9 @@ Contributions are not tax-deductible.
## Stripe test-mode setup
1. In the Stripe Dashboard, switch to test mode.
2. Create a webhook endpoint at:
2. Create the UAT test-mode webhook endpoint at:
`https://s3q.ranaze.com/api/donations/stripe-webhook`
`https://us3q.ranaze.com/api/donations/stripe-webhook`
3. Subscribe the endpoint to these events:
@@ -22,10 +22,12 @@ Contributions are not tax-deductible.
5. Copy a test secret API key (`sk_test_...`).
6. Add both values as Gitea Actions secrets in the API repository:
- `STRIPE_SECRET_KEY`
- `STRIPE_WEBHOOK_SECRET`
- `UAT_STRIPE_SECRET_KEY`
- `UAT_STRIPE_WEBHOOK_SECRET`
The deployment workflow writes these values to the Kubernetes secret `medmind-stripe`. Never commit either value to the repository.
The deployment workflow writes these values to the environment's
`step3-runtime-secrets` Kubernetes secret. Never commit either value to the
repository.
## Stripe account settings
@@ -47,9 +49,10 @@ The client-visible status endpoint returns only the donation ID, amount, currenc
## Live-mode cutover
1. Create the same webhook endpoint in Stripe live mode.
2. Replace `STRIPE_SECRET_KEY` with the live secret key (`sk_live_...`).
3. Replace `STRIPE_WEBHOOK_SECRET` with the live endpoint's signing secret.
1. Create `https://s3q.ranaze.com/api/donations/stripe-webhook` in Stripe live
mode.
2. Set `PRD_STRIPE_SECRET_KEY` to the live secret key (`sk_live_...`).
3. Set `PRD_STRIPE_WEBHOOK_SECRET` to that endpoint's signing secret.
4. Trigger a deployment and complete a small real contribution.
5. Confirm the payment, receipt, webhook delivery, and `paid` status before announcing availability.