Commit graph

15 commits

Author SHA1 Message Date
Vadym Samoilenko
a5784feda6 Address client feedback: WCAG badges, table grouping, retention, history UX, AI prompt ethics
- Issue 1: Recompute WCAG A/AA compliance badges after dismissing issues (JS +
  backend); exported reports now reflect updated pass/fail status
- Issue 2: Group document-wide table issues into collapsible cards with
  Dismiss All button; reduces noise for multi-table documents
- Issue 3: Split cleanup retention — uploads deleted after 24h, result/meta
  JSONs retained 30 days (RESULTS_RETENTION_HOURS env var, default 720h)
- Issue 4A: Library shows adjusted score when available (.adjusted.json preferred)
- Issue 4B: History page groups documents by retention countdown (red/yellow/green
  sections); adds 30-day retention banner
- Issue 5+6: AI prompt updated — describe people by role/action not appearance,
  use specific brand names; flags images with people for human review

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 10:51:10 +00:00
Vadym Samoilenko
79aaf050bf PDF report reflects adjusted score + manual pass for Matterhorn H-type CPs
- api.php: add save_adjusted_result action that merges dismissed issues,
  check overrides and recalculated score into {job_id}.adjusted.json;
  handleExport() now prefers .adjusted.json over .result.json
- js/results.js: displayMatterhorn() shows Mark as Passed / Undo buttons
  for H-type CPs (CP04, CP13) linked to overridden checks; overrideCheck /
  unoverrideCheck refresh Matterhorn table and recompute overall banner
- js/batch.js: exportReport() saves adjusted result before opening export
  URL, using pre-opened window to avoid popup blockers
- report_generator.py: filter dismissed issues, show (Adjusted) badge,
  Manual Pass in checks and Matterhorn tables; switch generate_html() to
  Montserrat + Oliver branding (#1a1a1a header, #FFC407 skip-link)
- css/styles.css: fix dark-mode log-header from blue-ish #252840 to #242424

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 16:28:53 +00:00
Vadym Samoilenko
5858f3c90d Header: remove sticky positioning, scrolls with page 2026-03-13 15:25:57 +00:00
Vadym Samoilenko
efa5ca09ba Fix sticky header: top: 30px -> top: 0 (dev banner was removed) 2026-03-13 15:25:06 +00:00
Vadym Samoilenko
1126c8a700 Fix history: correct score field name + add delete button
- api.php: read accessibility_score (not score) from result.json
- api.php: handleDelete() also removes .dismissed.json, .overrides.json, .error.log
- js/app.js: add Delete button to each history row with confirm dialog
- css/styles.css: red hover style for delete button

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 15:13:30 +00:00
Vadym Samoilenko
e60639c58d Add SSO user isolation and document history dashboard
- api.php: extractUserFromToken() decodes Azure AD JWT payload (oid/name/email)
- Upload: stores user_id, user_name, user_email in job .meta.json
- handleList(): filters jobs by authenticated user's oid — full user isolation
  (jobs without user_id are excluded for authenticated users to prevent leakage);
  enriches each entry with score, grade, critical/error counts from result JSON
- index.html: "My Documents" history section, shown after login
- js/app.js: showAuthenticatedUI() triggers loadHistory(); full renderHistory()
  renders sortable table with score, grade, severity badges, and Open/HTML/PDF/JSON
  action buttons; openHistoryJob() loads any past result into the results panel
- js/results.js: calls loadHistory() after displayResults() so table refreshes
  immediately after a new check completes
- css/styles.css: history table styles with colour-coded score/grade/severity badges

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 14:58:18 +00:00
Vadym Samoilenko
350f5de56e Fix Recalculate Score button click area clipped by overflow:hidden
.score-display had overflow:hidden which cut off the right half of the
btn-recheck button. Changed to overflow:visible — decorative ::before
and ::after pseudo-elements use position:absolute;inset:0 so they remain
visually contained within the border-radius.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 14:42:16 +00:00
Vadym Samoilenko
148853c699 Add WCAG compliance summary, level badges, font names, next steps
enterprise_pdf_checker.py:
- WCAG_LEVELS dict maps all 2.1 criteria to A/AA/AAA
- AccessibilityIssue.to_dict() now includes wcag_level field
- _check_fonts() collects actual font names into details dict
  instead of just counting (details.non_embedded_fonts list)
- _generate_summary() adds wcag_compliance block:
    level_a / level_aa bool + failing criteria lists
- _generate_summary() adds next_steps: top 8 prioritised actions
  (Critical → Error → Warning, deduplicated by recommendation text)

js/results.js:
- displayWcagCompliance(): renders pass/fail badges for Level A/AA
- displayNextSteps(): numbered action list with priority badges
- createIssueCard(): shows wcag_level pill (A/AA/AAA) alongside
  WCAG criterion link

index.html:
- #wcagCompliance div between statsGrid and scoreBreakdown
- #nextStepsCard below remediationCard

css/styles.css:
- .wcag-badge, .wcag-compliance-row, .wcag-badge-level/status
- .wcag-level-badge + .wcag-level-A/AA/AAA colour variants
- .next-step-item, .next-step-num, .next-step-body/action/meta

report_generator.py:
- HTML report: WCAG conformance section + next steps table
  between score card and issues table
- PDF report: compliance banners + next steps table in sections_html

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 14:32:21 +00:00
Vadym Samoilenko
304526a8c4 Fix 13 WCAG accessibility violations in the checker UI itself
HTML:
- Move <div id="msalConfig"> out of <head> (invalid HTML)
- Add skip-to-main-content link (WCAG 2.4.1)
- Wrap content in <main id="main-content">
- Auth overlay: aria-modal, aria-describedby, aria-describedby on p
- Microsoft SVG: aria-hidden="true" (decorative)
- Tab buttons: aria-controls; panels: role=tabpanel, aria-labelledby
- Score number: <div> → <output> element
- Marker legend: role=legend (invalid) → role=region + aria-label
- Reset zoom button: aria-label added

CSS:
- input:focus outline:none → outline:2px solid accent (WCAG 2.4.7)
- --text-muted #696969 → #5a5a5a (~5.5:1 contrast, was 4.35:1)
- Skip link styles (visible on focus)
- @media (prefers-reduced-motion: reduce) disables all animations

JS:
- upload.js/batch.js: keydown Enter/Space activates upload areas (WCAG 2.1.1)
- results.js: issue cards get role=listitem inside role=list
- results.js: filterIssues() updates aria-pressed on all filter buttons
- results.js: displayResults() focuses resultsSection for screen readers
- utils.js: aria-valuenow set on role=progressbar element, not fill div

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 14:19:20 +00:00
Vadym Samoilenko
c932e8b7e1 Make WCAG criterion badges clickable links to Understanding pages
Each issue card's WCAG criterion (e.g. "1.4.3") is now a link to the
WAI Understanding page at w3.org. Comma-separated multi-criteria and
PDF/UA are handled separately. Links open in a new tab.

- js/utils.js: WCAG_SLUGS map + wcagCriterionLinks() helper
- js/results.js: issue-meta now calls wcagCriterionLinks()
- css/styles.css: .wcag-link style (dotted underline, hover accent)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 14:05:55 +00:00
Vadym Samoilenko
8b70da3584 Add "Mark as Passed" check overrides and "Recalculate Score" feature
- api.php: override_check / unoverride_check endpoints write per-job
  .overrides.json; handleResult() injects overridden_checks on reload
- js/results.js: score breakdown rows show "Mark as Passed" / "Undo"
  buttons; recalculateScore() adjusts penalty for dismissed issues and
  base score for manual overrides without mutating original data
- index.html: score display gains hidden (Adjusted) badge and
  Recalculate Score button, revealed after first check
- css/styles.css: btn-mark-passed, btn-unoverride, check-manual-pass,
  btn-recheck, score-adjusted-label styles
- js/utils.js: escapeAttr() helper for safe inline onclick values

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 14:01:52 +00:00
Vadym Samoilenko
a5cd1af982 Fix color contrast false positives; table caption INFO; dismiss button more visible
Color contrast:
- Sample pixels 8px apart vertically instead of adjacent horizontal pixels
- Filter out near-uniform pairs (|Δlum| < 0.08) — eliminates photo/gradient noise
- ERROR threshold: >60% of significant edges fail (was 15% of all pixels)
- WARNING threshold: >30% (was 5%)
- Returns early with 'image-only page' if <20 significant edges found

Tables:
- Caption warning downgraded WARNING → INFO (table may have visible title nearby)
- Does not count toward check pass/fail anymore

Dismiss button:
- Renamed 'Dismiss' → '✕ False Positive' (clearer intent)
- Added background color so it's visible against card
- font-size 11→12px, padding increased

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 19:15:28 +00:00
Vadym Samoilenko
ac8aedf4a3 Implement QA report fixes: scoring, Matterhorn, dismiss, PDF report, UX
Part 1 — CSS/Contrast/Accessibility:
- Raise --text-muted contrast to WCAG AA (#696969 light, #9a9a9a dark)
- Add body font-size: 16px baseline
- Enlarge #themeToggle to 15px / 10px 20px padding

Part 2 — Start Button (user-controlled analysis):
- Upload no longer auto-starts check; shows ready state with filename/size
- New showReadyState() / removeFile() functions in upload.js
- beginCheck() now shows progress + hides ready state on click
- Add prominent "Check Another PDF" button at bottom of results

Part 3 — Scoring recalibration:
- Replace deduction formula with check-pass ratio + soft penalty (cap 20)
- Fix run_check() to only examine issues added by the current check
- Add score_breakdown (per-check table) to JSON output + results UI
- Downgrade readability ERROR → WARNING (advisory, not hard failure)

Part 4 — Auto-fix debugging:
- Remediation failure now returns up to 2000 chars of log (was 500)
- pdf_remediation.py: stderr output, sys.exit(0/1), output dir creation

Part 5 — Error location: View on Page button on each issue card

Part 6 — Matterhorn Protocol PDF/UA-1:
- _build_matterhorn_summary() maps 19 checks → 31 checkpoints
- Matterhorn card in index.html with grouped PASS/FAIL/Not-tested table
- Correct M/H badges per checkpoint

Part 7 — Dismiss / False Positive:
- dismissed_issues table in db/init.sql + dismiss/undismiss in db_manager.py
- api.php: dismiss/undismiss endpoints (file-backed), dismissed_indices
  injected into both handleStatus and handleResult responses
- results.js: dismissIssue/undismissIssue with visual strikethrough
- CSS: .dismissed, .btn-dismiss, .btn-undismiss styles

Part 8 — PDF Report (WeasyPrint):
- generate_pdf() in report_generator.py: PAC-style A4, Oliver branding
- api.php handleExport() supports format=pdf
- index.html: "PDF Report" download button in results header
- requirements.txt: weasyprint>=60.0

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 18:06:32 +00:00
Vadym Samoilenko
345cc1ceb2 Switch to Oliver branding: Montserrat font, black/#FFC407 palette, fix dark mode contrast
- Font: Outfit/Figtree → Montserrat
- Accent: coral #e8553d → Oliver yellow #FFC407 with black text
- Dark mode: neutral blacks instead of blue-tinted navy
- Fix score display, stat cards, and log entries contrast in dark mode
- Replace hardcoded light-mode colors in JS with CSS variables

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 18:54:47 +00:00
Vadym Samoilenko
112719b2c5 Add Docker stack, frontend redesign, and visual page inspector fix
- Redesigned frontend with Outfit/Figtree typography, coral accent palette,
  noise texture, glassmorphism header, and staggered animations
- Split monolithic index.html into modular JS (app, api, upload, batch,
  results, page-viewer, utils) and extracted CSS
- Fixed worker.py to generate page images for Visual Page Inspector
- Added Docker Compose stack (web, worker, redis, postgres)
- Added batch upload, HTML report export, rate limiting, and Redis queue
- Extended test suite with checker, remediation, worker, and DB tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 18:12:44 +00:00