dev #10

Merged
elirtf merged 15 commits from dev into main 2026-06-22 21:34:50 +00:00
Owner
No description provided.
Expands the Service Review (formerly QBR) into a professional client report: executive-summary KPIs, security posture (score/grade, MFA adoption, patch, threats, SLA breaches), billing (MRR, invoiced/collected/outstanding), asset lifecycle health, ticket categories, recent tickets and upcoming maintenance — with an audit footer naming the generator and timestamp. Generation is now recorded in the audit log (report.service_review). Adds a 'Generate service review' entry point on the Reports page (scoped to the selected client).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds a Meraki network-hardware panel to the Devices page (appliances/switches/APs/cameras with online status and IP), fed by devices/statuses with a demo fallback. Fixes device monitoring scoping: sample data now appears only on the unconfigured all-clients view — a specific client with no Microsoft/Meraki mapping shows a 'no live data, map it' hint instead of another client's sample devices. Removes the redundant header client-switcher so the Clients page (with the header scope pill as a read-only indicator) is the single place to choose a customer.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Add graph_entra_devices/entra_devices for full directory view (devices
  Intune doesn't manage: registered personal, hybrid-joined servers)
- Three-tab Devices page: Endpoints (Intune) / Directory (Entra) / Network (Meraki)
- Format MAC addresses with colons; IP column defaults off, labeled RMM-only
- Click-to-sort on all device table columns (asc/desc)
- Per-client scoping: a client with no mapping shows no demo data

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The portal had ~40 buttons whose small size was hand-coded inline with
six slightly-different font-size/padding pairs, so 'small' buttons looked
different from page to page. Replace all of them with two canonical size
modifiers (.btn.sm / .btn.xs) and add a single .btn.danger variant for
destructive actions. No behaviour change; consistent visual rhythm.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Graph returns cryptic skuPartNumbers (O365_BUSINESS_PREMIUM, SPB, ...).
Map the common ones to the names customers recognize, with a tidied
fallback for unknown SKUs. Match existing rows by friendly OR raw name so
the rename doesn't create duplicates on the next sync. Drop stale env-var
phrasing from the sync error and tooltip (config is GUI-managed).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The integrations were failing silently or with 'see backend logs'. Root
causes from the live tenant: Graph 403 (app registration missing
admin-consented permissions), Meraki unmapped, and an S1 site-id holding
the API token. None of this was visible in the UI.

- Capture the most recent failure per connector (graph/meraki/s1) as an
  actionable sentence and clear it on success. A Graph 403 now names the
  exact permission to consent to (Device.Read.All, Organization.Read.All,
  etc). License sync and the new pages display it instead of doing nothing.
- Split the combined Devices page into dedicated Microsoft 365 (Intune
  endpoints + Entra directory + license footprint + secure score) and
  Network (Meraki) pages, mirroring the Security page. /portal/devices
  redirects to /portal/microsoft. Nav updated under Assets & security.
- Strip repetitive copy on the Security page (MFA 'X without two-factor',
  Threat overview connect-hint now only when unconfigured).
- Document the required Graph permissions incl. the previously-missing
  Device.Read.All; drop the non-existent SubscribedSkus.Read.All.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The big one: Meraki and SentinelOne pull org-wide from the API key alone
now — no per-client mapping required. Mapping only scopes to a specific
client. Verified live: Meraki returns 95 devices, S1 returns 271 agents
(both previously empty).

- meraki_network/meraki_devices: empty network list = every device the key
  sees; all-clients view no longer needs network IDs mapped
- SentinelOne: omit siteIds to pull everything; drop non-numeric site IDs
  (an API token pasted into the Site IDs field was causing 400 Bad Request)
- Fix S1 pagination key totalItems vs total — threats blocked / open
  incidents were always None; now real (1 blocked, 4 open live)
- any_configured: Meraki/S1 count as configured on creds alone (Graph still
  needs a tenant for app-only tokens)
- Security page: 'What's affecting this score' breakdown (MFA, patch,
  incidents) with per-factor advice + score source line, so the number is
  explained rather than bare

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Integrations page no longer lists every organization at once (the 'other
clients popping up' problem). Mapping is now scoped to the selected client:
pick the client, then tick its Meraki network(s) / SentinelOne site(s) from
live dropdowns (by name — no IDs to copy), or set its Graph tenant. This is
also what makes per-client Network/Microsoft views work without hunting for
IDs.

- meraki_networks_list() / s1_sites_list(): live {id,name} lists for pickers
- /integrations/map accepts multiple checkbox values (CSV-stored)
- map section shows only the selected client; prompts to pick one otherwise
- nav: split overloaded 'Assets & security' into Monitoring (Microsoft 365,
  Network, Security) and Assets (Hardware, Licenses)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Define --danger (#BF616A): it was used in 8 places (overdue pills, SLA
  badges, KPI alerts, critical hardware/security states) but never declared,
  so every red/alert state rendered with inherited color instead of red.
  This is the most visible fix.
- Align card headings to one size (1.05rem) — maint/hw/kb cards were 1.02rem
  while section heads were 1.05rem
- Add .page-actions and .form-title utilities; replace the ad-hoc inline
  action-bar and form-heading styles repeated across ~7 templates
- Account page used the login-only .portal-card component, which centered its
  titles and forced full-width buttons; moved it to the standard .cc-section
  card with .form-title headings

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Theme scrollbars (webkit + firefox) to the Nord palette so horizontal/
  vertical bars match the dark UI instead of the OS default
- Stop tracking free / self-service Microsoft SKUs (Power BI Free, Power
  Automate Free, Windows Store for Business, Teams Exploratory, viral/trial
  SKUs, and any with 0 or unlimited prepaid). They reported counts like
  1,000,000 that made the 'License seats' KPI read 419/1010523. Free rows
  from earlier syncs are purged; the seat total now reflects purchased seats
  (393/548 live)
- Redesign the Security 'What's affecting this score' block from uneven
  bordered cards into a clean aligned row list: status dot, label + advice,
  state-coloured value

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the text rows with a meter per factor: fill width is the actual
value (0-100), a tick marks the target threshold, and the fill colour
reflects state (green/amber/red). Open incidents is inverted to a health
reading so all factors share one visual language. The design is now driven
by the data, not just worded.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Drop the section markup, the route code that built the factor/meter data,
the score-source line, and the now-unused CSS.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Both duplicated the top KPI strip (MFA %, patch, threats blocked, open
incidents). The page now leads with the score + KPI strip and keeps Recent
security events.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
elirtf merged commit 3acb123600 into main 2026-06-22 21:34:50 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
elirtf/msp!10
No description provided.