Files
PaperPhone/server/db/schema.sql
619dev 70982e58b1 init
2026-03-25 14:31:05 +08:00

88 lines
3.1 KiB
SQL

-- PaperPhone IM Database Schema
-- MySQL 8.0+
CREATE DATABASE IF NOT EXISTS paperphone CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE paperphone;
-- Users table
CREATE TABLE IF NOT EXISTS users (
id VARCHAR(36) PRIMARY KEY,
username VARCHAR(64) NOT NULL UNIQUE,
nickname VARCHAR(128) NOT NULL,
avatar VARCHAR(512) DEFAULT NULL,
password VARCHAR(255) NOT NULL,
-- X3DH Identity Key (public, base64)
ik_pub TEXT NOT NULL,
-- Signed PreKey (public, base64)
spk_pub TEXT NOT NULL,
spk_sig TEXT NOT NULL,
-- ML-KEM-768 long-term public key
kem_pub TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
last_seen DATETIME DEFAULT CURRENT_TIMESTAMP,
is_online TINYINT(1) DEFAULT 0,
INDEX idx_username (username)
) ENGINE=InnoDB;
-- One-time prekeys (X3DH OPKs)
CREATE TABLE IF NOT EXISTS prekeys (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id VARCHAR(36) NOT NULL,
key_id INT NOT NULL,
opk_pub TEXT NOT NULL,
used TINYINT(1) DEFAULT 0,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
INDEX idx_user_unused (user_id, used)
) ENGINE=InnoDB;
-- Friendships
CREATE TABLE IF NOT EXISTS friends (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id VARCHAR(36) NOT NULL,
friend_id VARCHAR(36) NOT NULL,
status ENUM('pending','accepted','blocked') DEFAULT 'pending',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY uk_pair (user_id, friend_id),
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY (friend_id) REFERENCES users(id) ON DELETE CASCADE
) ENGINE=InnoDB;
-- Groups
CREATE TABLE IF NOT EXISTS `groups` (
id VARCHAR(36) PRIMARY KEY,
name VARCHAR(128) NOT NULL,
avatar VARCHAR(512) DEFAULT NULL,
owner_id VARCHAR(36) NOT NULL,
notice TEXT DEFAULT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (owner_id) REFERENCES users(id)
) ENGINE=InnoDB;
-- Group members
CREATE TABLE IF NOT EXISTS group_members (
group_id VARCHAR(36) NOT NULL,
user_id VARCHAR(36) NOT NULL,
role ENUM('owner','admin','member') DEFAULT 'member',
joined_at DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (group_id, user_id),
FOREIGN KEY (group_id) REFERENCES `groups`(id) ON DELETE CASCADE,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
) ENGINE=InnoDB;
-- Messages (server only stores ciphertext for offline delivery)
-- Once delivered, messages are deleted from server
CREATE TABLE IF NOT EXISTS messages (
id VARCHAR(36) PRIMARY KEY,
type ENUM('private','group') NOT NULL,
from_id VARCHAR(36) NOT NULL,
to_id VARCHAR(36) NOT NULL, -- user_id or group_id
-- Encrypted payload (base64)
ciphertext LONGTEXT NOT NULL,
-- X3DH initial message header if first message
header TEXT DEFAULT NULL,
msg_type ENUM('text','image','file','voice','video_call','system') DEFAULT 'text',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
delivered TINYINT(1) DEFAULT 0,
INDEX idx_to_undelivered (to_id, delivered, created_at)
) ENGINE=InnoDB;