mirror of
https://github.com/djdevin/recflare.git
synced 2026-09-08 14:41:28 -07:00
naming cleanup and readme changes
This commit is contained in:
+2
-2
@@ -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"}'
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
@@ -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
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user