Files
family-planner/apps/server/src/db/migrations/001_initial.ts
T
jason 35ed5223a0 Phase 1 & 2: full-stack family dashboard scaffold
- 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>
2026-03-29 21:56:30 -05:00

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');
`;