feat: Add working hours for natural traffic patterns
Workers check their timezone (from preflight IP geolocation) and current hour's weight probability to determine availability. This creates natural traffic patterns - more workers active during peak hours, fewer during off-peak. Tasks queue up at night and drain during the day. Migrations: - 099: working_hours table with hourly weights by profile - 100: Add timezone column to worker_registry - 101: Store timezone from preflight IP geolocation - 102: check_working_hours() function with probability roll 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
68
backend/migrations/099_working_hours.sql
Normal file
68
backend/migrations/099_working_hours.sql
Normal file
@@ -0,0 +1,68 @@
|
||||
-- Migration: 099_working_hours.sql
|
||||
-- Description: Working hours profiles for natural traffic pattern simulation
|
||||
-- Created: 2024-12-13
|
||||
|
||||
-- Working hours table: defines hourly activity weights to mimic natural traffic
|
||||
CREATE TABLE IF NOT EXISTS working_hours (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(50) UNIQUE NOT NULL,
|
||||
description TEXT,
|
||||
|
||||
-- Hour weights: {"0": 15, "1": 5, ..., "18": 100, ...}
|
||||
-- Value = percent chance to trigger activity that hour (0-100)
|
||||
hour_weights JSONB NOT NULL,
|
||||
|
||||
-- Day-of-week multipliers (0=Sunday, 6=Saturday)
|
||||
-- Optional adjustment for weekend vs weekday patterns
|
||||
dow_weights JSONB DEFAULT '{"0": 90, "1": 100, "2": 100, "3": 100, "4": 100, "5": 110, "6": 95}',
|
||||
|
||||
timezone VARCHAR(50) DEFAULT 'America/Phoenix',
|
||||
enabled BOOLEAN DEFAULT true,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Seed: Natural traffic pattern based on internet usage research
|
||||
-- Optimized for cannabis dispensary browsing (lunch + after-work peaks)
|
||||
INSERT INTO working_hours (name, description, timezone, hour_weights) VALUES (
|
||||
'natural_traffic',
|
||||
'Mimics natural user browsing patterns - peaks at lunch and 5-7 PM',
|
||||
'America/Phoenix',
|
||||
'{
|
||||
"0": 15,
|
||||
"1": 5,
|
||||
"2": 5,
|
||||
"3": 5,
|
||||
"4": 5,
|
||||
"5": 10,
|
||||
"6": 20,
|
||||
"7": 30,
|
||||
"8": 35,
|
||||
"9": 45,
|
||||
"10": 50,
|
||||
"11": 60,
|
||||
"12": 75,
|
||||
"13": 65,
|
||||
"14": 60,
|
||||
"15": 70,
|
||||
"16": 80,
|
||||
"17": 95,
|
||||
"18": 100,
|
||||
"19": 100,
|
||||
"20": 90,
|
||||
"21": 70,
|
||||
"22": 45,
|
||||
"23": 25
|
||||
}'::jsonb
|
||||
) ON CONFLICT (name) DO UPDATE SET
|
||||
hour_weights = EXCLUDED.hour_weights,
|
||||
description = EXCLUDED.description,
|
||||
updated_at = NOW();
|
||||
|
||||
-- Index for quick lookups
|
||||
CREATE INDEX IF NOT EXISTS idx_working_hours_name ON working_hours(name);
|
||||
CREATE INDEX IF NOT EXISTS idx_working_hours_enabled ON working_hours(enabled);
|
||||
|
||||
COMMENT ON TABLE working_hours IS 'Activity profiles for natural traffic simulation. Hour weights are percent chance (0-100) to trigger activity.';
|
||||
COMMENT ON COLUMN working_hours.hour_weights IS 'JSON object mapping hour (0-23) to percent chance (0-100). 100 = always run, 0 = never run.';
|
||||
COMMENT ON COLUMN working_hours.dow_weights IS 'Optional day-of-week multipliers. 0=Sunday. Applied as (hour_weight * dow_weight / 100).';
|
||||
Reference in New Issue
Block a user