···11// Configuration defaults and constants for the takes application
2233export const TakesConfig = {
44- // Default takes session length in minutes (should be 90 for production)
55- DEFAULT_SESSION_LENGTH: 90,
66-77- // Maximum time in minutes that a takes session can be paused before automatic expiration
88- MAX_PAUSE_DURATION: 45,
99-1010- // Maximum number of past takes to display in history
1111- MAX_HISTORY_ITEMS: 7,
1212-1313- // Time thresholds for notifications (in minutes)
1414- NOTIFICATIONS: {
1515- // When to send a warning about low time remaining (minutes)
1616- LOW_TIME_WARNING: 5,
1717-1818- // When to send a warning about pause expiration (minutes)
1919- PAUSE_EXPIRATION_WARNING: 5,
2020-2121- // Frequency to check for notifications (milliseconds)
2222- CHECK_INTERVAL: 10 * 1000, // Every 10 seconds
2323- },
44+ START_DATE: new Date("2025-04-18"),
55+ END_DATE: new Date("2025-05-31"),
246};
257268export default TakesConfig;
+29-23
src/libs/schema.ts
···77 userId: text("user_id").notNull(),
88 ts: text("ts").notNull(),
99 elapsedTimeMs: integer("elapsed_time_ms").notNull().default(0),
1010- createdAt: integer("created_at")
1111- .$defaultFn(() => Math.floor(new Date().getTime() / 1000))
1010+ createdAt: text("created_at")
1111+ .$defaultFn(() => new Date().toISOString())
1212 .notNull(),
1313 media: text("media").notNull().default("[]"), // array of media urls
1414 multiplier: text("multiplier").notNull().default("1.0"),
···1818export const users = pgTable("users", {
1919 id: text("id").primaryKey(),
2020 totalTakesTime: integer("total_takes_time").default(0),
2121+ hackatimeKeys: text("hackatime_keys").notNull().default("[]"),
2222+ projectName: text("project_name").notNull().default(""),
2323+ projectDescription: text("project_description").notNull().default(""),
2124});
22252326export async function setupTriggers(pool: Pool) {
···2528 CREATE INDEX IF NOT EXISTS idx_takes_user_id ON takes(user_id);
26292730 CREATE OR REPLACE FUNCTION update_user_total_time()
2828- RETURNS TRIGGER AS $$
2929- BEGIN
3030- IF TG_OP = 'INSERT' THEN
3131- UPDATE users
3232- SET total_takes_time = COALESCE(total_takes_time, 0) + NEW.elapsed_time_ms
3333- WHERE id = NEW.user_id;
3434- ELSIF TG_OP = 'DELETE' THEN
3535- UPDATE users
3636- SET total_takes_time = COALESCE(total_takes_time, 0) - OLD.elapsed_time_ms
3737- WHERE id = OLD.user_id;
3838- ELSIF TG_OP = 'UPDATE' THEN
3939- UPDATE users
4040- SET total_takes_time = COALESCE(total_takes_time, 0) - OLD.elapsed_time_ms + NEW.elapsed_time_ms
4141- WHERE id = NEW.user_id;
4242- END IF;
3131+ RETURNS TRIGGER AS $$
3232+ BEGIN
3333+ IF TG_OP = 'INSERT' THEN
3434+ UPDATE users
3535+ SET total_takes_time = COALESCE(total_takes_time, 0) + NEW.elapsed_time_ms
3636+ WHERE id = NEW.user_id;
3737+ RETURN NEW;
3838+ ELSIF TG_OP = 'DELETE' THEN
3939+ UPDATE users
4040+ SET total_takes_time = COALESCE(total_takes_time, 0) - OLD.elapsed_time_ms
4141+ WHERE id = OLD.user_id;
4242+ RETURN OLD;
4343+ ELSIF TG_OP = 'UPDATE' THEN
4444+ UPDATE users
4545+ SET total_takes_time = COALESCE(total_takes_time, 0) - OLD.elapsed_time_ms + NEW.elapsed_time_ms
4646+ WHERE id = NEW.user_id;
4747+ RETURN NEW;
4848+ END IF;
43494444- EXCEPTION WHEN OTHERS THEN
4545- RAISE NOTICE 'Error updating user total time: %', SQLERRM;
4646- RETURN NULL;
5050+ RETURN NULL; -- Default return for unexpected operations
47514848- RETURN NEW;
4949- END;
5050- $$ LANGUAGE plpgsql;
5252+ EXCEPTION WHEN OTHERS THEN
5353+ RAISE NOTICE 'Error updating user total time: %', SQLERRM;
5454+ RETURN NULL;
5555+ END;
5656+ $$ LANGUAGE plpgsql;
51575258 DROP TRIGGER IF EXISTS update_user_total_time_trigger ON takes;
5359