# POS System Architecture Overview ## MVC-Inspired Structure This point-of-sale application keeps presentation, process control, and data logic clearly separated even without a heavyweight framework. ### Model (Data & Business Logic) - Implemented through MySQL plus PDO helper scripts (`db_connect.php`, `cart_handler.php`, `checkout_process.php`). - Responsible for inventory management, cart arithmetic, and all persistence concerns. - Centralizes transaction rules so the UI layer stays thin and secure. ### View (Presentation) - Built with touch-friendly HTML/CSS screens such as `login.php` and the main `pos.php` interface. - Embeds only the minimal PHP needed to render server-provided data, keeping logic out of the UI. - All dynamic values are wrapped with `htmlspecialchars()` before display to mitigate XSS. ### Controller (Routing & Security) - Handled by processing scripts (`auth_process.php`, `cart_handler.php`, `checkout_process.php`). - Validates user input, manages PHP sessions, enforces authorization, and orchestrates requests between the view and model layers. ## Security & Reliability Pillars Security drives every implementation decision. Key practices include: 1. **SQL Injection Prevention** – Every database call uses PDO prepared statements so SQL commands stay independent of user-supplied data. 2. **Password Hygiene** – Credentials are hashed with `password_hash()` and verified with `password_verify()`; plain-text passwords are never persisted. 3. **Cross-Site Scripting Protection** – UI templates escape all user-facing content via `htmlspecialchars()` before injecting it into the DOM. 4. **Transactional Integrity** – `checkout_process.php` encapsulates checkout within `beginTransaction()`, `commit()`, and `rollBack()` to guarantee atomic writes across the sales, line items, and inventory tables. 5. **Graceful Error Handling** – All PDO exceptions are caught, sanitized, and logged via `error_log()` so sensitive internals never reach the cashier terminal. ## End-to-End Flow 1. **Authentication** - `login.php` presents the form; submissions post to `auth_process.php`. - The processor looks up the user with PDO, verifies the password hash, then establishes the session (`$_SESSION['logged_in']`, `$_SESSION['user_id']`, `$_SESSION['role']`). 2. **POS Interaction** - The cashier works inside `pos.php`, which renders a three-panel layout (Product Grid, Cart Display, Action Pad). - Selecting a product triggers JavaScript that sends an AJAX call to `cart_handler.php`. - `cart_handler.php` updates `$_SESSION['cart']`, recalculates totals, and responds with JSON so the front end can refresh without a full page load. 3. **Checkout Finalization** - Pressing **Process Payment** posts the finalized cart to `checkout_process.php` via AJAX. - The script wraps database writes in a PDO transaction: recording the sale, logging each item, adjusting `products.stock_quantity`, and rolling back on any failure. - Upon success, the session cart is cleared and the client receives confirmation for receipt printing. ## Productivity Features - **Cart Reordering** – Each line item now includes up/down controls so cashiers can rearrange the receipt order before checkout. The backend stores a stable ordering array alongside cart contents to keep sessions consistent. - **Dedicated Product Management (Managers)** – Managers have quick links to `product_admin.php` for CRUD-style catalog maintenance and `product_order.php` for arranging the product grid order with smooth drag-and-drop handles. Both pages validate CSRF tokens, enforce roles, and submit through `product_handler.php`. - **Sales Insights Dashboard** – `sales_report.php` surfaces daily and monthly KPIs (revenue, transaction count, payment mix, top movers) so managers can monitor performance without digging through the database. ## Operational Notes - Sessions and database credentials should be configured via secure environment variables or per-host config files. - Additional logging (e.g., transaction IDs per request) can aid audits without exposing sensitive data to operators. - Future enhancements—such as role-based access or offline caching—can slot naturally into this structure because the concerns remain decoupled. ## Getting Started ### Prerequisites - PHP 8.1+ with the PDO MySQL extension enabled. - MySQL 8 (or compatible) server. - Composer is optional; this project uses native PHP only. ### Install & Configure 1. Copy the repo to your web root or run locally. 2. Create a MySQL database/user and grant privileges. 3. Import the schema and starter data: ```bash mysql -u root -p < database/schema.sql mysql -u root -p < database/seed.sql ``` 4. If you're upgrading from a previous version without the `display_order` column, run the migration script: ```bash mysql -u root -p < database/migrations/20231117_add_display_order.sql ``` 5. Export environment variables (or edit `config.php`) so the app can reach your database: ```bash export DB_HOST=127.0.0.1 export DB_PORT=3306 export DB_NAME=pos_app export DB_USER=pos_user export DB_PASS=secret ``` 6. Launch PHP's built-in server from the project root: ```bash php -S localhost:8000 ``` 7. Visit `http://localhost:8000/login.php` and sign in with the seeded credentials `manager` / `password`. ### Directory Overview - `auth_process.php`, `cart_handler.php`, `checkout_process.php`: controllers handling auth, cart AJAX, and checkout transactions. - `login.php`, `pos.php`: presentation layer. - `assets/css`, `assets/js`: styling and client-side interactions. - `database/schema.sql`, `database/seed.sql`: schema and sample data for MySQL. - `docs/system-plan.md`: implementation blueprint and data model reference. - `product_admin.php`: manager-only UI for creating items and reviewing the catalog. - `product_order.php`: manager-only page with drag-style controls for arranging product tiles. - `sales_report.php`: manager-only reporting hub showing daily/monthly rollups, payment mix, and top-selling products. - `services/report_service.php`: aggregations for sales KPIs that back the reporting UI. ### Security Checklist - Ensure HTTPS is enforced in production; adjust `config.php` cookie settings if you serve from a different domain. - Rotate the seeded `manager` password immediately in live environments. - Consider enabling HTTP Basic Auth or IP allow lists around `/login.php` and `/pos.php` if terminals reside on a secure LAN. ### Troubleshooting - **Blank page?** Check the PHP error log; PDO connection failures are logged via `error_log()`. - **Cart not updating?** Inspect browser dev tools to confirm AJAX requests carry the CSRF header/token and the PHP session persists. - **Stock mismatches?** The checkout script locks rows via `SELECT ... FOR UPDATE`; ensure MySQL tables use InnoDB. - **Cannot add products?** Only users with the `manager` role may access the inline catalog form. Promote the account or insert a manager row directly in the `users` table for setup.