From 2b24cd52a4595c0fe67ea7a1420676cbee0c4a79 Mon Sep 17 00:00:00 2001 From: Josh Ashton Date: Tue, 27 Jan 2026 18:02:33 -0700 Subject: [PATCH] init commit --- .gitignore | 2 + schema.sql | 176 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 178 insertions(+) create mode 100644 .gitignore create mode 100644 schema.sql diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..335c51a --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.env +*.env diff --git a/schema.sql b/schema.sql new file mode 100644 index 0000000..00377da --- /dev/null +++ b/schema.sql @@ -0,0 +1,176 @@ +CREATE DATABASE IF NOT EXISTS spaces; +USE spaces; + +CREATE TABLE IF NOT EXISTS roles ( + id INT PRIMARY KEY AUTO_INCREMENT, + role VARCHAR(16) NOT NULL +); + +INSERT IGNORE INTO roles (role) + VALUES ('owner'), ('developer'), ('user'); + +CREATE TABLE IF NOT EXISTS user ( + id INT PRIMARY KEY AUTO_INCREMENT, + username VARCHAR(32) NOT NULL UNIQUE, + email VARCHAR(64), + passwordHash VARCHAR(256) NOT NULL, + role INT DEFAULT 3, + createdAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + lastActive TIMESTAMP DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, + isActive BOOLEAN DEFAULT FALSE, + profilePicture VARCHAR(256), + bio VARCHAR(256), + website VARCHAR(64), + FOREIGN KEY (role) REFERENCES roles (id) ON DELETE CASCADE +); + +INSERT IGNORE INTO user (username, email, passwordHash, role, profilePicture) + VALUES ('joshashton', 'me@joshashton.dev', '$2y$12$CDMWB7IzcURWaxPxb1RrZezgy5acNFU7kSogM/ObohAZPT0.3H75K', 1, '2025.jpg'); + +CREATE TABLE IF NOT EXISTS rememberUser ( + token VARCHAR(128) PRIMARY KEY, + id INT NOT NULL, + remoteAddr VARCHAR(64) NOT NULL, + httpForward VARCHAR(64), + createdAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (id) REFERENCES user (id) ON DELETE CASCADE +); -- TODO: Need cron job to auto-delete after 30 days of inactivity + +CREATE TABLE IF NOT EXISTS postTypes ( + id INT PRIMARY KEY AUTO_INCREMENT, + postType VARCHAR(16) +); + +INSERT IGNORE INTO postTypes (postType) + VALUES ('essay'), ('moment'), ('thought'); + +CREATE TABLE IF NOT EXISTS postStatus ( + id INT PRIMARY KEY AUTO_INCREMENT, + status VARCHAR(16) +); + +INSERT IGNORE INTO postStatus (status) + VALUES ('draft'), ('published'); + +CREATE TABLE IF NOT EXISTS spaceVisibility ( + id INT PRIMARY KEY AUTO_INCREMENT, + spaceVisibility VARCHAR(16) +); + +INSERT IGNORE INTO spaceVisibility (spaceVisibility) + VALUES ('open'), ('public'), ('request'), ('invite'), ('private'); + +CREATE TABLE IF NOT EXISTS space ( + id INT PRIMARY KEY AUTO_INCREMENT, + visibility INT NOT NULL, + name VARCHAR(64) NOT NULL, + description TEXT, + parent INT DEFAULT NULL, + createdAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + FOREIGN KEY (parent) REFERENCES space(id) ON DELETE SET NULL, + FOREIGN KEY (visibility) REFERENCES spaceVisibility(id) +); + +INSERT IGNORE INTO space (visibility, name, description) + VALUES (5, "joshashton", "Thoughts, Moments, and Essays that I braindump."); + +CREATE TABLE IF NOT EXISTS spaceRoles ( + id INT PRIMARY KEY AUTO_INCREMENT, + role VARCHAR(16) NOT NULL +); + +INSERT IGNORE INTO spaceRoles (role) + VALUES ("owner"), ("administrator"), ("moderator"), ("viewer"); + +CREATE TABLE IF NOT EXISTS spaceMembers ( + id INT PRIMARY KEY AUTO_INCREMENT, + user INT NOT NULL, + space INT NOT NULL, + role INT NOT NULL, + addedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + favorited BOOLEAN DEFAULT FALSE, + FOREIGN KEY (user) REFERENCES user(id), + FOREIGN KEY (space) REFERENCES space(id), + FOREIGN KEY (role) REFERENCES spaceRoles(id) +); + +INSERT IGNORE INTO spaceMembers (id, user, space, role) + VALUES (1, 1, 1, 1); + +CREATE TABLE IF NOT EXISTS post ( + id INT PRIMARY KEY AUTO_INCREMENT, + space INT NOT NULL, + creator INT NOT NULL, + postType INT NOT NULL, + status INT NOT NULL, + title VARCHAR(255), -- Make title nullable to accommodate Moments and Thoughts + markdown TEXT, -- For Essays + excerpt VARCHAR(255), -- For Essays + caption TEXT, -- For Moments + images TEXT, -- Store image filenames as JSON for Moments + thought TEXT, -- For Thoughts + seenCount INT DEFAULT 0, + createdAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + FOREIGN KEY (space) REFERENCES space(id) ON DELETE CASCADE, + FOREIGN KEY (status) REFERENCES postStatus(id) ON DELETE CASCADE, + FOREIGN KEY (creator) REFERENCES user(id) ON DELETE CASCADE, + FOREIGN KEY (postType) REFERENCES postTypes(id) +); + +CREATE TABLE IF NOT EXISTS spacePosts ( + post INT NOT NULL, + space INT NOT NULL, + PRIMARY KEY (post, space), + FOREIGN KEY (post) REFERENCES post(id) ON DELETE CASCADE, + FOREIGN KEY (space) REFERENCES space(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS topics ( + id INT PRIMARY KEY AUTO_INCREMENT, + topic VARCHAR(16) NOT NULL +); + +CREATE TABLE IF NOT EXISTS postTopics ( + post INT NOT NULL, + topic INT NOT NULL, + PRIMARY KEY (post, topic), + FOREIGN KEY (post) REFERENCES post(id) ON DELETE CASCADE, + FOREIGN KEY (topic) REFERENCES topics(id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS todoPriority ( + id INT PRIMARY KEY AUTO_INCREMENT, + priority VARCHAR(16) NOT NULL +); + +INSERT IGNORE INTO todoPriority (priority) + VALUES ("Low"), ("Medium"), ("High"), ("Urgent"); + +CREATE TABLE IF NOT EXISTS todo ( + id INT NOT NULL, + space INT NOT NULL, + title VARCHAR(32) NOT NULL, + description TEXT, + due DATETIME, + priority INT NOT NULL, + link TEXT, + createdAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (id, space), + FOREIGN KEY (space) REFERENCES space(id) ON DELETE CASCADE, + FOREIGN KEY (priority) REFERENCES todoPriority(id) +); + +INSERT IGNORE INTO todo (id, space, title, description, due, priority, link) + VALUES (2026, 1, "weave.space", "Need to finish building this site.", CURRENT_TIMESTAMP, 3, "weave.space"); + +CREATE TABLE IF NOT EXISTS follows ( + follower INT NOT NULL, + following INT NOT NULL, + notifyUser BOOLEAN DEFAULT FALSE, + followed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (follower, following), + FOREIGN KEY (follower) REFERENCES user(id) ON DELETE CASCADE, + FOREIGN KEY (following) REFERENCES user(id) ON DELETE CASCADE +);