Complete Phase 1: MVC, DB migrations, Auth, RBAC, Security, and Views
This commit is contained in:
25
database/migrations/001_create_roles_and_permissions.sql
Normal file
25
database/migrations/001_create_roles_and_permissions.sql
Normal file
@@ -0,0 +1,25 @@
|
||||
CREATE TABLE roles (
|
||||
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
code VARCHAR(100) NOT NULL UNIQUE,
|
||||
description TEXT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE permissions (
|
||||
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
code VARCHAR(100) NOT NULL UNIQUE,
|
||||
description TEXT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE role_permissions (
|
||||
role_id BIGINT UNSIGNED NOT NULL,
|
||||
permission_id BIGINT UNSIGNED NOT NULL,
|
||||
PRIMARY KEY (role_id, permission_id),
|
||||
FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (permission_id) REFERENCES permissions(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
20
database/migrations/002_create_users_table.sql
Normal file
20
database/migrations/002_create_users_table.sql
Normal file
@@ -0,0 +1,20 @@
|
||||
CREATE TABLE users (
|
||||
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
email VARCHAR(255) NOT NULL UNIQUE,
|
||||
password_hash VARCHAR(255) NOT NULL,
|
||||
status VARCHAR(50) NOT NULL DEFAULT 'active',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP NULL,
|
||||
INDEX idx_users_email (email),
|
||||
INDEX idx_users_status (status)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE user_roles (
|
||||
user_id BIGINT UNSIGNED NOT NULL,
|
||||
role_id BIGINT UNSIGNED NOT NULL,
|
||||
PRIMARY KEY (user_id, role_id),
|
||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
@@ -0,0 +1,69 @@
|
||||
CREATE TABLE organizations (
|
||||
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
domain VARCHAR(255) NULL UNIQUE,
|
||||
description TEXT NULL,
|
||||
type VARCHAR(50) NOT NULL, -- 'vc', 'angel', 'accelerator', 'incubator', 'venture_studio', 'partner'
|
||||
country VARCHAR(100) NULL,
|
||||
city VARCHAR(100) NULL,
|
||||
website_url VARCHAR(2048) NULL,
|
||||
linkedin_url VARCHAR(2048) NULL,
|
||||
logo_url VARCHAR(2048) NULL,
|
||||
employee_count INT NULL,
|
||||
funding_stage VARCHAR(100) NULL,
|
||||
crm_status VARCHAR(50) NOT NULL DEFAULT 'New', -- 'New', 'Researching', 'Contacted', 'Follow Up', 'Meeting Scheduled', 'Interested', 'Rejected', 'Invested'
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP NULL,
|
||||
INDEX idx_orgs_type (type),
|
||||
INDEX idx_orgs_crm_status (crm_status)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE investors (
|
||||
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
organization_id BIGINT UNSIGNED NOT NULL UNIQUE,
|
||||
min_ticket_size DECIMAL(15,2) NULL,
|
||||
max_ticket_size DECIMAL(15,2) NULL,
|
||||
investment_stages JSON NULL, -- e.g. ['Pre-Seed', 'Seed']
|
||||
target_geographies JSON NULL, -- e.g. ['KSA', 'Egypt']
|
||||
active_portfolio_count INT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP NULL,
|
||||
FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE accelerators (
|
||||
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
organization_id BIGINT UNSIGNED NOT NULL UNIQUE,
|
||||
cohort_size INT NULL,
|
||||
program_duration_weeks INT NULL,
|
||||
equity_taken_percent DECIMAL(5,2) NULL,
|
||||
funding_provided DECIMAL(15,2) NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP NULL,
|
||||
FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE incubators (
|
||||
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
organization_id BIGINT UNSIGNED NOT NULL UNIQUE,
|
||||
program_duration_weeks INT NULL,
|
||||
facilities_offered JSON NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP NULL,
|
||||
FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE venture_studios (
|
||||
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
organization_id BIGINT UNSIGNED NOT NULL UNIQUE,
|
||||
focus_areas JSON NULL,
|
||||
resources_provided JSON NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP NULL,
|
||||
FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
32
database/migrations/004_create_contacts_and_crm.sql
Normal file
32
database/migrations/004_create_contacts_and_crm.sql
Normal file
@@ -0,0 +1,32 @@
|
||||
CREATE TABLE contacts (
|
||||
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
organization_id BIGINT UNSIGNED NULL,
|
||||
first_name VARCHAR(150) NOT NULL,
|
||||
last_name VARCHAR(150) NOT NULL,
|
||||
email VARCHAR(255) NULL,
|
||||
phone VARCHAR(50) NULL,
|
||||
title VARCHAR(150) NULL,
|
||||
linkedin_url VARCHAR(2048) NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP NULL,
|
||||
FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE SET NULL,
|
||||
INDEX idx_contacts_email (email)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE crm_activities (
|
||||
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
organization_id BIGINT UNSIGNED NOT NULL,
|
||||
contact_id BIGINT UNSIGNED NULL,
|
||||
type VARCHAR(50) NOT NULL, -- 'meeting', 'email', 'note', 'follow_up'
|
||||
details TEXT NOT NULL,
|
||||
scheduled_at TIMESTAMP NULL,
|
||||
completed_at TIMESTAMP NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP NULL,
|
||||
FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (contact_id) REFERENCES contacts(id) ON DELETE SET NULL,
|
||||
INDEX idx_crm_act_type (type),
|
||||
INDEX idx_crm_act_org (organization_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
82
database/migrations/005_create_opportunities_and_tags.sql
Normal file
82
database/migrations/005_create_opportunities_and_tags.sql
Normal file
@@ -0,0 +1,82 @@
|
||||
CREATE TABLE opportunities (
|
||||
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
title VARCHAR(255) NOT NULL,
|
||||
description TEXT NOT NULL,
|
||||
type VARCHAR(50) NOT NULL, -- 'grant', 'competition', 'demo_day', 'event', 'partnership', 'investment'
|
||||
organization_id BIGINT UNSIGNED NULL,
|
||||
url VARCHAR(2048) NULL,
|
||||
deadline TIMESTAMP NULL,
|
||||
amount DECIMAL(15, 2) NULL,
|
||||
location VARCHAR(255) NULL,
|
||||
status VARCHAR(50) NOT NULL DEFAULT 'active',
|
||||
score INT NOT NULL DEFAULT 0,
|
||||
raw_data JSON NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP NULL,
|
||||
FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE SET NULL,
|
||||
INDEX idx_opps_type (type),
|
||||
INDEX idx_opps_status (status),
|
||||
INDEX idx_opps_score (score)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE tags (
|
||||
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
name VARCHAR(100) NOT NULL UNIQUE,
|
||||
slug VARCHAR(100) NOT NULL UNIQUE,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE opportunity_tags (
|
||||
opportunity_id BIGINT UNSIGNED NOT NULL,
|
||||
tag_id BIGINT UNSIGNED NOT NULL,
|
||||
PRIMARY KEY (opportunity_id, tag_id),
|
||||
FOREIGN KEY (opportunity_id) REFERENCES opportunities(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (tag_id) REFERENCES tags(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE applications (
|
||||
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
opportunity_id BIGINT UNSIGNED NOT NULL,
|
||||
status VARCHAR(50) NOT NULL DEFAULT 'draft', -- 'draft', 'submitted', 'under_review', 'accepted', 'rejected'
|
||||
submission_date TIMESTAMP NULL,
|
||||
notes TEXT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP NULL,
|
||||
FOREIGN KEY (opportunity_id) REFERENCES opportunities(id) ON DELETE CASCADE,
|
||||
INDEX idx_applications_status (status)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE partnerships (
|
||||
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
title VARCHAR(255) NOT NULL,
|
||||
description TEXT NULL,
|
||||
partner_organization_id BIGINT UNSIGNED NOT NULL,
|
||||
target_organization_id BIGINT UNSIGNED NULL,
|
||||
terms TEXT NULL,
|
||||
status VARCHAR(50) NOT NULL DEFAULT 'open', -- 'open', 'signed', 'cancelled'
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP NULL,
|
||||
FOREIGN KEY (partner_organization_id) REFERENCES organizations(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (target_organization_id) REFERENCES organizations(id) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE startup_events (
|
||||
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
organization_id BIGINT UNSIGNED NULL,
|
||||
title VARCHAR(255) NOT NULL,
|
||||
description TEXT NULL,
|
||||
start_date TIMESTAMP NULL,
|
||||
end_date TIMESTAMP NULL,
|
||||
location_type VARCHAR(50) NOT NULL, -- 'online', 'in_person', 'hybrid'
|
||||
location_address VARCHAR(500) NULL,
|
||||
event_url VARCHAR(2048) NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP NULL,
|
||||
FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE SET NULL,
|
||||
INDEX idx_events_start (start_date)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
19
database/migrations/006_create_sources_and_tracking.sql
Normal file
19
database/migrations/006_create_sources_and_tracking.sql
Normal file
@@ -0,0 +1,19 @@
|
||||
CREATE TABLE sources (
|
||||
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
url VARCHAR(2048) NOT NULL,
|
||||
type VARCHAR(50) NOT NULL, -- 'rss', 'api', 'website'
|
||||
status VARCHAR(50) NOT NULL DEFAULT 'active',
|
||||
last_crawled_at TIMESTAMP NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP NULL,
|
||||
INDEX idx_sources_status (status)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE source_categories (
|
||||
source_id BIGINT UNSIGNED NOT NULL,
|
||||
category VARCHAR(100) NOT NULL,
|
||||
PRIMARY KEY (source_id, category),
|
||||
FOREIGN KEY (source_id) REFERENCES sources(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
56
database/migrations/007_create_reports_and_notifications.sql
Normal file
56
database/migrations/007_create_reports_and_notifications.sql
Normal file
@@ -0,0 +1,56 @@
|
||||
CREATE TABLE ai_reports (
|
||||
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
title VARCHAR(255) NOT NULL,
|
||||
content JSON NOT NULL,
|
||||
generation_date DATE NOT NULL,
|
||||
report_type VARCHAR(50) NOT NULL DEFAULT 'daily', -- 'daily', 'weekly', 'custom'
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
INDEX idx_ai_reports_date (generation_date)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE email_reports (
|
||||
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
ai_report_id BIGINT UNSIGNED NOT NULL,
|
||||
recipient_email VARCHAR(255) NOT NULL,
|
||||
status VARCHAR(50) NOT NULL DEFAULT 'pending', -- 'pending', 'sent', 'failed'
|
||||
sent_at TIMESTAMP NULL,
|
||||
error_message TEXT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (ai_report_id) REFERENCES ai_reports(id) ON DELETE CASCADE,
|
||||
INDEX idx_email_rep_status (status)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE activity_logs (
|
||||
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
user_id BIGINT UNSIGNED NULL,
|
||||
action VARCHAR(255) NOT NULL,
|
||||
description TEXT NULL,
|
||||
ip_address VARCHAR(45) NULL,
|
||||
user_agent VARCHAR(500) NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE notifications (
|
||||
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
user_id BIGINT UNSIGNED NOT NULL,
|
||||
title VARCHAR(255) NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
read_at TIMESTAMP NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
|
||||
INDEX idx_notifications_unread (user_id, read_at)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE settings (
|
||||
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
`key` VARCHAR(100) NOT NULL UNIQUE,
|
||||
value TEXT NULL,
|
||||
description TEXT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
INDEX idx_settings_key (`key`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
154
database/seeds/DatabaseSeeder.php
Normal file
154
database/seeds/DatabaseSeeder.php
Normal file
@@ -0,0 +1,154 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeds;
|
||||
|
||||
use App\Services\Database\Connection;
|
||||
use PDO;
|
||||
|
||||
class DatabaseSeeder
|
||||
{
|
||||
private PDO $pdo;
|
||||
|
||||
public function __construct(Connection $connection)
|
||||
{
|
||||
$this->pdo = $connection->getPdo();
|
||||
}
|
||||
|
||||
/**
|
||||
* Seed all defaults.
|
||||
*/
|
||||
public function seed(): void
|
||||
{
|
||||
echo "Seeding roles and permissions...\n";
|
||||
$this->seedRolesAndPermissions();
|
||||
|
||||
echo "Seeding default settings...\n";
|
||||
$this->seedSettings();
|
||||
|
||||
echo "Seeding sample crawler sources...\n";
|
||||
$this->seedSources();
|
||||
|
||||
echo "Seeding default administrator...\n";
|
||||
$this->seedDefaultAdmin();
|
||||
|
||||
echo "Seeding completed successfully!\n";
|
||||
}
|
||||
|
||||
private function seedRolesAndPermissions(): void
|
||||
{
|
||||
// Insert Roles
|
||||
$roles = [
|
||||
['name' => 'Administrator', 'code' => 'admin', 'description' => 'Full administrative access to the platform.'],
|
||||
['name' => 'Member', 'code' => 'member', 'description' => 'Access to CRM, Opportunities and Reports.'],
|
||||
];
|
||||
|
||||
foreach ($roles as $role) {
|
||||
$stmt = $this->pdo->prepare("INSERT IGNORE INTO roles (name, code, description) VALUES (?, ?, ?)");
|
||||
$stmt->execute([$role['name'], $role['code'], $role['description']]);
|
||||
}
|
||||
|
||||
// Insert Permissions
|
||||
$permissions = [
|
||||
['name' => 'View Dashboard', 'code' => 'view_dashboard', 'description' => 'Access the admin dashboard metrics.'],
|
||||
['name' => 'Manage CRM', 'code' => 'manage_crm', 'description' => 'Create/update contacts and log interactions.'],
|
||||
['name' => 'View Opportunities', 'code' => 'view_opportunities', 'description' => 'Browse VCs, grants and accelerators.'],
|
||||
['name' => 'Run Collectors', 'code' => 'run_collectors', 'description' => 'Manually trigger crawler collections.'],
|
||||
['name' => 'Generate Reports', 'code' => 'generate_reports', 'description' => 'Trigger AI daily summaries.'],
|
||||
['name' => 'Manage Settings', 'code' => 'manage_settings', 'description' => 'Update application parameters.'],
|
||||
['name' => 'Manage Users', 'code' => 'manage_users', 'description' => 'Manage roles and accounts of users.'],
|
||||
];
|
||||
|
||||
foreach ($permissions as $permission) {
|
||||
$stmt = $this->pdo->prepare("INSERT IGNORE INTO permissions (name, code, description) VALUES (?, ?, ?)");
|
||||
$stmt->execute([$permission['name'], $permission['code'], $permission['description']]);
|
||||
}
|
||||
|
||||
// Fetch Role IDs and Permission IDs
|
||||
$roleIds = $this->pdo->query("SELECT id, code FROM roles")->fetchAll(PDO::FETCH_KEY_PAIR);
|
||||
$permissionIds = $this->pdo->query("SELECT id, code FROM permissions")->fetchAll(PDO::FETCH_KEY_PAIR);
|
||||
|
||||
// Map Permissions to Admin (All permissions)
|
||||
foreach ($permissionIds as $pId => $pCode) {
|
||||
$stmt = $this->pdo->prepare("INSERT IGNORE INTO role_permissions (role_id, permission_id) VALUES (?, ?)");
|
||||
$stmt->execute([$roleIds['admin'], $pId]);
|
||||
}
|
||||
|
||||
// Map Permissions to Member (Subset of permissions)
|
||||
$memberPermissions = ['view_dashboard', 'manage_crm', 'view_opportunities', 'generate_reports'];
|
||||
foreach ($permissionIds as $pId => $pCode) {
|
||||
if (in_array($pCode, $memberPermissions)) {
|
||||
$stmt = $this->pdo->prepare("INSERT IGNORE INTO role_permissions (role_id, permission_id) VALUES (?, ?)");
|
||||
$stmt->execute([$roleIds['member'], $pId]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function seedSettings(): void
|
||||
{
|
||||
$settings = [
|
||||
['key' => 'system_email', 'value' => 'info@scoutiq.intaleqapp.com', 'description' => 'Primary sender email address.'],
|
||||
['key' => 'crawler_enabled', 'value' => 'true', 'description' => 'Global toggle for data collection crawlers.'],
|
||||
['key' => 'crawler_interval_hours', 'value' => '24', 'description' => 'Delay between crawler runs.'],
|
||||
];
|
||||
|
||||
foreach ($settings as $setting) {
|
||||
$stmt = $this->pdo->prepare("INSERT IGNORE INTO settings (`key`, value, description) VALUES (?, ?, ?)");
|
||||
$stmt->execute([$setting['key'], $setting['value'], $setting['description']]);
|
||||
}
|
||||
}
|
||||
|
||||
private function seedSources(): void
|
||||
{
|
||||
$sources = [
|
||||
['name' => 'TechCrunch Mobility Feed', 'url' => 'https://techcrunch.com/category/transportation/feed/', 'type' => 'rss'],
|
||||
['name' => 'VentureBeat AI Feed', 'url' => 'https://venturebeat.com/category/ai/feed/', 'type' => 'rss'],
|
||||
['name' => 'YC Directory API', 'url' => 'https://api.ycombinator.com/v1/companies', 'type' => 'api'],
|
||||
];
|
||||
|
||||
foreach ($sources as $source) {
|
||||
$stmt = $this->pdo->prepare("SELECT id FROM sources WHERE url = ?");
|
||||
$stmt->execute([$source['url']]);
|
||||
if (!$stmt->fetch()) {
|
||||
$stmt = $this->pdo->prepare("INSERT INTO sources (name, url, type, status) VALUES (?, ?, ?, 'active')");
|
||||
$stmt->execute([$source['name'], $source['url'], $source['type']]);
|
||||
$sourceId = (int)$this->pdo->lastInsertId();
|
||||
|
||||
$category = str_contains($source['name'], 'Mobility') ? 'mobility' : 'ai';
|
||||
$stmt = $this->pdo->prepare("INSERT INTO source_categories (source_id, category) VALUES (?, ?)");
|
||||
$stmt->execute([$sourceId, $category]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function seedDefaultAdmin(): void
|
||||
{
|
||||
$email = 'admin@scoutiq.com';
|
||||
$stmt = $this->pdo->prepare("SELECT id FROM users WHERE email = ?");
|
||||
$stmt->execute([$email]);
|
||||
if (!$stmt->fetch()) {
|
||||
$passwordHash = password_hash('AdminScout123!', PASSWORD_BCRYPT);
|
||||
|
||||
$this->pdo->beginTransaction();
|
||||
try {
|
||||
$stmt = $this->pdo->prepare("INSERT INTO users (name, email, password_hash, status) VALUES (?, ?, ?, 'active')");
|
||||
$stmt->execute(['ScoutIQ Admin', $email, $passwordHash]);
|
||||
$userId = (int)$this->pdo->lastInsertId();
|
||||
|
||||
$stmt = $this->pdo->prepare("SELECT id FROM roles WHERE code = 'admin'");
|
||||
$stmt->execute();
|
||||
$roleId = $stmt->fetchColumn();
|
||||
|
||||
if ($roleId) {
|
||||
$stmt = $this->pdo->prepare("INSERT INTO user_roles (user_id, role_id) VALUES (?, ?)");
|
||||
$stmt->execute([$userId, $roleId]);
|
||||
}
|
||||
|
||||
$this->pdo->commit();
|
||||
echo "Admin User Created: {$email} / AdminScout123!\n";
|
||||
} catch (\Exception $e) {
|
||||
$this->pdo->rollBack();
|
||||
echo "Failed to create default admin: " . $e->getMessage() . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user