naming cleanup and readme changes

This commit is contained in:
Devin Zuczek
2026-06-30 15:00:22 -04:00
parent 87581ddbcf
commit a6df6a435e
5 changed files with 78 additions and 11 deletions
+2 -2
View File
@@ -3,7 +3,7 @@ RECFLARE_DOMAIN=rec.example.com
# Optional per-app subdomain overrides, as a compact JSON object keyed by the # Optional per-app subdomain overrides, as a compact JSON object keyed by the
# worker's directory name. Defaults to the directory name when unset. # worker's directory name. Defaults to the directory name when unset.
# RECFLARE_SUBDOMAINS={"playersettings":"settings"} # RECFLARE_SUBDOMAINS='{"playersettings":"settings"}'
# Id of the shared `recflare` D1 database (create it manually with # Id of the shared `recflare` D1 database (create it manually with
# `wrangler d1 create recflare`). All D1-backed workers bind this one database. # `wrangler d1 create recflare`). All D1-backed workers bind this one database.
@@ -15,4 +15,4 @@ RECFLARE_DOMAIN=rec.example.com
# is distinct (create with `wrangler kv namespace create <BINDING>`). Kept out of # is distinct (create with `wrangler kv namespace create <BINDING>`). Kept out of
# the committed wrangler.jsonc (which uses "local" placeholders) and spliced in at # the committed wrangler.jsonc (which uses "local" placeholders) and spliced in at
# deploy time. Required to deploy any worker with the matching KV binding. # deploy time. Required to deploy any worker with the matching KV binding.
# RECFLARE_KV={"RECFLARE_MATCH_PRESENCE":"9f53f04b7dd244658d59f515a14748b6","RECFLARE_PLAYER_SETTINGS":"d33a90014e904b0eac720bddcbe0b036"} # RECFLARE_KV='{"RECFLARE_MATCH_PRESENCE":"9f53f04b7dd244658d59f515a14748b6","RECFLARE_PLAYER_SETTINGS":"d33a90014e904b0eac720bddcbe0b036"}'
+71 -4
View File
@@ -172,7 +172,72 @@ document and the api share-link base URL are built at runtime. Nothing in versio
control is rewritten; committed `wrangler.jsonc` files have no routes. control is rewritten; committed `wrangler.jsonc` files have no routes.
Per-app subdomain overrides come from Per-app subdomain overrides come from
`RECFLARE_SUBDOMAINS` (a JSON object, e.g. `{"playersettings":"settings"}`). `RECFLARE_SUBDOMAINS` (a JSON object, e.g. `'{"playersettings":"settings"}'`).
**Create the storage resources:**
The workers bind Cloudflare storage primitives — one shared D1 database, two KV
namespaces, two R2 buckets, and a Durable Object. Create them once against your
Cloudflare account, then record the ids in `.env`. The committed `wrangler.jsonc`
files carry `"local"` placeholders; the real ids are spliced in at deploy time, so
nothing in version control needs editing. Authenticate wrangler first
(`wrangler login`).
_D1 — one shared `recflare` database_ (bound by `api`, `accounts`, `auth`, `match`,
`rooms`):
```bash
wrangler d1 create recflare
# copy the printed database_id into .env:
# RECFLARE_D1=<database_id>
```
Then apply the schema. The `rooms` and `auth` workers own the migrations under
their `apps/<worker>/migrations/` directories. Remote operations need the real id
in the config (the committed file only has the `"local"` placeholder), so splice
it in the same way the deploy does — from each owning worker, with `RECFLARE_D1`
exported:
```bash
cd apps/rooms # then repeat for apps/auth
sed -E "s/\"database_id\": *\"local\"/\"database_id\": \"$RECFLARE_D1\"/" \
wrangler.jsonc >wrangler.generated.jsonc
wrangler d1 migrations apply recflare --remote --config wrangler.generated.jsonc
rm wrangler.generated.jsonc
```
For the local dev database no id is needed — it uses the `"local"` placeholder
directly: `wrangler d1 migrations apply recflare --local`.
_KV — two namespaces_ (`RECFLARE_MATCH_PRESENCE` for `match`/`auth`,
`RECFLARE_PLAYER_SETTINGS` for `playersettings`):
```bash
wrangler kv namespace create RECFLARE_MATCH_PRESENCE
wrangler kv namespace create RECFLARE_PLAYER_SETTINGS
```
Record both ids in `.env` as a single JSON object keyed by binding name (note the
surrounding single quotes — without them the shell strips the inner quotes):
```bash
RECFLARE_KV='{"RECFLARE_MATCH_PRESENCE":"<id>","RECFLARE_PLAYER_SETTINGS":"<id>"}'
```
_R2 — two buckets_ (`recflare-cdn` for `cdn`, `recflare-img` for `api`/`img`):
```bash
wrangler r2 bucket create recflare-cdn
wrangler r2 bucket create recflare-img
```
R2 buckets are referenced by name in the committed `wrangler.jsonc`, so there is
nothing to add to `.env`. See [`apps/img/README.md`](apps/img/README.md) for
seeding the default avatar/profile images.
_Durable Objects — no manual setup_. The `notify` worker's `RECFLARE_NOTIFICATIONS_HUB`
binding (class `NotificationsHub`) is provisioned automatically from the migration
declared in its `wrangler.jsonc` on first deploy — there is no id to create or set.
**Run the development microservices:** **Run the development microservices:**
@@ -191,9 +256,11 @@ just deploy
Deploying requires `wrangler` to be authenticated against your Cloudflare Deploying requires `wrangler` to be authenticated against your Cloudflare
account (`wrangler login`, or `CLOUDFLARE_API_TOKEN` / `CLOUDFLARE_ACCOUNT_ID` account (`wrangler login`, or `CLOUDFLARE_API_TOKEN` / `CLOUDFLARE_ACCOUNT_ID`
in the environment). Storage resources (D1 databases, KV namespaces, R2 buckets) in the environment). It also requires the storage resources to exist and their
must be created and their ids set in each worker's `wrangler.jsonc` — see the ids to be set in `.env` — see **Create the storage resources** above. At deploy
inline comments in those files for the exact `wrangler` commands. time the deploy script splices `RECFLARE_D1` and `RECFLARE_KV` into the `"local"`
placeholders in each worker's `wrangler.jsonc`; a missing id fails the deploy with
a message naming the binding.
## Repository Structure ## Repository Structure
+1 -1
View File
@@ -4,7 +4,7 @@ import type { SharedHonoEnv, SharedHonoVariables } from '@repo/hono-helpers/src/
export type Env = SharedHonoEnv & { export type Env = SharedHonoEnv & {
/** Durable Object hosting the SignalR notifications hub. */ /** Durable Object hosting the SignalR notifications hub. */
NOTIFICATIONS_HUB: DurableObjectNamespace<NotificationsHub> RECFLARE_NOTIFICATIONS_HUB: DurableObjectNamespace<NotificationsHub>
} }
/** Variables can be extended */ /** Variables can be extended */
+3 -3
View File
@@ -52,7 +52,7 @@ const app = new Hono<App>()
if ((c.req.header('upgrade') ?? '').toLowerCase() !== 'websocket') { if ((c.req.header('upgrade') ?? '').toLowerCase() !== 'websocket') {
return c.json({ error: 'Expected a WebSocket upgrade request' }, 426) return c.json({ error: 'Expected a WebSocket upgrade request' }, 426)
} }
return c.env.NOTIFICATIONS_HUB.getByName(HUB_INSTANCE).fetch(c.req.raw) return c.env.RECFLARE_NOTIFICATIONS_HUB.getByName(HUB_INSTANCE).fetch(c.req.raw)
}) })
// ---- Internal service-to-service send/broadcast -------------------------- // ---- Internal service-to-service send/broadcast --------------------------
@@ -65,7 +65,7 @@ const app = new Hono<App>()
if (!body || typeof body.playerId !== 'number' || typeof body.notificationType !== 'number') { if (!body || typeof body.playerId !== 'number' || typeof body.notificationType !== 'number') {
return c.json({ error: 'playerId and notificationType are required' }, 400) return c.json({ error: 'playerId and notificationType are required' }, 400)
} }
const result = await c.env.NOTIFICATIONS_HUB.getByName(HUB_INSTANCE).notifyPlayer( const result = await c.env.RECFLARE_NOTIFICATIONS_HUB.getByName(HUB_INSTANCE).notifyPlayer(
body.playerId, body.playerId,
body.notificationType, body.notificationType,
body.data body.data
@@ -80,7 +80,7 @@ const app = new Hono<App>()
if (!body || typeof body.notificationType !== 'number') { if (!body || typeof body.notificationType !== 'number') {
return c.json({ error: 'notificationType is required' }, 400) return c.json({ error: 'notificationType is required' }, 400)
} }
const result = await c.env.NOTIFICATIONS_HUB.getByName(HUB_INSTANCE).broadcast( const result = await c.env.RECFLARE_NOTIFICATIONS_HUB.getByName(HUB_INSTANCE).broadcast(
body.notificationType, body.notificationType,
body.data body.data
) )
+1 -1
View File
@@ -5,7 +5,7 @@
"compatibility_date": "2025-09-20", "compatibility_date": "2025-09-20",
"compatibility_flags": ["nodejs_compat"], "compatibility_flags": ["nodejs_compat"],
"durable_objects": { "durable_objects": {
"bindings": [{ "name": "NOTIFICATIONS_HUB", "class_name": "NotificationsHub" }] "bindings": [{ "name": "RECFLARE_NOTIFICATIONS_HUB", "class_name": "NotificationsHub" }]
}, },
"migrations": [{ "tag": "v1", "new_sqlite_classes": ["NotificationsHub"] }], "migrations": [{ "tag": "v1", "new_sqlite_classes": ["NotificationsHub"] }],
"logpush": false, "logpush": false,