# AARJAY GDP Portal — Complete Project Blueprint

**Document purpose:** Single save-point reference for platform, architecture, UI/UX, coding standards, modules, and related documents.  
**Codebase root:** `/Users/sagar/Downloads/AARJAY_GDP_Portal/mvc`  
**Product version (package):** v15.8 (`VERSION.txt`)  
**Remediation branch / floor:** `remediation/gdp-hardening` · migration floor **286**  
**Controlled posture:** Advanced GDP wholesale portal — **validation candidate** (not MHRA-approved software)

---

## 1. What this product is

A custom **UK GDP-oriented medicines wholesale distribution portal** covering:

**Buy → Goods Receiving → Stock batches → Sales Order → Dispatch → Invoice / Accounts**

with GDP-minded controls: site isolation, Trade Gate, electronic signatures, audit trail, soft void, dual-control dispatch release, stock ledger integrity.

---

## 2. Platform & technology stack

| Layer | Choice |
|-------|--------|
| Language | **PHP 8.0+** (local/runtime often 8.2–8.4; Docker `php:8.2-apache`) |
| Framework | **Custom MVC** (no Laravel/Symfony; no Composer `vendor/` required) |
| Database | **MySQL 8** via **PDO** (`utf8mb4`) |
| Web entry | Front controller `index.php` + `app/bootstrap.php` |
| Local runtime | `start-portal.sh` → `php -S` + `dev-router.php` (port **8080**) |
| DB local | Runtime MySQL (often port **3307**, unix socket under `~/gdp-portal-runtime`) |
| Optional Docker | `docker-compose.yml` (php + mysql) |
| Timezone | `Europe/London` |
| Installer | `install.php` / `install.sql` + gated reinstall |

### Programming languages & assets
- **PHP** — Controllers, Models, Services, Views  
- **SQL** — `install.sql` + `migrations/*.sql` (~270+ files, numbered through **286**)  
- **JavaScript** — `assets/js/pharma.js` (+ Bootstrap CDN bundle)  
- **CSS** — `assets/css/pharma.css` design system  
- **Shell** — `start-portal.sh`, packaging, migration, backup/restore scripts  

### Namespace
```
App\
  Core\       Config, Controller, Database, Model, Router, Session, Url
  Controllers\
  Models\
  Views\
  Services\
  Helpers\
```

Autoload: PSR-4-style simple autoloader in `app/bootstrap.php` (file path from class name).

---

## 3. Application architecture

### Pattern: Custom MVC + Services
```
Browser → index.php / dev-router.php
       → Router (routes.php + routeMap.php)
       → Controller (auth/RBAC/CSRF)
       → Model / Service (business + ledger/trade/esign)
       → View (PHP templates)
       → MySQL
```

### Core runtime files
| File | Role |
|------|------|
| `index.php` | Front controller |
| `dev-router.php` | Pretty URL rewrite for PHP built-in server |
| `app/bootstrap.php` | Autoload, helpers, session, timezone |
| `app/config.php` | DB + app + feature flags |
| `app/routes.php` | Route → Controller@action map |
| `app/routeMap.php` | Legacy route name → pretty path (~380 entries) |
| `app/Core/Url.php` | URL builder from routeMap |

### Key design patterns used
| Pattern | Implementation |
|---------|----------------|
| MVC | Controllers / Models / Views |
| Service layer | `app/Services/*` (StockLedger, TradeGate, Esign, MFA, Audit, SoftLifecycle…) |
| Soft lifecycle | Void/cancel with mandatory reason; hard delete disabled on critical entities |
| Feature flags | `config.php` → `FeatureFlags` service |
| RBAC | `permissions` table + `Auth::hasAccess(module, action)` |
| Site scope | `user_site_assignments` + fail-closed SQL scope |
| Append-only audit | `activity_log` + hash chain + DB triggers (UPDATE/DELETE blocked) |
| Stock ledger | Idempotent movements; stock before status on Dispatch/GRN |

### Approximate code volume
| Area | Approx count |
|------|----------------|
| Controllers | ~95 |
| Models | ~96 |
| Views | ~320+ PHP templates |
| Services | ~15+ |
| Migrations | ~270+ SQL files |

