Update
This commit is contained in:
1 parent
3d9674bd5a
commit
d1da86beab
20 files changed
+6109
-923
No files matched your search
+622
-82
File diff suppressed because it is too large.
Load diff
@@ -89,6 +89,16 @@ export async function migrate() {
|
||||
);
|
||||
`);
|
||||
|
||||
await query(`
|
||||
CREATE TABLE IF NOT EXISTS user_preferences (
|
||||
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
key TEXT NOT NULL,
|
||||
value JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
PRIMARY KEY (user_id, key)
|
||||
);
|
||||
`);
|
||||
|
||||
await query(`
|
||||
CREATE TABLE IF NOT EXISTS organizations (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
@@ -448,14 +458,54 @@ export async function migrate() {
|
||||
starts_on DATE,
|
||||
ends_on DATE,
|
||||
hour_budget_minutes INTEGER,
|
||||
manual_consumption_minutes INTEGER NOT NULL DEFAULT 0,
|
||||
closed_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
UNIQUE (user_id, ticket_id),
|
||||
CONSTRAINT projects_budget_non_negative CHECK (hour_budget_minutes IS NULL OR hour_budget_minutes >= 0),
|
||||
CONSTRAINT projects_manual_consumption_non_negative CHECK (manual_consumption_minutes >= 0),
|
||||
CONSTRAINT projects_valid_range CHECK (starts_on IS NULL OR ends_on IS NULL OR ends_on >= starts_on)
|
||||
);
|
||||
`);
|
||||
|
||||
await query("ALTER TABLE projects ADD COLUMN IF NOT EXISTS closed_at TIMESTAMPTZ;");
|
||||
await query("ALTER TABLE projects ADD COLUMN IF NOT EXISTS manual_consumption_minutes INTEGER NOT NULL DEFAULT 0;");
|
||||
await query(`
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM pg_constraint
|
||||
WHERE conname = 'projects_manual_consumption_non_negative'
|
||||
) THEN
|
||||
ALTER TABLE projects
|
||||
ADD CONSTRAINT projects_manual_consumption_non_negative CHECK (manual_consumption_minutes >= 0);
|
||||
END IF;
|
||||
END $$;
|
||||
`);
|
||||
|
||||
await query(`
|
||||
UPDATE tickets t
|
||||
SET work_type = 'consulting'
|
||||
WHERE EXISTS (
|
||||
SELECT 1
|
||||
FROM sessions s
|
||||
WHERE s.ticket_id = t.id
|
||||
AND s.work_type = 'consulting'
|
||||
);
|
||||
`);
|
||||
|
||||
await query(`
|
||||
INSERT INTO projects (user_id, ticket_id, teamspace_project, description, goals)
|
||||
SELECT DISTINCT s.user_id, s.ticket_id, COALESCE(t.title, ''), '', ''
|
||||
FROM sessions s
|
||||
JOIN tickets t ON t.id = s.ticket_id
|
||||
WHERE s.work_type = 'consulting'
|
||||
AND s.user_id IS NOT NULL
|
||||
ON CONFLICT (user_id, ticket_id) DO NOTHING;
|
||||
`);
|
||||
|
||||
await query(`
|
||||
CREATE TABLE IF NOT EXISTS ticket_todos (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
@@ -465,14 +515,50 @@ export async function migrate() {
|
||||
description TEXT NOT NULL DEFAULT '',
|
||||
priority TEXT NOT NULL DEFAULT 'medium',
|
||||
status TEXT NOT NULL DEFAULT 'open',
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
starts_on DATE,
|
||||
ends_on DATE,
|
||||
completed_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
CONSTRAINT ticket_todos_priority_valid CHECK (priority IN ('low', 'medium', 'high', 'urgent')),
|
||||
CONSTRAINT ticket_todos_status_valid CHECK (status IN ('open', 'done'))
|
||||
CONSTRAINT ticket_todos_status_valid CHECK (status IN ('open', 'done')),
|
||||
CONSTRAINT ticket_todos_valid_period CHECK (starts_on IS NULL OR ends_on IS NULL OR ends_on >= starts_on)
|
||||
);
|
||||
`);
|
||||
|
||||
await query("ALTER TABLE ticket_todos ADD COLUMN IF NOT EXISTS starts_on DATE;");
|
||||
await query("ALTER TABLE ticket_todos ADD COLUMN IF NOT EXISTS ends_on DATE;");
|
||||
await query("ALTER TABLE ticket_todos ADD COLUMN IF NOT EXISTS sort_order INTEGER;");
|
||||
await query(`
|
||||
WITH ordered_todos AS (
|
||||
SELECT
|
||||
id,
|
||||
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY created_at ASC, id ASC) AS row_number
|
||||
FROM ticket_todos
|
||||
WHERE sort_order IS NULL
|
||||
)
|
||||
UPDATE ticket_todos tt
|
||||
SET sort_order = ordered_todos.row_number * 1024
|
||||
FROM ordered_todos
|
||||
WHERE tt.id = ordered_todos.id;
|
||||
`);
|
||||
await query("ALTER TABLE ticket_todos ALTER COLUMN sort_order SET DEFAULT 0;");
|
||||
await query("ALTER TABLE ticket_todos ALTER COLUMN sort_order SET NOT NULL;");
|
||||
await query(`
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM pg_constraint
|
||||
WHERE conname = 'ticket_todos_valid_period'
|
||||
) THEN
|
||||
ALTER TABLE ticket_todos
|
||||
ADD CONSTRAINT ticket_todos_valid_period CHECK (starts_on IS NULL OR ends_on IS NULL OR ends_on >= starts_on);
|
||||
END IF;
|
||||
END $$;
|
||||
`);
|
||||
|
||||
await ensureClosureOwnership("ticket_month_closures", "month", ["ticket_id", "month"], adminId);
|
||||
await ensureClosureOwnership("month_closures", "month", ["month"], adminId);
|
||||
await ensureClosureOwnership("ticket_day_closures", "day", ["ticket_id", "day"], adminId);
|
||||
@@ -490,8 +576,11 @@ export async function migrate() {
|
||||
await query("CREATE INDEX IF NOT EXISTS idx_ticket_day_billing_ack_user_day ON ticket_day_billing_acknowledgements(user_id, day);");
|
||||
await query("CREATE INDEX IF NOT EXISTS idx_projects_user_ticket ON projects(user_id, ticket_id);");
|
||||
await query("CREATE INDEX IF NOT EXISTS idx_projects_user_updated ON projects(user_id, updated_at DESC);");
|
||||
await query("CREATE INDEX IF NOT EXISTS idx_projects_user_closed_updated ON projects(user_id, closed_at, updated_at DESC);");
|
||||
await query("CREATE INDEX IF NOT EXISTS idx_ticket_todos_user_status_priority ON ticket_todos(user_id, status, priority);");
|
||||
await query("CREATE INDEX IF NOT EXISTS idx_ticket_todos_ticket_user ON ticket_todos(ticket_id, user_id);");
|
||||
await query("CREATE INDEX IF NOT EXISTS idx_ticket_todos_user_period ON ticket_todos(user_id, starts_on, ends_on);");
|
||||
await query("CREATE INDEX IF NOT EXISTS idx_ticket_todos_user_sort_order ON ticket_todos(user_id, sort_order, id);");
|
||||
await query("CREATE INDEX IF NOT EXISTS idx_recurring_billings_user_active ON recurring_billings(user_id, active);");
|
||||
await query("UPDATE recurring_billings SET active = true WHERE active = false;");
|
||||
await query(`
|
||||
|
||||
Reference in new issue
Block a user