Skip to content

Commit 50d7848

Browse files
committed
feat(RPC): update new RPC to get data for heatmap
1 parent b28e951 commit 50d7848

2 files changed

Lines changed: 67 additions & 1 deletion

File tree

supabase/migrations/20260409084009_create_user_profile_rpc.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
CREATE OR REPLACE FUNCTION get_user_profile_stats()
22
RETURNS JSON
33
LANGUAGE plpgsql
4-
SECURITY INVOKER -- Chạy với quyền của user hiện tại (Tôn trọng RLS)
4+
SECURITY INVOKER
55
AS $$
66
DECLARE
77
v_user_id UUID;
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
CREATE OR REPLACE FUNCTION get_user_profile_stats(p_days INT DEFAULT 90)
2+
RETURNS JSON
3+
LANGUAGE plpgsql
4+
SECURITY INVOKER
5+
AS $$
6+
DECLARE
7+
v_user_id UUID;
8+
v_username TEXT;
9+
v_avatar TEXT;
10+
v_tasks_done INT;
11+
v_current_streak INT;
12+
v_heatmap_data JSON;
13+
BEGIN
14+
v_user_id := auth.uid();
15+
16+
IF v_user_id IS NULL THEN
17+
RAISE EXCEPTION 'User not authenticated';
18+
END IF;
19+
20+
SELECT username, avatar INTO v_username, v_avatar
21+
FROM public.profile
22+
WHERE id = v_user_id;
23+
24+
SELECT COUNT(*) INTO v_tasks_done
25+
FROM public.task
26+
WHERE profile_id = v_user_id AND status = 1;
27+
28+
-- Get task done per day for heatmap
29+
SELECT json_object_agg(task_date::TEXT, task_count) INTO v_heatmap_data
30+
FROM (
31+
SELECT DATE(updated_at AT TIME ZONE 'Asia/Ho_Chi_Minh') AS task_date, COUNT(*) AS task_count
32+
FROM public.task
33+
WHERE profile_id = v_user_id AND status = 1
34+
AND updated_at >= ((CURRENT_TIMESTAMP AT TIME ZONE 'Asia/Ho_Chi_Minh')::DATE - (p_days || ' days')::INTERVAL)
35+
GROUP BY DATE(updated_at AT TIME ZONE 'Asia/Ho_Chi_Minh')
36+
) t;
37+
38+
WITH completed_dates AS (
39+
SELECT DISTINCT DATE(updated_at AT TIME ZONE 'Asia/Ho_Chi_Minh') AS task_date
40+
FROM public.task
41+
WHERE profile_id = v_user_id AND status = 1
42+
),
43+
streak_groups AS (
44+
SELECT task_date,
45+
task_date - (ROW_NUMBER() OVER (ORDER BY task_date))::INT AS grp
46+
FROM completed_dates
47+
),
48+
streak_counts AS (
49+
SELECT grp, MAX(task_date) as end_date, COUNT(*) as streak_length
50+
FROM streak_groups
51+
GROUP BY grp
52+
)
53+
SELECT COALESCE(MAX(streak_length), 0) INTO v_current_streak
54+
FROM streak_counts
55+
WHERE end_date >= ((CURRENT_TIMESTAMP AT TIME ZONE 'Asia/Ho_Chi_Minh')::DATE - INTERVAL '1 day');
56+
57+
58+
RETURN json_build_object(
59+
'name', COALESCE(v_username, 'Unknown User'),
60+
'avatarUrl', COALESCE(v_avatar, ''),
61+
'tasksDone', COALESCE(v_tasks_done, 0),
62+
'streaks', COALESCE(v_current_streak, 0),
63+
'heatmapData', COALESCE(v_heatmap_data, '{}'::JSON)
64+
);
65+
END;
66+
$$;

0 commit comments

Comments
 (0)