35ed5223a0
- pnpm monorepo (apps/client + apps/server) - Server: Express + node:sqlite with numbered migration runner, REST API for all 9 features (members, events, chores, shopping, meals, messages, countdowns, photos, settings) - Client: React 18 + Vite + TypeScript + Tailwind + Framer Motion + Zustand - Theme system: dark/light + 5 accent colors, CSS custom properties, anti-FOUC script, ThemeToggle on every surface - AppShell: collapsible sidebar, animated route transitions, mobile drawer - Phase 2 features: Calendar (custom month grid, event chips, add/edit modal), Chores (card grid, complete/reset, member filter, streaks), Shopping (multi-list tabs, animated check-off, quick-add bar, member assign) - Family member CRUD with avatar, color picker - Settings page: theme/accent, photo folder, slideshow, weather, date/time - Docker: multi-stage Dockerfile, docker-compose.yml, entrypoint with PUID/PGID - Unraid: CA XML template, CLI install script, UNRAID.md guide - .gitignore covering node_modules, dist, db files, secrets, build artifacts Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
121 lines
5.2 KiB
TypeScript
121 lines
5.2 KiB
TypeScript
export const id = '001_initial';
|
|
|
|
export const up = `
|
|
-- ─── Family Members ───────────────────────────────────────────────
|
|
CREATE TABLE IF NOT EXISTS members (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
name TEXT NOT NULL,
|
|
color TEXT NOT NULL DEFAULT '#6366f1',
|
|
avatar TEXT,
|
|
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
);
|
|
|
|
-- ─── App Settings (key/value store) ───────────────────────────────
|
|
CREATE TABLE IF NOT EXISTS settings (
|
|
key TEXT PRIMARY KEY,
|
|
value TEXT NOT NULL
|
|
);
|
|
|
|
-- ─── Calendar Events ──────────────────────────────────────────────
|
|
CREATE TABLE IF NOT EXISTS events (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
title TEXT NOT NULL,
|
|
description TEXT,
|
|
start_at TEXT NOT NULL,
|
|
end_at TEXT NOT NULL,
|
|
all_day INTEGER NOT NULL DEFAULT 0,
|
|
recurrence TEXT,
|
|
member_id INTEGER REFERENCES members(id) ON DELETE SET NULL,
|
|
color TEXT,
|
|
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
);
|
|
|
|
-- ─── Shopping Lists ───────────────────────────────────────────────
|
|
CREATE TABLE IF NOT EXISTS shopping_lists (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
name TEXT NOT NULL,
|
|
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS shopping_items (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
list_id INTEGER NOT NULL REFERENCES shopping_lists(id) ON DELETE CASCADE,
|
|
name TEXT NOT NULL,
|
|
quantity TEXT,
|
|
checked INTEGER NOT NULL DEFAULT 0,
|
|
member_id INTEGER REFERENCES members(id) ON DELETE SET NULL,
|
|
sort_order INTEGER NOT NULL DEFAULT 0,
|
|
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
);
|
|
|
|
-- ─── Chores ───────────────────────────────────────────────────────
|
|
CREATE TABLE IF NOT EXISTS chores (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
title TEXT NOT NULL,
|
|
description TEXT,
|
|
member_id INTEGER REFERENCES members(id) ON DELETE SET NULL,
|
|
recurrence TEXT NOT NULL DEFAULT 'none',
|
|
status TEXT NOT NULL DEFAULT 'pending',
|
|
due_date TEXT,
|
|
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS chore_completions (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
chore_id INTEGER NOT NULL REFERENCES chores(id) ON DELETE CASCADE,
|
|
member_id INTEGER REFERENCES members(id) ON DELETE SET NULL,
|
|
completed_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
);
|
|
|
|
-- ─── Meal Planner (one meal per day — dinner) ─────────────────────
|
|
CREATE TABLE IF NOT EXISTS meals (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
date TEXT NOT NULL,
|
|
title TEXT NOT NULL,
|
|
description TEXT,
|
|
recipe_url TEXT,
|
|
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
UNIQUE(date)
|
|
);
|
|
|
|
-- ─── Message Board ────────────────────────────────────────────────
|
|
CREATE TABLE IF NOT EXISTS messages (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
member_id INTEGER REFERENCES members(id) ON DELETE SET NULL,
|
|
body TEXT NOT NULL,
|
|
color TEXT NOT NULL DEFAULT '#fef08a',
|
|
emoji TEXT,
|
|
pinned INTEGER NOT NULL DEFAULT 0,
|
|
expires_at TEXT,
|
|
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
);
|
|
|
|
-- ─── Countdowns ───────────────────────────────────────────────────
|
|
CREATE TABLE IF NOT EXISTS countdowns (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
title TEXT NOT NULL,
|
|
target_date TEXT NOT NULL,
|
|
emoji TEXT,
|
|
color TEXT NOT NULL DEFAULT '#6366f1',
|
|
show_on_dashboard INTEGER NOT NULL DEFAULT 1,
|
|
event_id INTEGER REFERENCES events(id) ON DELETE CASCADE,
|
|
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
);
|
|
|
|
-- ─── Seed default settings ────────────────────────────────────────
|
|
INSERT OR IGNORE INTO settings (key, value) VALUES
|
|
('theme', 'light'),
|
|
('accent', 'indigo'),
|
|
('photo_folder', ''),
|
|
('slideshow_speed', '6000'),
|
|
('slideshow_order', 'random'),
|
|
('idle_timeout', '120000'),
|
|
('time_format', '12h'),
|
|
('date_format', 'MM/DD/YYYY'),
|
|
('weather_api_key', ''),
|
|
('weather_location',''),
|
|
('weather_units', 'imperial');
|
|
|
|
INSERT OR IGNORE INTO shopping_lists (id, name) VALUES (1, 'Groceries');
|
|
`;
|