# graphql-abacus

GraphQL service backed by the `royalty_accounting` MySQL database, which exist behind an API across various [microservices](https://www.notion.so/ABACUS-Onboarding-System-Inventory-dd8b5d0996d840609c7c4af6f84c55d2#92a390f8c86745bb8a95df2f37b1beef) in the "accounting" `application_family`.

## Running

1. Make sure you have `yarn` and a `node` version greater than `24.0.0`.
2. We are using private npm packages from our [monorepo](https://github.com/theorchard/orchard-suite) and packagecloud.io registry. That means you need a valid access token for each of them. Follow this [guide](https://www.notion.so/Javascript-Package-Management-Setup-9553d5d491c94835aa787fdf0fc4838d) on how to setup NPM access.
3. Familiarize yourself with [GraphQL at The Orchard](https://www.notion.so/GraphQL-bee3d9f485734cadb2a6483f9bb02707) before contributing!
4. This Graphql is Federated with "graphql-theorchard". New schema Types should avoid name clashes with existing schema Types in other federated services. E.g., if a GlobalSoundRecording Type were added to this schema, it would conflict with GlobalSoundRecording in graphql-knowledge. We should extend those types instead and use it. E.g:
```gql
extend type GlobalSoundRecording @key(fields: "isrc")  {
  isrc: String! @external
}

type MyNewThing {
    id: ID!
    artistNames: String
    globalSoundRecording: GlobalSoundRecording
}
```

## Setup
1. Select the development version of nodejs `nvm use`.
2. Install dependencies: `yarn install`.
3. Copy the `.env.shadow` file to `.env` and fill in your information.
4. Run the server: `yarn start`.
5. Open your browser at [http://localhost:8080/graphql](http://localhost:8080/graphql).
6. Set the necessary headers for your query:

```graphql
apollographql-client-name: frontend-royalties
apollographql-client-version: 1.0.0
orchard-identity-id: your-identity-id
orchard-profile-id: your-abacus-profile-id
orchard-profile-type: AbacusProfile
orchard-roles: administrator
authorization: Bearer your-actual-token
```

## Authorization

### Running graphql-abacus With Frontend Services

This service uses jwt-service-handler private package. The package defaults to use QA auth0 creds for jwt token validation on local graphql setup. Make sure to use qa auth0 creds in your frontend service local setups so that they generate QA jwt and pass on in graphql calls.

### Running graphql-abacus With Microservices

As mentioned previously, this service uses the `jwt-service-handler` package to handle authorization. This means, if you are connecting to a microservice in QA that enforces authorization, you will need to do the following:

1. Set `ENABLE_JWT_SERVICE_CACHE=true` and `SPLIT_API_KEY=localhost` in your `.env` file.

2. Generate an AWS token using your Dev profile and set your default profile to use your Dev credentials in your `~/.aws/credentials` file. Run the following command to generate an aws token in your terminal session using awsume (recommended) or aws cli: `awsume`. This allows `jwt-service-handler` to read the `qa/lambda-jwt-refresh/jwt_enabled_services` from the AWS Dev account.

3. Grab a token from the `Authorization` header from any request in QA. Then add it to the list of headers for your query as explained in the [setup step](#setup) above.

> Please note, this token expires every hour.

![token](Token.gif)

> N.B - graphql-abacus may raise a _missing Authorization header_ error even though you are passing an Authorization header explicitly. This error may be due to your service not being added to `qa/lambda-jwt-refresh/jwt_enabled_services` list specifically for AWS Dev account.


## Dancing the Schema Way

Sometimes a change is made in code that will be interpreted as a breaking change by the schema check (`apollo service:check`) and/or schema push (`apollo service:push`) during CI/CD and deployment.

Usually the code change is legit and needs to be merged without failing these checks. The solution is to skip them (AKA *"do the schema dance"*).

Developers working on `graphql-abacus` are deemed *very* good dancers. They do not work hard when busting a move.

If the schema checks need to be side-stepped when opening a PR, include the phrase `change-schema` in the PR title. Jenkins will follow the PR's lead.

Example:
`ACC-XXXX: modify existing field` should become `ACC-XXXX: change-schema modify existing field`.

Boom. You just got served.

## Adding/modifying fields in schemas (*.graphql files)

If you've added or changed a field in a graphql schema and your PR is failing in CI at "Checks and Static Tests/Validate QA schema: error in 'sh' step" you'll need to re-run the pipeline manually and disable that step:

1. Go to https://pipeline.theorchard.io/job/theorchard/job/graphql-abacus/view/change-requests/
2. Click on your PR.
3. Go to "Build with Parameters" in the top left sidebar.
4. Uncheck the 3 parameters options: (DEPLOY_TO_UAT, DEPLOY_TO_PROD, VALIDATE_SCHEMA)
5. Click Build. Your PR should now skip the validate step and will be ready for review and merge. On merge the master pipeline will build the new schema and will be ready to get codegen'd in the frontend.
