346ee7b616
- Remove double pSQL() escaping in Db::insert/update calls (data corruption fix) - Rename honeypot field from 'website' to 'cyp_hp_v1' to prevent browser autofill false positives - Wrap Mail::Send() in try/catch; capture shop notification result to detect failures - Scope order lookup to current shop (multi-shop fix) - Translate scope_label and email subjects per language (de/en) - Make formatDateTimeForMail() language-aware - Add GDPR Art. 13 privacy notice to withdrawal form - Add configurable privacy policy URL and Widerrufsbelehrung link - Add configurable retention period and manual purge button in admin settings - Show full submitted data on success page as proper receipt - Fix admin redirect URL format in processStatusUpdate() - Remove IP/UA hash display from admin detail view (GDPR data minimization)
60 lines
2.8 KiB
Markdown
60 lines
2.8 KiB
Markdown
# 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 |
|
|
|------|------|
|
|
| `cyp_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/AdminCypWithdrawalController.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 `cyp_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 `AdminCypWithdrawal` — the controller class name must match
|
|
- Module config stored via `Configuration::get/updateValue()`
|
|
- Email sending uses `Mail::Send()` with template files in `mails/{lang}/`
|