WIP: backend auth/chores/households work and frontend styling
This commit is contained in:
+72
-1
@@ -1,10 +1,13 @@
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
|
||||
{- | SQLite database support for Sis.
|
||||
|
||||
Opens (and creates if missing) a SQLite database with WAL journal
|
||||
mode and foreign keys enabled.
|
||||
mode and foreign keys enabled. Runs schema migrations on startup.
|
||||
-}
|
||||
module Sis.Database (
|
||||
openDatabase,
|
||||
runMigrations,
|
||||
) where
|
||||
|
||||
import Database.SQLite.Simple qualified as SQL
|
||||
@@ -22,4 +25,72 @@ openDatabase path = do
|
||||
conn <- SQL.open path
|
||||
SQL.execute_ conn "PRAGMA journal_mode=WAL"
|
||||
SQL.execute_ conn "PRAGMA foreign_keys=ON"
|
||||
runMigrations conn
|
||||
pure conn
|
||||
|
||||
-- | Create all tables if they don't exist.
|
||||
runMigrations :: SQL.Connection -> IO ()
|
||||
runMigrations conn =
|
||||
mapM_
|
||||
(SQL.execute_ conn)
|
||||
[ "CREATE TABLE IF NOT EXISTS users (\
|
||||
\ id INTEGER PRIMARY KEY AUTOINCREMENT,\
|
||||
\ display_name TEXT NOT NULL,\
|
||||
\ email TEXT NOT NULL UNIQUE,\
|
||||
\ password_hash TEXT NOT NULL,\
|
||||
\ created_at TEXT NOT NULL DEFAULT (datetime('now')))"
|
||||
, "CREATE TABLE IF NOT EXISTS sessions (\
|
||||
\ id INTEGER PRIMARY KEY AUTOINCREMENT,\
|
||||
\ token TEXT NOT NULL UNIQUE,\
|
||||
\ user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,\
|
||||
\ expires_at TEXT NOT NULL,\
|
||||
\ created_at TEXT NOT NULL DEFAULT (datetime('now')))"
|
||||
, "CREATE TABLE IF NOT EXISTS households (\
|
||||
\ id INTEGER PRIMARY KEY AUTOINCREMENT,\
|
||||
\ name TEXT NOT NULL,\
|
||||
\ created_at TEXT NOT NULL DEFAULT (datetime('now')))"
|
||||
, "CREATE TABLE IF NOT EXISTS memberships (\
|
||||
\ id INTEGER PRIMARY KEY AUTOINCREMENT,\
|
||||
\ household_id INTEGER NOT NULL REFERENCES households(id) ON DELETE CASCADE,\
|
||||
\ user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,\
|
||||
\ role TEXT NOT NULL CHECK (role IN ('owner', 'member')),\
|
||||
\ UNIQUE (household_id, user_id))"
|
||||
, "CREATE TABLE IF NOT EXISTS invites (\
|
||||
\ id INTEGER PRIMARY KEY AUTOINCREMENT,\
|
||||
\ household_id INTEGER NOT NULL REFERENCES households(id) ON DELETE CASCADE,\
|
||||
\ code TEXT NOT NULL UNIQUE,\
|
||||
\ email TEXT,\
|
||||
\ status TEXT NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'accepted', 'revoked')),\
|
||||
\ created_at TEXT NOT NULL DEFAULT (datetime('now')))"
|
||||
, "CREATE TABLE IF NOT EXISTS chores (\
|
||||
\ id INTEGER PRIMARY KEY AUTOINCREMENT,\
|
||||
\ household_id INTEGER NOT NULL REFERENCES households(id) ON DELETE CASCADE,\
|
||||
\ name TEXT NOT NULL,\
|
||||
\ assignee_type TEXT NOT NULL DEFAULT 'anyone' CHECK (assignee_type IN ('user', 'anyone')),\
|
||||
\ assignee_user_id INTEGER REFERENCES users(id) ON DELETE SET NULL,\
|
||||
\ schedule_type TEXT NOT NULL CHECK (schedule_type IN ('one_off', 'recurring', 'sometime')),\
|
||||
\ schedule_data TEXT NOT NULL,\
|
||||
\ notify_on_due INTEGER NOT NULL DEFAULT 0,\
|
||||
\ created_at TEXT NOT NULL DEFAULT (datetime('now')))"
|
||||
, "CREATE TABLE IF NOT EXISTS occurrences (\
|
||||
\ id INTEGER PRIMARY KEY AUTOINCREMENT,\
|
||||
\ chore_id INTEGER NOT NULL REFERENCES chores(id) ON DELETE CASCADE,\
|
||||
\ due_date TEXT NOT NULL,\
|
||||
\ status TEXT NOT NULL DEFAULT 'due' CHECK (status IN ('due', 'overdue', 'completed', 'skipped')),\
|
||||
\ UNIQUE (chore_id, due_date))"
|
||||
, "CREATE TABLE IF NOT EXISTS activities (\
|
||||
\ id INTEGER PRIMARY KEY AUTOINCREMENT,\
|
||||
\ occurrence_id INTEGER NOT NULL REFERENCES occurrences(id) ON DELETE CASCADE,\
|
||||
\ user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,\
|
||||
\ status TEXT NOT NULL CHECK (status IN ('completed', 'skipped')),\
|
||||
\ note TEXT,\
|
||||
\ notify_household INTEGER NOT NULL DEFAULT 0,\
|
||||
\ recorded_at TEXT NOT NULL DEFAULT (datetime('now')))"
|
||||
, "CREATE TABLE IF NOT EXISTS reset_tokens (\
|
||||
\ id INTEGER PRIMARY KEY AUTOINCREMENT,\
|
||||
\ user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,\
|
||||
\ token TEXT NOT NULL UNIQUE,\
|
||||
\ used INTEGER NOT NULL DEFAULT 0,\
|
||||
\ expires_at TEXT NOT NULL,\
|
||||
\ created_at TEXT NOT NULL DEFAULT (datetime('now')))"
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user