Generate task breakdown for Policy Explorer UX Upgrade
47 tasks organized across 8 phases by user story: Phase 1: Setup (3 tasks) - Install Shadcn Sheet and Badge components - Create component directory structure Phase 2: Foundation (5 tasks) ⚠️ BLOCKING - getRecentPolicySettings() Server Action - Extend searchPolicySettings() with limit param - Null-value filtering in backend - Type exports Phase 3: User Story 1 - Browse Recent (8 tasks) 🎯 MVP - PolicyTable component with click handlers - PolicySearchContainer client wrapper - Refactor page to Server Component - 50 newest policies on load, no empty state Phase 4: User Story 2 - Detail Sheet (9 tasks) 🎯 MVP - PolicyDetailSheet component - JSON detection and formatting - Click-to-open sheet integration - Handle long content and errors Phase 5: User Story 3 - Search (6 tasks) P2 - Integrate SearchInput component - Search state management - Null filtering in results Phase 6: User Story 4 - Visual (5 tasks) P3 - Badge color mapping - Badge rendering for policy types - Hover effects verification Phase 7: Navigation (4 tasks) - Update config/nav.ts - Remove 'All Settings' menu item - Consolidate to single 'Policy Explorer' Phase 8: Polish (7 tasks) - Responsive layout - Loading states - Performance validation (<2s load, <300ms sheet) - Accessibility and cross-browser testing MVP Scope: Phases 1-4 (25 tasks) Total: 47 tasks with dependency graph and parallel execution opportunities
This commit is contained in:
parent
414eb709b9
commit
ae999e925d
334
specs/003-policy-explorer-ux/tasks.md
Normal file
334
specs/003-policy-explorer-ux/tasks.md
Normal file
@ -0,0 +1,334 @@
|
|||||||
|
# Tasks: Policy Explorer UX Upgrade
|
||||||
|
|
||||||
|
**Input**: Design documents from `/specs/003-policy-explorer-ux/`
|
||||||
|
**Prerequisites**: spec.md ✅, plan.md ✅
|
||||||
|
**Branch**: `003-policy-explorer-ux`
|
||||||
|
**Generated**: 2025-12-07
|
||||||
|
|
||||||
|
**Tests**: Tests are NOT included in this task list as they were not explicitly requested in the feature specification.
|
||||||
|
|
||||||
|
**Organization**: Tasks are grouped by user story to enable independent implementation and testing of each story.
|
||||||
|
|
||||||
|
## Format: `- [ ] [ID] [P?] [Story?] Description with file path`
|
||||||
|
|
||||||
|
- **[P]**: Can run in parallel (different files, no dependencies)
|
||||||
|
- **[Story]**: Which user story this task belongs to (US1, US2, US3, US4)
|
||||||
|
- File paths are absolute from repository root
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 1: Setup (Shared Infrastructure)
|
||||||
|
|
||||||
|
**Purpose**: Verify prerequisites and install missing Shadcn UI components
|
||||||
|
|
||||||
|
- [ ] T001 [P] Verify Shadcn Sheet component exists at `components/ui/sheet.tsx`, install if missing via `npx shadcn@latest add sheet`
|
||||||
|
- [ ] T002 [P] Verify Shadcn Badge component exists at `components/ui/badge.tsx`, install if missing via `npx shadcn@latest add badge`
|
||||||
|
- [ ] T003 Create new directory `components/policy-explorer/` for new feature components
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 2: Foundational (Blocking Prerequisites)
|
||||||
|
|
||||||
|
**Purpose**: Core backend infrastructure that MUST be complete before ANY user story can be implemented
|
||||||
|
|
||||||
|
**⚠️ CRITICAL**: No user story work can begin until this phase is complete
|
||||||
|
|
||||||
|
### Backend Server Actions
|
||||||
|
|
||||||
|
- [ ] T004 Add `getRecentPolicySettings(limit?: number)` Server Action in `lib/actions/policySettings.ts` - returns 50 newest policies sorted by lastSyncedAt DESC, filtered by tenantId and excluding null values
|
||||||
|
- [ ] T005 Extend `searchPolicySettings()` Server Action in `lib/actions/policySettings.ts` - add optional `limit` parameter (default 100, max 200)
|
||||||
|
- [ ] T006 Add null-value filtering logic to Server Actions - filter out entries where `settingValue === "null"` or `settingValue === null` (backend approach for performance)
|
||||||
|
- [ ] T007 Add type exports for `PolicySettingSearchResult` interface if not already exported from `lib/actions/policySettings.ts`
|
||||||
|
- [ ] T008 Test Server Actions manually - verify tenant isolation, null filtering, and limit parameters work correctly
|
||||||
|
|
||||||
|
**Checkpoint**: Backend ready - all Server Actions functional and tested
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 3: User Story 1 - Browse Recent Policies on Page Load (Priority: P1) 🎯 MVP
|
||||||
|
|
||||||
|
**Goal**: Admin sees 50 newest policy settings immediately when opening Policy Explorer (no empty state)
|
||||||
|
|
||||||
|
**Independent Test**: Navigate to `/policy-explorer`, verify 50 newest entries load without search, no null values visible
|
||||||
|
|
||||||
|
### Implementation for User Story 1
|
||||||
|
|
||||||
|
- [ ] T009 [P] [US1] Create `PolicyTable.tsx` component in `components/policy-explorer/PolicyTable.tsx` - display policies in table format with columns: Setting Name, Setting Value, Policy Name, Policy Type, Last Synced
|
||||||
|
- [ ] T010 [P] [US1] Add row click handler prop to `PolicyTable` component - accepts `onRowClick: (policy: PolicySettingSearchResult) => void`
|
||||||
|
- [ ] T011 [P] [US1] Add hover styles to table rows in `PolicyTable` - `hover:bg-accent cursor-pointer` classes
|
||||||
|
- [ ] T012 [P] [US1] Create `PolicySearchContainer.tsx` client component in `components/policy-explorer/PolicySearchContainer.tsx` - manages search state, accepts `initialPolicies` prop
|
||||||
|
- [ ] T013 [US1] Refactor `app/(app)/search/page.tsx` to Server Component pattern - call `getRecentPolicySettings(50)` in Server Component, pass data to `PolicySearchContainer`
|
||||||
|
- [ ] T014 [US1] Update page CardTitle to "Policy Explorer" and CardDescription in `app/(app)/search/page.tsx`
|
||||||
|
- [ ] T015 [US1] Add empty state handling - if no policies returned, show message "Keine Policies gefunden - Starten Sie einen Sync"
|
||||||
|
- [ ] T016 [US1] Keep existing `SyncButton` component in CardHeader of `app/(app)/search/page.tsx`
|
||||||
|
|
||||||
|
**Checkpoint**: Page loads with 50 newest policies, no null values, empty state works
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 4: User Story 2 - View Policy Details in Slide-Over Sheet (Priority: P1) 🎯 MVP
|
||||||
|
|
||||||
|
**Goal**: Admin can click any policy row to see full details with formatted JSON in a slide-over sheet
|
||||||
|
|
||||||
|
**Independent Test**: Click any table row, verify sheet opens from right with policy details, JSON is formatted
|
||||||
|
|
||||||
|
### Implementation for User Story 2
|
||||||
|
|
||||||
|
- [ ] T017 [P] [US2] Create `PolicyDetailSheet.tsx` component in `components/policy-explorer/PolicyDetailSheet.tsx` - uses Shadcn Sheet, accepts `policy`, `open`, `onOpenChange` props
|
||||||
|
- [ ] T018 [P] [US2] Implement JSON detection logic in `PolicyDetailSheet` - check if `settingValue.trim().startsWith('{')` or `startsWith('[')`
|
||||||
|
- [ ] T019 [P] [US2] Implement JSON formatting utility - `JSON.stringify(JSON.parse(value), null, 2)` wrapped in try/catch, fallback to plain text on error
|
||||||
|
- [ ] T020 [P] [US2] Render JSON values in `<pre>` tag with Tailwind prose classes for readability in `PolicyDetailSheet`
|
||||||
|
- [ ] T021 [P] [US2] Render non-JSON values as normal text in `PolicyDetailSheet`
|
||||||
|
- [ ] T022 [P] [US2] Add Sheet styling - proper width (e.g., `w-[600px]`), padding, close button, scroll for long content (`max-height` + `overflow-auto`)
|
||||||
|
- [ ] T023 [US2] Integrate `PolicyDetailSheet` into `PolicySearchContainer` - add state for selected policy and sheet open/close
|
||||||
|
- [ ] T024 [US2] Connect row click handler from `PolicyTable` to open detail sheet with clicked policy data
|
||||||
|
- [ ] T025 [US2] Test detail sheet with various data - nested JSON objects, arrays, long strings (>10KB), plain text values, malformed JSON
|
||||||
|
|
||||||
|
**Checkpoint**: Clicking rows opens detail sheet, JSON is formatted, sheet closes properly
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 5: User Story 3 - Search with Data Cleaning (Priority: P2)
|
||||||
|
|
||||||
|
**Goal**: Admin can search policies and results are filtered to exclude null values
|
||||||
|
|
||||||
|
**Independent Test**: Enter search term "USB", verify results contain "USB" and no null values
|
||||||
|
|
||||||
|
### Implementation for User Story 3
|
||||||
|
|
||||||
|
- [ ] T026 [US3] Integrate existing `SearchInput` component into `PolicySearchContainer` in `components/policy-explorer/PolicySearchContainer.tsx`
|
||||||
|
- [ ] T027 [US3] Add search handler in `PolicySearchContainer` - calls `searchPolicySettings()` Server Action with search term
|
||||||
|
- [ ] T028 [US3] Implement search state management using `useTransition()` hook for pending state
|
||||||
|
- [ ] T029 [US3] Update table to show search results when search term is entered, show initial 50 policies when search is cleared
|
||||||
|
- [ ] T030 [US3] Verify null values are filtered from search results (handled by Server Action from T006)
|
||||||
|
- [ ] T031 [US3] Add loading indicator while search is in progress (use `isPending` from `useTransition`)
|
||||||
|
|
||||||
|
**Checkpoint**: Search works, results exclude null values, loading states correct
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 6: User Story 4 - Improved Visual Hierarchy (Priority: P3)
|
||||||
|
|
||||||
|
**Goal**: Admin sees policy types as colored badges and improved row hover effects
|
||||||
|
|
||||||
|
**Independent Test**: View table, verify badges have distinct colors, rows highlight on hover
|
||||||
|
|
||||||
|
### Implementation for User Story 4
|
||||||
|
|
||||||
|
- [ ] T032 [P] [US4] Define policy type to badge color mapping - create utility function or constant (e.g., Compliance=blue, Configuration=gray, Security=red, etc.)
|
||||||
|
- [ ] T033 [P] [US4] Implement badge rendering in `PolicyTable` - replace plain text `policyType` with Shadcn Badge component
|
||||||
|
- [ ] T034 [P] [US4] Apply badge variant/color based on policy type in `PolicyTable` component
|
||||||
|
- [ ] T035 [US4] Test badge colors with real data - verify at least 3 distinct colors are visible and accessible (contrast check)
|
||||||
|
- [ ] T036 [US4] Verify hover effects on table rows - cursor changes to pointer, background color changes
|
||||||
|
|
||||||
|
**Checkpoint**: Badges show distinct colors, hover effects smooth, visual hierarchy improved
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 7: Navigation & Route Consolidation (Cross-Cutting)
|
||||||
|
|
||||||
|
**Purpose**: Update navigation and routing to consolidate under "Policy Explorer"
|
||||||
|
|
||||||
|
- [ ] T037 Update `config/nav.ts` - replace `{ title: "Search", href: "/search" }` with `{ title: "Policy Explorer", href: "/search" }` (keep /search route for now)
|
||||||
|
- [ ] T038 Remove "All Settings" menu item from `config/nav.ts` if it exists (from settings-overview feature)
|
||||||
|
- [ ] T039 Update page metadata (title, description) in `app/(app)/search/page.tsx` to reflect "Policy Explorer" branding
|
||||||
|
- [ ] T040 Add redirect from `/settings-overview` to `/search` if that route exists (optional, for backwards compatibility)
|
||||||
|
|
||||||
|
**Checkpoint**: Navigation shows single "Policy Explorer" entry, old routes redirect if needed
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 8: Polish & Final Integration
|
||||||
|
|
||||||
|
**Purpose**: Final refinements and end-to-end validation
|
||||||
|
|
||||||
|
- [ ] T041 Update `EmptyState` component message in `components/search/EmptyState.tsx` - change to Policy Explorer context if still used
|
||||||
|
- [ ] T042 Add loading skeleton to table (optional) - show placeholder rows while initial data loads
|
||||||
|
- [ ] T043 Verify responsive layout - test table and detail sheet on mobile viewport (< 768px)
|
||||||
|
- [ ] T044 Add error boundary for detail sheet - graceful error handling if sheet rendering fails
|
||||||
|
- [ ] T045 Performance check - verify initial page load < 2s, detail sheet opens < 300ms, search response < 2s
|
||||||
|
- [ ] T046 Accessibility check - verify keyboard navigation (Tab, Enter to open sheet, Escape to close), screen reader labels
|
||||||
|
- [ ] T047 Cross-browser test - verify in Chrome, Safari, Firefox (at minimum)
|
||||||
|
|
||||||
|
**Checkpoint**: Feature complete, polished, and tested across browsers/devices
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Dependencies Visualization
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
graph TD
|
||||||
|
T001[T001: Install Sheet] --> T017[T017: Create PolicyDetailSheet]
|
||||||
|
T002[T002: Install Badge] --> T033[T033: Implement Badge Rendering]
|
||||||
|
T003[T003: Create Directory] --> T009[T009: Create PolicyTable]
|
||||||
|
T003 --> T012[T012: Create PolicySearchContainer]
|
||||||
|
T003 --> T017
|
||||||
|
|
||||||
|
T004[T004: getRecentPolicySettings] --> T013[T013: Refactor Page to Server Component]
|
||||||
|
T005[T005: Extend searchPolicySettings] --> T027[T027: Add Search Handler]
|
||||||
|
T006[T006: Null Filtering] --> T004
|
||||||
|
T006 --> T005
|
||||||
|
T007[T007: Type Exports] --> T009
|
||||||
|
T007 --> T012
|
||||||
|
T007 --> T017
|
||||||
|
T008[T008: Test Server Actions] --> T013
|
||||||
|
|
||||||
|
T009 --> T013
|
||||||
|
T010[T010: Row Click Handler] --> T024[T024: Connect Click to Sheet]
|
||||||
|
T011[T011: Hover Styles] --> T036[T036: Verify Hover Effects]
|
||||||
|
T012 --> T013
|
||||||
|
T013 --> T026[T026: Integrate SearchInput]
|
||||||
|
|
||||||
|
T017 --> T023[T023: Integrate Sheet into Container]
|
||||||
|
T018[T018: JSON Detection] --> T019[T019: JSON Formatting]
|
||||||
|
T019 --> T020[T020: Render JSON in pre]
|
||||||
|
T020 --> T023
|
||||||
|
T021[T021: Render Non-JSON] --> T023
|
||||||
|
T022[T022: Sheet Styling] --> T023
|
||||||
|
T023 --> T024
|
||||||
|
|
||||||
|
T026 --> T027
|
||||||
|
T027 --> T028[T028: Search State Management]
|
||||||
|
T028 --> T029[T029: Update Table with Results]
|
||||||
|
T029 --> T030[T030: Verify Null Filtering]
|
||||||
|
T030 --> T031[T031: Loading Indicator]
|
||||||
|
|
||||||
|
T032[T032: Badge Color Mapping] --> T033
|
||||||
|
T033 --> T034[T034: Apply Badge Variants]
|
||||||
|
T034 --> T035[T035: Test Badge Colors]
|
||||||
|
|
||||||
|
T013 --> T037[T037: Update Navigation]
|
||||||
|
T037 --> T038[T038: Remove All Settings]
|
||||||
|
T038 --> T039[T039: Update Page Metadata]
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Parallel Execution Opportunities
|
||||||
|
|
||||||
|
### Phase 1 (All parallel):
|
||||||
|
- T001, T002, T003 can all run simultaneously
|
||||||
|
|
||||||
|
### Phase 2:
|
||||||
|
- **Parallel**: T007 can run while T004-T006 are being implemented
|
||||||
|
- **Sequential**: T004-T006 must complete before T008
|
||||||
|
- **Blocking**: T008 must complete before Phase 3 starts
|
||||||
|
|
||||||
|
### Phase 3 (User Story 1):
|
||||||
|
- **Parallel**: T009, T010, T011, T012 (different components)
|
||||||
|
- **Sequential**: T013 requires T009 and T012 complete
|
||||||
|
- **Sequential**: T014-T016 extend T013
|
||||||
|
|
||||||
|
### Phase 4 (User Story 2):
|
||||||
|
- **Parallel**: T017, T018, T019, T020, T021, T022 (all component work)
|
||||||
|
- **Sequential**: T023 requires T017-T022 complete
|
||||||
|
- **Sequential**: T024 requires T023 and T010 complete
|
||||||
|
- **Sequential**: T025 is final testing
|
||||||
|
|
||||||
|
### Phase 5 (User Story 3):
|
||||||
|
- **Sequential**: T026 → T027 → T028 → T029 → T030 → T031 (build on each other)
|
||||||
|
|
||||||
|
### Phase 6 (User Story 4):
|
||||||
|
- **Parallel**: T032, T033, T034 (component work)
|
||||||
|
- **Sequential**: T035, T036 (testing)
|
||||||
|
|
||||||
|
### Phase 7 (Navigation):
|
||||||
|
- **Parallel**: T037, T038 (different files)
|
||||||
|
- **Sequential**: T039, T040 extend T037/T038
|
||||||
|
|
||||||
|
### Phase 8 (Polish):
|
||||||
|
- **Mostly parallel**: T041-T044 (different concerns)
|
||||||
|
- **Sequential**: T045-T047 (validation after implementation)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Suggested MVP Scope
|
||||||
|
|
||||||
|
**Minimum Viable Product** = Phase 1 + Phase 2 + Phase 3 + Phase 4
|
||||||
|
|
||||||
|
This delivers:
|
||||||
|
- ✅ 50 newest policies on page load (no empty state)
|
||||||
|
- ✅ Null values filtered automatically
|
||||||
|
- ✅ Clickable rows with detail sheet
|
||||||
|
- ✅ JSON formatting in detail view
|
||||||
|
- ✅ Functional search (from existing feature)
|
||||||
|
|
||||||
|
**Can be deferred post-MVP**:
|
||||||
|
- User Story 3 tasks (search refinements) - existing search already works
|
||||||
|
- User Story 4 tasks (visual improvements) - badges and hover are polish
|
||||||
|
- Phase 7 tasks (navigation consolidation) - can keep both menu items temporarily
|
||||||
|
- Phase 8 tasks (polish) - can iterate after core functionality validated
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Implementation Strategy
|
||||||
|
|
||||||
|
### Week 1: Foundation + US1 (MVP Core)
|
||||||
|
- Days 1-2: Phase 1 (Setup) + Phase 2 (Backend)
|
||||||
|
- Days 3-5: Phase 3 (User Story 1 - Browse Recent)
|
||||||
|
|
||||||
|
**Deliverable**: Page loads with 50 newest policies, no null values
|
||||||
|
|
||||||
|
### Week 2: US2 + Testing (MVP Complete)
|
||||||
|
- Days 1-3: Phase 4 (User Story 2 - Detail Sheet)
|
||||||
|
- Days 4-5: Testing and bug fixes for US1 + US2
|
||||||
|
|
||||||
|
**Deliverable**: Functional Policy Explorer with detail view (MVP ready)
|
||||||
|
|
||||||
|
### Week 3: Polish + Enhancement
|
||||||
|
- Days 1-2: Phase 5 (User Story 3 - Search refinements)
|
||||||
|
- Days 3-4: Phase 6 (User Story 4 - Visual improvements)
|
||||||
|
- Day 5: Phase 7 (Navigation) + Phase 8 (Polish)
|
||||||
|
|
||||||
|
**Deliverable**: Full feature with all user stories, polished and production-ready
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task Count Summary
|
||||||
|
|
||||||
|
- **Phase 1 (Setup)**: 3 tasks
|
||||||
|
- **Phase 2 (Foundation)**: 5 tasks ⚠️ BLOCKING
|
||||||
|
- **Phase 3 (US1 - P1)**: 8 tasks 🎯 MVP
|
||||||
|
- **Phase 4 (US2 - P1)**: 9 tasks 🎯 MVP
|
||||||
|
- **Phase 5 (US3 - P2)**: 6 tasks
|
||||||
|
- **Phase 6 (US4 - P3)**: 5 tasks
|
||||||
|
- **Phase 7 (Navigation)**: 4 tasks
|
||||||
|
- **Phase 8 (Polish)**: 7 tasks
|
||||||
|
|
||||||
|
**Total**: 47 tasks
|
||||||
|
|
||||||
|
**MVP Subset**: T001-T025 (25 tasks) = Foundation + US1 + US2
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Success Criteria Mapping
|
||||||
|
|
||||||
|
| Success Criterion | Tasks |
|
||||||
|
|-------------------|-------|
|
||||||
|
| SC-001: Load < 2s | T004, T013, T045 |
|
||||||
|
| SC-002: 100% valid values (no nulls) | T006, T030 |
|
||||||
|
| SC-003: Detail sheet < 300ms | T017-T024, T045 |
|
||||||
|
| SC-004: JSON formatted | T018-T020, T025 |
|
||||||
|
| SC-005: Badge colors distinguishable | T032-T035 |
|
||||||
|
| SC-006: Single "Policy Explorer" menu | T037-T038 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- **No database migrations**: Feature works with existing schema ✅
|
||||||
|
- **Server-first architecture**: All data via Server Actions ✅
|
||||||
|
- **Shadcn UI components**: Sheet and Badge must be installed (T001, T002)
|
||||||
|
- **Backwards compatibility**: Can keep `/search` route, update navigation text
|
||||||
|
- **Performance**: Null filtering in backend (T006) for optimal performance
|
||||||
|
- **Testing**: Manual testing focus, no automated E2E tests in scope
|
||||||
|
- **Accessibility**: Covered in Phase 8 (T046)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- Feature Spec: [spec.md](./spec.md)
|
||||||
|
- Implementation Plan: [plan.md](./plan.md)
|
||||||
|
- Requirements Checklist: [checklists/requirements.md](./checklists/requirements.md)
|
||||||
|
- Related Features: [001-global-policy-search](../001-global-policy-search/), [002-manual-policy-sync](../002-manual-policy-sync/)
|
||||||
Loading…
Reference in New Issue
Block a user