feat(db): add Flyway migrations — schema V1 and demo seed V2

V1 creates users, projects, time_entries with CHECK constraints and
three indexes (entry_date, project_id, user+date composite).
V2 seeds 3 users (Alice/Bob/Clara) and 3 projects, one with a
project-level hourly rate override (Acme Relaunch).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-16 11:37:23 +02:00
parent cc00c6c6ae
commit ffa357775b
2 changed files with 36 additions and 0 deletions
@@ -0,0 +1,26 @@
CREATE TABLE users (
id BIGSERIAL PRIMARY KEY,
name TEXT NOT NULL,
default_hourly_rate_cents INTEGER NOT NULL CHECK (default_hourly_rate_cents >= 0)
);
CREATE TABLE projects (
id BIGSERIAL PRIMARY KEY,
name TEXT NOT NULL,
time_budget_minutes INTEGER NOT NULL CHECK (time_budget_minutes > 0),
cost_budget_cents INTEGER NOT NULL CHECK (cost_budget_cents >= 0),
-- NULL means: fall back to the logging user's default_hourly_rate_cents
hourly_rate_cents INTEGER NULL CHECK (hourly_rate_cents IS NULL OR hourly_rate_cents >= 0)
);
CREATE TABLE time_entries (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL REFERENCES users(id),
project_id BIGINT NOT NULL REFERENCES projects(id),
entry_date DATE NOT NULL,
duration_minutes INTEGER NOT NULL CHECK (duration_minutes > 0 AND duration_minutes <= 1440)
);
CREATE INDEX idx_time_entries_entry_date ON time_entries (entry_date);
CREATE INDEX idx_time_entries_project_id ON time_entries (project_id);
CREATE INDEX idx_time_entries_user_date ON time_entries (user_id, entry_date);
@@ -0,0 +1,10 @@
INSERT INTO users (name, default_hourly_rate_cents) VALUES
('Alice Müller', 9500), -- 95.00 EUR/h default rate
('Bob Schmidt', 8000), -- 80.00 EUR/h default rate
('Clara Weber', 11000); -- 110.00 EUR/h default rate
-- Project A: uses per-project rate override (120 EUR/h)
INSERT INTO projects (name, time_budget_minutes, cost_budget_cents, hourly_rate_cents) VALUES
('Acme Relaunch', 12000, 150000000, 12000), -- 200h budget, 1500 EUR budget, 120 EUR/h
('Internal Tools', 6000, 40000000, NULL), -- 100h budget, 400 EUR budget, user rate
('Support & Ops', 3000, 24000000, NULL); -- 50h budget, 240 EUR budget, user rate