-
-
Notifications
You must be signed in to change notification settings - Fork 1
Open
Description
Phase 3: GraphQL Client & Hooks Setup
Establish Quickslice GraphQL integration with reusable React hooks for all CRUD operations.
Depends On
- Completion of Phase 2 (Authentication working)
- Phase 1 assessment: Understanding of Quickslice GraphQL schema
Objectives
- Create GraphQL client configuration
- Define GraphQL queries and mutations
- Create reusable React hooks
- Establish patterns for form components
Tasks
Task 1: GraphQL Client Setup
-
Create
src/lib/graphql/client.ts- Initialize Apollo Client or graphql-request
- Configure Quickslice GraphQL endpoint
- Set up authentication middleware (attach bearer token)
- Export client instance
-
Create
src/types/graphql.ts- Define TypeScript types for all Quickslice GraphQL types
- Map Lexicon types to GraphQL types
- Export types for use in components
Task 2: Define GraphQL Operations
Create separate files for each domain:
-
src/lib/graphql/queries/- affiliations.ts - GET_AFFILIATIONS, GET_AFFILIATION
- qualifications.ts - GET_QUALIFICATIONS, GET_QUALIFICATION
- skills.ts - GET_SKILLS, GET_SKILL
- events.ts - GET_EVENTS, GET_EVENT
- works.ts - GET_WORKS, GET_WORK
- socialLinks.ts - GET_SOCIAL_LINKS, GET_SOCIAL_LINK
- webLinks.ts - GET_WEB_LINKS, GET_WEB_LINK
-
src/lib/graphql/mutations/- affiliations.ts - CREATE_AFFILIATION, UPDATE_AFFILIATION, DELETE_AFFILIATION
- qualifications.ts - CREATE_QUALIFICATION, UPDATE_QUALIFICATION, DELETE_QUALIFICATION
- skills.ts - CREATE_SKILL, UPDATE_SKILL, DELETE_SKILL
- events.ts - CREATE_EVENT, UPDATE_EVENT, DELETE_EVENT
- works.ts - CREATE_WORK, UPDATE_WORK, DELETE_WORK
- socialLinks.ts - CREATE_SOCIAL_LINK, UPDATE_SOCIAL_LINK, DELETE_SOCIAL_LINK
- webLinks.ts - CREATE_WEB_LINK, UPDATE_WEB_LINK, DELETE_WEB_LINK
Task 3: Create React Hooks
- Create
src/lib/graphql/hooks.ts- useAffiliations() - fetch list
- useCreateAffiliation() - mutation hook
- useUpdateAffiliation() - mutation hook
- useDeleteAffiliation() - mutation hook
- Similar for all other domains (20+ hooks total)
- Use Apollo Client's useQuery/useMutation or equivalent
- Handle loading, error, success states
- Handle optimistic updates where appropriate
Task 4: Test GraphQL Integration
- Write test file
src/lib/graphql/__tests__/client.test.ts- Test client initialization
- Test authentication header injection
- Test query execution
- Test mutation execution
- Test error handling
Task 5: Document GraphQL Patterns
- Create
docs/GRAPHQL_PATTERNS.md- How to create hooks
- How to use hooks in components
- Error handling patterns
- Loading state patterns
- Success/failure toast patterns
- Example: using hook in form component
Task 6: Create Hook Usage Examples
- Create example hook usage in one form component
- Demonstrate fetch on component mount
- Demonstrate mutation on form submit
- Demonstrate loading state
- Demonstrate error handling
- Demonstrate success notification
Files to Create
src/lib/graphql/
├── client.ts # Apollo/graphql-request client
├── hooks.ts # 20+ React hooks
├── queries/
│ ├── affiliations.ts
│ ├── qualifications.ts
│ ├── skills.ts
│ ├── events.ts
│ ├── works.ts
│ ├── socialLinks.ts
│ └── webLinks.ts
├── mutations/
│ ├── affiliations.ts
│ ├── qualifications.ts
│ ├── skills.ts
│ ├── events.ts
│ ├── works.ts
│ ├── socialLinks.ts
│ └── webLinks.ts
└── __tests__/
└── client.test.ts
src/types/
└── graphql.ts # TypeScript types
docs/
└── GRAPHQL_PATTERNS.md # Documentation
GraphQL Query Structure (Example)
query GetAffiliations($did: String!) {
affiliations(did: $did) {
rkey
organizationName
role
startDate
endDate
isPrimary
location {
city
country
}
website
createdAt
}
}
mutation CreateAffiliation($input: CreateAffiliationInput!) {
createAffiliation(input: $input) {
success
rkey
affiliation {
rkey
organizationName
role
startDate
}
error
}
}React Hook Pattern (Example)
// useAffiliations hook
export function useAffiliations(did: string) {
return useQuery(GET_AFFILIATIONS, {
variables: { did },
});
}
// useCreateAffiliation hook
export function useCreateAffiliation() {
const [mutate, { loading, error }] = useMutation(CREATE_AFFILIATION);
return {
createAffiliation: async (input: CreateAffiliationInput) => {
const result = await mutate({ variables: { input } });
return result.data.createAffiliation;
},
loading,
error,
};
}Testing Checklist
- Client connects to Quickslice GraphQL endpoint
- Authentication bearer token attached to requests
- Sample query executes successfully
- Sample mutation executes successfully
- Error handling works
- Loading states work
- Hooks can be imported and used in components
- TypeScript types correct
No Changes to Other Code
These continue to work without changes during Phase 3:
- src/app/api/ (REST endpoints still exist)
- Dashboard pages (still use REST)
- Form components (still use fetch)
- All other code
Risks
| Risk | Mitigation |
|---|---|
| GraphQL schema doesn't match expectations | Test queries against Quickslice before committing |
| Wrong authentication header format | Verify Quickslice docs, test with real requests |
| Type generation issues | Use graphql-codegen to auto-generate types |
Success Criteria
- GraphQL client successfully initialized
- Sample query returns data from Quickslice
- Sample mutation creates record successfully
- All hooks exported and usable
- TypeScript types all correct
- Tests passing
- Documentation complete
Estimated Duration
1-2 weeks
Next Phase
Once Phase 3 complete:
→ #92: Phase 4: REST to GraphQL Migration (Affiliations module)
→ #93: Phase 5: REST to GraphQL Migration (Qualifications)
→ #94: Phase 6: REST to GraphQL Migration (Skills + Links + Events + Works)
→ #95: Phase 7: Public Profile & Dashboard Pages
→ #96: Phase 8: Database & Code Cleanup
Notes
- This phase establishes the pattern used in all subsequent phases
- Quality matters here - good hooks make Phase 4-7 easier
- Document patterns well for team reference
- Don't migrate forms yet - Phase 4 starts that
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels