feat(arch-rules): TPL-016 flags large persona templates that skip shared/
Some checks failed
CI / ruff (push) Successful in 17s
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

Architecture rule that warns on any template under
app/modules/<m>/templates/<m>/{admin,merchant,store}/*.html that
exceeds 75 LOC AND does not {% include %} a `*/shared/*` partial.

Catches new persona-specific templates that inline body content rather
than sharing it with sibling personas (the project-wide pain point that
prompted the persona-template-consolidation work).

- Rule definition in .architecture-rules/frontend.yaml at warning
  severity. Suppressible per-file with `{# noqa: TPL-016 #}`.
- Check function `_check_persona_template_shared_include` in
  scripts/validate/validate_architecture.py, wired at both template
  validation sites (full scan + per-file -f mode).
- Loyalty was migrated under this rule and reports clean (5 legit
  exceptions carry noqa with reason).
- First run surfaces ~110 warnings across other modules — the
  migration backlog. Severity stays at warning until at least one
  non-loyalty module is migrated, then escalate to error.

See docs/architecture/persona-template-consolidation.md for the
pattern this rule guards.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-23 23:11:21 +02:00
parent f82dce30ca
commit f9a15deed7
2 changed files with 88 additions and 0 deletions

View File

@@ -644,6 +644,37 @@ template_rules:
exceptions:
- "shared/macros/headers.html"
- id: "TPL-016"
name: "Persona templates >75 LOC must include a shared/ partial"
severity: "warning"
description: |
Any persona template (under app/modules/<m>/templates/<m>/{admin,merchant,store}/*.html)
that exceeds 75 LOC AND does not {% include %} a `*/shared/*` partial is likely
duplicating body content that should live in a shared partial used by all three
personas. See docs/architecture/persona-template-consolidation.md for the pattern.
RIGHT (thin wrapper + shared body):
{% extends "store/base.html" %}
...page-header + loading/error...
{% set cards_api_prefix = '/store/loyalty' %}
{% set cards_base_url = '/store/' ~ store_code ~ '/loyalty/cards' %}
{% include 'loyalty/shared/cards-list.html' %}
WRONG (inlined table + filters that already exist in shared/):
{% extends "store/base.html" %}
...200 lines of inline <table>/filters/pagination identical to merchant's...
Suppress for legit exceptions (admin multi-merchant aggregator, store-only
hardware UI, persona-unique tabbed dashboard) with `{# noqa: TPL-016 #}`
anywhere in the file.
pattern:
file_pattern: "app/modules/*/templates/*/{admin,merchant,store}/*.html"
threshold_loc: 75
required_pattern: "{% include .*/shared/.*"
exceptions:
- "base.html"
- "partials/"
- id: "TPL-014"
name: "Use new modal_simple macro API with call block"
severity: "error"