From 52c3a94a986cbe0e8ba3a7977545d5866c7ee170 Mon Sep 17 00:00:00 2001 From: Jacek Pyziak Date: Tue, 17 Feb 2026 23:43:40 +0100 Subject: [PATCH] Add CLAUDE.md with project guidance for Claude Code Co-Authored-By: Claude Opus 4.6 --- CLAUDE.md | 193 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..3b3c409 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,193 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +shopPRO is a PHP e-commerce platform with an admin panel and customer-facing storefront. It uses Medoo ORM (`$mdb`), Redis caching, and is undergoing a migration from legacy architecture to Domain-Driven Design with Dependency Injection. + +## PHP Version Constraint + +**Production runs PHP < 8.0.** Do NOT use: +- `match` expressions (use ternary operators or if/else) +- Named arguments +- Union types (`int|string`) +- `str_contains()`, `str_starts_with()`, `str_ends_with()` +- Other PHP 8.0+ syntax + +`composer.json` requires `>=7.4`. + +## Commands + +### Running Tests +```bash +# Full suite (recommended — PowerShell, auto-finds php) +./test.ps1 + +# Specific file +./test.ps1 tests/Unit/Domain/Product/ProductRepositoryTest.php + +# Specific test method +./test.ps1 --filter testGetQuantityReturnsCorrectValue + +# Alternative +composer test +``` + +PHPUnit 9.6 via `phpunit.phar`. Bootstrap: `tests/bootstrap.php`. Config: `phpunit.xml`. + +Current suite: **610 tests, 1816 assertions**. + +### Creating Updates +See `docs/UPDATE_INSTRUCTIONS.md` for the full procedure. Updates are ZIP packages in `updates/0.XX/`. Never include `*.md` files, `updates/changelog.php`, or root `.htaccess` in update ZIPs. + +## Architecture + +### Directory Structure +``` +shopPRO/ +├── autoload/ # Autoloaded classes (core codebase) +│ ├── Domain/ # Business logic repositories (\Domain\) +│ ├── Shared/ # Shared utilities (\Shared\) +│ │ ├── Cache/ # CacheHandler, RedisConnection +│ │ ├── Helpers/ # Helpers (formerly class.S.php) +│ │ └── Tpl/ # Template engine +│ ├── admin/ # Admin panel layer +│ │ └── Controllers/ # DI controllers (\admin\Controllers\) +│ ├── front/ # Frontend layer +│ │ ├── App.php # Frontend router (\front\App) +│ │ ├── LayoutEngine.php # Layout engine (\front\LayoutEngine) +│ │ ├── Controllers/ # DI controllers (\front\Controllers\) +│ │ └── Views/ # Static views (\front\Views\) +│ └── shop/ # Legacy shop classes (Product, Order, etc.) +├── admin/ # Admin panel +│ ├── templates/ # Admin view templates +│ └── layout/ # Admin CSS/JS/icons +├── templates/ # Frontend view templates +├── libraries/ # Third-party libraries +├── tests/ # PHPUnit tests +│ ├── bootstrap.php +│ ├── stubs/ # Test stubs (CacheHandler, Helpers, ShopProduct) +│ └── Unit/ +│ ├── Domain/ # Repository tests +│ └── admin/Controllers/ # Controller tests +├── updates/ # Update packages for clients +├── docs/ # Technical documentation +├── config.php # Database/Redis config (not in repo) +├── index.php # Frontend entry point +├── ajax.php # Frontend AJAX handler +├── admin/index.php # Admin entry point +├── admin/ajax.php # Admin AJAX handler +├── cron.php # CRON jobs (Apilo sync) +└── api.php # REST API +``` + +### Autoloader + +Custom autoloader in each entry point (not Composer autoload at runtime). Tries two filename conventions: +1. `autoload/{namespace}/class.{ClassName}.php` (legacy) +2. `autoload/{namespace}/{ClassName}.php` (PSR-4 style, fallback) + +### Namespace Conventions (case-sensitive on Linux!) +- `\Domain\` → `autoload/Domain/` (uppercase D — new directory) +- `\admin\Controllers\` → `autoload/admin/Controllers/` (lowercase a — existing directory) +- `\Shared\` → `autoload/Shared/` +- `\front\` → `autoload/front/` +- `\shop\` → `autoload/shop/` +- Do NOT use `\Admin\` (uppercase A) — the server directory is `admin/` (lowercase) + +### Domain-Driven Architecture (migration complete for admin + frontend) + +All modules use this pattern: + +**Domain Layer** (`autoload/Domain/{Module}/`): +- `{Module}Repository.php` — data access, business logic, Redis caching +- Constructor DI with `$db` (Medoo instance) +- Methods serve both admin and frontend (shared Domain, no separate services) + +**Admin Controllers** (`autoload/admin/Controllers/`): +- DI via constructor (repositories injected) +- Wired in `admin\App::route()` via `$newControllers` map + +**Frontend Controllers** (`autoload/front/Controllers/`): +- DI via constructor +- Wired in `front\App::getControllerFactories()` + +**Frontend Views** (`autoload/front/Views/`): +- Static classes, no state, no DI — pure rendering + +### Key Classes +| Class | Purpose | +|-------|---------| +| `\admin\App` | Admin router — maps URL segments to controllers | +| `\front\App` | Frontend router — `route()`, `checkUrlParams()` | +| `\front\LayoutEngine` | Frontend layout engine — `show()`, tag replacement | +| `\Shared\Helpers\Helpers` | Utility methods (SEO, email, cache clearing) | +| `\Shared\Tpl\Tpl` | Template engine — `render()`, `set()` | +| `\Shared\Cache\CacheHandler` | Redis cache — `get()`, `set()`, `delete()`, `deletePattern()` | + +### Database +- ORM: Medoo (`$mdb` global variable, injected via DI in new code) +- Table prefix: `pp_` +- Key tables: `pp_shop_products`, `pp_shop_orders`, `pp_shop_categories`, `pp_shop_clients` +- Full schema: `docs/DATABASE_STRUCTURE.md` + +### Form Edit System +Universal form system for admin edit views. Uses ViewModels (`FormEditViewModel`, `FormField`, `FormTab`, `FormAction`), validation (`FormValidator`), and rendering (`FormFieldRenderer`). Template: `admin/templates/components/form-edit.php`. Docs: `docs/FORM_EDIT_SYSTEM.md`. + +### Caching +- Redis via `\Shared\Cache\CacheHandler` (singleton `RedisConnection`) +- Key pattern for products: `shop\product:{id}:{lang}:{permutation_hash}` +- Clear product cache: `\Shared\Helpers\Helpers::clear_product_cache($id)` +- Config: `config.php` (`$config['redis']`) + +## Code Patterns + +### New code should follow DI pattern +```php +// Repository with constructor DI +class ExampleRepository { + private $db; + public function __construct($db) { + $this->db = $db; + } + public function find(int $id): ?array { + return $this->db->get('pp_table', '*', ['id' => $id]); + } +} + +// Controller wiring (in admin\App or front\App) +$repo = new \Domain\Example\ExampleRepository($mdb); +$controller = new \admin\Controllers\ExampleController($repo); +``` + +### File naming +- New classes: `ClassName.php` (no `class.` prefix) +- Legacy classes: `class.ClassName.php` (leave until migrated) + +### Test conventions +- Extend `PHPUnit\Framework\TestCase` +- Mock Medoo: `$this->createMock(\medoo::class)` +- AAA pattern: Arrange, Act, Assert +- Tests mirror source structure: `tests/Unit/Domain/{Module}/{Class}Test.php` + +## Workflow (AGENTS.md) + +When user says **"KONIEC PRACY"**, execute in order: +1. Run tests +2. Update documentation if needed: `docs/DATABASE_STRUCTURE.md`, `docs/PROJECT_STRUCTURE.md`, `docs/FRONTEND_REFACTORING_PLAN.md`, `docs/FORM_EDIT_SYSTEM.md`, `docs/CHANGELOG.md`, `docs/TESTING.md` +3. Prepare update package per `docs/UPDATE_INSTRUCTIONS.md` +4. Commit +5. Push + +Before starting implementation, review current state of docs (see AGENTS.md for full list). + +## Key Documentation +- `docs/PROJECT_STRUCTURE.md` — detailed project structure and module status +- `docs/REFACTORING_PLAN.md` — Domain migration plan and status +- `docs/FRONTEND_REFACTORING_PLAN.md` — frontend migration plan (mostly complete) +- `docs/DATABASE_STRUCTURE.md` — full database schema +- `docs/TESTING.md` — test suite status and history +- `docs/FORM_EDIT_SYSTEM.md` — form system architecture +- `docs/CHANGELOG.md` — version history +- `docs/UPDATE_INSTRUCTIONS.md` — how to build client update packages