---

## 4. UI / UX design system

### Layout structure
- **App shell:** left **sidebar** (260px) + top **topbar** (64px) + main content  
- Layout templates: `app/Views/layout/header.php`, `footer.php`  
- Shared partials: `app/Views/partials/` (e-sign fields, trade override, void forms, etc.)  
- Login: bare layout (`renderBare`) — split branding panel + form  

### CSS / JS files
| Asset | Path |
|-------|------|
| Design system CSS | `assets/css/pharma.css` |
| App JS (line items, UI helpers) | `assets/js/pharma.js` |
| Framework CSS/JS | Bootstrap **5.3.3** (CDN) |
| Icons | Bootstrap Icons **1.11.3** (CDN) |

### Typography (font style)
- **Primary font:** **Inter** (Google Fonts) weights **300–800**  
- Fallback stack: `'Inter', system-ui, -apple-system, sans-serif`  
- Loaded via `@import` in `pharma.css` and layout `<link>`  

### Colour palette (CSS variables in `:root`)
| Token | Value | Use |
|-------|-------|-----|
| `--primary` | `#1E3A5F` | Brand navy |
| `--primary-light` | `#2E5FA0` | Links / hover |
| `--primary-dark` | `#0F2340` | Sidebar end / dark brand |
| `--accent` | `#00C896` | Success accent / CTAs |
| `--danger` | `#E74C3C` | Errors / voids |
| `--warning` | `#F39C12` | Warnings |
| `--success` | `#27AE60` | Success |
| `--info` | `#2980B9` | Info |
| `--surface` | `#F8FAFC` | Page background |
| `--card-bg` | `#FFFFFF` | Cards / panels |
| `--text-primary` | `#1A2332` | Body text |
| `--text-secondary` | `#6B7A8D` | Secondary |
| `--text-muted` | `#9BA8B5` | Hints |
| `--border-color` | `#E8ECF0` | Borders |

Dark theme overrides exist under `[data-theme="dark"]`.

### Shape & motion
| Token | Value |
|-------|-------|
| `--radius-card` | 12px |
| `--radius-btn` / `--radius-input` | 8px |
| `--shadow-card` | soft elevation |
| `--transition` | `all 0.2s ease` |
| Reduced motion | Prefer honouring `prefers-reduced-motion` (CSS) |

### UX conventions
- GDP forms: clear required fields, status badges, audit-linked voids  
- Dual control: Dispatch release requires **different** picked-by and checked-by  
- E-sign blocks: signature profile + phrase + account password (+ MFA for high-risk)  
- Flash messages for success/error  
- Module nav grouped (Trading Partners, Products, Orders & Dispatch, GDP Compliance, Accounts, Stock, Admin, Reports)  
- System Health page for admins (migration floor, table checks)

### Accessibility / responsive
- Bootstrap grid for responsive layout  
- Semantic headings/breadcrumbs on most screens  
- Formal WCAG audit still a known limitation (not a sealed AA certification)

---

## 5. Authentication, security & GDP controls

### Session (`App\Core\Session`)
- HttpOnly cookies, SameSite=Lax, Secure when HTTPS  
- Idle timeout **30 minutes**  
- Absolute timeout **12 hours**  
- Regenerated on login  

### Login & MFA
- CSRF on login  
- Login throttle / lockout (`LoginThrottleService`)  
- Optional login MFA (`mfa_optional_framework`)  
- **High-risk e-sign / Trade override require MFA enrolled**  
- TOTP via `MfaService` (no external OTP library)

### Authorisation
- Role examples: `admin`, `rp`, `deputy_rp`, `qa`, `warehouse`, `accounts`, `viewer`, `inspector`, …  
- Permissions: `can_view/create/edit/delete` + extended `can_submit/approve/release/sign/void/export/override`  
- Site fail-closed for non-admins (`Auth::canAccessSite`, `siteScopeSql`)  
- Temporary RP delegation table `authority_delegations`  

