Commit Graph

289 Commits

Author SHA1 Message Date
7d652716bb feat(loyalty): production readiness round 2 — 12 security, integrity & correctness fixes
Some checks failed
CI / ruff (push) Successful in 12s
CI / validate (push) Successful in 27s
CI / dependency-scanning (push) Successful in 31s
CI / pytest (push) Failing after 3h14m58s
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
Security:
- Fix TOCTOU race conditions: move balance/limit checks after row lock in redeem_points, add_stamp, redeem_stamps
- Add PIN ownership verification to update/delete/unlock store routes
- Gate adjust_points endpoint to merchant_owner role only

Data integrity:
- Track total_points_voided in void_points
- Add order_reference idempotency guard in earn_points

Correctness:
- Fix LoyaltyProgramAlreadyExistsException to use merchant_id parameter
- Add StorefrontProgramResponse excluding wallet IDs from public API
- Add bounds (±100000) to PointsAdjustRequest.points_delta

Audit & config:
- Add CARD_REACTIVATED transaction type with audit record
- Improve admin audit logging with actor identity and old values
- Use merchant-specific PIN lockout settings with global fallback
- Guard MerchantLoyaltySettings creation with get_or_create pattern

Tests: 27 new tests (265 total) covering all 12 items — unit and integration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 23:37:23 +01:00
540205402f feat(middleware): harden routing with fail-closed policy, custom subdomain management, and perf fixes
Some checks failed
CI / pytest (push) Waiting to run
CI / ruff (push) Successful in 12s
CI / validate (push) Successful in 26s
CI / dependency-scanning (push) Successful in 31s
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
- Fix IPv6 host parsing with _strip_port() utility
- Remove dangerous StorePlatform→Store.subdomain silent fallback
- Close storefront gate bypass when frontend_type is None
- Add custom subdomain management UI and API for stores
- Add domain health diagnostic tool
- Convert db.add() in loops to db.add_all() (24 PERF-006 fixes)
- Add tests for all new functionality (18 subdomain service tests)
- Add .github templates for validator compliance

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 18:13:01 +01:00
adec17cd02 docs(deployment): add future scaling section for 50+ custom domains
Document two strategies for scaling beyond manual Caddyfile management:
- Caddy on-demand TLS (simple, no Cloudflare protection)
- Cloudflare for SaaS / Custom Hostnames (recommended, full protection)
- Infrastructure scaling notes for 1,000+ sites

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 19:41:35 +01:00
183f55c7b3 docs(deployment): add runbooks for store subdomains, custom domains, and new platforms
- Update origin cert config: wildcards for omsflow.lu, rewardflow.lu, hostwizard.lu
- Add wildcard Caddy blocks to production Caddyfile example
- Replace "Future" section with actionable runbooks:
  - Add a Store Subdomain (self-service, no infra changes)
  - Add a Custom Store Domain (Cloudflare + Caddy + DB)
  - Add a New Platform Domain (full setup)
- Document wizard.lu exception (no wildcard due to git.wizard.lu DNS-only)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 12:31:56 +01:00
c2c0e3c740 refactor: rename platform_domain → main_domain to avoid confusion with platform.domain
Some checks failed
CI / ruff (push) Successful in 10s
CI / validate (push) Has been cancelled
CI / dependency-scanning (push) Has been cancelled
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
CI / pytest (push) Has started running
The setting `settings.platform_domain` (the global/main domain like "wizard.lu")
was easily confused with `platform.domain` (per-platform domain like "rewardflow.lu").
Renamed to `settings.main_domain` / `MAIN_DOMAIN` env var across the entire codebase.

Also updated docs to reflect the refactored store detection logic with
`is_platform_domain` / `is_subdomain_of_platform` guards.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 04:45:28 +01:00
4a1f71a312 fix(loyalty): resolve critical production readiness issues
Some checks failed
CI / ruff (push) Successful in 11s
CI / validate (push) Successful in 26s
CI / dependency-scanning (push) Successful in 32s
CI / pytest (push) Failing after 3h8m55s
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
- Add pessimistic locking (SELECT FOR UPDATE) on card write operations
  to prevent race conditions in stamp_service and points_service
- Replace 16 console.log/error/warn calls with LogConfig.createLogger()
  in 3 storefront JS files (dashboard, history, enroll)
- Delete all stale lu.json locale files across 8 modules (lb is the
  correct ISO 639-1 code for Luxembourgish)
- Update architecture rules and docs to reference lb.json not lu.json
- Add production-readiness.md report for loyalty module

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 23:18:18 +01:00
5dd5e01dc6 fix: skip custom domain store detection for platform domains
Some checks failed
CI / ruff (push) Successful in 12s
CI / validate (push) Has been cancelled
CI / dependency-scanning (push) Has been cancelled
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
CI / pytest (push) Has been cancelled
StoreContextMiddleware was treating platform domains (e.g. rewardflow.lu)
as custom store domains, causing store lookup to fail before reaching
path-based detection (/storefront/FASHIONHUB/...). Now skips custom
domain detection when the host matches the platform's own domain.

Also fixes menu tests to use loyalty-program instead of loyalty-overview,
and adds LOYALTY_DEFAULT_LOGO_URL and LOYALTY_GOOGLE_WALLET_ORIGINS to
Hetzner deployment docs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 23:06:49 +01:00
319900623a feat: add SQL query tool, platform debug, loyalty settings, and multi-module improvements
Some checks failed
CI / ruff (push) Successful in 14s
CI / pytest (push) Failing after 50m12s
CI / validate (push) Successful in 25s
CI / dependency-scanning (push) Successful in 32s
CI / docs (push) Has been skipped
CI / deploy (push) Has been skipped
- Add admin SQL query tool with saved queries, schema explorer presets,
  and collapsible category sections (dev_tools module)
- Add platform debug tool for admin diagnostics
- Add loyalty settings page with owner-only access control
- Fix loyalty settings owner check (use currentUser instead of window.__userData)
- Replace HTTPException with AuthorizationException in loyalty routes
- Expand loyalty module with PIN service, Apple Wallet, program management
- Improve store login with platform detection and multi-platform support
- Update billing feature gates and subscription services
- Add store platform sync improvements and remove is_primary column
- Add unit tests for loyalty (PIN, points, stamps, program services)
- Update i18n translations across dev_tools locales

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 20:08:07 +01:00
a77a8a3a98 feat: multi-module improvements across merchant, store, i18n, and customer systems
All checks were successful
CI / ruff (push) Successful in 12s
CI / pytest (push) Successful in 50m57s
CI / validate (push) Successful in 24s
CI / dependency-scanning (push) Successful in 29s
CI / docs (push) Successful in 40s
CI / deploy (push) Successful in 51s
- Fix platform-grouped merchant sidebar menu with core items at root level
- Add merchant store management (detail page, create store, team page)
- Fix store settings 500 error by removing dead stripe/API tab
- Move onboarding translations to module-owned locale files
- Fix onboarding banner i18n with server-side rendering + context inheritance
- Refactor login language selectors to use languageSelector() function (LANG-002)
- Move HTTPException handling to global exception handler in merchant routes (API-003)
- Add language selector to all login pages and portal headers
- Fix customer module: drop order stats from customer model, add to orders module
- Fix admin menu config visibility for super admin platform context
- Fix storefront auth and layout issues
- Add missing i18n translations for onboarding steps (en/fr/de/lb)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 23:48:25 +01:00
f141cc4e6a docs: migrate module documentation to single source of truth
Move 39 documentation files from top-level docs/ into each module's
docs/ folder, accessible via symlinks from docs/modules/. Create
data-model.md files for 10 modules with full schema documentation.
Replace originals with redirect stubs. Remove empty guide stubs.

Modules migrated: tenancy, billing, loyalty, marketplace, orders,
messaging, cms, catalog, inventory, hosting, prospecting.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 23:38:37 +01:00
a099bfdc48 docs(deployment): add git pull step to full reset procedure
Some checks failed
CI / ruff (push) Successful in 10s
CI / validate (push) Has been cancelled
CI / dependency-scanning (push) Has been cancelled
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
CI / pytest (push) Has been cancelled
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 19:34:40 +01:00
8c449d7baa docs(deployment): add full network architecture diagram
Some checks failed
CI / ruff (push) Successful in 9s
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
CI / validate (push) Has been cancelled
CI / dependency-scanning (push) Has been cancelled
CI / pytest (push) Has been cancelled
ASCII diagram showing all services, Docker networks, port bindings,
and traffic flow from Cloudflare through Caddy to each container.
Clearly marks which ports are internet-exposed, localhost-only,
or Docker-internal-only.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 23:41:54 +01:00
2268f32f51 docs(security): update Hetzner guide with all security hardening for rebuild
Some checks failed
CI / ruff (push) Successful in 11s
CI / validate (push) Has been cancelled
CI / dependency-scanning (push) Has been cancelled
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
CI / pytest (push) Has been cancelled
- Fix Gitea docker-compose in Step 7 to bind port 3000 to 127.0.0.1
- Add REDIS_PASSWORD to Step 10 critical production values
- Replace misleading UFW rules with Docker port binding instructions
- Add warning about Docker bypassing UFW in Step 14
- Add initial setup note for temporary Gitea port exposure

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 23:33:53 +01:00
b68d542258 fix(security): harden Redis auth, restrict /metrics, document Gitea port fix
Some checks failed
CI / ruff (push) Successful in 10s
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
CI / validate (push) Has been cancelled
CI / dependency-scanning (push) Has been cancelled
CI / pytest (push) Has been cancelled
- Add Redis password via REDIS_PASSWORD env var (--requirepass flag)
- Update all REDIS_URL and REDIS_ADDR references to include password
- Restrict /metrics endpoint to localhost and Docker internal networks (403 for external requests)
- Document Gitea port 3000 localhost binding fix (must be applied manually on server)
- Add REDIS_PASSWORD to .env.example

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 23:15:15 +01:00
a7392de9f6 fix(security): close exposed PostgreSQL and Redis ports (BSI/CERT-Bund report)
Some checks failed
CI / ruff (push) Successful in 12s
CI / validate (push) Has been cancelled
CI / dependency-scanning (push) Has been cancelled
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
CI / pytest (push) Has been cancelled
Docker bypasses UFW iptables, so bare port mappings like "5432:5432"
exposed the database to the public internet. Removed port mappings for
PostgreSQL and Redis (they only need Docker-internal networking), and
bound the API port to 127.0.0.1 since only Caddy needs to reach it.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 22:31:07 +01:00
8b147f53c6 feat(hosting): add HostWizard platform module and fix migration chain
Some checks failed
CI / pytest (push) Failing after 49m20s
CI / validate (push) Successful in 24s
CI / dependency-scanning (push) Successful in 33s
CI / docs (push) Has been skipped
CI / deploy (push) Has been skipped
CI / ruff (push) Successful in 10s
- Add complete hosting module (models, routes, schemas, services, templates, migrations)
- Add HostWizard platform to init_production seed (code=hosting, domain=hostwizard.lu)
- Fix cms_002 migration down_revision to z_unique_subdomain_domain
- Fix prospecting_001 migration to chain after cms_002 (remove branch label)
- Add hosting/prospecting version_locations to alembic.ini
- Fix admin_services delete endpoint to use proper response model
- Add hostwizard.lu to deployment docs (DNS, Caddy, Cloudflare)
- Add hosting and prospecting user journey docs to mkdocs nav

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 19:34:56 +01:00
784bcb9d23 docs(i18n): document CMS template translations and multi-language content pages
Some checks failed
CI / dependency-scanning (push) Successful in 34s
CI / docs (push) Has been skipped
CI / deploy (push) Has been skipped
CI / ruff (push) Successful in 11s
CI / pytest (push) Failing after 48m7s
CI / validate (push) Successful in 28s
Add sections covering CMS locale file structure, translated template
inventory, TranslatableText pattern for sections, and the new
title_translations/content_translations model API with migration cms_002.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 18:00:00 +01:00
05c53e1865 docs(deployment): add verified full reset procedure to Hetzner guide
Some checks failed
CI / pytest (push) Failing after 48m4s
CI / validate (push) Successful in 25s
CI / ruff (push) Successful in 11s
CI / dependency-scanning (push) Successful in 29s
CI / docs (push) Has been skipped
CI / deploy (push) Has been skipped
Document the complete nuclear reset sequence (tested end-to-end):
stop → build → infra up → schema reset → migrations → seeds → start.
Update seeded data counts to match current output (30 CMS pages,
12 tiers, 3 admins, 28 email templates). Switch from exec to run --rm
for seed commands so they work before services are started.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 23:21:52 +01:00
f631283286 docs(deployment): update memory limits and celery concurrency across all guides
Some checks failed
CI / validate (push) Has been cancelled
CI / dependency-scanning (push) Has been cancelled
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
CI / ruff (push) Successful in 11s
CI / pytest (push) Has been cancelled
Sync all deployment docs with actual docker-compose.yml values:
- celery-worker: 512→768MB, concurrency 4→2
- db: 512→256MB, celery-beat: 256→128MB, flower: 256→192MB
- Redis maxmemory: 256mb→100mb (matches container mem_limit 128m)
- Add redis-exporter to scaling guide memory budget

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 22:21:25 +01:00
78ee05f50e docs(prospecting): add scoring, database, and research docs
Some checks failed
CI / validate (push) Has been cancelled
CI / dependency-scanning (push) Has been cancelled
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
CI / ruff (push) Successful in 11s
CI / pytest (push) Has been cancelled
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 16:04:52 +01:00
35d1559162 feat(monitoring): add Redis exporter + Sentry docs to deployment guide
Some checks failed
CI / ruff (push) Successful in 10s
CI / pytest (push) Failing after 47m30s
CI / validate (push) Successful in 24s
CI / dependency-scanning (push) Successful in 29s
CI / docs (push) Has been skipped
CI / deploy (push) Has been skipped
- Add redis-exporter container to docker-compose (oliver006/redis_exporter, 32MB)
- Add Redis scrape target to Prometheus config
- Add 4 Redis alert rules: RedisDown, HighMemory, HighConnections, RejectedConnections
- Document Step 19b (Sentry Error Tracking) in Hetzner deployment guide
- Document Step 19c (Redis Monitoring) in Hetzner deployment guide
- Update resource budget and port reference tables

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 23:30:18 +01:00
30c4593e0f refactor(P6): standardize route variable naming to router
Some checks failed
CI / ruff (push) Successful in 9s
CI / pytest (push) Has been cancelled
CI / validate (push) Has been cancelled
CI / dependency-scanning (push) Has been cancelled
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
All route files (admin.py, store.py) now export `router` instead of
`admin_router`/`store_router`. Consumer code (definition.py, __init__.py)
imports as `router as admin_router` where distinction is needed.
ModuleDefinition fields remain admin_router/store_router.

64 files changed across all modules. Architecture rules, docs, and
migration plan updated. Added noqa:API001 support to validator for
pre-existing raw dict endpoints now visible with standardized router name.
All 1114 tests pass.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 11:05:34 +01:00
86e85a98b8 refactor(arch): eliminate all cross-module model imports in service layer
Some checks failed
CI / ruff (push) Successful in 9s
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
CI / validate (push) Has been cancelled
CI / dependency-scanning (push) Has been cancelled
CI / pytest (push) Has been cancelled
Enforce MOD-025/MOD-026 rules: zero top-level cross-module model imports
remain in any service file. All 66 files migrated using deferred import
patterns (method-body, _get_model() helpers, instance-cached self._Model)
and new cross-module service methods in tenancy. Documentation updated
with Pattern 6 (deferred imports), migration plan marked complete, and
violations status reflects 84→0 service-layer violations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 06:13:15 +01:00
4aa6f76e46 refactor(arch): move auth schemas to tenancy module and add cross-module service methods
Some checks failed
CI / validate (push) Has been cancelled
CI / dependency-scanning (push) Has been cancelled
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
CI / pytest (push) Has been cancelled
CI / ruff (push) Successful in 10s
Move all auth schemas (UserContext, UserLogin, LoginResponse, etc.) from
legacy models/schema/auth.py to app/modules/tenancy/schemas/auth.py per
MOD-019. Update 84 import sites across 14 modules. Legacy file now
re-exports for backwards compatibility.

Add missing tenancy service methods for cross-module consumers:
- merchant_service.get_merchant_by_owner_id()
- merchant_service.get_merchant_count_for_owner()
- admin_service.get_user_by_id() (public, was private-only)
- platform_service.get_active_store_count()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 23:57:04 +01:00
f95db7c0b1 feat(roles): add admin store roles page, permission i18n, and menu integration
Some checks failed
CI / ruff (push) Successful in 9s
CI / validate (push) Has been cancelled
CI / dependency-scanning (push) Has been cancelled
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
CI / pytest (push) Has started running
- Add admin store roles page with merchant→store cascading for superadmin
  and store-only selection for platform admin
- Add permission catalog API with translated labels/descriptions (en/fr/de/lb)
- Add permission translations to all 15 module locale files (60 files total)
- Add info icon tooltips for permission descriptions in role editor
- Add store roles menu item and admin menu item in module definition
- Fix store-selector.js URL construction bug when apiEndpoint has query params
- Add admin store roles API (CRUD + platform scoping)
- Add integration tests for admin store roles and permission catalog

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 23:31:27 +01:00
cb3bc3c118 feat: implement complete RBAC access control with tests
Some checks failed
CI / pytest (push) Failing after 45m29s
CI / validate (push) Successful in 24s
CI / dependency-scanning (push) Successful in 28s
CI / docs (push) Has been skipped
CI / deploy (push) Has been skipped
CI / ruff (push) Successful in 9s
Add 4-layer access control stack (subscription → module → menu → permissions):
- P1: Wire requires_permission into menu sidebar filtering
- P2: Expose window.USER_PERMISSIONS for Alpine.js client-side gating
- P3: Add page-level permission guards on store routes
- P4: Role CRUD API endpoints and role editor UI
- P5: Audit trail for all role/permission changes

Includes unit tests (menu permission filtering, role CRUD service) and
integration tests (role API endpoints). All 404 core+tenancy tests pass.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 18:26:59 +01:00
d480b59df4 docs: update routing docs and seed script for production routing changes
Some checks failed
CI / ruff (push) Successful in 9s
CI / validate (push) Has been cancelled
CI / dependency-scanning (push) Has been cancelled
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
CI / pytest (push) Has been cancelled
Reflect the production routing refactor (ce5b54f): document store dashboard
double-mounting, per-platform subdomain overrides via StorePlatform.custom_subdomain,
get_resolved_store_code dependency, and /merchants/ reserved path. Update seed
script to populate custom_subdomain and StoreDomain.platform_id for demo data.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 11:44:43 +01:00
d648c921b7 docs: add consolidated dev URL reference and migrate /shop to /storefront
Some checks failed
CI / ruff (push) Successful in 10s
CI / validate (push) Has been cancelled
CI / dependency-scanning (push) Has been cancelled
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
CI / pytest (push) Has been cancelled
- Add Development URL Quick Reference section to url-routing overview
  with all login URLs, entry points, and full examples
- Replace /shop/ path segments with /storefront/ across 50 docs files
- Update file references: shop_pages.py → storefront_pages.py,
  templates/shop/ → templates/storefront/, api/v1/shop/ → api/v1/storefront/
- Preserve domain references (orion.shop) and /store/ staff dashboard paths
- Archive docs left unchanged (historical)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 13:23:44 +01:00
a6e6d9be8e refactor: rename shopLayoutData to storefrontLayoutData
Some checks failed
CI / ruff (push) Successful in 11s
CI / pytest (push) Failing after 46m49s
CI / validate (push) Successful in 23s
CI / dependency-scanning (push) Successful in 30s
CI / docs (push) Has been skipped
CI / deploy (push) Has been skipped
Align Alpine.js base component naming with storefront terminology.
Updated across all storefront JS, templates, and documentation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 19:06:45 +01:00
cfce6c0ca4 fix: loyalty module end-to-end — merchant route, store menus, sidebar, API error handling
Some checks failed
CI / ruff (push) Successful in 10s
CI / validate (push) Has been cancelled
CI / dependency-scanning (push) Has been cancelled
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
CI / pytest (push) Has been cancelled
- Add merchant loyalty overview route and template (was 404)
- Fix store loyalty route paths to match menu URLs (/{store_code}/loyalty/...)
- Add loyalty rewards card to storefront account dashboard
- Fix merchant overview to resolve merchant via get_merchant_for_current_user_page
- Fix store login to use store's primary platform for JWT token (interim fix)
- Fix apiClient to attach status/errorCode to thrown errors (fixes error.status
  checks in 12+ JS files — loyalty settings, terminal, email templates, etc.)
- Hide "Add Product" sidebar button when catalog module is not enabled
- Add proposal doc for proper platform detection in store login flow

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 13:52:11 +01:00
32e4aa6564 feat: wire Google Wallet into loyalty enrollment, stamps, and points flows
Connect the fully-implemented Google Wallet service to the loyalty module:
- Create wallet class/object on customer enrollment
- Sync wallet passes on stamp and points operations
- Expose wallet URLs in storefront API responses
- Add conditional "Add to Google Wallet" buttons on dashboard and enroll-success pages
- Use platform-wide env var config (not per-merchant DB column)
- Add Google service account patterns to .gitignore
- Add LOYALTY_GOOGLE_* fields to app Settings
- Update deployment docs and add local testing guide

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 10:38:46 +01:00
6c78827c7f feat: add language switching to admin and merchant frontends
Some checks failed
CI / ruff (push) Successful in 10s
CI / pytest (push) Failing after 46m27s
CI / validate (push) Successful in 23s
CI / dependency-scanning (push) Successful in 29s
CI / docs (push) Has been skipped
CI / deploy (push) Has been skipped
- Add cookie to ADMIN resolution chain (cookie → user_pref → "en")
- Add explicit MERCHANT resolution (cookie → user_pref → "fr")
- Add language selector dropdown to admin and merchant headers
- Add languageSelector() function to merchant init-alpine.js
- Add flag-icons CSS and i18n.js setup to merchant base template
- Add compact flag-based language selector to both login pages
- Make lang attribute dynamic on all base and login templates
- Pass current_language to login route template context
- Update architecture doc with ADMIN/MERCHANT resolution priorities

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 10:26:57 +01:00
0389294b1a fix: language switcher stuck in French on store dashboard
Some checks failed
CI / ruff (push) Successful in 11s
CI / pytest (push) Failing after 44m35s
CI / validate (push) Successful in 23s
CI / dependency-scanning (push) Successful in 28s
CI / docs (push) Has been skipped
CI / deploy (push) Has been skipped
Three compounding bugs prevented language switching on the store dashboard:
- Cookie missing path="/", scoping it to the API endpoint path only
- STORE frontend resolution chain ignored the cookie entirely
- Store header used inline x-data with wrong language names instead of shared languageSelector()

Also updates architecture doc with correct per-frontend resolution priorities,
cookie name, API endpoint path, and file references.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 05:30:25 +01:00
05d31a7fc5 docs: add Google Wallet setup guide and loyalty env vars
Some checks failed
CI / ruff (push) Successful in 11s
CI / pytest (push) Failing after 45m26s
CI / validate (push) Successful in 22s
CI / dependency-scanning (push) Successful in 29s
CI / docs (push) Has been skipped
CI / deploy (push) Has been skipped
Step 25 in Hetzner docs with full Google Cloud/Wallet Console setup,
service account configuration, local testing, and architecture diagrams.
Loyalty module env vars added to environment.md and .env.example.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 00:31:43 +01:00
272b62fbd3 docs: update documentation for platform-aware storefront routing
Update 8 documentation files to reflect new URL scheme:
- Dev: /platforms/{code}/storefront/{store_code}/
- Prod: subdomain.platform.lu/ (root path = storefront)
- Rename DEFAULT_PLATFORM_CODE to MAIN_PLATFORM_CODE
- Replace hardcoded platform_id=1 with dynamic values
- Update route examples, middleware descriptions, code samples

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 23:56:26 +01:00
b9ac252a9f feat: add merchant user edit page with editable profile fields
All checks were successful
CI / ruff (push) Successful in 11s
CI / pytest (push) Successful in 47m48s
CI / validate (push) Successful in 24s
CI / dependency-scanning (push) Successful in 30s
CI / docs (push) Successful in 40s
CI / deploy (push) Successful in 1m18s
- Add /admin/merchant-users/{id}/edit page route and template
- Replace toggle-status button with edit button on merchant-users list
- Editable fields: username, email, first name, last name
- Quick actions: toggle status, delete (with double confirm)
- Move RBAC two-phase plan to docs/proposals/

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 23:30:50 +01:00
1dcb0e6c33 feat: RBAC Phase 1 — consolidate user roles into 4-value enum
Some checks failed
CI / ruff (push) Successful in 11s
CI / validate (push) Has been cancelled
CI / dependency-scanning (push) Has been cancelled
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
CI / pytest (push) Has been cancelled
Consolidate User.role (2-value: admin/store) + User.is_super_admin (boolean)
into a single 4-value UserRole enum: super_admin, platform_admin,
merchant_owner, store_member. Drop stale StoreUser.user_type column.
Fix role="user" bug in merchant creation.

Key changes:
- Expand UserRole enum from 2 to 4 values with computed properties
  (is_admin, is_super_admin, is_platform_admin, is_merchant_owner, is_store_user)
- Add Alembic migration (tenancy_003) for data migration + column drops
- Remove is_super_admin from JWT token payload
- Update all auth dependencies, services, routes, templates, JS, and tests
- Update all RBAC documentation

66 files changed, 1219 unit tests passing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 22:44:29 +01:00
93731b7173 test: add 73 unit tests for app/api/deps.py auth dependencies
Cover all core authentication paths: helpers (_get_token_from_request,
_validate_user_token, _get_user_model, _validate_customer_token),
admin/store/merchant/customer auth (cookie + header + API variants),
optional auth, store permission factories, and store ownership checks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 17:38:31 +01:00
67260e9322 docs: update progress — server fully ready (44/44 checks pass)
All checks were successful
CI / ruff (push) Successful in 11s
CI / pytest (push) Successful in 36m0s
CI / validate (push) Successful in 23s
CI / dependency-scanning (push) Successful in 31s
CI / docs (push) Successful in 39s
CI / deploy (push) Successful in 48s
- Mark all server-side tasks as complete (fail2ban, Flower password,
  unattended-upgrades, verification script)
- Correct memory limits: celery-beat and flower bumped to 256m after OOM
- Update scaling guide memory budget to match actual limits

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 11:04:43 +01:00
10fdf91dfa feat(infra): add launch readiness quick wins
Some checks failed
CI / ruff (push) Successful in 12s
CI / validate (push) Has been cancelled
CI / dependency-scanning (push) Has been cancelled
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
CI / pytest (push) Has been cancelled
- Add mem_limit to all 6 app containers (db: 512m, redis: 128m,
  api: 512m, celery-worker: 512m, celery-beat: 128m, flower: 128m)
- Restrict Flower port to localhost (127.0.0.1:5555:5555)
- Add PostgreSQL and Redis health checks to /health/ready endpoint
  with individual check details (name, status, latency)
- Add scaling guide with metrics, thresholds, Hetzner pricing
- Add server verification script (12 infrastructure checks)
- Update hetzner-server-setup.md with progress and pending tasks

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 10:24:20 +01:00
3a7cf29386 docs(deployment): document Cloudflare proxy, SendGrid SMTP, and Caddyfile updates
Captures all server-side work completed on 2026-02-16:
- Cloudflare Full setup for wizard.lu, omsflow.lu, rewardflow.lu (NS, SSL, origin certs)
- SendGrid SMTP configured for Alertmanager and app transactional emails
- Caddyfile updated with origin certs and tls issuer acme for git.wizard.lu
- Alertmanager v2 API for test alerts, multi-domain email strategy documented
- Cloudflare security: bot protection, DDoS, rate limiting on /api/ paths

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 20:20:17 +01:00
eaab47f2f8 fix: eliminate all 1600 SEC-015 security info findings
Add safe-pattern exceptions to the x-html check in validate_security.py
for $icon(), $store methods, and window.icons lookups. Suppress remaining
8 legitimate x-html uses (admin-authored content, app-controlled JS) with
noqa comments. Security validator now reports 0 errors, 0 warnings, 0 info.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 18:02:59 +01:00
6458ab13d7 docs: update validator noqa proposal with current results
Reflect resolved architecture warnings, performance warnings, and
current info-only findings (3127) from validate_all output.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 14:25:45 +01:00
0b701fb847 docs: add proposal to fix 1600 SEC-015 x-html security info findings
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 22:23:15 +01:00
f67510b706 docs: switch email provider recommendation from Mailgun to SendGrid
SendGrid handles both transactional emails and marketing campaigns
under one account. Updated alertmanager SMTP placeholders, hetzner
setup guide (Step 19.5), and environment reference to recommend
SendGrid as the primary email provider.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 22:21:49 +01:00
8c715cfde3 docs(deployment): expand server-side setup for Steps 19-20
- Add Mailgun SMTP setup instructions for Alertmanager with test alert
- Expand fail2ban to fully copy-pasteable sudo tee commands
- Add Caddy access logging config (required for fail2ban Caddy jail)
- Add orion_default network cleanup step
- Expand verification checklist

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 22:17:15 +01:00
4bce16fb73 feat(infra): add alerting, network segmentation, and ops docs (Steps 19-24)
All checks were successful
CI / ruff (push) Successful in 11s
CI / pytest (push) Successful in 36m6s
CI / validate (push) Successful in 22s
CI / dependency-scanning (push) Successful in 28s
CI / docs (push) Successful in 37s
CI / deploy (push) Successful in 47s
- Prometheus alert rules (host, container, API, Celery, target-down)
- Alertmanager with email routing (critical 1h, warning 4h repeat)
- Docker network segmentation (frontend/backend/monitoring)
- Incident response runbook with 8 copy-paste runbooks
- Environment variables reference (55+ vars documented)
- Hetzner setup docs updated with Steps 19-24
- Launch readiness updated with Feb 2026 infrastructure status

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 22:06:54 +01:00
b382090771 refactor: remove GitLab CI config and docs after full Gitea migration
Some checks failed
CI / ruff (push) Successful in 12s
CI / validate (push) Has been cancelled
CI / dependency-scanning (push) Has been cancelled
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
CI / pytest (push) Has been cancelled
- Delete .gitlab-ci.yml (replaced by .gitea/workflows/ci.yml)
- Delete docs/deployment/gitlab.md (superseded by gitea.md)
- Update audit rules to reference .gitea/workflows/*.yml
- Update validate_audit.py to check Gitea CI paths
- Clean up GitLab references in gitea.md, mkdocs.yml, .dockerignore
- Mark IPv6 AAAA records as completed in hetzner docs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 19:28:35 +01:00
5474fc5301 docs(deployment): update backup docs with R2 completion, pip3 install, systemd PATH
Some checks failed
CI / ruff (push) Successful in 9s
CI / validate (push) Has been cancelled
CI / dependency-scanning (push) Has been cancelled
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
CI / pytest (push) Has been cancelled
- Mark Steps 1-18 as fully complete (R2 offsite backups operational)
- Fix awscli install instructions: pip3 instead of apt (Ubuntu 24.04)
- Add Environment PATH to systemd service for ~/.local/bin/aws
- Add --upload flag to systemd ExecStart now that R2 is configured

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 19:15:49 +01:00
cd596b85b3 docs(deployment): remove --upload from backup timer (R2 not yet configured)
All checks were successful
CI / ruff (push) Successful in 11s
CI / pytest (push) Successful in 37m38s
CI / dependency-scanning (push) Successful in 33s
CI / docs (push) Successful in 43s
CI / validate (push) Successful in 24s
CI / deploy (push) Successful in 52s
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 18:28:08 +01:00