11 KiB
| description |
|---|
| Task list for Manual Policy Sync Button feature |
Tasks: Manual Policy Sync Button
Branch: 002-manual-policy-sync
Input: plan.md, spec.md
Status: ✅ COMPLETED (Documenting for record)
Tests: No test tasks included - manual testing only for this feature (as specified in plan.md)
Organization: Tasks organized by user story to enable independent implementation and testing
Format: - [ ] [ID] [P?] [Story] Description
- [P]: Can run in parallel (different files, no dependencies)
- [Story]: Which user story this task belongs to (US1, US2, US3)
- Paths are absolute from repository root
Phase 1: Setup (Shared Infrastructure)
Purpose: Configure environment and prepare existing codebase
- T001 Add N8N_SYNC_WEBHOOK_URL to lib/env.mjs server schema with z.string().optional()
- T002 [P] Verify existing authentication extracts tenantId in lib/auth/utils.ts
- T003 [P] Confirm Shadcn Button and Toast (sonner) are available
Status: ✅ Complete - No new project setup needed, leveraging existing infrastructure
Phase 2: Foundational (Blocking Prerequisites)
Purpose: Core infrastructure that MUST be complete before ANY user story can be implemented
⚠️ CRITICAL: No user story work can begin until this phase is complete
- T004 Verify NextAuth session includes tenantId field (already implemented in previous feature)
- T005 Verify getUserAuth() server action exists in lib/auth/utils.ts
- T006 Confirm fetch() is available for webhook calls (Node.js built-in)
Status: ✅ Complete - All foundational pieces already exist from 001-global-policy-search feature
Checkpoint: Foundation ready - user story implementation can now begin in parallel
Phase 3: User Story 1 - Trigger Immediate Sync (Priority: P1) 🎯 MVP
Goal: Admin can click button to trigger n8n webhook for immediate policy sync
Independent Test: Login → /search page → Click "Sync Policies" → Success toast appears → n8n receives POST with tenantId
Implementation for User Story 1
- T007 [P] [US1] Create SyncButton component in components/search/SyncButton.tsx
- T008 [P] [US1] Implement triggerPolicySync() Server Action in lib/actions/policySettings.ts
- T009 [US1] Add authentication check with getUserAuth() in triggerPolicySync()
- T010 [US1] Extract tenantId from session with null check
- T011 [US1] Validate N8N_SYNC_WEBHOOK_URL environment variable exists
- T012 [US1] Implement fetch POST request to webhook with JSON body
- T013 [US1] Add useTransition() hook in SyncButton for loading state
- T014 [US1] Implement handleSync function calling Server Action
- T015 [US1] Add success toast notification "Policy sync triggered successfully"
- T016 [US1] Render Button with RefreshCw icon from lucide-react
- T017 [US1] Integrate SyncButton into app/(app)/search/page.tsx CardHeader
- T018 [US1] Position button right of title using flexbox (justify-between)
Files Modified:
- ✅
lib/env.mjs- Added N8N_SYNC_WEBHOOK_URL - ✅
lib/actions/policySettings.ts- Added triggerPolicySync() function - ✅
components/search/SyncButton.tsx- Created new component - ✅
app/(app)/search/page.tsx- Integrated SyncButton
Checkpoint: ✅ User Story 1 is fully functional and testable independently
Phase 4: User Story 2 - Handle Sync Errors Gracefully (Priority: P2)
Goal: Admin receives clear error feedback when sync fails
Independent Test: Simulate webhook failure (wrong URL, network error) → Error toast appears with user-friendly message
Implementation for User Story 2
- T019 [US2] Add try-catch block in triggerPolicySync() to handle network errors
- T020 [US2] Return error response when session.user is null ("Not authenticated")
- T021 [US2] Return error response when tenantId is null ("No tenant ID found in session")
- T022 [US2] Return error response when N8N_SYNC_WEBHOOK_URL is not configured ("Sync webhook not configured")
- T023 [US2] Check webhook response status and throw error if not ok
- T024 [US2] Add error toast notification in SyncButton handleSync catch block
- T025 [US2] Add console.error logging in triggerPolicySync() for debugging
- T026 [US2] Ensure button returns to normal state after error (useTransition handles this)
Files Modified:
- ✅
lib/actions/policySettings.ts- Added comprehensive error handling - ✅
components/search/SyncButton.tsx- Added error toast display
Checkpoint: ✅ User Stories 1 AND 2 both work independently with proper error handling
Phase 5: User Story 3 - Prevent Multiple Simultaneous Syncs (Priority: P3)
Goal: Button prevents duplicate requests during sync operation
Independent Test: Click button rapidly multiple times → Only one request sent, button stays disabled
Implementation for User Story 3
- T027 [US3] Add disabled prop to Button based on isPending state
- T028 [US3] Conditionally render "Syncing..." text when isPending is true
- T029 [US3] Add animate-spin class to RefreshCw icon when isPending is true
- T030 [US3] Verify useTransition() prevents multiple simultaneous calls
Files Modified:
- ✅
components/search/SyncButton.tsx- Added disabled state and loading UI
Checkpoint: ✅ All user stories (1, 2, 3) are independently functional with proper UX
Phase 6: Polish & Cross-Cutting Concerns
Purpose: Final touches and production readiness
- T031 Test button on mobile responsive layout
- T032 Verify button styling matches existing search page design
- T033 Test with missing N8N_SYNC_WEBHOOK_URL → Error toast appears
- T034 Test with unauthenticated user → Error toast appears
- T035 Test with mock webhook success → Success toast appears
- T036 Document N8N_SYNC_WEBHOOK_URL in deployment notes
- T037 Commit changes to 002-manual-policy-sync branch
- T038 Create specification and plan documentation
Status: ✅ Complete - All polish tasks finished
Deployment Checklist
- All tasks completed (T001-T038)
- Code committed to feature branch
- Specification (spec.md) created
- Implementation plan (plan.md) created
- Tasks (tasks.md) documented
- TODO: Configure N8N_SYNC_WEBHOOK_URL in Dokploy environment variables
- TODO: Merge 002-manual-policy-sync → main
- TODO: Deploy to production
- TODO: Verify button appears on /search page in production
- TODO: Test manual sync trigger with real n8n webhook
Dependencies Between Tasks
Legend: → means "depends on"
Setup Phase:
T001, T002, T003 → [Can run in parallel]
Foundational Phase:
T004, T005, T006 → [Already complete from previous work]
User Story 1 (Core Sync):
T007 [SyncButton UI] → T013-T018 [UI refinements]
T008 [Server Action] → T009-T012 [Action logic]
T007, T008 → T017 [Page integration]
User Story 2 (Error Handling):
T008 complete → T019-T025 [Add error cases]
T007 complete → T024, T026 [Error UI feedback]
User Story 3 (Prevent Duplicates):
T007, T013 complete → T027-T030 [Loading state enhancements]
Parallel Opportunities:
- Phase 1: All tasks (T001-T003) can run in parallel
- User Story 1: T007 (UI) and T008 (Server Action) can be built in parallel
- User Story 2: Error handling can be added to both files simultaneously
Parallel Execution Examples
Example 1: User Story 1 (Two Developers)
Developer A (Frontend):
# Create SyncButton component
- T007: components/search/SyncButton.tsx (stub Server Action call)
- T013-T016: Add loading state, toast, button rendering
- T017-T018: Integrate into search page
Developer B (Backend):
# Create Server Action
- T008: lib/actions/policySettings.ts (stub return success)
- T009-T012: Add auth check, tenant ID extraction, webhook call
Integration: Once both T007 and T008 are complete, connect them together
Example 2: User Story 2 (One Developer)
# Add error handling after US1 is complete
- T019-T023: Server Action error cases (5 min each)
- T024-T026: UI error handling (5 min each)
- Total time: ~30 minutes
Implementation Strategy
MVP-First Approach
MVP = User Story 1 ONLY (P1):
- Admin can click button
- Button shows loading state
- Success toast appears
- n8n receives webhook
This delivers immediate value and can be shipped independently.
Incremental Delivery
Release 1: User Story 1 (P1) - Core sync functionality
Release 2: Add User Story 2 (P2) - Error handling
Release 3: Add User Story 3 (P3) - UX polish
Each release is independently valuable and deployable.
Testing Notes
Manual Testing Checklist (from plan.md):
✅ Happy Path:
- Login → /search → Click "Sync Policies" → Loading state → Success toast
- Verify n8n receives POST with correct tenantId
✅ Error Cases:
- Not authenticated → Error toast
- No tenantId in session → Error toast
- Webhook URL not configured → Error toast
- Network error → Error toast
- Webhook returns 500 → Error toast
✅ UI/UX:
- Button shows spinner during sync
- Button disabled during sync
- Rapid clicks don't send duplicates
- Mobile responsive
No automated tests for this feature - manual testing deemed sufficient for MVP (as per plan.md).
Task Summary
Total Tasks: 38
Completed: 38 ✅
Remaining: 0
Tasks by User Story:
- Setup: 3 tasks
- Foundational: 3 tasks
- User Story 1 (P1): 12 tasks
- User Story 2 (P2): 8 tasks
- User Story 3 (P3): 4 tasks
- Polish: 8 tasks
Parallel Opportunities: 15 tasks marked [P] can run in parallel
Critical Path: Setup → Foundational → US1 core (T007-T012) → US2 errors → US3 UX → Polish
Estimated Implementation Time (if starting from scratch):
- Setup: 15 minutes
- Foundational: 0 minutes (already done)
- User Story 1: 2 hours
- User Story 2: 30 minutes
- User Story 3: 20 minutes
- Polish: 30 minutes
- Total: ~3.5 hours
Actual Time: Already completed ✅
Next Feature Recommendations
Based on this implementation, consider these follow-up features:
-
Sync History Tracking (new spec)
- Track when syncs were triggered
- Display last sync timestamp on search page
- Show sync status (pending, success, failed)
-
Rate Limiting (enhancement to 002)
- Prevent syncs more frequently than once per 5 minutes
- Show countdown timer until next sync allowed
-
Bulk Tenant Sync (admin feature)
- Allow platform admins to trigger sync for all tenants
- New admin dashboard page
- Requires admin role system
These can each be separate feature specs following the same workflow.