Commit graph

131 commits

Author SHA1 Message Date
michael
a08d54ec6d Fix Agency Admin campaign creation and proof upload permissions
Switch canWrite from blacklist (role !== 'oversight_admin') to explicit
whitelist (super_admin, agency_admin, basic_user) for clearer permission
logic. Propagate readOnly prop to CampaignDetail and ProofDetailView
subcomponents so upload/delete buttons are properly hidden for read-only
roles at all navigation levels.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 07:23:58 -06:00
michael
3207ec301c Standardise Issue/Recommendation formatting across all agents
Replace single-line bullet format with a structured two-part format
(**Issue:** / **Recommendation:**) in all specialist and lead agent
prompts. Update Gemini response schema description to match. Update
frontend formatFeedbackText and formatFeedbackTextForPDF to parse
**bold** markdown and preserve line breaks within multi-line bullets.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 10:17:08 -06:00
michael
f1183e1bff Display user role and agency on Profile page
Replace the hardcoded "Account Type" field with a "Role" field that
shows the user's role label and agency name from the backend /api/me
endpoint (e.g. "Super Admin (Oliver)", "Standard User (Barclays)").

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 10:00:25 -06:00
michael
a2f52c0960 Add example-correction formatting rule to all agent prompts
Agents now show example corrections in the format they're recommending
(e.g. sentence case examples when recommending sentence case) to avoid
contradictions between advice and examples.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 09:55:01 -06:00
michael
4cae1e4c78 Remove "Verdict:" prefix inconsistency from lead agent summaries
Replace all "verdict" language in the lead agent prompt with "status/summary"
and add prescriptive opening-line templates so the LLM produces consistent
output without a "Verdict:" prefix.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 09:50:26 -06:00
michael
dee0df57d8 Rename "Actionable Issues" heading to "Key Actions"
Replace the repetitive "Actionable Issues" label with the more
constructive "Key Actions" in the feedback report and PDF export.
Remove the uppercase CSS class so the heading renders in sentence case.
Update empty-state text to "No key actions identified."

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 09:42:27 -06:00
michael
37f364ec0f Add acronym expansion guidance to all agent prompts
Agents now spell out acronyms in full on first use (e.g. "Web Content
Accessibility Guidelines (WCAG)") for clarity. The instruction covers
common acronyms like WCAG, FSCS, GDE, APR, CTA, FCA, PRA, and T&Cs,
and applies to any acronym encountered in output.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 09:35:45 -06:00
michael
f92e76b333 Add punctuation and capitalisation consistency rules to all agent prompts
Adds an IMPORTANT instruction block to all 5 agent prompt templates
(legal, brand, channel best practices, channel tech specs, lead) that
enforces: capitalisation after full stops and in labels, consistent
bullet-point ending style, and "e.g." without a trailing comma.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 09:31:37 -06:00
michael
6504511fb6 Add Plain English language instructions to all agent prompts
Instructs all five agents (legal, brand, channel best practices,
channel tech specs, lead) to prefer simple vocabulary over complex
alternatives (e.g. "add" over "incorporate", "about" over "regarding").
Also fixes "constitute" → "qualify as" in the legal agent prompt itself.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 09:26:39 -06:00
michael
265bf08470 Replace punitive "violation" language with constructive alternatives in agent prompts
UAT feedback flagged the use of "violations", "violates", etc. as feeling
accusatory. Replaced all instances with constructive terms ("issues",
"doesn't align with", "doesn't meet") and added an explicit instruction
to all 5 agent prompt templates to avoid this language in output.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 09:18:52 -06:00
michael
4a684e7757 Enforce British English spelling in all agent prompt templates
Added explicit UK English instruction to the Response Format section of
all five agents (legal, brand, channel best practices, channel tech specs,
lead) so output uses spellings like "authorised", "colour", "capitalise".

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 08:53:51 -06:00
michael
05e74becfe Add frontend RBAC: UserContext, role-based sidebar, agency filter, user management
- Add UserRole type and AppUser interface to types.ts
- Create UserContext with useUser() hook providing role-based permission booleans
- Split App into App (auth wrapper) + AppContent (uses UserContext)
- Update Sidebar to filter nav items by UserRole instead of boolean isAdmin
- Add User Management nav item (super_admin only)
- Add AgencyFilterBar component for oversight_admin/super_admin session-level filtering
- Pass agencyId to getCampaigns, getAnalytics, audit endpoints in apiService
- Add getMe, getUsers, updateUser, createAgency to apiService
- Build UserManagement page with user table (role/agency dropdowns) and agency CRUD
- Add readOnly prop to Campaigns (hides create/delete/status-toggle for oversight_admin)
- Add readOnly prop to Settings (disables all ManagementCards, shows view-only banner)
- Pass agencyId to Analytics component for filtered data
- Update urlState with Knowledge Base and User Management views

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 08:36:38 -06:00
michael
d21036a0de Add 4-tier RBAC backend: auth dependencies, role enforcement, agency filtering
- Add CHECK constraint migration for users.role (super_admin, oversight_admin, agency_admin, basic_user)
- Add get_current_db_user dependency resolving Azure claims to User ORM with agency
- Add require_role() factory and require_write_access() dependency
- Auto-promote dev user to super_admin when DISABLE_AUTH=true
- Add /api/me, PUT /api/users/{id}, POST /api/agencies endpoints
- Apply agency-based data filtering on campaigns, analytics, audit routes
- Block oversight_admin from all mutation routes (campaigns, proofs, flags, resolves)
- Restrict dropdown option mutations to super_admin only
- Add role check in WebSocket handler to block oversight_admin from analysis
- Add CurrentUserResponse, UserUpdate, AgencyCreate schemas

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 08:28:23 -06:00
michael
6bd8a03a15 Remove page number and document name references from agent feedback
Add explicit no-citations instructions to all 5 agent prompts to prevent
Gemini from including page numbers, document names, or source citations
in analysis feedback. These references were unhelpful since the system
doesn't use RAG and users cannot action them.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 08:39:41 -06:00
michael
60ac3ab22e Rewrite distillation prompts to preserve all source document details
The previous prompts instructed Gemini to "remove redundancy, marketing
fluff, or content not relevant to..." which caused salient details —
especially unusual, granular, or edge-case instructions — to be lost
from spec output. Rewritten all 5 agent prompts (legal, brand_barclays,
brand_barclaycard, channel_best_practices, channel_tech_specs) to:

- Reframe the task as "restructure and organise" rather than "distil
  and filter"
- Add a zero-tolerance detail-loss instruction with concrete examples
  of unconventional rules that must be preserved
- Explicitly forbid omitting, summarising away, or paraphrasing
  specific rules/values/conditions
- Allow merging only exact duplicates while keeping all unique content

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 08:21:03 -06:00
michael
00207be5f0 Add metadata specifications summary to Channel Tech Specs agent output
Instruct Gemini to begin its feedback with a "Specifications checked"
line recapping the channel, sub-channel, and proof type metadata so
reviewers can confirm the correct specs were applied.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 07:59:41 -06:00
michael
941f84d7ed Fix resolved items not persisting in proof report UI after refresh
Thread resolvedItems from App → Campaigns → ProofDetailView → FeedbackReport
→ SubReviewCard so that issues previously marked as resolved are restored
from the database on page load instead of resetting to actionable.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 07:39:34 -06:00
michael
3e548bc949 Fix flags and resolves not persisting to database
Remove proof_version_id from FlaggedItemCreate and ResolvedItemCreate
request schemas — the backend already derives it from URL path params.
The frontend was sending an empty string which caused Pydantic to reject
the request with 422, silently preventing flags/resolves from saving.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 07:26:11 -06:00
michael
f3d7f9b6d3 Fix retry reprocessing all proofs instead of just the failed one
DB-loaded proofs don't have a tempId, so the retry handler's
proof.tempId === tempId check matched all DB proofs (both undefined).
Now the handler uses a matchProof helper that checks both tempId and
_id, and call sites pass proof.tempId || proof._id as the identifier.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 18:15:09 -06:00
michael
a15bce8796 Add clickable error modal for failed proof analyses
When a proof analysis fails, "Analysis failed." is now a clickable
underlined link that opens a modal showing:
- The lead agent summary explaining why the analysis failed
- Details for each agent that returned an Error status

Applied to both Campaigns and Projects views.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 18:09:15 -06:00
michael
1800e71229 Fix cache invalidation falling back to static files after reprocessing
After processing a new knowledge base spec, invalidate_cache() was
clearing the DB spec from the cache without replacing it. The next
analysis would then fall back to static prompts/*.md files instead of
using the newly generated DB spec.

Now invalidate_cache() accepts optional new_spec_content to immediately
populate the DB cache, and knowledge_base_service passes the freshly
distilled spec content so it's available for the next analysis without
a server restart.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 17:56:11 -06:00
michael
de62fa1f87 Show partial parse status in UI when some pages fail
- LlamaParse service now returns a ParseResult dataclass with markdown,
  total page count, and a list of failed pages (page number + error)
- Knowledge base service sets status to "partial" (instead of "parsed")
  when some pages failed, with a descriptive error listing which pages
  failed and why
- Frontend StatusBadge shows "partial parse" in orange for partial status
- Error details are shown inline below the document row for both partial
  and error statuses

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 17:51:52 -06:00
michael
49facbe713 Log full details of failed LlamaParse pages for troubleshooting
Handle MarkdownPageFailedMarkdownPage objects gracefully by checking for
the markdown attribute with hasattr instead of assuming all pages have
it. Failed pages now log their type and all attributes so the actual
LlamaParse error is visible in logs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 17:45:58 -06:00
michael
8a9a24ebe6 Parallelize LlamaParse document processing with asyncio.gather
Parse documents concurrently (up to 10 at a time via semaphore) instead
of serially. Each coroutine uses its own DB session for per-document
status updates, while a shared lock serializes job progress increments
on the main session to avoid session-sharing issues.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 17:39:01 -06:00
michael
919e8185fa Add confirmation dialog before deleting source documents
Prevents accidental deletion of knowledge base source documents by
prompting the user to confirm before proceeding.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 16:28:25 -06:00
michael
ba9c0ebde3 Reduce auth logging verbosity: INFO → DEBUG
All routine MSAL token verification logs now use DEBUG level so they
don't flood the console on every polling request.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 16:13:25 -06:00
michael
7835f557aa Fix processing job not visible to background task (FK violation)
The background task runs in its own DB session but the job row hadn't been
committed yet by the request session. The background task couldn't find
the job, causing FK violations when trying to create spec_versions.

Fix: explicitly commit the request session after creating the job and
before adding the background task, ensuring the job row is visible.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 16:09:50 -06:00
michael
3aa99144d4 Stop job polling on error (404) to prevent infinite poll loop
When the poll request fails (e.g. job not found 404), clear the activeJob
state and stop the interval instead of endlessly retrying. Also refresh
the KB detail to get the current state.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 16:08:21 -06:00
michael
42bf5ad003 Fix stuck processing state: auto-fail stale jobs, improve active job detection
- Frontend: only treat parsing_documents/distilling as actively running;
  pending jobs older than 2 minutes are ignored as stale
- Backend: add fail_stale_jobs() that marks pending/active jobs older than
  5 minutes as failed before checking for active jobs in trigger_processing
- Prevents UI from getting stuck on old jobs that never completed

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 16:03:25 -06:00
michael
0b7213af01 Fix doc ID mismatch in KB document upload
Create DB record first to get the auto-generated UUID, then use that ID
for the storage key. Previously a separate UUID was generated for storage
but the DB record got a different one, causing file retrieval to fail
during processing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 15:50:35 -06:00
michael
1601622e07 Fix SpecVersion/ProcessingJob circular relationship direction error
Remove bidirectional back_populates between SpecVersion and ProcessingJob
since both sides have FKs to each other (circular), causing SQLAlchemy to
see both as MANYTOONE. ProcessingJob.spec_version is now a standalone
relationship with explicit foreign_keys. SpecVersion no longer has a
reverse relationship to ProcessingJob (not needed for any queries).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 15:42:35 -06:00
michael
4833fa127d Fix SQLAlchemy ambiguous FK error between SpecVersion and ProcessingJob
Add explicit foreign_keys argument to both sides of the bidirectional
relationship to resolve the multiple FK paths (SpecVersion.processing_job_id
and ProcessingJob.spec_version_id).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 15:40:36 -06:00
michael
2c6f3d0686 Switch LlamaParse to llama-cloud SDK with agentic_plus tier
Replace deprecated llama-cloud-services package with llama-cloud>=1.0 (API v2).
Use AsyncLlamaCloud client with tier="agentic_plus" for maximum parsing accuracy
on complex layouts, tables, and visual structure.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 15:29:23 -06:00
michael
9e2473c3e9 Add Knowledge Base management system for AI agent specs
Full-stack implementation enabling UI-driven management of the 5 AI agent knowledge bases
(Legal, Brand Barclays, Brand Barclaycard, Channel Best Practices, Channel Tech Specs).

Backend:
- 4 new DB models: KnowledgeBase, SourceDocument, SpecVersion, ProcessingJob
- Migration 006: creates tables, seeds 5 KB rows, imports existing prompts/*.md as v1 specs
- KnowledgeBaseRepository with full CRUD for all 4 tables
- LlamaParseService for document parsing, KnowledgeBaseService for pipeline orchestration
- ReferenceDocsService updated with DB-backed spec loading + cache invalidation
- 11 REST endpoints under /api/knowledge-base (list, detail, upload, delete, process, job status, versions, diff, activate)
- StorageService extended with KB document storage

Frontend:
- TypeScript types for all KB entities (KnowledgeBaseListItem, SourceDocument, ProcessingJob, SpecVersion, DiffResult)
- ApiService methods for all KB endpoints including multipart file upload
- KnowledgeBase component with 3-level UI: agent grid, detail view (documents + versions tabs), diff viewer
- Drag-and-drop file upload, processing progress bar with 3s polling, version comparison
- KnowledgeBaseIcon + Sidebar nav item with adminOnly filtering

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-12 15:00:36 -06:00
michael
2b2d82ecec Fix Resolutions tab Proof Name to use blue link styling
Change from plain black text (font-medium text-black-title) to blue
link styling (font-semibold text-active-blue), matching the Flags and
Errors tabs for visual consistency.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 14:09:19 -06:00
michael
220a97ab57 Wire up Errors tab in Auditing: auto-create ErrorItem on Analysis Error
- Create ErrorItem record when proof analysis results in "Analysis Error" status
- Add submitter_name/submitter_agency fields to ErrorItemResponse schema
- Eager-load proof creator and agency in error items query to avoid N+1
- Populate submitter fields from proof creator in the API route
- Update frontend ErrorItemResponse type and conversion to map submitter fields
- Fix ErrorsTable proof name styling to blue link (text-active-blue) matching Flags tab

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 13:55:16 -06:00
michael
9ec892b46b Fix flagging feature: blue link in Auditing, remove alert popup, show solid red flag icon
- Style Proof Name column in Auditing Flags tab as blue clickable link
- Replace browser alert() with in-app success message in flag modal that auto-closes after 2s
- Add filled prop to FlagIcon for solid red variant when flagged
- Thread flaggedItems from App → Campaigns → ProofDetailView → FeedbackReport
- Show solid red flag icon on SubReviewCard and LeadAgentSummary when agent has been flagged

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 13:46:15 -06:00
michael
33c2ce5cf4 Remove unused [Beta] tab from Settings page
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 12:07:12 -06:00
michael
cf29d70908 Hide Users tab in Settings since it's not connected to the app
The Settings > Users tab is a disconnected prototype that stores data
only in localStorage and is not used by any other part of the application.
Backend user management is handled separately via Azure AD auto-provisioning.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 11:40:41 -06:00
michael
a67236af73 Remove 'View Documentation' button from Hero section
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 11:33:15 -06:00
michael
a957cf0276 Pass proof metadata (channel, sub-channel, proof type) to AI agents during analysis
Previously, proof metadata collected during upload was only used for database
persistence. Now it flows through the entire analysis pipeline so agents can
tailor their feedback to the specific channel and format being reviewed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 11:30:38 -06:00
michael
adc7a2cc71 Update CampaignDetailView table text color from black to primary blue
Change all proof table body cells in the CampaignDetailView (analyzing,
error, and completed states) from text-black-title to text-primary-blue
to match the campaign list table styling.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 16:59:22 -06:00
michael
325221610f UI overhaul: white backgrounds, flat design, teal hero, sidebar flush-left nav
- Add teal-brand (#01A1A2) color to Tailwind config
- Hero: white bg, teal text, remove gradient circles/noise overlay, font-semibold
- Sidebar: stacked logo, lime COMPLIANCE AI, flush-left active items, remove blue dots
- ChecksOverview: remove gradient background and decorative blurs
- Campaigns: white bg, primary-blue table text, font-semibold headings
- Analytics: white bg, borderless shadow cards, sentence case headings
- Auditing: white bg, font-semibold heading
- Settings: white bg, remove tab container styling, flat cards, sentence case Proof types
- Profile: white bg, flat layout, active-blue question button, design system colors
- All page titles changed from font-bold to font-semibold

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 16:53:03 -06:00
michael
ebf92a91c7 Replace 'asset' with 'proof' in user-facing UI text
Update all user-visible strings across the frontend to use "proof/proofs"
terminology instead of "asset/assets". This includes button labels, headers,
tooltips, confirmation messages, and mock feedback text. Internal code
(variable names, types, HTML IDs) remains unchanged.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 15:45:48 -06:00
michael
35918dd310 Replace low-quality icons on Analytics page with Heroicons
- TrendingUpIcon: Changed to chart-bar icon for Pass Rate
- BugIcon: Changed to x-circle icon for Failed Reviews
- LightbulbIcon: Changed to proper light-bulb icon for Key Insight

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 15:30:18 -06:00
michael
b83a2a219f Adjust status pill padding: 0 top, 13px bottom
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 15:21:24 -06:00
michael
98633534ef Remove debug border and set bottom padding to 20px
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 15:18:47 -06:00
michael
24150ab221 Adjust padding to 2px top / 6px bottom to raise text
More bottom padding pushes text upward in the badge.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 15:16:49 -06:00
michael
ed040efac0 Add blue border to status badge to verify deployment
Testing if changes are being picked up correctly.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 15:15:25 -06:00
michael
8ba0f01e20 Use table/table-cell display for reliable vertical centering
Wrap text in nested spans using display: inline-table on outer
and display: table-cell with vertical-align: middle on inner.
This is a classic centering technique that html2canvas should handle.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 15:09:14 -06:00