All checks were successful
Trigger Cloudarix Deploy / call-webhook (push) Successful in 1s
319 lines
11 KiB
Markdown
319 lines
11 KiB
Markdown
---
|
|
description: "Task list for Manual Policy Sync Button feature"
|
|
---
|
|
|
|
# Tasks: Manual Policy Sync Button
|
|
|
|
**Branch**: `002-manual-policy-sync`
|
|
**Input**: [plan.md](./plan.md), [spec.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
|
|
|
|
- [x] T001 Add N8N_SYNC_WEBHOOK_URL to lib/env.mjs server schema with z.string().optional()
|
|
- [x] T002 [P] Verify existing authentication extracts tenantId in lib/auth/utils.ts
|
|
- [x] 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
|
|
|
|
- [x] T004 Verify NextAuth session includes tenantId field (already implemented in previous feature)
|
|
- [x] T005 Verify getUserAuth() server action exists in lib/auth/utils.ts
|
|
- [x] 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
|
|
|
|
- [x] T007 [P] [US1] Create SyncButton component in components/search/SyncButton.tsx
|
|
- [x] T008 [P] [US1] Implement triggerPolicySync() Server Action in lib/actions/policySettings.ts
|
|
- [x] T009 [US1] Add authentication check with getUserAuth() in triggerPolicySync()
|
|
- [x] T010 [US1] Extract tenantId from session with null check
|
|
- [x] T011 [US1] Validate N8N_SYNC_WEBHOOK_URL environment variable exists
|
|
- [x] T012 [US1] Implement fetch POST request to webhook with JSON body
|
|
- [x] T013 [US1] Add useTransition() hook in SyncButton for loading state
|
|
- [x] T014 [US1] Implement handleSync function calling Server Action
|
|
- [x] T015 [US1] Add success toast notification "Policy sync triggered successfully"
|
|
- [x] T016 [US1] Render Button with RefreshCw icon from lucide-react
|
|
- [x] T017 [US1] Integrate SyncButton into app/(app)/search/page.tsx CardHeader
|
|
- [x] 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
|
|
|
|
- [x] T019 [US2] Add try-catch block in triggerPolicySync() to handle network errors
|
|
- [x] T020 [US2] Return error response when session.user is null ("Not authenticated")
|
|
- [x] T021 [US2] Return error response when tenantId is null ("No tenant ID found in session")
|
|
- [x] T022 [US2] Return error response when N8N_SYNC_WEBHOOK_URL is not configured ("Sync webhook not configured")
|
|
- [x] T023 [US2] Check webhook response status and throw error if not ok
|
|
- [x] T024 [US2] Add error toast notification in SyncButton handleSync catch block
|
|
- [x] T025 [US2] Add console.error logging in triggerPolicySync() for debugging
|
|
- [x] 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
|
|
|
|
- [x] T027 [US3] Add disabled prop to Button based on isPending state
|
|
- [x] T028 [US3] Conditionally render "Syncing..." text when isPending is true
|
|
- [x] T029 [US3] Add animate-spin class to RefreshCw icon when isPending is true
|
|
- [x] 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
|
|
|
|
- [x] T031 Test button on mobile responsive layout
|
|
- [x] T032 Verify button styling matches existing search page design
|
|
- [x] T033 Test with missing N8N_SYNC_WEBHOOK_URL → Error toast appears
|
|
- [x] T034 Test with unauthenticated user → Error toast appears
|
|
- [x] T035 Test with mock webhook success → Success toast appears
|
|
- [x] T036 Document N8N_SYNC_WEBHOOK_URL in deployment notes
|
|
- [x] T037 Commit changes to 002-manual-policy-sync branch
|
|
- [x] T038 Create specification and plan documentation
|
|
|
|
**Status**: ✅ Complete - All polish tasks finished
|
|
|
|
---
|
|
|
|
## Deployment Checklist
|
|
|
|
- [x] All tasks completed (T001-T038)
|
|
- [x] Code committed to feature branch
|
|
- [x] Specification (spec.md) created
|
|
- [x] Implementation plan (plan.md) created
|
|
- [x] 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"
|
|
|
|
```text
|
|
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):
|
|
```bash
|
|
# 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):
|
|
```bash
|
|
# 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)
|
|
|
|
```bash
|
|
# 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**:
|
|
- [x] Login → /search → Click "Sync Policies" → Loading state → Success toast
|
|
- [x] Verify n8n receives POST with correct tenantId
|
|
|
|
✅ **Error Cases**:
|
|
- [x] Not authenticated → Error toast
|
|
- [x] No tenantId in session → Error toast
|
|
- [x] Webhook URL not configured → Error toast
|
|
- [x] Network error → Error toast
|
|
- [x] Webhook returns 500 → Error toast
|
|
|
|
✅ **UI/UX**:
|
|
- [x] Button shows spinner during sync
|
|
- [x] Button disabled during sync
|
|
- [x] Rapid clicks don't send duplicates
|
|
- [x] 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:
|
|
|
|
1. **Sync History Tracking** (new spec)
|
|
- Track when syncs were triggered
|
|
- Display last sync timestamp on search page
|
|
- Show sync status (pending, success, failed)
|
|
|
|
2. **Rate Limiting** (enhancement to 002)
|
|
- Prevent syncs more frequently than once per 5 minutes
|
|
- Show countdown timer until next sync allowed
|
|
|
|
3. **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.
|