ISS-108 — per-player onboarding. New registrants get a starter plane at EDDF: buildStarterPlane(airports, id) extracted from buildSeed (byte-identical values, no RNG draws), reused by POST /api/register and the test mint hook for custom usernames. Legacy players without planes are out of scope (ponytail comment).
ISS-109 — planes.owner_id + ownership checks. New NOT NULL column in DDL + Drizzle mirror; one-time guarded migration backfills pre-v1.2.0 rows to "local" via SQLite constant ALTER default (idempotent). All seven plane actions plus repairPlane take the session player id and 403 "not your plane" on foreign planes through shared assertPlaneOwner(); performAction passes auth.player.id as its callback second arg, routes stay pass-throughs. Economy per-player via new getPlayer/updatePlayerEconomy helpers (getLocalPlayer stays for snapshot/engine). Sell last-plane guard is now PER OWNER; buyPlane stamps the buyer as owner.
Mint hook default → kamilkrzywda. e2e specs play with seeded planes by id, so the no-body mint resolves to the existing local player that owns them after backfill (no new rows); custom usernames create fresh accounts WITH onboarding. No e2e spec changes needed.
Tests. New backfill migration test (client.test.ts), new ownership suite in actions.test.ts (403 both directions, per-owner last-plane guard, buyer stamped as owner with own cash debited); register + mint route tests assert the onboarding plane at EDDF. Local: tsc clean, 432/432 unit, 64 e2e specs list.
Multiplayer steps 4+5 of 12.
**ISS-108 — per-player onboarding.** New registrants get a starter plane at EDDF: `buildStarterPlane(airports, id)` extracted from `buildSeed` (byte-identical values, no RNG draws), reused by POST /api/register and the test mint hook for custom usernames. Legacy players without planes are out of scope (ponytail comment).
**ISS-109 — planes.owner_id + ownership checks.** New NOT NULL column in DDL + Drizzle mirror; one-time guarded migration backfills pre-v1.2.0 rows to "local" via SQLite constant ALTER default (idempotent). All seven plane actions plus repairPlane take the session player id and 403 "not your plane" on foreign planes through shared `assertPlaneOwner()`; performAction passes auth.player.id as its callback second arg, routes stay pass-throughs. Economy per-player via new getPlayer/updatePlayerEconomy helpers (getLocalPlayer stays for snapshot/engine). Sell last-plane guard is now PER OWNER; buyPlane stamps the buyer as owner.
**Mint hook default → kamilkrzywda.** e2e specs play with seeded planes by id, so the no-body mint resolves to the existing local player that owns them after backfill (no new rows); custom usernames create fresh accounts WITH onboarding. No e2e spec changes needed.
**OpenAPI.** Seven plane-targeted endpoints document 403; path count unchanged at eighteen — openapi.test.ts error-code lists updated.
**Tests.** New backfill migration test (client.test.ts), new ownership suite in actions.test.ts (403 both directions, per-owner last-plane guard, buyer stamped as owner with own cash debited); register + mint route tests assert the onboarding plane at EDDF. Local: tsc clean, 432/432 unit, 64 e2e specs list.
v1.2.0 — CHANGELOG entry added; package.json bumped.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Multiplayer steps 4+5 of 12.
ISS-108 — per-player onboarding. New registrants get a starter plane at EDDF:
buildStarterPlane(airports, id)extracted frombuildSeed(byte-identical values, no RNG draws), reused by POST /api/register and the test mint hook for custom usernames. Legacy players without planes are out of scope (ponytail comment).ISS-109 — planes.owner_id + ownership checks. New NOT NULL column in DDL + Drizzle mirror; one-time guarded migration backfills pre-v1.2.0 rows to "local" via SQLite constant ALTER default (idempotent). All seven plane actions plus repairPlane take the session player id and 403 "not your plane" on foreign planes through shared
assertPlaneOwner(); performAction passes auth.player.id as its callback second arg, routes stay pass-throughs. Economy per-player via new getPlayer/updatePlayerEconomy helpers (getLocalPlayer stays for snapshot/engine). Sell last-plane guard is now PER OWNER; buyPlane stamps the buyer as owner.Mint hook default → kamilkrzywda. e2e specs play with seeded planes by id, so the no-body mint resolves to the existing local player that owns them after backfill (no new rows); custom usernames create fresh accounts WITH onboarding. No e2e spec changes needed.
OpenAPI. Seven plane-targeted endpoints document 403; path count unchanged at eighteen — openapi.test.ts error-code lists updated.
Tests. New backfill migration test (client.test.ts), new ownership suite in actions.test.ts (403 both directions, per-owner last-plane guard, buyer stamped as owner with own cash debited); register + mint route tests assert the onboarding plane at EDDF. Local: tsc clean, 432/432 unit, 64 e2e specs list.
v1.2.0 — CHANGELOG entry added; package.json bumped.