Skip to content

Architecture

One Laravel API, four React apps, a CRM middleware to three Microsoft Dynamics 365 orgs, a PDF service, and payments. If you hold this picture, every flow makes sense.

flowchart TB
subgraph Personas
  P1(Shopper):::person
  P2(Broker / Sales-Manager):::person
  P3(Sales-Man):::person
  P4(Shopper-Admin):::person
  P5(Admin):::person
end
subgraph Frontend["Frontend — Nx monorepo (React 18 · Vite)"]
  A1[Shopper SPA]:::fe
  A2[Broker SPA]:::fe
  A3[Sales-Man SPA]:::fe
  A4[Shopper-Analytics SPA]:::fe
end
BE[Backend API<br/>Laravel 10 · PHP 8.2]:::be
VOY[Voyager admin /admin]:::be
MW[crms-middleware<br/>Laravel 9]:::mw
PDF[PDF service<br/>Node · Puppeteer]:::svc
DB[(MySQL 8)]:::store
RD[(Redis)]:::store
LA{{Azure Logic Apps}}:::ext
D365[(Dynamics 365<br/>Egypt · Oman · Montenegro)]:::ext
PAY[Paymob · Thawani · WSPG]:::ext
TP[Sentry · Firebase · Azure AD · S3 · Infobip · GA]:::ext

P1 --> A1
P2 --> A2
P3 --> A3
P4 --> A4
P5 --> VOY
A1 & A2 & A3 & A4 -->|HTTPS REST · Bearer| BE
BE --> DB
BE -.->|cache/queue| RD
BE -->|OAuth client_credentials| MW
BE -->|HTTPS| PDF
BE -->|HTTPS| PAY
BE --> TP
PAY -.->|webhook callback| BE
MW -->|writes: Logic App| LA
MW -->|reads: OData v9.1/v9.2| D365
LA --> D365
classDef person fill:#e7eef6,stroke:#2563A8,color:#0b1b2b;
classDef fe fill:#e7eef6,stroke:#2563A8,color:#0b1b2b;
classDef be fill:#dff0f0,stroke:#0C7C84,color:#0b1b2b;
classDef mw fill:#efe7f7,stroke:#7A4FB5,color:#0b1b2b;
classDef svc fill:#f7efdc,stroke:#B7791F,color:#0b1b2b;
classDef store fill:#eceff1,stroke:#5B6B7A,color:#0b1b2b;
classDef ext fill:#f6e7dc,stroke:#C4622D,color:#0b1b2b;
Orascom Portals — container view (current)
  • One backend, many frontends. Four React SPAs (one per persona group) from a single Nx workspace all talk only to the Laravel backend — never to a CRM directly.
  • The backend is the hub. Business logic, auth, payment orchestration, the Voyager admin, and all outbound integrations.
  • CRM access goes through the middleware. The crms-middleware service is the only thing that talks to the CRMs.
Repo Stack Prod?
backend Laravel 10 · PHP 8.2 · MySQL 8 · Passport + Sanctum · Voyager
frontend Nx · React 18 · TypeScript · Vite · Yarn 1 — 4 apps + 5 libs
crms-middleware Laravel 9 · PHP 8.1 — the CRM proxy
backend-pdf-service Node 20 · Express · Puppeteer · TypeScript
crm-mock Laravel 12 · SQLite — dev CRM stand-in dev only
middleware-package PHP Composer library — proposed replacement for crms-middleware not wired

The production system runs on AWS (account 907815021625, eu-central-1 / Frankfurt):

flowchart TB
U(Client) --> DNS(DNS) --> WAF[AWS WAF & Shield]
WAF --> ALB[Application Load Balancer]
subgraph VPC
  subgraph Public
    ALB
    NAT[NAT Gateway]
  end
  subgraph Private
    FE[Frontend — AWS Amplify]
    BEASG[Backend EC2 AutoScaling]
    CRMASG[CRM EC2 AutoScaling]
    RDS[(RDS MySQL · Multi-AZ)]
    REDIS[(Redis)]
    S3[(S3 media)]
    CF[CloudFront]
  end
end
ALB --> FE
ALB --> BEASG
ALB --> CRMASG
BEASG --> RDS
BEASG --> REDIS
BEASG --> CF --> S3
CRMASG --> RDS
GH[GitHub · OrascomDevelopment] -->|push / merge| GHA[GitHub Actions] -->|build revision| CD[AWS CodeDeploy]
CD -->|blue/green: prod + uat<br/>in-place: staging| BEASG
CD -->|blue/green| CRMASG
GH -->|autoBuild| FE
Production topology (AWS)
  • Frontend = AWS Amplify (serverless static hosting), sourced from GitHub Orascom-Portals-Frontend with autoBuild=true. Backend + CRM = EC2 Auto Scaling groups (Graviton t4g) behind the shared ALB. DB = RDS MySQL (Multi-AZ). Plus a dedicated Redis instance, S3 (media via CloudFront), WAF on the prod ALB, CloudWatch.
  • Branch → environment: develop → staging, uat → UAT, main → production.
  • Deploy rail: push/merge to GitHub (OrascomDevelopment) → GitHub Actions builds a self-contained revision → AWS CodeDeploy deploys it — blue/green in production + UAT, in-place in staging. Backend + CRM production cut over to this rail on 2026-07-20.
  • The full AWS estate — the supervisor box, ECR + the PDF rail, every CodeDeploy app, the OIDC deploy roles, Secrets Manager, and the observability/audit stack — is on the dedicated Infrastructure page.