### Evidence / uploads
- `UploadHelper`: magic bytes, checksum, preferred `storage/private/`  
- `FileController`: auth + module ACL + site check for key folders  
- Malware scan hook (`MalwareScanService`); fail-closed when `env` is staging/production  

### Stock integrity
- `StockLedgerService`: locks, non-negative, quarantine/recall/expiry blocks, idempotency  
- GRN / Dispatch: **stock movements before status** (atomic)  

### Trade Gate
- Blocks unqualified customer/supplier  
- Timed `trade_overrides` honoured  
- New override: RP/Deputy (or delegate) + reason + e-sign  

---

## 6. Core business module map

### Commercial / stock cycle
```
Purchase Request → Goods Receiving (inspected/accepted)
        ↓ creates stock_batches (receipt)
Sales Order (optional reservation — tags batch, does not reduce qty)
        ↓
Dispatch (draft → ready → dispatched)
        ↓ sale movement (−qty) when dispatched
Customer Invoice / Accounts close-out
```

### Major module groups
1. **Company & Sites** — company profiles, site profiles, assignments  
2. **Trading Partners** — customers, suppliers, qualifications, verification packs  
3. **Products & Stock** — products, batches, transfers, non-saleable / defective / falsified  
4. **Orders & Dispatch** — sales orders, dispatches, purchase requests, GRNs, returns  
5. **Accounts & Tax** — invoices, credit notes, VAT, statements, payment tracker  
6. **GDP / QMS** — deviations, CAPA, change control, SOPs, recalls, audits, MHRA packs  
7. **Premises & Equipment** — assets, cleaning, pest, calibration, temperature logs/excursions  
8. **People & Training** — users, training matrix, SOP sign-off  
9. **Admin** — permissions, system health, backups register, validation packs, feature flags  

Detailed registry: `MODULE_REGISTRY.md`, `COMPLETED_MODULES.md`, `PENDING_MODULES.md`.

---

## 7. Coding conventions (how the project is written)

| Topic | Convention |
|-------|------------|
| Style | Procedural-MVC PHP with classes; Views are PHP templates with helpers `e()`, `csrfField()`, `hasAccess()` |
| Controllers | `*Controller.php`, actions `*Action()`, extend `Controller` |
| Models | Table access + status transitions; SoftLifecycle for void |
| SQL | Prepared statements (PDO); migrations incremental numbered SQL |
| Naming | Pretty routes kebab-case; DB snake_case |
| Validation | Controller request validation + model rules |
| Logging | `AuditService` / `ActivityLog` for GDP events |
| Features | Experimental flags default **OFF** |
| Uploads | Never trust original filename; use `UploadHelper` |

More detail: `CONVENTIONS.md`, `UPLOAD_STANDARD.md`, `.cursor/rules/*`.

---

## 8. Data & migrations

- Baseline schema + seeded data via install / dumps  
- Forward migrations in `migrations/` (e.g. `283_*` stock ledger, `284_*` e-sign bind, `285_*` authority/audit, `286_*` MFA/delegation/triggers)  
- Runner: `scripts/run_migrations.php` (checksum; **do not mark applied on failure**)  
- SystemHealth expected floor: **286**  
- Optional least-privilege DB grants: `scripts/optional_gdp_app_user_grants.sql`  

---

## 9. Operations & release tooling

| Script / artefact | Purpose |
|-------------------|---------|
| `start-portal.sh` / `stop-portal.sh` | Local stack |
| `scripts/php_lint_all.sh` | Syntax check |
| `scripts/tests/stock_ledger_remediation_test.php` | Stock integrity CLI |
| `scripts/tests/dispatch_grn_atomicity_test.php` | Atomic Dispatch/GRN |
| `scripts/tests/phase5e_remediation_test.php` | MFA / audit / delegation |
| `scripts/make_manifest.sh` | `MANIFEST.sha256` |
| `scripts/sign_manifest.sh` / `verify_release.sh` | Signed release |
| `scripts/prove_restore.sh` | Backup→restore proof |
| `scripts/package_release.sh` | Zip package |
| `RELEASE_PUBLIC_KEY.pem` | Public verify key |

Default local URL: **http://127.0.0.1:8080**

