feat: persist player-scoped assignments

This commit is contained in:
Josh Creek
2026-08-31 23:19:23 +01:00
parent 7f7516d9a0
commit 3ae2daec88
5 changed files with 172 additions and 1 deletions
+28
View File
@@ -0,0 +1,28 @@
-- Restart-safe player-scoped assignment projections. The signed manifest and
-- join authorisation are persisted only after the allocator/manifest gate has
-- succeeded; clients still receive them only through an authenticated owner
-- read.
CREATE TABLE assignments (
match_id TEXT NOT NULL,
player_id TEXT NOT NULL,
allocation_id TEXT NOT NULL,
server_id TEXT NOT NULL,
slot INTEGER NOT NULL CHECK (slot BETWEEN 0 AND 5),
region TEXT NOT NULL CHECK (region IN ('EU', 'NA')),
client_build TEXT NOT NULL,
protocol_version INTEGER NOT NULL CHECK (protocol_version > 0),
transport TEXT NOT NULL CHECK (transport IN ('enet', 'steam_sdr')),
endpoint TEXT NOT NULL,
join_authorisation TEXT NOT NULL,
manifest_digest BYTEA NOT NULL,
expires_at TIMESTAMPTZ NOT NULL,
revision BIGINT NOT NULL DEFAULT 0 CHECK (revision >= 0),
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
PRIMARY KEY (match_id, player_id),
FOREIGN KEY (match_id, player_id) REFERENCES match_participants(match_id, player_id),
UNIQUE (match_id, slot)
);
CREATE INDEX assignments_player_expiry
ON assignments (player_id, expires_at);
+10
View File
@@ -5,6 +5,7 @@ import unittest
SQL = (Path(__file__).parent / "0001_initial.sql").read_text()
ASSIGNMENTS_SQL = (Path(__file__).parent / "0002_assignments.sql").read_text()
class MigrationTest(unittest.TestCase):
@@ -43,6 +44,15 @@ class MigrationTest(unittest.TestCase):
self.assertIn("REFERENCES identities(player_id)", SQL)
self.assertIn("REFERENCES matches(match_id)", SQL)
def test_assignments_are_player_scoped_and_expiry_bound(self):
for fragment in (
"CREATE TABLE assignments", "PRIMARY KEY (match_id, player_id)",
"FOREIGN KEY (match_id, player_id)", "UNIQUE (match_id, slot)",
"join_authorisation TEXT NOT NULL", "expires_at TIMESTAMPTZ NOT NULL",
"assignments_player_expiry",
):
self.assertIn(fragment, ASSIGNMENTS_SQL)
if __name__ == "__main__":
unittest.main()