added graphql entegration and tested tanstack query
This commit is contained in:
10
backend/package-lock.json
generated
10
backend/package-lock.json
generated
@@ -19,6 +19,7 @@
|
||||
"@nestjs/platform-express": "^11.0.1",
|
||||
"graphql": "^16.12.0",
|
||||
"graphql-fields": "^2.0.3",
|
||||
"graphql-type-json": "^0.3.2",
|
||||
"mongoose": "^8.19.3",
|
||||
"reflect-metadata": "^0.2.2",
|
||||
"rxjs": "^7.8.1"
|
||||
@@ -6769,6 +6770,15 @@
|
||||
"graphql": "^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/graphql-type-json": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/graphql-type-json/-/graphql-type-json-0.3.2.tgz",
|
||||
"integrity": "sha512-J+vjof74oMlCWXSvt0DOf2APEdZOCdubEvGDUAlqH//VBYcOYsGgRW7Xzorr44LvkjiuvecWc8fChxuZZbChtg==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"graphql": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/graphql-ws": {
|
||||
"version": "6.0.6",
|
||||
"resolved": "https://registry.npmjs.org/graphql-ws/-/graphql-ws-6.0.6.tgz",
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
"@nestjs/platform-express": "^11.0.1",
|
||||
"graphql": "^16.12.0",
|
||||
"graphql-fields": "^2.0.3",
|
||||
"graphql-type-json": "^0.3.2",
|
||||
"mongoose": "^8.19.3",
|
||||
"reflect-metadata": "^0.2.2",
|
||||
"rxjs": "^7.8.1"
|
||||
|
||||
0
backend/src/build/build.queries.graphql
Normal file
0
backend/src/build/build.queries.graphql
Normal file
17
backend/src/dto/list.input.ts
Normal file
17
backend/src/dto/list.input.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { GraphQLJSONObject } from 'graphql-type-json';
|
||||
import { Field, Int, InputType } from '@nestjs/graphql';
|
||||
|
||||
@InputType()
|
||||
export class ListArguments {
|
||||
@Field(() => GraphQLJSONObject, { nullable: true })
|
||||
filters?: any;
|
||||
|
||||
@Field(() => GraphQLJSONObject, { nullable: true })
|
||||
sort?: any;
|
||||
|
||||
@Field(() => Int, { defaultValue: 0 })
|
||||
skip: number;
|
||||
|
||||
@Field(() => Int, { defaultValue: 10 })
|
||||
limit: number;
|
||||
}
|
||||
14
backend/src/people/dto/list-result.response.ts
Normal file
14
backend/src/people/dto/list-result.response.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { Field, ObjectType } from "@nestjs/graphql";
|
||||
import { User } from "@/models/user.model";
|
||||
import { Int } from "@nestjs/graphql";
|
||||
|
||||
@ObjectType()
|
||||
export class UsersListResponse {
|
||||
|
||||
@Field(() => [User])
|
||||
data: User[];
|
||||
|
||||
@Field(() => Int)
|
||||
totalCount: number;
|
||||
|
||||
}
|
||||
73
backend/src/people/people.queries.graphql
Normal file
73
backend/src/people/people.queries.graphql
Normal file
@@ -0,0 +1,73 @@
|
||||
mutation CreatePerson {
|
||||
createPerson(
|
||||
input: {
|
||||
firstName: "John",
|
||||
surname: "Doe",
|
||||
middleName: "Michael",
|
||||
sexCode: "M",
|
||||
personRef: "REF12345",
|
||||
personTag: "TAG001",
|
||||
fatherName: "Robert",
|
||||
motherName: "Jane",
|
||||
countryCode: "US",
|
||||
nationalIdentityId: "12345678901",
|
||||
birthPlace: "New York",
|
||||
birthDate: "1990-01-01T00:00:00.000Z",
|
||||
taxNo: "987654321",
|
||||
birthname: "Johnathan"
|
||||
}
|
||||
) {
|
||||
_id
|
||||
firstName
|
||||
surname
|
||||
birthDate
|
||||
}
|
||||
}
|
||||
|
||||
query {
|
||||
Persons {
|
||||
firstName
|
||||
surname
|
||||
middleName
|
||||
sexCode
|
||||
personRef
|
||||
personTag
|
||||
fatherName
|
||||
motherName
|
||||
countryCode
|
||||
nationalIdentityId
|
||||
birthPlace
|
||||
birthDate
|
||||
taxNo
|
||||
birthname
|
||||
}
|
||||
}
|
||||
|
||||
query GetPerson {
|
||||
Person(id: "AnID") {
|
||||
_id
|
||||
uuid
|
||||
expiryStarts
|
||||
expiryEnds
|
||||
isConfirmed
|
||||
deleted
|
||||
active
|
||||
crypUuId
|
||||
createdCredentialsToken
|
||||
updatedCredentialsToken
|
||||
confirmedCredentialsToken
|
||||
isNotificationSend
|
||||
isEmailSend
|
||||
refInt
|
||||
refId
|
||||
replicationId
|
||||
createdAt
|
||||
updatedAt
|
||||
|
||||
firstName
|
||||
surname
|
||||
middleName
|
||||
sexCode
|
||||
birthDate
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
mutation CreatePerson {
|
||||
createPerson(input: {
|
||||
firstName: "John",
|
||||
surname: "Doe",
|
||||
middleName: "Michael",
|
||||
sexCode: "M",
|
||||
personRef: "REF12345",
|
||||
personTag: "TAG001",
|
||||
fatherName: "Robert",
|
||||
motherName: "Jane",
|
||||
countryCode: "US",
|
||||
nationalIdentityId: "12345678901",
|
||||
birthPlace: "New York",
|
||||
birthDate: "1990-01-01T00:00:00.000Z",
|
||||
taxNo: "987654321",
|
||||
birthname: "Johnathan"
|
||||
}) {
|
||||
_id
|
||||
firstName
|
||||
surname
|
||||
birthDate
|
||||
}
|
||||
}
|
||||
|
||||
query GetPerson {
|
||||
Person(id: "69175eec7baea04628ad126c") {
|
||||
_id
|
||||
firstName
|
||||
surname
|
||||
middleName
|
||||
sexCode
|
||||
birthDate
|
||||
}
|
||||
}
|
||||
|
||||
query {
|
||||
Persons {
|
||||
firstName
|
||||
surname
|
||||
middleName
|
||||
sexCode
|
||||
personRef
|
||||
personTag
|
||||
fatherName
|
||||
motherName
|
||||
countryCode
|
||||
nationalIdentityId
|
||||
birthPlace
|
||||
birthDate
|
||||
taxNo
|
||||
birthname
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
mutation {
|
||||
createUser(input: {
|
||||
password: "secret123",
|
||||
history: ["login1"],
|
||||
tag: "admin",
|
||||
email: "test@example.com",
|
||||
phone: "555123456",
|
||||
collectionTokens: {
|
||||
default: "default-token",
|
||||
tokens: [{ prefix: "main", token: "abc123" }]
|
||||
},
|
||||
person: "64f8b2a4e1234567890abcdef"
|
||||
}) {
|
||||
_id
|
||||
password
|
||||
tag
|
||||
email
|
||||
phone
|
||||
tag
|
||||
collectionTokens {
|
||||
default
|
||||
tokens {
|
||||
prefix
|
||||
token
|
||||
}
|
||||
}
|
||||
person
|
||||
}
|
||||
}
|
||||
|
||||
120
backend/src/users/users.queries.graphql
Normal file
120
backend/src/users/users.queries.graphql
Normal file
@@ -0,0 +1,120 @@
|
||||
mutation {
|
||||
createUser(input: {
|
||||
password: "secret123",
|
||||
history: ["login1"],
|
||||
tag: "admin",
|
||||
email: "test@example.com",
|
||||
phone: "555123456",
|
||||
collectionTokens: {
|
||||
default: "default-token",
|
||||
tokens: [{ prefix: "main", token: "abc123" }]
|
||||
},
|
||||
person: "64f8b2a4e1234567890abcdef"
|
||||
}) {
|
||||
_id
|
||||
password
|
||||
tag
|
||||
email
|
||||
phone
|
||||
tag
|
||||
collectionTokens {
|
||||
default
|
||||
tokens {
|
||||
prefix
|
||||
token
|
||||
}
|
||||
}
|
||||
person
|
||||
}
|
||||
}
|
||||
|
||||
query {
|
||||
users(limit:1, skip: 0) {
|
||||
_id
|
||||
uuid
|
||||
expiryStarts
|
||||
expiryEnds
|
||||
isConfirmed
|
||||
deleted
|
||||
active
|
||||
crypUuId
|
||||
createdCredentialsToken
|
||||
updatedCredentialsToken
|
||||
confirmedCredentialsToken
|
||||
isNotificationSend
|
||||
isEmailSend
|
||||
refInt
|
||||
refId
|
||||
replicationId
|
||||
|
||||
expiresAt
|
||||
resetToken
|
||||
password
|
||||
history
|
||||
tag
|
||||
email
|
||||
phone
|
||||
|
||||
collectionTokens {
|
||||
default
|
||||
tokens {
|
||||
prefix
|
||||
token
|
||||
}
|
||||
}
|
||||
createdAt
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
query TestUsers(
|
||||
$skip: Int
|
||||
$limit: Int
|
||||
$sort: JSON
|
||||
$filters: JSON
|
||||
) {
|
||||
users(skip: $skip, limit: $limit, sort: $sort, filters: $filters) {
|
||||
_id
|
||||
email
|
||||
phone
|
||||
tag
|
||||
createdAt
|
||||
person {
|
||||
firstName
|
||||
lastName
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
"skip": 0,
|
||||
"limit": 5,
|
||||
"sort": {
|
||||
"createdAt": 1
|
||||
},
|
||||
"filters": {}
|
||||
}
|
||||
|
||||
{
|
||||
"skip": 0,
|
||||
"limit": 20,
|
||||
"sort": { "email": -1 },
|
||||
"filters": {
|
||||
"email": {
|
||||
"$regex": "@gmail.com",
|
||||
"$options": "i"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
"skip": 0,
|
||||
"limit": 50,
|
||||
"sort": { "tag": 1 },
|
||||
"filters": {
|
||||
"$or": [
|
||||
{ "email": { "$regex": "example", "$options": "i" }},
|
||||
{ "phone": { "$regex": "555", "$options": "i" }}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -2,25 +2,21 @@ import { Resolver, Query, Args, ID, Info, Mutation, Int } from '@nestjs/graphql'
|
||||
import { Types } from 'mongoose';
|
||||
import { User } from '@/models/user.model';
|
||||
import { UsersService } from '@/users/users.service';
|
||||
import type { GraphQLResolveInfo } from 'graphql';
|
||||
import graphqlFields from 'graphql-fields';
|
||||
import { CreateUserInput } from './dto/create-user.input';
|
||||
import { ListArguments } from '@/dto/list.input';
|
||||
import { UsersListResponse } from '@/people/dto/list-result.response';
|
||||
import graphqlFields from 'graphql-fields';
|
||||
import type { GraphQLResolveInfo } from 'graphql';
|
||||
|
||||
@Resolver(() => User)
|
||||
export class UsersResolver {
|
||||
|
||||
constructor(private readonly usersService: UsersService) { }
|
||||
|
||||
// Add pagination skip and limit arguments
|
||||
@Query(() => [User], { name: 'users' })
|
||||
async getUsers(
|
||||
@Info() info: GraphQLResolveInfo,
|
||||
@Args('skip', { type: () => Int, defaultValue: 0 }) skip: number,
|
||||
@Args('limit', { type: () => Int, defaultValue: 10 }) limit: number,
|
||||
): Promise<User[]> {
|
||||
const fields = graphqlFields(info);
|
||||
const projection = this.usersService.buildProjection(fields);
|
||||
return this.usersService.findAll(projection, skip, limit);
|
||||
@Query(() => UsersListResponse, { name: "users" })
|
||||
async getUsers(@Info() info: GraphQLResolveInfo, @Args('input') input: ListArguments): Promise<UsersListResponse> {
|
||||
const fields = graphqlFields(info); const projection = this.usersService.buildProjection(fields?.data); const { skip, limit, sort, filters } = input;
|
||||
return await this.usersService.findAll(projection, skip, limit, sort, filters);
|
||||
}
|
||||
|
||||
@Query(() => User, { name: 'user', nullable: true })
|
||||
@@ -29,8 +25,6 @@ export class UsersResolver {
|
||||
}
|
||||
|
||||
@Mutation(() => User, { name: 'createUser' })
|
||||
async createUser(@Args('input') input: CreateUserInput): Promise<User> {
|
||||
return this.usersService.create(input);
|
||||
}
|
||||
async createUser(@Args('input') input: CreateUserInput): Promise<User> { return this.usersService.create(input) }
|
||||
|
||||
}
|
||||
|
||||
@@ -3,18 +3,26 @@ import { InjectModel } from '@nestjs/mongoose';
|
||||
import { Types, Model } from 'mongoose';
|
||||
import { User, UserDocument } from '@/models/user.model';
|
||||
import { CreateUserInput } from './dto/create-user.input';
|
||||
import { UsersListResponse } from '@/people/dto/list-result.response';
|
||||
|
||||
@Injectable()
|
||||
export class UsersService {
|
||||
|
||||
constructor(@InjectModel(User.name) private readonly userModel: Model<UserDocument>) { }
|
||||
|
||||
async findAll(projection?: any, skip: number = 0, limit: number = 10): Promise<UserDocument[]> { return this.userModel.find({}, projection, { lean: false }).skip(skip).limit(limit).exec() }
|
||||
async findAll(projection: any, skip: number, limit: number, sort?: Record<string, 1 | -1>, filters?: Record<string, any>): Promise<UsersListResponse> {
|
||||
const query: any = {}; if (filters && Object.keys(filters).length > 0) { Object.assign(query, filters) };
|
||||
const totalCount = await this.userModel.countDocuments(query).exec();
|
||||
const data = await this.userModel.find(query, projection, { lean: true }).skip(skip).limit(limit).sort(sort).exec()
|
||||
return { data, totalCount };
|
||||
}
|
||||
|
||||
async findById(id: Types.ObjectId, projection?: any): Promise<UserDocument | null> { return this.userModel.findById(id, projection, { lean: false }).populate({ path: 'person', select: projection?.person }).exec() }
|
||||
|
||||
async create(input: CreateUserInput): Promise<UserDocument> { const user = new this.userModel(input); return user.save() }
|
||||
|
||||
buildProjection(fields: Record<string, any>): any { const projection: any = {}; for (const key in fields) { projection[key] = 1 }; return projection }
|
||||
buildProjection(fields: Record<string, any>): Record<string, 1> {
|
||||
const projection: Record<string, 1> = {}; for (const key in fields) { projection[key] = 1 }; console.dir({ fields, projection }, { depth: null }); return projection
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user