diff --git a/docs/deployment/hetzner-server-setup.md b/docs/deployment/hetzner-server-setup.md index 1f06334b..9eb82011 100644 --- a/docs/deployment/hetzner-server-setup.md +++ b/docs/deployment/hetzner-server-setup.md @@ -546,7 +546,9 @@ docker compose --profile full run --rm -e PYTHONPATH=/app api alembic upgrade he docker compose --profile full run --rm -e PYTHONPATH=/app api python scripts/seed/init_production.py docker compose --profile full run --rm -e PYTHONPATH=/app api python scripts/seed/init_log_settings.py docker compose --profile full run --rm -e PYTHONPATH=/app api python scripts/seed/create_default_content_pages.py -docker compose --profile full run --rm -e PYTHONPATH=/app api python scripts/seed/seed_email_templates.py +docker compose --profile full run --rm -e PYTHONPATH=/app api python scripts/seed/seed_email_templates_core.py +docker compose --profile full run --rm -e PYTHONPATH=/app api python scripts/seed/seed_email_templates_loyalty.py +docker compose --profile full run --rm -e PYTHONPATH=/app api python scripts/seed/seed_demo.py # 9. Start all services docker compose --profile full up -d @@ -556,6 +558,9 @@ docker compose --profile full ps docker stats --no-stream --format "table {{.Name}}\t{{.MemUsage}}\t{{.MemPerc}}" ``` +!!! note "After the reset" + `init_production.py` re-creates the four admin users with their **default** passwords (see `init_production.py:280-300`). Any admin-side configuration that lives in the `admin_settings` table (e.g. the manual SMTP overrides under `/admin/settings`) is wiped and must be re-applied. The `/health` endpoint reads `.build-info` which is only regenerated by `scripts/deploy.sh`, so after a manual reset it will report the **previous** commit; harmless but worth knowing. + ### Seeded Data Summary | Data | Count | diff --git a/docs/proposals/loyalty-go-live-readiness.md b/docs/proposals/loyalty-go-live-readiness.md index 3739db3b..e63fb608 100644 --- a/docs/proposals/loyalty-go-live-readiness.md +++ b/docs/proposals/loyalty-go-live-readiness.md @@ -15,6 +15,53 @@ loyalty platform live for FASHIONHUB's stores and start the Google Wallet production-access review in parallel (1–3 day Google review, non-blocking). +## 2026-05-16 update — Test 1 round 1: 7 bugs found, 6 fixed, 1 pending + +First attempt at the customer-facing journey on FASHIONHUB's fallback +subdomain (`fashionhub.rewardflow.lu`) surfaced more than expected. A +critical timestamp bug was masquerading as a re-enrollment confusion, +which sent us briefly down the wrong investigation path. The clean-slate +reset described below cleared the bad data so the remaining gates can be +verified on a known-good baseline. + +**Six bugs fixed and deployed to prod** (5 commits): + +| Bug | Layer | Fix | +|---|---|---| +| `TimestampMixin` evaluated `datetime.now(UTC)` once at module import — every row stamped at process-start time | `models/database/base.py` | Pass `_utc_now` callable as `default` / `onupdate`. Critical: affected every `created_at` / `updated_at` on every table that uses the mixin since the last app restart. | +| Admin/store/merchant card detail page showed "-" for phone + birthday even when both were captured during enrollment | `app/modules/loyalty/schemas/card.py` + 3 endpoints | Added `customer_phone` + `customer_birthday` to `CardDetailResponse` and populated from `customer.phone` / `customer.birth_date`. Data was persisting all along — purely a serialization gap. | +| Storefront `` hardcoded made `` show in mm/dd/yyyy on the FR storefront | `app/templates/storefront/base.html` | Dynamic `lang="{{ current_language\|default('en') }}"` so the browser respects the FR locale. | +| Storefront nav "Home" rendered as English literal across all locales despite `nav.home` existing in every locale file | `app/templates/storefront/base.html` | Use `{{ _('nav.home') }}` on both desktop and mobile nav. | +| `Store.description` (the per-store tagline) was single-language only — FASHIONHUB's "Trendy clothing and accessories" rendered in EN on the FR storefront footer | `Store` model + migration `tenancy_005` + template + `seed_demo.py` | Added `description_translations` JSON column with the same shape used by CMS / Platform / Subscription. Added `get_translated_description(lang)` getter with FR/DE → DEFAULT_LANGUAGE → `description` fallback. Seeded FR/DE/LB/EN for Fashion Group's two stores so they render correctly out of the box. | +| `make init-prod` and `make db-reset` referenced `scripts/seed/seed_email_templates.py`, which doesn't exist (the real seeders are `_core.py` + `_loyalty.py`) — `db-reset` would silently bomb mid-way | `Makefile` | Call both real scripts in both targets. | +| `scripts/seed/create_default_content_pages.py` still passed `meta_keywords` to `ContentPage`, but the column was dropped in migration `cms_003` — fresh seeding failed on the first platform | `scripts/seed/create_default_content_pages.py` | Drop the `meta_keywords` kwarg. | + +**One bug still open:** + +- **B1-F — welcome email not received.** The original investigation was confounded by the timestamp bug (customer looked like it was from May 12 when it was actually fresh, making the re-enrollment hypothesis seem plausible). Needs fresh repro on the clean DB: enroll with a new email, tail `api` + `celery-worker` logs live, check `email_logs` for a row. If still no email, then there's a real bug in the dispatch path — `notification_service.send_enrollment_confirmation` is called from `card_service.enroll_customer:636` and wraps the call in a try/except that only logs warnings (`card_service.py:631-645`), so a silent failure in `_resolve_context` or the Celery enqueue would be invisible from the user's perspective. + +**Two product decisions pending** (from the same session, not yet implemented): + +- **B1-E — QR code in welcome email.** Scoped: pass `wallet_save_url` into the `loyalty_enrollment` template, generate QR server-side (Python `qrcode`), update the HTML body in all 4 locales in `scripts/seed/seed_email_templates_loyalty.py:294-299`, reseed. Blocked on B1-F (no point adding a QR to an email that doesn't send). +- **C1-C backfill scope.** Other stores (WizaTech, BookWorld, LuxWeb, WizaMart etc.) still only have a single-language `description`. Fashion Group was seeded; rest can be done by hand via admin UI as merchants come online, or batch-updated later. No code work needed. + +### Prod data reset + +Wiped and reseeded — used the corrected sequence from +[`deployment/hetzner-server-setup.md`](../deployment/hetzner-server-setup.md) +section 12. Two doc gaps found and patched in the same pass: + +- Reset procedure called `scripts/seed/seed_email_templates.py` (doesn't exist) — now calls both real scripts +- Reset procedure was missing `seed_demo.py` at the end of step 8 — now included + +After reset, admin credentials are back to the defaults from `init_production.py` (admin / `Ollama@8044`, etc.); platform admin SMTP overrides in `/admin/settings` need to be re-applied (port 587, STARTTLS, `support@wizard.lu`). + +### Status board delta + +- Step 1 (email templates seeded) — re-seeded post-reset, still ✅ +- Step 3 (migrations) — now at `tenancy_005`, still ✅ +- Step 6 (web user-journey E2E tests) — Test 1 round 2 pending on clean DB; the bugs found in round 1 are no longer blockers + ## Status board | # | Pre-launch step | State | Notes | diff --git a/mkdocs.yml b/mkdocs.yml index 47559b64..9170b638 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -220,6 +220,7 @@ nav: - Program Analysis: modules/loyalty/program-analysis.md - UI Design: modules/loyalty/ui-design.md - Production Launch Plan: modules/loyalty/production-launch-plan.md + - Production Readiness: modules/loyalty/production-readiness.md - Monitoring: modules/loyalty/monitoring.md - Runbook - Wallet Certs: modules/loyalty/runbook-wallet-certs.md - Runbook - Expiration Task: modules/loyalty/runbook-expiration-task.md @@ -253,6 +254,7 @@ nav: - Overview: modules/prospecting/index.md - Database: modules/prospecting/database.md - Scoring: modules/prospecting/scoring.md + - Batch Scanning: modules/prospecting/batch-scanning.md - Research Findings: modules/prospecting/research-findings.md - User Journeys: modules/prospecting/user-journeys.md @@ -325,22 +327,36 @@ nav: - Documentation Consolidation: proposals/PLAN_documentation-consolidation.md - Module Dependency Redesign: proposals/SESSION_NOTE_2026-02-03_module-dependency-redesign.md - Import-002 Cross-Module Deps: proposals/SESSION_NOTE_2026-02-09_import002-cross-module-deps.md + - Android Terminal Implementation: proposals/android-terminal-implementation.md + - Backward Compatibility Cleanup: proposals/backward-compatibility-cleanup.md + - CMS Redesign Alignment: proposals/cms-redesign-alignment.md - Decouple Modules: proposals/decouple-modules.md - Decouple Modules Implementation: proposals/decouple-modules-implementation-plan.md - - Loyalty Phase 2 Interfaces: proposals/loyalty-phase2-interfaces-plan.md - - Loyalty Program Analysis: proposals/loyalty-program-analysis.md - - Permissions Plan: proposals/plan-perms.md - - Validator Noqa & Remaining Findings: proposals/validator-noqa-suppressions-and-remaining-findings.md - - Backward Compatibility Cleanup: proposals/backward-compatibility-cleanup.md - - Module Documentation Migration: proposals/module-documentation-migration-plan.md + - End-to-End Prospecting to Live Site: proposals/end-to-end-prospecting-to-live-site.md - Fix SEC-015 x-html Findings: proposals/fix-1600-sec015-xhtml-findings.md - Google Wallet Local Testing: proposals/google-wallet-local-testing.md - - RBAC Cleanup Two-Phase Plan: proposals/rbac-cleanup-two-phase-plan.md - - Store Login Platform Detection: proposals/store-login-platform-detection.md - - Test API Deps Auth Dependencies: proposals/test-api-deps-auth-dependencies.md - - Post Soft-Delete Follow-ups: proposals/post-soft-delete-followups.md + - Hosting Architecture Decision: proposals/hosting-architecture-decision.md + - Hosting Cascade Delete: proposals/hosting-cascade-delete.md + - Hosting Site Creation Fix: proposals/hosting-site-creation-fix.md + - Loyalty Go-Live Readiness: proposals/loyalty-go-live-readiness.md + - Loyalty Phase 2 Interfaces: proposals/loyalty-phase2-interfaces-plan.md + - Loyalty Program Analysis: proposals/loyalty-program-analysis.md - Merchant Intake Checklist: proposals/merchant-intake-checklist.md - "Merchant Intake Checklist (FR)": proposals/merchant-intake-checklist-fr.md + - Module Documentation Migration: proposals/module-documentation-migration-plan.md + - Permissions Plan: proposals/plan-perms.md + - POC Content Mapping: proposals/poc-content-mapping.md + - Post Soft-Delete Follow-ups: proposals/post-soft-delete-followups.md + - Prospecting Contact Scraper Fix: proposals/prospecting-contact-scraper-fix.md + - RBAC Cleanup Two-Phase Plan: proposals/rbac-cleanup-two-phase-plan.md + - Security Audit Demo POC Builder: proposals/security-audit-demo-poc-builder.md + - Security Hardening Plan: proposals/security-hardening-plan.md + - Store Login Platform Detection: proposals/store-login-platform-detection.md + - Store Menu Multi-Platform Visibility: proposals/store-menu-multi-platform-visibility.md + - Storefront Builder Vision: proposals/storefront-builder-vision.md + - Test API Deps Auth Dependencies: proposals/test-api-deps-auth-dependencies.md + - Transaction Categories: proposals/transaction-categories.md + - Validator Noqa & Remaining Findings: proposals/validator-noqa-suppressions-and-remaining-findings.md # --- Archive --- - Archive: