--- name: project-tomsjavajive description: Tom's Java Jive coffee shop e-commerce — DB creds, admin portal map, known schema quirks, and fixed bugs metadata: type: project originSessionId: 002fe81e-7e03-414d-b842-1f94f1390a22 --- PHP e-commerce site for a Fort Worth coffee shop. On DO server 165.22.1.228. ## Credentials & Access - **SSH:** root / Gonewalk1974!@# @ 165.22.1.228 - **DB:** toms_tjj_db / toms_tjj_user / +60wlPc+55e@gFq4 (localhost) - **Admin login:** `admin@tomsjavajive.com / Joker1974!!!` OR `myronblair@outlook.com / Joker1974!!!` (both work, reset 2026-06-14) - **Stripe:** placeholder keys in config (test mode — real keys must be added manually) - **GitHub:** myronblair/tomsjavajive (private) ## File Structure ``` /home/tomsjavajive.com/public_html/ admin/ — admin portal includes/header.php — nav (Content group: Splash Box, About Us Text; Catalog group: Import/Export at bottom) customers.php — customer CRUD + wallet adjust reviews.php — review list + inline edit modal with star picker splashes.php — Homepage splash blocks CRUD (drag-drop image upload, icon picker, drag-to-reorder) about-us.php — About Us text CRUD (live preview, paragraph-aware) import-export.php — Inventory export CSV + import CSV (smart/replace) + inline table editing api/upload-splash.php — handles splash image uploads → /uploads/splashes/ api/ — backend API endpoints account/ — customer-facing portal wishlist.php rewards.php reviews.php config/ config.php — site config (Stripe, SendGrid, etc.) — in git database.php — DB credentials — GITIGNORED includes/ — shared PHP includes uploads/splashes/ — splash block images (owned nobody:nobody, 755) ``` ## Database Schema Notes - **products table:** no `slug` column — product URLs use `?id=product_id` (not `?slug=`) - **wallet_transactions.type enum:** deposit, withdrawal, purchase, refund, reward, loyalty_redemption, credit, debit - **loyalty_transactions.type enum:** earn, redeem, adjustment, birthday_bonus, referral_bonus, referral_welcome, tier_upgrade - **customers table:** has `lifetime_points` (INT) and `loyalty_tier` (VARCHAR 20) columns added 2026-05-22 - **Collation:** ALL tables must be utf8mb4_unicode_ci — mixed collation (general_ci vs unicode_ci) causes JOIN errors (MySQL 1267) ## Admin Nav Groups - **Dashboard** — dashboard.php - **Catalog** — products, categories, inventory, import-export - **Orders** — orders, fulfillment - **Customers** — customers, reviews - **Content** — splashes (Splash Box), about-us (About Us Text) - **Analytics, Settings, etc.** ## Homepage DB-Driven Sections - **Splash blocks:** `homepage_splashes` table → feature cards above products (scrollable if >4) - **About Us text:** `about_us_sections` table → paragraphs under "Our Story" heading ## Google Merchant Feed — Fixed 2026-06-17 - Feed URL: `https://tomsjavajive.com/merchant-feed.php` - Title was being built as `$p['name'] . ' ' . $categoryLabel . ' Coffee'` — doubled the suffix for products whose names already include "Whole Bean Coffee" / "Ground Coffee" - Fix: title now uses `$p['name']` as-is, matching exactly what's shown on the site - Products are approved in Google Merchant Center ## Known Bugs Fixed (2026-05-22) - `p.slug` in wishlist/reviews queries → replaced with `p.product_id`, URLs use `?id=` - `wallet_transactions` adjust_wallet used wrong enum values (credit/debit) → fixed to deposit/withdrawal - `reviews` table uses `comment` (not `content`) and `is_approved` (not `status`) - `rewards.php` crashed because `lifetime_points`/`loyalty_tier` didn't exist → added via ALTER TABLE - Collation mismatch on wishlist, loyalty_transactions, loyalty_tiers, product_types, loyalty_settings → all converted to unicode_ci ## Pages Added (2026-06-04) - `faq.php` — accordion FAQ: Orders & Payment, Coffee & Products, Coffee Freshness & Storage, Account & Loyalty - `shipping.php` — rates table (3–5 days standard after processing), "every order made fresh to ship" messaging - `returns.php` — three-tier policy: Your Responsibility / Our Responsibility / Shared Responsibility (covers coffee cost up to $25 on shared issues) - `returns.php` — adapted from DripShipper policy language - `track-order.php` — lookup by order_number + email; shows progress stepper, tracking number/link, items, shipping address; logged-in users see recent orders - `privacy.php` — full privacy policy adapted from DripShipper; GDPR section, children's info, log files, third-party cookies - `includes/footer.php` — Privacy Policy link added to Support section ## Email (CyberMail) — Fixed 2026-06-14 - API key: `sk_live_7f9b0f9a29f6de31a0d229d4af75d56b094ad724fc58a57d` (stored in DB as `cybermail_api_key`) - From email: `noreply@tomsjavajive.com` (stored as `cybermail_from_email`) - From name: `Toms Java Jive` (stored as `cybermail_from_name`) - **CyberMail API requires separate `from` and `from_name` fields** — NOT the combined `Name ` format. Using `Name ` in the `from` field returns "Invalid 'from' email address" error. - Fixed in: `includes/email.php` (Email class send method) and `includes/functions.php` (sendEmail function) ## Product Image Upload — Fixed 2026-06-14 - Upload endpoint: `/admin/upload-image.php` - Saved to: `/uploads/products/` (must be owned by `tomsj4710:nogroup`, chmod 755) - **Do NOT include `header.php` in upload-image.php** — it outputs full HTML which breaks JSON response - Upload-image.php uses `require_once '../includes/auth.php'` + `AdminAuth::getUser()` check directly - JS in product-edit.php uses `fetch('/admin/upload-image.php', {credentials: 'same-origin', ...})` - Textarea for image URLs must be `name="image_urls"` (form handler reads `$_POST['image_urls']`) ## CSV Import — Fixed 2026-06-14 - `tags`, `images`, `dimensions` columns have MySQL `CHECK (json_valid())` constraints - CSV cells with plain text (e.g. `coffee,dark roast`) or plain URLs must be converted to JSON arrays before insert - `toJsonField()` helper in import-export.php handles: already-valid JSON (pass-through), comma-separated → JSON array, empty → NULL - Always wrap `$r['tags']` and `$r['images']` with `toJsonField()` in any import code **Why:** Reference when debugging or extending Tom's Java Jive. **How to apply:** Always check these schema quirks before writing new queries against this DB.