testing generic deploy

This commit is contained in:
Devin Zuczek
2026-06-29 21:52:50 -04:00
parent 3affabd280
commit 69b89e2dc4
79 changed files with 399 additions and 307 deletions
+2 -2
View File
@@ -21,7 +21,7 @@ export const SCHEMA_DDL: string[] = [
`CREATE INDEX IF NOT EXISTS idx_accounts_username_lower ON accounts (username_lower)`,
]
/** Client-facing account shape (PascalCase, matches the C# `Account`). */
/** Client-facing account shape (PascalCase, as the client expects). */
export interface Account {
AccountId: number
Username: string
@@ -61,7 +61,7 @@ export function randomUsername(): string {
}
/**
* Build a full account object from an id, applying the C# fallbacks for any
* Build a full account object from an id, applying default fallbacks for any
* column the caller doesn't override. Used both to synthesize accounts that
* aren't in the DB and as the base for a freshly created account.
*/
+10 -11
View File
@@ -10,17 +10,17 @@ import type { Context } from 'hono'
import type { App } from './context'
/**
* Ported from the C# `AccountsController`. Account reads/writes are backed by the
* shared `accounts` table in D1 (schema owned by the `auth` worker). Accounts not
* in the table fall back to a synthesized default (the C# fills every column with
* a fallback anyway). Profile mutations still accept-and-ack (marked `TODO`).
* Account reads/writes are backed by the shared `accounts` table in D1 (schema
* owned by the `auth` worker). Accounts not in the table fall back to a
* synthesized default (every column has a fallback anyway). Profile mutations
* still accept-and-ack (marked `TODO`).
*
* Auth-gated routes still validate the Bearer JWT issued by the `auth` worker.
*/
/**
* Resolve the account id from a Bearer token, mirroring the repeated
* auth-header check in the C#. Returns `null` when the header is missing,
* auth-header check. Returns `null` when the header is missing,
* the token is invalid, or the `sub` claim isn't an integer.
*/
async function authedId(c: Context<App>): Promise<number | null> {
@@ -61,7 +61,7 @@ const app = new Hono<App>()
.onError(withOnError())
.notFound(withNotFound())
// Root health check (the C# source returned a placeholder string here).
// Root health check.
.get('/', (c) => c.json({ service: 'accounts', status: 'ok' }))
// ---- Self account --------------------------------------------------------
@@ -70,11 +70,10 @@ const app = new Hono<App>()
if (id === null) return unauthorized(c)
// Load the stored account, falling back to a synthesized default.
const account = (await getAccount(c.env.DB, id)) ?? defaultAccount(id)
// The C# `SelfAccount` marks `JuniorState` (an enum) and `ParentAccountId`
// with `[JsonIgnore(WhenWritingNull)]`, so they're OMITTED when null —
// `JuniorState` (an enum) and `ParentAccountId` are OMITTED when null —
// emitting `"juniorState":null` makes the client's enum parser throw
// ("Can't parse JSON to Enum format"). `Email`/`Phone`/`Birthday` are kept
// as null (the C# has no JsonIgnore on those, and they aren't enums).
// as null (they aren't enums, so null is fine).
return c.json({
...account,
Email: null,
@@ -87,7 +86,7 @@ const app = new Hono<App>()
// ---- Bulk / single lookup ------------------------------------------------
// Register the static `bulk` path before the `/account/:id` param route.
.get('/account/bulk', async (c) => {
// C# reads repeated `id` query params; also accept a comma-separated list.
// Reads repeated `id` query params; also accept a comma-separated list.
const ids =
c.req
.queries('id')
@@ -95,7 +94,7 @@ const app = new Hono<App>()
.map((s) => Number.parseInt(s.trim(), 10))
.filter((n) => !Number.isNaN(n)) ?? []
// Resolve stored accounts, synthesizing a default for any id not in the DB
// so every requested id is present in the response (matches the C#).
// so every requested id is present in the response.
const stored = new Map((await getAccountsByIds(c.env.DB, ids)).map((a) => [a.AccountId, a]))
return c.json(ids.map((id) => stored.get(id) ?? defaultAccount(id)))
})
+1 -1
View File
@@ -1,5 +1,5 @@
/**
* Minimal HS256 JWT validation, mirroring the C# `JwtTokenService.ValidateAndGetAccountId`.
* Minimal HS256 JWT validation.
*
* Uses the same placeholder dev secret as the `auth` worker (`apps/auth/src/jwt.ts`).
* Swap both for a shared secret binding before this is used for anything real.
@@ -12,7 +12,7 @@ declare module 'cloudflare:test' {
interface ProvidedEnv extends Env {}
}
const ORIGIN = 'https://accounts.rec.djdevin.net'
const ORIGIN = 'https://example.com'
// Apply the accounts schema + seed the system (uid 0) and Coach (uid 1) accounts
// into the test D1 (mirrors apps/auth/migrations/0001_accounts.sql).