Skip to content

[comp] Production Deploy#3382

Merged
tofikwest merged 11 commits into
releasefrom
main
Jul 10, 2026
Merged

[comp] Production Deploy#3382
tofikwest merged 11 commits into
releasefrom
main

Conversation

@github-actions

@github-actions github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

This is an automated pull request to release the candidate branch into production, which will trigger a deployment.
It was created by the [Production PR] action.


Summary by cubic

Adds connectionStatus to the device-sync API and rebuilds the Devices selector so users see reconnect/connect states instead of the selector disappearing. Also adds source-reported device compliance and provider last-seen so imported devices show accurate status and context, updates the compliance chart to include imported devices with correct coloring, and refines the control with an icon-only re-sync button and sync times shown inside the dropdown.

  • New Features

    • API now returns connectionStatus per provider: 'active' | 'error' | null, based on the latest connection row.
    • Available-providers now uses one batched connections query (newest-first) for all providers instead of per-provider lookups.
    • Always-visible selector with a dashed “Connect an integration” slot when no device-sync connection exists.
    • Lists broken connections as disabled options labeled “Reconnect.”
    • Adds “Don’t auto-sync” option; shows provider logos, Active markers, and an icon-only re-sync button (neutral outline); last/next sync times live in the dropdown info.
    • Controlled select: the saved provider is marked as selected in the open dropdown; value is guarded to listed items.
    • Displays “Needs reconnection” on the closed trigger when the saved provider is errored.
    • Source-reported compliance for device sync: DSL supports optional isCompliant, checks[], and lastSeenAt; stored in Device.sourceCompliance; UI shows provider verdict and named checks with attribution; imported devices get honest online/offline from provider last-seen; CSV exports source-reported status.
    • Device Compliance chart counts imported devices using the source verdict; devices with no verdict land in a gray “Not Tracked” segment; legend hides it when empty.
  • Bug Fixes

    • No false reconnect hints after a deliberate disconnect (uses the latest connection row, not any stale error row).
    • Shows “Needs reconnection” if the saved provider is broken even if another provider is connected.
    • Falls back to the connect slot when older API responses omit connectionStatus.
    • Compliance chart colors now use design-system tokens so segments render correctly (no more black slices).
    • Comprehensive tests for API connection states, selector behavior (including controlled selection and older-API fixtures), source-reported compliance/DSL validation, and chart counting/legend behavior.

Written for commit f0c9f2c. Summary will update on new commits.

Review in cubic

github-actions Bot and others added 6 commits July 8, 2026 23:32
When an org's only device-sync-capable connection (Intune/Kandji/JumpCloud)
is in error state (e.g. expired OAuth), the Devices tab hid the sync
selector entirely with no explanation. Now available-providers reports
connectionStatus ('active' | 'error' | null) and the selector renders a
reconnect hint linking to Integrations instead of rendering nothing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TfDHFTwRgYxUoyyqGkHPDc
…e pattern

Replaces the notification-bar approach with the established sync-source
control UX (TwoFactorSourceSelector / people sync): an always-visible
labeled select — dashed 'Connect an integration' slot when the org has
no device-sync connection, provider options with logo/Active marker and
a 'Don't auto-sync' option, and broken (errored) connections listed as
disabled options marked 'Reconnect'.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TfDHFTwRgYxUoyyqGkHPDc
- connectionStatus fallback now decides by the LATEST connection row:
  reconnects create new rows, so a newer 'disconnected' row must not be
  shadowed by a stale older 'error' row (no more false reconnect hints
  after a deliberate disconnect)
- closed select trigger shows 'Needs reconnection' instead of the
  misleading 'Not syncing' when the only connection(s) are broken
- 'Don't auto-sync' Active marker keyed on the saved provider slug, not
  the resolved connected provider, so a broken chosen provider no longer
  mislabels auto-sync as disabled

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TfDHFTwRgYxUoyyqGkHPDc
The 'Needs reconnection' trigger state only fired when NO provider was
connected. If the saved sync source's connection broke while another
provider stayed connected, the trigger fell back to 'Not syncing' even
though the daily sync was failing. Key the trigger off the saved
provider's errored state as well.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TfDHFTwRgYxUoyyqGkHPDc
…ction-hint

feat(devices): always-visible device-sync source selector (People-tab pattern)
@vercel

vercel Bot commented Jul 9, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
app (staging) Ready Ready Preview, Comment Jul 10, 2026 4:07am
comp-framework-editor (staging) Ready Ready Preview, Comment Jul 10, 2026 4:07am
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
portal (staging) Skipped Skipped Jul 10, 2026 4:07am

Request Review

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 5 files

Confidence score: 5/5

  • Safe to merge after the addressed issues were fixed.

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

