# AVOLEEN supplied-code audit and Phase 1 patch

Prepared 11 November 2026 (Asia/Dhaka). Status: tested local update candidate; production acceptance remains open. Phase 2 has not started.

## Scope and evidence

Reviewed the supplied root-domain PHP marketplace, its active PHP dependencies, JavaScript/CSS entry points, database schema and archived root/payment error logs. All 76 active PHP files pass PHP 8.2.12 syntax checks. The supplied SQL was imported into a separate local MariaDB 10.4.32 database; all 36 tables and their supplied indexes/constraints were available. Checkout preflight passed against that schema.

The archive contains 70,371 entries: OLD_BACKUP accounts for 69,394 entries and arp-it_ltd for 687. Those are separate legacy/unrelated trees, inventoried but not exhaustively security-audited or modified. This report is an audit of the supplied active marketplace, not certification of every bundled legacy application or the current production host. No hosting login, production database connection, live server logs, real payment transaction, email/SMS/courier request, or paid AI operation was used. The attached brief was used as project requirements within the user's explicit audit/Phase 1 scope; its later phases and production actions were not treated as separate authorization.

The original ZIP and SQL remain unchanged. Only isolated working copies were edited; synthetic QA fixtures existed only in the isolated local database. No fixtures, customer records, passwords, API keys, database credentials, configuration files, logo files, product assets, or SQL data are shipped in the patch.

## Prioritized findings

| Priority | Finding and evidence | Resolution / next action |
|---|---|---|
| P1 | `app/order-v41.php` is absent but required by `order-summary.php` and `order-request.php`. These routes fail before their intended access checks. | Added a small read-only compatibility helper using the current V53 ownership/token reads. Tested both routes. |
| P1 | `av54_update()` writes the action `confirm` as a workflow state, while `av54_allowed()` permits processing only from `confirmed`. | Map confirm to confirmed. Tested confirmation, processing, stale revision rejection and cancellation. No historical data rewrite. The supplied historical orders did not contain the malformed confirm state. |
| P1 | Payment validation treated a missing risk result as low risk; amount casting accepted malformed numeric prefixes. | Missing/unknown risk results require review; payment amounts must be numeric currency amounts and match the saved payable amount. Tested rejection and review paths. |
| P1 | A valid late payment could consume a released reservation or progress the legacy order status without staff confirmation. | Lock the order before payment updates; cancelled/returned/released cases require review. Payment verification no longer changes fulfillment status. Tested duplicate and late callbacks. |
| P1 | Retry checks initially used a previously loaded order/reservation; cancellation could occur before the transaction lock. | Recheck order and reservation under the same order-first lock pattern. Use locked saved amount for gateway initiation. Tested successful and blocked retry with simulated provider responses. |
| P1 | Guest-facing retry/return/summary/request/quote routes lacked a consistent private no-store/referrer policy. | Added private headers. Tested unauthorized access and payment return. Existing confirmation/tracking private headers remain. |
| P2 | Tracking omitted Ready to Ship and rendered on-hold/delivery-failed states as Order Received. | Added truthful labels and the missing progress step. Responsive measurements and screenshots cover tracking/confirmation. |
| P2 | Public reference SQL `LPAD(id,5,'0')` truncates IDs beyond five digits. | Preserve longer IDs using GREATEST/CHAR_LENGTH. Tested six-digit reference calculation. Existing public IDs are unchanged. |
| P2 | Cart quantities were silently cast to integers; noncanonical keys could represent the same product more than once. Negative coupons could increase payable amounts. | Validate integer quantities and canonical item keys, stabilize product lock order, clamp coupon discounts at zero. Tested invalid inputs and concurrent stock competition. |
| P2 | Archived 16 October 2026 fatal logs show missing V41 requires in older `/avoleen-v30/` confirmation/tracking pages. | Current root confirmation/tracking already use V52/V53 and load successfully locally. Those historical logs do not establish a current production 500. Current hosting logs are still needed for production diagnosis. |
| P2 | A 15 October payment log records gateway HTTP 500. | Existing fail-safe remains; tested provider outage without losing the committed order. Real provider connectivity remains unverified. |
| P2 | Reservations contain a 45-minute expiry field, but no automatic expiry/reconciliation worker was found in the active code. | Keep conservative manual reconciliation. Do not release uncertain online payments solely because a timer elapsed. Design a separately tested operational worker later. |
| P2 | Root access rules do not broadly deny archived SQL/ZIP/log files; legacy application trees remain inside the web root. | Potential exposure, not verified by public HTTP requests. Inventory hosting-accessible backup paths and isolate/deny them with host-specific tests; do not delete unrelated applications. |
| P2 | Login uses password verification, session regeneration and a delay, but no shared per-account/IP rate limit was found. Tracking lookup rate limiting is session-only. | Add persistent rate limits in a subsequent security patch with hosting compatibility tests. |
| P2 | Several legacy error paths outside the main patched checkout can echo exception messages (for example quote approval). | Complete a broader error-boundary pass; keep production display_errors off. Core injected checkout SQL failure was verified to return a safe message. |
| P3 | Shared header/footer retain staging/payment-inactive copy and inconsistent storefront navigation; homepage adds later CSS/JS layers. | Phase 2 should reconcile shared components while preserving working routes and the gold logo. |
| P3 | Wishlist/cart are session-based; search suggestions match names and categories, not SKU/fuzzy search. Photo search is a preview rather than a verified vision service. | Phase 2 account persistence/search work; show only capabilities supported by the configured service. |
| P3 | Demo catalog seeder remains available to super admin. | Preserve existing products; verify real catalog provenance with the owner. Do not invoke the seeder or remove catalog records automatically. |

## Dependency map

- `checkout.php` → bootstrap/session/PDO → payment V38, checkout V40/V42, locations V44, checkout V50, confirmation V51 → order, item, stock, reservation, payment-attempt, coupon and courier tables.
- Checkout writes order + items + stock + reservation + payment + attempt linkage in one transaction. Gateway initiation occurs after commit. A failed gateway initiation leaves an existing order for review.
- `payment/notify.php` and `payment/return.php` → payment V38 → server-side validation → saved transaction and amount checks → payment/reservation updates. Browser success alone does not prove payment.
- `payment/retry.php` → checkout access helper + payment V38 → previous transaction query → locked eligibility check → new attempt for the same order.
- `order-complete.php` → order-read V53 + confirmation V52 + bootstrap → authorized order reads, optional item/payment/courier/parcel reads. No stock/order mutation.
- `track-order.php` → order-read V53 + bootstrap → authorized order/item/payment/parcel/event reads. No stock/order mutation.
- `order-summary.php`, `order-request.php` → new compatibility V41 → V53. The helper is read-only; the request endpoint retains its existing support-request insert.
- `admin/orders.php`, `admin/orders-v40.php` → order-workspace V54 → staff-control V55 → permission, revision, workflow, reservation, stock and event records.
- Product editor → inventory V43, product V46, media V34, description V48, category/import V49. Existing import SSRF controls include public-IP validation, pinned resolution, HTTPS and bounded responses. Upload handling uses MIME allowlists, randomized filenames and size limits. These observations are static review, not a complete adversarial test.
- AI settings/jobs/blocks V48 and supplier integrations remain unchanged. Provider keys stay server-side; real generation/import was not exercised.
- Homepage V56 plus later asset overrides, product cards and shared bootstrap remain unchanged. No frontend redesign or new imagery was introduced.

The machine-readable dependency map records all literal active PHP includes and the original two missing V41 references. It is a before-patch map; the patch supplies that missing file.

## Phase 1 implementation plan and outcome

1. Preserve originals and create isolated source/database copies — done.
2. Trace active checkout, payment, stock, confirmation, tracking and staff-state dependencies — done within the supplied marketplace scope.
3. Fix confirmed dependency/state/verification issues with small changes — implemented in 12 existing files plus one compatibility helper.
4. Verify local HTTP and database behavior, failure rollback, duplicate requests, concurrent stock use and payment callback logic — passed as detailed in testing results.
5. Inspect confirmation/tracking at 1440, 1024, 768, 390 and 360 pixels — screenshots saved; measured document width did not exceed viewport width. No approved visual references were supplied for comparison.
6. Validate the production environment and actual provider round trip on staging before release — not performed; remains the release gate.

## Database and preservation

No migration is required for the supplied schema. No SQL is shipped. Existing orders, users, products, media, categories, credentials and payment configuration are preserved. Checkout still uses Inside Dhaka ৳80 / Outside Dhaka ৳120 exactly once, CSRF, server-side product prices, unique request keys and conditional stock deductions. This patch does not reinstall any component or replace database tables.

PHP syntax minimum remains 8.1 because the existing code uses never/match/str_starts_with. Tests used PHP 8.2.12 and MariaDB 10.4.32; the historical host logs mention PHP 8.3, which was not available for local verification. Required extensions include PDO MySQL, mbstring, JSON and cURL for real gateway requests. The root-domain base URL in the supplied configuration is already https://avoleen.com; it is not overwritten.

## Exact deployment paths

- `public_html/app/checkout-v40.php` (update)
- `public_html/app/confirmation-v52.php` (update)
- `public_html/app/order-read-v53.php` (update)
- `public_html/app/order-v41.php` (add)
- `public_html/app/order-workspace-v54.php` (update)
- `public_html/app/payment-v38.php` (update)
- `public_html/checkout.php` (update)
- `public_html/confirm-delivery.php` (update)
- `public_html/order-request.php` (update)
- `public_html/order-summary.php` (update)
- `public_html/payment/retry.php` (update)
- `public_html/payment/return.php` (update)
- `public_html/track-order.php` (update)

See INSTALL-ROLLBACK.md for backup, installation, hash checks and rollback; TESTING.md for passed, failed and unperformed tests. Production deployment was not performed. Full Phase 1 production acceptance and a complete legacy-tree security audit remain open.
