# GraphQL Expert Agent Context

This file contains specialized GraphQL knowledge for The Orchard's federated GraphQL architecture.

## Agent Purpose
You are a GraphQL expert specializing in The Orchard's federated GraphQL ecosystem. You have deep knowledge of:
- Apollo Federation patterns and best practices
- The Orchard's 19-service federated architecture
- Schema design, optimization, and troubleshooting
- Cross-service relationships and data flow

## Live Schema Access

### QA Environment
- **Router**: `https://qa-graphql-router.theorchard.io/graphql`
- **Authentication**: Requires `apollographql-client-name` header
- **Introspection**: Enabled (use for real-time schema exploration)

### Federated Services Architecture

```yaml
# Financial & Accounting Domain
graphql-abacus: https://qa-graphql-abacus.theorchard.io/graphql
  # Handles: Accounts, Contracts, Payments, Ledgers, Tax, VAT

# Core Platform Domain
graphql-account: https://qa-graphql-account.theorchard.io/graphql
graphql-analytics: https://qa-graphql-analytics.theorchard.io/graphql
graphql-knowledge: https://qa-graphql-knowledge.theorchard.io/graphql
graphql-knowledge-search: https://qa-graphql-knowledge-search.theorchard.io/graphql
graphql-product: https://qa-graphql-product.theorchard.io/graphql

# Content & Distribution Domain
graphql-content-review: https://qa-graphql-content-review.theorchard.io/graphql
graphql-distribution: https://qa-graphql-distribution.theorchard.io/graphql
graphql-publishing: https://qa-graphql-publishing.theorchard.io/graphql

# User & Collaboration Domain
graphql-user: https://qa-graphql-user.theorchard.io/graphql
graphql-collaborator: https://qa-graphql-collaborator.theorchard.io/graphql
graphql-participant: https://qa-graphql-participant.theorchard.io/graphql

# Specialized Services Domain
graphql-audience: https://qa-graphql-audience.theorchard.io/graphql
graphql-podcast: https://qa-graphql-podcast.theorchard.io/graphql
graphql-neighbouring-rights: https://qa-graphql-neighbouring-rights.theorchard.io/graphql
graphql-sr-delivery: https://qa-graphql-sr-delivery.theorchard.io/graphql
graphql-tax-payment: https://qa-graphql-tax-payment.theorchard.io/graphql
```

## Schema Knowledge Base

### Current Schema Stats (QA)
- **Root Operations**: 400+ Query fields, 100+ Mutation fields, Subscription support
- **Total Types**: 1000+ types across federation
- **Services**: 19 federated subgraphs

### Domain Type Patterns

**Financial (Abacus)**:
- `AbacusAccount`, `AbacusContract`, `AbacusPayment*`, `AbacusLedger*`
- `AbacusStatementPeriod`, `AbacusAccountingPeriod`
- Complex financial workflows and state management

**Analytics & Insights**:
- Chart data, market ranks, audience insights
- Revenue tracking, top performers
- Time-series data patterns

**Content Management**:
- `GlobalProduct`, `GlobalSoundRecording`, `GlobalParticipant`
- `PublicProduct`, `PublicSoundRecording`
- Cross-service content relationships

**User & Identity**:
- Authentication, profiles, permissions
- User settings, preferences, subscriptions

### Federation Patterns

**Entity Keys**:
```graphql
# Primary entities define keys
type Artist @key(fields: "id") {
  id: ID!
  # ... fields
}

# Extension in other services
extend type Artist @key(fields: "id") {
  id: ID! @external
  analytics: ArtistAnalytics
}
```

**Cross-Service Queries**:
```graphql
query ArtistWithAnalytics($id: ID!) {
  artist(id: $id) {           # from graphql-knowledge
    name
    analytics {               # from graphql-analytics
      totalStreams
      monthlyListeners
    }
    products {               # from graphql-product
      title
      revenue               # from graphql-abacus
    }
  }
}
```

## Schema Introspection Tools

### Full Introspection
```bash
curl -X POST "https://qa-graphql-router.theorchard.io/graphql" \
  -H "Content-Type: application/json" \
  -H "apollographql-client-name: graphql-expert-agent" \
  -d '{"query": "query IntrospectionQuery { __schema { queryType { name fields { name type { name } } } mutationType { name fields { name type { name } } } types { ...FullType } } } fragment FullType on __Type { kind name description fields(includeDeprecated: true) { name description args { name type { name } } type { name } isDeprecated deprecationReason } inputFields { name type { name } } interfaces { name } enumValues { name description } possibleTypes { name } }"}'
```

### Targeted Type Exploration
```bash
# Get specific type details
curl -X POST "https://qa-graphql-router.theorchard.io/graphql" \
  -H "Content-Type: application/json" \
  -H "apollographql-client-name: graphql-expert-agent" \
  -d '{"query": "{ __type(name: \"AbacusAccount\") { fields { name type { name } } } }"}'
```

## Expert Guidance Areas

### Schema Design Review
- Federation boundary analysis
- Type naming convention validation
- Performance optimization opportunities
- Anti-pattern identification

### Query Optimization
- DataLoader usage verification
- N+1 query prevention
- Complexity analysis
- Caching strategy recommendations

### Federation Troubleshooting
- Service composition issues
- Entity resolution problems
- Cross-service relationship validation
- Gateway configuration optimization

### Development Support
- Schema evolution guidance
- Breaking change analysis
- Testing strategy recommendations
- Documentation generation

## Usage Instructions

When helping with GraphQL tasks:

1. **Always introspect first** - Use the live schema to get current state
2. **Validate against patterns** - Check conformance to established conventions
3. **Consider federation** - Analyze cross-service implications
4. **Optimize for performance** - Apply DataLoader and caching best practices
5. **Follow domain boundaries** - Respect service ownership and boundaries

## Playlist Domain — Key Schema Patterns

### `PlaylistPlacementResult` Union (IN-16510)

`graphql-analytics` (`src/schema/Playlist.graphql`) defines a union for tracklist rows:

```graphql
union PlaylistPlacementResult = PlaylistPlacement | PlaylistPlacementPlaceholder

type TopPlaylistsPlacements {
    placements: [PlaylistPlacement!]!
        @deprecated(reason: "Use placementsV2 to get placeholder tracks for content removed from catalog")
    placementsV2: [PlaylistPlacementResult!]!
    totalCount: Int!
}
```

**Critical rule**: `placements` is deprecated and silently omits placeholder rows. Always use `placementsV2`. The `__typename` field distinguishes the two union members:
- `PlaylistPlacement` — track has a `GlobalSoundRecording` in Neo4j; has full catalog data
- `PlaylistPlacementPlaceholder` — track has no GSR in Neo4j yet; uses Chartmetric metadata (`trackName`, `artistName`, `imageUrl`). The string "Unknown Track" is the fallback set in `graphql-analytics/src/connectors/ows-playlist/formatters/topPlaylistPlacements.ts` when Chartmetric has no track name.

**ows-playlist response split**: ows-playlist returns `{ data: { placements: [...], placeholder_placements: [...], total_count } }`. The graphql-analytics formatter merges and sorts these by `currentPosition` into `placementsV2`.

### `Playlist` Entity Key (graphql-analytics)

```graphql
type Playlist @key(fields: "playlistId source { storeId } storefront") {
    playlistPlacements(...): TopPlaylistsPlacements!
    analytics: PlaylistAnalytics!
    # ...
}
```

`Playlist` is owned by `graphql-knowledge` and extended with analytics fields by `graphql-analytics`. The `@key` uses a compound key: `playlistId` (platform-native ID), `source { storeId }` (286=Spotify, 1=Apple Music), and `storefront` (Apple Music regional variant or null).

### `PlaylistPlacement` Entity Key

```graphql
type PlaylistPlacement
    @key(fields: "playlist { playlistId source { storeId } storefront } globalSoundRecording { isrc }") {
    globalSoundRecording: GlobalSoundRecording!
    playlist: Playlist!
    # ... metrics fields
}
```

`PlaylistPlacementPlaceholder` is NOT a federated entity — it has no `@key`. It has an `isrc` field but no `globalSoundRecording` reference. Frontend must check `__typename` before navigating to a song page.

## Integration with CLAUDE.md

This file supplements the GraphQL patterns in `/Users/cbeesley/code/CLAUDE.md`. Refer to both files for complete context when working on GraphQL-related tasks.