tenantpilot/specs/002-manual-policy-sync/spec.md

6.8 KiB

Feature Specification: Manual Policy Sync Button

Feature Branch: 002-manual-policy-sync
Created: 2025-12-06
Status: Draft
Input: User description: "Manual Policy Sync Button - Allow admins to trigger immediate policy synchronization from Intune without waiting for scheduled sync"

User Scenarios & Testing (mandatory)

User Story 1 - Trigger Immediate Sync (Priority: P1)

An IT administrator has just made changes to an Intune policy and wants to see those changes reflected in TenantPilot immediately without waiting for the scheduled nightly sync.

Why this priority: Core functionality that directly addresses the pain point of waiting for scheduled syncs. Delivers immediate value and is the primary reason for this feature.

Independent Test: Admin can click "Sync Policies" button on search page, receives confirmation that sync started, and n8n workflow is triggered for their tenant.

Acceptance Scenarios:

  1. Given an authenticated admin is on the /search page, When they click the "Sync Policies" button, Then the button shows a loading state with "Syncing..." text and a spinner
  2. Given a sync request is successfully sent to n8n, When the request completes, Then a success toast message appears saying "Policy sync triggered successfully"
  3. Given an authenticated admin with a valid tenant ID, When they trigger a sync, Then the n8n webhook receives a POST request with their tenant ID and source "manual_trigger"

User Story 2 - Handle Sync Errors Gracefully (Priority: P2)

When the sync cannot be triggered (network error, webhook down, etc.), the admin needs clear feedback about what went wrong.

Why this priority: Essential for production reliability. Without error handling, users won't know if sync failed and may think it succeeded.

Independent Test: Can be tested by simulating webhook failures (wrong URL, network timeout) and verifying error messages appear.

Acceptance Scenarios:

  1. Given the n8n webhook is unreachable, When admin clicks "Sync Policies", Then an error toast appears with message "Failed to trigger sync. Please try again later."
  2. Given a sync request fails, When the error occurs, Then the button returns to its normal state (not stuck in loading)
  3. Given user is not authenticated, When they attempt to trigger sync, Then they receive "Not authenticated" error

User Story 3 - Prevent Multiple Simultaneous Syncs (Priority: P3)

Admin should not be able to trigger multiple syncs simultaneously for the same tenant to avoid duplicate processing.

Why this priority: Nice-to-have for UX polish. Prevents confusion but not critical for MVP since n8n workflows can handle duplicates.

Independent Test: Click sync button multiple times rapidly and verify only one request is sent, button stays disabled during processing.

Acceptance Scenarios:

  1. Given a sync is in progress, When admin clicks the button again, Then the button remains disabled and no additional request is sent
  2. Given a sync completes (success or error), When the toast dismisses, Then the button becomes clickable again

Edge Cases

  • What happens when user's session has no tenant ID? (Show error: "No tenant ID found in session")
  • What happens when N8N_SYNC_WEBHOOK_URL environment variable is not configured? (Show error: "Sync webhook not configured")
  • What happens when n8n webhook returns non-200 status? (Log error, show user-friendly message)
  • What happens if user navigates away while sync is in progress? (No issue - webhook call already sent, no cleanup needed)

Requirements (mandatory)

Functional Requirements

  • FR-001: System MUST provide a "Sync Policies" button on the /search page visible to authenticated users
  • FR-002: System MUST validate user authentication before allowing sync trigger
  • FR-003: System MUST extract tenant ID from user session and include it in webhook payload
  • FR-004: System MUST send POST request to n8n webhook with JSON body containing { tenantId, source: "manual_trigger", triggeredAt: ISO timestamp }
  • FR-005: System MUST show loading state (spinner + "Syncing..." text) while request is in progress
  • FR-006: System MUST display success toast notification when sync is triggered successfully
  • FR-007: System MUST display error toast notification when sync fails with user-friendly error message
  • FR-008: System MUST disable button during sync operation to prevent duplicate requests
  • FR-009: System MUST log sync errors to console for debugging
  • FR-010: System MUST validate that N8N_SYNC_WEBHOOK_URL environment variable is configured before attempting request

Key Entities (include if feature involves data)

  • Sync Request: Represents a manual sync trigger event
    • Attributes: tenantId (from session), source ("manual_trigger"), triggeredAt (ISO timestamp)
    • Sent to n8n webhook, not persisted in database
    • Used for audit trail in n8n workflow logs

Success Criteria (mandatory)

Measurable Outcomes

  • SC-001: Admin can trigger policy sync with single button click from search page
  • SC-002: Sync request reaches n8n webhook within 2 seconds of button click
  • SC-003: Admin receives visual feedback (loading state + toast) within 1 second of clicking button
  • SC-004: Error scenarios (network failure, missing config) show clear error messages to user
  • SC-005: Button correctly handles rapid multiple clicks without sending duplicate requests
  • SC-006: 100% of sync triggers include correct tenant ID from authenticated user's session

Assumptions

  • N8N_SYNC_WEBHOOK_URL will be configured in environment variables before feature deployment
  • n8n workflow already exists and can handle manual sync requests (separate from scheduled sync)
  • Webhook endpoint accepts POST requests with JSON body
  • Tenant ID is always available in authenticated user's session (handled by existing auth logic)
  • No database changes required - this is a client-side UI + server action feature
  • Sync is asynchronous - user doesn't wait for actual Intune data fetch to complete

Dependencies

  • Existing authentication system (NextAuth with tenant ID in session)
  • Existing server actions infrastructure (lib/actions/policySettings.ts)
  • Existing UI components (Shadcn Button, Toast from sonner)
  • n8n webhook endpoint must be deployed and accessible
  • Environment variable validation system (lib/env.mjs)

Out of Scope

  • Showing sync progress or status (user only gets confirmation that sync was triggered)
  • Displaying last sync timestamp on the page
  • Limiting sync frequency (e.g., rate limiting to once per 5 minutes)
  • Syncing specific policies (all policies for tenant are synced)
  • Admin controls for other tenants (admin can only sync their own tenant)