# Product requirements — edi_shopfront (EDI ShopFlow / Transactflow Shopfront)

Evidence date: 2026-10-16.

Source repository: `git@bitbucket.org:overdrive/edi_shopfront.git`, `main` at `9d1d726`.

Provenance labels used below: **Documented**, **Implemented**, **Inferred**, **Planned**, **Unknown**.

Nothing in this document is a new product decision. Where the code and the README disagree, both are stated.

## Product purpose

**Implemented:** Authenticated users can operate a B2B retail shopfront: buyers select a store, browse products, build carts, place standard or JAB (multi-store) orders, track order/item statuses, and submit orders to an external Transactflow Store API. Sellers use a separate portal to view and process orders and export documents. Platform operators manage companies, stores, seller/buyer groups, price files, EDI transport methods, users/roles, adverts, notifications, reports, and cron-driven EDI import/export with retailers.

**Documented** in `composer.json` / `overview.md` as Transactflow (Overdrive). **Documented** in `README.md` as Admin Overdrive Starter with only auth, authorization, registration, and menu management.

**Inferred:** The product serves South African retail supply-chain ordering and EDI document exchange (Pick n Pay SOAP, Shoprite REST, M2North SOAP, folder XML).

**Unknown / Requires Confirmation:** Official customer-facing name and whether this repository is the sole shopfront or part of a larger Transactflow/EDI suite.

## Users and roles

### Seeded roles

From `app/Database/Seeds/UserRole.php`:

| Role (seed order → typical id) | Name |
|---|---|
| 1 | Developer |
| 2 | Admin |
| 3 | Company Admin |
| 4 | Company User |

Menu grants are seeded in `UserAccess.php`. Exact production role ids should be confirmed against live data.

### User types and portals

**Implemented** (`AddUserTypeToUsersTable` migration, `UserModel`, `Welcome.php`, layouts):

| Field | Values |
|---|---|
| `user_type` | `Buyer`, `Seller`, `Buyer and Seller` |
| `default_portal` | `Buyer`, `Seller` |

Dual-type users are prompted for portal selection. Session key `portal` distinguishes Seller portal from the main/buyer UI. Seller portal also has `/seller/login`.

### Access model

| Mechanism | Behaviour | Evidence |
|---|---|---|
| Session auth | Cookie sessions via DatabaseHandler / `sessions` table | `app/env`, filters |
| Login / logout / password reset / unlock | Welcome + UnlockController routes | `Routes.php`, `Filters.php` |
| Email 2FA | Codes in `email_authentication_codes`; blocked users list | Migrations + Welcome |
| Menu RBAC | `isGranted` checks `user_menu` / `user_access` | `Authorization.php` |
| Company scope | Developer/Admin → all companies; Company Admin → linked companies | `Welcome::setCompanyUsersAndAdminSessionVars` |
| Store scope | `store_users`, session `currentStoreID` | Models / shop controllers |
| Organisations API | REST resource + JWT Bearer | `Routes.php`, `JwtLibrary.php` |

**Inferred — FR access:** CSRF and honeypot are disabled globally. **Requires confirmation** whether that is accepted risk.

## Main workflows

### Sign in (buyer / admin)

1. `GET /` shows login when not authenticated.
2. User posts credentials (`getLogin` / Welcome).
3. Optional email 2FA validation routes (`2fa-validation`, `confirmCode`, unblock flows).
4. If `user_type` is Buyer and Seller, portal-selection is required.
5. Session established; company and store context loaded for shop use.

**Implemented** in `Welcome.php` and filter exceptions in `Filters.php`.

### Buyer shop journey

1. Select / work in a store context.
2. Browse products (`shop/*`, `Products`).
3. Add items to cart(s) (`Carts`) — multi-cart and combine supported by schema/controllers.
4. Create order from cart (`Orders::createOrder`) — items grouped by seller company; supports scheduled dates.
5. Optional JAB order: distribute quantities across stores (`JabOrders`).
6. Submit to external TAF API (`ExternalOrderService`); failures can be retried; circuit breaker after repeated failures.
7. Track order statuses and item-level regrets; reorder from history.

**Order status validation (order header)** — **Implemented** in `OrdersModel`:

`Pending`, `Scheduled`, `Partially Supplied`, `Successfull` (spelling as in code), `Regret`, `Cancelled`.

**Order item statuses** — **Implemented** in `OrderItemsModel`:

`Pending`, `Successfull`, `Regret`, `Cancelled`.

UI or other code may reference additional status labels (e.g. Partially Completed). Those are **Requires confirmation** if used outside the model `in_list` rules.

### Seller journey

1. Login at `/seller` (`SellerPortal\SellerAuth`).
2. Dashboard / switch seller context.
3. Manage products; process unprocessed orders; update status; export Excel/PDF.
4. Analytics and settings screens.

**Implemented** under `app/Controllers/SellerPortal/` and `Routes.php` group `seller`.

### Admin / EDI journey

1. Configure companies and per-company transport methods (Folder / API / Email options in UI).
2. Maintain stores, seller groups, buyer groups, industries, products, price files.
3. Cron (`GET cronJobs`) runs DB-configured `cronjob_actions` (orders/invoices import/export, emails, reports, fault finder, etc.).
4. Operators use FaultFinder, Reports, ServerMonitoring for operations.

**Implemented.** Email EDI transport for some paths is noted as not fully implemented in `GetXMLData` comments (**Planned / incomplete**).

### Price file journey

Upload price file → mapping rules → application approve/reject → apply/restore/revert.

**Implemented** via `PriceFiles`, `PriceFileData`, `PriceFileMappingRules`, `PriceFileApplications`, `PriceFileTransformationService`.

## Functional requirements

### FR-001 — Session authentication

**Requirement:** Unauthenticated users cannot access protected screens; they are redirected to login.

**Who:** Any visitor.

**Trigger:** HTTP request to a non-excepted path.

**Expected behaviour:** `isLoggedIn` filter enforces session; excepted paths include `/`, login/register, password reset, 2FA, `cronJobs`, `store-api/*`, `organisations`, `tracking-pixel`, `slack`, unlock routes.

**Evidence:** `app/Config/Filters.php`.

**Implementation:** Implemented. Confidence: High.

### FR-002 — Menu authorization

**Requirement:** Logged-in users may only open menus granted to their role.

**Who:** Authenticated user.

**Trigger:** Request to a path not in the `isGranted` exception list.

**Expected behaviour:** Unknown menu → redirect `/`; known menu without grant → `blocked`. AJAX behaviour may skip menu check when logged in (see Authorization filter).

**Evidence:** `app/Filters/Authorization.php`, `user_menu` / `user_access`.

**Implementation:** Implemented. Confidence: High.

### FR-003 — Role set

**Requirement:** System supports Developer, Admin, Company Admin, Company User roles.

**Evidence:** `UserRole` seeder.

**Implementation:** Implemented (seeded). Confidence: High for seed names; production assignments **Unknown**.

### FR-004 — Buyer / Seller user types

**Requirement:** Users are typed as Buyer, Seller, or both, with a default portal and optional portal selection.

**Evidence:** Migration `2025-09-10-000001_AddUserTypeToUsersTable.php`, Welcome, header layout.

**Implementation:** Implemented. Confidence: High.

### FR-005 — Store-scoped shopping

**Requirement:** Buyer shopping runs in a store context; store membership is managed via store-user links.

**Evidence:** `StoreManagement`, `store_users`, shop controllers, session store id.

**Implementation:** Implemented. Confidence: High.

### FR-006 — Cart and order creation

**Requirement:** Buyers add products to carts and create orders; order creation groups line items by product company (seller).

**Evidence:** `Carts.php`, `Orders::createOrder`, carts/orders migrations.

**Implementation:** Implemented. Confidence: High.

### FR-007 — JAB multi-store orders

**Requirement:** Buyers can create JAB orders that distribute quantities across stores.

**Evidence:** `JabOrders.php`, order/cart type fields Standard Order / JAB Order.

**Implementation:** Implemented. Confidence: High.

### FR-008 — Order status lifecycle

**Requirement:** Orders and order items use constrained status lists (including the spelling `Successfull`).

**Evidence:** `OrdersModel`, `OrderItemsModel` validation rules.

**Implementation:** Implemented. Confidence: High for validated values.

### FR-009 — External Store API submission

**Requirement:** Orders can be submitted to an external StoreFront/TAF API with retries, logging, and a circuit breaker.

**Inputs:** Env `STORE_API_BASE_URL`, `STORE_API_KEY`, `STORE_API_ORG_NAME`.

**Constraints (config):** max 100 items; currencies ZAR/USD/EUR/GBP; VAT rates 0/0.15/0.20/0.25; max order value 1e6; rate limit 60/min; SSL verify false by default; timeout 30s; max retries 3.

**Evidence:** `Config/StoreApi.php`, `ExternalOrderService.php`.

**Implementation:** Implemented. Confidence: High for presence; production org mapping **Unknown**.

### FR-010 — Seller portal

**Requirement:** Sellers authenticate to a dedicated portal to manage products and orders and export documents.

**Evidence:** `SellerPortal/*`, routes group `seller`.

**Implementation:** Implemented. Confidence: High.

### FR-011 — Partner master data

**Requirement:** Operators manage sellers, seller groups, buyer groups, stores, industries, companies, and company users.

**Evidence:** Corresponding `*Management` controllers and routes.

**Implementation:** Implemented. Confidence: High.

### FR-012 — Price file pipeline

**Requirement:** Operators upload price files, define mapping rules, and approve/apply/revert applications.

**Evidence:** Price file controllers and `PriceFileTransformationService`.

**Implementation:** Implemented. Confidence: High.

### FR-013 — EDI import/export via cron

**Requirement:** Scheduled HTTP cron executes configured actions to get/export orders and invoices across transport methods.

**Constraints:** Cron window Mon–Fri approximately 08:00–23:00; production requires security key (**Implemented** in `CronJobs`).

**Evidence:** `CronJobs.php`, `cronjob_actions` table, `GetXMLData`, `Soap`, `Rest`.

**Implementation:** Implemented for Folder/SOAP/REST paths; Email transport incomplete per code comments. Confidence: Medium–High.

### FR-014 — Retailer integrations

**Requirement:** System exchanges EDI documents with Pick n Pay (SOAP), Shoprite (REST), M2North (SOAP), and folder drops.

**Evidence:** `Soap.php`, `Rest.php`, `GetXMLData.php`.

**Implementation:** Implemented. Partner onboarding rules **Unknown**.

### FR-015 — Fault finder and reports

**Requirement:** Operators can investigate faults (orders/invoices/products) and run fill-rate / BI / uninvoiced / sales reports.

**Evidence:** `FaultFinder.php`, `Reports.php`.

**Implementation:** Implemented. Confidence: Medium (large controllers; surface confirmed).

### FR-016 — Adverts

**Requirement:** Platform can manage in-shop adverts with expiry; expired adverts deactivate via Spark command.

**Evidence:** `AdvertsManagement.php`, `Commands/DeactivateExpiredAdverts.php`.

**Implementation:** Implemented. Confidence: High.

### FR-017 — System notifications

**Requirement:** Users receive system notifications that can be read/dismissed.

**Evidence:** `SystemNotifications` controller + migrations/seeds.

**Implementation:** Implemented. Confidence: High.

### FR-018 — Email queue and open tracking

**Requirement:** Outbound emails can be queued (`sent_queue`) and tracked via a public tracking pixel.

**Evidence:** `Email.php`, `EmailPixelTracking`, mail helper.

**Implementation:** Implemented. Confidence: High.

### FR-019 — Organisations JWT API

**Requirement:** Organisations resource supports login token issuance for API-style access.

**Evidence:** `$routes->resource('organisations')`, `JwtLibrary.php`.

**Implementation:** Implemented. Confidence: Medium.

### FR-020 — Developer tooling

**Requirement:** Developer role can use menu management (file generation), CRUD generator, DB viewers, ChatGPT page.

**Evidence:** `Developers/*`, `ChatGPT.php`.

**Documented** in README as menu management with auto-create controller/view.

**Implementation:** Implemented. Whether these are production-exposed is **Requires confirmation**.

### FR-021 — Payments

**Requirement:** Unknown. A payments data surface exists without gateway code.

**Evidence:** payments-related migrations/models; no gateway controllers found.

**Implementation:** Schema only / Unknown product intent. Confidence: Low.

## Integrations summary

| System | Direction | Purpose | Auth (known) |
|---|---|---|---|
| Transactflow Store API | Outbound | Submit shop orders | API key + org name from env |
| Pick n Pay SOAP | Bidirectional EDI | Orders / confirm / invoices | SOAP client / WSDL |
| Shoprite REST | Inbound/outbound EDI | Vendor orders | REST endpoints in GetXMLData/Rest |
| M2North SOAP | Outbound EDI | Invoices | SOAP |
| Folder XML | File drop | Orders/invoices | Filesystem under `writable/` |
| SMTP / email | Outbound | Notifications, EDI email (partial) | Env SMTP / SendGrid keys in template |
| Slack | Outbound | Alerts | Webhooks / helper |
| OpenAI | Outbound | ChatGPT UI | API key in env template |
| AWS | — | Declared unused | — |
| Salesforce / Africa's Talking | — | Stubs | — |

## Important constraints

- Auto-routing is enabled (`setAutoRoute(true)`), so controller methods may be reachable beyond explicit routes, subject to filters.
- Global CSRF is off.
- Cron and `store-api` are outside the login filter.
- Store API SSL verification defaults to false in config.
- Order status spelling includes `Successfull` (typo retained in validation).

## Documented vs implemented conflicts

| Topic | Documented | Implemented |
|---|---|---|
| Product identity | Admin Overdrive Starter / Transactflow | Full EDI shopfront (ShopFlow) |
| Features list | Auth, authz, registration, menus | Shop, seller portal, EDI, price files, etc. |
| PHP version | README 8.3 | composer.json `^8.0` |
| Env file location | README: copy `env` to `.env` | Template observed as `app/env` |
| AWS | Listed as included package / "likely" AWS features in overview | No app usage found |
| Testing | overview implies comprehensive suite | Only example PHPUnit tests |

## Unknown / Requires Confirmation

1. Official product name and brand for customers.
2. PHP version target for production.
3. Whether payments are planned or abandoned.
4. AWS SDK purpose.
5. Label* routes referencing missing controllers — obsolete?
6. Production Store API base URL, orgs, and SLAs.
7. Which companies use Folder vs SOAP vs REST vs Email.
8. CSRF disabled — intentional?
9. Cron security key management (hardcoded vs env).
10. Relationship of this repo to other EDI/Transactflow repositories.
11. Acceptance criteria living only in Jira/Confluence.
12. Invoice UI for buyers (routes/comments suggest partial exposure).
13. Multi-currency / VAT business policy beyond config lists.
14. QA strategy for retailer partner certifications.