---

## 10. Related documents (save / browse index)

### Start here
- `START_HERE.md`, `RUN_ME.md`, `README.md`  
- `PORTAL_TECHNICAL_INVENTORY.md`  
- `MASTER_SPEC.md`, `MODULE_REGISTRY.md`  

### Design / build rules
- `CONVENTIONS.md`  
- `UPLOAD_STANDARD.md`  
- `assets/css/pharma.css` (source of truth for visual tokens)  
- `.cursor/rules/master-spec.mdc`, `portal-context.mdc`, `module-redesign-notes.mdc`  

### Quality / release
- `RELEASE_CHECKLIST.md`, `FINAL_RELEASE_NOTES.md`, `CHANGELOG.md`  
- `STAGING_QUICKSTART.md`, `STAGING_TEST_REPORT_TEMPLATE.md`  
- `SECURITY_HARDENING.md`, `GO_LIVE_RUNBOOK.md`, `CPANEL_DEPLOYMENT.md`  
- `TROUBLESHOOTING.md`, `POST_DEPLOYMENT_MONITORING.md`  

### Remediation / readiness
- `REMEDIATION_GAP_REGISTER.md`  
- `REMEDIATION_EXECUTED_TEST_REPORT.md`  
- `REMEDIATION_BASELINE_FREEZE.md`  
- `KNOWN_LIMITATIONS.md`  
- `docs/validation/*` (URS / IQ / OQ / PQ templates)  

### Commercial
- `COMMERCIAL_GTM_PACK.md` — selling to small wholesalers  

### Training / ops
- `USER_TRAINING_GUIDE.md`  
- `PERMISSIONS_MATRIX_CHECKLIST.md`  
- `DATA_MIGRATION_GUIDE.md`  

---

## 11. Directory blueprint (logical)

```
mvc/
├── index.php, dev-router.php, install.php, install.sql
├── start-portal.sh, stop-portal.sh, docker-compose.yml
├── app/
│   ├── bootstrap.php, config.php, routes.php, routeMap.php
│   ├── Core/          # framework kernels
│   ├── Controllers/   # HTTP actions
│   ├── Models/        # persistence + workflows
│   ├── Views/         # layout + module templates + partials
│   ├── Services/      # GDP/domain services
│   └── Helpers/       # Auth, Upload, ActivityLog, functions
├── assets/css/pharma.css
├── assets/js/pharma.js
├── migrations/        # numbered SQL
├── scripts/           # ops + tests + release
├── storage/private/   # evidence (deny web)
├── uploads/           # legacy evidence path
├── docs/validation/   # validation templates
└── *.md               # project documentation set
```

---

## 12. Environment configuration snapshot (`app/config.php`)

Typical local keys:
- `database`: host/port/name/user/pass  
- `app.env`: `local` | `staging` | `production`  
- `app.mfa_optional_framework`: login MFA soft/hard policy  
- `app.malware_scan_required` / `malware_scan_cmd`  
- `features.experimental_*`: AI, accounting, QR, cold-chain (default **false**)

Production expectation: `env=production`, malware required/enforced, least-privilege DB user, HTTPS, MFA policy enforced for high-risk roles as agreed with customer RP.

---

## 13. Honest product status (for this blueprint)

| Claim | Status |
|-------|--------|
| Feature-rich GDP wholesale ops portal | **Yes** |
| Hardened stock / auth / audit / Trade Gate controls | **Yes (remediated)** |
| Perfect / bug-free forever | **No** |
| MHRA-approved software | **No** |
| Sellable to small WHDs with correct packaging | **Yes (see GTM pack)** |

---

## 14. How to use this blueprint

1. Keep this file as the **master map** when briefing developers, designers, or buyers.  
2. For visual rebuilds, use **§4** tokens (Inter + navy/teal palette + Bootstrap 5 shell).  
3. For coding, follow **§3 + §7** and existing Controllers/Services.  
4. For GDP claims, use remediation + validation docs — never imply MHRA approval.  

---

*End of blueprint. Generated from the live AARJAY GDP Portal codebase structure and design tokens.*
