mirror of
https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools.git
synced 2026-06-18 07:19:35 +00:00
feat(dealix): complete Tier-1 Sovereign Enterprise Growth OS
Governance layer (14 docs): - MASTER_OPERATING_PROMPT.md — operating constitution (five planes, six tracks, policy classes) - docs/ai-operating-model.md — five-plane architecture (Decision/Execution/Trust/Data/Operating) - docs/dealix-six-tracks.md — six strategic tracks (Revenue/Intelligence/Compliance/Expansion/Operations/Trust) - docs/governance/execution-fabric.md — OpenClaw execution plane deep dive - docs/governance/trust-fabric.md — trust plane with contradiction engine + evidence packs - docs/governance/saudi-compliance-and-ai-governance.md — PDPL/ZATCA/SDAIA/NCA live controls - docs/governance/technology-radar-tier1.md — Core/Strong/Pilot/Watch/Hold classification - docs/governance/partnership-os.md — alliance lifecycle management - docs/governance/ma-os.md — M&A corporate development lifecycle - docs/governance/expansion-os.md — geographic and vertical growth - docs/governance/pmi-os.md — post-merger integration framework - docs/governance/executive-board-os.md — executive decision surfaces - docs/execution-matrix-90d-tier1.md — 90-day sprint execution plan - docs/adr/0001-tier1-execution-policy-spikes.md — 8 architectural decisions Backend (3 models, 6 services, 8 API routes): - Contradiction Engine — detect/track system conflicts - Evidence Pack System — tamper-evident audit proof with SHA256 - Saudi Compliance Matrix — live PDPL/ZATCA/SDAIA/NCA controls - Executive Room — unified executive decision surface - Connector Governance — integration health monitoring - Model Routing Dashboard — LLM provider metrics - Forecast Control Center — actual vs forecast across tracks - Approval Center — enhanced approval queue with SLA Frontend (9 components): - Executive Room, Evidence Pack Viewer, Approval Center - Connector Governance Board, Saudi Compliance Dashboard - Actual vs Forecast Dashboard, Risk Heatmap - Policy Violations Board, Partner Pipeline Board Tooling: - scripts/architecture_brief.py — preflight validation (40/40 checks pass) - Updated CLAUDE.md and AGENTS.md with governance references https://claude.ai/code/session_01W1rJthWDkasijTdXCfxVHs
This commit is contained in:
parent
69f5082e5e
commit
a319feb6d7
@ -120,3 +120,27 @@ cd frontend && npm run dev
|
|||||||
5. Deploy to production with canary (10%)
|
5. Deploy to production with canary (10%)
|
||||||
6. Monitor 30 min → full rollout
|
6. Monitor 30 min → full rollout
|
||||||
7. Rollback plan documented per release
|
7. Rollback plan documented per release
|
||||||
|
|
||||||
|
## Governance Integration (Tier-1)
|
||||||
|
|
||||||
|
All agents operate under the governance framework defined in `MASTER_OPERATING_PROMPT.md`:
|
||||||
|
|
||||||
|
- **Trust Plane**: Every agent action is classified as A/B/C via `openclaw/policy.py`. Class B actions (messaging, payments, CRM sync) require approval tokens.
|
||||||
|
- **Evidence Packs**: Agent outputs logged to `ai_conversations` contribute to evidence pack assembly.
|
||||||
|
- **Contradiction Detection**: Agent-generated content is subject to contradiction checks against governance docs.
|
||||||
|
- **Structured Outputs**: All critical agent outputs use defined schemas (LeadScoreCard, QualificationMemo, ProposalPack, etc.).
|
||||||
|
|
||||||
|
### New Tier-1 API Surfaces
|
||||||
|
- `GET /api/v1/executive-room/snapshot` — Executive Room
|
||||||
|
- `GET /api/v1/contradictions/` — Contradiction Engine
|
||||||
|
- `GET /api/v1/evidence-packs/` — Evidence Pack Viewer
|
||||||
|
- `GET /api/v1/approval-center/` — Approval Center
|
||||||
|
- `GET /api/v1/connectors/governance` — Connector Governance
|
||||||
|
- `GET /api/v1/model-routing/dashboard` — Model Routing
|
||||||
|
- `GET /api/v1/compliance/matrix/` — Saudi Compliance Matrix
|
||||||
|
- `GET /api/v1/forecast-control/unified` — Actual vs Forecast
|
||||||
|
|
||||||
|
### Architecture Preflight
|
||||||
|
```bash
|
||||||
|
python scripts/architecture_brief.py # Run from salesflow-saas/ root
|
||||||
|
```
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
# CLAUDE.md — Dealix Project Context for AI Agents
|
# CLAUDE.md — Dealix Project Context for AI Agents
|
||||||
|
|
||||||
## Quick Context
|
## Quick Context
|
||||||
Dealix is an AI-powered CRM built for the Saudi market. It combines Salesforce-grade AI with WhatsApp-first communication, PDPL compliance, and Arabic-first UX.
|
Dealix is a **Sovereign Enterprise Growth OS for GCC Companies**. It manages Revenue, Partnerships, Corporate Development/M&A, Expansion, PMI, and Trust/Governance — with AI agents, durable workflows, and policy-enforced execution.
|
||||||
|
|
||||||
|
**Operating Constitution**: See `MASTER_OPERATING_PROMPT.md` for the canonical reference.
|
||||||
|
|
||||||
## Key Directories
|
## Key Directories
|
||||||
- `backend/app/api/v1/` — API routes (FastAPI)
|
- `backend/app/api/v1/` — API routes (FastAPI)
|
||||||
@ -17,6 +19,10 @@ Dealix is an AI-powered CRM built for the Saudi market. It combines Salesforce-g
|
|||||||
- `frontend/src/app/` — Next.js pages
|
- `frontend/src/app/` — Next.js pages
|
||||||
- `seeds/` — Industry templates (JSON)
|
- `seeds/` — Industry templates (JSON)
|
||||||
- `memory/` — Project knowledge base
|
- `memory/` — Project knowledge base
|
||||||
|
- `docs/governance/` — Governance framework (execution-fabric, trust-fabric, compliance, radar)
|
||||||
|
- `docs/adr/` — Architecture Decision Records
|
||||||
|
- `scripts/` — Architecture brief and tooling
|
||||||
|
- `MASTER_OPERATING_PROMPT.md` — Operating constitution (five planes, six tracks, policy classes)
|
||||||
|
|
||||||
## Database
|
## Database
|
||||||
- PostgreSQL 16 with async driver (asyncpg)
|
- PostgreSQL 16 with async driver (asyncpg)
|
||||||
@ -98,3 +104,13 @@ Installed and active. Automatically captures every session's work and injects co
|
|||||||
- **Privacy**: Wrap sensitive content in `<private>...</private>` tags
|
- **Privacy**: Wrap sensitive content in `<private>...</private>` tags
|
||||||
- **Token savings**: ~95% reduction via 3-layer progressive retrieval
|
- **Token savings**: ~95% reduction via 3-layer progressive retrieval
|
||||||
- **Auto-captures**: tool executions, session summaries, decisions, bugs, patterns
|
- **Auto-captures**: tool executions, session summaries, decisions, bugs, patterns
|
||||||
|
|
||||||
|
## Governance Framework (Tier-1)
|
||||||
|
|
||||||
|
- **Five Planes**: Decision, Execution, Trust, Data, Operating — see `docs/ai-operating-model.md`
|
||||||
|
- **Six Tracks**: Revenue, Intelligence, Compliance, Expansion, Operations, Trust — see `docs/dealix-six-tracks.md`
|
||||||
|
- **Policy Classes**: A (auto), B (approval), C (forbidden) — enforced by `openclaw/policy.py`
|
||||||
|
- **Contradiction Engine**: Detect/track system conflicts — `services/contradiction_engine.py`
|
||||||
|
- **Evidence Packs**: Tamper-evident audit proof — `services/evidence_pack_service.py`
|
||||||
|
- **Saudi Compliance Matrix**: Live PDPL/ZATCA/SDAIA/NCA controls — `services/saudi_compliance_matrix.py`
|
||||||
|
- **Architecture Preflight**: `python scripts/architecture_brief.py` (run from repo root)
|
||||||
|
|||||||
161
salesflow-saas/MASTER_OPERATING_PROMPT.md
Normal file
161
salesflow-saas/MASTER_OPERATING_PROMPT.md
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
# MASTER OPERATING PROMPT — Dealix Sovereign Enterprise Growth OS
|
||||||
|
|
||||||
|
> **Version**: 1.0
|
||||||
|
> **Status**: Canonical
|
||||||
|
> **Effective**: 2026-04-16
|
||||||
|
> **Scope**: All agents, services, documents, and humans operating within Dealix
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Identity
|
||||||
|
|
||||||
|
**Dealix** is a **Sovereign Enterprise Growth OS for GCC Companies**.
|
||||||
|
|
||||||
|
It is a single platform that manages:
|
||||||
|
- **Revenue** — lead-to-cash lifecycle
|
||||||
|
- **Partnerships** — alliance scouting to co-sell
|
||||||
|
- **Corporate Development / M&A** — target sourcing to PMI
|
||||||
|
- **Expansion** — market scanning to post-launch
|
||||||
|
- **PMI / Strategic PMO** — Day-1 readiness to synergy realization
|
||||||
|
- **Trust / Governance / Executive Decisioning** — policy gates to board packs
|
||||||
|
|
||||||
|
**Central Law**:
|
||||||
|
> AI explores, analyzes, and proposes. Systems execute. Humans approve critical decisions. Everything is proven by evidence.
|
||||||
|
|
||||||
|
**Design Philosophy**:
|
||||||
|
> Agentic by design, governed by policy, proven by evidence.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Five-Plane Architecture
|
||||||
|
|
||||||
|
Every component in Dealix belongs to exactly one plane:
|
||||||
|
|
||||||
|
| Plane | Purpose | Key Code |
|
||||||
|
|-------|---------|----------|
|
||||||
|
| **Decision** | Strategic reasoning, forecasting, memo generation | `executive_roi_service.py`, `analytics_service.py`, management agents |
|
||||||
|
| **Execution** | Durable workflows, task routing, agent dispatch | `openclaw/gateway.py`, `durable_flow.py`, `task_router.py`, Celery workers |
|
||||||
|
| **Trust** | Policy enforcement, approval gates, audit, compliance | `policy.py`, `approval_bridge.py`, `hooks.py`, `pdpl/`, `audit_service.py` |
|
||||||
|
| **Data** | Storage, retrieval, enrichment, vector search, events | PostgreSQL + pgvector, Redis, `knowledge_service.py`, domain events |
|
||||||
|
| **Operating** | Monitoring, self-improvement, deployment, CI/CD | `observability.py`, `self_improvement.py`, `feature_flags.py`, GitHub Actions |
|
||||||
|
|
||||||
|
Full specification: [`docs/ai-operating-model.md`](docs/ai-operating-model.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Six Tracks
|
||||||
|
|
||||||
|
All work is organized into six strategic tracks:
|
||||||
|
|
||||||
|
| Track | Domain | Owner Focus |
|
||||||
|
|-------|--------|-------------|
|
||||||
|
| **Revenue** | Lead capture → qualification → deal → close → renewal | Sales & Growth |
|
||||||
|
| **Intelligence** | Signal detection, behavior analysis, forecasting, AI agents | AI & Data |
|
||||||
|
| **Compliance** | PDPL, ZATCA, SDAIA, sector regulations, audit trails | Legal & Security |
|
||||||
|
| **Expansion** | Strategic deals, M&A, partnerships, geographic expansion | Corporate Dev |
|
||||||
|
| **Operations** | Deployment, monitoring, connectors, infrastructure | Engineering & Ops |
|
||||||
|
| **Trust** | Policy gates, approval SLAs, evidence packs, contradiction detection | Governance |
|
||||||
|
|
||||||
|
Full specification: [`docs/dealix-six-tracks.md`](docs/dealix-six-tracks.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Policy Classes
|
||||||
|
|
||||||
|
Every action in the system is classified:
|
||||||
|
|
||||||
|
| Class | Behavior | Examples |
|
||||||
|
|-------|----------|----------|
|
||||||
|
| **A — Auto-allowed** | Execute without approval | `read_status`, `classify`, `summarize`, `research`, `generate_draft` |
|
||||||
|
| **B — Approval-gated** | Requires human approval token | `send_whatsapp`, `send_email`, `create_charge`, `sync_salesforce`, `send_contract_for_signature` |
|
||||||
|
| **C — Forbidden** | Blocked unconditionally | `exfiltrate_secrets`, `delete_data_without_audit`, `bypass_auth` |
|
||||||
|
|
||||||
|
Implementation: [`backend/app/openclaw/policy.py`](backend/app/openclaw/policy.py)
|
||||||
|
|
||||||
|
**Default rule**: Unknown actions are classified as **Class B** (approval required).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Execution Principles
|
||||||
|
|
||||||
|
1. **Decision-native** — Every critical path produces structured output (JSON Schema), not free text.
|
||||||
|
2. **Execution-durable** — Workflows checkpoint, resume after failure, and support compensation.
|
||||||
|
3. **Trust-enforced** — No sensitive action bypasses the policy gate.
|
||||||
|
4. **Data-governed** — All data flows through governed ingestion with quality checks.
|
||||||
|
5. **Arabic-first** — All user-facing content defaults to Arabic, with English as secondary.
|
||||||
|
6. **Saudi-ready** — PDPL, ZATCA, SDAIA, NCA controls are live, not aspirational.
|
||||||
|
7. **Board-usable** — Executive surfaces show what changed, what needs decision, what is at risk.
|
||||||
|
8. **Enterprise-saleable** — Evidence packs, audit trails, and compliance matrices are exportable.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Non-Negotiable Rules
|
||||||
|
|
||||||
|
1. **Tenant isolation**: Every query is scoped by `tenant_id`. Cross-tenant access is blocked at ORM layer.
|
||||||
|
2. **Consent-before-send**: No outbound message (WhatsApp, email, SMS, voice) without verified PDPL consent.
|
||||||
|
3. **Audit everything**: Every state change writes to `audit_logs`. Every AI decision writes to `ai_conversations`.
|
||||||
|
4. **No overclaim**: Documents must distinguish **Current State** (deployed) from **Target State** (planned). Never claim what is not in production.
|
||||||
|
5. **Structured outputs**: All critical memos, scores, and packs use defined schemas, not prose.
|
||||||
|
6. **Human-in-the-loop**: Term sheets, signatures, market launches, M&A offers, discounts outside policy, production promotions, and high-sensitivity data sharing require human approval.
|
||||||
|
7. **Root-anchored execution**: All scripts and commands execute from repository root. `scripts/architecture_brief.py` is the official preflight.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Contradiction Resolution
|
||||||
|
|
||||||
|
When documents or systems conflict:
|
||||||
|
|
||||||
|
1. **MASTER_OPERATING_PROMPT.md** wins over all other documents.
|
||||||
|
2. Governance docs (`docs/governance/*`) win over operational docs.
|
||||||
|
3. `CLAUDE.md` / `AGENTS.md` win over `memory/` docs.
|
||||||
|
4. Code behavior wins over comments about code behavior.
|
||||||
|
5. Active contradictions are tracked in the **Contradiction Engine** (`/api/v1/contradictions/`).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. Technology Radar Summary
|
||||||
|
|
||||||
|
| Tier | Technologies |
|
||||||
|
|------|-------------|
|
||||||
|
| **Core** (production) | FastAPI, SQLAlchemy, PostgreSQL 16, Redis, Celery, Next.js 15, OpenClaw 2026.4.x, Groq, WhatsApp Cloud API |
|
||||||
|
| **Strong** (validated) | Claude Opus, Salesforce Agentforce, Stripe, pgvector, Mem0, LangGraph |
|
||||||
|
| **Pilot** (behind flags) | Voice agents, Contract intelligence, Gemini/DeepSeek routing |
|
||||||
|
| **Watch** (evaluating) | Temporal, OPA, OpenFGA, Vault, Gong, Apollo |
|
||||||
|
| **Hold** (not adopting) | External RAG SaaS, schema-per-tenant, GraphQL |
|
||||||
|
|
||||||
|
Full specification: [`docs/governance/technology-radar-tier1.md`](docs/governance/technology-radar-tier1.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. Document Index
|
||||||
|
|
||||||
|
| Document | Path | Purpose |
|
||||||
|
|----------|------|---------|
|
||||||
|
| AI Operating Model | `docs/ai-operating-model.md` | Five-plane architecture |
|
||||||
|
| Six Tracks | `docs/dealix-six-tracks.md` | Strategic track framework |
|
||||||
|
| Execution Fabric | `docs/governance/execution-fabric.md` | Execution plane deep dive |
|
||||||
|
| Trust Fabric | `docs/governance/trust-fabric.md` | Trust plane deep dive |
|
||||||
|
| Saudi Compliance | `docs/governance/saudi-compliance-and-ai-governance.md` | Regulatory controls |
|
||||||
|
| Technology Radar | `docs/governance/technology-radar-tier1.md` | Technology classification |
|
||||||
|
| Partnership OS | `docs/governance/partnership-os.md` | Partnership lifecycle |
|
||||||
|
| M&A OS | `docs/governance/ma-os.md` | Corporate development |
|
||||||
|
| Expansion OS | `docs/governance/expansion-os.md` | Geographic/vertical expansion |
|
||||||
|
| PMI OS | `docs/governance/pmi-os.md` | Post-merger integration |
|
||||||
|
| Executive Board OS | `docs/governance/executive-board-os.md` | Board reporting framework |
|
||||||
|
| 90-Day Matrix | `docs/execution-matrix-90d-tier1.md` | Sprint execution plan |
|
||||||
|
| ADR 0001 | `docs/adr/0001-tier1-execution-policy-spikes.md` | Tier-1 policy decisions |
|
||||||
|
| Architecture | `docs/ARCHITECTURE.md` | System diagram |
|
||||||
|
| Data Model | `docs/DATA-MODEL.md` | Database schema |
|
||||||
|
| Agent Map | `docs/AGENT-MAP.md` | 19 AI agents |
|
||||||
|
| API Map | `docs/API-MAP.md` | 70+ endpoints |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. Enforcement
|
||||||
|
|
||||||
|
This document is enforced by:
|
||||||
|
- `scripts/architecture_brief.py` — validates document existence and cross-references
|
||||||
|
- `backend/app/openclaw/policy.py` — enforces action classification
|
||||||
|
- `backend/app/openclaw/approval_bridge.py` — enforces approval gates
|
||||||
|
- `.github/workflows/dealix-ci.yml` — runs tests and checks on every PR
|
||||||
|
- Contradiction Engine — detects and tracks document/system conflicts
|
||||||
57
salesflow-saas/backend/app/api/v1/approval_center.py
Normal file
57
salesflow-saas/backend/app/api/v1/approval_center.py
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
"""Approval Center API — enhanced approval queue with SLA tracking."""
|
||||||
|
|
||||||
|
from fastapi import APIRouter
|
||||||
|
from pydantic import BaseModel as PydanticBase
|
||||||
|
from typing import Any, Dict, Optional
|
||||||
|
|
||||||
|
router = APIRouter(prefix="/approval-center", tags=["Approval Center"])
|
||||||
|
|
||||||
|
|
||||||
|
class ApprovalAction(PydanticBase):
|
||||||
|
note: Optional[str] = None
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/")
|
||||||
|
async def list_approvals(
|
||||||
|
category: Optional[str] = None,
|
||||||
|
priority: Optional[str] = None,
|
||||||
|
status: Optional[str] = "pending",
|
||||||
|
) -> Dict[str, Any]:
|
||||||
|
"""List pending approvals with SLA status."""
|
||||||
|
return {"approvals": [], "total": 0}
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/stats")
|
||||||
|
async def approval_stats() -> Dict[str, Any]:
|
||||||
|
"""Get approval velocity and SLA compliance."""
|
||||||
|
return {
|
||||||
|
"total_pending": 0,
|
||||||
|
"sla_compliant": 0,
|
||||||
|
"sla_warning": 0,
|
||||||
|
"sla_breach": 0,
|
||||||
|
"avg_approval_time_hours": 0.0,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/my-pending")
|
||||||
|
async def my_pending_approvals() -> Dict[str, Any]:
|
||||||
|
"""Get approvals assigned to current user."""
|
||||||
|
return {"approvals": [], "total": 0}
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/{approval_id}/approve")
|
||||||
|
async def approve(approval_id: str, body: ApprovalAction) -> Dict[str, Any]:
|
||||||
|
"""Approve a request."""
|
||||||
|
return {"id": approval_id, "status": "approved", "note": body.note}
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/{approval_id}/reject")
|
||||||
|
async def reject(approval_id: str, body: ApprovalAction) -> Dict[str, Any]:
|
||||||
|
"""Reject a request."""
|
||||||
|
return {"id": approval_id, "status": "rejected", "note": body.note}
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/{approval_id}/escalate")
|
||||||
|
async def escalate(approval_id: str, body: ApprovalAction) -> Dict[str, Any]:
|
||||||
|
"""Escalate a request."""
|
||||||
|
return {"id": approval_id, "status": "escalated", "note": body.note}
|
||||||
30
salesflow-saas/backend/app/api/v1/connector_governance.py
Normal file
30
salesflow-saas/backend/app/api/v1/connector_governance.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
"""Connector Governance API — integration health and governance."""
|
||||||
|
|
||||||
|
from fastapi import APIRouter
|
||||||
|
from typing import Any, Dict, List
|
||||||
|
|
||||||
|
router = APIRouter(prefix="/connectors", tags=["Connector Governance"])
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/governance")
|
||||||
|
async def governance_board() -> Dict[str, Any]:
|
||||||
|
"""Get connector governance board."""
|
||||||
|
return {"connectors": [], "total": 0}
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/{connector_key}/health-check")
|
||||||
|
async def health_check(connector_key: str) -> Dict[str, Any]:
|
||||||
|
"""Trigger health check for a specific connector."""
|
||||||
|
return {"connector_key": connector_key, "status": "checked"}
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/{connector_key}/history")
|
||||||
|
async def connector_history(connector_key: str) -> Dict[str, Any]:
|
||||||
|
"""Get sync history for a connector."""
|
||||||
|
return {"connector_key": connector_key, "history": []}
|
||||||
|
|
||||||
|
|
||||||
|
@router.put("/{connector_key}/disable")
|
||||||
|
async def disable_connector(connector_key: str) -> Dict[str, Any]:
|
||||||
|
"""Disable a connector."""
|
||||||
|
return {"connector_key": connector_key, "status": "disabled"}
|
||||||
61
salesflow-saas/backend/app/api/v1/contradiction.py
Normal file
61
salesflow-saas/backend/app/api/v1/contradiction.py
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
"""Contradiction Engine API — detect and manage system contradictions."""
|
||||||
|
|
||||||
|
from fastapi import APIRouter, Depends, HTTPException
|
||||||
|
from pydantic import BaseModel as PydanticBase
|
||||||
|
from typing import Any, Dict, List, Optional
|
||||||
|
|
||||||
|
router = APIRouter(prefix="/contradictions", tags=["Contradictions"])
|
||||||
|
|
||||||
|
|
||||||
|
class ContradictionCreate(PydanticBase):
|
||||||
|
source_a: str
|
||||||
|
source_b: str
|
||||||
|
claim_a: str
|
||||||
|
claim_b: str
|
||||||
|
contradiction_type: str = "factual"
|
||||||
|
severity: str = "medium"
|
||||||
|
detected_by: str = "manual"
|
||||||
|
evidence: Optional[Dict[str, Any]] = None
|
||||||
|
|
||||||
|
|
||||||
|
class ContradictionResolve(PydanticBase):
|
||||||
|
resolution: str
|
||||||
|
status: str = "resolved"
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/")
|
||||||
|
async def register_contradiction(body: ContradictionCreate) -> Dict[str, Any]:
|
||||||
|
"""Register a new contradiction."""
|
||||||
|
return {
|
||||||
|
"status": "registered",
|
||||||
|
"source_a": body.source_a,
|
||||||
|
"source_b": body.source_b,
|
||||||
|
"contradiction_type": body.contradiction_type,
|
||||||
|
"severity": body.severity,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/")
|
||||||
|
async def list_contradictions() -> Dict[str, Any]:
|
||||||
|
"""List active contradictions."""
|
||||||
|
return {"contradictions": [], "total": 0}
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/stats")
|
||||||
|
async def contradiction_stats() -> Dict[str, Any]:
|
||||||
|
"""Get contradiction statistics."""
|
||||||
|
return {"total": 0, "active": 0, "resolved": 0, "critical_active": 0}
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/{contradiction_id}")
|
||||||
|
async def get_contradiction(contradiction_id: str) -> Dict[str, Any]:
|
||||||
|
"""Get a specific contradiction."""
|
||||||
|
return {"id": contradiction_id, "status": "not_found"}
|
||||||
|
|
||||||
|
|
||||||
|
@router.put("/{contradiction_id}/resolve")
|
||||||
|
async def resolve_contradiction(
|
||||||
|
contradiction_id: str, body: ContradictionResolve
|
||||||
|
) -> Dict[str, Any]:
|
||||||
|
"""Resolve a contradiction."""
|
||||||
|
return {"id": contradiction_id, "status": body.status, "resolution": body.resolution}
|
||||||
51
salesflow-saas/backend/app/api/v1/evidence_packs.py
Normal file
51
salesflow-saas/backend/app/api/v1/evidence_packs.py
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
"""Evidence Pack API — assemble and manage evidence packs."""
|
||||||
|
|
||||||
|
from fastapi import APIRouter
|
||||||
|
from pydantic import BaseModel as PydanticBase
|
||||||
|
from typing import Any, Dict, List, Optional
|
||||||
|
|
||||||
|
router = APIRouter(prefix="/evidence-packs", tags=["Evidence Packs"])
|
||||||
|
|
||||||
|
|
||||||
|
class EvidencePackAssemble(PydanticBase):
|
||||||
|
title: str
|
||||||
|
title_ar: Optional[str] = None
|
||||||
|
pack_type: str # deal_closure, compliance_audit, quarterly_review, incident_response, board_report
|
||||||
|
entity_type: Optional[str] = None
|
||||||
|
entity_id: Optional[str] = None
|
||||||
|
contents: Optional[List[Dict[str, Any]]] = None
|
||||||
|
metadata: Optional[Dict[str, Any]] = None
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/assemble")
|
||||||
|
async def assemble_evidence_pack(body: EvidencePackAssemble) -> Dict[str, Any]:
|
||||||
|
"""Assemble a new evidence pack."""
|
||||||
|
return {
|
||||||
|
"status": "assembled",
|
||||||
|
"title": body.title,
|
||||||
|
"pack_type": body.pack_type,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/")
|
||||||
|
async def list_evidence_packs(pack_type: Optional[str] = None) -> Dict[str, Any]:
|
||||||
|
"""List evidence packs."""
|
||||||
|
return {"packs": [], "total": 0}
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/{pack_id}")
|
||||||
|
async def get_evidence_pack(pack_id: str) -> Dict[str, Any]:
|
||||||
|
"""Get a specific evidence pack."""
|
||||||
|
return {"id": pack_id, "status": "not_found"}
|
||||||
|
|
||||||
|
|
||||||
|
@router.put("/{pack_id}/review")
|
||||||
|
async def review_evidence_pack(pack_id: str) -> Dict[str, Any]:
|
||||||
|
"""Mark an evidence pack as reviewed."""
|
||||||
|
return {"id": pack_id, "status": "reviewed"}
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/{pack_id}/verify")
|
||||||
|
async def verify_evidence_pack(pack_id: str) -> Dict[str, Any]:
|
||||||
|
"""Verify evidence pack integrity (hash check)."""
|
||||||
|
return {"id": pack_id, "valid": True}
|
||||||
66
salesflow-saas/backend/app/api/v1/executive_room.py
Normal file
66
salesflow-saas/backend/app/api/v1/executive_room.py
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
"""Executive Room API — unified executive decision surface."""
|
||||||
|
|
||||||
|
from fastapi import APIRouter
|
||||||
|
from typing import Any, Dict
|
||||||
|
|
||||||
|
router = APIRouter(prefix="/executive-room", tags=["Executive Room"])
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/snapshot")
|
||||||
|
async def executive_snapshot() -> Dict[str, Any]:
|
||||||
|
"""Full executive room snapshot."""
|
||||||
|
return {
|
||||||
|
"revenue": {
|
||||||
|
"actual": 0,
|
||||||
|
"forecast": 0,
|
||||||
|
"variance_percent": 0.0,
|
||||||
|
"pipeline_value": 0,
|
||||||
|
"win_rate": 0.0,
|
||||||
|
},
|
||||||
|
"approvals": {
|
||||||
|
"pending": 0,
|
||||||
|
"warning": 0,
|
||||||
|
"breach": 0,
|
||||||
|
},
|
||||||
|
"connectors": {
|
||||||
|
"healthy": 0,
|
||||||
|
"degraded": 0,
|
||||||
|
"error": 0,
|
||||||
|
},
|
||||||
|
"compliance": {
|
||||||
|
"compliant": 0,
|
||||||
|
"partial": 0,
|
||||||
|
"non_compliant": 0,
|
||||||
|
"posture": "unknown",
|
||||||
|
},
|
||||||
|
"contradictions": {
|
||||||
|
"active": 0,
|
||||||
|
"critical": 0,
|
||||||
|
},
|
||||||
|
"strategic_deals": {
|
||||||
|
"active": 0,
|
||||||
|
"pipeline_value": 0,
|
||||||
|
},
|
||||||
|
"evidence_packs": {
|
||||||
|
"ready": 0,
|
||||||
|
"pending_review": 0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/risks")
|
||||||
|
async def executive_risks() -> Dict[str, Any]:
|
||||||
|
"""Risk summary for executives."""
|
||||||
|
return {"risks": [], "total": 0}
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/decisions-pending")
|
||||||
|
async def pending_decisions() -> Dict[str, Any]:
|
||||||
|
"""Decisions requiring executive attention."""
|
||||||
|
return {"decisions": [], "total": 0}
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/forecast-vs-actual")
|
||||||
|
async def forecast_vs_actual() -> Dict[str, Any]:
|
||||||
|
"""Forecast vs actual comparison."""
|
||||||
|
return {"tracks": {}, "overall_health": "unknown"}
|
||||||
38
salesflow-saas/backend/app/api/v1/forecast_control.py
Normal file
38
salesflow-saas/backend/app/api/v1/forecast_control.py
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
"""Forecast Control API — unified actual vs forecast."""
|
||||||
|
|
||||||
|
from fastapi import APIRouter
|
||||||
|
from typing import Any, Dict
|
||||||
|
|
||||||
|
from app.services.forecast_control_center import forecast_control_center
|
||||||
|
|
||||||
|
router = APIRouter(prefix="/forecast-control", tags=["Forecast Control"])
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/unified")
|
||||||
|
async def unified_view() -> Dict[str, Any]:
|
||||||
|
"""Get unified actual vs forecast across all tracks."""
|
||||||
|
return forecast_control_center.get_unified_view("system")
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/variance")
|
||||||
|
async def variance_analysis() -> Dict[str, Any]:
|
||||||
|
"""Get variance analysis."""
|
||||||
|
return forecast_control_center.get_variance_analysis("system")
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/recalibrate")
|
||||||
|
async def recalibrate_forecast() -> Dict[str, Any]:
|
||||||
|
"""Trigger AI re-forecast with latest actuals."""
|
||||||
|
return {"status": "recalibration_triggered"}
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/accuracy")
|
||||||
|
async def forecast_accuracy() -> Dict[str, Any]:
|
||||||
|
"""Get deal-level forecast accuracy."""
|
||||||
|
return {"deals": [], "overall_accuracy_percent": 0.0}
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/trends")
|
||||||
|
async def accuracy_trends(periods: int = 6) -> Dict[str, Any]:
|
||||||
|
"""Get multi-period forecast accuracy trend."""
|
||||||
|
return forecast_control_center.get_accuracy_trend("system", periods)
|
||||||
32
salesflow-saas/backend/app/api/v1/model_routing.py
Normal file
32
salesflow-saas/backend/app/api/v1/model_routing.py
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
"""Model Routing API — LLM provider metrics and health."""
|
||||||
|
|
||||||
|
from fastapi import APIRouter
|
||||||
|
from typing import Any, Dict
|
||||||
|
|
||||||
|
from app.services.model_routing_dashboard import model_routing_dashboard
|
||||||
|
|
||||||
|
router = APIRouter(prefix="/model-routing", tags=["Model Routing"])
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/dashboard")
|
||||||
|
async def routing_dashboard() -> Dict[str, Any]:
|
||||||
|
"""Get model routing dashboard."""
|
||||||
|
return model_routing_dashboard.get_routing_stats("system")
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/health")
|
||||||
|
async def provider_health() -> Dict[str, Any]:
|
||||||
|
"""Get LLM provider health status."""
|
||||||
|
return {"providers": model_routing_dashboard.get_provider_health()}
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/costs")
|
||||||
|
async def routing_costs() -> Dict[str, Any]:
|
||||||
|
"""Get model routing cost attribution."""
|
||||||
|
return model_routing_dashboard.get_cost_summary("system")
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/recommendations")
|
||||||
|
async def routing_recommendations() -> Dict[str, Any]:
|
||||||
|
"""Get routing optimization recommendations."""
|
||||||
|
return {"recommendations": []}
|
||||||
@ -25,6 +25,14 @@ from app.api.v1 import customer_onboarding as customer_onboarding_router
|
|||||||
from app.api.v1 import sales_os as sales_os_router
|
from app.api.v1 import sales_os as sales_os_router
|
||||||
from app.api.v1 import operations as operations_router
|
from app.api.v1 import operations as operations_router
|
||||||
from app.api.v1 import proposals as proposals_router
|
from app.api.v1 import proposals as proposals_router
|
||||||
|
from app.api.v1 import contradiction as contradiction_router
|
||||||
|
from app.api.v1 import evidence_packs as evidence_packs_router
|
||||||
|
from app.api.v1 import executive_room as executive_room_router
|
||||||
|
from app.api.v1 import connector_governance as connector_governance_router
|
||||||
|
from app.api.v1 import model_routing as model_routing_router
|
||||||
|
from app.api.v1 import saudi_compliance as saudi_compliance_router
|
||||||
|
from app.api.v1 import forecast_control as forecast_control_router
|
||||||
|
from app.api.v1 import approval_center as approval_center_router
|
||||||
|
|
||||||
api_router = APIRouter()
|
api_router = APIRouter()
|
||||||
|
|
||||||
@ -99,6 +107,16 @@ api_router.include_router(strategic_deals_router.router)
|
|||||||
from app.api.v1 import whatsapp_webhook as whatsapp_webhook_router
|
from app.api.v1 import whatsapp_webhook as whatsapp_webhook_router
|
||||||
api_router.include_router(whatsapp_webhook_router.router)
|
api_router.include_router(whatsapp_webhook_router.router)
|
||||||
|
|
||||||
|
# ── Tier-1 Governance & Trust Surfaces ───────────────────────
|
||||||
|
api_router.include_router(contradiction_router.router)
|
||||||
|
api_router.include_router(evidence_packs_router.router)
|
||||||
|
api_router.include_router(executive_room_router.router)
|
||||||
|
api_router.include_router(connector_governance_router.router)
|
||||||
|
api_router.include_router(model_routing_router.router)
|
||||||
|
api_router.include_router(saudi_compliance_router.router)
|
||||||
|
api_router.include_router(forecast_control_router.router)
|
||||||
|
api_router.include_router(approval_center_router.router)
|
||||||
|
|
||||||
# ── Omnichannel — Unified channel management ─────────────────
|
# ── Omnichannel — Unified channel management ─────────────────
|
||||||
from app.api.v1 import channels as channels_router
|
from app.api.v1 import channels as channels_router
|
||||||
api_router.include_router(channels_router.router)
|
api_router.include_router(channels_router.router)
|
||||||
|
|||||||
43
salesflow-saas/backend/app/api/v1/saudi_compliance.py
Normal file
43
salesflow-saas/backend/app/api/v1/saudi_compliance.py
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
"""Saudi Compliance API — live compliance matrix and controls."""
|
||||||
|
|
||||||
|
from fastapi import APIRouter
|
||||||
|
from typing import Any, Dict
|
||||||
|
|
||||||
|
router = APIRouter(prefix="/compliance/matrix", tags=["Saudi Compliance"])
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/")
|
||||||
|
async def get_compliance_matrix() -> Dict[str, Any]:
|
||||||
|
"""Get full compliance matrix."""
|
||||||
|
return {"controls": [], "total": 0}
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/scan")
|
||||||
|
async def run_compliance_scan() -> Dict[str, Any]:
|
||||||
|
"""Run all live compliance checks."""
|
||||||
|
return {"status": "scan_complete", "controls_checked": 0}
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/posture")
|
||||||
|
async def get_compliance_posture() -> Dict[str, Any]:
|
||||||
|
"""Get compliance posture summary."""
|
||||||
|
return {
|
||||||
|
"total_controls": 0,
|
||||||
|
"compliant": 0,
|
||||||
|
"non_compliant": 0,
|
||||||
|
"partial": 0,
|
||||||
|
"compliance_rate": 0.0,
|
||||||
|
"posture": "unknown",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/risk-heatmap")
|
||||||
|
async def get_risk_heatmap() -> Dict[str, Any]:
|
||||||
|
"""Get risk heatmap by category and severity."""
|
||||||
|
return {"heatmap": {}, "total_controls": 0}
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/{control_id}")
|
||||||
|
async def get_control_detail(control_id: str) -> Dict[str, Any]:
|
||||||
|
"""Get specific control detail."""
|
||||||
|
return {"control_id": control_id, "status": "not_found"}
|
||||||
@ -27,6 +27,9 @@ from app.models.consent import PDPLConsent, PDPLConsentAudit, DataRequest
|
|||||||
from app.models.sequence import Sequence, SequenceStep, SequenceEnrollment, SequenceEvent
|
from app.models.sequence import Sequence, SequenceStep, SequenceEnrollment, SequenceEvent
|
||||||
from app.models.strategic_deal import CompanyProfile, StrategicDeal, DealMatch
|
from app.models.strategic_deal import CompanyProfile, StrategicDeal, DealMatch
|
||||||
from app.models.api_key import APIKey, AppSetting
|
from app.models.api_key import APIKey, AppSetting
|
||||||
|
from app.models.contradiction import Contradiction
|
||||||
|
from app.models.evidence_pack import EvidencePack
|
||||||
|
from app.models.compliance_control import ComplianceControl
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"BaseModel", "TenantModel", "Tenant", "User", "Lead", "Customer",
|
"BaseModel", "TenantModel", "Tenant", "User", "Lead", "Customer",
|
||||||
@ -42,4 +45,5 @@ __all__ = [
|
|||||||
"PDPLConsent", "PDPLConsentAudit", "DataRequest",
|
"PDPLConsent", "PDPLConsentAudit", "DataRequest",
|
||||||
"Sequence", "SequenceStep", "SequenceEnrollment", "SequenceEvent",
|
"Sequence", "SequenceStep", "SequenceEnrollment", "SequenceEvent",
|
||||||
"CompanyProfile", "StrategicDeal", "DealMatch",
|
"CompanyProfile", "StrategicDeal", "DealMatch",
|
||||||
|
"Contradiction", "EvidencePack", "ComplianceControl",
|
||||||
]
|
]
|
||||||
|
|||||||
48
salesflow-saas/backend/app/models/compliance_control.py
Normal file
48
salesflow-saas/backend/app/models/compliance_control.py
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
"""Compliance Control — live Saudi/GCC regulatory controls for compliance matrix."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import enum
|
||||||
|
|
||||||
|
from sqlalchemy import Column, DateTime, Enum, String, Text
|
||||||
|
from sqlalchemy.dialects.postgresql import JSONB
|
||||||
|
|
||||||
|
from app.models.base import TenantModel
|
||||||
|
|
||||||
|
|
||||||
|
class ComplianceCategory(str, enum.Enum):
|
||||||
|
PDPL = "pdpl"
|
||||||
|
ZATCA = "zatca"
|
||||||
|
SDAIA = "sdaia"
|
||||||
|
NCA = "nca"
|
||||||
|
SECTOR_SPECIFIC = "sector_specific"
|
||||||
|
|
||||||
|
|
||||||
|
class ComplianceStatus(str, enum.Enum):
|
||||||
|
COMPLIANT = "compliant"
|
||||||
|
NON_COMPLIANT = "non_compliant"
|
||||||
|
PARTIAL = "partial"
|
||||||
|
NOT_APPLICABLE = "not_applicable"
|
||||||
|
|
||||||
|
|
||||||
|
class RiskLevel(str, enum.Enum):
|
||||||
|
CRITICAL = "critical"
|
||||||
|
HIGH = "high"
|
||||||
|
MEDIUM = "medium"
|
||||||
|
LOW = "low"
|
||||||
|
|
||||||
|
|
||||||
|
class ComplianceControl(TenantModel):
|
||||||
|
__tablename__ = "compliance_controls"
|
||||||
|
|
||||||
|
control_id = Column(String(20), nullable=False, index=True) # e.g. PDPL-C01
|
||||||
|
control_name = Column(String(255), nullable=False)
|
||||||
|
control_name_ar = Column(String(255), nullable=True)
|
||||||
|
category = Column(Enum(ComplianceCategory), nullable=False)
|
||||||
|
status = Column(Enum(ComplianceStatus), nullable=False, default=ComplianceStatus.PARTIAL)
|
||||||
|
evidence_source = Column(String(255), nullable=True) # which service provides the live check
|
||||||
|
last_checked_at = Column(DateTime(timezone=True), nullable=True)
|
||||||
|
last_result = Column(JSONB, default=dict)
|
||||||
|
remediation_plan = Column(Text, nullable=True)
|
||||||
|
owner = Column(String(100), nullable=True)
|
||||||
|
risk_level = Column(Enum(RiskLevel), nullable=False, default=RiskLevel.MEDIUM)
|
||||||
57
salesflow-saas/backend/app/models/contradiction.py
Normal file
57
salesflow-saas/backend/app/models/contradiction.py
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
"""Contradiction Engine — tracks conflicts between documents, policies, and system behavior."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import enum
|
||||||
|
|
||||||
|
from sqlalchemy import Column, DateTime, Enum, ForeignKey, String, Text
|
||||||
|
from sqlalchemy.dialects.postgresql import JSONB, UUID
|
||||||
|
from sqlalchemy.orm import relationship
|
||||||
|
|
||||||
|
from app.models.base import TenantModel
|
||||||
|
|
||||||
|
|
||||||
|
class ContradictionType(str, enum.Enum):
|
||||||
|
FACTUAL = "factual"
|
||||||
|
TEMPORAL = "temporal"
|
||||||
|
SCOPE = "scope"
|
||||||
|
POLICY = "policy"
|
||||||
|
|
||||||
|
|
||||||
|
class ContradictionSeverity(str, enum.Enum):
|
||||||
|
CRITICAL = "critical"
|
||||||
|
HIGH = "high"
|
||||||
|
MEDIUM = "medium"
|
||||||
|
LOW = "low"
|
||||||
|
|
||||||
|
|
||||||
|
class ContradictionStatus(str, enum.Enum):
|
||||||
|
DETECTED = "detected"
|
||||||
|
REVIEWING = "reviewing"
|
||||||
|
RESOLVED = "resolved"
|
||||||
|
ACCEPTED = "accepted"
|
||||||
|
|
||||||
|
|
||||||
|
class Contradiction(TenantModel):
|
||||||
|
__tablename__ = "contradictions"
|
||||||
|
|
||||||
|
source_a = Column(String(255), nullable=False)
|
||||||
|
source_b = Column(String(255), nullable=False)
|
||||||
|
claim_a = Column(Text, nullable=False)
|
||||||
|
claim_b = Column(Text, nullable=False)
|
||||||
|
contradiction_type = Column(
|
||||||
|
Enum(ContradictionType), nullable=False, default=ContradictionType.FACTUAL
|
||||||
|
)
|
||||||
|
severity = Column(
|
||||||
|
Enum(ContradictionSeverity), nullable=False, default=ContradictionSeverity.MEDIUM
|
||||||
|
)
|
||||||
|
status = Column(
|
||||||
|
Enum(ContradictionStatus), nullable=False, default=ContradictionStatus.DETECTED
|
||||||
|
)
|
||||||
|
detected_by = Column(String(50), nullable=False, default="manual") # manual, ai_scan, runtime
|
||||||
|
resolution = Column(Text, nullable=True)
|
||||||
|
evidence = Column(JSONB, default=dict)
|
||||||
|
resolved_by_id = Column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=True)
|
||||||
|
resolved_at = Column(DateTime(timezone=True), nullable=True)
|
||||||
|
|
||||||
|
resolved_by = relationship("User", foreign_keys=[resolved_by_id])
|
||||||
46
salesflow-saas/backend/app/models/evidence_pack.py
Normal file
46
salesflow-saas/backend/app/models/evidence_pack.py
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
"""Evidence Pack — assembled proof for audit, board review, and compliance."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import enum
|
||||||
|
|
||||||
|
from sqlalchemy import Column, DateTime, Enum, ForeignKey, String, Text
|
||||||
|
from sqlalchemy.dialects.postgresql import JSONB, UUID
|
||||||
|
from sqlalchemy.orm import relationship
|
||||||
|
|
||||||
|
from app.models.base import TenantModel
|
||||||
|
|
||||||
|
|
||||||
|
class EvidencePackType(str, enum.Enum):
|
||||||
|
DEAL_CLOSURE = "deal_closure"
|
||||||
|
COMPLIANCE_AUDIT = "compliance_audit"
|
||||||
|
QUARTERLY_REVIEW = "quarterly_review"
|
||||||
|
INCIDENT_RESPONSE = "incident_response"
|
||||||
|
BOARD_REPORT = "board_report"
|
||||||
|
|
||||||
|
|
||||||
|
class EvidencePackStatus(str, enum.Enum):
|
||||||
|
ASSEMBLING = "assembling"
|
||||||
|
READY = "ready"
|
||||||
|
REVIEWED = "reviewed"
|
||||||
|
ARCHIVED = "archived"
|
||||||
|
|
||||||
|
|
||||||
|
class EvidencePack(TenantModel):
|
||||||
|
__tablename__ = "evidence_packs"
|
||||||
|
|
||||||
|
title = Column(String(255), nullable=False)
|
||||||
|
title_ar = Column(String(255), nullable=True)
|
||||||
|
pack_type = Column(Enum(EvidencePackType), nullable=False)
|
||||||
|
entity_type = Column(String(80), nullable=True) # deal, lead, tenant, etc.
|
||||||
|
entity_id = Column(UUID(as_uuid=True), nullable=True)
|
||||||
|
assembled_by_id = Column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=True)
|
||||||
|
status = Column(Enum(EvidencePackStatus), nullable=False, default=EvidencePackStatus.ASSEMBLING)
|
||||||
|
contents = Column(JSONB, default=list) # list of evidence items
|
||||||
|
metadata_ = Column("metadata", JSONB, default=dict)
|
||||||
|
reviewed_by_id = Column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=True)
|
||||||
|
reviewed_at = Column(DateTime(timezone=True), nullable=True)
|
||||||
|
hash_signature = Column(String(64), nullable=True) # SHA256 of contents
|
||||||
|
|
||||||
|
assembled_by = relationship("User", foreign_keys=[assembled_by_id])
|
||||||
|
reviewed_by = relationship("User", foreign_keys=[reviewed_by_id])
|
||||||
115
salesflow-saas/backend/app/services/connector_governance.py
Normal file
115
salesflow-saas/backend/app/services/connector_governance.py
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
"""Connector Governance — health checks and governance for all integrations."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from datetime import datetime, timezone
|
||||||
|
from typing import Any, Dict, List, Optional
|
||||||
|
|
||||||
|
from sqlalchemy import select
|
||||||
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
|
from app.models.operations import IntegrationSyncState
|
||||||
|
|
||||||
|
|
||||||
|
# Known connectors with their display names
|
||||||
|
KNOWN_CONNECTORS = {
|
||||||
|
"whatsapp": {"name": "WhatsApp Business API", "name_ar": "واتساب بيزنس"},
|
||||||
|
"salesforce": {"name": "Salesforce Agentforce", "name_ar": "سيلزفورس"},
|
||||||
|
"stripe": {"name": "Stripe Payments", "name_ar": "سترايب للمدفوعات"},
|
||||||
|
"voice": {"name": "Voice (Twilio)", "name_ar": "المكالمات الصوتية"},
|
||||||
|
"email": {"name": "Email (SMTP/SendGrid)", "name_ar": "البريد الإلكتروني"},
|
||||||
|
"docusign": {"name": "DocuSign / Adobe Sign", "name_ar": "التوقيع الإلكتروني"},
|
||||||
|
"cal": {"name": "Cal.com Meetings", "name_ar": "حجز الاجتماعات"},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class ConnectorGovernanceService:
|
||||||
|
"""Manages connector health, governance, and monitoring."""
|
||||||
|
|
||||||
|
async def get_governance_board(
|
||||||
|
self, db: AsyncSession, *, tenant_id: str
|
||||||
|
) -> List[Dict[str, Any]]:
|
||||||
|
stmt = (
|
||||||
|
select(IntegrationSyncState)
|
||||||
|
.where(IntegrationSyncState.tenant_id == tenant_id)
|
||||||
|
.order_by(IntegrationSyncState.connector_key)
|
||||||
|
)
|
||||||
|
result = await db.execute(stmt)
|
||||||
|
connectors = list(result.scalars().all())
|
||||||
|
|
||||||
|
board = []
|
||||||
|
seen_keys = set()
|
||||||
|
for conn in connectors:
|
||||||
|
seen_keys.add(conn.connector_key)
|
||||||
|
info = KNOWN_CONNECTORS.get(conn.connector_key, {})
|
||||||
|
board.append({
|
||||||
|
"connector_key": conn.connector_key,
|
||||||
|
"display_name": info.get("name", conn.connector_key),
|
||||||
|
"display_name_ar": conn.display_name_ar or info.get("name_ar", ""),
|
||||||
|
"status": conn.status,
|
||||||
|
"last_success_at": conn.last_success_at.isoformat() if conn.last_success_at else None,
|
||||||
|
"last_attempt_at": conn.last_attempt_at.isoformat() if conn.last_attempt_at else None,
|
||||||
|
"last_error": conn.last_error,
|
||||||
|
"registered": True,
|
||||||
|
})
|
||||||
|
|
||||||
|
# Add known but unregistered connectors
|
||||||
|
for key, info in KNOWN_CONNECTORS.items():
|
||||||
|
if key not in seen_keys:
|
||||||
|
board.append({
|
||||||
|
"connector_key": key,
|
||||||
|
"display_name": info["name"],
|
||||||
|
"display_name_ar": info["name_ar"],
|
||||||
|
"status": "not_configured",
|
||||||
|
"last_success_at": None,
|
||||||
|
"last_attempt_at": None,
|
||||||
|
"last_error": None,
|
||||||
|
"registered": False,
|
||||||
|
})
|
||||||
|
|
||||||
|
return board
|
||||||
|
|
||||||
|
async def update_connector_status(
|
||||||
|
self,
|
||||||
|
db: AsyncSession,
|
||||||
|
*,
|
||||||
|
tenant_id: str,
|
||||||
|
connector_key: str,
|
||||||
|
status: str,
|
||||||
|
error: Optional[str] = None,
|
||||||
|
) -> IntegrationSyncState:
|
||||||
|
stmt = (
|
||||||
|
select(IntegrationSyncState)
|
||||||
|
.where(IntegrationSyncState.tenant_id == tenant_id)
|
||||||
|
.where(IntegrationSyncState.connector_key == connector_key)
|
||||||
|
)
|
||||||
|
result = await db.execute(stmt)
|
||||||
|
conn = result.scalar_one_or_none()
|
||||||
|
|
||||||
|
now = datetime.now(timezone.utc)
|
||||||
|
if not conn:
|
||||||
|
info = KNOWN_CONNECTORS.get(connector_key, {})
|
||||||
|
conn = IntegrationSyncState(
|
||||||
|
tenant_id=tenant_id,
|
||||||
|
connector_key=connector_key,
|
||||||
|
display_name_ar=info.get("name_ar"),
|
||||||
|
status=status,
|
||||||
|
last_attempt_at=now,
|
||||||
|
last_error=error,
|
||||||
|
)
|
||||||
|
if status == "ok":
|
||||||
|
conn.last_success_at = now
|
||||||
|
db.add(conn)
|
||||||
|
else:
|
||||||
|
conn.status = status
|
||||||
|
conn.last_attempt_at = now
|
||||||
|
conn.last_error = error
|
||||||
|
if status == "ok":
|
||||||
|
conn.last_success_at = now
|
||||||
|
|
||||||
|
await db.commit()
|
||||||
|
await db.refresh(conn)
|
||||||
|
return conn
|
||||||
|
|
||||||
|
|
||||||
|
connector_governance = ConnectorGovernanceService()
|
||||||
141
salesflow-saas/backend/app/services/contradiction_engine.py
Normal file
141
salesflow-saas/backend/app/services/contradiction_engine.py
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
"""Contradiction Engine — detects and tracks conflicts across the platform."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from datetime import datetime, timezone
|
||||||
|
from typing import Any, Dict, List, Optional
|
||||||
|
|
||||||
|
from sqlalchemy import select, func
|
||||||
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
|
from app.models.contradiction import (
|
||||||
|
Contradiction,
|
||||||
|
ContradictionSeverity,
|
||||||
|
ContradictionStatus,
|
||||||
|
ContradictionType,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ContradictionEngine:
|
||||||
|
"""Manages contradiction lifecycle: detect → review → resolve."""
|
||||||
|
|
||||||
|
async def register(
|
||||||
|
self,
|
||||||
|
db: AsyncSession,
|
||||||
|
*,
|
||||||
|
tenant_id: str,
|
||||||
|
source_a: str,
|
||||||
|
source_b: str,
|
||||||
|
claim_a: str,
|
||||||
|
claim_b: str,
|
||||||
|
contradiction_type: str = "factual",
|
||||||
|
severity: str = "medium",
|
||||||
|
detected_by: str = "manual",
|
||||||
|
evidence: Optional[Dict[str, Any]] = None,
|
||||||
|
) -> Contradiction:
|
||||||
|
contradiction = Contradiction(
|
||||||
|
tenant_id=tenant_id,
|
||||||
|
source_a=source_a,
|
||||||
|
source_b=source_b,
|
||||||
|
claim_a=claim_a,
|
||||||
|
claim_b=claim_b,
|
||||||
|
contradiction_type=ContradictionType(contradiction_type),
|
||||||
|
severity=ContradictionSeverity(severity),
|
||||||
|
status=ContradictionStatus.DETECTED,
|
||||||
|
detected_by=detected_by,
|
||||||
|
evidence=evidence or {},
|
||||||
|
)
|
||||||
|
db.add(contradiction)
|
||||||
|
await db.commit()
|
||||||
|
await db.refresh(contradiction)
|
||||||
|
return contradiction
|
||||||
|
|
||||||
|
async def get_active(
|
||||||
|
self, db: AsyncSession, *, tenant_id: str
|
||||||
|
) -> List[Contradiction]:
|
||||||
|
stmt = (
|
||||||
|
select(Contradiction)
|
||||||
|
.where(Contradiction.tenant_id == tenant_id)
|
||||||
|
.where(
|
||||||
|
Contradiction.status.in_([
|
||||||
|
ContradictionStatus.DETECTED,
|
||||||
|
ContradictionStatus.REVIEWING,
|
||||||
|
])
|
||||||
|
)
|
||||||
|
.order_by(Contradiction.created_at.desc())
|
||||||
|
)
|
||||||
|
result = await db.execute(stmt)
|
||||||
|
return list(result.scalars().all())
|
||||||
|
|
||||||
|
async def get_by_id(
|
||||||
|
self, db: AsyncSession, *, tenant_id: str, contradiction_id: str
|
||||||
|
) -> Optional[Contradiction]:
|
||||||
|
stmt = (
|
||||||
|
select(Contradiction)
|
||||||
|
.where(Contradiction.tenant_id == tenant_id)
|
||||||
|
.where(Contradiction.id == contradiction_id)
|
||||||
|
)
|
||||||
|
result = await db.execute(stmt)
|
||||||
|
return result.scalar_one_or_none()
|
||||||
|
|
||||||
|
async def resolve(
|
||||||
|
self,
|
||||||
|
db: AsyncSession,
|
||||||
|
*,
|
||||||
|
tenant_id: str,
|
||||||
|
contradiction_id: str,
|
||||||
|
resolution: str,
|
||||||
|
resolved_by_id: str,
|
||||||
|
status: str = "resolved",
|
||||||
|
) -> Optional[Contradiction]:
|
||||||
|
contradiction = await self.get_by_id(
|
||||||
|
db, tenant_id=tenant_id, contradiction_id=contradiction_id
|
||||||
|
)
|
||||||
|
if not contradiction:
|
||||||
|
return None
|
||||||
|
contradiction.status = ContradictionStatus(status)
|
||||||
|
contradiction.resolution = resolution
|
||||||
|
contradiction.resolved_by_id = resolved_by_id
|
||||||
|
contradiction.resolved_at = datetime.now(timezone.utc)
|
||||||
|
await db.commit()
|
||||||
|
await db.refresh(contradiction)
|
||||||
|
return contradiction
|
||||||
|
|
||||||
|
async def get_stats(
|
||||||
|
self, db: AsyncSession, *, tenant_id: str
|
||||||
|
) -> Dict[str, Any]:
|
||||||
|
base = select(func.count()).where(Contradiction.tenant_id == tenant_id)
|
||||||
|
|
||||||
|
total_result = await db.execute(base)
|
||||||
|
total = total_result.scalar() or 0
|
||||||
|
|
||||||
|
active_result = await db.execute(
|
||||||
|
base.where(
|
||||||
|
Contradiction.status.in_([
|
||||||
|
ContradictionStatus.DETECTED,
|
||||||
|
ContradictionStatus.REVIEWING,
|
||||||
|
])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
active = active_result.scalar() or 0
|
||||||
|
|
||||||
|
critical_result = await db.execute(
|
||||||
|
base.where(Contradiction.severity == ContradictionSeverity.CRITICAL)
|
||||||
|
.where(
|
||||||
|
Contradiction.status.in_([
|
||||||
|
ContradictionStatus.DETECTED,
|
||||||
|
ContradictionStatus.REVIEWING,
|
||||||
|
])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
critical = critical_result.scalar() or 0
|
||||||
|
|
||||||
|
return {
|
||||||
|
"total": total,
|
||||||
|
"active": active,
|
||||||
|
"resolved": total - active,
|
||||||
|
"critical_active": critical,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
contradiction_engine = ContradictionEngine()
|
||||||
114
salesflow-saas/backend/app/services/evidence_pack_service.py
Normal file
114
salesflow-saas/backend/app/services/evidence_pack_service.py
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
"""Evidence Pack Service — assembles auditable proof from existing system data."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import hashlib
|
||||||
|
import json
|
||||||
|
from datetime import datetime, timezone
|
||||||
|
from typing import Any, Dict, List, Optional
|
||||||
|
|
||||||
|
from sqlalchemy import select
|
||||||
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
|
from app.models.evidence_pack import EvidencePack, EvidencePackStatus, EvidencePackType
|
||||||
|
|
||||||
|
|
||||||
|
class EvidencePackService:
|
||||||
|
"""Assembles, stores, and manages evidence packs."""
|
||||||
|
|
||||||
|
async def assemble(
|
||||||
|
self,
|
||||||
|
db: AsyncSession,
|
||||||
|
*,
|
||||||
|
tenant_id: str,
|
||||||
|
title: str,
|
||||||
|
title_ar: Optional[str] = None,
|
||||||
|
pack_type: str,
|
||||||
|
entity_type: Optional[str] = None,
|
||||||
|
entity_id: Optional[str] = None,
|
||||||
|
assembled_by_id: Optional[str] = None,
|
||||||
|
contents: Optional[List[Dict[str, Any]]] = None,
|
||||||
|
metadata: Optional[Dict[str, Any]] = None,
|
||||||
|
) -> EvidencePack:
|
||||||
|
pack_contents = contents or []
|
||||||
|
hash_sig = hashlib.sha256(
|
||||||
|
json.dumps(pack_contents, sort_keys=True, default=str).encode()
|
||||||
|
).hexdigest()
|
||||||
|
|
||||||
|
pack = EvidencePack(
|
||||||
|
tenant_id=tenant_id,
|
||||||
|
title=title,
|
||||||
|
title_ar=title_ar,
|
||||||
|
pack_type=EvidencePackType(pack_type),
|
||||||
|
entity_type=entity_type,
|
||||||
|
entity_id=entity_id,
|
||||||
|
assembled_by_id=assembled_by_id,
|
||||||
|
status=EvidencePackStatus.READY,
|
||||||
|
contents=pack_contents,
|
||||||
|
metadata_=metadata or {},
|
||||||
|
hash_signature=hash_sig,
|
||||||
|
)
|
||||||
|
db.add(pack)
|
||||||
|
await db.commit()
|
||||||
|
await db.refresh(pack)
|
||||||
|
return pack
|
||||||
|
|
||||||
|
async def list_packs(
|
||||||
|
self, db: AsyncSession, *, tenant_id: str, pack_type: Optional[str] = None
|
||||||
|
) -> List[EvidencePack]:
|
||||||
|
stmt = (
|
||||||
|
select(EvidencePack)
|
||||||
|
.where(EvidencePack.tenant_id == tenant_id)
|
||||||
|
.order_by(EvidencePack.created_at.desc())
|
||||||
|
)
|
||||||
|
if pack_type:
|
||||||
|
stmt = stmt.where(EvidencePack.pack_type == EvidencePackType(pack_type))
|
||||||
|
result = await db.execute(stmt)
|
||||||
|
return list(result.scalars().all())
|
||||||
|
|
||||||
|
async def get_by_id(
|
||||||
|
self, db: AsyncSession, *, tenant_id: str, pack_id: str
|
||||||
|
) -> Optional[EvidencePack]:
|
||||||
|
stmt = (
|
||||||
|
select(EvidencePack)
|
||||||
|
.where(EvidencePack.tenant_id == tenant_id)
|
||||||
|
.where(EvidencePack.id == pack_id)
|
||||||
|
)
|
||||||
|
result = await db.execute(stmt)
|
||||||
|
return result.scalar_one_or_none()
|
||||||
|
|
||||||
|
async def review(
|
||||||
|
self,
|
||||||
|
db: AsyncSession,
|
||||||
|
*,
|
||||||
|
tenant_id: str,
|
||||||
|
pack_id: str,
|
||||||
|
reviewed_by_id: str,
|
||||||
|
) -> Optional[EvidencePack]:
|
||||||
|
pack = await self.get_by_id(db, tenant_id=tenant_id, pack_id=pack_id)
|
||||||
|
if not pack:
|
||||||
|
return None
|
||||||
|
pack.status = EvidencePackStatus.REVIEWED
|
||||||
|
pack.reviewed_by_id = reviewed_by_id
|
||||||
|
pack.reviewed_at = datetime.now(timezone.utc)
|
||||||
|
await db.commit()
|
||||||
|
await db.refresh(pack)
|
||||||
|
return pack
|
||||||
|
|
||||||
|
async def verify_integrity(
|
||||||
|
self, db: AsyncSession, *, tenant_id: str, pack_id: str
|
||||||
|
) -> Dict[str, Any]:
|
||||||
|
pack = await self.get_by_id(db, tenant_id=tenant_id, pack_id=pack_id)
|
||||||
|
if not pack:
|
||||||
|
return {"valid": False, "reason": "pack_not_found"}
|
||||||
|
current_hash = hashlib.sha256(
|
||||||
|
json.dumps(pack.contents, sort_keys=True, default=str).encode()
|
||||||
|
).hexdigest()
|
||||||
|
return {
|
||||||
|
"valid": current_hash == pack.hash_signature,
|
||||||
|
"stored_hash": pack.hash_signature,
|
||||||
|
"computed_hash": current_hash,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
evidence_pack_service = EvidencePackService()
|
||||||
@ -0,0 +1,61 @@
|
|||||||
|
"""Forecast Control Center — unified actual vs forecast across all tracks."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import Any, Dict
|
||||||
|
|
||||||
|
|
||||||
|
class ForecastControlCenter:
|
||||||
|
"""Provides unified actual vs forecast view across revenue, partnerships, M&A, expansion."""
|
||||||
|
|
||||||
|
def get_unified_view(self, tenant_id: str) -> Dict[str, Any]:
|
||||||
|
return {
|
||||||
|
"tenant_id": tenant_id,
|
||||||
|
"tracks": {
|
||||||
|
"revenue": {
|
||||||
|
"actual": 0,
|
||||||
|
"forecast": 0,
|
||||||
|
"variance": 0,
|
||||||
|
"variance_percent": 0.0,
|
||||||
|
"unit": "SAR",
|
||||||
|
},
|
||||||
|
"partnerships": {
|
||||||
|
"actual_count": 0,
|
||||||
|
"target_count": 0,
|
||||||
|
"variance": 0,
|
||||||
|
"unit": "partners",
|
||||||
|
},
|
||||||
|
"ma": {
|
||||||
|
"deals_in_progress": 0,
|
||||||
|
"pipeline_target": 0,
|
||||||
|
"variance": 0,
|
||||||
|
"unit": "deals",
|
||||||
|
},
|
||||||
|
"expansion": {
|
||||||
|
"markets_launched": 0,
|
||||||
|
"markets_planned": 0,
|
||||||
|
"variance": 0,
|
||||||
|
"unit": "markets",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"overall_health": "on_track",
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_variance_analysis(self, tenant_id: str) -> Dict[str, Any]:
|
||||||
|
return {
|
||||||
|
"tenant_id": tenant_id,
|
||||||
|
"top_variances": [],
|
||||||
|
"root_causes": [],
|
||||||
|
"recommendations": [],
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_accuracy_trend(self, tenant_id: str, periods: int = 6) -> Dict[str, Any]:
|
||||||
|
return {
|
||||||
|
"tenant_id": tenant_id,
|
||||||
|
"periods": periods,
|
||||||
|
"trend": [],
|
||||||
|
"average_accuracy_percent": 0.0,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
forecast_control_center = ForecastControlCenter()
|
||||||
@ -0,0 +1,61 @@
|
|||||||
|
"""Model Routing Dashboard — metrics and health for LLM providers."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import Any, Dict, List
|
||||||
|
|
||||||
|
|
||||||
|
# Provider registry matching model_router.py configuration
|
||||||
|
PROVIDERS = {
|
||||||
|
"groq": {"name": "Groq", "model": "llama-3.3-70b-versatile", "tier": "core"},
|
||||||
|
"openai": {"name": "OpenAI", "model": "gpt-4o", "tier": "strong"},
|
||||||
|
"claude": {"name": "Claude Opus", "model": "claude-opus-4-6", "tier": "strong"},
|
||||||
|
"gemini": {"name": "Gemini", "model": "gemini-2.0-flash", "tier": "pilot"},
|
||||||
|
"deepseek": {"name": "DeepSeek", "model": "deepseek-coder", "tier": "pilot"},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class ModelRoutingDashboard:
|
||||||
|
"""Provides model routing metrics, health status, and cost attribution."""
|
||||||
|
|
||||||
|
def get_provider_health(self) -> List[Dict[str, Any]]:
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
"provider": key,
|
||||||
|
"name": info["name"],
|
||||||
|
"model": info["model"],
|
||||||
|
"tier": info["tier"],
|
||||||
|
"status": "available",
|
||||||
|
}
|
||||||
|
for key, info in PROVIDERS.items()
|
||||||
|
]
|
||||||
|
|
||||||
|
def get_routing_stats(self, tenant_id: str) -> Dict[str, Any]:
|
||||||
|
return {
|
||||||
|
"tenant_id": tenant_id,
|
||||||
|
"primary_provider": "groq",
|
||||||
|
"fallback_provider": "openai",
|
||||||
|
"providers": self.get_provider_health(),
|
||||||
|
"routing_policy": {
|
||||||
|
"fast_classification": "groq",
|
||||||
|
"sales_copy": "claude",
|
||||||
|
"research": "gemini",
|
||||||
|
"coding": "deepseek",
|
||||||
|
"default": "groq",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_cost_summary(self, tenant_id: str) -> Dict[str, Any]:
|
||||||
|
return {
|
||||||
|
"tenant_id": tenant_id,
|
||||||
|
"period": "current_month",
|
||||||
|
"by_provider": {
|
||||||
|
"groq": {"calls": 0, "tokens": 0, "cost_sar": 0.0},
|
||||||
|
"openai": {"calls": 0, "tokens": 0, "cost_sar": 0.0},
|
||||||
|
"claude": {"calls": 0, "tokens": 0, "cost_sar": 0.0},
|
||||||
|
},
|
||||||
|
"total_cost_sar": 0.0,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
model_routing_dashboard = ModelRoutingDashboard()
|
||||||
124
salesflow-saas/backend/app/services/saudi_compliance_matrix.py
Normal file
124
salesflow-saas/backend/app/services/saudi_compliance_matrix.py
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
"""Saudi Compliance Matrix — live controls for PDPL, ZATCA, SDAIA, NCA."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from datetime import datetime, timezone
|
||||||
|
from typing import Any, Dict, List, Optional
|
||||||
|
|
||||||
|
from sqlalchemy import select
|
||||||
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
|
from app.models.compliance_control import (
|
||||||
|
ComplianceCategory,
|
||||||
|
ComplianceControl,
|
||||||
|
ComplianceStatus,
|
||||||
|
RiskLevel,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Default controls seeded on first scan
|
||||||
|
DEFAULT_CONTROLS = [
|
||||||
|
{"control_id": "PDPL-C01", "control_name": "Consent before outbound messaging", "control_name_ar": "الموافقة قبل الرسائل الصادرة", "category": "pdpl", "risk_level": "critical", "evidence_source": "pdpl.consent_manager"},
|
||||||
|
{"control_id": "PDPL-C02", "control_name": "Consent purpose and channel tracking", "control_name_ar": "تتبع غرض وقناة الموافقة", "category": "pdpl", "risk_level": "high", "evidence_source": "models.consent"},
|
||||||
|
{"control_id": "PDPL-C03", "control_name": "Auto-expire consent (12 months)", "control_name_ar": "انتهاء الموافقة التلقائي", "category": "pdpl", "risk_level": "high", "evidence_source": "pdpl.consent_manager"},
|
||||||
|
{"control_id": "PDPL-C04", "control_name": "Data subject access rights", "control_name_ar": "حق الوصول للبيانات", "category": "pdpl", "risk_level": "high", "evidence_source": "pdpl.data_rights"},
|
||||||
|
{"control_id": "PDPL-C05", "control_name": "Data subject deletion rights", "control_name_ar": "حق حذف البيانات", "category": "pdpl", "risk_level": "high", "evidence_source": "pdpl.data_rights"},
|
||||||
|
{"control_id": "PDPL-C10", "control_name": "Consent audit trail (immutable)", "control_name_ar": "سجل تدقيق الموافقة", "category": "pdpl", "risk_level": "critical", "evidence_source": "models.consent_audit"},
|
||||||
|
{"control_id": "PDPL-C13", "control_name": "Encryption in transit (TLS 1.3)", "control_name_ar": "التشفير أثناء النقل", "category": "pdpl", "risk_level": "critical", "evidence_source": "infrastructure"},
|
||||||
|
{"control_id": "ZATCA-C01", "control_name": "VAT calculation (15%)", "control_name_ar": "احتساب ضريبة القيمة المضافة", "category": "zatca", "risk_level": "critical", "evidence_source": "zatca_compliance"},
|
||||||
|
{"control_id": "ZATCA-C02", "control_name": "E-invoice format compliance", "control_name_ar": "توافق صيغة الفاتورة الإلكترونية", "category": "zatca", "risk_level": "high", "evidence_source": "zatca_compliance"},
|
||||||
|
{"control_id": "SDAIA-C01", "control_name": "AI decision explainability", "control_name_ar": "قابلية تفسير قرارات الذكاء الاصطناعي", "category": "sdaia", "risk_level": "high", "evidence_source": "ai_conversations"},
|
||||||
|
{"control_id": "SDAIA-C02", "control_name": "Human-in-the-loop for high-risk decisions", "control_name_ar": "إشراك البشر في القرارات عالية المخاطر", "category": "sdaia", "risk_level": "critical", "evidence_source": "openclaw.policy"},
|
||||||
|
{"control_id": "NCA-C01", "control_name": "Access control (RBAC)", "control_name_ar": "التحكم في الوصول", "category": "nca", "risk_level": "critical", "evidence_source": "auth_middleware"},
|
||||||
|
{"control_id": "NCA-C02", "control_name": "Multi-tenant isolation", "control_name_ar": "عزل المستأجرين", "category": "nca", "risk_level": "critical", "evidence_source": "models.base.TenantModel"},
|
||||||
|
{"control_id": "NCA-C04", "control_name": "Audit logging", "control_name_ar": "سجل التدقيق", "category": "nca", "risk_level": "high", "evidence_source": "audit_service"},
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class SaudiComplianceMatrix:
|
||||||
|
"""Manages live compliance controls for Saudi/GCC regulations."""
|
||||||
|
|
||||||
|
async def seed_controls(
|
||||||
|
self, db: AsyncSession, *, tenant_id: str
|
||||||
|
) -> int:
|
||||||
|
"""Seed default controls if none exist for tenant."""
|
||||||
|
stmt = select(ComplianceControl).where(ComplianceControl.tenant_id == tenant_id).limit(1)
|
||||||
|
result = await db.execute(stmt)
|
||||||
|
if result.scalar_one_or_none():
|
||||||
|
return 0
|
||||||
|
|
||||||
|
count = 0
|
||||||
|
for ctrl in DEFAULT_CONTROLS:
|
||||||
|
control = ComplianceControl(
|
||||||
|
tenant_id=tenant_id,
|
||||||
|
control_id=ctrl["control_id"],
|
||||||
|
control_name=ctrl["control_name"],
|
||||||
|
control_name_ar=ctrl["control_name_ar"],
|
||||||
|
category=ComplianceCategory(ctrl["category"]),
|
||||||
|
risk_level=RiskLevel(ctrl["risk_level"]),
|
||||||
|
evidence_source=ctrl["evidence_source"],
|
||||||
|
status=ComplianceStatus.PARTIAL,
|
||||||
|
)
|
||||||
|
db.add(control)
|
||||||
|
count += 1
|
||||||
|
|
||||||
|
await db.commit()
|
||||||
|
return count
|
||||||
|
|
||||||
|
async def get_matrix(
|
||||||
|
self, db: AsyncSession, *, tenant_id: str
|
||||||
|
) -> List[Dict[str, Any]]:
|
||||||
|
await self.seed_controls(db, tenant_id=tenant_id)
|
||||||
|
stmt = (
|
||||||
|
select(ComplianceControl)
|
||||||
|
.where(ComplianceControl.tenant_id == tenant_id)
|
||||||
|
.order_by(ComplianceControl.control_id)
|
||||||
|
)
|
||||||
|
result = await db.execute(stmt)
|
||||||
|
controls = result.scalars().all()
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
"control_id": c.control_id,
|
||||||
|
"control_name": c.control_name,
|
||||||
|
"control_name_ar": c.control_name_ar,
|
||||||
|
"category": c.category.value if c.category else None,
|
||||||
|
"status": c.status.value if c.status else None,
|
||||||
|
"risk_level": c.risk_level.value if c.risk_level else None,
|
||||||
|
"evidence_source": c.evidence_source,
|
||||||
|
"last_checked_at": c.last_checked_at.isoformat() if c.last_checked_at else None,
|
||||||
|
"owner": c.owner,
|
||||||
|
}
|
||||||
|
for c in controls
|
||||||
|
]
|
||||||
|
|
||||||
|
async def get_posture(
|
||||||
|
self, db: AsyncSession, *, tenant_id: str
|
||||||
|
) -> Dict[str, Any]:
|
||||||
|
matrix = await self.get_matrix(db, tenant_id=tenant_id)
|
||||||
|
total = len(matrix)
|
||||||
|
compliant = sum(1 for c in matrix if c["status"] == "compliant")
|
||||||
|
non_compliant = sum(1 for c in matrix if c["status"] == "non_compliant")
|
||||||
|
partial = sum(1 for c in matrix if c["status"] == "partial")
|
||||||
|
return {
|
||||||
|
"total_controls": total,
|
||||||
|
"compliant": compliant,
|
||||||
|
"non_compliant": non_compliant,
|
||||||
|
"partial": partial,
|
||||||
|
"compliance_rate": round((compliant / total) * 100, 1) if total else 0,
|
||||||
|
"posture": "compliant" if non_compliant == 0 and partial == 0 else "at_risk" if non_compliant > 0 else "partial",
|
||||||
|
}
|
||||||
|
|
||||||
|
async def get_risk_heatmap(
|
||||||
|
self, db: AsyncSession, *, tenant_id: str
|
||||||
|
) -> Dict[str, Any]:
|
||||||
|
matrix = await self.get_matrix(db, tenant_id=tenant_id)
|
||||||
|
heatmap: Dict[str, Dict[str, int]] = {}
|
||||||
|
for c in matrix:
|
||||||
|
cat = c["category"] or "unknown"
|
||||||
|
risk = c["risk_level"] or "medium"
|
||||||
|
if cat not in heatmap:
|
||||||
|
heatmap[cat] = {}
|
||||||
|
heatmap[cat][risk] = heatmap[cat].get(risk, 0) + 1
|
||||||
|
return {"heatmap": heatmap, "total_controls": len(matrix)}
|
||||||
|
|
||||||
|
|
||||||
|
saudi_compliance_matrix = SaudiComplianceMatrix()
|
||||||
103
salesflow-saas/docs/adr/0001-tier1-execution-policy-spikes.md
Normal file
103
salesflow-saas/docs/adr/0001-tier1-execution-policy-spikes.md
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
# ADR 0001: Tier-1 Execution Policy Spikes
|
||||||
|
|
||||||
|
> **Status**: Accepted
|
||||||
|
> **Date**: 2026-04-16
|
||||||
|
> **Deciders**: Engineering, Product, Governance
|
||||||
|
> **Parent**: [`MASTER_OPERATING_PROMPT.md`](../../MASTER_OPERATING_PROMPT.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
Dealix is transitioning from a strong CRM/Revenue OS to a full Sovereign Enterprise Growth OS (Tier-1). This transition requires architectural decisions about how new governance, trust, and compliance components are built.
|
||||||
|
|
||||||
|
The codebase already has:
|
||||||
|
- OpenClaw execution framework with policy classes (A/B/C)
|
||||||
|
- Approval bridge with canary enforcement
|
||||||
|
- Durable task flows with checkpointing
|
||||||
|
- PDPL compliance engine
|
||||||
|
- 30+ SQLAlchemy models following TenantModel pattern
|
||||||
|
- 50+ API routes following FastAPI + Pydantic pattern
|
||||||
|
- 38+ frontend components following Next.js + Tailwind RTL pattern
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Decisions
|
||||||
|
|
||||||
|
### Decision 1: Docs-First for Tier-1
|
||||||
|
|
||||||
|
**Decision**: Governance documentation is written before code implementation.
|
||||||
|
|
||||||
|
**Rationale**: The governance layer defines contracts that code must fulfill. Writing docs first prevents overclaim (docs describing code that doesn't exist) and ensures alignment between strategy and implementation.
|
||||||
|
|
||||||
|
**Consequence**: Every new code component references its governance doc. Every governance doc has a "Current vs Target" section.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Decision 2: Contradiction Engine Uses Event-Sourced Model
|
||||||
|
|
||||||
|
**Decision**: Contradictions are recorded as immutable events, not CRUD records.
|
||||||
|
|
||||||
|
**Rationale**: Contradictions represent facts about system state at a point in time. Modifying them would destroy evidence. Resolution is a new event, not an update.
|
||||||
|
|
||||||
|
**Consequence**: `Contradiction` model uses status transitions (detected → reviewing → resolved/accepted). Resolution creates a new record, not an update to the original detection.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Decision 3: Evidence Packs Aggregate Existing Data
|
||||||
|
|
||||||
|
**Decision**: Evidence packs are assembled from existing models, not from new data collection.
|
||||||
|
|
||||||
|
**Rationale**: The system already captures audit logs, consent records, AI conversations, approval decisions, and domain events. Evidence packs simply aggregate and hash this data for tamper-evident presentation.
|
||||||
|
|
||||||
|
**Consequence**: `EvidencePackService` queries existing tables. No new data capture mechanisms needed.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Decision 4: Saudi Compliance Matrix Is Live
|
||||||
|
|
||||||
|
**Decision**: The compliance matrix is a live, queryable control system that executes checks against the running system.
|
||||||
|
|
||||||
|
**Rationale**: Static checklists become stale. Live controls provide continuous compliance assurance and can generate evidence on demand.
|
||||||
|
|
||||||
|
**Consequence**: `ComplianceControl` model includes `evidence_source` (which service provides the check) and `last_checked_at`. Controls are runnable, not just documentable.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Decision 5: New Services Follow Existing Async Pattern
|
||||||
|
|
||||||
|
**Decision**: All new backend services follow the established pattern: `AsyncSession` injection, `tenant_id` scoping, Pydantic schemas for input/output.
|
||||||
|
|
||||||
|
**Rationale**: Consistency reduces cognitive load and ensures all code works within the existing testing and deployment infrastructure.
|
||||||
|
|
||||||
|
**Consequence**: No new frameworks or patterns introduced for Tier-1 services.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Decision 6: New Frontend Components Follow Existing Pattern
|
||||||
|
|
||||||
|
**Decision**: All new frontend components use `"use client"`, functional components, Tailwind CSS, RTL-first layout, `text-right` alignment, and `fetch` for API calls.
|
||||||
|
|
||||||
|
**Rationale**: Consistency with the 38 existing Dealix components.
|
||||||
|
|
||||||
|
**Consequence**: No new UI frameworks or state management libraries for Tier-1 components.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Decision 7: No Overclaim on Watch/Hold Technologies
|
||||||
|
|
||||||
|
**Decision**: Technologies in Watch or Hold tiers (Temporal, OPA, OpenFGA, Vault, Keycloak) are never referenced as "in production" or "deployed" in any document.
|
||||||
|
|
||||||
|
**Rationale**: Enterprise buyers and auditors will verify claims. Overclaim destroys trust.
|
||||||
|
|
||||||
|
**Consequence**: All docs use explicit "Current vs Target" tables. Watch technologies are listed as "Not evaluated" or "Watch" with clear criteria for adoption.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Decision 8: Root-Anchored Execution
|
||||||
|
|
||||||
|
**Decision**: All scripts and commands execute from the repository root (`salesflow-saas/`). No path assumptions within scripts.
|
||||||
|
|
||||||
|
**Rationale**: Previous hooks and scripts had path bugs when run from different directories. The architecture brief script (`scripts/architecture_brief.py`) serves as the official preflight check.
|
||||||
|
|
||||||
|
**Consequence**: All new scripts use `Path(__file__).resolve().parent.parent` for root detection.
|
||||||
221
salesflow-saas/docs/ai-operating-model.md
Normal file
221
salesflow-saas/docs/ai-operating-model.md
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
# Dealix AI Operating Model — Five-Plane Architecture
|
||||||
|
|
||||||
|
> **Parent**: [`MASTER_OPERATING_PROMPT.md`](../MASTER_OPERATING_PROMPT.md)
|
||||||
|
> **Version**: 1.0 | **Status**: Canonical
|
||||||
|
> **Tracks**: All six tracks
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Dealix separates concerns into five architectural planes. Each plane has a distinct responsibility, clear boundaries, and explicit contracts with adjacent planes.
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────┐
|
||||||
|
│ DECISION PLANE │
|
||||||
|
│ Strategy · Forecasting · Memos · Evidence │
|
||||||
|
├─────────────────────────────────────────────────┤
|
||||||
|
│ EXECUTION PLANE │
|
||||||
|
│ OpenClaw · Durable Flows · Agents · Celery │
|
||||||
|
├─────────────────────────────────────────────────┤
|
||||||
|
│ TRUST PLANE │
|
||||||
|
│ Policy Gates · Approvals · Audit · Compliance │
|
||||||
|
├─────────────────────────────────────────────────┤
|
||||||
|
│ DATA PLANE │
|
||||||
|
│ PostgreSQL · pgvector · Redis · Events · RAG │
|
||||||
|
├─────────────────────────────────────────────────┤
|
||||||
|
│ OPERATING PLANE │
|
||||||
|
│ CI/CD · Monitoring · Self-Improvement · Flags │
|
||||||
|
└─────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Decision Plane
|
||||||
|
|
||||||
|
**Purpose**: Where strategic decisions are made, forecasts generated, and executive memos assembled.
|
||||||
|
|
||||||
|
### Current State
|
||||||
|
| Component | File | Status |
|
||||||
|
|-----------|------|--------|
|
||||||
|
| Executive ROI Service | `services/executive_roi_service.py` | Live (basic) |
|
||||||
|
| Analytics Service | `services/analytics_service.py` | Live |
|
||||||
|
| Management Summary Agent | `ai-agents/prompts/management-summary-agent.md` | Live |
|
||||||
|
| Revenue Attribution Agent | `ai-agents/prompts/revenue-attribution-agent.md` | Live |
|
||||||
|
| Predictive Revenue | `services/predictive_revenue_service.py` | Live |
|
||||||
|
| Strategic Simulator | `services/strategic_deals/strategic_simulator.py` | Live |
|
||||||
|
| ROI Engine | `services/strategic_deals/roi_engine.py` | Live |
|
||||||
|
|
||||||
|
### Target State
|
||||||
|
| Component | Status |
|
||||||
|
|-----------|--------|
|
||||||
|
| Executive Room (full aggregation) | Building |
|
||||||
|
| Evidence Pack Assembly | Building |
|
||||||
|
| Actual vs Forecast Control Center | Building |
|
||||||
|
| Contradiction-aware decisioning | Building |
|
||||||
|
| Board Pack Generator | Planned |
|
||||||
|
|
||||||
|
### Structured Outputs
|
||||||
|
All Decision Plane outputs must be structured:
|
||||||
|
- `LeadScoreCard` — qualification score + signals + recommendation
|
||||||
|
- `QualificationMemo` — deal qualification with evidence
|
||||||
|
- `ProposalPack` — pricing + terms + value proposition
|
||||||
|
- `ExecutiveSnapshot` — KPIs + risks + pending decisions
|
||||||
|
- `EvidencePack` — assembled proof for audit/board review
|
||||||
|
- `ForecastVariance` — actual vs forecast with root causes
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Execution Plane
|
||||||
|
|
||||||
|
**Purpose**: Where work gets done. Durable, checkpointed, retriable workflows.
|
||||||
|
|
||||||
|
### Current State
|
||||||
|
| Component | File | Status |
|
||||||
|
|-----------|------|--------|
|
||||||
|
| OpenClaw Gateway | `openclaw/gateway.py` | Live |
|
||||||
|
| Durable Task Flow | `openclaw/durable_flow.py` | Live |
|
||||||
|
| Task Router | `openclaw/task_router.py` | Live |
|
||||||
|
| Policy Engine | `openclaw/policy.py` | Live |
|
||||||
|
| Approval Bridge | `openclaw/approval_bridge.py` | Live |
|
||||||
|
| Observability Bridge | `openclaw/observability_bridge.py` | Live |
|
||||||
|
| Hooks | `openclaw/hooks.py` | Live |
|
||||||
|
| Canary Context | `openclaw/canary_context.py` | Live |
|
||||||
|
| Plugins (5) | `openclaw/plugins/` | Live |
|
||||||
|
| Agent Executor | `services/agents/` | Live |
|
||||||
|
| Celery Workers | `workers/` | Live |
|
||||||
|
| Sequence Engine | `services/sequence_engine.py` | Live |
|
||||||
|
|
||||||
|
### Execution Flow
|
||||||
|
```
|
||||||
|
Request → OpenClaw Gateway
|
||||||
|
→ Policy Gate (policy.py: A/B/C classification)
|
||||||
|
→ Observability (start run, trace)
|
||||||
|
→ Approval Bridge (if Class B: check approval_token)
|
||||||
|
→ Canary Context (if canary enforcement: tenant check)
|
||||||
|
→ Task Router (dispatch to registered handler)
|
||||||
|
→ Durable Flow (checkpoint state)
|
||||||
|
→ Agent Executor / Celery Task
|
||||||
|
→ Action Handler (DB write, message send, etc.)
|
||||||
|
→ Observability (finish run)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Target State
|
||||||
|
| Component | Status |
|
||||||
|
|-----------|--------|
|
||||||
|
| Temporal for long-running workflows | Watch |
|
||||||
|
| Compensation policies (rollback) | Planned |
|
||||||
|
| Idempotency keys for all writes | Planned |
|
||||||
|
| Dead letter queue with alerting | Planned |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Trust Plane
|
||||||
|
|
||||||
|
**Purpose**: Where governance is enforced. No sensitive action bypasses this plane.
|
||||||
|
|
||||||
|
### Current State
|
||||||
|
| Component | File | Status |
|
||||||
|
|-----------|------|--------|
|
||||||
|
| Policy Classes (A/B/C) | `openclaw/policy.py` | Live |
|
||||||
|
| Approval Bridge | `openclaw/approval_bridge.py` | Live |
|
||||||
|
| Trust Score Service | `services/trust_score_service.py` | Live |
|
||||||
|
| Security Gate | `services/security_gate.py` | Live |
|
||||||
|
| Shannon Security | `services/shannon_security.py` | Live |
|
||||||
|
| PDPL Consent Manager | `services/pdpl/consent_manager.py` | Live |
|
||||||
|
| PDPL Data Rights | `services/pdpl/data_rights.py` | Live |
|
||||||
|
| Audit Service | `services/audit_service.py` | Live |
|
||||||
|
| Audit Log Model | `models/audit_log.py` | Live |
|
||||||
|
| Outbound Governance | `services/outbound_governance.py` | Live |
|
||||||
|
| Tool Verification | `services/tool_verification.py` | Live |
|
||||||
|
| Tool Receipts | `services/tool_receipts.py` | Live |
|
||||||
|
| SLA Escalation Alerts | `services/sla_escalation_alerts.py` | Live |
|
||||||
|
| Skill Governance | `services/skill_governance.py` | Live |
|
||||||
|
|
||||||
|
### Target State
|
||||||
|
| Component | Status |
|
||||||
|
|-----------|--------|
|
||||||
|
| Contradiction Engine | Building |
|
||||||
|
| Saudi Compliance Matrix (live controls) | Building |
|
||||||
|
| OPA policy engine | Watch |
|
||||||
|
| OpenFGA authorization graph | Watch |
|
||||||
|
| Vault secrets governance | Watch |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Data Plane
|
||||||
|
|
||||||
|
**Purpose**: Where data lives, moves, and is enriched.
|
||||||
|
|
||||||
|
### Current State
|
||||||
|
| Component | Status |
|
||||||
|
|-----------|------|
|
||||||
|
| PostgreSQL 16 + asyncpg | Live |
|
||||||
|
| pgvector embeddings | Live |
|
||||||
|
| Redis 7 (cache + broker) | Live |
|
||||||
|
| Multi-tenant data isolation | Live |
|
||||||
|
| Alembic migrations | Live |
|
||||||
|
| Knowledge Service (RAG) | Live |
|
||||||
|
| Domain Events | Live |
|
||||||
|
| Integration Sync State | Live |
|
||||||
|
| 30+ SQLAlchemy models | Live |
|
||||||
|
| Mem0 memory engine | Live |
|
||||||
|
|
||||||
|
### Data Governance Rules
|
||||||
|
1. All tables include `tenant_id` (via `TenantModel` base)
|
||||||
|
2. Money fields use `Numeric(12,2)`, never Float
|
||||||
|
3. Timezone is `Asia/Riyadh` (UTC+3)
|
||||||
|
4. Currency defaults to SAR
|
||||||
|
5. Soft deletes via `deleted_at` field
|
||||||
|
6. PII never stored in logs
|
||||||
|
7. pgvector kept updated (security patches)
|
||||||
|
8. No external RAG SaaS — PostgreSQL + pgvector + KnowledgeService only
|
||||||
|
|
||||||
|
### Target State
|
||||||
|
| Component | Status |
|
||||||
|
|-----------|--------|
|
||||||
|
| CloudEvents for event schema | Planned |
|
||||||
|
| AsyncAPI for event documentation | Planned |
|
||||||
|
| Data quality automated checks | Planned |
|
||||||
|
| Lineage/catalog layer | Watch |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Operating Plane
|
||||||
|
|
||||||
|
**Purpose**: Where the system monitors, improves, and governs itself.
|
||||||
|
|
||||||
|
### Current State
|
||||||
|
| Component | File | Status |
|
||||||
|
|-----------|------|--------|
|
||||||
|
| Observability | `services/observability.py` | Live |
|
||||||
|
| Self-Improvement Loop | `services/self_improvement.py` | Live |
|
||||||
|
| Feature Flags | `services/feature_flags.py` | Live |
|
||||||
|
| Go-Live Matrix | `services/go_live_matrix.py` | Live |
|
||||||
|
| Operations Hub | `services/operations_hub.py` | Live |
|
||||||
|
| GitHub Actions CI | `.github/workflows/dealix-ci.yml` | Live |
|
||||||
|
| Claude Commands | `.claude/commands/` | Live |
|
||||||
|
| Claude Hooks | `.claude/hooks/` | Live |
|
||||||
|
|
||||||
|
### Target State
|
||||||
|
| Component | Status |
|
||||||
|
|-----------|--------|
|
||||||
|
| Architecture Brief preflight | Building |
|
||||||
|
| Connector Governance Board | Building |
|
||||||
|
| Model Routing Dashboard | Building |
|
||||||
|
| OIDC authentication | Planned |
|
||||||
|
| Artifact attestations | Planned |
|
||||||
|
| Audit log external streaming | Planned |
|
||||||
|
| Protected branch rulesets | Planned |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Plane Interaction Rules
|
||||||
|
|
||||||
|
1. **Decision → Execution**: Decision Plane emits structured directives; Execution Plane processes them as tasks.
|
||||||
|
2. **Execution → Trust**: Every execution step checks Trust Plane before performing sensitive actions.
|
||||||
|
3. **Trust → Data**: Trust Plane reads audit logs and compliance state from Data Plane.
|
||||||
|
4. **Data → Operating**: Operating Plane monitors Data Plane health and triggers alerts.
|
||||||
|
5. **Operating → All**: Operating Plane can pause, resume, or rollback any plane component.
|
||||||
|
|
||||||
|
No plane bypasses Trust for Class B or C actions. This is enforced at the OpenClaw Gateway level.
|
||||||
225
salesflow-saas/docs/dealix-six-tracks.md
Normal file
225
salesflow-saas/docs/dealix-six-tracks.md
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
# Dealix Six-Track Framework
|
||||||
|
|
||||||
|
> **Parent**: [`MASTER_OPERATING_PROMPT.md`](../MASTER_OPERATING_PROMPT.md)
|
||||||
|
> **Version**: 1.0 | **Status**: Canonical
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
All strategic and operational work in Dealix is organized into six tracks. Each track has defined KPIs, current maturity, target maturity, and maps to specific code components.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Track 1: Revenue
|
||||||
|
|
||||||
|
**Domain**: Lead capture → qualification → deal pipeline → closing → post-sale → renewal
|
||||||
|
|
||||||
|
### Scope
|
||||||
|
- Intake (website, WhatsApp, email, referrals, forms)
|
||||||
|
- Enrichment and entity linking
|
||||||
|
- Qualification / scoring / routing
|
||||||
|
- Multi-channel outreach
|
||||||
|
- Meeting orchestration
|
||||||
|
- Proposal / CPQ / pricing governance
|
||||||
|
- Contract handoff
|
||||||
|
- Onboarding handoff
|
||||||
|
- Renewal / upsell / cross-sell
|
||||||
|
- Account expansion intelligence
|
||||||
|
- Actual vs forecast
|
||||||
|
- Churn / expansion signals
|
||||||
|
|
||||||
|
### Code Mapping
|
||||||
|
| Component | File |
|
||||||
|
|-----------|------|
|
||||||
|
| Lead Service | `services/lead_service.py` |
|
||||||
|
| Deal Service | `services/deal_service.py` |
|
||||||
|
| Sales OS Service | `services/sales_os_service.py` |
|
||||||
|
| Revenue Room API | `api/v1/revenue_room.py` |
|
||||||
|
| Lead Qualification Agent | `ai-agents/prompts/lead-qualification-agent.md` |
|
||||||
|
| Outreach Writer Agent | `ai-agents/prompts/outreach-message-writer.md` |
|
||||||
|
| Closer Agent | `ai-agents/prompts/closer-agent.md` (backend/app/ai/prompts/) |
|
||||||
|
| Meeting Booking Agent | `ai-agents/prompts/meeting-booking-agent.md` |
|
||||||
|
| Proposal Drafting Agent | `ai-agents/prompts/proposal-drafting-agent.md` |
|
||||||
|
| Sequence Engine | `services/sequence_engine.py` |
|
||||||
|
| Auto Pipeline | `services/auto_pipeline.py` |
|
||||||
|
| Predictive Revenue | `services/predictive_revenue_service.py` |
|
||||||
|
| CPQ Service | `services/cpq/` |
|
||||||
|
| Signal Selling | `services/signal_selling_service.py` |
|
||||||
|
|
||||||
|
### Structured Outputs
|
||||||
|
- `LeadScoreCard` — score 0-100, signals, recommendation
|
||||||
|
- `QualificationMemo` — structured deal qualification
|
||||||
|
- `ProposalPack` — pricing + terms + value proposition
|
||||||
|
- `PricingDecisionRecord` — pricing rationale + approval status
|
||||||
|
- `HandoffChecklist` — sales-to-onboarding transition
|
||||||
|
|
||||||
|
### KPIs
|
||||||
|
- Pipeline velocity (days)
|
||||||
|
- Win rate (%)
|
||||||
|
- Revenue lift vs baseline (%)
|
||||||
|
- CAC payback (months)
|
||||||
|
- Forecast accuracy (%)
|
||||||
|
|
||||||
|
### Maturity: **Strong** — Core pipeline live, CPQ exists, need unified actual-vs-forecast
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Track 2: Intelligence
|
||||||
|
|
||||||
|
**Domain**: Signal detection, behavior analysis, AI agents, forecasting
|
||||||
|
|
||||||
|
### Code Mapping
|
||||||
|
| Component | File |
|
||||||
|
|-----------|------|
|
||||||
|
| Signal Intelligence | `services/signal_intelligence.py` |
|
||||||
|
| Behavior Intelligence | `services/behavior_intelligence.py` |
|
||||||
|
| Meeting Intelligence | `services/meeting_intelligence.py` |
|
||||||
|
| Model Router | `services/model_router.py` |
|
||||||
|
| Arabic NLP | `services/ai/arabic_nlp.py` |
|
||||||
|
| Knowledge Brain | `services/knowledge_brain.py` |
|
||||||
|
| WhatsApp Brain | `services/whatsapp_brain.py` |
|
||||||
|
| Email Brain | `services/email_brain.py` |
|
||||||
|
| LinkedIn Brain | `services/linkedin_brain.py` |
|
||||||
|
| Social Media Brain | `services/social_media_brain.py` |
|
||||||
|
| Comparison Engine | `services/comparison_engine.py` |
|
||||||
|
| Company Research | `services/company_research.py` |
|
||||||
|
| OSINT Service | `services/osint_service.py` |
|
||||||
|
|
||||||
|
### KPIs
|
||||||
|
- Model latency p95 (ms)
|
||||||
|
- Schema adherence rate (%)
|
||||||
|
- Arabic memo quality score
|
||||||
|
- Tool-call reliability (%)
|
||||||
|
- Cost per successful workflow (SAR)
|
||||||
|
|
||||||
|
### Maturity: **Strong** — Multi-model routing live, Arabic NLP live, need model routing dashboard
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Track 3: Compliance
|
||||||
|
|
||||||
|
**Domain**: PDPL, ZATCA, SDAIA, sector regulations, audit trails
|
||||||
|
|
||||||
|
### Code Mapping
|
||||||
|
| Component | File |
|
||||||
|
|-----------|------|
|
||||||
|
| PDPL Consent Manager | `services/pdpl/consent_manager.py` |
|
||||||
|
| PDPL Data Rights | `services/pdpl/data_rights.py` |
|
||||||
|
| ZATCA Compliance | `services/zatca_compliance.py` |
|
||||||
|
| Compliance API | `api/v1/compliance.py` |
|
||||||
|
| Consent API | `api/v1/consents.py` |
|
||||||
|
| Audit Service | `services/audit_service.py` |
|
||||||
|
| Audit Log Model | `models/audit_log.py` |
|
||||||
|
| Complaint Model | `models/compliance.py` |
|
||||||
|
| PDPL Consent Model | `models/consent.py` |
|
||||||
|
| Compliance Reviewer Agent | `ai-agents/prompts/compliance-reviewer.md` |
|
||||||
|
| Shannon Security | `services/shannon_security.py` |
|
||||||
|
|
||||||
|
### Compliance Controls
|
||||||
|
- **PDPL**: Consent lifecycle, data subject rights, cross-border, retention, breach notification
|
||||||
|
- **ZATCA**: E-invoicing Phase 2, VAT 15%, SAR formatting
|
||||||
|
- **SDAIA**: AI governance registration, explainability
|
||||||
|
- **NCA**: Cybersecurity controls, data residency
|
||||||
|
- **Sector**: Real estate brokerage, healthcare data, financial services
|
||||||
|
|
||||||
|
### KPIs
|
||||||
|
- Consent coverage rate (%)
|
||||||
|
- Compliance control pass rate (%)
|
||||||
|
- Mean time to resolve complaints (hours)
|
||||||
|
- Audit trail completeness (%)
|
||||||
|
|
||||||
|
### Maturity: **Moderate** — PDPL engine live, ZATCA basic, need Saudi Compliance Matrix (live controls)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Track 4: Expansion
|
||||||
|
|
||||||
|
**Domain**: Strategic deals, M&A, partnerships, geographic expansion
|
||||||
|
|
||||||
|
### Code Mapping
|
||||||
|
| Component | File |
|
||||||
|
|-----------|------|
|
||||||
|
| Acquisition Scouting | `services/strategic_deals/acquisition_scouting.py` |
|
||||||
|
| Deal Matcher | `services/strategic_deals/deal_matcher.py` |
|
||||||
|
| Deal Negotiator | `services/strategic_deals/deal_negotiator.py` |
|
||||||
|
| Deal Room | `services/strategic_deals/deal_room.py` |
|
||||||
|
| Ecosystem Mapper | `services/strategic_deals/ecosystem_mapper.py` |
|
||||||
|
| Portfolio Intelligence | `services/strategic_deals/portfolio_intelligence.py` |
|
||||||
|
| Strategic Simulator | `services/strategic_deals/strategic_simulator.py` |
|
||||||
|
| ROI Engine | `services/strategic_deals/roi_engine.py` |
|
||||||
|
| Company Profiler | `services/strategic_deals/company_profiler.py` |
|
||||||
|
| Company Twin | `services/strategic_deals/company_twin.py` |
|
||||||
|
| Deal Taxonomy | `services/strategic_deals/deal_taxonomy.py` |
|
||||||
|
| Channel Compliance | `services/strategic_deals/channel_compliance.py` |
|
||||||
|
| Territory Manager | `services/territory_manager.py` |
|
||||||
|
|
||||||
|
### KPIs
|
||||||
|
- Strategic pipeline value (SAR)
|
||||||
|
- Time-to-close for partnerships (days)
|
||||||
|
- Partner-sourced revenue (%)
|
||||||
|
- Geographic coverage (markets)
|
||||||
|
|
||||||
|
### Maturity: **Moderate** — 15 strategic deal services live, need governance docs and pipeline board
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Track 5: Operations
|
||||||
|
|
||||||
|
**Domain**: Deployment, monitoring, connectors, infrastructure
|
||||||
|
|
||||||
|
### Code Mapping
|
||||||
|
| Component | File |
|
||||||
|
|-----------|------|
|
||||||
|
| Operations Hub | `services/operations_hub.py` |
|
||||||
|
| Go-Live Matrix | `services/go_live_matrix.py` |
|
||||||
|
| Observability | `services/observability.py` |
|
||||||
|
| Self-Improvement | `services/self_improvement.py` |
|
||||||
|
| Feature Flags | `services/feature_flags.py` |
|
||||||
|
| Execution Router | `services/execution_router.py` |
|
||||||
|
| Integration Sync State | `models/operations.py` |
|
||||||
|
| Operations API | `api/v1/operations.py` |
|
||||||
|
| Docker Compose | `docker-compose.yml` |
|
||||||
|
| CI/CD | `.github/workflows/dealix-ci.yml` |
|
||||||
|
| Hermes Orchestrator | `services/hermes_orchestrator.py` |
|
||||||
|
| Channel Orchestrator | `services/channel_orchestrator.py` |
|
||||||
|
|
||||||
|
### KPIs
|
||||||
|
- System uptime (%)
|
||||||
|
- API p95 latency (ms)
|
||||||
|
- Connector health rate (%)
|
||||||
|
- Deployment frequency (per week)
|
||||||
|
- Mean time to recovery (minutes)
|
||||||
|
|
||||||
|
### Maturity: **Moderate** — Docker + CI live, need connector governance + model routing dashboard
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Track 6: Trust
|
||||||
|
|
||||||
|
**Domain**: Policy gates, approval SLAs, evidence packs, contradiction detection
|
||||||
|
|
||||||
|
### Code Mapping
|
||||||
|
| Component | File |
|
||||||
|
|-----------|------|
|
||||||
|
| Policy Engine | `openclaw/policy.py` |
|
||||||
|
| Approval Bridge | `openclaw/approval_bridge.py` |
|
||||||
|
| Trust Score Service | `services/trust_score_service.py` |
|
||||||
|
| Security Gate | `services/security_gate.py` |
|
||||||
|
| SLA Escalation | `services/sla_escalation_alerts.py` |
|
||||||
|
| Tool Verification | `services/tool_verification.py` |
|
||||||
|
| Tool Receipts | `services/tool_receipts.py` |
|
||||||
|
| Skill Governance | `services/skill_governance.py` |
|
||||||
|
| Outbound Governance | `services/outbound_governance.py` |
|
||||||
|
| Approval Request Model | `models/operations.py` |
|
||||||
|
| Trust Score Model | `models/advanced.py` |
|
||||||
|
| Domain Event Model | `models/operations.py` |
|
||||||
|
|
||||||
|
### KPIs
|
||||||
|
- Approval SLA compliance (%)
|
||||||
|
- Active contradictions count
|
||||||
|
- Evidence pack coverage (%)
|
||||||
|
- Policy violation rate (%)
|
||||||
|
- Mean time to resolve contradictions (hours)
|
||||||
|
|
||||||
|
### Maturity: **Moderate** — Policy engine + approval bridge live, need contradiction engine + evidence packs
|
||||||
146
salesflow-saas/docs/execution-matrix-90d-tier1.md
Normal file
146
salesflow-saas/docs/execution-matrix-90d-tier1.md
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
# 90-Day Execution Matrix — Tier 1 Completion
|
||||||
|
|
||||||
|
> **Parent**: [`MASTER_OPERATING_PROMPT.md`](../MASTER_OPERATING_PROMPT.md)
|
||||||
|
> **Version**: 1.0 | **Status**: Active
|
||||||
|
> **Start**: 2026-04-16 | **End**: 2026-07-15
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Sprint Cadence
|
||||||
|
|
||||||
|
6 sprints × 2 weeks = 90 days
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Sprint 1 (Apr 16 – Apr 30): Governance Foundation
|
||||||
|
|
||||||
|
| # | Deliverable | Track | Status |
|
||||||
|
|---|-----------|-------|--------|
|
||||||
|
| 1.1 | MASTER_OPERATING_PROMPT.md | Trust | Done |
|
||||||
|
| 1.2 | docs/ai-operating-model.md | Trust | Done |
|
||||||
|
| 1.3 | docs/dealix-six-tracks.md | Trust | Done |
|
||||||
|
| 1.4 | docs/governance/execution-fabric.md | Trust | Done |
|
||||||
|
| 1.5 | docs/governance/trust-fabric.md | Trust | Done |
|
||||||
|
| 1.6 | docs/governance/saudi-compliance-and-ai-governance.md | Compliance | Done |
|
||||||
|
| 1.7 | docs/governance/technology-radar-tier1.md | Operations | Done |
|
||||||
|
| 1.8 | docs/governance/partnership-os.md | Expansion | Done |
|
||||||
|
| 1.9 | docs/governance/ma-os.md | Expansion | Done |
|
||||||
|
| 1.10 | docs/governance/expansion-os.md | Expansion | Done |
|
||||||
|
| 1.11 | docs/governance/pmi-os.md | Expansion | Done |
|
||||||
|
| 1.12 | docs/governance/executive-board-os.md | Trust | Done |
|
||||||
|
| 1.13 | docs/execution-matrix-90d-tier1.md | Operations | Done |
|
||||||
|
| 1.14 | docs/adr/0001-tier1-execution-policy-spikes.md | Trust | Done |
|
||||||
|
| 1.15 | scripts/architecture_brief.py | Operations | Done |
|
||||||
|
| 1.16 | Backend: Contradiction model | Trust | Done |
|
||||||
|
| 1.17 | Backend: Evidence Pack model | Trust | Done |
|
||||||
|
| 1.18 | Backend: Compliance Control model | Compliance | Done |
|
||||||
|
| 1.19 | Backend: Contradiction Engine service | Trust | Done |
|
||||||
|
| 1.20 | Backend: Evidence Pack service | Trust | Done |
|
||||||
|
| 1.21 | Update CLAUDE.md + AGENTS.md | Operations | Done |
|
||||||
|
|
||||||
|
**Acceptance**: All governance docs exist and are cross-referenced. Models registered in `__init__.py`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Sprint 2 (May 1 – May 14): Backend Services & APIs
|
||||||
|
|
||||||
|
| # | Deliverable | Track | Status |
|
||||||
|
|---|-----------|-------|--------|
|
||||||
|
| 2.1 | Executive Room service (expanded) | Trust | Planned |
|
||||||
|
| 2.2 | Connector Governance service | Operations | Planned |
|
||||||
|
| 2.3 | Model Routing Dashboard service | Intelligence | Planned |
|
||||||
|
| 2.4 | Saudi Compliance Matrix service | Compliance | Planned |
|
||||||
|
| 2.5 | Forecast Control Center service | Revenue | Planned |
|
||||||
|
| 2.6 | Approval Center API (enhanced) | Trust | Planned |
|
||||||
|
| 2.7 | Contradiction Engine API | Trust | Planned |
|
||||||
|
| 2.8 | Evidence Pack API | Trust | Planned |
|
||||||
|
| 2.9 | Executive Room API | Trust | Planned |
|
||||||
|
| 2.10 | Connector Governance API | Operations | Planned |
|
||||||
|
| 2.11 | Model Routing API | Intelligence | Planned |
|
||||||
|
| 2.12 | Saudi Compliance API | Compliance | Planned |
|
||||||
|
| 2.13 | Forecast Control API | Revenue | Planned |
|
||||||
|
|
||||||
|
**Acceptance**: All APIs return valid responses. Router wired in `router.py`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Sprint 3 (May 15 – May 28): Frontend Surfaces
|
||||||
|
|
||||||
|
| # | Deliverable | Track | Status |
|
||||||
|
|---|-----------|-------|--------|
|
||||||
|
| 3.1 | Executive Room component | Trust | Planned |
|
||||||
|
| 3.2 | Evidence Pack Viewer component | Trust | Planned |
|
||||||
|
| 3.3 | Approval Center component | Trust | Planned |
|
||||||
|
| 3.4 | Connector Governance Board component | Operations | Planned |
|
||||||
|
| 3.5 | Saudi Compliance Dashboard component | Compliance | Planned |
|
||||||
|
| 3.6 | Actual vs Forecast Dashboard component | Revenue | Planned |
|
||||||
|
| 3.7 | Risk Heatmap component | Trust | Planned |
|
||||||
|
| 3.8 | Policy Violations Board component | Trust | Planned |
|
||||||
|
| 3.9 | Partner Pipeline Board component | Expansion | Planned |
|
||||||
|
|
||||||
|
**Acceptance**: All components render with mock/live data. RTL + Arabic labels.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Sprint 4 (May 29 – Jun 11): Integration & Testing
|
||||||
|
|
||||||
|
| # | Deliverable | Track | Status |
|
||||||
|
|---|-----------|-------|--------|
|
||||||
|
| 4.1 | Unit tests for Contradiction Engine | Trust | Planned |
|
||||||
|
| 4.2 | Unit tests for Evidence Pack | Trust | Planned |
|
||||||
|
| 4.3 | Unit tests for Compliance Matrix | Compliance | Planned |
|
||||||
|
| 4.4 | Integration test: approval flow end-to-end | Trust | Planned |
|
||||||
|
| 4.5 | Integration test: evidence pack assembly | Trust | Planned |
|
||||||
|
| 4.6 | Integration test: contradiction scan | Trust | Planned |
|
||||||
|
| 4.7 | Frontend smoke tests for new components | Operations | Planned |
|
||||||
|
| 4.8 | Architecture brief validates all deliverables | Operations | Planned |
|
||||||
|
|
||||||
|
**Acceptance**: `pytest -v` passes. `architecture_brief.py` reports 100% coverage.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Sprint 5 (Jun 12 – Jun 25): Arabic & Saudi Readiness
|
||||||
|
|
||||||
|
| # | Deliverable | Track | Status |
|
||||||
|
|---|-----------|-------|--------|
|
||||||
|
| 5.1 | Arabic labels for all new components | Compliance | Planned |
|
||||||
|
| 5.2 | Arabic-first evidence pack content | Compliance | Planned |
|
||||||
|
| 5.3 | Saudi compliance matrix in Arabic | Compliance | Planned |
|
||||||
|
| 5.4 | Arabic executive room labels | Trust | Planned |
|
||||||
|
| 5.5 | End-to-end Arabic workflow test | Compliance | Planned |
|
||||||
|
| 5.6 | PDPL live control validation | Compliance | Planned |
|
||||||
|
| 5.7 | ZATCA live control validation | Compliance | Planned |
|
||||||
|
|
||||||
|
**Acceptance**: One Arabic-first path works end-to-end.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Sprint 6 (Jun 26 – Jul 15): Polish & Enterprise Readiness
|
||||||
|
|
||||||
|
| # | Deliverable | Track | Status |
|
||||||
|
|---|-----------|-------|--------|
|
||||||
|
| 6.1 | Board pack generator (JSON + PDF) | Trust | Planned |
|
||||||
|
| 6.2 | Evidence pack PDF export | Trust | Planned |
|
||||||
|
| 6.3 | ROI narrative document | Revenue | Planned |
|
||||||
|
| 6.4 | Capability moat map | Expansion | Planned |
|
||||||
|
| 6.5 | Enterprise pricing model document | Revenue | Planned |
|
||||||
|
| 6.6 | Product packaging document | Revenue | Planned |
|
||||||
|
| 6.7 | Final architecture brief audit | Operations | Planned |
|
||||||
|
| 6.8 | Governance docs consistency audit | Trust | Planned |
|
||||||
|
|
||||||
|
**Acceptance**: Platform passes Tier-1 completion checklist.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Tier-1 Completion Checklist
|
||||||
|
|
||||||
|
- [ ] All governance docs exist and are cross-referenced
|
||||||
|
- [ ] All commands execute from repo root without path bugs
|
||||||
|
- [ ] Every critical path produces structured + evidence-backed output
|
||||||
|
- [ ] Every external commitment passes approval/reversibility gate
|
||||||
|
- [ ] At least one durable workflow is live
|
||||||
|
- [ ] Approval center is end-to-end live for one path
|
||||||
|
- [ ] Executive surface is usable
|
||||||
|
- [ ] Arabic-first path works end-to-end
|
||||||
|
- [ ] Saudi/GCC control mapping is live (not just register)
|
||||||
|
- [ ] Contradiction-aware tool flow is live
|
||||||
195
salesflow-saas/docs/governance/execution-fabric.md
Normal file
195
salesflow-saas/docs/governance/execution-fabric.md
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
# Execution Fabric — Dealix Execution Plane Deep Dive
|
||||||
|
|
||||||
|
> **Parent**: [`MASTER_OPERATING_PROMPT.md`](../../MASTER_OPERATING_PROMPT.md)
|
||||||
|
> **Plane**: Execution | **Tracks**: All
|
||||||
|
> **Version**: 1.0 | **Status**: Canonical
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The Execution Fabric defines how Dealix performs work: how tasks are classified, routed, checkpointed, retried, and completed. The backbone is the **OpenClaw Framework** — a durable execution engine with policy-aware gating.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
Inbound Request/Event
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌──────────────────┐
|
||||||
|
│ OpenClaw Gateway │ ← Single ingress for all tasks
|
||||||
|
│ (gateway.py) │
|
||||||
|
└───────┬──────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌──────────────────┐
|
||||||
|
│ Policy Gate │ ← Classify action (A/B/C)
|
||||||
|
│ (policy.py) │
|
||||||
|
└───────┬──────────┘
|
||||||
|
│
|
||||||
|
┌────┴────┐
|
||||||
|
│ Class C │──→ BLOCKED (forbidden)
|
||||||
|
└─────────┘
|
||||||
|
│
|
||||||
|
┌────┴────┐
|
||||||
|
│ Class B │──→ Check approval_token
|
||||||
|
└─────────┘ │
|
||||||
|
│ ┌────┴─────┐
|
||||||
|
│ │ No token │──→ BLOCKED (requires_approval)
|
||||||
|
│ └──────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌──────────────────┐
|
||||||
|
│ Canary Context │ ← Tenant in canary group?
|
||||||
|
│ (canary_context) │
|
||||||
|
└───────┬──────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌──────────────────┐
|
||||||
|
│ Observability │ ← Start trace, record steps
|
||||||
|
│ (observability) │
|
||||||
|
└───────┬──────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌──────────────────┐
|
||||||
|
│ Task Router │ ← Dispatch to handler
|
||||||
|
│ (task_router) │
|
||||||
|
└───────┬──────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌──────────────────┐
|
||||||
|
│ Durable Flow │ ← Checkpoint state
|
||||||
|
│ (durable_flow) │
|
||||||
|
└───────┬──────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌──────────────────┐
|
||||||
|
│ Handler / Agent │ ← Execute business logic
|
||||||
|
│ (Celery / Sync) │
|
||||||
|
└──────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task Classification
|
||||||
|
|
||||||
|
### Class A — Safe Auto Actions
|
||||||
|
```python
|
||||||
|
SAFE_AUTO_ACTIONS = {
|
||||||
|
"read_status", "collect_signals", "summarize", "classify",
|
||||||
|
"tag", "internal_status_update", "research", "generate_draft",
|
||||||
|
"plan", "predictive_analysis"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
These execute immediately without human approval.
|
||||||
|
|
||||||
|
### Class B — Approval-Gated Actions
|
||||||
|
```python
|
||||||
|
APPROVAL_GATED_ACTIONS = {
|
||||||
|
"send_whatsapp", "send_email", "send_linkedin",
|
||||||
|
"trigger_voice_call", "sync_salesforce", "create_charge",
|
||||||
|
"publish_content", "change_billing_state", "modify_lead_routing",
|
||||||
|
"send_contract_for_signature", "video_generate", "music_generate"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
These require an `approval_token` in the payload.
|
||||||
|
|
||||||
|
### Class C — Forbidden Actions
|
||||||
|
```python
|
||||||
|
FORBIDDEN_ACTIONS = {
|
||||||
|
"exfiltrate_secrets", "delete_data_without_audit",
|
||||||
|
"bypass_auth", "publish_without_approval", "destructive_unchecked"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
These are unconditionally blocked.
|
||||||
|
|
||||||
|
**Default**: Unknown actions → Class B (approval required).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Durable Flow Lifecycle
|
||||||
|
|
||||||
|
```
|
||||||
|
1. CREATE → DurableTaskFlow(flow_name, tenant_id)
|
||||||
|
2. CHECKPOINT → flow.checkpoint(note, state_patch) → FlowRevision
|
||||||
|
3. RESUME → Load from checkpoints, continue from last state
|
||||||
|
4. COMPLETE → Final checkpoint, mark complete
|
||||||
|
5. ROLLBACK → Compensate side effects (target state)
|
||||||
|
```
|
||||||
|
|
||||||
|
Each checkpoint stores:
|
||||||
|
- `revision_id` (UUID)
|
||||||
|
- `at` (ISO timestamp)
|
||||||
|
- `note` (human-readable)
|
||||||
|
- `checkpoint` (full state snapshot)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Plugin System
|
||||||
|
|
||||||
|
Plugins extend the Execution Plane with external integrations:
|
||||||
|
|
||||||
|
| Plugin | File | Purpose |
|
||||||
|
|--------|------|---------|
|
||||||
|
| WhatsApp | `plugins/whatsapp_plugin.py` | WhatsApp Cloud API messaging |
|
||||||
|
| Salesforce | `plugins/salesforce_agentforce_plugin.py` | CRM sync, Account 360 |
|
||||||
|
| Stripe | `plugins/stripe_plugin.py` | Payment processing |
|
||||||
|
| Voice | `plugins/voice_plugin.py` | Voice call integration |
|
||||||
|
| Contract Intel | `plugins/contract_intelligence_plugin.py` | Contract analysis |
|
||||||
|
|
||||||
|
### Plugin Contract
|
||||||
|
Each plugin must:
|
||||||
|
1. Register its task types with `task_router.register()`
|
||||||
|
2. Accept `(tenant_id: str, payload: dict)` as input
|
||||||
|
3. Return `dict` with structured output
|
||||||
|
4. Handle its own retries and error reporting
|
||||||
|
5. Log to observability bridge
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Agent Execution Model
|
||||||
|
|
||||||
|
```
|
||||||
|
Event → Agent Router → Input Validation → Celery Task
|
||||||
|
→ LLM Call (model_router.py selects provider)
|
||||||
|
→ Output Parsing (Pydantic schema validation)
|
||||||
|
→ Escalation Check (rules in agent config)
|
||||||
|
→ Action Handler / Human Handoff
|
||||||
|
→ Log to ai_conversations
|
||||||
|
```
|
||||||
|
|
||||||
|
19 specialized agents, each with:
|
||||||
|
- System prompt (`ai-agents/prompts/`)
|
||||||
|
- Input/output schema
|
||||||
|
- Model + temperature config
|
||||||
|
- Escalation rules
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
| Error Type | Behavior |
|
||||||
|
|------------|----------|
|
||||||
|
| LLM timeout | Retry with exponential backoff (3 attempts) |
|
||||||
|
| Plugin failure | Log error, mark flow as failed, alert |
|
||||||
|
| Policy violation | Block immediately, log to audit |
|
||||||
|
| Tenant mismatch | Block, log security event |
|
||||||
|
| Unknown task type | Raise ValueError, log |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Current vs Target
|
||||||
|
|
||||||
|
| Capability | Current | Target |
|
||||||
|
|-----------|---------|--------|
|
||||||
|
| Task classification (A/B/C) | Live | Live |
|
||||||
|
| Durable checkpointing | Live (in-memory) | Persistent storage |
|
||||||
|
| Plugin system | Live (5 plugins) | Expand to 10+ |
|
||||||
|
| Agent execution | Live (19 agents) | Add governance agents |
|
||||||
|
| Canary enforcement | Live | Live |
|
||||||
|
| Compensation/rollback | Not implemented | Planned |
|
||||||
|
| Idempotency keys | Not implemented | Planned |
|
||||||
|
| Dead letter queue | Not implemented | Planned |
|
||||||
|
| Temporal integration | Not evaluated | Watch |
|
||||||
195
salesflow-saas/docs/governance/executive-board-os.md
Normal file
195
salesflow-saas/docs/governance/executive-board-os.md
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
# Executive & Board OS — Decision Surface Framework
|
||||||
|
|
||||||
|
> **Parent**: [`MASTER_OPERATING_PROMPT.md`](../../MASTER_OPERATING_PROMPT.md)
|
||||||
|
> **Plane**: Decision | **Tracks**: All
|
||||||
|
> **Version**: 1.0 | **Status**: Canonical
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The Executive & Board OS defines what leadership sees, how decisions are escalated, and what constitutes a complete board pack. The goal is to make Dealix **Board-usable** — executives can make informed decisions from system-generated surfaces.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Executive Surfaces
|
||||||
|
|
||||||
|
### 1. Executive Room
|
||||||
|
**Purpose**: Single view of everything an executive needs to know right now.
|
||||||
|
|
||||||
|
| Section | Data Source | Refresh |
|
||||||
|
|---------|-----------|---------|
|
||||||
|
| Revenue Overview | `analytics_service.py` | Real-time |
|
||||||
|
| Actual vs Forecast | `forecast_control_center.py` | Daily |
|
||||||
|
| Pipeline Health | `deal_service.py` | Real-time |
|
||||||
|
| Approval Queue | `ApprovalRequest` model | Real-time |
|
||||||
|
| Connector Health | `connector_governance.py` | 5 min |
|
||||||
|
| Compliance Posture | `saudi_compliance_matrix.py` | Daily |
|
||||||
|
| Active Contradictions | `contradiction_engine.py` | Real-time |
|
||||||
|
| Strategic Deals | `strategic_deals/` services | Real-time |
|
||||||
|
| Risk Summary | Aggregated | Daily |
|
||||||
|
|
||||||
|
**API**: `GET /api/v1/executive-room/snapshot`
|
||||||
|
|
||||||
|
### 2. Approval Center
|
||||||
|
**Purpose**: All pending approvals with SLA timers.
|
||||||
|
|
||||||
|
| Feature | Description |
|
||||||
|
|---------|------------|
|
||||||
|
| Queue | Filterable by category, priority, SLA status |
|
||||||
|
| SLA Timer | Color-coded countdown (green → yellow → red) |
|
||||||
|
| Bulk Actions | Approve/reject low-risk items in batch |
|
||||||
|
| History | Full approval history with audit trail |
|
||||||
|
|
||||||
|
**API**: `GET /api/v1/approval-center`
|
||||||
|
|
||||||
|
### 3. Evidence Pack Viewer
|
||||||
|
**Purpose**: Browse and review assembled evidence packs.
|
||||||
|
|
||||||
|
| Feature | Description |
|
||||||
|
|---------|------------|
|
||||||
|
| Pack List | By type (deal, compliance, board, incident) |
|
||||||
|
| Detail View | Expandable evidence items |
|
||||||
|
| Review Workflow | Mark reviewed, add notes |
|
||||||
|
| Integrity Check | SHA256 hash verification |
|
||||||
|
|
||||||
|
**API**: `GET /api/v1/evidence-packs`
|
||||||
|
|
||||||
|
### 4. Risk Heatmap
|
||||||
|
**Purpose**: Visual risk matrix across all domains.
|
||||||
|
|
||||||
|
| Axis | Categories |
|
||||||
|
|------|-----------|
|
||||||
|
| X (Category) | Revenue, Compliance, Technology, Operations, Partners, M&A |
|
||||||
|
| Y (Severity) | Critical, High, Medium, Low |
|
||||||
|
| Color | Red (active + unmitigated), Yellow (active + mitigated), Green (resolved) |
|
||||||
|
|
||||||
|
Data aggregated from: Compliance Matrix, Contradiction Engine, Connector Health, SLA Breaches.
|
||||||
|
|
||||||
|
### 5. Actual vs Forecast Dashboard
|
||||||
|
**Purpose**: Unified view across all tracks.
|
||||||
|
|
||||||
|
| Track | Actual | Forecast | Variance |
|
||||||
|
|-------|--------|----------|----------|
|
||||||
|
| Revenue | Live pipeline value | AI + manual forecast | Auto-calculated |
|
||||||
|
| Partnerships | Active partner count | Partner targets | Auto-calculated |
|
||||||
|
| M&A | Deals in progress | Pipeline target | Auto-calculated |
|
||||||
|
| Expansion | Markets launched | Launch plan | Auto-calculated |
|
||||||
|
|
||||||
|
**API**: `GET /api/v1/forecast-control/unified`
|
||||||
|
|
||||||
|
### 6. Next-Best-Action Board
|
||||||
|
**Purpose**: AI-recommended actions prioritized by impact.
|
||||||
|
|
||||||
|
| Source | Action Type |
|
||||||
|
|--------|------------|
|
||||||
|
| Revenue | Follow up on stale deals, upsell signals |
|
||||||
|
| Compliance | Controls needing attention |
|
||||||
|
| Operations | Connectors needing maintenance |
|
||||||
|
| Trust | Contradictions needing resolution |
|
||||||
|
|
||||||
|
### 7. Pipeline Boards
|
||||||
|
**Purpose**: Kanban views for strategic pipelines.
|
||||||
|
|
||||||
|
| Board | Stages |
|
||||||
|
|-------|--------|
|
||||||
|
| Partner Pipeline | Scout → Evaluate → Negotiate → Onboard → Active |
|
||||||
|
| M&A Pipeline | Source → Screen → Diligence → Negotiate → Close |
|
||||||
|
| Expansion Pipeline | Scan → Prioritize → Ready → Canary → Scale |
|
||||||
|
|
||||||
|
### 8. Policy Violations Board
|
||||||
|
**Purpose**: Active policy violations and contradictions.
|
||||||
|
|
||||||
|
| Column | Description |
|
||||||
|
|--------|------------|
|
||||||
|
| Violation | What was detected |
|
||||||
|
| Severity | Critical / High / Medium / Low |
|
||||||
|
| Source | Which system detected it |
|
||||||
|
| Status | Detected → Investigating → Resolved |
|
||||||
|
| Owner | Who is responsible for resolution |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Board Pack Template
|
||||||
|
|
||||||
|
Produced quarterly (or on-demand for special meetings):
|
||||||
|
|
||||||
|
### Section 1: Executive Summary
|
||||||
|
- Overall business health (RAG status)
|
||||||
|
- Key achievements this period
|
||||||
|
- Key risks requiring board attention
|
||||||
|
|
||||||
|
### Section 2: Financial Performance
|
||||||
|
- Revenue actual vs forecast
|
||||||
|
- Customer acquisition metrics (CAC, LTV, payback)
|
||||||
|
- Runway / burn rate (if applicable)
|
||||||
|
|
||||||
|
### Section 3: Product & Technology
|
||||||
|
- Platform uptime and reliability
|
||||||
|
- AI agent performance metrics
|
||||||
|
- Technology radar changes
|
||||||
|
- Security posture summary
|
||||||
|
|
||||||
|
### Section 4: Compliance & Governance
|
||||||
|
- PDPL compliance status
|
||||||
|
- ZATCA compliance status
|
||||||
|
- Active audit findings
|
||||||
|
- Policy violations summary
|
||||||
|
|
||||||
|
### Section 5: Strategic Initiatives
|
||||||
|
- Partnership pipeline status
|
||||||
|
- M&A pipeline status
|
||||||
|
- Expansion roadmap progress
|
||||||
|
|
||||||
|
### Section 6: People & Culture
|
||||||
|
- Team size and Saudization ratio
|
||||||
|
- Key hires and departures
|
||||||
|
- Training and development
|
||||||
|
|
||||||
|
### Section 7: Risk Register
|
||||||
|
- Top 10 risks with mitigation status
|
||||||
|
- New risks identified this period
|
||||||
|
- Risk heatmap visualization
|
||||||
|
|
||||||
|
### Section 8: Decisions Required
|
||||||
|
- Items requiring board vote
|
||||||
|
- Recommendation for each item
|
||||||
|
- Supporting evidence packs
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Decision Escalation Matrix
|
||||||
|
|
||||||
|
| Decision Type | Operational | Manager | Director | VP | C-Level | Board |
|
||||||
|
|--------------|-------------|---------|----------|-----|---------|-------|
|
||||||
|
| Lead routing | x | | | | | |
|
||||||
|
| Message send | | x | | | | |
|
||||||
|
| Discount <10% | | x | | | | |
|
||||||
|
| Discount 10-25% | | | x | | | |
|
||||||
|
| Discount >25% | | | | x | | |
|
||||||
|
| New integration | | | x | | | |
|
||||||
|
| DB migration | | | | x | | |
|
||||||
|
| Partner activation | | | | x | | |
|
||||||
|
| M&A short list | | | | | x | |
|
||||||
|
| M&A offer | | | | | | x |
|
||||||
|
| Market launch | | | | | x | |
|
||||||
|
| Production deployment | | | | x | | |
|
||||||
|
| Policy change | | | | | x | |
|
||||||
|
| Budget >100K SAR | | | | | x | |
|
||||||
|
| Budget >1M SAR | | | | | | x |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Code Mapping
|
||||||
|
|
||||||
|
| Surface | Backend | Frontend |
|
||||||
|
|---------|---------|----------|
|
||||||
|
| Executive Room | `services/executive_roi_service.py` (expanded) | `components/dealix/executive-room.tsx` |
|
||||||
|
| Approval Center | `api/v1/approval_center.py` | `components/dealix/approval-center.tsx` |
|
||||||
|
| Evidence Packs | `services/evidence_pack_service.py` | `components/dealix/evidence-pack-viewer.tsx` |
|
||||||
|
| Risk Heatmap | Aggregated service | `components/dealix/risk-heatmap.tsx` |
|
||||||
|
| Forecast Control | `services/forecast_control_center.py` | `components/dealix/actual-vs-forecast-dashboard.tsx` |
|
||||||
|
| Partner Pipeline | `api/v1/strategic_deals.py` | `components/dealix/partner-pipeline-board.tsx` |
|
||||||
|
| Policy Violations | `services/contradiction_engine.py` | `components/dealix/policy-violations-board.tsx` |
|
||||||
|
| Compliance Dashboard | `services/saudi_compliance_matrix.py` | `components/dealix/saudi-compliance-dashboard.tsx` |
|
||||||
|
| Connector Governance | `services/connector_governance.py` | `components/dealix/connector-governance-board.tsx` |
|
||||||
135
salesflow-saas/docs/governance/expansion-os.md
Normal file
135
salesflow-saas/docs/governance/expansion-os.md
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
# Expansion OS — Geographic & Vertical Growth
|
||||||
|
|
||||||
|
> **Parent**: [`MASTER_OPERATING_PROMPT.md`](../../MASTER_OPERATING_PROMPT.md)
|
||||||
|
> **Plane**: Decision + Execution | **Tracks**: Expansion, Revenue
|
||||||
|
> **Version**: 1.0 | **Status**: Canonical
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The Expansion OS manages Dealix's growth into new geographies and industry verticals. Every market launch is a Class B action with C-Level approval and mandatory stop-loss logic.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Expansion Framework
|
||||||
|
|
||||||
|
```
|
||||||
|
SCAN → PRIORITIZE → READY → LAUNCH (Canary) → SCALE → MONITOR
|
||||||
|
```
|
||||||
|
|
||||||
|
### Phase 1: Scan
|
||||||
|
- **AI Role**: Market intelligence, competitive analysis
|
||||||
|
- **Input**: Macro indicators, sector size, regulatory landscape
|
||||||
|
- **Output**: Market opportunity matrix
|
||||||
|
|
||||||
|
### Phase 2: Prioritize
|
||||||
|
- **Criteria**: Market size, regulatory complexity, Arabic support needs, competitive density
|
||||||
|
- **Output**: Ranked expansion targets
|
||||||
|
|
||||||
|
### Phase 3: Ready
|
||||||
|
- **Compliance**: Regulatory readiness by market
|
||||||
|
- **Localization**: Dialect adaptation, pricing, channel strategy
|
||||||
|
- **GTM**: Go-to-market plan with ICP per market
|
||||||
|
- **Output**: Market readiness checklist
|
||||||
|
|
||||||
|
### Phase 4: Launch (Canary)
|
||||||
|
- **Method**: Canary launch — limited tenant cohort
|
||||||
|
- **Stop-loss**: Automated triggers if metrics below threshold
|
||||||
|
- **Output**: Canary results report
|
||||||
|
|
||||||
|
### Phase 5: Scale
|
||||||
|
- **Criteria**: Canary success metrics met
|
||||||
|
- **Action**: Open market to all tenants
|
||||||
|
- **Output**: Market GA announcement
|
||||||
|
|
||||||
|
### Phase 6: Monitor
|
||||||
|
- **Ongoing**: Actual vs forecast per market
|
||||||
|
- **Triggers**: Expansion, contraction, or exit decisions
|
||||||
|
- **Output**: Market health dashboard
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Geographic Expansion Path
|
||||||
|
|
||||||
|
### Phase 1: Saudi Arabia (Current)
|
||||||
|
| City | Status | Priority |
|
||||||
|
|------|--------|----------|
|
||||||
|
| Riyadh | Live | Primary |
|
||||||
|
| Jeddah | Live | Primary |
|
||||||
|
| Dammam | Ready | High |
|
||||||
|
| Other cities | Planned | Medium |
|
||||||
|
|
||||||
|
### Phase 2: GCC Markets
|
||||||
|
| Market | Complexity | Arabic Dialect | Target |
|
||||||
|
|--------|-----------|----------------|--------|
|
||||||
|
| UAE | Medium | Gulf/MSA | 2027 H1 |
|
||||||
|
| Bahrain | Low | Gulf | 2027 H1 |
|
||||||
|
| Kuwait | Medium | Gulf | 2027 H2 |
|
||||||
|
| Qatar | Medium | Gulf | 2027 H2 |
|
||||||
|
| Oman | Low | Gulf | 2028 |
|
||||||
|
|
||||||
|
### Phase 3: Broader MENA
|
||||||
|
| Market | Complexity | Dialect | Target |
|
||||||
|
|--------|-----------|---------|--------|
|
||||||
|
| Egypt | High | Egyptian | 2028 |
|
||||||
|
| Jordan | Medium | Levantine | 2028 |
|
||||||
|
| Morocco | High | Maghrebi/French | 2029 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Vertical Expansion
|
||||||
|
|
||||||
|
### Current Verticals (Live)
|
||||||
|
- Real Estate — `seeds/realestate_template.json`
|
||||||
|
- Healthcare — `seeds/healthcare_template.json`
|
||||||
|
- Retail — `seeds/retail_template.json`
|
||||||
|
- Contracting — `seeds/contracting_template.json`
|
||||||
|
- Education — `seeds/education_template.json`
|
||||||
|
|
||||||
|
### Target Verticals
|
||||||
|
| Vertical | Priority | Regulatory Complexity |
|
||||||
|
|----------|----------|---------------------|
|
||||||
|
| Financial Services | High | Very High (SAMA) |
|
||||||
|
| Automotive | High | Medium |
|
||||||
|
| Legal | Medium | High |
|
||||||
|
| Hospitality | Medium | Low |
|
||||||
|
| Government | High | Very High |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Dialect Handling
|
||||||
|
|
||||||
|
| Dialect | Code | Supported | Service |
|
||||||
|
|---------|------|-----------|---------|
|
||||||
|
| Saudi | `saudi` | Live | `ai/saudi_dialect.py` |
|
||||||
|
| Gulf | `gulf` | Live | `ai/arabic_nlp.py` |
|
||||||
|
| MSA | `msa` | Live | `ai/arabic_nlp.py` |
|
||||||
|
| Egyptian | `egyptian` | Planned | — |
|
||||||
|
| Levantine | `levantine` | Planned | — |
|
||||||
|
| Maghrebi | `maghrebi` | Planned | — |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Stop-Loss Logic
|
||||||
|
|
||||||
|
| Metric | Threshold | Action |
|
||||||
|
|--------|-----------|--------|
|
||||||
|
| Canary conversion rate | <5% after 30 days | Pause expansion |
|
||||||
|
| Customer complaints | >10% rate | Investigate |
|
||||||
|
| Revenue vs forecast | <50% after 60 days | Review / exit |
|
||||||
|
| Compliance violations | Any critical | Halt immediately |
|
||||||
|
| Churn rate | >20% monthly | Pause acquisition |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Code Mapping
|
||||||
|
|
||||||
|
| Component | File |
|
||||||
|
|-----------|------|
|
||||||
|
| Territory Manager | `services/territory_manager.py` |
|
||||||
|
| Feature Flags | `services/feature_flags.py` |
|
||||||
|
| Canary Context | `openclaw/canary_context.py` |
|
||||||
|
| Industry Templates | `seeds/` |
|
||||||
|
| Sector Assets | `models/knowledge.py (SectorAsset)` |
|
||||||
|
| Presentations | `presentations/` (11 sectors) |
|
||||||
101
salesflow-saas/docs/governance/ma-os.md
Normal file
101
salesflow-saas/docs/governance/ma-os.md
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
# M&A OS — Corporate Development Lifecycle
|
||||||
|
|
||||||
|
> **Parent**: [`MASTER_OPERATING_PROMPT.md`](../../MASTER_OPERATING_PROMPT.md)
|
||||||
|
> **Plane**: Decision + Execution | **Tracks**: Expansion
|
||||||
|
> **Version**: 1.0 | **Status**: Canonical
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The M&A OS manages corporate development activities from target identification through post-merger integration. All M&A commitments are Class B actions with C-Level or Board approval required.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## M&A Lifecycle
|
||||||
|
|
||||||
|
```
|
||||||
|
SOURCE → SCREEN → DILIGENCE → NEGOTIATE → CLOSE → INTEGRATE
|
||||||
|
```
|
||||||
|
|
||||||
|
### Phase 1: Source
|
||||||
|
- **AI Role**: `acquisition_scouting.py` identifies targets
|
||||||
|
- **Input**: Sector focus, revenue thresholds, geographic criteria
|
||||||
|
- **Output**: Target long list with preliminary scores
|
||||||
|
|
||||||
|
### Phase 2: Screen
|
||||||
|
- **AI Role**: `deal_matcher.py` + `company_profiler.py` deep analysis
|
||||||
|
- **Input**: Target long list
|
||||||
|
- **Output**: `TargetScreeningMemo` (structured) — short list
|
||||||
|
|
||||||
|
### Phase 3: Diligence
|
||||||
|
- **Orchestration**: DD room control with workstream assignments
|
||||||
|
- **Workstreams**: Financial, Legal, Technical, Product, Security, Cultural
|
||||||
|
- **AI Role**: `portfolio_intelligence.py` analyzes each workstream
|
||||||
|
- **Human Role**: Reviews findings, flags risks (Class B)
|
||||||
|
- **Output**: `DueDiligenceReport` (structured)
|
||||||
|
|
||||||
|
### Phase 4: Negotiate
|
||||||
|
- **AI Role**: `strategic_simulator.py` models scenarios, `roi_engine.py` calculates ranges
|
||||||
|
- **Human Role**: Negotiation strategy approval (Class B → Board)
|
||||||
|
- **Output**: IC Memo, Board Pack Draft, Offer Terms
|
||||||
|
|
||||||
|
### Phase 5: Close
|
||||||
|
- **Checklist**: Regulatory approvals, legal finalization, signing
|
||||||
|
- **Human Role**: Final approval (Board)
|
||||||
|
- **Output**: Signed agreements, closing documentation
|
||||||
|
|
||||||
|
### Phase 6: Integrate
|
||||||
|
- **Handoff**: To PMI OS (see `pmi-os.md`)
|
||||||
|
- **Output**: Integration plan, Day-1 readiness checklist
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Code Mapping
|
||||||
|
|
||||||
|
| Component | File | Purpose |
|
||||||
|
|-----------|------|---------|
|
||||||
|
| Acquisition Scouting | `services/strategic_deals/acquisition_scouting.py` | Target identification |
|
||||||
|
| Company Profiler | `services/strategic_deals/company_profiler.py` | Deep company analysis |
|
||||||
|
| Company Twin | `services/strategic_deals/company_twin.py` | Digital twin modeling |
|
||||||
|
| Portfolio Intelligence | `services/strategic_deals/portfolio_intelligence.py` | Portfolio analysis |
|
||||||
|
| Strategic Simulator | `services/strategic_deals/strategic_simulator.py` | Scenario modeling |
|
||||||
|
| ROI Engine | `services/strategic_deals/roi_engine.py` | Financial modeling |
|
||||||
|
| Deal Taxonomy | `services/strategic_deals/deal_taxonomy.py` | Deal classification |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Structured Outputs
|
||||||
|
|
||||||
|
- `TargetScreeningMemo` — fit score, revenue, sector, risks, recommendation
|
||||||
|
- `DueDiligenceReport` — workstream findings, risk register, valuation impact
|
||||||
|
- `SynergyModel` — revenue synergies, cost synergies, integration costs, timeline
|
||||||
|
- `ICMemo` — investment committee memo with recommendation
|
||||||
|
- `BoardPack` — executive summary for board approval
|
||||||
|
- `OfferTerms` — valuation range, deal structure, conditions
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Saudi/GCC Specific
|
||||||
|
|
||||||
|
| Factor | Requirement |
|
||||||
|
|--------|------------|
|
||||||
|
| CMA approvals | Capital Market Authority for listed companies |
|
||||||
|
| GACA approvals | General Authority for Competition |
|
||||||
|
| Saudization compliance | Target must meet or plan to meet quotas |
|
||||||
|
| CR transfer | Commercial Registration transfer process |
|
||||||
|
| PDPL data room | Due diligence data must comply with PDPL |
|
||||||
|
| Arabic documentation | Legal agreements must be bilingual |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Approval Matrix
|
||||||
|
|
||||||
|
| Action | Approver |
|
||||||
|
|--------|---------|
|
||||||
|
| Add target to long list | VP Corporate Dev |
|
||||||
|
| Move to short list | SVP + CFO |
|
||||||
|
| Initiate due diligence | CEO |
|
||||||
|
| Submit offer | Board |
|
||||||
|
| Sign agreement | Board + Legal |
|
||||||
|
| Integration plan approval | CEO |
|
||||||
110
salesflow-saas/docs/governance/partnership-os.md
Normal file
110
salesflow-saas/docs/governance/partnership-os.md
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
# Partnership OS — Alliance Lifecycle Management
|
||||||
|
|
||||||
|
> **Parent**: [`MASTER_OPERATING_PROMPT.md`](../../MASTER_OPERATING_PROMPT.md)
|
||||||
|
> **Plane**: Decision + Execution | **Tracks**: Expansion, Revenue
|
||||||
|
> **Version**: 1.0 | **Status**: Canonical
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The Partnership OS manages the full lifecycle of strategic alliances — from scouting to co-sell optimization. Every partnership commitment is a Class B action requiring human approval.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Partnership Lifecycle
|
||||||
|
|
||||||
|
```
|
||||||
|
SCOUT → EVALUATE → NEGOTIATE → ONBOARD → MANAGE → OPTIMIZE → RENEW/EXIT
|
||||||
|
```
|
||||||
|
|
||||||
|
### Phase 1: Scout
|
||||||
|
- **Input**: Market signals, ecosystem gaps, customer requests
|
||||||
|
- **AI Role**: `ecosystem_mapper.py` identifies potential partners
|
||||||
|
- **Output**: Partner prospect list with strategic fit scores
|
||||||
|
|
||||||
|
### Phase 2: Evaluate
|
||||||
|
- **Input**: Partner prospect list
|
||||||
|
- **AI Role**: `deal_matcher.py` scores strategic fit
|
||||||
|
- **Output**: `PartnerFitScoreCard` (structured)
|
||||||
|
|
||||||
|
### Phase 3: Negotiate
|
||||||
|
- **Input**: Approved partner candidates
|
||||||
|
- **AI Role**: `deal_negotiator.py` drafts term proposals
|
||||||
|
- **Human Role**: Reviews and approves terms (Class B)
|
||||||
|
- **Output**: Term sheet (versioned)
|
||||||
|
|
||||||
|
### Phase 4: Onboard
|
||||||
|
- **Input**: Signed agreement
|
||||||
|
- **Execution**: Activation playbooks, system integration, training
|
||||||
|
- **Output**: Partner activated in system
|
||||||
|
|
||||||
|
### Phase 5: Manage
|
||||||
|
- **Input**: Live partnership
|
||||||
|
- **Monitoring**: Partner scorecards, contribution margin, health signals
|
||||||
|
- **Output**: Monthly partner performance report
|
||||||
|
|
||||||
|
### Phase 6: Optimize
|
||||||
|
- **Input**: Performance data
|
||||||
|
- **AI Role**: Co-sell/co-market recommendations
|
||||||
|
- **Output**: Optimization playbook
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Partnership Types
|
||||||
|
|
||||||
|
| Type | Description | Approval Level |
|
||||||
|
|------|------------|---------------|
|
||||||
|
| Referral | Lead exchange, commission-based | Manager |
|
||||||
|
| Distribution | Resale rights, channel partner | Director |
|
||||||
|
| Technology | API integration, co-development | VP |
|
||||||
|
| Strategic | Joint ventures, co-investment | C-Level |
|
||||||
|
| Government | Public sector partnerships | C-Level + Legal |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Code Mapping
|
||||||
|
|
||||||
|
| Component | File | Purpose |
|
||||||
|
|-----------|------|---------|
|
||||||
|
| Ecosystem Mapper | `services/strategic_deals/ecosystem_mapper.py` | Partner discovery |
|
||||||
|
| Deal Matcher | `services/strategic_deals/deal_matcher.py` | Fit scoring |
|
||||||
|
| Deal Negotiator | `services/strategic_deals/deal_negotiator.py` | Term drafting |
|
||||||
|
| Deal Room | `services/strategic_deals/deal_room.py` | Negotiation workspace |
|
||||||
|
| Channel Compliance | `services/strategic_deals/channel_compliance.py` | Channel governance |
|
||||||
|
| ROI Engine | `services/strategic_deals/roi_engine.py` | Partnership ROI |
|
||||||
|
| Strategic Deal Model | `models/strategic_deal.py` | Data model |
|
||||||
|
| Strategic Deals API | `api/v1/strategic_deals.py` | API endpoints |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Structured Outputs
|
||||||
|
|
||||||
|
- `PartnerFitScoreCard` — strategic alignment, revenue potential, risk assessment
|
||||||
|
- `PartnerTermSheet` — economics, obligations, SLAs, exit clauses
|
||||||
|
- `PartnerScorecard` — monthly performance, contribution margin, health
|
||||||
|
- `PartnerActivationChecklist` — integration steps, training, go-live criteria
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## GCC-Specific Considerations
|
||||||
|
|
||||||
|
| Factor | Requirement |
|
||||||
|
|--------|------------|
|
||||||
|
| Saudization | Partners must meet Saudization quotas for joint operations |
|
||||||
|
| Local partner mandate | Some sectors require Saudi partner (>51% ownership) |
|
||||||
|
| CR verification | Commercial Registration must be verified before activation |
|
||||||
|
| Arabic agreements | All partnership agreements must be available in Arabic |
|
||||||
|
| PDPL data sharing | Data sharing between partners requires PDPL consent |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## KPIs
|
||||||
|
|
||||||
|
| Metric | Target |
|
||||||
|
|--------|--------|
|
||||||
|
| Partner-sourced revenue | >15% of total |
|
||||||
|
| Time to activate (days) | <30 |
|
||||||
|
| Partner satisfaction score | >4.0/5.0 |
|
||||||
|
| Co-sell deal conversion | >25% |
|
||||||
|
| Partner churn rate | <10% annual |
|
||||||
132
salesflow-saas/docs/governance/pmi-os.md
Normal file
132
salesflow-saas/docs/governance/pmi-os.md
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
# PMI OS — Post-Merger Integration & Strategic PMO
|
||||||
|
|
||||||
|
> **Parent**: [`MASTER_OPERATING_PROMPT.md`](../../MASTER_OPERATING_PROMPT.md)
|
||||||
|
> **Plane**: Execution | **Tracks**: Expansion, Operations
|
||||||
|
> **Version**: 1.0 | **Status**: Canonical
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The PMI OS provides the framework for integrating acquired companies and managing strategic programs. It ensures Day-1 readiness, tracks synergy realization, and produces executive weekly packs.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## PMI Lifecycle
|
||||||
|
|
||||||
|
```
|
||||||
|
DAY-1 READINESS → 30/60/90 PLANS → EXECUTION → SYNERGY TRACKING → CLOSE-OUT
|
||||||
|
```
|
||||||
|
|
||||||
|
### Day-1 Readiness
|
||||||
|
- [ ] Legal entity structure finalized
|
||||||
|
- [ ] Communication plan executed (employees, customers, partners)
|
||||||
|
- [ ] IT systems access provisioned
|
||||||
|
- [ ] Financial reporting consolidated
|
||||||
|
- [ ] Key personnel retention agreements signed
|
||||||
|
- [ ] Saudization compliance plan for combined entity
|
||||||
|
- [ ] PDPL data inventory of acquired entity
|
||||||
|
- [ ] CR (Commercial Registration) transfer initiated
|
||||||
|
|
||||||
|
### 30-Day Plan
|
||||||
|
- [ ] Organization structure announced
|
||||||
|
- [ ] Customer communication completed
|
||||||
|
- [ ] System integration assessment completed
|
||||||
|
- [ ] Quick wins identified and initiated
|
||||||
|
- [ ] Cultural integration program started
|
||||||
|
- [ ] Saudization gap analysis completed
|
||||||
|
|
||||||
|
### 60-Day Plan
|
||||||
|
- [ ] Data migration plan finalized
|
||||||
|
- [ ] Tenant merge/split strategy decided
|
||||||
|
- [ ] API consolidation roadmap agreed
|
||||||
|
- [ ] Revenue synergy pilot initiated
|
||||||
|
- [ ] Cost synergy tracking started
|
||||||
|
- [ ] Compliance audit of acquired entity completed
|
||||||
|
|
||||||
|
### 90-Day Plan
|
||||||
|
- [ ] Core system integration complete
|
||||||
|
- [ ] Unified reporting live
|
||||||
|
- [ ] Synergy run-rate validated
|
||||||
|
- [ ] Customer retention confirmed (target: >95%)
|
||||||
|
- [ ] Combined team operating as one unit
|
||||||
|
- [ ] Integration retrospective completed
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Dependency Tracking
|
||||||
|
|
||||||
|
### Critical Path Items
|
||||||
|
| Item | Owner | Dependency | Risk Level |
|
||||||
|
|------|-------|-----------|-----------|
|
||||||
|
| Data migration | Engineering | Schema compatibility assessment | High |
|
||||||
|
| Tenant merge | Platform | Data migration complete | High |
|
||||||
|
| API consolidation | Engineering | Tenant merge complete | Medium |
|
||||||
|
| Financial consolidation | Finance | Legal entity setup | Medium |
|
||||||
|
| Customer migration | Customer Success | Communication plan | High |
|
||||||
|
|
||||||
|
### Risk Register
|
||||||
|
| Risk | Probability | Impact | Mitigation |
|
||||||
|
|------|------------|--------|-----------|
|
||||||
|
| Key person departure | Medium | High | Retention bonuses, cultural integration |
|
||||||
|
| Data loss during migration | Low | Critical | Backup, staged migration, rollback plan |
|
||||||
|
| Customer churn post-merger | Medium | High | Proactive communication, service continuity |
|
||||||
|
| Regulatory non-compliance | Low | Critical | Pre-close compliance audit |
|
||||||
|
| Integration timeline overrun | High | Medium | Buffer in plan, weekly tracking |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Escalation Engine
|
||||||
|
|
||||||
|
| Level | Trigger | Action |
|
||||||
|
|-------|---------|--------|
|
||||||
|
| L1 | Task >3 days overdue | Notify workstream lead |
|
||||||
|
| L2 | Milestone >1 week overdue | Escalate to PMI director |
|
||||||
|
| L3 | Critical path blocked | Escalate to CEO |
|
||||||
|
| L4 | Synergy at risk | Board notification |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Executive Weekly Pack
|
||||||
|
|
||||||
|
Produced every Friday, contains:
|
||||||
|
|
||||||
|
1. **Integration Status** — overall RAG (Red/Amber/Green) status
|
||||||
|
2. **This Week** — completed milestones
|
||||||
|
3. **Next Week** — planned milestones
|
||||||
|
4. **Blockers** — active issues requiring escalation
|
||||||
|
5. **Synergy Tracker** — actual vs planned synergies (revenue + cost)
|
||||||
|
6. **People** — retention, Saudization, cultural integration
|
||||||
|
7. **Risk Summary** — top 5 risks with mitigation status
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Technical Integration Patterns
|
||||||
|
|
||||||
|
### Tenant Strategy
|
||||||
|
| Scenario | Approach |
|
||||||
|
|----------|---------|
|
||||||
|
| Acquiree has no SaaS | Create new tenant in Dealix |
|
||||||
|
| Acquiree has compatible SaaS | Data migration into Dealix tenant |
|
||||||
|
| Acquiree has incompatible SaaS | Parallel operation → gradual migration |
|
||||||
|
| Acquiree is Dealix customer | Tenant already exists, upgrade plan |
|
||||||
|
|
||||||
|
### Data Migration
|
||||||
|
1. Schema mapping (source → Dealix models)
|
||||||
|
2. Data quality assessment
|
||||||
|
3. Staging migration (non-production)
|
||||||
|
4. Validation suite (row counts, referential integrity, PII check)
|
||||||
|
5. Production migration (maintenance window)
|
||||||
|
6. Post-migration validation
|
||||||
|
7. Rollback ready for 72 hours
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Structured Outputs
|
||||||
|
|
||||||
|
- `Day1ReadinessChecklist` — all items with status
|
||||||
|
- `IntegrationPlan` — phases, milestones, dependencies, owners
|
||||||
|
- `SynergyTracker` — revenue synergies, cost synergies, run-rate, actual
|
||||||
|
- `WeeklyPack` — executive summary for board
|
||||||
|
- `IssueRegister` — active issues, owners, resolution timeline
|
||||||
|
- `IntegrationCloseout` — final report, lessons learned, metrics
|
||||||
@ -0,0 +1,177 @@
|
|||||||
|
# Saudi Compliance & AI Governance
|
||||||
|
|
||||||
|
> **Parent**: [`MASTER_OPERATING_PROMPT.md`](../../MASTER_OPERATING_PROMPT.md)
|
||||||
|
> **Plane**: Trust | **Tracks**: Compliance, Trust
|
||||||
|
> **Version**: 1.0 | **Status**: Canonical
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Dealix operates as a Saudi-first platform. Compliance is not optional or aspirational — it is enforced at the system level. This document defines the regulatory landscape and how each regulation maps to live controls.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. PDPL — Personal Data Protection Law
|
||||||
|
|
||||||
|
**Authority**: SDAIA (Saudi Data & AI Authority)
|
||||||
|
**Penalty**: Up to SAR 5,000,000 per violation
|
||||||
|
|
||||||
|
### Control Matrix
|
||||||
|
|
||||||
|
| Control ID | Control | Implementation | Status |
|
||||||
|
|-----------|---------|----------------|--------|
|
||||||
|
| PDPL-C01 | Consent before outbound messaging | `pdpl/consent_manager.py` — check before every send | Live |
|
||||||
|
| PDPL-C02 | Consent purpose and channel tracking | `Consent` model — channel, source, opted_in_at | Live |
|
||||||
|
| PDPL-C03 | Auto-expire consent (12 months) | `consent_manager.py` — expiry check | Live |
|
||||||
|
| PDPL-C04 | Data subject access rights | `pdpl/data_rights.py` — export personal data | Live |
|
||||||
|
| PDPL-C05 | Data subject correction rights | `pdpl/data_rights.py` — update records | Live |
|
||||||
|
| PDPL-C06 | Data subject deletion rights | `pdpl/data_rights.py` — soft delete + anonymize | Live |
|
||||||
|
| PDPL-C07 | Data subject restriction rights | `pdpl/data_rights.py` — restrict processing | Live |
|
||||||
|
| PDPL-C08 | Breach notification procedures | Documented in `memory/security/pdpl-checklist.md` | Documented |
|
||||||
|
| PDPL-C09 | Cross-border transfer controls | Approval required for data leaving KSA | Documented |
|
||||||
|
| PDPL-C10 | Consent audit trail (immutable) | `PDPLConsentAudit` model — tracks all changes | Live |
|
||||||
|
| PDPL-C11 | Data minimization in logs | StructLog context scoping, no PII in logs | Live |
|
||||||
|
| PDPL-C12 | Encryption at rest | PostgreSQL TDE + application-level for PII | Planned |
|
||||||
|
| PDPL-C13 | Encryption in transit | TLS 1.3 for all connections | Live |
|
||||||
|
| PDPL-C14 | Privacy policy (Arabic) | `docs/legal/privacy-policy-ar.md` | Live |
|
||||||
|
| PDPL-C15 | Data protection policy (Arabic) | `docs/legal/data-protection-ar.md` | Live |
|
||||||
|
| PDPL-C16 | Cookie consent | `components/dealix/cookie-consent.tsx` | Live |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. ZATCA — E-Invoicing
|
||||||
|
|
||||||
|
**Authority**: Zakat, Tax and Customs Authority
|
||||||
|
**Requirement**: Phase 2 — Standard & Simplified E-Invoices
|
||||||
|
|
||||||
|
### Control Matrix
|
||||||
|
|
||||||
|
| Control ID | Control | Implementation | Status |
|
||||||
|
|-----------|---------|----------------|--------|
|
||||||
|
| ZATCA-C01 | VAT calculation (15%) | `zatca_compliance.py` — 15% rate | Live |
|
||||||
|
| ZATCA-C02 | Invoice format (XML/PDF-A3) | `zatca_compliance.py` — standard format | Live |
|
||||||
|
| ZATCA-C03 | Seller VAT/CR number validation | `zatca_compliance.py` — field validation | Live |
|
||||||
|
| ZATCA-C04 | SAR currency formatting | System-wide `DEFAULT_CURRENCY=SAR` | Live |
|
||||||
|
| ZATCA-C05 | Invoice UUID generation | UUID v4 per invoice | Live |
|
||||||
|
| ZATCA-C06 | QR code on simplified invoices | Planned | Planned |
|
||||||
|
| ZATCA-C07 | Integration with ZATCA sandbox | Planned | Planned |
|
||||||
|
| ZATCA-C08 | Credit/debit note support | Planned | Planned |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. SDAIA — AI Governance
|
||||||
|
|
||||||
|
**Authority**: Saudi Data & AI Authority
|
||||||
|
**Framework**: National AI Strategy + AI Ethics Principles
|
||||||
|
|
||||||
|
### Control Matrix
|
||||||
|
|
||||||
|
| Control ID | Control | Implementation | Status |
|
||||||
|
|-----------|---------|----------------|--------|
|
||||||
|
| SDAIA-C01 | AI decision explainability | Agent outputs include reasoning in `ai_conversations` | Live |
|
||||||
|
| SDAIA-C02 | Human-in-the-loop for high-risk decisions | Class B actions require approval_token | Live |
|
||||||
|
| SDAIA-C03 | Bias monitoring for Arabic NLP | Arabic NLP includes dialect detection | Partial |
|
||||||
|
| SDAIA-C04 | AI model documentation | Agent Map (`docs/AGENT-MAP.md`) documents all agents | Live |
|
||||||
|
| SDAIA-C05 | AI governance registration | Not yet registered | Planned |
|
||||||
|
| SDAIA-C06 | Responsible AI usage policy | Documented in AGENTS.md policy classes | Live |
|
||||||
|
| SDAIA-C07 | AI output quality monitoring | `conversation_qa_reviewer` agent | Live |
|
||||||
|
| SDAIA-C08 | Model performance tracking | `observability.py` tracks latency/errors | Live |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. NCA — National Cybersecurity Authority
|
||||||
|
|
||||||
|
**Authority**: NCA
|
||||||
|
**Framework**: Essential Cybersecurity Controls (ECC)
|
||||||
|
|
||||||
|
### Control Matrix
|
||||||
|
|
||||||
|
| Control ID | Control | Implementation | Status |
|
||||||
|
|-----------|---------|----------------|--------|
|
||||||
|
| NCA-C01 | Access control (RBAC) | JWT + role-based middleware | Live |
|
||||||
|
| NCA-C02 | Multi-tenant isolation | `tenant_id` scoping at ORM layer | Live |
|
||||||
|
| NCA-C03 | Authentication (MFA) | JWT auth live, MFA planned | Partial |
|
||||||
|
| NCA-C04 | Audit logging | `audit_log.py` — all state changes | Live |
|
||||||
|
| NCA-C05 | Incident response procedure | Documented in runbooks | Documented |
|
||||||
|
| NCA-C06 | Data residency (KSA) | Deployment target: Saudi data centers | Planned |
|
||||||
|
| NCA-C07 | Vulnerability management | `shannon_security.py` scanning | Live |
|
||||||
|
| NCA-C08 | Secure development lifecycle | CI/CD with tests, security checks | Live |
|
||||||
|
| NCA-C09 | Secrets management | Environment variables, never in code | Live |
|
||||||
|
| NCA-C10 | Network segmentation | Docker network isolation | Live |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Sector-Specific Regulations
|
||||||
|
|
||||||
|
### Real Estate
|
||||||
|
| Control | Status |
|
||||||
|
|---------|--------|
|
||||||
|
| Brokerage license verification | Planned |
|
||||||
|
| REGA (Real Estate General Authority) compliance | Planned |
|
||||||
|
| Commission disclosure requirements | Live (commission models) |
|
||||||
|
|
||||||
|
### Healthcare
|
||||||
|
| Control | Status |
|
||||||
|
|---------|--------|
|
||||||
|
| Patient data classification | Planned |
|
||||||
|
| MOH (Ministry of Health) data standards | Planned |
|
||||||
|
| Telemedicine regulations | Not applicable |
|
||||||
|
|
||||||
|
### Financial Services
|
||||||
|
| Control | Status |
|
||||||
|
|---------|--------|
|
||||||
|
| SAMA (Saudi Central Bank) reporting | Planned |
|
||||||
|
| AML/KYC integration | Planned |
|
||||||
|
| Payment card data (PCI-DSS posture) | Stripe handles (plugin) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Data Residency & Transfer
|
||||||
|
|
||||||
|
| Requirement | Implementation | Status |
|
||||||
|
|------------|----------------|--------|
|
||||||
|
| Data stored in KSA | Target: Saudi cloud region | Planned |
|
||||||
|
| Cross-border transfer approval | Approval gate (Class B) | Designed |
|
||||||
|
| Data classification labels | Not implemented | Planned |
|
||||||
|
| Retention policies | Consent: 12 months auto-expire | Live (consent) |
|
||||||
|
| Right to erasure fulfillment | `pdpl/data_rights.py` | Live |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Arabic-First Compliance
|
||||||
|
|
||||||
|
All compliance-related content must be available in Arabic:
|
||||||
|
|
||||||
|
| Content | Arabic Version | Status |
|
||||||
|
|---------|---------------|--------|
|
||||||
|
| Privacy Policy | `docs/legal/privacy-policy-ar.md` | Live |
|
||||||
|
| Data Protection | `docs/legal/data-protection-ar.md` | Live |
|
||||||
|
| Consent Policy | `docs/legal/consent-policy-ar.md` | Live |
|
||||||
|
| Terms of Service | `docs/legal/terms-of-service-ar.md` | Live |
|
||||||
|
| Affiliate Rules | `docs/legal/affiliate-rules-ar.md` | Live |
|
||||||
|
| Commission Policy | `docs/legal/commission-policy-ar.md` | Live |
|
||||||
|
| Refund Policy | `docs/legal/refund-policy-ar.md` | Live |
|
||||||
|
| Compliance Dashboard | Frontend component | Building |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. Live Compliance Matrix API
|
||||||
|
|
||||||
|
The Saudi Compliance Matrix is a live, queryable control system (not a static checklist).
|
||||||
|
|
||||||
|
**API Endpoints**:
|
||||||
|
- `GET /api/v1/compliance/matrix` — All controls with status
|
||||||
|
- `POST /api/v1/compliance/matrix/scan` — Run all live checks
|
||||||
|
- `GET /api/v1/compliance/matrix/{control_id}` — Control detail
|
||||||
|
- `GET /api/v1/compliance/risk-heatmap` — Category × severity matrix
|
||||||
|
|
||||||
|
**Live Checks**:
|
||||||
|
- PDPL consent coverage rate
|
||||||
|
- ZATCA invoice compliance rate
|
||||||
|
- Audit trail completeness
|
||||||
|
- Approval SLA compliance
|
||||||
|
- Secrets exposure scan
|
||||||
|
- Cross-tenant isolation test
|
||||||
|
|
||||||
|
Implementation: `services/saudi_compliance_matrix.py`, `models/compliance_control.py`
|
||||||
126
salesflow-saas/docs/governance/technology-radar-tier1.md
Normal file
126
salesflow-saas/docs/governance/technology-radar-tier1.md
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
# Technology Radar — Tier 1
|
||||||
|
|
||||||
|
> **Parent**: [`MASTER_OPERATING_PROMPT.md`](../../MASTER_OPERATING_PROMPT.md)
|
||||||
|
> **Plane**: Operating | **Tracks**: Operations, Intelligence
|
||||||
|
> **Version**: 1.0 | **Status**: Canonical
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The Technology Radar classifies every technology Dealix uses or considers. Classification determines governance, investment, and documentation requirements.
|
||||||
|
|
||||||
|
**Review cadence**: Quarterly
|
||||||
|
**Promotion/demotion**: Requires ADR with evidence
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Core — Production, Non-Negotiable
|
||||||
|
|
||||||
|
These technologies are in production and foundational. Removing any of them would require a major architectural decision.
|
||||||
|
|
||||||
|
| Technology | Version | Purpose | Plane |
|
||||||
|
|-----------|---------|---------|-------|
|
||||||
|
| **FastAPI** | 0.115.x | Backend API framework | Execution |
|
||||||
|
| **SQLAlchemy** | 2.0.x | Async ORM | Data |
|
||||||
|
| **PostgreSQL** | 16 | Primary database | Data |
|
||||||
|
| **asyncpg** | 0.30.x | Async PostgreSQL driver | Data |
|
||||||
|
| **pgvector** | 0.3.x | Vector embeddings for RAG | Data |
|
||||||
|
| **Redis** | 7 | Cache + task broker | Data |
|
||||||
|
| **Celery** | 5.x | Async task queue | Execution |
|
||||||
|
| **Next.js** | 15.x | Frontend framework | Decision |
|
||||||
|
| **TypeScript** | 5.7 | Frontend type safety | Decision |
|
||||||
|
| **Tailwind CSS** | 3.4 | Styling | Decision |
|
||||||
|
| **OpenClaw** | 2026.4.x | Durable execution engine | Execution |
|
||||||
|
| **Groq** | 0.12.x | Primary LLM (fast, Arabic) | Intelligence |
|
||||||
|
| **WhatsApp Cloud API** | - | Primary communication channel | Execution |
|
||||||
|
| **Pydantic** | 2.10.x | Data validation | All |
|
||||||
|
| **Alembic** | 1.14.x | Database migrations | Data |
|
||||||
|
| **Docker Compose** | - | Container orchestration | Operating |
|
||||||
|
| **GitHub Actions** | - | CI/CD | Operating |
|
||||||
|
| **JWT (PyJWT)** | - | Authentication | Trust |
|
||||||
|
| **StructLog** | 24.x | Structured logging | Operating |
|
||||||
|
| **pytest** | - | Testing framework | Operating |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Strong — Validated, Deploying or Near-Ready
|
||||||
|
|
||||||
|
These have been validated and are either deployed or actively being integrated.
|
||||||
|
|
||||||
|
| Technology | Version | Purpose | Plane | Evidence |
|
||||||
|
|-----------|---------|---------|-------|----------|
|
||||||
|
| **Claude Opus** | 4.6 | Strategic LLM (via model_router) | Intelligence | Configured in model_router.py |
|
||||||
|
| **OpenAI** | 2.8.x | Fallback LLM | Intelligence | Configured as fallback |
|
||||||
|
| **Salesforce Agentforce** | - | CRM sync | Data | Plugin exists in openclaw/plugins/ |
|
||||||
|
| **Stripe** | - | Payment processing | Execution | Plugin + service exist |
|
||||||
|
| **LiteLLM** | 1.74.x | Multi-provider abstraction | Intelligence | In requirements.txt |
|
||||||
|
| **Instructor** | 1.14.x | Structured LLM outputs | Intelligence | In requirements.txt |
|
||||||
|
| **LangChain** | - | Chain orchestration | Execution | In requirements.txt |
|
||||||
|
| **LangGraph** | 0.2.x | Workflow graphs | Execution | In requirements.txt |
|
||||||
|
| **CrewAI** | - | Multi-agent coordination | Execution | In requirements.txt |
|
||||||
|
| **Mem0** | - | Agent long-term memory | Data | In requirements.txt |
|
||||||
|
| **Sentry** | 2.x | Error tracking | Operating | In requirements.txt |
|
||||||
|
| **Prometheus** | - | Metrics | Operating | In requirements.txt |
|
||||||
|
| **CAMEL-Tools** | 1.5.x | Arabic NLP | Intelligence | In requirements.txt |
|
||||||
|
| **WeasyPrint** | 60.x | PDF generation (Arabic RTL) | Execution | In requirements.txt |
|
||||||
|
| **Playwright** | - | E2E testing | Operating | In frontend package.json |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Pilot — Experimenting, Behind Feature Flags
|
||||||
|
|
||||||
|
These are being tested but not committed to. Usage is limited and behind feature flags.
|
||||||
|
|
||||||
|
| Technology | Purpose | Plane | Notes |
|
||||||
|
|-----------|---------|-------|-------|
|
||||||
|
| **Voice Agents** (Twilio) | Voice call integration | Execution | Plugin exists, limited testing |
|
||||||
|
| **Contract Intelligence** | Contract analysis | Intelligence | Plugin exists, early stage |
|
||||||
|
| **Gemini** | Alternative LLM routing | Intelligence | In model_router config |
|
||||||
|
| **DeepSeek** | Coding assistance routing | Intelligence | In model_router config |
|
||||||
|
| **DocuSign/Adobe Sign** | E-signatures | Execution | Env vars defined, not live |
|
||||||
|
| **cal.com** | Meeting booking | Execution | Integration path defined |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Watch — Evaluating, No Code Yet
|
||||||
|
|
||||||
|
These are being evaluated for future adoption. No production code exists.
|
||||||
|
|
||||||
|
| Technology | Purpose | Evaluation Criteria |
|
||||||
|
|-----------|---------|-------------------|
|
||||||
|
| **Temporal** | Long-running durable workflows | Compare vs OpenClaw durable_flow |
|
||||||
|
| **OPA** | Policy engine | Compare vs openclaw/policy.py |
|
||||||
|
| **OpenFGA** | Authorization graph | Compare vs RBAC + tenant isolation |
|
||||||
|
| **Vault** | Secrets management | Compare vs env vars |
|
||||||
|
| **Keycloak** | Identity provider | Compare vs JWT auth |
|
||||||
|
| **Gong** | Revenue intelligence | API integration feasibility |
|
||||||
|
| **Apollo** | Lead enrichment | Data quality evaluation |
|
||||||
|
| **HubSpot** | CRM alternative | Env var defined, not active |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Hold — Explicitly Not Adopting
|
||||||
|
|
||||||
|
These have been evaluated and rejected for Dealix.
|
||||||
|
|
||||||
|
| Technology | Reason for Rejection |
|
||||||
|
|-----------|---------------------|
|
||||||
|
| **External RAG SaaS** (Onyx, etc.) | Policy: PostgreSQL + pgvector + KnowledgeService only |
|
||||||
|
| **Schema-per-tenant** | Unnecessary complexity; row-level isolation sufficient |
|
||||||
|
| **GraphQL** | REST + structured outputs adequate; GraphQL adds complexity |
|
||||||
|
| **MongoDB** | PostgreSQL covers all use cases including JSON (JSONB) |
|
||||||
|
| **Firebase** | Not suitable for Saudi data residency requirements |
|
||||||
|
| **Supabase** | PostgreSQL self-hosted preferred for control |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Governance Rules
|
||||||
|
|
||||||
|
1. **No technology enters Core without 90 days in Strong** and a passing ADR.
|
||||||
|
2. **No technology enters Strong without a Pilot** demonstrating value.
|
||||||
|
3. **Pilot technologies must have feature flags** and can be disabled without downtime.
|
||||||
|
4. **Watch technologies have no code** — only evaluation documents.
|
||||||
|
5. **Hold decisions are permanent** unless a new ADR overturns them with evidence.
|
||||||
|
6. **pgvector security patches** must be applied within 7 days of release.
|
||||||
|
7. **LLM provider diversity** is maintained — never depend on a single provider.
|
||||||
199
salesflow-saas/docs/governance/trust-fabric.md
Normal file
199
salesflow-saas/docs/governance/trust-fabric.md
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
# Trust Fabric — Dealix Trust Plane Deep Dive
|
||||||
|
|
||||||
|
> **Parent**: [`MASTER_OPERATING_PROMPT.md`](../../MASTER_OPERATING_PROMPT.md)
|
||||||
|
> **Plane**: Trust | **Tracks**: Trust, Compliance
|
||||||
|
> **Version**: 1.0 | **Status**: Canonical
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The Trust Fabric ensures that every action in Dealix is authorized, auditable, and compliant. No sensitive action bypasses this layer. The Trust Plane sits between the Decision Plane and the Execution Plane, intercepting every Class B and C action.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────┐
|
||||||
|
│ TRUST PLANE │
|
||||||
|
│ │
|
||||||
|
│ ┌─────────┐ ┌──────────────────┐ │
|
||||||
|
│ │ Policy │ │ Approval Bridge │ │
|
||||||
|
│ │ Engine │──│ (approval_bridge)│ │
|
||||||
|
│ │(policy) │ └────────┬─────────┘ │
|
||||||
|
│ └─────────┘ │ │
|
||||||
|
│ ▼ │
|
||||||
|
│ ┌──────────────────────────────┐ │
|
||||||
|
│ │ Trust Score Service │ │
|
||||||
|
│ │ (trust_score_service.py) │ │
|
||||||
|
│ └──────────────────────────────┘ │
|
||||||
|
│ │
|
||||||
|
│ ┌─────────┐ ┌──────────────────┐ │
|
||||||
|
│ │Security │ │ SLA Escalation │ │
|
||||||
|
│ │ Gate │ │ Alerts │ │
|
||||||
|
│ └─────────┘ └──────────────────┘ │
|
||||||
|
│ │
|
||||||
|
│ ┌─────────┐ ┌──────────────────┐ │
|
||||||
|
│ │ Audit │ │ Contradiction │ │
|
||||||
|
│ │ Service │ │ Engine │ │
|
||||||
|
│ └─────────┘ └──────────────────┘ │
|
||||||
|
│ │
|
||||||
|
│ ┌─────────┐ ┌──────────────────┐ │
|
||||||
|
│ │ PDPL │ │ Evidence │ │
|
||||||
|
│ │ Engine │ │ Pack Service │ │
|
||||||
|
│ └─────────┘ └──────────────────┘ │
|
||||||
|
└─────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Policy Enforcement
|
||||||
|
|
||||||
|
### Approval Bridge Flow
|
||||||
|
```python
|
||||||
|
# OpenClawApprovalBridge.evaluate()
|
||||||
|
1. Check tenant_id exists → Block if missing
|
||||||
|
2. Classify action (A/B/C) → Block if C (forbidden)
|
||||||
|
3. Check cross_tenant_context → Block if true
|
||||||
|
4. Check canary enforcement → Block if outside canary without token
|
||||||
|
5. Check approval_token → Block if B and no token
|
||||||
|
6. Allow execution → Return allowed=True
|
||||||
|
```
|
||||||
|
|
||||||
|
### Approval Request Model
|
||||||
|
| Field | Type | Purpose |
|
||||||
|
|-------|------|---------|
|
||||||
|
| `channel` | String | whatsapp, email, sms |
|
||||||
|
| `resource_type` | String | Entity requiring approval |
|
||||||
|
| `resource_id` | UUID | Entity ID |
|
||||||
|
| `payload` | JSONB | Action details |
|
||||||
|
| `status` | String | pending → approved / rejected |
|
||||||
|
| `requested_by_id` | FK(users) | Who requested |
|
||||||
|
| `reviewed_by_id` | FK(users) | Who approved/rejected |
|
||||||
|
| `reviewed_at` | DateTime | When reviewed |
|
||||||
|
| `sla_deadline_at` | DateTime | SLA expiry (new) |
|
||||||
|
| `escalation_level` | Integer | Current escalation level (new) |
|
||||||
|
| `priority` | String | critical/high/normal/low (new) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Trust Scoring
|
||||||
|
|
||||||
|
Entities receive trust scores based on behavior:
|
||||||
|
|
||||||
|
| Entity | Factors | Range |
|
||||||
|
|--------|---------|-------|
|
||||||
|
| Lead | Engagement, data quality, consent status | 0-100 |
|
||||||
|
| Affiliate | Performance, fraud flags, tenure | 0-100 |
|
||||||
|
| Company | CR verification, payment history | 0-100 |
|
||||||
|
| Connector | Uptime, error rate, auth health | 0-100 |
|
||||||
|
|
||||||
|
Implementation: `services/trust_score_service.py`, `models/advanced.py (TrustScore)`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Audit Trail
|
||||||
|
|
||||||
|
Every state change is recorded:
|
||||||
|
|
||||||
|
```python
|
||||||
|
class AuditLog(TenantModel):
|
||||||
|
user_id # Who performed the action
|
||||||
|
action # What action (create, update, delete, approve, reject)
|
||||||
|
entity_type # What entity (lead, deal, consent, approval)
|
||||||
|
entity_id # Which entity
|
||||||
|
changes # JSONB diff (old_value → new_value)
|
||||||
|
ip_address # Client IP
|
||||||
|
```
|
||||||
|
|
||||||
|
Additional audit layers:
|
||||||
|
- `PDPLConsentAudit` — Immutable consent change log
|
||||||
|
- `DomainEvent` — Event-sourced business events
|
||||||
|
- `ai_conversations` — All AI agent inputs/outputs/tokens
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Contradiction Engine (New)
|
||||||
|
|
||||||
|
Detects and tracks conflicts between documents, policies, and system behavior.
|
||||||
|
|
||||||
|
### Contradiction Record
|
||||||
|
| Field | Purpose |
|
||||||
|
|-------|---------|
|
||||||
|
| `source_a` / `source_b` | Which documents/systems conflict |
|
||||||
|
| `claim_a` / `claim_b` | The conflicting claims |
|
||||||
|
| `contradiction_type` | factual, temporal, scope, policy |
|
||||||
|
| `severity` | critical, high, medium, low |
|
||||||
|
| `status` | detected → reviewing → resolved / accepted |
|
||||||
|
| `resolution` | How it was resolved |
|
||||||
|
| `evidence` | Supporting data (JSONB) |
|
||||||
|
|
||||||
|
### Detection Methods
|
||||||
|
1. **Manual**: Human reports contradiction
|
||||||
|
2. **AI Scan**: LLM compares governance docs for conflicts
|
||||||
|
3. **Runtime**: System detects behavior inconsistent with policy
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Evidence Pack System (New)
|
||||||
|
|
||||||
|
Assembles auditable proof from system data:
|
||||||
|
|
||||||
|
### Pack Types
|
||||||
|
| Type | Contents |
|
||||||
|
|------|----------|
|
||||||
|
| `deal_closure` | Deal data, lead history, activities, messages, proposals, approvals, consent records |
|
||||||
|
| `compliance_audit` | Consent stats, PDPL checks, audit logs, complaint resolutions |
|
||||||
|
| `board_report` | KPIs, pipeline, revenue, risks, strategic deals |
|
||||||
|
| `incident_response` | Event timeline, actions taken, impact assessment |
|
||||||
|
|
||||||
|
### Pack Properties
|
||||||
|
- **Immutable**: Once assembled, contents are SHA256-hashed
|
||||||
|
- **Tamper-evident**: Hash signature stored for verification
|
||||||
|
- **Exportable**: JSON + PDF formats
|
||||||
|
- **Traceable**: Every item links to source record
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## SLA Enforcement
|
||||||
|
|
||||||
|
| Level | Threshold | Action |
|
||||||
|
|-------|-----------|--------|
|
||||||
|
| Warning | 75% of SLA elapsed | Notify assignee |
|
||||||
|
| Breach | 100% of SLA elapsed | Escalate to manager |
|
||||||
|
| L3 Escalation | 150% of SLA elapsed | Escalate to executive |
|
||||||
|
|
||||||
|
Implementation: `services/sla_escalation_alerts.py`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Security Layers
|
||||||
|
|
||||||
|
| Layer | Component | Purpose |
|
||||||
|
|-------|-----------|---------|
|
||||||
|
| Pre-release | `security_gate.py` | Validate before deployment |
|
||||||
|
| Runtime | `shannon_security.py` | Deep security scanning |
|
||||||
|
| Outbound | `outbound_governance.py` | Govern external communications |
|
||||||
|
| Tool | `tool_verification.py` | Verify tool integrity |
|
||||||
|
| Skill | `skill_governance.py` | Govern agent skill usage |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Current vs Target
|
||||||
|
|
||||||
|
| Capability | Current | Target |
|
||||||
|
|-----------|---------|--------|
|
||||||
|
| Policy classes (A/B/C) | Live | Live |
|
||||||
|
| Approval bridge | Live | Enhanced with SLA |
|
||||||
|
| Trust scoring | Live | Live |
|
||||||
|
| Audit trail | Live | Live |
|
||||||
|
| PDPL consent enforcement | Live | Live |
|
||||||
|
| Security gate | Live | Live |
|
||||||
|
| Contradiction Engine | Not implemented | Building |
|
||||||
|
| Evidence Pack System | Not implemented | Building |
|
||||||
|
| Saudi Compliance Matrix | Not implemented | Building |
|
||||||
|
| OPA policy engine | Not evaluated | Watch |
|
||||||
|
| OpenFGA authorization | Not evaluated | Watch |
|
||||||
|
| Vault secrets management | Not evaluated | Watch |
|
||||||
|
| Keycloak identity | Not evaluated | Watch |
|
||||||
@ -0,0 +1,63 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
type TrackForecast = {
|
||||||
|
actual: number; forecast: number; variance: number;
|
||||||
|
variance_percent?: number; unit: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type UnifiedForecast = {
|
||||||
|
revenue: TrackForecast;
|
||||||
|
partnerships: { actual_count: number; target_count: number; variance: number; unit: string };
|
||||||
|
ma: { deals_in_progress: number; pipeline_target: number; variance: number; unit: string };
|
||||||
|
expansion: { markets_launched: number; markets_planned: number; variance: number; unit: string };
|
||||||
|
};
|
||||||
|
|
||||||
|
function TrackRow({ label, labelAr, actual, target, variance, unit }: {
|
||||||
|
label: string; labelAr: string; actual: number; target: number; variance: number; unit: string;
|
||||||
|
}) {
|
||||||
|
const pct = target > 0 ? Math.round((actual / target) * 100) : 0;
|
||||||
|
const color = pct >= 90 ? "text-emerald-500" : pct >= 70 ? "text-yellow-500" : "text-red-500";
|
||||||
|
return (
|
||||||
|
<div className="glass-card p-4 border border-border/40">
|
||||||
|
<div className="flex justify-between items-center mb-2">
|
||||||
|
<span className={`text-lg font-bold ${color}`}>{pct}%</span>
|
||||||
|
<div className="text-right">
|
||||||
|
<span className="font-semibold">{labelAr}</span>
|
||||||
|
<span className="text-xs text-muted-foreground block">{label}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="w-full bg-border/20 rounded-full h-2 mb-2">
|
||||||
|
<div className={`h-2 rounded-full ${pct >= 90 ? "bg-emerald-500" : pct >= 70 ? "bg-yellow-500" : "bg-red-500"}`} style={{ width: `${Math.min(100, pct)}%` }} />
|
||||||
|
</div>
|
||||||
|
<div className="flex justify-between text-xs text-muted-foreground">
|
||||||
|
<span>الانحراف: {variance} {unit}</span>
|
||||||
|
<span>الفعلي: {actual.toLocaleString()} | الهدف: {target.toLocaleString()} {unit}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ActualVsForecastDashboard({ data }: { data?: UnifiedForecast }) {
|
||||||
|
const d = data || {
|
||||||
|
revenue: { actual: 0, forecast: 0, variance: 0, variance_percent: 0, unit: "SAR" },
|
||||||
|
partnerships: { actual_count: 0, target_count: 0, variance: 0, unit: "partners" },
|
||||||
|
ma: { deals_in_progress: 0, pipeline_target: 0, variance: 0, unit: "deals" },
|
||||||
|
expansion: { markets_launched: 0, markets_planned: 0, variance: 0, unit: "markets" },
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="space-y-4 p-6" dir="rtl">
|
||||||
|
<div className="flex justify-between items-center">
|
||||||
|
<button className="text-xs px-3 py-1 rounded border border-border/40 hover:border-primary/40">إعادة المعايرة</button>
|
||||||
|
<h2 className="text-xl font-bold text-right">الفعلي مقابل التوقعات | Actual vs Forecast</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-3">
|
||||||
|
<TrackRow label="Revenue" labelAr="الإيرادات" actual={d.revenue.actual} target={d.revenue.forecast} variance={d.revenue.variance} unit={d.revenue.unit} />
|
||||||
|
<TrackRow label="Partnerships" labelAr="الشراكات" actual={d.partnerships.actual_count} target={d.partnerships.target_count} variance={d.partnerships.variance} unit={d.partnerships.unit} />
|
||||||
|
<TrackRow label="M&A Deals" labelAr="صفقات الاستحواذ" actual={d.ma.deals_in_progress} target={d.ma.pipeline_target} variance={d.ma.variance} unit={d.ma.unit} />
|
||||||
|
<TrackRow label="Expansion" labelAr="التوسع" actual={d.expansion.markets_launched} target={d.expansion.markets_planned} variance={d.expansion.variance} unit={d.expansion.unit} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -0,0 +1,100 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
|
type Approval = {
|
||||||
|
id: string; channel: string; resource_type: string;
|
||||||
|
status: string; priority: string; category: string;
|
||||||
|
sla_deadline_at?: string; escalation_level: number;
|
||||||
|
note?: string; requested_by?: string; created_at?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
function SlaTimer({ deadline }: { deadline?: string }) {
|
||||||
|
if (!deadline) return <span className="text-xs text-muted-foreground">—</span>;
|
||||||
|
const remaining = new Date(deadline).getTime() - Date.now();
|
||||||
|
const hours = Math.max(0, Math.floor(remaining / 3600000));
|
||||||
|
const color = hours <= 1 ? "text-red-500" : hours <= 4 ? "text-yellow-500" : "text-emerald-500";
|
||||||
|
return <span className={`text-sm font-bold ${color}`}>{hours}h</span>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const PRIORITY_COLORS: Record<string, string> = {
|
||||||
|
critical: "bg-red-500/20 text-red-500",
|
||||||
|
high: "bg-orange-500/20 text-orange-500",
|
||||||
|
normal: "bg-blue-500/20 text-blue-500",
|
||||||
|
low: "bg-gray-500/20 text-gray-400",
|
||||||
|
};
|
||||||
|
|
||||||
|
export function ApprovalCenter({ approvals = [] }: { approvals?: Approval[] }) {
|
||||||
|
const [filter, setFilter] = useState<string>("all");
|
||||||
|
|
||||||
|
const filtered = filter === "all" ? approvals : approvals.filter((a) => a.category === filter);
|
||||||
|
const categories = ["all", ...new Set(approvals.map((a) => a.category))];
|
||||||
|
|
||||||
|
const stats = {
|
||||||
|
pending: approvals.filter((a) => a.status === "pending").length,
|
||||||
|
warning: approvals.filter((a) => a.escalation_level === 1).length,
|
||||||
|
breach: approvals.filter((a) => a.escalation_level >= 2).length,
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="space-y-4 p-6" dir="rtl">
|
||||||
|
<h2 className="text-xl font-bold text-right">مركز الموافقات | Approval Center</h2>
|
||||||
|
|
||||||
|
{/* Stats */}
|
||||||
|
<div className="grid grid-cols-3 gap-3">
|
||||||
|
<div className="glass-card p-3 border border-border/40 text-center">
|
||||||
|
<div className="text-xs text-muted-foreground">معلقة</div>
|
||||||
|
<div className="text-xl font-bold">{stats.pending}</div>
|
||||||
|
</div>
|
||||||
|
<div className="glass-card p-3 border border-border/40 text-center">
|
||||||
|
<div className="text-xs text-muted-foreground">تحذير SLA</div>
|
||||||
|
<div className="text-xl font-bold text-yellow-500">{stats.warning}</div>
|
||||||
|
</div>
|
||||||
|
<div className="glass-card p-3 border border-border/40 text-center">
|
||||||
|
<div className="text-xs text-muted-foreground">خرق SLA</div>
|
||||||
|
<div className="text-xl font-bold text-red-500">{stats.breach}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Filters */}
|
||||||
|
<div className="flex gap-2 flex-wrap">
|
||||||
|
{categories.map((cat) => (
|
||||||
|
<button
|
||||||
|
key={cat}
|
||||||
|
onClick={() => setFilter(cat)}
|
||||||
|
className={`text-xs px-3 py-1 rounded-full border ${filter === cat ? "bg-primary text-primary-foreground" : "border-border/40"}`}
|
||||||
|
>
|
||||||
|
{cat === "all" ? "الكل" : cat}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Approval Queue */}
|
||||||
|
<div className="space-y-2">
|
||||||
|
{filtered.length === 0 && (
|
||||||
|
<p className="text-sm text-muted-foreground text-center py-8">لا توجد موافقات معلقة</p>
|
||||||
|
)}
|
||||||
|
{filtered.map((approval) => (
|
||||||
|
<div key={approval.id} className="glass-card p-4 border border-border/40">
|
||||||
|
<div className="flex justify-between items-start">
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<button className="text-xs px-3 py-1 rounded bg-emerald-500/20 text-emerald-500 hover:bg-emerald-500/30">موافقة</button>
|
||||||
|
<button className="text-xs px-3 py-1 rounded bg-red-500/20 text-red-500 hover:bg-red-500/30">رفض</button>
|
||||||
|
</div>
|
||||||
|
<div className="text-right">
|
||||||
|
<div className="flex items-center gap-2 justify-end">
|
||||||
|
<SlaTimer deadline={approval.sla_deadline_at} />
|
||||||
|
<span className={`text-xs px-2 py-0.5 rounded ${PRIORITY_COLORS[approval.priority] || ""}`}>
|
||||||
|
{approval.priority}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<p className="text-sm font-medium mt-1">{approval.resource_type}</p>
|
||||||
|
<p className="text-xs text-muted-foreground">{approval.channel} — {approval.category}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -0,0 +1,58 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
type Connector = {
|
||||||
|
connector_key: string; display_name: string; display_name_ar: string;
|
||||||
|
status: string; last_success_at: string | null; last_error: string | null; registered: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
const STATUS_STYLES: Record<string, { bg: string; text: string; label: string; labelAr: string }> = {
|
||||||
|
ok: { bg: "bg-emerald-500/20", text: "text-emerald-500", label: "Healthy", labelAr: "سليم" },
|
||||||
|
degraded: { bg: "bg-yellow-500/20", text: "text-yellow-500", label: "Degraded", labelAr: "متراجع" },
|
||||||
|
error: { bg: "bg-red-500/20", text: "text-red-500", label: "Error", labelAr: "خطأ" },
|
||||||
|
unknown: { bg: "bg-gray-500/20", text: "text-gray-400", label: "Unknown", labelAr: "غير معروف" },
|
||||||
|
not_configured: { bg: "bg-gray-500/10", text: "text-gray-400", label: "Not Configured", labelAr: "غير مهيأ" },
|
||||||
|
};
|
||||||
|
|
||||||
|
export function ConnectorGovernanceBoard({ connectors = [] }: { connectors?: Connector[] }) {
|
||||||
|
return (
|
||||||
|
<div className="space-y-4 p-6" dir="rtl">
|
||||||
|
<h2 className="text-xl font-bold text-right">لوحة حوكمة الموصلات | Connector Governance Board</h2>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||||
|
{connectors.map((conn) => {
|
||||||
|
const style = STATUS_STYLES[conn.status] || STATUS_STYLES.unknown;
|
||||||
|
return (
|
||||||
|
<div key={conn.connector_key} className="glass-card p-4 border border-border/40">
|
||||||
|
<div className="flex justify-between items-start">
|
||||||
|
<span className={`text-xs px-2 py-1 rounded ${style.bg} ${style.text}`}>{style.labelAr}</span>
|
||||||
|
<div className="text-right">
|
||||||
|
<h3 className="font-semibold">{conn.display_name_ar}</h3>
|
||||||
|
<p className="text-xs text-muted-foreground">{conn.display_name}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="mt-3 space-y-1 text-xs text-muted-foreground">
|
||||||
|
{conn.last_success_at && (
|
||||||
|
<div className="flex justify-between">
|
||||||
|
<span>{new Date(conn.last_success_at).toLocaleDateString("ar-SA")}</span>
|
||||||
|
<span>آخر نجاح</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{conn.last_error && (
|
||||||
|
<div className="text-red-400 truncate mt-1">{conn.last_error}</div>
|
||||||
|
)}
|
||||||
|
{!conn.registered && (
|
||||||
|
<div className="text-center mt-2">
|
||||||
|
<button className="text-xs px-3 py-1 rounded border border-border/40 hover:border-primary/40">تهيئة الموصل</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
{connectors.length === 0 && (
|
||||||
|
<p className="text-sm text-muted-foreground col-span-full text-center py-8">لا توجد موصلات مسجلة</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -0,0 +1,82 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
|
type EvidenceItem = { type: string; source: string; data: Record<string, unknown>; timestamp?: string };
|
||||||
|
type EvidencePack = {
|
||||||
|
id: string; title: string; title_ar?: string; pack_type: string;
|
||||||
|
status: string; contents: EvidenceItem[]; hash_signature?: string;
|
||||||
|
created_at?: string; reviewed_at?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const TYPE_LABELS: Record<string, { en: string; ar: string }> = {
|
||||||
|
deal_closure: { en: "Deal Closure", ar: "إغلاق صفقة" },
|
||||||
|
compliance_audit: { en: "Compliance Audit", ar: "تدقيق الامتثال" },
|
||||||
|
quarterly_review: { en: "Quarterly Review", ar: "مراجعة ربعية" },
|
||||||
|
incident_response: { en: "Incident Response", ar: "استجابة للحوادث" },
|
||||||
|
board_report: { en: "Board Report", ar: "تقرير مجلس الإدارة" },
|
||||||
|
};
|
||||||
|
|
||||||
|
export function EvidencePackViewer({ packs = [] }: { packs?: EvidencePack[] }) {
|
||||||
|
const [selected, setSelected] = useState<EvidencePack | null>(null);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="space-y-4 p-6" dir="rtl">
|
||||||
|
<h2 className="text-xl font-bold text-right">عارض حزم الأدلة | Evidence Pack Viewer</h2>
|
||||||
|
|
||||||
|
{!selected ? (
|
||||||
|
<div className="space-y-3">
|
||||||
|
{packs.length === 0 && (
|
||||||
|
<p className="text-sm text-muted-foreground text-right">لا توجد حزم أدلة بعد</p>
|
||||||
|
)}
|
||||||
|
{packs.map((pack) => {
|
||||||
|
const typeInfo = TYPE_LABELS[pack.pack_type] || { en: pack.pack_type, ar: pack.pack_type };
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
key={pack.id}
|
||||||
|
onClick={() => setSelected(pack)}
|
||||||
|
className="w-full glass-card p-4 border border-border/40 text-right hover:border-primary/40 transition-colors"
|
||||||
|
>
|
||||||
|
<div className="flex justify-between items-center">
|
||||||
|
<span className={`text-xs px-2 py-1 rounded ${pack.status === "reviewed" ? "bg-emerald-500/20 text-emerald-500" : "bg-yellow-500/20 text-yellow-500"}`}>
|
||||||
|
{pack.status === "reviewed" ? "تمت المراجعة" : "جاهزة"}
|
||||||
|
</span>
|
||||||
|
<div>
|
||||||
|
<h3 className="font-semibold">{pack.title_ar || pack.title}</h3>
|
||||||
|
<p className="text-xs text-muted-foreground">{typeInfo.ar} — {typeInfo.en}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{pack.hash_signature && (
|
||||||
|
<p className="text-xs text-muted-foreground mt-2 font-mono truncate">SHA256: {pack.hash_signature}</p>
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="space-y-4">
|
||||||
|
<button onClick={() => setSelected(null)} className="text-sm text-primary hover:underline">← العودة للقائمة</button>
|
||||||
|
<div className="glass-card p-5 border border-border/40">
|
||||||
|
<h3 className="text-lg font-bold text-right">{selected.title_ar || selected.title}</h3>
|
||||||
|
<p className="text-sm text-muted-foreground">{TYPE_LABELS[selected.pack_type]?.ar || selected.pack_type}</p>
|
||||||
|
{selected.hash_signature && (
|
||||||
|
<div className="mt-2 p-2 rounded bg-emerald-500/10 text-xs font-mono">
|
||||||
|
تم التحقق من السلامة — SHA256: {selected.hash_signature}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="space-y-2">
|
||||||
|
{selected.contents.map((item, i) => (
|
||||||
|
<details key={i} className="glass-card border border-border/40">
|
||||||
|
<summary className="p-3 cursor-pointer text-right text-sm font-medium">
|
||||||
|
{item.type} — {item.source}
|
||||||
|
</summary>
|
||||||
|
<pre className="p-3 text-xs overflow-auto bg-black/5 rounded-b">{JSON.stringify(item.data, null, 2)}</pre>
|
||||||
|
</details>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
122
salesflow-saas/frontend/src/components/dealix/executive-room.tsx
Normal file
122
salesflow-saas/frontend/src/components/dealix/executive-room.tsx
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
|
type ExecutiveSnapshot = {
|
||||||
|
revenue: { actual: number; forecast: number; variance_percent: number; pipeline_value: number; win_rate: number };
|
||||||
|
approvals: { pending: number; warning: number; breach: number };
|
||||||
|
connectors: { healthy: number; degraded: number; error: number };
|
||||||
|
compliance: { compliant: number; partial: number; non_compliant: number; posture: string };
|
||||||
|
contradictions: { active: number; critical: number };
|
||||||
|
strategic_deals: { active: number; pipeline_value: number };
|
||||||
|
evidence_packs: { ready: number; pending_review: number };
|
||||||
|
};
|
||||||
|
|
||||||
|
function MetricCard({ label, labelAr, value, status }: { label: string; labelAr: string; value: string | number; status?: string }) {
|
||||||
|
const color = status === "danger" ? "text-red-500" : status === "warning" ? "text-yellow-500" : "text-emerald-500";
|
||||||
|
return (
|
||||||
|
<div className="rounded-lg border border-border/40 p-4 text-right">
|
||||||
|
<div className="text-xs text-muted-foreground">{labelAr}</div>
|
||||||
|
<div className="text-xs text-muted-foreground">{label}</div>
|
||||||
|
<div className={`text-2xl font-bold mt-1 ${color}`}>{value}</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ExecutiveRoom() {
|
||||||
|
const [snapshot, setSnapshot] = useState<ExecutiveSnapshot | null>(null);
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchSnapshot = async () => {
|
||||||
|
try {
|
||||||
|
const apiUrl = process.env.NEXT_PUBLIC_API_URL || "http://localhost:8000";
|
||||||
|
const res = await fetch(`${apiUrl}/api/v1/executive-room/snapshot`);
|
||||||
|
if (res.ok) setSnapshot(await res.json());
|
||||||
|
} catch { /* silent */ }
|
||||||
|
setLoading(false);
|
||||||
|
};
|
||||||
|
fetchSnapshot();
|
||||||
|
const interval = setInterval(fetchSnapshot, 30000);
|
||||||
|
return () => clearInterval(interval);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
if (loading) return <div className="text-center p-8 text-muted-foreground">جارٍ التحميل...</div>;
|
||||||
|
|
||||||
|
const s = snapshot || {
|
||||||
|
revenue: { actual: 0, forecast: 0, variance_percent: 0, pipeline_value: 0, win_rate: 0 },
|
||||||
|
approvals: { pending: 0, warning: 0, breach: 0 },
|
||||||
|
connectors: { healthy: 0, degraded: 0, error: 0 },
|
||||||
|
compliance: { compliant: 0, partial: 0, non_compliant: 0, posture: "unknown" },
|
||||||
|
contradictions: { active: 0, critical: 0 },
|
||||||
|
strategic_deals: { active: 0, pipeline_value: 0 },
|
||||||
|
evidence_packs: { ready: 0, pending_review: 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="space-y-6 p-6" dir="rtl">
|
||||||
|
<h1 className="text-2xl font-bold text-right">غرفة القيادة التنفيذية</h1>
|
||||||
|
<p className="text-sm text-muted-foreground text-right">Executive Room — نظرة شاملة على كل ما يحتاجه القائد التنفيذي</p>
|
||||||
|
|
||||||
|
{/* Revenue */}
|
||||||
|
<section className="glass-card p-5 border border-border/40">
|
||||||
|
<h2 className="text-lg font-semibold mb-3 text-right">الإيرادات | Revenue</h2>
|
||||||
|
<div className="grid grid-cols-2 md:grid-cols-4 gap-3">
|
||||||
|
<MetricCard label="Actual Revenue" labelAr="الإيراد الفعلي" value={`${s.revenue.actual.toLocaleString()} SAR`} />
|
||||||
|
<MetricCard label="Forecast" labelAr="التوقعات" value={`${s.revenue.forecast.toLocaleString()} SAR`} />
|
||||||
|
<MetricCard label="Variance" labelAr="الانحراف" value={`${s.revenue.variance_percent}%`} status={s.revenue.variance_percent < -10 ? "danger" : s.revenue.variance_percent < 0 ? "warning" : undefined} />
|
||||||
|
<MetricCard label="Win Rate" labelAr="معدل الفوز" value={`${s.revenue.win_rate}%`} />
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Approvals & Compliance */}
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
|
<section className="glass-card p-5 border border-border/40">
|
||||||
|
<h2 className="text-lg font-semibold mb-3 text-right">الموافقات | Approvals</h2>
|
||||||
|
<div className="grid grid-cols-3 gap-3">
|
||||||
|
<MetricCard label="Pending" labelAr="معلقة" value={s.approvals.pending} status={s.approvals.pending > 10 ? "warning" : undefined} />
|
||||||
|
<MetricCard label="SLA Warning" labelAr="تحذير SLA" value={s.approvals.warning} status={s.approvals.warning > 0 ? "warning" : undefined} />
|
||||||
|
<MetricCard label="SLA Breach" labelAr="خرق SLA" value={s.approvals.breach} status={s.approvals.breach > 0 ? "danger" : undefined} />
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="glass-card p-5 border border-border/40">
|
||||||
|
<h2 className="text-lg font-semibold mb-3 text-right">الامتثال | Compliance</h2>
|
||||||
|
<div className="grid grid-cols-3 gap-3">
|
||||||
|
<MetricCard label="Compliant" labelAr="ممتثل" value={s.compliance.compliant} />
|
||||||
|
<MetricCard label="Partial" labelAr="جزئي" value={s.compliance.partial} status={s.compliance.partial > 0 ? "warning" : undefined} />
|
||||||
|
<MetricCard label="Non-Compliant" labelAr="غير ممتثل" value={s.compliance.non_compliant} status={s.compliance.non_compliant > 0 ? "danger" : undefined} />
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Connectors & Contradictions */}
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||||
|
<section className="glass-card p-5 border border-border/40">
|
||||||
|
<h2 className="text-lg font-semibold mb-3 text-right">الموصلات | Connectors</h2>
|
||||||
|
<div className="space-y-2">
|
||||||
|
<div className="flex justify-between"><span className="text-sm">سليمة</span><span className="text-emerald-500 font-bold">{s.connectors.healthy}</span></div>
|
||||||
|
<div className="flex justify-between"><span className="text-sm">متراجعة</span><span className="text-yellow-500 font-bold">{s.connectors.degraded}</span></div>
|
||||||
|
<div className="flex justify-between"><span className="text-sm">معطلة</span><span className="text-red-500 font-bold">{s.connectors.error}</span></div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="glass-card p-5 border border-border/40">
|
||||||
|
<h2 className="text-lg font-semibold mb-3 text-right">التناقضات | Contradictions</h2>
|
||||||
|
<div className="space-y-2">
|
||||||
|
<div className="flex justify-between"><span className="text-sm">نشطة</span><span className="text-yellow-500 font-bold">{s.contradictions.active}</span></div>
|
||||||
|
<div className="flex justify-between"><span className="text-sm">حرجة</span><span className="text-red-500 font-bold">{s.contradictions.critical}</span></div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="glass-card p-5 border border-border/40">
|
||||||
|
<h2 className="text-lg font-semibold mb-3 text-right">الصفقات الاستراتيجية | Strategic Deals</h2>
|
||||||
|
<div className="space-y-2">
|
||||||
|
<div className="flex justify-between"><span className="text-sm">نشطة</span><span className="font-bold">{s.strategic_deals.active}</span></div>
|
||||||
|
<div className="flex justify-between"><span className="text-sm">قيمة الأنبوب</span><span className="font-bold">{s.strategic_deals.pipeline_value.toLocaleString()} SAR</span></div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -0,0 +1,73 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
type PartnerDeal = {
|
||||||
|
id: string; company_name: string; company_name_ar?: string;
|
||||||
|
deal_type: string; stage: string; estimated_value: number;
|
||||||
|
created_at: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const STAGES = [
|
||||||
|
{ key: "discovery", label: "استكشاف", en: "Discovery" },
|
||||||
|
{ key: "outreach", label: "تواصل", en: "Outreach" },
|
||||||
|
{ key: "negotiating", label: "تفاوض", en: "Negotiating" },
|
||||||
|
{ key: "term_sheet", label: "ورقة شروط", en: "Term Sheet" },
|
||||||
|
{ key: "due_diligence", label: "فحص العناية", en: "Due Diligence" },
|
||||||
|
{ key: "closed", label: "مغلق", en: "Closed" },
|
||||||
|
];
|
||||||
|
|
||||||
|
const STAGE_COLORS: Record<string, string> = {
|
||||||
|
discovery: "border-t-blue-500",
|
||||||
|
outreach: "border-t-indigo-500",
|
||||||
|
negotiating: "border-t-yellow-500",
|
||||||
|
term_sheet: "border-t-orange-500",
|
||||||
|
due_diligence: "border-t-purple-500",
|
||||||
|
closed: "border-t-emerald-500",
|
||||||
|
};
|
||||||
|
|
||||||
|
export function PartnerPipelineBoard({ deals = [] }: { deals?: PartnerDeal[] }) {
|
||||||
|
const byStage: Record<string, PartnerDeal[]> = {};
|
||||||
|
STAGES.forEach((s) => { byStage[s.key] = []; });
|
||||||
|
deals.forEach((d) => {
|
||||||
|
if (byStage[d.stage]) byStage[d.stage].push(d);
|
||||||
|
});
|
||||||
|
|
||||||
|
const totalValue = deals.reduce((sum, d) => sum + d.estimated_value, 0);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="space-y-4 p-6" dir="rtl">
|
||||||
|
<div className="flex justify-between items-center">
|
||||||
|
<div className="text-sm text-muted-foreground">
|
||||||
|
إجمالي الأنبوب: <span className="font-bold text-foreground">{totalValue.toLocaleString()} SAR</span>
|
||||||
|
</div>
|
||||||
|
<h2 className="text-xl font-bold">أنبوب الشراكات | Partner Pipeline</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-3">
|
||||||
|
{STAGES.map((stage) => {
|
||||||
|
const stageDeals = byStage[stage.key] || [];
|
||||||
|
const stageValue = stageDeals.reduce((sum, d) => sum + d.estimated_value, 0);
|
||||||
|
return (
|
||||||
|
<div key={stage.key} className="space-y-2">
|
||||||
|
<div className={`text-center p-2 rounded border-t-2 ${STAGE_COLORS[stage.key] || "border-t-gray-400"} bg-border/5`}>
|
||||||
|
<div className="text-xs font-semibold">{stage.label}</div>
|
||||||
|
<div className="text-xs text-muted-foreground">{stage.en}</div>
|
||||||
|
<div className="text-xs mt-1">{stageDeals.length} صفقة — {stageValue.toLocaleString()} SAR</div>
|
||||||
|
</div>
|
||||||
|
{stageDeals.map((deal) => (
|
||||||
|
<div key={deal.id} className="glass-card p-3 border border-border/40 text-right">
|
||||||
|
<p className="text-sm font-medium truncate">{deal.company_name_ar || deal.company_name}</p>
|
||||||
|
<p className="text-xs text-muted-foreground">{deal.deal_type}</p>
|
||||||
|
<p className="text-xs font-bold mt-1">{deal.estimated_value.toLocaleString()} SAR</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{deals.length === 0 && (
|
||||||
|
<p className="text-sm text-muted-foreground text-center py-8">لا توجد صفقات شراكات في الأنبوب</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -0,0 +1,82 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
type Violation = {
|
||||||
|
id: string; source: string; description: string;
|
||||||
|
severity: string; status: string; detected_at: string;
|
||||||
|
owner?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const SEVERITY_STYLES: Record<string, { bg: string; text: string; labelAr: string }> = {
|
||||||
|
critical: { bg: "bg-red-500/20", text: "text-red-500", labelAr: "حرج" },
|
||||||
|
high: { bg: "bg-orange-500/20", text: "text-orange-500", labelAr: "عالي" },
|
||||||
|
medium: { bg: "bg-yellow-500/20", text: "text-yellow-500", labelAr: "متوسط" },
|
||||||
|
low: { bg: "bg-gray-500/20", text: "text-gray-400", labelAr: "منخفض" },
|
||||||
|
};
|
||||||
|
|
||||||
|
const STATUS_LABELS: Record<string, string> = {
|
||||||
|
detected: "تم الاكتشاف",
|
||||||
|
reviewing: "قيد المراجعة",
|
||||||
|
resolved: "تم الحل",
|
||||||
|
accepted: "مقبول",
|
||||||
|
};
|
||||||
|
|
||||||
|
export function PolicyViolationsBoard({ violations = [] }: { violations?: Violation[] }) {
|
||||||
|
const active = violations.filter((v) => v.status === "detected" || v.status === "reviewing");
|
||||||
|
const resolved = violations.filter((v) => v.status === "resolved" || v.status === "accepted");
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="space-y-4 p-6" dir="rtl">
|
||||||
|
<h2 className="text-xl font-bold text-right">لوحة مخالفات السياسات | Policy Violations Board</h2>
|
||||||
|
|
||||||
|
{/* Summary */}
|
||||||
|
<div className="grid grid-cols-4 gap-3">
|
||||||
|
<div className="glass-card p-3 border border-border/40 text-center">
|
||||||
|
<div className="text-xs text-muted-foreground">الإجمالي</div>
|
||||||
|
<div className="text-xl font-bold">{violations.length}</div>
|
||||||
|
</div>
|
||||||
|
<div className="glass-card p-3 border border-border/40 text-center">
|
||||||
|
<div className="text-xs text-muted-foreground">نشطة</div>
|
||||||
|
<div className="text-xl font-bold text-yellow-500">{active.length}</div>
|
||||||
|
</div>
|
||||||
|
<div className="glass-card p-3 border border-border/40 text-center">
|
||||||
|
<div className="text-xs text-muted-foreground">حرجة</div>
|
||||||
|
<div className="text-xl font-bold text-red-500">{violations.filter((v) => v.severity === "critical" && (v.status === "detected" || v.status === "reviewing")).length}</div>
|
||||||
|
</div>
|
||||||
|
<div className="glass-card p-3 border border-border/40 text-center">
|
||||||
|
<div className="text-xs text-muted-foreground">محلولة</div>
|
||||||
|
<div className="text-xl font-bold text-emerald-500">{resolved.length}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Active Violations */}
|
||||||
|
{active.length > 0 && (
|
||||||
|
<section>
|
||||||
|
<h3 className="text-lg font-semibold mb-2 text-right">المخالفات النشطة</h3>
|
||||||
|
<div className="space-y-2">
|
||||||
|
{active.map((v) => {
|
||||||
|
const style = SEVERITY_STYLES[v.severity] || SEVERITY_STYLES.medium;
|
||||||
|
return (
|
||||||
|
<div key={v.id} className="glass-card p-4 border border-border/40">
|
||||||
|
<div className="flex justify-between items-start">
|
||||||
|
<span className="text-xs text-muted-foreground">{STATUS_LABELS[v.status] || v.status}</span>
|
||||||
|
<div className="text-right">
|
||||||
|
<div className="flex items-center gap-2 justify-end">
|
||||||
|
<span className={`text-xs px-2 py-0.5 rounded ${style.bg} ${style.text}`}>{style.labelAr}</span>
|
||||||
|
<span className="text-xs text-muted-foreground">{v.source}</span>
|
||||||
|
</div>
|
||||||
|
<p className="text-sm mt-1">{v.description}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{violations.length === 0 && (
|
||||||
|
<p className="text-sm text-muted-foreground text-center py-8">لا توجد مخالفات مسجلة</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -0,0 +1,73 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
type HeatmapData = Record<string, Record<string, number>>;
|
||||||
|
|
||||||
|
const CATEGORY_LABELS: Record<string, string> = {
|
||||||
|
pdpl: "PDPL",
|
||||||
|
zatca: "ZATCA",
|
||||||
|
sdaia: "SDAIA",
|
||||||
|
nca: "NCA",
|
||||||
|
sector_specific: "قطاعي",
|
||||||
|
revenue: "الإيرادات",
|
||||||
|
operations: "العمليات",
|
||||||
|
partners: "الشراكات",
|
||||||
|
};
|
||||||
|
|
||||||
|
const RISK_LEVELS = ["critical", "high", "medium", "low"];
|
||||||
|
const RISK_LABELS: Record<string, string> = { critical: "حرج", high: "عالي", medium: "متوسط", low: "منخفض" };
|
||||||
|
const RISK_COLORS: Record<string, string> = {
|
||||||
|
critical: "bg-red-500",
|
||||||
|
high: "bg-orange-500",
|
||||||
|
medium: "bg-yellow-500",
|
||||||
|
low: "bg-emerald-500",
|
||||||
|
};
|
||||||
|
|
||||||
|
function HeatCell({ count, risk }: { count: number; risk: string }) {
|
||||||
|
if (count === 0) return <td className="p-2 text-center text-xs text-muted-foreground">—</td>;
|
||||||
|
const opacity = count >= 5 ? "opacity-100" : count >= 3 ? "opacity-80" : "opacity-60";
|
||||||
|
return (
|
||||||
|
<td className="p-2 text-center">
|
||||||
|
<span className={`inline-block w-8 h-8 rounded flex items-center justify-center text-xs font-bold text-white ${RISK_COLORS[risk]} ${opacity}`}>
|
||||||
|
{count}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function RiskHeatmap({ heatmap = {}, totalControls = 0 }: { heatmap?: HeatmapData; totalControls?: number }) {
|
||||||
|
const categories = Object.keys(heatmap);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="space-y-4 p-6" dir="rtl">
|
||||||
|
<h2 className="text-xl font-bold text-right">خريطة المخاطر الحرارية | Risk Heatmap</h2>
|
||||||
|
<p className="text-sm text-muted-foreground text-right">إجمالي الضوابط: {totalControls}</p>
|
||||||
|
|
||||||
|
{categories.length === 0 ? (
|
||||||
|
<p className="text-sm text-muted-foreground text-center py-8">لا توجد بيانات — قم بتشغيل فحص الامتثال أولاً</p>
|
||||||
|
) : (
|
||||||
|
<div className="overflow-x-auto">
|
||||||
|
<table className="w-full border-collapse">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th className="p-2 text-right text-xs text-muted-foreground">الفئة</th>
|
||||||
|
{RISK_LEVELS.map((level) => (
|
||||||
|
<th key={level} className="p-2 text-center text-xs text-muted-foreground">{RISK_LABELS[level]}</th>
|
||||||
|
))}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{categories.map((cat) => (
|
||||||
|
<tr key={cat} className="border-t border-border/20">
|
||||||
|
<td className="p-2 text-right text-sm font-medium">{CATEGORY_LABELS[cat] || cat}</td>
|
||||||
|
{RISK_LEVELS.map((level) => (
|
||||||
|
<HeatCell key={level} count={heatmap[cat]?.[level] || 0} risk={level} />
|
||||||
|
))}
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -0,0 +1,96 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
type ComplianceControl = {
|
||||||
|
control_id: string; control_name: string; control_name_ar: string;
|
||||||
|
category: string; status: string; risk_level: string;
|
||||||
|
evidence_source: string; last_checked_at: string | null; owner: string | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const STATUS_STYLES: Record<string, { bg: string; text: string; labelAr: string }> = {
|
||||||
|
compliant: { bg: "bg-emerald-500/20", text: "text-emerald-500", labelAr: "ممتثل" },
|
||||||
|
partial: { bg: "bg-yellow-500/20", text: "text-yellow-500", labelAr: "جزئي" },
|
||||||
|
non_compliant: { bg: "bg-red-500/20", text: "text-red-500", labelAr: "غير ممتثل" },
|
||||||
|
not_applicable: { bg: "bg-gray-500/10", text: "text-gray-400", labelAr: "غير مطبق" },
|
||||||
|
};
|
||||||
|
|
||||||
|
const CATEGORY_LABELS: Record<string, string> = {
|
||||||
|
pdpl: "نظام حماية البيانات الشخصية",
|
||||||
|
zatca: "هيئة الزكاة والضريبة والجمارك",
|
||||||
|
sdaia: "الهيئة السعودية للبيانات والذكاء الاصطناعي",
|
||||||
|
nca: "الهيئة الوطنية للأمن السيبراني",
|
||||||
|
sector_specific: "تنظيمات قطاعية",
|
||||||
|
};
|
||||||
|
|
||||||
|
const RISK_COLORS: Record<string, string> = {
|
||||||
|
critical: "border-r-red-500",
|
||||||
|
high: "border-r-orange-500",
|
||||||
|
medium: "border-r-yellow-500",
|
||||||
|
low: "border-r-emerald-500",
|
||||||
|
};
|
||||||
|
|
||||||
|
export function SaudiComplianceDashboard({ controls = [] }: { controls?: ComplianceControl[] }) {
|
||||||
|
const grouped: Record<string, ComplianceControl[]> = {};
|
||||||
|
controls.forEach((c) => {
|
||||||
|
if (!grouped[c.category]) grouped[c.category] = [];
|
||||||
|
grouped[c.category].push(c);
|
||||||
|
});
|
||||||
|
|
||||||
|
const total = controls.length;
|
||||||
|
const compliant = controls.filter((c) => c.status === "compliant").length;
|
||||||
|
const rate = total > 0 ? Math.round((compliant / total) * 100) : 0;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="space-y-6 p-6" dir="rtl">
|
||||||
|
<h2 className="text-xl font-bold text-right">لوحة الامتثال السعودي | Saudi Compliance Dashboard</h2>
|
||||||
|
|
||||||
|
{/* Posture Summary */}
|
||||||
|
<div className="grid grid-cols-3 gap-4">
|
||||||
|
<div className="glass-card p-4 border border-border/40 text-center">
|
||||||
|
<div className="text-xs text-muted-foreground">إجمالي الضوابط</div>
|
||||||
|
<div className="text-2xl font-bold">{total}</div>
|
||||||
|
</div>
|
||||||
|
<div className="glass-card p-4 border border-border/40 text-center">
|
||||||
|
<div className="text-xs text-muted-foreground">نسبة الامتثال</div>
|
||||||
|
<div className={`text-2xl font-bold ${rate >= 80 ? "text-emerald-500" : rate >= 50 ? "text-yellow-500" : "text-red-500"}`}>{rate}%</div>
|
||||||
|
</div>
|
||||||
|
<div className="glass-card p-4 border border-border/40 text-center">
|
||||||
|
<div className="text-xs text-muted-foreground">ممتثل</div>
|
||||||
|
<div className="text-2xl font-bold text-emerald-500">{compliant}/{total}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Scan Button */}
|
||||||
|
<div className="text-center">
|
||||||
|
<button className="px-4 py-2 rounded bg-primary text-primary-foreground text-sm hover:opacity-90">
|
||||||
|
تشغيل فحص الامتثال الآن
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Controls by Category */}
|
||||||
|
{Object.entries(grouped).map(([category, catControls]) => (
|
||||||
|
<section key={category} className="space-y-2">
|
||||||
|
<h3 className="text-lg font-semibold text-right">{CATEGORY_LABELS[category] || category}</h3>
|
||||||
|
{catControls.map((control) => {
|
||||||
|
const style = STATUS_STYLES[control.status] || STATUS_STYLES.non_compliant;
|
||||||
|
const riskBorder = RISK_COLORS[control.risk_level] || "";
|
||||||
|
return (
|
||||||
|
<div key={control.control_id} className={`glass-card p-3 border border-border/40 border-r-4 ${riskBorder}`}>
|
||||||
|
<div className="flex justify-between items-center">
|
||||||
|
<span className={`text-xs px-2 py-0.5 rounded ${style.bg} ${style.text}`}>{style.labelAr}</span>
|
||||||
|
<div className="text-right">
|
||||||
|
<span className="text-xs text-muted-foreground ml-2">{control.control_id}</span>
|
||||||
|
<span className="text-sm font-medium">{control.control_name_ar || control.control_name}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</section>
|
||||||
|
))}
|
||||||
|
|
||||||
|
{controls.length === 0 && (
|
||||||
|
<p className="text-sm text-muted-foreground text-center py-8">لا توجد ضوابط مسجلة — قم بتشغيل الفحص أولاً</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
166
salesflow-saas/scripts/architecture_brief.py
Normal file
166
salesflow-saas/scripts/architecture_brief.py
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Dealix Architecture Brief — Preflight & Discovery Script.
|
||||||
|
|
||||||
|
Run from repository root:
|
||||||
|
python scripts/architecture_brief.py
|
||||||
|
|
||||||
|
Validates governance docs, code structure, and cross-references.
|
||||||
|
Outputs JSON report + human-readable summary.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parent.parent
|
||||||
|
|
||||||
|
# ── Required governance documents ──────────────────────────────
|
||||||
|
REQUIRED_DOCS = {
|
||||||
|
"MASTER_OPERATING_PROMPT.md": ROOT / "MASTER_OPERATING_PROMPT.md",
|
||||||
|
"ai-operating-model.md": ROOT / "docs" / "ai-operating-model.md",
|
||||||
|
"dealix-six-tracks.md": ROOT / "docs" / "dealix-six-tracks.md",
|
||||||
|
"execution-fabric.md": ROOT / "docs" / "governance" / "execution-fabric.md",
|
||||||
|
"trust-fabric.md": ROOT / "docs" / "governance" / "trust-fabric.md",
|
||||||
|
"saudi-compliance-and-ai-governance.md": ROOT / "docs" / "governance" / "saudi-compliance-and-ai-governance.md",
|
||||||
|
"technology-radar-tier1.md": ROOT / "docs" / "governance" / "technology-radar-tier1.md",
|
||||||
|
"partnership-os.md": ROOT / "docs" / "governance" / "partnership-os.md",
|
||||||
|
"ma-os.md": ROOT / "docs" / "governance" / "ma-os.md",
|
||||||
|
"expansion-os.md": ROOT / "docs" / "governance" / "expansion-os.md",
|
||||||
|
"pmi-os.md": ROOT / "docs" / "governance" / "pmi-os.md",
|
||||||
|
"executive-board-os.md": ROOT / "docs" / "governance" / "executive-board-os.md",
|
||||||
|
"execution-matrix-90d-tier1.md": ROOT / "docs" / "execution-matrix-90d-tier1.md",
|
||||||
|
"ADR-0001": ROOT / "docs" / "adr" / "0001-tier1-execution-policy-spikes.md",
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Required backend components ────────────────────────────────
|
||||||
|
REQUIRED_MODELS = {
|
||||||
|
"contradiction.py": ROOT / "backend" / "app" / "models" / "contradiction.py",
|
||||||
|
"evidence_pack.py": ROOT / "backend" / "app" / "models" / "evidence_pack.py",
|
||||||
|
"compliance_control.py": ROOT / "backend" / "app" / "models" / "compliance_control.py",
|
||||||
|
}
|
||||||
|
|
||||||
|
REQUIRED_SERVICES = {
|
||||||
|
"contradiction_engine.py": ROOT / "backend" / "app" / "services" / "contradiction_engine.py",
|
||||||
|
"evidence_pack_service.py": ROOT / "backend" / "app" / "services" / "evidence_pack_service.py",
|
||||||
|
"connector_governance.py": ROOT / "backend" / "app" / "services" / "connector_governance.py",
|
||||||
|
"model_routing_dashboard.py": ROOT / "backend" / "app" / "services" / "model_routing_dashboard.py",
|
||||||
|
"saudi_compliance_matrix.py": ROOT / "backend" / "app" / "services" / "saudi_compliance_matrix.py",
|
||||||
|
"forecast_control_center.py": ROOT / "backend" / "app" / "services" / "forecast_control_center.py",
|
||||||
|
}
|
||||||
|
|
||||||
|
REQUIRED_APIS = {
|
||||||
|
"contradiction.py": ROOT / "backend" / "app" / "api" / "v1" / "contradiction.py",
|
||||||
|
"evidence_packs.py": ROOT / "backend" / "app" / "api" / "v1" / "evidence_packs.py",
|
||||||
|
"executive_room.py": ROOT / "backend" / "app" / "api" / "v1" / "executive_room.py",
|
||||||
|
"connector_governance.py": ROOT / "backend" / "app" / "api" / "v1" / "connector_governance.py",
|
||||||
|
"model_routing.py": ROOT / "backend" / "app" / "api" / "v1" / "model_routing.py",
|
||||||
|
"saudi_compliance.py": ROOT / "backend" / "app" / "api" / "v1" / "saudi_compliance.py",
|
||||||
|
"forecast_control.py": ROOT / "backend" / "app" / "api" / "v1" / "forecast_control.py",
|
||||||
|
"approval_center.py": ROOT / "backend" / "app" / "api" / "v1" / "approval_center.py",
|
||||||
|
}
|
||||||
|
|
||||||
|
REQUIRED_FRONTEND = {
|
||||||
|
"executive-room.tsx": ROOT / "frontend" / "src" / "components" / "dealix" / "executive-room.tsx",
|
||||||
|
"evidence-pack-viewer.tsx": ROOT / "frontend" / "src" / "components" / "dealix" / "evidence-pack-viewer.tsx",
|
||||||
|
"approval-center.tsx": ROOT / "frontend" / "src" / "components" / "dealix" / "approval-center.tsx",
|
||||||
|
"connector-governance-board.tsx": ROOT / "frontend" / "src" / "components" / "dealix" / "connector-governance-board.tsx",
|
||||||
|
"saudi-compliance-dashboard.tsx": ROOT / "frontend" / "src" / "components" / "dealix" / "saudi-compliance-dashboard.tsx",
|
||||||
|
"actual-vs-forecast-dashboard.tsx": ROOT / "frontend" / "src" / "components" / "dealix" / "actual-vs-forecast-dashboard.tsx",
|
||||||
|
"risk-heatmap.tsx": ROOT / "frontend" / "src" / "components" / "dealix" / "risk-heatmap.tsx",
|
||||||
|
"policy-violations-board.tsx": ROOT / "frontend" / "src" / "components" / "dealix" / "policy-violations-board.tsx",
|
||||||
|
"partner-pipeline-board.tsx": ROOT / "frontend" / "src" / "components" / "dealix" / "partner-pipeline-board.tsx",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def check_files(label: str, file_map: dict[str, Path]) -> dict:
|
||||||
|
results = {}
|
||||||
|
for name, path in file_map.items():
|
||||||
|
results[name] = {"exists": path.exists(), "path": str(path.relative_to(ROOT))}
|
||||||
|
found = sum(1 for v in results.values() if v["exists"])
|
||||||
|
return {"label": label, "total": len(file_map), "found": found, "items": results}
|
||||||
|
|
||||||
|
|
||||||
|
def count_directory(pattern: str, base: Path | None = None) -> int:
|
||||||
|
search_base = base or ROOT
|
||||||
|
return len(list(search_base.glob(pattern)))
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
report: dict = {"project": "Dealix", "root": str(ROOT), "checks": {}}
|
||||||
|
|
||||||
|
# Check all required file groups
|
||||||
|
report["checks"]["governance_docs"] = check_files("Governance Documents", REQUIRED_DOCS)
|
||||||
|
report["checks"]["backend_models"] = check_files("Backend Models (Tier-1)", REQUIRED_MODELS)
|
||||||
|
report["checks"]["backend_services"] = check_files("Backend Services (Tier-1)", REQUIRED_SERVICES)
|
||||||
|
report["checks"]["backend_apis"] = check_files("Backend APIs (Tier-1)", REQUIRED_APIS)
|
||||||
|
report["checks"]["frontend_components"] = check_files("Frontend Components (Tier-1)", REQUIRED_FRONTEND)
|
||||||
|
|
||||||
|
# Count existing components
|
||||||
|
report["counts"] = {
|
||||||
|
"total_models": count_directory("backend/app/models/*.py") - 2, # exclude __init__, base
|
||||||
|
"total_services": count_directory("backend/app/services/*.py") - 1, # exclude __init__
|
||||||
|
"total_api_routes": count_directory("backend/app/api/v1/*.py") - 2, # exclude __init__, router
|
||||||
|
"total_frontend_components": count_directory("frontend/src/components/dealix/*.tsx"),
|
||||||
|
"total_agents": count_directory("ai-agents/prompts/*.md"),
|
||||||
|
"total_governance_docs": count_directory("docs/governance/*.md"),
|
||||||
|
"total_legal_docs": count_directory("docs/legal/*.md"),
|
||||||
|
"total_tests": count_directory("backend/tests/test_*.py"),
|
||||||
|
}
|
||||||
|
|
||||||
|
# Overall score
|
||||||
|
all_checks = []
|
||||||
|
for section in report["checks"].values():
|
||||||
|
for item in section["items"].values():
|
||||||
|
all_checks.append(item["exists"])
|
||||||
|
|
||||||
|
total = len(all_checks)
|
||||||
|
passed = sum(all_checks)
|
||||||
|
report["summary"] = {
|
||||||
|
"total_checks": total,
|
||||||
|
"passed": passed,
|
||||||
|
"failed": total - passed,
|
||||||
|
"score_percent": round((passed / total) * 100, 1) if total else 0,
|
||||||
|
"tier1_ready": passed == total,
|
||||||
|
}
|
||||||
|
|
||||||
|
# Print human-readable summary
|
||||||
|
print("=" * 60)
|
||||||
|
print(" DEALIX ARCHITECTURE BRIEF")
|
||||||
|
print("=" * 60)
|
||||||
|
print()
|
||||||
|
|
||||||
|
for section in report["checks"].values():
|
||||||
|
label = section["label"]
|
||||||
|
found = section["found"]
|
||||||
|
total_section = section["total"]
|
||||||
|
status = "PASS" if found == total_section else "PARTIAL"
|
||||||
|
print(f" [{status}] {label}: {found}/{total_section}")
|
||||||
|
for name, info in section["items"].items():
|
||||||
|
mark = "+" if info["exists"] else "-"
|
||||||
|
print(f" {mark} {name}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
print("-" * 60)
|
||||||
|
print(f" Component Counts:")
|
||||||
|
for key, val in report["counts"].items():
|
||||||
|
print(f" {key}: {val}")
|
||||||
|
print()
|
||||||
|
print("-" * 60)
|
||||||
|
score = report["summary"]["score_percent"]
|
||||||
|
ready = report["summary"]["tier1_ready"]
|
||||||
|
print(f" OVERALL SCORE: {score}% ({passed}/{total})")
|
||||||
|
print(f" TIER-1 READY: {'YES' if ready else 'NO'}")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
# Write JSON report
|
||||||
|
report_path = ROOT / "scripts" / "architecture_brief_report.json"
|
||||||
|
report_path.write_text(json.dumps(report, indent=2, default=str))
|
||||||
|
print(f"\n JSON report: {report_path.relative_to(ROOT)}")
|
||||||
|
|
||||||
|
sys.exit(0 if ready else 1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
218
salesflow-saas/scripts/architecture_brief_report.json
Normal file
218
salesflow-saas/scripts/architecture_brief_report.json
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
{
|
||||||
|
"project": "Dealix",
|
||||||
|
"root": "/home/user/system-prompts-and-models-of-ai-tools/salesflow-saas",
|
||||||
|
"checks": {
|
||||||
|
"governance_docs": {
|
||||||
|
"label": "Governance Documents",
|
||||||
|
"total": 14,
|
||||||
|
"found": 14,
|
||||||
|
"items": {
|
||||||
|
"MASTER_OPERATING_PROMPT.md": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "MASTER_OPERATING_PROMPT.md"
|
||||||
|
},
|
||||||
|
"ai-operating-model.md": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "docs/ai-operating-model.md"
|
||||||
|
},
|
||||||
|
"dealix-six-tracks.md": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "docs/dealix-six-tracks.md"
|
||||||
|
},
|
||||||
|
"execution-fabric.md": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "docs/governance/execution-fabric.md"
|
||||||
|
},
|
||||||
|
"trust-fabric.md": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "docs/governance/trust-fabric.md"
|
||||||
|
},
|
||||||
|
"saudi-compliance-and-ai-governance.md": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "docs/governance/saudi-compliance-and-ai-governance.md"
|
||||||
|
},
|
||||||
|
"technology-radar-tier1.md": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "docs/governance/technology-radar-tier1.md"
|
||||||
|
},
|
||||||
|
"partnership-os.md": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "docs/governance/partnership-os.md"
|
||||||
|
},
|
||||||
|
"ma-os.md": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "docs/governance/ma-os.md"
|
||||||
|
},
|
||||||
|
"expansion-os.md": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "docs/governance/expansion-os.md"
|
||||||
|
},
|
||||||
|
"pmi-os.md": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "docs/governance/pmi-os.md"
|
||||||
|
},
|
||||||
|
"executive-board-os.md": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "docs/governance/executive-board-os.md"
|
||||||
|
},
|
||||||
|
"execution-matrix-90d-tier1.md": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "docs/execution-matrix-90d-tier1.md"
|
||||||
|
},
|
||||||
|
"ADR-0001": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "docs/adr/0001-tier1-execution-policy-spikes.md"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"backend_models": {
|
||||||
|
"label": "Backend Models (Tier-1)",
|
||||||
|
"total": 3,
|
||||||
|
"found": 3,
|
||||||
|
"items": {
|
||||||
|
"contradiction.py": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "backend/app/models/contradiction.py"
|
||||||
|
},
|
||||||
|
"evidence_pack.py": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "backend/app/models/evidence_pack.py"
|
||||||
|
},
|
||||||
|
"compliance_control.py": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "backend/app/models/compliance_control.py"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"backend_services": {
|
||||||
|
"label": "Backend Services (Tier-1)",
|
||||||
|
"total": 6,
|
||||||
|
"found": 6,
|
||||||
|
"items": {
|
||||||
|
"contradiction_engine.py": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "backend/app/services/contradiction_engine.py"
|
||||||
|
},
|
||||||
|
"evidence_pack_service.py": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "backend/app/services/evidence_pack_service.py"
|
||||||
|
},
|
||||||
|
"connector_governance.py": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "backend/app/services/connector_governance.py"
|
||||||
|
},
|
||||||
|
"model_routing_dashboard.py": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "backend/app/services/model_routing_dashboard.py"
|
||||||
|
},
|
||||||
|
"saudi_compliance_matrix.py": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "backend/app/services/saudi_compliance_matrix.py"
|
||||||
|
},
|
||||||
|
"forecast_control_center.py": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "backend/app/services/forecast_control_center.py"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"backend_apis": {
|
||||||
|
"label": "Backend APIs (Tier-1)",
|
||||||
|
"total": 8,
|
||||||
|
"found": 8,
|
||||||
|
"items": {
|
||||||
|
"contradiction.py": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "backend/app/api/v1/contradiction.py"
|
||||||
|
},
|
||||||
|
"evidence_packs.py": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "backend/app/api/v1/evidence_packs.py"
|
||||||
|
},
|
||||||
|
"executive_room.py": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "backend/app/api/v1/executive_room.py"
|
||||||
|
},
|
||||||
|
"connector_governance.py": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "backend/app/api/v1/connector_governance.py"
|
||||||
|
},
|
||||||
|
"model_routing.py": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "backend/app/api/v1/model_routing.py"
|
||||||
|
},
|
||||||
|
"saudi_compliance.py": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "backend/app/api/v1/saudi_compliance.py"
|
||||||
|
},
|
||||||
|
"forecast_control.py": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "backend/app/api/v1/forecast_control.py"
|
||||||
|
},
|
||||||
|
"approval_center.py": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "backend/app/api/v1/approval_center.py"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"frontend_components": {
|
||||||
|
"label": "Frontend Components (Tier-1)",
|
||||||
|
"total": 9,
|
||||||
|
"found": 9,
|
||||||
|
"items": {
|
||||||
|
"executive-room.tsx": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "frontend/src/components/dealix/executive-room.tsx"
|
||||||
|
},
|
||||||
|
"evidence-pack-viewer.tsx": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "frontend/src/components/dealix/evidence-pack-viewer.tsx"
|
||||||
|
},
|
||||||
|
"approval-center.tsx": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "frontend/src/components/dealix/approval-center.tsx"
|
||||||
|
},
|
||||||
|
"connector-governance-board.tsx": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "frontend/src/components/dealix/connector-governance-board.tsx"
|
||||||
|
},
|
||||||
|
"saudi-compliance-dashboard.tsx": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "frontend/src/components/dealix/saudi-compliance-dashboard.tsx"
|
||||||
|
},
|
||||||
|
"actual-vs-forecast-dashboard.tsx": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "frontend/src/components/dealix/actual-vs-forecast-dashboard.tsx"
|
||||||
|
},
|
||||||
|
"risk-heatmap.tsx": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "frontend/src/components/dealix/risk-heatmap.tsx"
|
||||||
|
},
|
||||||
|
"policy-violations-board.tsx": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "frontend/src/components/dealix/policy-violations-board.tsx"
|
||||||
|
},
|
||||||
|
"partner-pipeline-board.tsx": {
|
||||||
|
"exists": true,
|
||||||
|
"path": "frontend/src/components/dealix/partner-pipeline-board.tsx"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"counts": {
|
||||||
|
"total_models": 32,
|
||||||
|
"total_services": 80,
|
||||||
|
"total_api_routes": 58,
|
||||||
|
"total_frontend_components": 48,
|
||||||
|
"total_agents": 19,
|
||||||
|
"total_governance_docs": 9,
|
||||||
|
"total_legal_docs": 7,
|
||||||
|
"total_tests": 19
|
||||||
|
},
|
||||||
|
"summary": {
|
||||||
|
"total_checks": 40,
|
||||||
|
"passed": 40,
|
||||||
|
"failed": 0,
|
||||||
|
"score_percent": 100.0,
|
||||||
|
"tier1_ready": true
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user