-- Social Media Rewards & Advertising Marketplace module
USE aihub;

-- Extend wallet types
ALTER TABLE wallet_accounts
  MODIFY wallet_type ENUM('main','investment','bonus','cashback','referral','earnings','escrow') NOT NULL;

ALTER TABLE wallet_ledger
  MODIFY category VARCHAR(40) NOT NULL DEFAULT 'other';

ALTER TABLE wallet_ledger
  MODIFY wallet_type VARCHAR(20) NOT NULL;

-- Extend subscription plan types
ALTER TABLE subscription_plans
  MODIFY plan_type ENUM(
    'general','football','sure_odds','casino','forex','ads','ads_poster',
    'social_media','social_posts','social_rewards'
  ) NOT NULL DEFAULT 'general';

-- Extend member paths
ALTER TABLE users
  MODIFY member_path ENUM('general','ads_earner','ads_advertiser','sm_worker','sm_advertiser') NOT NULL DEFAULT 'general';

-- Extend sm_accounts for OAuth / sync
ALTER TABLE sm_accounts
  ADD COLUMN oauth_provider VARCHAR(40) NULL AFTER platform,
  ADD COLUMN oauth_token_enc TEXT NULL AFTER status,
  ADD COLUMN oauth_refresh_enc TEXT NULL AFTER oauth_token_enc,
  ADD COLUMN token_expires_at DATETIME NULL AFTER oauth_refresh_enc,
  ADD COLUMN following_count INT NOT NULL DEFAULT 0 AFTER follower_count,
  ADD COLUMN last_synced_at DATETIME NULL AFTER following_count,
  ADD COLUMN device_fingerprint VARCHAR(64) NULL AFTER last_synced_at;

ALTER TABLE sm_accounts
  MODIFY status ENUM('pending','active','rejected','suspended','disconnected') DEFAULT 'pending';

-- ── Core marketplace ──

CREATE TABLE IF NOT EXISTS smt_advertiser_profiles (
  id INT AUTO_INCREMENT PRIMARY KEY,
  user_id INT NOT NULL UNIQUE,
  company_name VARCHAR(160) NULL,
  business_category VARCHAR(60) NULL,
  website_url VARCHAR(500) NULL,
  credit_balance DECIMAL(15,2) NOT NULL DEFAULT 0,
  total_spent DECIMAL(15,2) NOT NULL DEFAULT 0,
  status ENUM('pending','approved','rejected','suspended') NOT NULL DEFAULT 'pending',
  rejection_reason VARCHAR(255) NULL,
  reviewed_by INT NULL,
  reviewed_at DATETIME NULL,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
  INDEX idx_smt_adv_status (status)
) ENGINE=InnoDB;

CREATE TABLE IF NOT EXISTS smt_campaigns (
  id INT AUTO_INCREMENT PRIMARY KEY,
  user_id INT NOT NULL,
  advertiser_profile_id INT NOT NULL,
  title VARCHAR(160) NOT NULL,
  description TEXT NULL,
  platform ENUM('instagram','tiktok','facebook','twitter','youtube','linkedin') NOT NULL,
  task_type ENUM('follow','like','comment','share','view','subscribe','repost','watch_video','visit_profile','join_channel') NOT NULL,
  target_url VARCHAR(500) NOT NULL,
  target_quantity INT NOT NULL,
  completed_quantity INT NOT NULL DEFAULT 0,
  pending_quantity INT NOT NULL DEFAULT 0,
  budget_total DECIMAL(15,2) NOT NULL,
  budget_spent DECIMAL(15,2) NOT NULL DEFAULT 0,
  cost_per_task DECIMAL(15,2) NOT NULL,
  reward_per_task DECIMAL(15,2) NOT NULL,
  platform_commission DECIMAL(15,2) NOT NULL DEFAULT 0,
  escrow_amount DECIMAL(15,2) NOT NULL DEFAULT 0,
  verification_method ENUM('api','screenshot','manual','ai','url_check') NOT NULL DEFAULT 'screenshot',
  proof_instructions TEXT NULL,
  geo_targets JSON NULL,
  min_followers INT NOT NULL DEFAULT 0,
  max_daily_completions INT NOT NULL DEFAULT 1,
  status ENUM('draft','pending_review','approved','active','paused','completed','rejected','expired') NOT NULL DEFAULT 'draft',
  rejection_reason VARCHAR(255) NULL,
  starts_at DATETIME NULL,
  ends_at DATETIME NULL,
  reviewed_by INT NULL,
  reviewed_at DATETIME NULL,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
  FOREIGN KEY (advertiser_profile_id) REFERENCES smt_advertiser_profiles(id),
  INDEX idx_smt_camp_status (status, platform, task_type),
  INDEX idx_smt_camp_active (status, starts_at, ends_at),
  INDEX idx_smt_camp_owner (user_id, status)
) ENGINE=InnoDB;

CREATE TABLE IF NOT EXISTS smt_campaign_tasks (
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  campaign_id INT NOT NULL,
  task_slot INT NOT NULL,
  status ENUM('available','assigned','submitted','verified','rejected','expired') NOT NULL DEFAULT 'available',
  assigned_user_id INT NULL,
  assigned_at DATETIME NULL,
  expires_at DATETIME NULL,
  reward_amount DECIMAL(15,2) NOT NULL DEFAULT 0,
  UNIQUE KEY uq_smt_camp_slot (campaign_id, task_slot),
  FOREIGN KEY (campaign_id) REFERENCES smt_campaigns(id) ON DELETE CASCADE,
  FOREIGN KEY (assigned_user_id) REFERENCES users(id) ON DELETE SET NULL,
  INDEX idx_smt_task_avail (campaign_id, status),
  INDEX idx_smt_task_user (assigned_user_id, status)
) ENGINE=InnoDB;

CREATE TABLE IF NOT EXISTS smt_task_submissions (
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  campaign_task_id BIGINT NOT NULL,
  campaign_id INT NOT NULL,
  user_id INT NOT NULL,
  sm_account_id INT NULL,
  proof_type ENUM('screenshot','url','api_response','text') NOT NULL DEFAULT 'screenshot',
  proof_url VARCHAR(500) NULL,
  proof_data JSON NULL,
  verification_status ENUM('pending','auto_verified','manual_review','approved','rejected') NOT NULL DEFAULT 'pending',
  verification_score DECIMAL(5,2) NULL,
  verified_by INT NULL,
  verified_at DATETIME NULL,
  rejection_reason VARCHAR(255) NULL,
  reward_paid DECIMAL(15,2) NOT NULL DEFAULT 0,
  fraud_score DECIMAL(5,2) NOT NULL DEFAULT 0,
  fraud_level ENUM('low','medium','high') NOT NULL DEFAULT 'low',
  ip_address VARCHAR(45) NULL,
  device_fingerprint VARCHAR(64) NULL,
  submitted_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  FOREIGN KEY (campaign_task_id) REFERENCES smt_campaign_tasks(id),
  FOREIGN KEY (campaign_id) REFERENCES smt_campaigns(id),
  FOREIGN KEY (user_id) REFERENCES users(id),
  FOREIGN KEY (sm_account_id) REFERENCES sm_accounts(id) ON DELETE SET NULL,
  INDEX idx_smt_sub_verify (verification_status, submitted_at),
  INDEX idx_smt_sub_user (user_id, verification_status),
  INDEX idx_smt_sub_camp (campaign_id, verification_status)
) ENGINE=InnoDB;

CREATE TABLE IF NOT EXISTS smt_campaign_escrow (
  id INT AUTO_INCREMENT PRIMARY KEY,
  campaign_id INT NOT NULL,
  user_id INT NOT NULL,
  amount DECIMAL(15,2) NOT NULL,
  action ENUM('hold','release','refund','partial_release') NOT NULL,
  balance_after DECIMAL(15,2) NOT NULL DEFAULT 0,
  reference_id BIGINT NULL,
  reference_table VARCHAR(40) NULL,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  FOREIGN KEY (campaign_id) REFERENCES smt_campaigns(id) ON DELETE CASCADE,
  FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
  INDEX idx_smt_escrow_camp (campaign_id, created_at)
) ENGINE=InnoDB;

CREATE TABLE IF NOT EXISTS smt_verification_logs (
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  submission_id BIGINT NOT NULL,
  method ENUM('api','screenshot','manual','ai','url_check') NOT NULL,
  result ENUM('pass','fail','inconclusive') NOT NULL,
  confidence DECIMAL(5,2) NULL,
  detail JSON NULL,
  processed_by INT NULL,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  FOREIGN KEY (submission_id) REFERENCES smt_task_submissions(id) ON DELETE CASCADE,
  INDEX idx_smt_vlog_sub (submission_id)
) ENGINE=InnoDB;

CREATE TABLE IF NOT EXISTS smt_fraud_scores (
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  user_id INT NOT NULL,
  submission_id BIGINT NULL,
  score DECIMAL(5,2) NOT NULL,
  level ENUM('low','medium','high') NOT NULL,
  signals JSON NOT NULL,
  action_taken ENUM('none','warning','temp_suspend','permanent_ban') NOT NULL DEFAULT 'none',
  reviewed_by INT NULL,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
  FOREIGN KEY (submission_id) REFERENCES smt_task_submissions(id) ON DELETE SET NULL,
  INDEX idx_smt_fraud_user (user_id, level, created_at)
) ENGINE=InnoDB;

CREATE TABLE IF NOT EXISTS smt_analytics_daily (
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  user_id INT NULL,
  campaign_id INT NULL,
  platform VARCHAR(40) NOT NULL,
  metric_date DATE NOT NULL,
  reach INT NOT NULL DEFAULT 0,
  impressions INT NOT NULL DEFAULT 0,
  clicks INT NOT NULL DEFAULT 0,
  likes INT NOT NULL DEFAULT 0,
  shares INT NOT NULL DEFAULT 0,
  comments INT NOT NULL DEFAULT 0,
  followers_growth INT NOT NULL DEFAULT 0,
  watch_time_seconds INT NOT NULL DEFAULT 0,
  engagement_rate DECIMAL(8,4) NOT NULL DEFAULT 0,
  roi DECIMAL(10,4) NULL,
  UNIQUE KEY uq_smt_analytics (user_id, campaign_id, platform, metric_date),
  INDEX idx_smt_analytics_date (metric_date, platform)
) ENGINE=InnoDB;

-- ── Engagement: offerwalls, spin, check-in, contests ──

CREATE TABLE IF NOT EXISTS smt_offerwall_providers (
  id INT AUTO_INCREMENT PRIMARY KEY,
  code VARCHAR(40) NOT NULL UNIQUE,
  name VARCHAR(100) NOT NULL,
  api_endpoint VARCHAR(500) NULL,
  api_key_enc TEXT NULL,
  postback_secret VARCHAR(128) NULL,
  commission_pct DECIMAL(5,2) NOT NULL DEFAULT 30,
  status ENUM('active','disabled') NOT NULL DEFAULT 'active',
  config_json JSON NULL
) ENGINE=InnoDB;

CREATE TABLE IF NOT EXISTS smt_offerwall_completions (
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  user_id INT NOT NULL,
  provider_id INT NOT NULL,
  external_offer_id VARCHAR(120) NOT NULL,
  offer_name VARCHAR(200) NULL,
  reward_amount DECIMAL(15,2) NOT NULL,
  platform_share DECIMAL(15,2) NOT NULL DEFAULT 0,
  status ENUM('pending','credited','reversed') NOT NULL DEFAULT 'pending',
  ip_address VARCHAR(45) NULL,
  postback_data JSON NULL,
  credited_at DATETIME NULL,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  UNIQUE KEY uq_smt_offer (provider_id, external_offer_id, user_id),
  FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
  FOREIGN KEY (provider_id) REFERENCES smt_offerwall_providers(id),
  INDEX idx_smt_offer_user (user_id, created_at)
) ENGINE=InnoDB;

CREATE TABLE IF NOT EXISTS smt_spin_rewards (
  id INT AUTO_INCREMENT PRIMARY KEY,
  label VARCHAR(60) NOT NULL,
  reward_type ENUM('cash','bonus','free_spin','multiplier') NOT NULL DEFAULT 'cash',
  reward_amount DECIMAL(15,2) NOT NULL DEFAULT 0,
  weight INT NOT NULL DEFAULT 1,
  status ENUM('active','disabled') NOT NULL DEFAULT 'active'
) ENGINE=InnoDB;

CREATE TABLE IF NOT EXISTS smt_spin_logs (
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  user_id INT NOT NULL,
  reward_id INT NOT NULL,
  reward_amount DECIMAL(15,2) NOT NULL,
  spin_date DATE NOT NULL,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
  FOREIGN KEY (reward_id) REFERENCES smt_spin_rewards(id),
  INDEX idx_smt_spin_user_date (user_id, spin_date)
) ENGINE=InnoDB;

CREATE TABLE IF NOT EXISTS smt_checkin_claims (
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  user_id INT NOT NULL,
  claim_date DATE NOT NULL,
  streak_day INT NOT NULL DEFAULT 1,
  reward_amount DECIMAL(15,2) NOT NULL,
  UNIQUE KEY uq_smt_checkin (user_id, claim_date),
  FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
) ENGINE=InnoDB;

CREATE TABLE IF NOT EXISTS smt_referral_contests (
  id INT AUTO_INCREMENT PRIMARY KEY,
  title VARCHAR(160) NOT NULL,
  description TEXT NULL,
  prize_pool DECIMAL(15,2) NOT NULL,
  min_referrals INT NOT NULL DEFAULT 1,
  starts_at DATETIME NOT NULL,
  ends_at DATETIME NOT NULL,
  status ENUM('upcoming','active','completed','cancelled') NOT NULL DEFAULT 'upcoming',
  rules_json JSON NULL,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;

CREATE TABLE IF NOT EXISTS smt_contest_entries (
  id INT AUTO_INCREMENT PRIMARY KEY,
  contest_id INT NOT NULL,
  user_id INT NOT NULL,
  referral_count INT NOT NULL DEFAULT 0,
  score DECIMAL(15,2) NOT NULL DEFAULT 0,
  prize_won DECIMAL(15,2) NOT NULL DEFAULT 0,
  rank_position INT NULL,
  UNIQUE KEY uq_smt_contest_user (contest_id, user_id),
  FOREIGN KEY (contest_id) REFERENCES smt_referral_contests(id) ON DELETE CASCADE,
  FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
) ENGINE=InnoDB;

CREATE TABLE IF NOT EXISTS smt_advertiser_credit_packages (
  id INT AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(100) NOT NULL,
  credit_amount DECIMAL(15,2) NOT NULL,
  price DECIMAL(15,2) NOT NULL,
  bonus_pct DECIMAL(5,2) NOT NULL DEFAULT 0,
  sort_order INT NOT NULL DEFAULT 0,
  status ENUM('active','disabled') NOT NULL DEFAULT 'active'
) ENGINE=InnoDB;

-- ── Queue & events ──

CREATE TABLE IF NOT EXISTS job_queue (
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  queue_name VARCHAR(60) NOT NULL DEFAULT 'default',
  job_type VARCHAR(80) NOT NULL,
  payload JSON NOT NULL,
  status ENUM('pending','processing','completed','failed','dead') NOT NULL DEFAULT 'pending',
  attempts INT NOT NULL DEFAULT 0,
  max_attempts INT NOT NULL DEFAULT 3,
  available_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  started_at DATETIME NULL,
  completed_at DATETIME NULL,
  error_message TEXT NULL,
  INDEX idx_job_poll (queue_name, status, available_at),
  INDEX idx_job_type (job_type, status)
) ENGINE=InnoDB;

CREATE TABLE IF NOT EXISTS platform_events (
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  event_type VARCHAR(80) NOT NULL,
  aggregate_type VARCHAR(40) NOT NULL,
  aggregate_id BIGINT NOT NULL,
  payload JSON NOT NULL,
  processed TINYINT(1) NOT NULL DEFAULT 0,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  INDEX idx_pe_unprocessed (processed, created_at),
  INDEX idx_pe_aggregate (aggregate_type, aggregate_id)
) ENGINE=InnoDB;

CREATE TABLE IF NOT EXISTS smt_audit_logs (
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  actor_type ENUM('user','admin','system') NOT NULL,
  actor_id INT NULL,
  action VARCHAR(80) NOT NULL,
  entity_type VARCHAR(40) NOT NULL,
  entity_id BIGINT NOT NULL,
  old_values JSON NULL,
  new_values JSON NULL,
  ip_address VARCHAR(45) NULL,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  INDEX idx_smt_audit_entity (entity_type, entity_id, created_at)
) ENGINE=InnoDB;

-- ── Module & plans ──

INSERT IGNORE INTO modules (slug, name, icon, description, status, sort_order) VALUES
('social_rewards', 'Social Rewards', '🎯', 'Complete social tasks & earn — advertisers buy engagement', 'enabled', 15);

INSERT IGNORE INTO subscription_plans (plan_code, name, plan_type, price, duration_days, perks_json, status) VALUES
('SMT-STARTER-MONTH',  'Starter Monthly',   'social_rewards', 10000,  30,  '{"monthly_task_limit":100,"tier":"starter"}', 'active'),
('SMT-STARTER-QUART',  'Starter Quarterly', 'social_rewards', 27000,  90,  '{"monthly_task_limit":100,"tier":"starter"}', 'active'),
('SMT-STARTER-YEAR',   'Starter Annual',    'social_rewards', 96000, 365,  '{"monthly_task_limit":100,"tier":"starter"}', 'active'),
('SMT-SILVER-MONTH',   'Silver Monthly',    'social_rewards', 25000,  30,  '{"monthly_task_limit":300,"tier":"silver"}', 'active'),
('SMT-SILVER-QUART',   'Silver Quarterly',  'social_rewards', 67500,  90,  '{"monthly_task_limit":300,"tier":"silver"}', 'active'),
('SMT-SILVER-YEAR',    'Silver Annual',     'social_rewards', 240000,365,  '{"monthly_task_limit":300,"tier":"silver"}', 'active'),
('SMT-GOLD-MONTH',     'Gold Monthly',      'social_rewards', 60000,  30,  '{"monthly_task_limit":1000,"tier":"gold"}', 'active'),
('SMT-GOLD-QUART',     'Gold Quarterly',    'social_rewards',162000, 90,  '{"monthly_task_limit":1000,"tier":"gold"}', 'active'),
('SMT-GOLD-YEAR',      'Gold Annual',       'social_rewards',576000,365,  '{"monthly_task_limit":1000,"tier":"gold"}', 'active'),
('SMT-PREMIUM-MONTH',  'Premium Monthly',   'social_rewards',120000, 30,  '{"monthly_task_limit":null,"tier":"premium"}', 'active'),
('SMT-PREMIUM-QUART',  'Premium Quarterly', 'social_rewards',324000, 90,  '{"monthly_task_limit":null,"tier":"premium"}', 'active'),
('SMT-PREMIUM-YEAR',   'Premium Annual',    'social_rewards',1152000,365, '{"monthly_task_limit":null,"tier":"premium"}', 'active');

INSERT IGNORE INTO unlock_rules (module_id, rule_type, plan_id, sort_order, status)
SELECT m.id, 'subscription', sp.id, sp.id, 'active'
FROM modules m
JOIN subscription_plans sp ON sp.plan_type = 'social_rewards' AND sp.status = 'active'
WHERE m.slug = 'social_rewards'
AND NOT EXISTS (
  SELECT 1 FROM unlock_rules ur WHERE ur.module_id = m.id AND ur.plan_id = sp.id
);

INSERT IGNORE INTO settings (setting_key, setting_value) VALUES
('smt_platform_commission_pct', '40'),
('smt_reward_pool_pct', '60'),
('smt_referral_commission_pct', '5'),
('smt_daily_earning_limit', '50000'),
('smt_monthly_earning_limit', '500000'),
('smt_min_withdrawal', '10000'),
('smt_task_assignment_ttl_minutes', '30'),
('smt_auto_verify_confidence_threshold', '85'),
('smt_fraud_high_threshold', '75'),
('smt_fraud_medium_threshold', '45'),
('smt_kyc_required_for_withdrawal', '1'),
('smt_spin_daily_limit', '1'),
('smt_checkin_base_reward', '500'),
('smt_min_campaign_budget', '5000'),
('smt_platform_owner_user_id', '');

INSERT IGNORE INTO smt_advertiser_credit_packages (name, credit_amount, price, bonus_pct, sort_order) VALUES
('Starter Credits', 50000, 50000, 0, 1),
('Growth Pack', 150000, 140000, 5, 2),
('Pro Pack', 500000, 450000, 10, 3),
('Enterprise Pack', 2000000, 1700000, 15, 4);

INSERT IGNORE INTO smt_spin_rewards (label, reward_type, reward_amount, weight) VALUES
('500 UGX', 'cash', 500, 30),
('1000 UGX', 'cash', 1000, 25),
('2500 UGX', 'cash', 2500, 15),
('5000 UGX', 'cash', 5000, 8),
('Try Again', 'cash', 0, 12),
('2x Next Task', 'multiplier', 0, 5),
('10000 UGX', 'cash', 10000, 5);

INSERT IGNORE INTO smt_offerwall_providers (code, name, commission_pct, status) VALUES
('demo', 'Demo Offerwall', 30, 'active');

INSERT IGNORE INTO achievements (code, title, description, icon, reward_amount, criteria_json) VALUES
('smt_first_task', 'First Task', 'Complete your first social task', '🎯', 1000, '{"type":"smt_tasks","count":1}'),
('smt_task_10', 'Task Rookie', 'Complete 10 social tasks', '⭐', 3000, '{"type":"smt_tasks","count":10}'),
('smt_task_100', 'Task Master', 'Complete 100 social tasks', '🏆', 15000, '{"type":"smt_tasks","count":100}'),
('smt_streak_7', 'Weekly Warrior', '7-day SMT check-in streak', '🔥', 5000, '{"type":"smt_streak","count":7}'),
('smt_referral_5', 'Social Recruiter', 'Refer 5 active workers', '👥', 8000, '{"type":"referrals","count":5}');

-- Ensure earnings/escrow wallets for existing users
INSERT IGNORE INTO wallet_accounts (user_id, wallet_type, balance)
SELECT id, 'earnings', 0 FROM users;

INSERT IGNORE INTO wallet_accounts (user_id, wallet_type, balance)
SELECT id, 'escrow', 0 FROM users;

ALTER TABLE leaderboard_snapshots
  MODIFY metric ENUM('wagered','wins','profit','referrals','tasks_completed') NOT NULL;