Comment thread apps/api/src/integration-platform/controllers/sync.controller.ts Outdated
…evice sync (#3383)

* feat(devices): universal source-reported compliance for device sync

Device sync's universal shape gains optional provider-reported fields:
- isCompliant (overall verdict, e.g. Intune complianceState)
- checks[] ({id,label,passed}, provider's own vocabulary, capped at 50)
- lastSeenAt (provider's last-contact timestamp)

Stored in a new nullable Device.sourceCompliance JSON column, fully
separate from the agent's measured compliance columns. The devices UI
renders what the source reported — verdict badge with provider
attribution, provider-named check badges, honest online/offline dot from
the provider timestamp — and keeps 'Not tracked' + dashes when a
provider reports nothing. Agent and Fleet rendering paths untouched.

All fields optional: existing device-sync definitions (Kandji, Intune,
JumpCloud) keep validating unchanged; providers adopt per-field via
their DB-row definitions with no deploy.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TfDHFTwRgYxUoyyqGkPDc

* fix(devices): address cubic review on source-reported compliance

- accept timezone offsets in lastSeenAt (a +02:00 timestamp must not
  drop the whole device from the sync)
- clamp future lastSeenAt to now so provider clock skew can't pin an
  imported device 'Online' for days
- details panel: provider attribution uses the accessible tooltip
  pattern (matching stale/not-tracked) instead of a title attribute
- details header: online/offline shown for imported devices too,
  consistent with the list
- drop 'red' from a test name that didn't assert color

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TfDHFTwRgYxUoyyqGkHPDc

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(devices): count imported devices in the compliance chart

The Device Compliance donut previously excluded integration-imported
devices entirely, so its total contradicted the device table right below
it. Now every device counts: imported devices use the SOURCE's verdict
(sourceCompliance.isCompliant) for Compliant/Non-Compliant, and imported
devices with no verdict land in a gray 'Not Tracked' segment instead of
being fabricated into a verdict. The Not Tracked legend entry only
appears when it exists, so agent/Fleet-only orgs see no change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TfDHFTwRgYxUoyyqGkHPDc

* fix(devices): compliance chart colors — dead legacy tokens rendered black

CHART_COLORS referenced hsl(var(--chart-positive)) etc. from the legacy
@trycompai/ui stylesheet, which the app no longer loads — so all pie
segments fell back to SVG-default black. Use the design-system tokens
the app actually defines: --primary (brand green) for compliant,
--destructive for non-compliant, --muted-foreground for not tracked.
Dark mode adapts automatically.

Note: vendors/backup-overview charts reference the same dead tokens
(same black rendering) — left for a follow-up, out of scope here.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TfDHFTwRgYxUoyyqGkHPDc

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…sync button (#3385)

* refactor(devices): right-align device-sync control, icon-only re-sync button

The sync-source select moves to the right end of its row (it's a
setting, not the page subject), with the re-sync button snug beside it
as an icon-only button — the select already names what's syncing, so
the 'Sync now' text was redundant. aria-label + title keep it
accessible; the connect-an-integration empty slot right-aligns too so
the control doesn't jump sides between states.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TfDHFTwRgYxUoyyqGkHPDc

* refactor(devices): match device-sync control to design — inline synced-ago + primary icon button

Inline row per Tofik's mockup: 'Synced Xh ago' muted text, compact
provider select (label dropped — the provider name + refresh affordance
identify the control), and the re-sync button in the brand primary
color, icon-only. Connect-an-integration slot keeps its label.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TfDHFTwRgYxUoyyqGkHPDc

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
#3386)

The dropdown's info block already shows last/next sync times, so the
inline 'Synced Xh ago' text was redundant. The icon-only re-sync button
goes back to the neutral outline variant — a lone refresh icon doesn't
warrant primary emphasis.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@tofikwest

Copy link
Copy Markdown
Contributor

Reviewed the three cubic findings on this deploy — all three are valid, none are release blockers (no correctness/data risk in what ships here; they are an efficiency improvement, an a11y improvement, and a test-accuracy fix). Fixes for all three are in #3387 to ride the next deploy.

- available-providers: one batched connections query for all providers
  (newest-first, resolved in memory) instead of up to two point lookups
  per provider
- device-sync select is controlled (value guarded to listed items) so
  the open dropdown marks the saved selection for keyboard and
  screen-reader users
- older-API test fixture now genuinely omits connectionStatus instead
  of inheriting 'active' from the base fixture
@vercel vercel Bot temporarily deployed to staging – portal July 10, 2026 04:03 Inactive
@tofikwest tofikwest merged commit 4db9f23 into release Jul 10, 2026
13 checks passed
@claudfuen

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 3.100.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants