Skip to content

Add task support for calendar #3139

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 25 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
79102b5
chore!: add calendar table tasks
phatgg221 Jun 20, 2025
64536a2
feat: button and add event front end
phatgg221 Jun 20, 2025
ffd4e18
update: event-modal front end
phatgg221 Jun 20, 2025
7dd16d9
refactor: add overflow for dialog
phatgg221 Jun 20, 2025
a33c045
update: update dialog form
phatgg221 Jun 20, 2025
7f2948d
chore: add description for event
phatgg221 Jun 20, 2025
d0e849b
fix: submit grm Error
phatgg221 Jun 20, 2025
16867b6
feat: save tasks to database
phatgg221 Jun 20, 2025
36cae75
fix: delete unwanted imports
phatgg221 Jun 20, 2025
8bad6cb
Update supabase.ts
phatgg221 Jun 20, 2025
e442cde
update: update tasks table policy
phatgg221 Jun 20, 2025
212dd3e
update: change total duration to float number
phatgg221 Jun 20, 2025
5ae2a5f
fix: miss data type of total duration
phatgg221 Jun 20, 2025
051dd1d
Update 20250620103311_changed_policy_of_tasks_table.sql
phatgg221 Jun 20, 2025
f2a9187
fix: hardcoded emails and remove unwanted props
phatgg221 Jun 20, 2025
55c5415
Update add-event-dialog.tsx
phatgg221 Jun 20, 2025
6f9726e
Merge branch 'main' into feat-scheduler-db-and-functionality
vhpx Jun 20, 2025
d24aead
chore(db): consolidate migration files
vhpx Jun 20, 2025
540a5b9
chore(db): fix migration timestampt
vhpx Jun 20, 2025
b921e0b
Merge branch 'main' into feat-scheduler-db-and-functionality
phatgg221 Jun 21, 2025
19bfa98
fix: duplicates errors
phatgg221 Jun 21, 2025
e902936
chore: migrate to tasks table
phatgg221 Jun 21, 2025
0fa7534
refactor: moving to tasks table for schedule tasks
phatgg221 Jun 21, 2025
0160404
chore: rename from minutes to hours
phatgg221 Jun 21, 2025
8981c08
fix: build checks
phatgg221 Jun 21, 2025
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
create type "public"."calendar_task_time" as enum ('working_time', 'personal_time');

create type "public"."priority_status" as enum ('low', 'medium', 'high', 'critical');

create table "public"."workspace_calendar_tasks" (
"id" uuid not null default gen_random_uuid(),
"created_at" timestamp with time zone not null default now(),
"ws_id" uuid,
"creator_id" uuid,
Comment on lines +8 to +9
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Foreign key columns should be NOT NULL.

The ws_id and creator_id columns allow NULL values, but they have foreign key constraints and are essential for the application logic.

-    "ws_id" uuid,
-    "creator_id" uuid,
+    "ws_id" uuid not null,
+    "creator_id" uuid not null,

This prevents orphaned records and ensures data integrity.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"ws_id" uuid,
"creator_id" uuid,
"ws_id" uuid not null,
"creator_id" uuid not null,
🤖 Prompt for AI Agents
In apps/db/supabase/migrations/20250620145741_add_calendar_tasks_table.sql at
lines 8 to 9, the columns "ws_id" and "creator_id" are foreign keys but
currently allow NULL values. Modify these columns to be NOT NULL to enforce data
integrity and prevent orphaned records by updating their definitions to include
the NOT NULL constraint.

"updated_at" timestamp with time zone,
"is_splittable" boolean,
"name" text,
"min_split_duration_minutes" smallint,
"max_split_duration_minutes" smallint,
"schedule_after" timestamp with time zone,
"due_date" timestamp with time zone,
"time_reference" calendar_task_time default 'working_time'::calendar_task_time,
"user_defined_priority" priority_status default 'medium'::priority_status,
"evaluated_priority" priority_status default 'medium'::priority_status
);


alter table "public"."workspace_calendar_tasks" enable row level security;

CREATE UNIQUE INDEX workspace_calendar_tasks_pkey ON public.workspace_calendar_tasks USING btree (id);

alter table "public"."workspace_calendar_tasks" add constraint "workspace_calendar_tasks_pkey" PRIMARY KEY using index "workspace_calendar_tasks_pkey";

alter table "public"."workspace_calendar_tasks" add constraint "workspace_calendar_tasks_creator_id_fkey" FOREIGN KEY (creator_id) REFERENCES users(id) ON DELETE CASCADE not valid;

alter table "public"."workspace_calendar_tasks" validate constraint "workspace_calendar_tasks_creator_id_fkey";

alter table "public"."workspace_calendar_tasks" add constraint "workspace_calendar_tasks_ws_id_fkey" FOREIGN KEY (ws_id) REFERENCES workspaces(id) ON DELETE CASCADE not valid;

alter table "public"."workspace_calendar_tasks" validate constraint "workspace_calendar_tasks_ws_id_fkey";

grant delete on table "public"."workspace_calendar_tasks" to "anon";

grant insert on table "public"."workspace_calendar_tasks" to "anon";

grant references on table "public"."workspace_calendar_tasks" to "anon";

grant select on table "public"."workspace_calendar_tasks" to "anon";

grant trigger on table "public"."workspace_calendar_tasks" to "anon";

grant truncate on table "public"."workspace_calendar_tasks" to "anon";

grant update on table "public"."workspace_calendar_tasks" to "anon";

grant delete on table "public"."workspace_calendar_tasks" to "authenticated";

grant insert on table "public"."workspace_calendar_tasks" to "authenticated";

grant references on table "public"."workspace_calendar_tasks" to "authenticated";

grant select on table "public"."workspace_calendar_tasks" to "authenticated";

grant trigger on table "public"."workspace_calendar_tasks" to "authenticated";

grant truncate on table "public"."workspace_calendar_tasks" to "authenticated";

grant update on table "public"."workspace_calendar_tasks" to "authenticated";

grant delete on table "public"."workspace_calendar_tasks" to "service_role";

grant insert on table "public"."workspace_calendar_tasks" to "service_role";

grant references on table "public"."workspace_calendar_tasks" to "service_role";

grant select on table "public"."workspace_calendar_tasks" to "service_role";

grant trigger on table "public"."workspace_calendar_tasks" to "service_role";

grant truncate on table "public"."workspace_calendar_tasks" to "service_role";

grant update on table "public"."workspace_calendar_tasks" to "service_role";

alter table "public"."workspace_calendar_tasks" add column "description" text;

alter table "public"."workspace_calendar_tasks" add column "total_duration" text not null;

alter table "public"."workspace_calendar_tasks" alter column "max_split_duration_minutes" set data type real using "max_split_duration_minutes"::real;

alter table "public"."workspace_calendar_tasks" alter column "min_split_duration_minutes" set data type real using "min_split_duration_minutes"::real;

alter table "public"."workspace_calendar_tasks" enable row level security;

create policy "allow only user in the workspace to insert"
on "public"."workspace_calendar_tasks"
as permissive
for insert
to authenticated
with check (true);
Comment on lines +89 to +94
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

RLS policy too permissive for workspace isolation.

The current policy allows any authenticated user to insert tasks with with check (true), which doesn't enforce workspace membership constraints.

This could allow users to create tasks in workspaces they don't belong to. Update the policy to check workspace membership:

 create policy "allow only user in the workspace to insert"
 on "public"."workspace_calendar_tasks"
 as permissive
 for insert
 to authenticated
-with check (true);
+with check (
+  exists (
+    select 1 from workspace_users 
+    where workspace_users.ws_id = workspace_calendar_tasks.ws_id 
+    and workspace_users.user_id = auth.uid()
+  )
+);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
create policy "allow only user in the workspace to insert"
on "public"."workspace_calendar_tasks"
as permissive
for insert
to authenticated
with check (true);
create policy "allow only user in the workspace to insert"
on "public"."workspace_calendar_tasks"
as permissive
for insert
to authenticated
with check (
exists (
select 1
from workspace_users
where workspace_users.ws_id = workspace_calendar_tasks.ws_id
and workspace_users.user_id = auth.uid()
)
);
🤖 Prompt for AI Agents
In apps/db/supabase/migrations/20250620145741_add_calendar_tasks_table.sql
around lines 89 to 94, the row-level security policy for inserting into
workspace_calendar_tasks is too permissive because it uses "with check (true)"
allowing any authenticated user to insert tasks regardless of workspace
membership. Modify the policy to include a condition in the "with check" clause
that verifies the user is a member of the workspace associated with the task,
ensuring only authorized users can insert tasks in their own workspaces.


alter table "public"."workspace_calendar_tasks" alter column "total_duration" set data type real using "total_duration"::real;

alter table "public"."workspace_calendar_tasks" alter column "updated_at" set default now();
209 changes: 209 additions & 0 deletions apps/db/supabase/migrations/20250621070438_alter_tasks_table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
drop policy "Users can view sync logs for their workspaces" on "public"."workspace_calendar_sync_log";

drop policy "Workspace members can read and write whiteboards" on "public"."workspace_whiteboards";

revoke delete on table "public"."workspace_calendar_sync_log" from "anon";

revoke insert on table "public"."workspace_calendar_sync_log" from "anon";

revoke references on table "public"."workspace_calendar_sync_log" from "anon";

revoke select on table "public"."workspace_calendar_sync_log" from "anon";

revoke trigger on table "public"."workspace_calendar_sync_log" from "anon";

revoke truncate on table "public"."workspace_calendar_sync_log" from "anon";

revoke update on table "public"."workspace_calendar_sync_log" from "anon";

revoke delete on table "public"."workspace_calendar_sync_log" from "authenticated";

revoke insert on table "public"."workspace_calendar_sync_log" from "authenticated";

revoke references on table "public"."workspace_calendar_sync_log" from "authenticated";

revoke select on table "public"."workspace_calendar_sync_log" from "authenticated";

revoke trigger on table "public"."workspace_calendar_sync_log" from "authenticated";

revoke truncate on table "public"."workspace_calendar_sync_log" from "authenticated";

revoke update on table "public"."workspace_calendar_sync_log" from "authenticated";

revoke delete on table "public"."workspace_calendar_sync_log" from "service_role";

revoke insert on table "public"."workspace_calendar_sync_log" from "service_role";

revoke references on table "public"."workspace_calendar_sync_log" from "service_role";

revoke select on table "public"."workspace_calendar_sync_log" from "service_role";

revoke trigger on table "public"."workspace_calendar_sync_log" from "service_role";

revoke truncate on table "public"."workspace_calendar_sync_log" from "service_role";

revoke update on table "public"."workspace_calendar_sync_log" from "service_role";

revoke delete on table "public"."workspace_whiteboards" from "anon";

revoke insert on table "public"."workspace_whiteboards" from "anon";

revoke references on table "public"."workspace_whiteboards" from "anon";

revoke select on table "public"."workspace_whiteboards" from "anon";

revoke trigger on table "public"."workspace_whiteboards" from "anon";

revoke truncate on table "public"."workspace_whiteboards" from "anon";

revoke update on table "public"."workspace_whiteboards" from "anon";

revoke delete on table "public"."workspace_whiteboards" from "authenticated";

revoke insert on table "public"."workspace_whiteboards" from "authenticated";

revoke references on table "public"."workspace_whiteboards" from "authenticated";

revoke select on table "public"."workspace_whiteboards" from "authenticated";

revoke trigger on table "public"."workspace_whiteboards" from "authenticated";

revoke truncate on table "public"."workspace_whiteboards" from "authenticated";

revoke update on table "public"."workspace_whiteboards" from "authenticated";

revoke delete on table "public"."workspace_whiteboards" from "service_role";

revoke insert on table "public"."workspace_whiteboards" from "service_role";

revoke references on table "public"."workspace_whiteboards" from "service_role";

revoke select on table "public"."workspace_whiteboards" from "service_role";

revoke trigger on table "public"."workspace_whiteboards" from "service_role";

revoke truncate on table "public"."workspace_whiteboards" from "service_role";

revoke update on table "public"."workspace_whiteboards" from "service_role";

alter table "public"."workspace_calendar_sync_log" drop constraint "workspace_calendar_sync_log_status_check";

alter table "public"."workspace_calendar_sync_log" drop constraint "workspace_calendar_sync_log_timestamps_check";

alter table "public"."workspace_calendar_sync_log" drop constraint "workspace_calendar_sync_log_triggered_by_check";

alter table "public"."workspace_calendar_sync_log" drop constraint "workspace_calendar_sync_log_ws_id_fkey";

alter table "public"."workspace_calendar_tasks" drop constraint "workspace_calendar_tasks_creator_id_fkey";

alter table "public"."workspace_calendar_tasks" drop constraint "workspace_calendar_tasks_ws_id_fkey";

alter table "public"."workspace_whiteboards" drop constraint "workspace_whiteboards_creator_id_fkey";

alter table "public"."workspace_whiteboards" drop constraint "workspace_whiteboards_ws_id_fkey";

drop view if exists "public"."time_tracking_session_analytics";

alter table "public"."workspace_calendar_sync_log" drop constraint "workspace_calendar_sync_log_pkey";

alter table "public"."workspace_calendar_tasks" drop constraint "workspace_calendar_tasks_pkey";

alter table "public"."workspace_whiteboards" drop constraint "workspace_whiteboards_pkey";

drop index if exists "public"."idx_whiteboards_creator_id";

drop index if exists "public"."idx_whiteboards_snapshot_gin";

drop index if exists "public"."idx_whiteboards_ws_id";

drop index if exists "public"."workspace_calendar_sync_log_pkey";

drop index if exists "public"."workspace_calendar_sync_log_status_idx";

drop index if exists "public"."workspace_calendar_sync_log_sync_started_at_idx";

drop index if exists "public"."workspace_calendar_sync_log_workspace_id_idx";

drop index if exists "public"."workspace_calendar_tasks_pkey";

drop index if exists "public"."workspace_whiteboards_pkey";

drop table "public"."workspace_calendar_sync_log";

drop table "public"."workspace_whiteboards";

alter table "public"."tasks" add column "is_splittable" boolean not null default true;

alter table "public"."tasks" add column "max_split_duration_minutes" real default '240'::real;

alter table "public"."tasks" add column "min_split_duration_minutes" real default '30'::real;

alter table "public"."tasks" add column "time_reference" calendar_task_time not null default 'working_time'::calendar_task_time;

alter table "public"."tasks" add column "total_duration" real;

alter table "public"."tasks" add column "user_defined_priority" priority_status default 'medium'::priority_status;




CREATE UNIQUE INDEX workspace_calendar_taskss_pkey ON public.workspace_calendar_tasks USING btree (id);

alter table "public"."workspace_calendar_tasks" add constraint "workspace_calendar_taskss_pkey" PRIMARY KEY using index "workspace_calendar_taskss_pkey";

Comment on lines +150 to +153
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Typo in index/constraint name: extra “s” in workspace_calendar_taskss_pkey.

You dropped and then recreated the PK index as workspace_calendar_taskss_pkey, but your table is workspace_calendar_tasks. This typo will cause confusion; rename it to workspace_calendar_tasks_pkey.

🤖 Prompt for AI Agents
In apps/db/supabase/migrations/20250621070438_alter_tasks_table.sql around lines
150 to 153, the index and constraint names have an extra "s" resulting in
"workspace_calendar_taskss_pkey". Rename both the unique index and the primary
key constraint to "workspace_calendar_tasks_pkey" to match the table name and
avoid confusion.

alter table "public"."workspace_calendar_tasks" add constraint "workspace_calendar_taskss_creator_id_fkey" FOREIGN KEY (creator_id) REFERENCES users(id) ON DELETE CASCADE not valid;

alter table "public"."workspace_calendar_tasks" validate constraint "workspace_calendar_taskss_creator_id_fkey";

alter table "public"."workspace_calendar_tasks" add constraint "workspace_calendar_taskss_ws_id_fkey" FOREIGN KEY (ws_id) REFERENCES workspaces(id) ON DELETE CASCADE not valid;

alter table "public"."workspace_calendar_tasks" validate constraint "workspace_calendar_taskss_ws_id_fkey";
Comment on lines +154 to +160
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Constraint names for FKs carry the same typo (“taskss”).

The foreign-key constraints are added as

  • workspace_calendar_taskss_creator_id_fkey
  • workspace_calendar_taskss_ws_id_fkey

Rename to use workspace_calendar_tasks_creator_id_fkey and workspace_calendar_tasks_ws_id_fkey for consistency.

🤖 Prompt for AI Agents
In apps/db/supabase/migrations/20250621070438_alter_tasks_table.sql around lines
154 to 160, the foreign key constraint names contain a typo with "taskss"
instead of "tasks". Rename the constraints from
"workspace_calendar_taskss_creator_id_fkey" to
"workspace_calendar_tasks_creator_id_fkey" and from
"workspace_calendar_taskss_ws_id_fkey" to "workspace_calendar_tasks_ws_id_fkey"
to correct the spelling and maintain consistency.


create or replace view "public"."time_tracking_session_analytics" as SELECT tts.id,
tts.ws_id,
tts.user_id,
tts.task_id,
tts.category_id,
tts.title,
tts.description,
tts.start_time,
tts.end_time,
tts.duration_seconds,
tts.is_running,
tts.tags,
tts.created_at,
tts.updated_at,
tts.productivity_score,
tts.was_resumed,
ttc.name AS category_name,
ttc.color AS category_color,
t.name AS task_name,
EXTRACT(hour FROM tts.start_time) AS start_hour,
EXTRACT(dow FROM tts.start_time) AS day_of_week,
date_trunc('day'::text, tts.start_time) AS session_date,
date_trunc('week'::text, tts.start_time) AS session_week,
date_trunc('month'::text, tts.start_time) AS session_month,
CASE
WHEN (tts.duration_seconds >= 7200) THEN 'long'::text
WHEN (tts.duration_seconds >= 1800) THEN 'medium'::text
WHEN (tts.duration_seconds >= 300) THEN 'short'::text
ELSE 'micro'::text
END AS session_length_category
FROM ((time_tracking_sessions tts
LEFT JOIN time_tracking_categories ttc ON ((tts.category_id = ttc.id)))
LEFT JOIN tasks t ON ((tts.task_id = t.id)));



alter table "public"."tasks" alter column "is_splittable" drop default;

alter table "public"."tasks" alter column "is_splittable" drop not null;

alter table "public"."tasks" alter column "max_split_duration_minutes" drop default;

alter table "public"."tasks" alter column "min_split_duration_minutes" drop default;

alter table "public"."tasks" alter column "time_reference" drop default;

alter table "public"."tasks" alter column "time_reference" drop not null;

50 changes: 50 additions & 0 deletions apps/db/supabase/migrations/20250621074218_new_migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@








alter table "public"."tasks" alter column "list_id" drop not null;





create or replace view "public"."time_tracking_session_analytics" as SELECT tts.id,
tts.ws_id,
tts.user_id,
tts.task_id,
tts.category_id,
tts.title,
tts.description,
tts.start_time,
tts.end_time,
tts.duration_seconds,
tts.is_running,
tts.tags,
tts.created_at,
tts.updated_at,
tts.productivity_score,
tts.was_resumed,
ttc.name AS category_name,
ttc.color AS category_color,
t.name AS task_name,
EXTRACT(hour FROM tts.start_time) AS start_hour,
EXTRACT(dow FROM tts.start_time) AS day_of_week,
date_trunc('day'::text, tts.start_time) AS session_date,
date_trunc('week'::text, tts.start_time) AS session_week,
date_trunc('month'::text, tts.start_time) AS session_month,
CASE
WHEN (tts.duration_seconds >= 7200) THEN 'long'::text
WHEN (tts.duration_seconds >= 1800) THEN 'medium'::text
WHEN (tts.duration_seconds >= 300) THEN 'short'::text
ELSE 'micro'::text
END AS session_length_category
FROM ((time_tracking_sessions tts
LEFT JOIN time_tracking_categories ttc ON ((tts.category_id = ttc.id)))
LEFT JOIN tasks t ON ((tts.task_id = t.id)));



Loading
Loading