- Settings: selected dropdown state now shows azure bg with white text
- Analytics stats: icon circle bg changed from white to grey (#EFEFEF)
- Analytics AI summary: uniform border (remove asymmetric left border);
lightbulb icon sized to match other icons (h-9 w-9)
- Sidebar: active nav item highlight changed from azure to white,
visually connecting to the white main content area
- Sidebar: logo increased from h-20 to h-28
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
All modal inner containers now have border-2 border-oliver-azure
for consistent Oliver branding across:
- CreateCampaignModal, CreateProjectModal
- FeedbackReport (resolve + flag modals)
- UserManagement (confirmation + history modals)
- Campaigns (upload, delete confirmation, version history modals)
- Projects (upload, delete modals)
- Login (support contact modal)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace entire Barclays colour palette (navy #1A2142, lime #C3FB5A, violet
#7A0FF9) with Oliver brand tokens: black #1A1A1A, gold #FFCB05, orange
#FF5C00, azure #0487B6, sky #5DF5EA, grey #EFEFEF, green #09821F.
- Switch font from Inter/Barclays Effra to Arial (system font)
- Add new Oliver logo asset (BAR-ModComms-logo-v4.png)
- Sidebar: black background, new logo, azure active state
- Hero: orange "Intelligent Review" text, hide AI-Powered tagline
- Hide ChecksOverview on Home page per Oliver design
- Toast notification: orange background with black text
- All tables: sky headers, alternating white/grey rows
- Campaign badges: gold "In Progress", green "Completed"
- Analytics: grey KPI cards, sky accent on Key Insight, oliver trend colours
- All buttons: azure fill, pill-shaped (rounded-full)
- All tabs/toggles/dropdowns: azure accent colour
- Update HTML title to "Mod Comms - Intelligent Review"
- Default border radius set to 10px
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
UserManagement now calls refresh() on the global UserContext when the
current user's agency or role is changed, so downstream consumers
(e.g. CreateCampaignModal) immediately reflect the update.
CreateProjectModal now reads the Agency and Agency Lead fields from
the current user's profile instead of hardcoding "OLIVER Agency" and
"Steve O'Donoghue".
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Each line in a bullet group (Issue, Recommendation, etc.) now renders as
its own top-level <li> at the same bullet level. Groups are visually
separated with top margin on the first item of each group.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Recommendation lines are now displayed as an indented nested bullet
beneath their parent Issue bullet, keeping them visually grouped together
while giving each Recommendation its own bullet marker.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Recommendation lines were rendered as continuation text within the same
bullet as their Issue, appearing without a bullet marker. Now lines
starting with "Recommendation:" are treated as new bullet groups so they
each get their own bullet point in the list.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Gemini sometimes returns the literal two-character sequence \n instead of
a real newline in agent feedback text. This caused "Recommendation:" to
appear on the same line as "Issue:" with visible \n characters. Adding a
normalization step at the start of formatFeedbackText converts literal \n
sequences to real newlines so the existing line-splitting logic handles
them correctly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Display the brandGuidelines field as a sortable, filterable "Brand"
column between Owning Agency and Last Modified.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Allow oversight_admin users to view the User Management screen with
read-only access. They can see users, roles, agencies, and change
history but cannot edit roles, assign agencies, or create agencies.
Backend: open GET /users and GET /users/{id}/change-history to
oversight_admin (PUT /users stays super_admin only).
Frontend: add oversight_admin to sidebar nav and context permission,
render static text instead of dropdowns and hide the add-agency form
for non-super-admin users.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Change user-facing strings from American to British English: analyze→analyse,
analyzing→analysing, optimized→optimised, color→colour, analyzes→analyses,
synthesizes→synthesises, optimization→optimisation. Code identifiers, status
enums, and developer-facing messages are intentionally unchanged.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New GET /analytics/by-agency endpoint groups review metrics by agency.
The Analytics page now shows a sortable agency performance table with
pass rates, failures, errors, and legal review counts for each agency.
Only visible to super_admin and oversight_admin users. Selected agency
row is highlighted when the AgencyFilterBar is active.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Backend: Expose created_by field on CampaignResponse schema and all
response constructors in routes.py
- Frontend API layer: Add created_by to CampaignResponse interface and
createdBy to the frontend campaign converter
- Campaign list: Add column sorting (click headers to toggle asc/desc),
per-column text filter inputs below headers, and a "My Campaigns Only"
toggle that filters to campaigns created by the current user
- Default sort is lastModified descending to match existing behavior
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reorder user details from Role/First/Last/Email to First/Last/Email/Role/Agency
so the 2-column grid shows names together at the top. Add Agency as its own
field instead of appending it to the Role display.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace hardcoded "OLIVER Agency" with the logged-in user's agency name
from UserContext. The field remains disabled/non-editable.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds a user_change_logs table to track all role and agency changes made
to users by super admins. Includes a change history modal in the User
Management screen (clock icon per row) showing timestamped, human-readable
change descriptions with the actor who made each change.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Prevents accidental Super Admin privilege grants by requiring users to
type "make this user super admin" before the role change is applied.
Modal blocks paste/drag input and reverts the dropdown on cancel.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Role and agency changes now show an inline green checkmark + "Saved" indicator
on the affected row that auto-clears after 2 seconds. Agency creation shows a
green success banner that auto-dismisses after 3 seconds. Successful actions
also clear any stale error banners.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
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>
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>
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>
- 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>
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>
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>
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>
- 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>
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>
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>
- 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>
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>
- 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>
- 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>
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>
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>
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>
- 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>
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>
Use height: 24px with line-height: 24px and no vertical padding.
This forces text to center vertically within the fixed height container.
Added box-sizing: border-box and vertical-align: middle for reliability.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Text was sitting too low, reducing top padding and increasing bottom
to push text upward for visual centering.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>