Database

Current Database Schema

The ASCII diagram below reflects the current SQLite schema in data/mud.db.

+----------------------------------+
| users                            |
+----------------------------------+
| PK  id                 INTEGER   |
| NN  username           TEXT      | UNIQUE
| NN  password_hash      TEXT      |
|     email_hash          TEXT     | UNIQUE
| NN  role               TEXT      | DEFAULT 'player'
| NN  is_active          INTEGER   | DEFAULT 1
| NN  is_guest           INTEGER   | DEFAULT 0
|     guest_expires_at   TIMESTAMP |
| NN  account_origin     TEXT      | DEFAULT 'legacy'
|     created_at         TIMESTAMP | DEFAULT CURRENT_TIMESTAMP
|     last_login         TIMESTAMP |
|     tombstoned_at      TIMESTAMP |
+----------------------------------+


+----------------------------------+
| characters                       |
+----------------------------------+
| PK  id                 INTEGER   |
|     user_id            INTEGER   | FK -> users.id (ON DELETE SET NULL)
| NN  name               TEXT      | UNIQUE
| NN  inventory          TEXT      | DEFAULT '[]'
| NN  is_guest_created   INTEGER   | DEFAULT 0
|     created_at         TIMESTAMP | DEFAULT CURRENT_TIMESTAMP
|     updated_at         TIMESTAMP | DEFAULT CURRENT_TIMESTAMP
+----------------------------------+


+----------------------------------+
| character_locations              |
+----------------------------------+
| PK  character_id      INTEGER    | FK -> characters.id (ON DELETE CASCADE)
| NN  room_id           TEXT       |
|     updated_at        TIMESTAMP  | DEFAULT CURRENT_TIMESTAMP
+----------------------------------+


+----------------------------------+
| sessions                         |
+----------------------------------+
| PK  id                 INTEGER   |
| NN  user_id            INTEGER   | FK -> users.id (ON DELETE CASCADE)
|     character_id       INTEGER   | FK -> characters.id (ON DELETE SET NULL)
| NN  session_id         TEXT      | UNIQUE
|     created_at         TIMESTAMP | DEFAULT CURRENT_TIMESTAMP
|     last_activity      TIMESTAMP | DEFAULT CURRENT_TIMESTAMP
|     expires_at         TIMESTAMP |
|     client_type        TEXT      | DEFAULT 'unknown'
+----------------------------------+


+----------------------------------+
| chat_messages                    |
+----------------------------------+
| PK  id                 INTEGER   |
|     character_id       INTEGER   | FK -> characters.id (ON DELETE SET NULL)
|     user_id            INTEGER   | FK -> users.id (ON DELETE SET NULL)
| NN  message            TEXT      |
| NN  room               TEXT      |
|     recipient_character_id INTEGER | FK -> characters.id (ON DELETE SET NULL)
|     timestamp          TIMESTAMP | DEFAULT CURRENT_TIMESTAMP
+----------------------------------+

Notes

  • users.email_hash stores a hashed email address (no plaintext email). The column is nullable during development but intended to be required later; the unique index keeps that migration path open.

  • users.is_guest + users.guest_expires_at model temporary accounts that are auto-purged; the user row is deleted and related characters are unlinked (user_id set to NULL) rather than deleted.

  • characters.name is a plain TEXT field, so names with spaces (e.g., first + last) are supported.