Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
.vscode
.env
.test.env
TODO.md
TODO.md
digest.txt
8 changes: 8 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,18 @@ db-down:
db-migrate-up:
DATABASE_URL="$(DATABASE_URL)" diesel migration run

.PHONY: db-secondary-migrate-up
db-secondary-migrate-up:
DATABASE_URL="$(DATABASE_URL)" diesel migration --migration-dir secondary_migrations run

.PHONY: db-migrate-down
db-migrate-down:
DATABASE_URL="$(DATABASE_URL)" diesel migration revert

.PHONY: db-secondary-migrate-down
db-secondary-migrate-down:
DATABASE_URL="$(DATABASE_URL)" diesel migration --migration-dir secondary_migrations revert

.PHONY: db-migrate-redo
db-migrate-redo:
DATABASE_URL="$(DATABASE_URL)" diesel migration redo
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
DELETE FROM tasks
WHERE type = 'dev'
AND id IN (SELECT id FROM issues);

DELETE FROM users_projects_roles
WHERE role_id = 2
AND user_id IN (SELECT DISTINCT assignee_id FROM issues WHERE assignee_id IS NOT NULL);
62 changes: 62 additions & 0 deletions secondary_migrations/2025-01-19-212212_issues-to-tasks/up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
-- Migrate issues to tasks

INSERT INTO tasks (
id,
number,
repository_id,
project_id,
title,
description,
labels,
open,
is_certified,
assignee_user_id,
issue_created_at,
issue_closed_at,
created_at,
updated_at,
type,
status,
url
)
SELECT
i.id,
i.number,
i.repository_id,
r.project_id,
i.title,
i.description,
i.labels,
i.open,
COALESCE(i.certified, false) AS is_certified,
i.assignee_id AS assignee_user_id,
i.issue_created_at,
i.issue_closed_at,
i.created_at,
i.updated_at,
'dev' AS type,
CASE
WHEN i.open = TRUE AND i.assignee_id IS NULL THEN 'open'
WHEN i.open = TRUE AND i.assignee_id IS NOT NULL THEN 'in-progress'
WHEN i.open = FALSE THEN 'completed'
END AS status,
CONCAT(
'https://github.com/',
r.slug,
'/issues/',
i.number
) AS url
FROM
issues i
JOIN
repositories r
ON
i.repository_id = r.id;

-- add CONTRIBUTOR role

INSERT INTO users_projects_roles (user_id, role_id)
SELECT DISTINCT assignee_id AS user_id, 2 AS role_id
FROM issues
WHERE assignee_id IS NOT NULL
ON CONFLICT (user_id, project_id, role_id) DO NOTHING;
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
DROP TRIGGER IF EXISTS trigger_assign_role_to_user ON tasks;
DROP FUNCTION IF EXISTS assign_role_to_user;
21 changes: 21 additions & 0 deletions secondary_migrations/2025-01-19-215731_contributor-role/up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
CREATE OR REPLACE FUNCTION assign_role_to_user()
RETURNS TRIGGER AS $$
BEGIN
IF NEW.assignee_user_id IS NOT NULL THEN
INSERT INTO users_projects_roles (user_id, role_id)
SELECT NEW.assignee_user_id, 2
WHERE NOT EXISTS (
SELECT 1
FROM users_projects_roles
WHERE user_id = NEW.assignee_user_id
AND role_id = 2
);
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trigger_assign_role_to_user
AFTER INSERT OR UPDATE OF assignee_user_id ON tasks
FOR EACH ROW
EXECUTE FUNCTION assign_role_to_user();
2 changes: 2 additions & 0 deletions secondary_migrations/2025-01-19-223138_tasks-status/down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
DROP TRIGGER IF EXISTS update_task_status_trigger ON tasks;
DROP FUNCTION IF EXISTS update_task_status;
16 changes: 16 additions & 0 deletions secondary_migrations/2025-01-19-223138_tasks-status/up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

CREATE OR REPLACE FUNCTION update_task_status() RETURNS TRIGGER AS $$
BEGIN
NEW.status := CASE
WHEN NEW.open = TRUE AND NEW.assignee_user_id IS NULL THEN 'open'
WHEN NEW.open = TRUE AND NEW.assignee_user_id IS NOT NULL THEN 'in-progress'
WHEN NEW.open = FALSE THEN 'completed'
END;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER update_task_status_trigger
BEFORE INSERT OR UPDATE ON tasks
FOR EACH ROW
EXECUTE FUNCTION update_task_status();
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE tasks
DROP CONSTRAINT tasks_repo_number_unique;
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE tasks
ADD CONSTRAINT tasks_repo_number_unique UNIQUE (repository_id, number);
3 changes: 3 additions & 0 deletions secondary_migrations/2025-01-29-212647_repository-id/down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

ALTER TABLE tasks
DROP CONSTRAINT tasks_repository_id_fkey;
6 changes: 6 additions & 0 deletions secondary_migrations/2025-01-29-212647_repository-id/up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

ALTER TABLE tasks
ADD CONSTRAINT tasks_repository_id_fkey
FOREIGN KEY (repository_id)
REFERENCES repositories(id)
ON DELETE CASCADE;
8 changes: 8 additions & 0 deletions secondary_migrations/2025-01-29-212911_project-id/down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

DROP TRIGGER IF EXISTS trigger_set_project_id ON tasks;
DROP FUNCTION IF EXISTS set_project_id_from_repository;
ALTER TABLE tasks
DROP CONSTRAINT tasks_repository_id_fkey;

ALTER TABLE repositories
DROP CONSTRAINT unique_id_project_id;
16 changes: 16 additions & 0 deletions secondary_migrations/2025-01-29-212911_project-id/up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
ALTER TABLE repositories
ADD CONSTRAINT unique_id_project_id UNIQUE (id, project_id);

CREATE OR REPLACE FUNCTION set_project_id_from_repository()
RETURNS TRIGGER AS $$
BEGIN
NEW.project_id := (SELECT project_id FROM repositories WHERE id = NEW.repository_id);
RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trigger_set_project_id
BEFORE INSERT OR UPDATE ON tasks
FOR EACH ROW
WHEN (NEW.repository_id IS NOT NULL AND NEW.project_id IS NULL)
EXECUTE FUNCTION set_project_id_from_repository();
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- This file should undo anything in `up.sql`
DROP TABLE IF EXISTS task_comments;
13 changes: 13 additions & 0 deletions secondary_migrations/2025-07-26-070123_create_task_comments/up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
-- Your SQL goes here
CREATE TABLE IF NOT EXISTS task_comments (
id SERIAL PRIMARY KEY,
content TEXT NOT NULL,
task_id INT REFERENCES tasks(id) ON DELETE CASCADE NOT NULL,
user_id INT REFERENCES users(id) ON DELETE CASCADE NOT NULL,
parent_comment_id INT REFERENCES task_comments(id) ON DELETE CASCADE, -- For threaded replies
created_at TIMESTAMP WITH TIME ZONE DEFAULT (now() AT TIME ZONE 'utc') NOT NULL,
updated_at TIMESTAMP WITH TIME ZONE NULL
);

-- Add an index on task_id for faster comment lookups
CREATE INDEX idx_task_comments_task_id ON task_comments(task_id);
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
-- This file should undo anything in `up.sql`
-- Revert to the original version that doesn't handle UPDATE
CREATE OR REPLACE FUNCTION update_task_votes()
RETURNS TRIGGER AS $$
BEGIN
IF TG_OP = 'INSERT' THEN
IF NEW.vote > 0 THEN
UPDATE tasks SET upvotes = upvotes + 1 WHERE id = NEW.task_id;
ELSIF NEW.vote < 0 THEN
UPDATE tasks SET downvotes = downvotes + 1 WHERE id = NEW.task_id;
END IF;

ELSIF TG_OP = 'DELETE' THEN
IF OLD.vote > 0 THEN
UPDATE tasks SET upvotes = upvotes - 1 WHERE id = OLD.task_id;
ELSIF OLD.vote < 0 THEN
UPDATE tasks SET downvotes = downvotes - 1 WHERE id = OLD.task_id;
END IF;
END IF;

RETURN NULL;
END;
$$ LANGUAGE plpgsql;

-- Drop and recreate original trigger
DROP TRIGGER IF EXISTS trigger_update_task_votes ON tasks_votes;

CREATE TRIGGER trigger_update_task_votes
AFTER INSERT OR DELETE ON tasks_votes
FOR EACH ROW
EXECUTE FUNCTION update_task_votes();
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
-- Drop and replace the trigger function
CREATE OR REPLACE FUNCTION update_task_votes()
RETURNS TRIGGER AS $$
BEGIN
IF TG_OP = 'INSERT' THEN
IF NEW.vote > 0 THEN
UPDATE tasks SET upvotes = upvotes + 1 WHERE id = NEW.task_id;
ELSIF NEW.vote < 0 THEN
UPDATE tasks SET downvotes = downvotes + 1 WHERE id = NEW.task_id;
END IF;

ELSIF TG_OP = 'DELETE' THEN
IF OLD.vote > 0 THEN
UPDATE tasks SET upvotes = upvotes - 1 WHERE id = OLD.task_id;
ELSIF OLD.vote < 0 THEN
UPDATE tasks SET downvotes = downvotes - 1 WHERE id = OLD.task_id;
END IF;

ELSIF TG_OP = 'UPDATE' THEN
IF OLD.vote != NEW.vote THEN
IF OLD.vote > 0 THEN
UPDATE tasks SET upvotes = upvotes - 1 WHERE id = OLD.task_id;
ELSIF OLD.vote < 0 THEN
UPDATE tasks SET downvotes = downvotes - 1 WHERE id = OLD.task_id;
END IF;

IF NEW.vote > 0 THEN
UPDATE tasks SET upvotes = upvotes + 1 WHERE id = NEW.task_id;
ELSIF NEW.vote < 0 THEN
UPDATE tasks SET downvotes = downvotes + 1 WHERE id = NEW.task_id;
END IF;
END IF;
END IF;

RETURN NULL;
END;
$$ LANGUAGE plpgsql;

-- Recreate the trigger to include UPDATE
DROP TRIGGER IF EXISTS trigger_update_task_votes ON tasks_votes;

CREATE TRIGGER trigger_update_task_votes
AFTER INSERT OR DELETE OR UPDATE ON tasks_votes
FOR EACH ROW
EXECUTE FUNCTION update_task_votes();
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-- This file should undo anything in `up.sql`
ALTER TABLE task_comments
DROP COLUMN status;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- Your SQL goes here
-- Add a status column to track if a comment is active or soft-deleted
ALTER TABLE task_comments
ADD COLUMN status TEXT NOT NULL DEFAULT 'active'
CONSTRAINT comment_status_check CHECK (status IN ('active', 'deleted'));
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
-- This file should undo anything in `up.sql`
ALTER TABLE users
DROP CONSTRAINT IF EXISTS users_bio_not_blank,
DROP CONSTRAINT IF EXISTS users_telegram_not_blank,
DROP CONSTRAINT IF EXISTS users_twitter_not_blank;

ALTER TABLE users
DROP COLUMN IF EXISTS twitter,
DROP COLUMN IF EXISTS telegram,
DROP COLUMN IF EXISTS interests,
DROP COLUMN IF EXISTS skills,
DROP COLUMN IF EXISTS bio;
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
-- Your SQL goes here
ALTER TABLE users ADD COLUMN bio TEXT;
ALTER TABLE users ADD COLUMN skills TEXT[];
ALTER TABLE users ADD COLUMN interests TEXT[];
ALTER TABLE users ADD COLUMN telegram TEXT;
ALTER TABLE users ADD COLUMN twitter TEXT;

ALTER TABLE users
ADD CONSTRAINT users_bio_not_blank
CHECK (bio IS NULL OR length(btrim(bio)) > 0),
ADD CONSTRAINT users_telegram_not_blank
CHECK (telegram IS NULL OR length(btrim(telegram)) > 0),
ADD CONSTRAINT users_twitter_not_blank
CHECK (twitter IS NULL OR length(btrim(twitter)) > 0);
Loading
Loading