Skip to content

Deploy api V2 to prod #295

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 76 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
f561480
feat(supabaseservice): refactor base service to use strategies
bitbeckers Feb 12, 2025
960c191
refactor(graphql): consolidate and simplify where, sort, pagination a…
bitbeckers Feb 13, 2025
97a5e5f
feat(refactor): refactor db services into entity services
bitbeckers Mar 4, 2025
27ca9c4
chore(docs): developer guide
bitbeckers Mar 7, 2025
c47c6ef
fix(sortBy): fix sortBy build errors
bitbeckers Mar 7, 2025
d2c8bb5
fix(types): add missing 'id' field to WhereFieldDefinitions and exten…
bitbeckers Mar 7, 2025
08ff65d
fix(blueprint): convert blueprint ID to string for query comparison
bitbeckers Mar 7, 2025
020689d
fix(metadata): update hypercerts relationship and query strategy
bitbeckers Mar 7, 2025
67542f3
fix(sales): update sales query to use item_ids instead of token_id
bitbeckers Mar 7, 2025
1d9720a
fix(types): improve type safety in address filtering
bitbeckers Mar 7, 2025
6227ee0
fix(types): improve type safety for sort order in query arguments
bitbeckers Mar 7, 2025
ab08d62
fix(blueprint): update blueprint ID type from string to number
bitbeckers Mar 7, 2025
df09cac
refactor(types): use WhereFieldDefinitions for User query arguments
bitbeckers Mar 7, 2025
0d2059e
refactor(attestations): remove metadata join condition from query str…
bitbeckers Mar 7, 2025
f47faa8
refactor(collections): update query strategy type arguments
bitbeckers Mar 7, 2025
efce384
feat(signature-requests): add status field to query arguments
bitbeckers Mar 7, 2025
f727e35
feat(graphql): update createEntitySortArgs with comprehensive test co…
bitbeckers Mar 7, 2025
50f4e34
feat(graphql): enhance createEntityWhereArgs with comprehensive docum…
bitbeckers Mar 8, 2025
ee56443
feat(graphql): enhance createEntityArgs with comprehensive documentat…
bitbeckers Mar 8, 2025
4f00f75
feat(graphql): enhance TypeRegistry with comprehensive documentation …
bitbeckers Mar 9, 2025
830b20f
refactor(graphql): migrate TypeRegistry to tsyringe singleton with im…
bitbeckers Mar 9, 2025
9295c4e
feat(graphql): basequeryargs with documentation and tests
bitbeckers Mar 9, 2025
54895f2
feat(graphql): enhance buildWhereCondition with advanced filtering an…
bitbeckers Mar 9, 2025
025c7d8
feat(graphql): enhance DataResponse with comprehensive documentation …
bitbeckers Mar 9, 2025
f9f57c8
feat(graphql): add comprehensive documentation for WhereFieldDefinitions
bitbeckers Mar 9, 2025
8976be3
feat(db): enhance applyPagination with comprehensive documentation an…
bitbeckers Mar 9, 2025
5df0b8b
feat(db): enhance applyWhere with comprehensive documentation and rob…
bitbeckers Mar 9, 2025
7119317
feat(db): enhance applySort with comprehensive documentation and robu…
bitbeckers Mar 9, 2025
5bb1ff0
feat(db): enhance queryModifiers with comprehensive documentation and…
bitbeckers Mar 9, 2025
0ff0e0e
chore(lib): migrated db lib tools from graphql to db dir
bitbeckers Mar 9, 2025
cc841f8
refactor(db): restructure QueryStrategyFactory with improved registry…
bitbeckers Mar 9, 2025
0eca3f6
feat(db): enhance EntityServiceFactory with comprehensive documentati…
bitbeckers Mar 10, 2025
f4a3d97
feat(graphql): add comprehensive support for AllowlistRecord with enh…
bitbeckers Mar 10, 2025
68e8532
feat(attestation): implement comprehensive attestation resolver and s…
bitbeckers Mar 10, 2025
b4259aa
feat(attestationschema): restructure attestation schema resolver and …
bitbeckers Mar 10, 2025
25d5cc4
refactor(contract): restructure contract resolver and related components
bitbeckers Mar 10, 2025
7a6f0b1
refactor(fraction): restructure fraction resolver and related components
bitbeckers Mar 10, 2025
13a68ec
feat(graphql): standardize error handling across resolvers with null …
bitbeckers Mar 10, 2025
19817cb
refactor(metadata): document metadata resolver and update metadata-re…
bitbeckers Mar 10, 2025
e98d7b0
refactor(hypercert): restructure hypercert resolver and related compo…
bitbeckers Mar 10, 2025
22da606
refactor(sales): implement comprehensive sales resolver and services
bitbeckers Mar 10, 2025
073b341
refactor(blueprint): restructure blueprint resolver and related compo…
bitbeckers Mar 11, 2025
3a0ca3a
refactor(user): implement comprehensive user resolver and related com…
bitbeckers Mar 11, 2025
b796a81
refactor(collection): restructure collection resolver and enhance rel…
bitbeckers Mar 13, 2025
069f002
feat(order): add order resolver and enhance marketplace order services
bitbeckers Mar 17, 2025
b085990
feat(hyperboard): enhance hyperboard functionality and restructure re…
bitbeckers Mar 17, 2025
c58f3ce
refactor(signatureRequests): restructure signature request handling a…
bitbeckers Mar 17, 2025
77037f7
fix(build): fix build errors and broken types
bitbeckers Mar 17, 2025
de397b1
fix(pr): pr review comments
bitbeckers Apr 2, 2025
5d25f5c
fix(hyperboard): update hyperboard response types
bitbeckers Apr 8, 2025
8ae04bf
fix(build): build errors after rebase
bitbeckers Apr 8, 2025
a3f2a96
fix(types): add missing fields to order requests
bitbeckers Apr 8, 2025
54d79c8
fix: add version prefix to health monitoring endpoint
Jipperism Apr 16, 2025
c289e75
fix(stuff): last bits
bitbeckers Apr 17, 2025
dc47e1c
fix(docs): update README and development documentation for v2 endpoints
Jipperism Apr 17, 2025
f6c29f1
Merge branch 'develop' into feat/refactor_supabase_services
bitbeckers Apr 17, 2025
a4b32b8
fix: build
Jipperism Apr 17, 2025
e90a4c9
Merge pull request #263 from hypercerts-org/feat/refactor_supabase_se…
bitbeckers Apr 17, 2025
bd4edab
fix(build): cleanup dependencies and generated files
bitbeckers Apr 17, 2025
882f8ac
fix: build-better-sqlite3
Jipperism Apr 17, 2025
9c2ffba
refactor: remove Infura
Jipperism May 17, 2025
0c24789
feat(metadataArgs): add hypercert reference to Metadata entity arguments
Jipperism May 23, 2025
82d5468
feat(hypercert): add HypercertWithMetadata type and update Order type…
Jipperism May 23, 2025
d2d7dc3
fix(pricePerPercent): do not fetch hypercerts by lowercased ID
Jipperism May 23, 2025
419b530
feat(graphql): add contract_address to WhereFieldDefinitions
Jipperism May 23, 2025
2e0e84b
fix(attestations): do not cast tokenId to string
Jipperism May 23, 2025
ff70103
fix(isWhereEmpty): update logic to check for undefined values in wher…
Jipperism May 23, 2025
9ed0afb
fix(blueprints): use blueprints_with_admins view instead of blueprint…
Jipperism May 25, 2025
27ff7c3
fix(sales): update graphql query params to enable querying on metadata
Jipperism May 25, 2025
374f887
fix(hyperboards): make hyperboards queryable by admin_address using view
Jipperism May 25, 2025
9868634
fix: uint8 parsing
Jipperism May 27, 2025
24b075a
feat(allowlist): add optional ID field to AllowlistRecord type defini…
Jipperism May 27, 2025
e2956bf
chore: update graphql schema
Jipperism May 27, 2025
178a6a7
refactor(graphql): move HypercertWithMetadata to own file
Jipperism May 29, 2025
f1ee48a
fix(tests): update sql tests
Jipperism May 29, 2025
1cbf4ac
fix(tests): disable failing entity service tests
Jipperism May 29, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .env.template
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,5 @@ SENTRY_AUTH_TOKEN="" #disabled for local
# https://www.alchemy.com/
ALCHEMY_API_KEY=""

# https://www.infura.io/
INFURA_API_KEY=""

# https://drpc.org/
DRPC_API_KEY=""
1 change: 0 additions & 1 deletion .github/workflows/ci-test-unit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ jobs:

ALCHEMY_API_KEY: ${{ secrets.ALCHEMY_API_KEY }}
DRPC_API_KEY: "test"
INFURA_API_KEY: "test"
FILECOIN_API_KEY: "test"

INDEXER_ENVIRONMENT: "test"
Expand Down
6 changes: 3 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ yarn-error.log*
*.tsbuildinfo
next-env.d.ts

# generated graphql files
src/generated/

dist
.rollup.cache
.idea

# generated swagger files
src/__generated__/
32 changes: 16 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ The API implements a fallback to the first available RPC. You can set the RPCs i

### Supabase

* Install Docker
* `git submodule init`
* `git submodule update --remote`
* `pnpm supabase:start:all`
- Install Docker
- `git submodule init`
- `git submodule update --remote`
- `pnpm supabase:start:all`

This will spin up 2 Supabase instances in Docker, one for the indexer service (caching) and one for the data service (static data) which are both exposed by the API.

Expand All @@ -43,21 +43,21 @@ From both instances, you can get their respective keys and add them to the env v

This will run a live production instance by running `swc` to compile the code and `nodemon` to restart the server on changes.

You can then find the API at `localhost:4000/spec` (Swagger instance) and the GraphQL at `localhost:4000/v1/graphql`
You can then find the API at `localhost:4000/spec` (Swagger instance) and the GraphQL at `localhost:4000/v2/graphql`

## Deployments

Production: `https://api.hypercerts.org/`
Staging: `https://staging-api.hypercerts.org`

`/spec` - Swagger instance documenting the API and exposing a playground to experiment with the endpoints
`/v1/graphql` - GraphQL API to access hypercerts data like claims, fractions, attestations, allow lists
`/v2/graphql` - GraphQL API to access hypercerts data like claims, fractions, attestations, allow lists

## Scripts

- `dev`: Starts the development server using `nodemon`, which will automatically restart the server whenever you save a file that the server uses.
- `build`: Denerates the OpenAPI specification and routes using `tsoa`, and then compiles the TypeScript code into JavaScript using `swc`. The compiled code is output to the `dist` directory.
- `start`: Starts the application in production mode.
- `start`: Starts the application in production mode.
- `lint`: Runs `eslint` on the codebase to check for linting errors.
- `test`: Runs tests using `vitest`

Expand Down Expand Up @@ -86,38 +86,38 @@ The API also provides an upload and validation endpoint for hypercert and allow
graph TB
Client[Client Applications]
API[Hypercerts API :4000]

subgraph "API Endpoints"
Swagger["/spec\nSwagger Documentation"]
GraphQL["/v1/graphql\nGraphQL Endpoint"]
GraphQL["/v2/graphql\nGraphQL Endpoint"]
Upload["Upload & Validation\nEndpoints"]
end

subgraph "Data Services"
Static[("Static Data Service\n(Supabase DB)\n- User Data\n- Collections\n- Signed Orders")]
Indexer[("Indexer Service\n(Supabase DB)\n- On-chain Data\n- IPFS Data")]
end

subgraph "External Services"
IPFS[(IPFS\nMetadata Storage)]
Blockchain[(Blockchain\nSupported Chains)]
EAS[(EAS\nAttestations)]
end

Client --> API
API --> Swagger
API --> GraphQL
API --> Upload

GraphQL --> Static
GraphQL --> Indexer
Upload --> IPFS

Indexer --> Blockchain
Indexer --> IPFS
Indexer --> EAS

class Swagger,GraphQL,Upload apiEndpoint;
class Static,Indexer database;
class IPFS,Blockchain,EAS external;
```
```
176 changes: 176 additions & 0 deletions docs/DEVELOPMENT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
# Development Guide: Implementing a New Entity

This guide explains how to implement a new entity in the Hypercerts API, from type definition to resolver implementation.

## Overview

The Hypercerts API uses a modular architecture where each entity follows a consistent pattern:

1. Type Definition
2. Query Arguments
3. Entity Service
4. Resolver

## Step-by-Step Implementation

### 1. Define Entity Types

Create a new file in `src/graphql/schemas/typeDefs/` for your entity types:

```typescript
// src/graphql/schemas/typeDefs/yourEntityTypeDefs.ts
import { Field, ObjectType } from "type-graphql";
import { BaseEntity } from "./baseTypes.js";

@ObjectType()
export class YourEntity extends BaseEntity {
@Field(() => String)
name: string;

@Field(() => String, { nullable: true })
description?: string;

// Add other fields as needed
}

@ObjectType()
export class GetYourEntitiesResponse {
@Field(() => [YourEntity])
data: YourEntity[];

@Field(() => Int)
count: number;
}
```

### 2. Define Query Arguments

Create a new file in `src/graphql/schemas/args/` for your query arguments:

```typescript
// src/graphql/schemas/args/yourEntityArgs.ts
import { ArgsType } from "type-graphql";
import { createEntityArgs } from "../../../lib/graphql/createEntityArgs.js";
import { EntityTypeDefs } from "../typeDefs/typeDefs.js";

// Define your entity fields
const fields = {
name: "string",
description: "string",
// Add other fields as needed
} as const;

// Create query arguments
export const { WhereInput, SortOptions } = createEntityArgs(
"YourEntity" as EntityTypeDefs,
fields,
);

@ArgsType()
export class GetYourEntitiesArgs {
first?: number;
offset?: number;
where?: typeof WhereInput;
sortBy?: typeof SortOptions;
}
```

### 3. Create Entity Service

Create a new file in `src/services/database/entities/` for your entity service:

```typescript
// src/services/database/entities/YourEntityService.ts
import { injectable } from "tsyringe";
import { createEntityService } from "./EntityServiceFactory.js";
import { GetYourEntitiesArgs } from "../../../graphql/schemas/args/yourEntityArgs.js";
import { YourEntity } from "../../../graphql/schemas/typeDefs/yourEntityTypeDefs.js";

@injectable()
export class YourEntityService {
private service = createEntityService<YourEntity, GetYourEntitiesArgs>(
"your_entity_table",
{
// Add any custom query modifiers if needed
},
);

async getYourEntities(args: GetYourEntitiesArgs) {
return this.service.getMany(args);
}

async getYourEntity(args: GetYourEntitiesArgs) {
return this.service.getSingle(args);
}
}
```

### 4. Implement Resolver

Create a new file in `src/graphql/schemas/resolvers/` for your resolver:

```typescript
// src/graphql/schemas/resolvers/yourEntityResolver.ts
import { inject, injectable } from "tsyringe";
import { Args, Query, Resolver } from "type-graphql";
import { YourEntityService } from "../../../services/database/entities/YourEntityService.js";
import { GetYourEntitiesArgs } from "../args/yourEntityArgs.js";
import {
GetYourEntitiesResponse,
YourEntity,
} from "../typeDefs/yourEntityTypeDefs.js";

@injectable()
@Resolver(() => YourEntity)
class YourEntityResolver {
constructor(
@inject(YourEntityService)
private yourEntityService: YourEntityService,
) {}

@Query(() => GetYourEntitiesResponse)
async yourEntities(@Args() args: GetYourEntitiesArgs) {
return this.yourEntityService.getYourEntities(args);
}
}
```

### 5. Register the Resolver

Add your resolver to the list of resolvers in `src/graphql/schemas/resolvers/index.ts`:

```typescript
export * from "./yourEntityResolver.js";
```

## Best Practices

1. **Type Safety**: Always use TypeScript's type system to ensure type safety across your implementation.
2. **Consistent Naming**: Follow the existing naming conventions in the codebase.
3. **Error Handling**: Implement proper error handling in your service and resolver methods.
4. **Testing**: Write unit tests for your new entity implementation.
5. **Documentation**: Add JSDoc comments to document your types, methods, and classes.

## Example Implementation

For a complete example, you can look at the implementation of existing entities like `Contract`, `Metadata`, or `AttestationSchema` in the codebase.

## Common Pitfalls

1. **Type Registration**: Ensure all your types are properly registered in the GraphQL schema.
2. **Dependency Injection**: Use the `@injectable()` and `@inject()` decorators correctly.
3. **Query Arguments**: Make sure your query arguments match the expected structure.
4. **Database Schema**: Ensure your database table matches the entity structure.

## Testing Your Implementation

1. Start the development server: `pnpm dev`
2. Access the GraphQL playground at `http://localhost:4000/v2/graphql`
3. Test your queries and mutations
4. Run the test suite: `pnpm test`

## Additional Resources

- [TypeGraphQL Documentation](https://typegraphql.com/)
- [Kysely Documentation](https://kysely.dev/docs/intro)
- [Supabase Documentation](https://supabase.com/docs)
10 changes: 10 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,14 @@ export default tseslint.config(
"@typescript-eslint/no-extraneous-class": "off",
},
},
{
files: ["**/*.test.ts"],
rules: {
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-unused-vars": [
"error",
{ argsIgnorePattern: "^_" },
],
},
},
);
Loading