Wayfinder: accounts #346

Closed
opened 2026-10-11 12:59:10 +00:00 by root · 17 comments
root commented 2026-10-11 12:59:10 +00:00 (Migrated from gitlab.core-project.space)

Imported from GitHub amaurycoudr/chess-project#346, opened by @amaurycoudr on 2026-10-11 12:59 UTC.


Destination

An ordered list of account features, each sharp enough to hand to /to-spec, with the structuring architecture decisions settled: database on the VPS, what a finished Game keeps and who owns it, the email provider, the session model, the account ↔ Seat token link, and guest-history merging.

Notes

  • Domain: GLOSSARY.md (Play layer), ADR 0016 (Seat token identity — "revisit when accounts arrive"), ADR 0028 (origin guard), ADR 0029 (VPS hosting; accounts need Postgres per stack).
  • Every grilling ticket: call grilling and domain-modeling. Decisions that change architecture end in an ADR.
  • Motivations, in order: (1) find your games again — history, other device; (2) a base for Elo, matchmaking and friends later; (3) a visible identity.
  • Guest play stays: accounts are optional, and a guest can later claim their games.
  • Auth partly reuses the private amaurycoudr/core-project: keep its oRPC auth contract shape, global guard with @Auth(None) opt-out, @ActiveUser(), HashingService (bcrypt), Drizzle + drizzle-kit, case-insensitive unique index helper, auth e2e tests. Drop its single-session-per-user design, its bearer tokens in client storage and its open CORS.

Chosen feature order

  1. Postgres in place — Drizzle v1 RC, a Postgres container per stack (production and previews), Drizzle Gateway on the VPS.
  2. Guest history — finished Games stored with both players (guest or account) and the result; "my games" on this device; PGN export; the Guest replaces the Seat token as the proof of a Seat (ADR 0034).
  3. Accounts v1 — sign up with email, password and a unique username; sign in, sign out, JWT in httpOnly cookies; password reset by email (Resend, Mailpit, DNS); rate limiting; account deletion and export; a signed-in browser takes a Seat as its Account and picks it back up on another device (ADR 0034).
  4. Claim a Guest into an account, new or existing (ADR 0035).
  5. Public profile — username, join date and the Account's decided Games, listed publicly.

Decisions so far

Not yet specified

Nothing. Every feature is ready for /to-spec.

Out of scope

  • Elo, matchmaking and friends — a later map; this one only guarantees that a finished Game records both players and the result so a rating can be computed after the fact.
  • Preferences (theme, language, orientation).
  • Email verification at sign-up, a reporting flow for names, and changing a username — not in v1 (Last product decisions before the account specs).
  • Rooms surviving a redeploy — no account feature needs it once a Seat is held by a Guest or an Account (How does an account relate to the Seat token?).
  • Abandoned Games and Games whose Seat changed hands mid-game — not stored or treated specially now; revisit with Elo.
