Update: 2026-05-08 00:26:39

This commit is contained in:
Hamza-Ayed
2026-05-08 00:26:40 +03:00
parent 51d1d42f75
commit 08e2a87c10
24 changed files with 1743 additions and 210 deletions

View File

@@ -0,0 +1,87 @@
-- ════════════════════════════════════════════════════════════
-- مُصادَق — Comprehensive Phase 1 Migration
-- Tables for AI Extraction, JoFotara Integration, and Usage Logs
-- ════════════════════════════════════════════════════════════
-- 1. Invoice Line Items (For AI extracted data)
CREATE TABLE IF NOT EXISTS invoice_lines (
id CHAR(36) PRIMARY KEY DEFAULT (UUID()),
invoice_id CHAR(36) NOT NULL,
line_number INT NOT NULL,
description VARCHAR(255) NOT NULL,
quantity DECIMAL(10,3) DEFAULT 1,
unit_price DECIMAL(15,4) NOT NULL,
tax_rate DECIMAL(5,2) DEFAULT 16.00,
tax_amount DECIMAL(15,4) DEFAULT 0,
discount DECIMAL(15,4) DEFAULT 0,
total_amount DECIMAL(15,4) NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_invoice (invoice_id),
FOREIGN KEY (invoice_id) REFERENCES invoices(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 2. JoFotara Submissions Log
CREATE TABLE IF NOT EXISTS jofotara_submissions (
id CHAR(36) PRIMARY KEY DEFAULT (UUID()),
invoice_id CHAR(36) NOT NULL,
tenant_id CHAR(36) NOT NULL,
company_id CHAR(36) NOT NULL,
jofotara_uuid VARCHAR(100) NULL,
xml_content LONGTEXT NULL,
status ENUM('accepted', 'rejected', 'pending') DEFAULT 'pending',
qr_code_raw TEXT NULL, -- Base64 QR from JoFotara
response_body JSON NULL,
submitted_at DATETIME NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_invoice (invoice_id),
INDEX idx_tenant (tenant_id),
FOREIGN KEY (invoice_id) REFERENCES invoices(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 3. Update Companies for JoFotara Credentials
ALTER TABLE companies
ADD COLUMN IF NOT EXISTS jofotara_client_id VARCHAR(255) NULL AFTER tax_identification_number,
ADD COLUMN IF NOT EXISTS jofotara_secret_key VARCHAR(255) NULL AFTER jofotara_client_id,
ADD COLUMN IF NOT EXISTS jofotara_status ENUM('active', 'inactive', 'pending') DEFAULT 'inactive' AFTER jofotara_secret_key;
-- 4. Update Invoices for AI and JoFotara metadata
ALTER TABLE invoices
ADD COLUMN IF NOT EXISTS invoice_category ENUM('simplified', 'standard') DEFAULT 'simplified' AFTER invoice_type,
ADD COLUMN IF NOT EXISTS ubl_type_code VARCHAR(10) DEFAULT '388' AFTER invoice_category,
ADD COLUMN IF NOT EXISTS payment_method_code VARCHAR(10) DEFAULT '013' AFTER ubl_type_code,
ADD COLUMN IF NOT EXISTS validation_warnings JSON NULL AFTER qr_code,
ADD COLUMN IF NOT EXISTS ai_confidence DECIMAL(5,2) DEFAULT 0 AFTER validation_warnings,
ADD COLUMN IF NOT EXISTS jofotara_uuid VARCHAR(100) NULL AFTER status;
-- 5. AI Usage Log (Cost & Token tracking)
CREATE TABLE IF NOT EXISTS ai_usage_log (
id INT AUTO_INCREMENT PRIMARY KEY,
tenant_id CHAR(36) NOT NULL,
user_id CHAR(36) NULL,
company_id CHAR(36) NULL,
action_type ENUM('invoice_extraction','voice_transcribe','voice_intent','report_generation','chatbot') NOT NULL,
model_name VARCHAR(50) NOT NULL,
prompt_tokens INT DEFAULT 0,
completion_tokens INT DEFAULT 0,
total_tokens INT DEFAULT 0,
estimated_cost DECIMAL(10,6) DEFAULT 0,
request_metadata JSON NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_tenant_date (tenant_id, created_at),
FOREIGN KEY (tenant_id) REFERENCES tenants(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 6. Notifications Table
CREATE TABLE IF NOT EXISTS notifications (
id CHAR(36) PRIMARY KEY DEFAULT (UUID()),
tenant_id CHAR(36) NOT NULL,
user_id CHAR(36) NULL,
type ENUM('invoice_processed','invoice_rejected','quota_warning','month_end','system','achievement') NOT NULL,
title VARCHAR(255) NOT NULL,
body TEXT NOT NULL,
is_read BOOLEAN DEFAULT FALSE,
metadata JSON NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_user_read (user_id, is_read),
FOREIGN KEY (tenant_id) REFERENCES tenants(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

View File

@@ -0,0 +1,64 @@
#!/bin/bash
# ─────────────────────────────────────────────────────
# Musadaq Production Deployment Script
# Run this on the production server after syncing files
# ─────────────────────────────────────────────────────
set -e
echo "═══════════════════════════════════════════════"
echo " مُصادَق — Production Deployment Script"
echo "═══════════════════════════════════════════════"
# 1. Install PHP dependencies
echo ""
echo "▶ Step 1: Installing Composer dependencies..."
cd /home/musadaq/htdocs/musadaq.intaleqapp.com
composer install --no-dev --optimize-autoloader
# 2. Ensure storage directories exist
echo ""
echo "▶ Step 2: Creating storage directories..."
mkdir -p storage/invoices
mkdir -p storage/logs
mkdir -p storage/exports
mkdir -p storage/temp
chmod -R 775 storage/
# 3. Set up the Cron Job for AI Queue Worker
echo ""
echo "▶ Step 3: Setting up Cron Job for AI Worker..."
echo ""
echo " Run: crontab -e"
echo " Add this line:"
echo ""
echo " * * * * * /usr/bin/php /home/musadaq/htdocs/musadaq.intaleqapp.com/app/cron/process_batches.php >> /home/musadaq/htdocs/musadaq.intaleqapp.com/storage/logs/cron.log 2>&1"
echo ""
echo " This runs the AI Queue Worker every minute."
echo " The worker has its own lock file to prevent duplicates."
echo ""
# 4. Verify environment variables
echo "▶ Step 4: Checking .env configuration..."
if [ -f .env ]; then
echo " ✅ .env file found"
# Check critical keys
grep -q "GEMINI_API_KEY" .env && echo " ✅ GEMINI_API_KEY set" || echo " ❌ GEMINI_API_KEY missing!"
grep -q "DB_HOST" .env && echo " ✅ DB_HOST set" || echo " ❌ DB_HOST missing!"
grep -q "ENCRYPTION_KEY" .env && echo " ✅ ENCRYPTION_KEY set" || echo " ❌ ENCRYPTION_KEY missing!"
grep -q "JWT_SECRET" .env && echo " ✅ JWT_SECRET set" || echo " ❌ JWT_SECRET missing!"
grep -q "FCM_SERVER_KEY\|FIREBASE" .env && echo " ✅ Firebase key set" || echo " ⚠️ Firebase key missing (push notifications won't work)"
else
echo " ❌ .env file not found! Copy .env.example and configure it."
fi
echo ""
echo "═══════════════════════════════════════════════"
echo " ✅ Deployment Complete!"
echo ""
echo " Next steps:"
echo " 1. Add the Cron Job (shown above)"
echo " 2. Test the API: curl https://musadaq.intaleqapp.com/api/v1/auth/login"
echo " 3. Monitor logs: tail -f storage/logs/cron.log"
echo "═══════════════════════════════════════════════"

View File

@@ -0,0 +1,72 @@
-- ════════════════════════════════════════════════════════════
-- مُصادَق — Phase 1: AI Usage Tracking + Notifications
-- ════════════════════════════════════════════════════════════
-- AI Usage Log (tracks every AI request)
CREATE TABLE IF NOT EXISTS ai_usage_log (
id INT AUTO_INCREMENT PRIMARY KEY,
tenant_id CHAR(36) NOT NULL,
user_id CHAR(36) NULL,
company_id CHAR(36) NULL,
action_type ENUM('invoice_extraction','voice_transcribe','voice_intent','report_generation','chatbot') NOT NULL,
model_name VARCHAR(50) NOT NULL,
prompt_tokens INT DEFAULT 0,
completion_tokens INT DEFAULT 0,
total_tokens INT DEFAULT 0,
estimated_cost DECIMAL(10,6) DEFAULT 0,
request_metadata JSON NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_tenant_date (tenant_id, created_at),
INDEX idx_action (action_type),
FOREIGN KEY (tenant_id) REFERENCES tenants(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- Notifications
CREATE TABLE IF NOT EXISTS notifications (
id CHAR(36) PRIMARY KEY DEFAULT (UUID()),
tenant_id CHAR(36) NOT NULL,
user_id CHAR(36) NULL,
type ENUM('invoice_processed','invoice_rejected','quota_warning','month_end','system','achievement') NOT NULL,
title VARCHAR(255) NOT NULL,
body TEXT NOT NULL,
is_read BOOLEAN DEFAULT FALSE,
metadata JSON NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_user_read (user_id, is_read),
INDEX idx_tenant (tenant_id),
FOREIGN KEY (tenant_id) REFERENCES tenants(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- Referral Codes (Phase 2 prep)
CREATE TABLE IF NOT EXISTS referral_codes (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id CHAR(36) NOT NULL,
code VARCHAR(20) NOT NULL UNIQUE,
uses_count INT DEFAULT 0,
max_uses INT DEFAULT 50,
reward_months INT DEFAULT 1,
is_active BOOLEAN DEFAULT TRUE,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- Referral Uses (Phase 2 prep)
CREATE TABLE IF NOT EXISTS referral_uses (
id INT AUTO_INCREMENT PRIMARY KEY,
code_id INT NOT NULL,
referred_tenant_id CHAR(36) NOT NULL,
reward_applied BOOLEAN DEFAULT FALSE,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (code_id) REFERENCES referral_codes(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- User Achievements (Phase 2 prep)
CREATE TABLE IF NOT EXISTS user_achievements (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id CHAR(36) NOT NULL,
achievement_code VARCHAR(50) NOT NULL,
points INT NOT NULL DEFAULT 0,
earned_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
UNIQUE KEY uq_user_achievement (user_id, achievement_code)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;