# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview PrestaShop module (v0.1.0) implementing an electronic withdrawal declaration form for German B2C e-commerce. Fulfills EU consumer protection law requirements (Widerrufsrecht) by providing a documented receipt of withdrawal requests. **Compatibility**: PrestaShop 1.7.8+ / 8 / 9, PHP 7.2+ ## No Build System This is a classical PrestaShop legacy module with no npm, Composer, Makefile, or test framework. Deployment is via ZIP upload in PrestaShop Admin → Module Manager. ## Architecture ### Core Components | File | Role | |------|------| | `simple_withdrawalbutton.php` | Main module class: install/uninstall, config form, hook handlers, utility methods | | `controllers/front/withdraw.php` | Public front controller for the withdrawal form (no auth required) | | `controllers/admin/AdminSimpleWithdrawalController.php` | Backoffice list/detail view with status management | ### Request Flow 1. Customer clicks footer link (`displayFooter` hook) or account dashboard link (`displayCustomerAccount` hook) 2. `controllers/front/withdraw.php` handles two POST steps: - **Step 1** (`prepare`): validate + render `confirm.tpl` - **Step 2** (`confirm`): write to DB, send emails, render `success.tpl` 3. Two emails sent: customer confirmation + shop notification (configured admin email) ### Database Single table `ps_cyp_withdrawal_request`. Schema is defined inline in `simple_withdrawalbutton.php::install()` — no separate SQL files. Records are intentionally **not deleted on uninstall** (legal compliance). Key fields: `order_reference`, `withdrawal_scope` (ENUM: full|partial), `status` (ENUM: new|processing|closed), `customer_ip_hash` / `user_agent_hash` (SHA256, privacy). ### Security Model - CSRF token stored in session, validated on confirm step - Honeypot field (`website` input, must be empty) - Rate limiting: configurable max requests per email+IP hash per hour (default 5) - All DB queries use PrestaShop's `pSQL()` parameterization - IP and user-agent are hashed (SHA256) before storage ### Templates Smarty templates in `views/templates/front/` (form.tpl, confirm.tpl, success.tpl) and `views/templates/hook/`. Email templates in `mails/de/` and `mails/en/`. The items field in `form.tpl` is conditionally shown via vanilla JS only when `withdrawal_scope === 'partial'`. ## PrestaShop Conventions - Use `pSQL()` for all DB string interpolation; `(int)` cast for integers - Hook registration/deregistration in `install()`/`uninstall()` - Admin tab registered as `AdminSimpleWithdrawal` — the controller class name must match - Module config stored via `Configuration::get/updateValue()` - Email sending uses `Mail::Send()` with template files in `mails/{lang}/`