> _Imported from GitHub [amaurycoudr/chess-project#346](https://github.com/amaurycoudr/chess-project/issues/346), opened by [@amaurycoudr](https://github.com/amaurycoudr) on 2026-10-11 12:59 UTC._ <!-- github-issue:346 --> --- ## Destination An ordered list of account features, each sharp enough to hand to `/to-spec`, with the structuring architecture decisions settled: database on the VPS, what a finished **Game** keeps and who owns it, the email provider, the session model, the account ↔ **Seat token** link, and guest-history merging. ## Notes - Domain: `GLOSSARY.md` (Play layer), ADR 0016 (Seat token identity — "revisit when accounts arrive"), ADR 0028 (origin guard), ADR 0029 (VPS hosting; accounts need Postgres per stack). - Every grilling ticket: call `grilling` and `domain-modeling`. Decisions that change architecture end in an ADR. - Motivations, in order: (1) find your games again — history, other device; (2) a base for Elo, matchmaking and friends later; (3) a visible identity. - Guest play stays: accounts are optional, and a guest can later claim their games. - Auth partly reuses the private `amaurycoudr/core-project`: keep its oRPC auth contract shape, global guard with `@Auth(None)` opt-out, `@ActiveUser()`, `HashingService` (bcrypt), Drizzle + drizzle-kit, case-insensitive unique index helper, auth e2e tests. Drop its single-session-per-user design, its bearer tokens in client storage and its open CORS. ### Chosen feature order 1. **Postgres in place** — Drizzle v1 RC, a Postgres container per stack (production and previews), Drizzle Gateway on the VPS. 2. **Guest history** — finished **Games** stored with both players (guest or account) and the result; "my games" on this device; PGN export; the **Guest** replaces the Seat token as the proof of a **Seat** (ADR 0034). 3. **Accounts v1** — sign up with email, password and a unique username; sign in, sign out, JWT in httpOnly cookies; password reset by email (Resend, Mailpit, DNS); rate limiting; account deletion and export; a signed-in browser takes a **Seat** as its Account and picks it back up on another device (ADR 0034). 4. **Claim a Guest** into an account, new or existing (ADR 0035). 5. **Public profile** — username, join date and the Account's decided Games, listed publicly. ## Decisions so far <!-- one line per closed ticket --> - [Postgres on the VPS: a database per preview, or a schema per preview on a shared server?](https://github.com/amaurycoudr/chess-project/issues/347): a Postgres container per stack, no published port; Drizzle v1 RC; Drizzle Gateway on the VPS over an SSH tunnel, production editable. - [What a finished Game keeps, and which guest identity owns it](https://github.com/amaurycoudr/chess-project/issues/348): decided Online games only, owned by a new browser-wide **Guest** secret beside the Seat token; UCI line from STARTPOS plus result and timestamps; readable by link, listed to owners. - [Which email provider sends password resets?](https://github.com/amaurycoudr/chess-project/issues/349): Resend over SMTP in production, Mailpit in previews, dev and e2e. - [Sessions: JWT in httpOnly cookies, reworked from core-project](https://github.com/amaurycoudr/chess-project/issues/350): one Postgres row per signed-in browser; 15-minute access JWT and rotating 30-day refresh token in httpOnly host-only cookies; no CSRF token, the origin guard covers it (ADR 0030). - [How does an account relate to the Seat token?](https://github.com/amaurycoudr/chess-project/issues/351): no more Seat token; a Seat's occupant is a Guest or an Account, proven by the Guest header or the Session (ADR 0034, superseding 0016 and 0033); old feature 6 folds into Accounts v1. - [How are guest games merged into an account?](https://github.com/amaurycoudr/chess-project/issues/352): confirmed claim links a Guest to an Account and rewrites its Games, including those decided later; final; self-games allowed (ADR 0035). - [Last product decisions before the account specs](https://github.com/amaurycoudr/chess-project/issues/362): email folds into Accounts v1; no email verification; API rate limits by IP and email; unique, fixed username at sign-up; Guests show as "Guest"; public profile lists an Account's Games. ## Not yet specified Nothing. Every feature is ready for `/to-spec`. ## Out of scope - Elo, matchmaking and friends — a later map; this one only guarantees that a finished **Game** records both players and the result so a rating can be computed after the fact. - Preferences (theme, language, orientation). - Email verification at sign-up, a reporting flow for names, and changing a username — not in v1 ([Last product decisions before the account specs](https://github.com/amaurycoudr/chess-project/issues/362)). - **Rooms** surviving a redeploy — no account feature needs it once a Seat is held by a Guest or an Account ([How does an account relate to the Seat token?](https://github.com/amaurycoudr/chess-project/issues/351)). - Abandoned Games and Games whose Seat changed hands mid-game — not stored or treated specially now; revisit with Elo.
root commented 2026-10-11 12:59:10 +00:00 (Migrated from gitlab.core-project.space)

GitHub issue relations, imported as "related" links (GitLab CE has no sub-issues or blocking links).

> _GitHub issue relations, imported as "related" links (GitLab CE has no sub-issues or blocking links)._ <!-- github-relations --> - Sub-issues: #347, #348, #349, #350, #351, #352, #362
root commented 2026-10-11 16:10:44 +00:00 (Migrated from gitlab.core-project.space)

Imported from a GitHub comment by @amaurycoudr on 2026-10-11 16:10 UTC.

The five account specs are published. They ship in this order, and each later spec assumes the earlier ones have landed. Each piece of data belongs to exactly one spec.

  1. Postgres in place: a database per stack, migrations, backup and Drizzle Gateway, revised in place. Next: more than one PR, so /to-tickets then /implement-spec. Its PR writes the PGlite testing ADR.
  2. Guest history: a Guest holds the Seat and owns its decided Games, listed on this browser, read and exported by link, revised in place for ADR 0034. Next: /to-tickets then /implement-spec (Seat token retirement, storage and wire, front views, e2e).
  3. Accounts v1: sign up with a username, sign in on any device, reset a password by email. Next: /to-tickets then /implement-spec, about six tickets. Calls for two ADRs: the Username, and in-memory rate limits.
  4. Claim a Guest into an Account, new or existing. Next: likely two PRs, so /to-tickets then /implement-spec.
  5. Public profile: an Account's username, join date and decided Games, listed for anyone. Next: one PR, so /implement. Calls for an ADR superseding ADR 0034's "listed only to its owners".

Every spec except Postgres in place has an e2e seam. The seams and the open product points were agreed with the owner in one round. The map is ready to close whenever the owner wants.

> _Imported from a [GitHub comment](https://github.com/amaurycoudr/chess-project/issues/346#issuecomment-6110985248) by [@amaurycoudr](https://github.com/amaurycoudr) on 2026-10-11 16:10 UTC._ <!-- github-comment:6110985248 --> The five account specs are published. They ship in this order, and each later spec assumes the earlier ones have landed. Each piece of data belongs to exactly one spec. 1. [Postgres in place: a database per stack, migrations, backup and Drizzle Gateway](https://github.com/amaurycoudr/chess-project/issues/354), revised in place. Next: more than one PR, so `/to-tickets` then `/implement-spec`. Its PR writes the PGlite testing ADR. 2. [Guest history: a Guest holds the Seat and owns its decided Games, listed on this browser, read and exported by link](https://github.com/amaurycoudr/chess-project/issues/355), revised in place for ADR 0034. Next: `/to-tickets` then `/implement-spec` (Seat token retirement, storage and wire, front views, e2e). 3. [Accounts v1: sign up with a username, sign in on any device, reset a password by email](https://github.com/amaurycoudr/chess-project/issues/364). Next: `/to-tickets` then `/implement-spec`, about six tickets. Calls for two ADRs: the Username, and in-memory rate limits. 4. [Claim a Guest into an Account, new or existing](https://github.com/amaurycoudr/chess-project/issues/365). Next: likely two PRs, so `/to-tickets` then `/implement-spec`. 5. [Public profile: an Account's username, join date and decided Games, listed for anyone](https://github.com/amaurycoudr/chess-project/issues/366). Next: one PR, so `/implement`. Calls for an ADR superseding ADR 0034's "listed only to its owners". Every spec except Postgres in place has an e2e seam. The seams and the open product points were agreed with the owner in one round. The map is ready to close whenever the owner wants.
root commented 2026-10-13 08:39:37 +00:00 (Migrated from gitlab.core-project.space)

mentioned in issue #347

mentioned in issue #347
root commented 2026-10-13 08:39:37 +00:00 (Migrated from gitlab.core-project.space)

mentioned in issue #348

mentioned in issue #348
root commented 2026-10-13 08:39:37 +00:00 (Migrated from gitlab.core-project.space)

mentioned in issue #349

mentioned in issue #349
root commented 2026-10-13 08:39:38 +00:00 (Migrated from gitlab.core-project.space)

mentioned in issue #350

mentioned in issue #350
root commented 2026-10-13 08:39:38 +00:00 (Migrated from gitlab.core-project.space)

mentioned in issue #351

mentioned in issue #351
root commented 2026-10-13 08:39:38 +00:00 (Migrated from gitlab.core-project.space)

mentioned in issue #352

mentioned in issue #352
root commented 2026-10-13 08:39:40 +00:00 (Migrated from gitlab.core-project.space)

mentioned in issue #362

mentioned in issue #362
root commented 2026-10-13 08:39:44 +00:00 (Migrated from gitlab.core-project.space)

mentioned in issue #370

mentioned in issue #370
root commented 2026-10-13 08:42:21 +00:00 (Migrated from gitlab.core-project.space)

marked this issue as related to #347

marked this issue as related to #347
root commented 2026-10-13 08:42:21 +00:00 (Migrated from gitlab.core-project.space)

marked this issue as related to #348

marked this issue as related to #348
root commented 2026-10-13 08:42:21 +00:00 (Migrated from gitlab.core-project.space)

marked this issue as related to #349

marked this issue as related to #349
root commented 2026-10-13 08:42:21 +00:00 (Migrated from gitlab.core-project.space)

marked this issue as related to #350

marked this issue as related to #350
root commented 2026-10-13 08:42:22 +00:00 (Migrated from gitlab.core-project.space)

marked this issue as related to #351

marked this issue as related to #351
root commented 2026-10-13 08:42:22 +00:00 (Migrated from gitlab.core-project.space)

marked this issue as related to #352

marked this issue as related to #352
root commented 2026-10-13 08:42:22 +00:00 (Migrated from gitlab.core-project.space)

marked this issue as related to #362

marked this issue as related to #362
root (Migrated from gitlab.core-project.space) closed this issue 2026-10-15 14:46:39 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
amaurycoudr/chess-project#346
No description provided.