source: db-scripts/triggers/compute_daily_completion.sql@ 545738f

Last change on this file since 545738f was 42da64d, checked in by Andrej <asumanovski@…>, 8 weeks ago

Fixed auth issue

  • Property mode set to 100644
File size: 2.9 KB
Line 
1-- Compute daily completion for a single user and date entirely in the DB
2-- Inserts a daily_completions row (if not exists), links finished tasks into task_daily_completions,
3-- and resets tasks.finished = false for that user.
4-- Usage: SELECT trekr.fn_compute_daily_completion(user_id := 123, day := DATE '2026-05-06');
5
6CREATE OR REPLACE FUNCTION trekr.fn_compute_daily_completion(user_id bigint, day date)
7RETURNS TABLE(created boolean, daily_completion_id bigint, procent numeric)
8LANGUAGE plpgsql
9AS $$
10DECLARE
11 total_count bigint;
12 finished_count bigint;
13 pct numeric;
14 dc_id bigint;
15 user_rec record;
16 finished_tasks RECORD;
17BEGIN
18 IF user_id IS NULL THEN
19 RAISE EXCEPTION 'user_id is required';
20 END IF;
21 IF day IS NULL THEN
22 RAISE EXCEPTION 'day is required';
23 END IF;
24 IF day > current_date THEN
25 RAISE EXCEPTION 'date cannot be in the future';
26 END IF;
27
28 -- ensure user tracking exists: rely on discipline_users table existence
29 IF NOT EXISTS (SELECT 1 FROM trekr.discipline_users du WHERE du.user_id = user_id) THEN
30 RAISE EXCEPTION 'Discipline tracking is not enabled for this user';
31 END IF;
32
33 -- if already computed for that user+date, return existing
34 SELECT dc.daily_completion_id, dc.procent INTO dc_id, pct
35 FROM trekr.daily_completions dc
36 WHERE dc.user_id = user_id AND dc.date = day
37 LIMIT 1;
38
39 IF dc_id IS NOT NULL THEN
40 RETURN QUERY SELECT false, dc_id, pct;
41 RETURN;
42 END IF;
43
44 SELECT COUNT(*) INTO total_count FROM trekr.tasks t WHERE t.discipline_user_id = (
45 SELECT du.discipline_user_id FROM trekr.discipline_users du WHERE du.user_id = user_id
46 );
47
48 SELECT COUNT(*) INTO finished_count FROM trekr.tasks t WHERE t.discipline_user_id = (
49 SELECT du.discipline_user_id FROM trekr.discipline_users du WHERE du.user_id = user_id
50 ) AND t.finished = true;
51
52 IF total_count <= 0 THEN
53 pct := 0;
54 ELSE
55 pct := round((finished_count::numeric * 100) / total_count::numeric, 2);
56 END IF;
57
58 -- insert daily completion
59 INSERT INTO trekr.daily_completions (user_id, date, procent)
60 VALUES (user_id, day, pct)
61 RETURNING daily_completion_id INTO dc_id;
62
63 -- link finished tasks
64 FOR finished_tasks IN
65 SELECT t.task_id FROM trekr.tasks t
66 WHERE t.discipline_user_id = (
67 SELECT du.discipline_user_id FROM trekr.discipline_users du WHERE du.user_id = user_id
68 ) AND t.finished = true
69 LOOP
70 INSERT INTO trekr.task_daily_completions (task_id, daily_completion_id)
71 VALUES (finished_tasks.task_id, dc_id)
72 ON CONFLICT DO NOTHING;
73 END LOOP;
74
75 -- reset all tasks for user
76 UPDATE trekr.tasks t SET finished = false
77 WHERE t.discipline_user_id = (
78 SELECT du.discipline_user_id FROM trekr.discipline_users du WHERE du.user_id = user_id
79 );
80
81 RETURN QUERY SELECT true, dc_id, pct;
82END;
83$$;
84
Note: See TracBrowser for help on using the repository browser.