Add trace files.
This commit is contained in:
81
docs/plans/sprint_1_story_2_task_2.md
Normal file
81
docs/plans/sprint_1_story_2_task_2.md
Normal file
@@ -0,0 +1,81 @@
|
||||
# Task 6: Build React Query Hooks
|
||||
|
||||
**Task ID**: TASK-006 | **Story**: [STORY-002](sprint_1_story_2.md) | **Sprint**: [Sprint 1](sprint_1.md)
|
||||
**Estimated Hours**: 3h | **Assignee**: Frontend Developer 2 | **Priority**: P0 | **Status**: Not Started
|
||||
|
||||
## Task Description
|
||||
Create React Query hooks for Epic/Story/Task with query caching, mutations, and optimistic updates.
|
||||
|
||||
## Implementation
|
||||
|
||||
### File: `src/hooks/useEpics.ts`
|
||||
```typescript
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { epicApiClient } from '../api/clients/EpicApiClient';
|
||||
|
||||
export const useEpics = (projectId: string) => {
|
||||
return useQuery({
|
||||
queryKey: ['epics', projectId],
|
||||
queryFn: () => epicApiClient.getAll(projectId),
|
||||
staleTime: 60000 // 1 minute
|
||||
});
|
||||
};
|
||||
|
||||
export const useCreateEpic = () => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: epicApiClient.create,
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ['epics'] });
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const useUpdateEpic = () => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: ({ id, dto }) => epicApiClient.update(id, dto),
|
||||
onMutate: async ({ id, dto }) => {
|
||||
// Optimistic update
|
||||
await queryClient.cancelQueries({ queryKey: ['epics', id] });
|
||||
const previous = queryClient.getQueryData(['epics', id]);
|
||||
queryClient.setQueryData(['epics', id], dto);
|
||||
return { previous };
|
||||
},
|
||||
onError: (err, vars, context) => {
|
||||
queryClient.setQueryData(['epics', vars.id], context.previous);
|
||||
},
|
||||
onSettled: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ['epics'] });
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const useDeleteEpic = () => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: epicApiClient.delete,
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ['epics'] });
|
||||
}
|
||||
});
|
||||
};
|
||||
```
|
||||
|
||||
## Acceptance Criteria
|
||||
- [ ] useEpics/Stories/Tasks query hooks
|
||||
- [ ] useCreate/Update/Delete mutation hooks
|
||||
- [ ] Query cache invalidation working
|
||||
- [ ] Optimistic updates for better UX
|
||||
- [ ] Loading and error states handled
|
||||
|
||||
## Deliverables
|
||||
1. useEpics.ts with 4 hooks
|
||||
2. useStories.ts with 4 hooks
|
||||
3. useTasks.ts with 4 hooks
|
||||
4. Unit tests (12+ tests)
|
||||
|
||||
**Status**: Not Started | **Created**: 2025-11-04
|
||||
Reference in New Issue
Block a user