Skip to content

Phase 3: GraphQL Client & Hooks Setup #92

@renderghost

Description

@renderghost

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

  1. Create GraphQL client configuration
  2. Define GraphQL queries and mutations
  3. Create reusable React hooks
  4. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions