Files
mataba/shop/docs/ARCHITECTURE.md
T

157 lines
8.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# XShop – Architecture (v1.0.0)
## 1. Overview
```
repo/
docs/ # product specs & ADRs
xshop-theme/ # presentation layer
xshop-core/ # companion plugin
release/ # built zips (not committed)
tools/ # build / QA scripts
```
Two installable artifacts: theme (`xshop`) + plugin (`xshop-core`). Theme never stores business logic that outlives theme activation (wishlist/compare/Q&A/banners live in plugin).
## 2. Theme – `xshop-theme`
### 2.1 File map (M4)
```
xshop-theme/
inc/setup/assets.php — tokens→…→woo→utilities + theme.js + search.js + filter.js (front-end, DOM guard, documented)
inc/woocommerce/setup.php — loop, toolbar, gallery, related, product.js, pre_get_posts no-JS fallback
assets/css/woo.css — + search + filters (.xshop-shop, _filters, _chip, _drawer, responsive)
assets/js/search.js — debounce 250ms, AbortController, stale seq
assets/js/filter.js — URL sync, chips, debounce 300ms for price, AbortController, drawer a11y
template-parts/components/ajax-search.php + product-filters.php (sidebar+drawer, no-JS fallback)
woocommerce/archive-product.php — shop/category with filters layout + chips + AJAX grid
xshop-core/
includes/Query/ProductQuery.php — shared sanitize, map_orderby, build_product_query_args, format_product, execute_query
includes/REST/Search.php — refactored to use Query
includes/REST/Products.php — xshop/v1/products (category, pa_*, price, stock, sale, rating, orderby, pagination, search)
includes/Core/Plugin.php — loads Query + both REST
```
### 2.2 Bootstrap
`functions.php` is a thin loader:
```php
require_once __DIR__ . '/inc/setup/theme-support.php';
require_once __DIR__ . '/inc/setup/menus.php';
// ... each file exposes a single setup function hooked appropriately
```
No giant `functions.php`. Each `inc/*` file is namespaced or prefixed `xshop_`.
### 2.3 Namespacing & Prefixing
- Text domain: `xshop`
- PHP functions/options/actions/meta: `xshop_` prefix.
- Classes: `XShop\Theme\...` and `XShop\Core\...` (PSR-4 style even if manual require).
### 2.4 Hook Strategy
- Use `after_setup_theme` for theme support, `init` for CPT/taxonomy (only banners/Q&A).
- Use `wp_enqueue_scripts` with conditional loading.
- Use WC hooks for pricing, badges, loops – avoid overriding templates unless necessary.
## 3. Plugin – `xshop-core`
```
xshop-core/
xshop-core.php # plugin header + loader
includes/
Core/ # plugin bootstrap, constants
Modules/
Wishlist/
Compare/
QA/
Search/
Filter/
Banners/
Badges/
DemoImport/
SetupWizard/
SystemStatus/
Widgets/
Admin/ # menu, dashboard, settings pages
REST/ # REST endpoints (search/filter/wishlist/compare/QA)
Compatibility/
assets/ css/ js/
languages/
templates/ # wishlist, compare, banners front-end fragments
```
Plugin owns persistence for wishlist/compare/Q&A/banners. Theme only renders.
## 4. Data Ownership
- **WC**: products, variations, orders, customers, coupons, shipping, payment, taxes, cart, checkout.
- **WP**: users, posts, pages, media, menus, comments.
- **Custom**: banners (CPT `xshop_banner`), Q&A (CPT or comments extension – see DATABASE-MODEL.md), wishlist/compare (user meta + cookie + transient for guests), theme settings (single option `xshop_settings` + mods).
Avoid custom tables in v1; revisit via ADR if scale demands.
## 5. Design System (M2)
Tokens: `tokens.css` unchanged — adds WC tokens `--xshop-wc-badge-sale/--xshop-wc-price` etc. Layering `tokens→base→layout→components→woo→utilities→style.css` (woo.css 159 lines, tokens for shop/product/cart). Dark mode semantic swap covers `bg/surface/card/text/muted/border/input/focus/link/notice` — verified on shop/card/gallery/tabs/cart/checkout. Logical props only, zero `left/right`.
## 6. Asset Strategy (M2)
- Vanilla JS: `theme.js` (deferred) + `product.js` (enqueued only on `is_product()` via `xshop_wc_single_setup` guard). No gallery framework, 40 lines, keyboard Arrow/Home/End.
- Enqueue: `tokens→base→layout→components→woo→utilities→style.css` chain in `inc/setup/assets.php:1` (`woo.css` **intentionally global** 12KB — replaces Woo's 3 stylesheets, avoids FOUC on shop/product/cart/account; documented, tiny vs conditional complexity). WC styles dequeued (`woocommerce_enqueue_styles → __return_empty_array`). `product.js` conditional, `comment-reply` conditional.
- Localized `xshopData` on `xshop` handle. No jQuery for theme code; Woo's jQuery remains for variations/add-to-cart.
- Build: `tools/build-release.ps1` now includes top-level folder `xshop/` wrapper (fixed in M1.1).
## 7. AJAX / REST (M4)
- **Search** (M3): `GET /wp-json/xshop/v1/search?search=&limit=` — public, `search` max 100 + `limit` 1..20, min 2, `WP_Query s` + `_sku LIKE`, `publish` only, `no_found_rows` `fields ids`, `{items:[id,title,url,image,price_html,type,in_stock],total}` + `Cache-Control: public, max-age=60`, shared `Query\ProductQuery`.
- **Products** (M4): `GET /wp-json/xshop/v1/products?search=&category=&pa_*=&min_price=&max_price=&stock=&on_sale=&rating=&orderby=&page=&per_page=` — public, sanitized `search` + `category` slug/ID + dynamic `pa_*` (only `taxonomy_exists`), `min/max` numeric 0..99M + `min<=max` 400, `stock all/instock/outofstock`, `on_sale 0/1` via meta OR, `rating 0..5` via `_wc_average_rating`, `orderby` allow-list `default/latest/price_asc/desc/popularity/rating/date` → `map_orderby`, `page 1..100` `per_page 1..24` default 12, shared `ProductQuery::build_product_query_args` → `WP_Query` `tax_query` + `meta_query` + `orderby` + `post__in` for sale, `execute_query` → `{items, pagination:{page,per_page,total,total_pages}}` + `Cache-Control: public, max-age=30`, no private data, no N+1.
- Prefer REST for search/filter, fallback `admin-ajax` for cart.
## 8. Security Model
See `SECURITY.md`. TL;DR: sanitize in, escape out, nonces, capability checks, prepared statements, no `unserialize`, no open redirects.
## 9. Performance Model
See `PERFORMANCE.md`. Conditional assets, lazy-load, transients for expensive queries, no N+1, `wp_cache`.
## 10. i18n / RTL
- All strings via `__()`, `_e()`, `esc_html__()` with text domain `xshop`.
- Logical CSS, `dir` attribute toggling, `is_rtl()` branching only where logical props insufficient.
- Persian typography tokens, `lang="fa"` support, mixed LTR numbers handled via `unicode-bidi` where needed.
## 11. Templating (M2)
`header.php` → `site-header` + breadcrumbs; `footer.php` → `site-footer`. Content templates use Loop + `get_template_part`. Reusable: `product-card.php:1` (WC_Product badges/price/rating, hook `xshop_product_card_after_actions`), `product-grid.php:1`, `product-gallery.php:1` (featured+thumbs, keyboard). `front-page.php` section-based via `xshop_front_hero_args`.
**Woo overrides (4, all minimal, versioned):**
- `woocommerce/content-product.php` (3.6.0) — Why: grid/token alignment; Hooks/CSS insufficient (li.product markup). Minimal: single `<li>` + `get_template_part product-card`. Risk: Woo 3.6 → bump → re-check `wc_product_class`.
- `woocommerce/archive-product.php` (3.4.0) — Why: XShop header (category title/desc/count) + toolbar + empty-state CTA. Hooks could do header but empty-state needs override. Minimal.
- `woocommerce/content-single-product.php` (3.6.0) — Why: grid layout `.xshop-product` gallery+summary + custom gallery component. Hooks alone can't provide grid wrapper without CSS hacks. Minimal: wraps hooks, replaces `woocommerce_show_product_images`.
- `woocommerce/single-product.php` (1.6.4) — Delegator to `content-single-product.php`; kept for explicitness, could be removed (Woo default works) but retained for clarity.
All keep Woo hooks (`woocommerce_before_single_product`, `woocommerce_single_product_summary`, `woocommerce_after_single_product_summary` etc.) — no business logic rewrite. `inc/woocommerce/setup.php:1` handles `loop_start/end` filter (`xshop-products`), toolbar `woocommerce_before_shop_loop` 9/35, remove gallery, related args `posts_per_page 4 columns 4`.
## 12. Decision Records
ADRs in `docs/ADR/` – one per major decision (e.g., “No custom tables for Q&A in v1”).
## 13. Release
`release/xshop.zip` + `release/xshop-core.zip` built via `tools/build-release.ps1`. Excludes `.git`, `node_modules`, `.env`, logs, temp.
## 14. Versioning
SemVer 1.0.0. `CHANGELOG.md` follows Keep a Changelog.
## 15. Risks & Mitigations
- WC API churn → pin tested versions, monitor template versions, use hooks not overrides.
- RTL regressions → logical props + visual regression checklist.
- Demo import timeouts → chunked importer with resume.