feat(loyalty): wallet debug page, Google Wallet fixes, and module config env_file standardization
Some checks failed
CI / ruff (push) Successful in 12s
CI / validate (push) Successful in 27s
CI / dependency-scanning (push) Successful in 32s
CI / pytest (push) Failing after 1h13m39s
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled

- Add wallet diagnostics page at /admin/loyalty/wallet-debug (super admin only)
  with explorer-sidebar pattern: config validation, class status, card inspector,
  save URL tester, recent enrollments, and Apple Wallet status panels
- Fix Google Wallet fat JWT: include both loyaltyClasses and loyaltyObjects in
  payload, use UNDER_REVIEW instead of DRAFT for class reviewStatus
- Fix StorefrontProgramResponse schema: accept google_class_id values while
  keeping exclude=True (was rejecting non-None values)
- Standardize all module configs to read from .env file directly
  (env_file=".env", extra="ignore") matching core Settings pattern
- Add MOD-026 architecture rule enforcing env_file in module configs
- Add SVC-005 noqa support in architecture validator
- Add test files for dev_tools domain_health and isolation_audit services
- Add google_wallet_status.py script for querying Google Wallet API
- Use table_wrapper macro in wallet-debug.html (FE-005 compliance)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-19 22:18:39 +01:00
parent 11b8e31a29
commit f89c0382f0
31 changed files with 1721 additions and 64 deletions

View File

@@ -2236,6 +2236,9 @@ class ArchitectureValidator:
for i, line in enumerate(lines, 1):
# Check for .all() queries that might not be scoped
if ".query(" in line and ".all()" in line:
# Skip if noqa comment present
if "noqa: SVC-005" in line or "noqa: SVC005" in line:
continue
# Check context for store filtering
context_start = max(0, i - 5)
context_end = min(len(lines), i + 3)
@@ -4112,7 +4115,7 @@ class ArchitectureValidator:
)
def _validate_modules(self, target_path: Path):
"""Validate module structure rules (MOD-001 to MOD-012)"""
"""Validate module structure rules (MOD-001 to MOD-012, MOD-026)"""
print("📦 Validating module structure...")
modules_path = target_path / "app" / "modules"
@@ -4353,6 +4356,47 @@ class ArchitectureValidator:
suggestion=f"Add translation files: {', '.join(missing_langs)}",
)
# MOD-026: Check config.py uses env_file for .env loading
config_file = module_dir / "config.py"
if config_file.exists():
config_content = config_file.read_text()
if "model_config" in config_content:
if '"env_file"' not in config_content and "'env_file'" not in config_content:
# Find the model_config line number
config_line = next(
(i for i, line in enumerate(config_content.split("\n"), 1) if "model_config" in line),
1,
)
self._add_violation(
rule_id="MOD-026",
rule_name="Module config must read from .env file",
severity=Severity.ERROR,
file_path=config_file,
line_number=config_line,
message=f"Module '{module_name}' config has model_config without env_file=\".env\""
"settings won't load from .env when running outside Docker",
context="model_config missing env_file",
suggestion='Add env_file and extra to model_config: '
'{"env_prefix": "...", "env_file": ".env", "extra": "ignore"}',
)
if '"extra"' not in config_content and "'extra'" not in config_content:
config_line = next(
(i for i, line in enumerate(config_content.split("\n"), 1) if "model_config" in line),
1,
)
self._add_violation(
rule_id="MOD-026",
rule_name="Module config must ignore extra .env fields",
severity=Severity.ERROR,
file_path=config_file,
line_number=config_line,
message=f"Module '{module_name}' config has model_config without extra=\"ignore\""
"will fail when .env contains vars for other modules",
context="model_config missing extra=ignore",
suggestion='Add extra to model_config: '
'{"env_prefix": "...", "env_file": ".env", "extra": "ignore"}',
)
# MOD-007: Validate definition paths match directory structure
self._validate_module_definition_paths(module_dir, module_name, definition_file, definition_content)