Skip to content

Audit follow-ups: criteria stepper, risk scale reload, direct delete links, assessment phases - #182

Merged
frousselet merged 5 commits into
mainfrom
feat/ui-audit-framework
Nov 3, 2026
Merged

frousselet merged 5 commits into
mainfrom
feat/ui-audit-framework

Conversation

@frousselet

Copy link
Copy Markdown
Owner

Summary

Follow-up fixes for the defects noticed during the UX/UI audit (#181) but kept out of it: a missing lifecycle stepper, a risk form behaviour that never worked where risks are actually created (plus the scope leak behind it), drawer delete links that rendered a bare fragment, a status literal in the assessment results, and two missing breadcrumbs.

Related issue

Follow-up to #181.

Type of change

  • Bug fix
  • New feature
  • Refactor / tech debt
  • Documentation
  • Build / CI / tooling

Changes

  • 48bdb99 Risk criteria stepper: the criteria detail view lacked LifecycleStepperMixin, so a criteria set could not be submitted, validated or archived from the interface.
  • ec8d4ea Risk scales reload: choosing another assessment on a new risk reloads its likelihood / impact scales in the drawer, on the page and after a boosted navigation. The behaviour is declared on the form (data-scale-source / data-scale-target) and wired once in base.html (TomSelect-aware); the inline DOMContentLoaded script, which never ran in the drawer, is gone. Security: the scale endpoint now applies the user's scopes before reading an assessment's criteria. The "validated criteria" fallback uses reportable().
  • b3c1a16 Assessment phases: ComplianceAssessment.is_planning_phase / is_fieldwork_phase replace a status tuple in the toggle view and assessment.status == 'in_progress' in the results template.
  • bbf42ac Drawer delete links: thirteen drawer-only delete views render a full confirmation page on a direct visit (ConfirmDeleteShellMixin + {% extends delete_shell %}), with the same wording; the page form posts without hx-boost so it redirects. Documented in docs/sdk/ui-components.md.
  • 887da21 Breadcrumbs: NAV_TREE entries for the Trust Center hub and the semantic index.

Screenshots

The direct visit to an incident delete URL now renders the confirmation page (checked at 390 px dark: page shell, consequences kept, Cancel left, Delete right). The scale reload was exercised in a browser, in the drawer and after a boosted navigation, with a stubbed endpoint returning distinct scales: the TomSelect options are replaced.

Checklist

  • Tests added or updated, and pytest passes
  • ruff check passes
  • New feature exposed as MCP tools in mcp/tools.py (accurate docstrings and parameter descriptions)
  • New feature has REST API endpoints under the app's api/ (serializers, viewsets, routes under /api/v1/)
  • UI renders correctly in light and dark mode
  • UI renders correctly on mobile (multi-selects, sticky bars, form layouts)
  • User-facing strings use _() / {% trans %} with French translations in locale/fr/LC_MESSAGES/django.po (no duplicate msgid; compilemessages passes)
  • Lifecycle / workflow respected (state metadata and generic stepper UI; no hardcoded status values)
  • README.md updated (features, MCP tools, tech stack, install) when behaviour changed
  • CHANGELOG.md updated under ## [Unreleased]
  • Brand guidelines respected (docs/brand/brand-guidelines.md); no em dash characters
  • Relevant spec under docs/specs/ updated in the same PR
  • Project / documentation screenshots captured at 2560x1440 (16:9, 1440p)
  • Audit-grade rigor preserved (approval workflows, versioning, history, permission checks not bypassed)

Not applicable: no new capability (no MCP tool, endpoint, README or spec change; no new string), and no documented screen changed appearance. Full suite: 3,271 passed; generate_docs --check and build_wiki.py --check clean.

Left for a decision: the EBIOS RM spec sets no ordering between workshops, so W4 / W5 can be started while W3 is in progress; not changed here.

🤖 Generated with Claude Code

https://claude.ai/code/session_01FaEkJnhS3VNDeb6jrdn6MC

RiskCriteria runs the default lifecycle, but its detail view lacked
LifecycleStepperMixin and its template the shared stepper include, so
a criteria set could not be submitted, validated or archived from the
interface. Both are added, with a test on the transition URL.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FaEkJnhS3VNDeb6jrdn6MC
The risk form reloaded the likelihood / impact choices of the chosen
assessment from an inline script bound to DOMContentLoaded: it never
ran in the drawer (the way risks are created) nor after a boosted
navigation, and on the page it rewrote options TomSelect no longer
displayed.

The behaviour is now declared on the form (data-scale-source on the
assessment, data-scale-target on the four scales) and wired once in
base.html by a delegated change listener that refreshes plain and
TomSelect-enhanced selects alike. The form's fallback to "a validated
criteria set" goes through reportable() instead of a state literal.

Security: the scale endpoint looked the assessment up without the
user's scopes, so it disclosed the scale labels of any assessment; it
now answers with the defaults for an assessment the user cannot see.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FaEkJnhS3VNDeb6jrdn6MC
…dwork phases

The result toggle view decided "planning" from a tuple of statuses and
the results table decided "fieldwork" by comparing
assessment.status == 'in_progress' in the template, two copies of one
rule. ComplianceAssessment now exposes is_planning_phase and
is_fieldwork_phase, built on ASSESSMENT_PLANNING_STATUSES /
ASSESSMENT_FIELDWORK_STATUSES next to the existing toggleable set, and
both the view and the template read them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FaEkJnhS3VNDeb6jrdn6MC
Thirteen delete views (ten in incidents, the nonconformity register,
supplier contacts and sub-processors) only had a drawer template, so
opening their /delete/ URL directly (a bookmark, a shared link) returned
the bare modal fragment outside the page.

Their templates now extend delete_shell, which the new
ConfirmDeleteShellMixin sets to the modal shell for a drawer request and
to includes/confirm_delete_page.html otherwise; both shells read the
same blocks, so the wording, consequences and protection notices are
identical. The page shell posts without hx-boost, so its form performs
a plain POST and redirect (a boosted POST would get the drawer's 204).
is_drawer_request() is extracted from HtmxFormMixin and shared.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FaEkJnhS3VNDeb6jrdn6MC
Neither page had a NAV_TREE entry, so their headers fell back to a
plain eyebrow, and the hub's read "Strategy" although it is reached
from Administration > General. Both now build the menu breadcrumb.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FaEkJnhS3VNDeb6jrdn6MC
@frousselet
frousselet merged commit 9c2d632 into main Nov 3, 2026
7 checks passed
@frousselet
frousselet deleted the feat/ui-audit-framework branch November 3, 2026 19:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants