Files
mataba/shop/docs/DATABASE-MODEL.md
T

81 lines
4.4 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 – Database Model
## 1. Philosophy
Reuse WP/WC primitives. No custom tables in v1.0 – revisit via ADR if query scale warrants. Document every key.
## 2. WordPress-Owned
- **Users** (`wp_users`, `wp_usermeta`): native. XShop adds: `xshop_wishlist` (array of product IDs), `xshop_compare` (array), `xshop_recently_viewed` (capped list).
- **Posts/Pages** (`wp_posts`, `wp_postmeta`): native.
- **Media** (`wp_posts` attachment): native.
- **Menus** (`wp_terms` nav_menu): native.
- **Comments/Reviews**: WC reviews = WP comments on `product` post type. XShop Q&A moderation hooks onto comment moderation flow where applicable – but primary store is custom (below).
## 3. WooCommerce-Owned
- **Products** (`wp_posts` post_type `product` + `wp_postmeta` + `wp_wc_*` where HPOS enabled). Variations are `product_variation` children.
- **Orders/Customers/Coupons/Shipping/Payment/Taxes/Cart/Checkout**: WC owned (HPOS tables if enabled). XShop never writes directly to WC order tables except via WC APIs.
## 4. XShop-Core Custom Data
### 4.1 Banners – CPT `xshop_banner`
- `post_type = xshop_banner` (non-public, `show_ui` true under XShop menu).
- Meta:
- `_xshop_banner_image` (attachment ID, int)
- `_xshop_banner_mobile_image` (attachment ID, int, nullable)
- `_xshop_banner_link` (url, esc_url_raw)
- `_xshop_banner_cta` (string)
- `_xshop_banner_position` (enum: `home_hero`, `home_strip`, `shop_top`, `product_sidebar`, etc.)
- `_xshop_banner_active` (`1`|`0`)
- `_xshop_banner_start` / `_xshop_banner_end` (datetime Y-m-d H:i:s, UTC)
- `_xshop_banner_order` (int)
- Scheduling checked on render (skip if outside window or inactive).
### 4.2 Questions & Answers – CPT `xshop_qa`
Decision: CPT (not comments) for cleaner moderation + threading without polluting reviews.
- `post_type = xshop_qa`, `post_parent` = product ID (or meta `_xshop_qa_product_id` for query flexibility – both stored, parent is canonical).
- Post fields: `post_title` empty, `post_content` = question body, `post_status` = `pending`|`publish`|`trash`, `post_author` = asker.
- Meta:
- `_xshop_qa_product_id` (int, indexed via meta query)
- `_xshop_qa_answer` (string, nullable – single answer for v1; extension to multiple answers uses child `xshop_qa` rows with `post_parent` = question ID in v1.1)
- `_xshop_qa_answered_by` (int user ID)
- `_xshop_qa_answered_at` (datetime)
- Alternative for multiple answers (future): child posts `post_type=xshop_qa`, `post_parent=question ID`.
- Spam: honeypot + nonce + rate limit (transient per IP/user, 60s).
### 4.3 Wishlist & Compare
- **Logged-in**: `wp_usermeta` keys `xshop_wishlist`, `xshop_compare` (serialized array of ints, capped: wishlist 200, compare 4).
- **Guest**: cookie `xshop_wishlist` / `xshop_compare` (JSON, HttpOnly false for JS count, SameSite Lax, 30 days) + optional transient `xshop_guest_<token>`.
- On login: merge cookie → user meta (union, cap), clear cookie.
- Counts exposed via REST and localized script data.
### 4.4 Recently Viewed
- Cookie `xshop_recently_viewed` (JSON array of product IDs, capped 20, 30 days). No DB write for guests. Logged-in also stored in `xshop_recently_viewed` user meta for cross-device.
## 5. Options
- Single option `xshop_settings` (array) – all Theme Options. Autoload `yes`. Individual mods also mirrored via `theme_mod` for Customizer preview where needed, but source of truth is `xshop_settings`.
- Option `xshop_settings_backup` (for import/export).
- Transient `xshop_search_cache_<hash>` (5 min) for AJAX search results.
- Transient `xshop_filter_counts_<hash>` (5 min) for filter counts.
Do NOT scatter random options.
## 6. Indexes & Query Patterns
- Banners: query by `post_type` + meta `position`+`active`+date range → meta query; small cardinality.
- Q&A: `WP_Query` by `post_type=xshop_qa` + `post_parent=product_id` + `post_status=publish` (index on `post_parent` + `post_type` already exists).
- Wishlist/Compare: user meta single-row lookup – O(1).
- Search: `WP_Query` with `s` + `post_type=product` + `tax_query` for category, `meta_query` for SKU (`_sku`), limited to 8 suggestions, `no_found_rows` true, `fields=ids` then prime caches.
## 7. Migrations & Compatibility
- HPOS: use `wc_get_products()` / CRUD, not direct `wp_postmeta` writes for product data.
- On plugin deactivate: data retained (no destructive cleanup). Uninstall hook offered to purge (`uninstall.php` with confirmation).