diff --git a/backend/src/models/base.model.ts b/backend/src/models/base.model.ts index b6cae87..a0ea37c 100644 --- a/backend/src/models/base.model.ts +++ b/backend/src/models/base.model.ts @@ -1,49 +1,76 @@ import { Prop } from '@nestjs/mongoose'; import { randomUUID } from 'crypto'; +import { Field } from '@nestjs/graphql'; +import { ObjectType } from '@nestjs/graphql'; +@ObjectType({ isAbstract: true }) export class Base { + + @Field() @Prop({ default: randomUUID, unique: true }) uuid: string; + @Field() + @Prop({ default: () => new Date(Date.now()) }) + createdAt: Date; + + @Field() + @Prop({ default: () => new Date(Date.now()) }) + updatedAt: Date; + + @Field() @Prop({ default: () => new Date(Date.now()) }) expiryStarts: Date; + @Field() @Prop({ default: () => new Date('2099-12-31') }) expiryEnds: Date; + @Field() @Prop({ default: false }) isConfirmed: boolean; + @Field() @Prop({ default: false }) deleted: boolean; + @Field() @Prop({ default: true }) active: boolean; + @Field() @Prop({ default: randomUUID }) crypUuId: string; + @Field() @Prop({ default: randomUUID }) createdCredentialsToken: string; + @Field() @Prop({ default: randomUUID }) updatedCredentialsToken: string; + @Field() @Prop({ default: randomUUID }) confirmedCredentialsToken: string; + @Field() @Prop({ default: false }) isNotificationSend: boolean; + @Field() @Prop({ default: false }) isEmailSend: boolean; + @Field() @Prop({ default: 0 }) refInt: number; + @Field() @Prop({ default: randomUUID }) refId: string; + @Field() @Prop({ default: 0 }) replicationId: number; } diff --git a/backend/src/models/user.model.ts b/backend/src/models/user.model.ts index 848dabe..67973b3 100644 --- a/backend/src/models/user.model.ts +++ b/backend/src/models/user.model.ts @@ -72,9 +72,6 @@ export class User extends Base { @Prop({ type: Types.ObjectId, ref: Person.name, required: true }) person: Types.ObjectId; - @Field(() => ID, { nullable: true }) - @Prop({ type: Types.ObjectId, ref: UserType.name }) - type?: Types.ObjectId; } export type UserDocument = User & Document; diff --git a/backend/src/people/people.service.ts b/backend/src/people/people.service.ts index 9996685..6f90532 100644 --- a/backend/src/people/people.service.ts +++ b/backend/src/people/people.service.ts @@ -12,11 +12,11 @@ export class PeopleService { ) { } async findAll(projection?: any): Promise { - return this.personModel.find({}, projection, { lean: false }).populate({ path: 'person', select: projection?.person }).exec(); + return this.personModel.find({}, projection, { lean: false }).exec(); } async findById(id: Types.ObjectId, projection?: any): Promise { - return this.personModel.findById(id, projection, { lean: false }).populate({ path: 'person', select: projection?.person }).exec(); + return this.personModel.findById(id, projection, { lean: false }).exec(); } async create(input: CreatePersonInput): Promise { diff --git a/backend/src/people/queries.graphql b/backend/src/people/queries.graphql new file mode 100644 index 0000000..5564ee8 --- /dev/null +++ b/backend/src/people/queries.graphql @@ -0,0 +1,53 @@ +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 + } +} \ No newline at end of file diff --git a/backend/src/users/queries.graphql b/backend/src/users/queries.graphql new file mode 100644 index 0000000..227ddff --- /dev/null +++ b/backend/src/users/queries.graphql @@ -0,0 +1,30 @@ +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 + } +} + diff --git a/backend/src/users/users.resolver.ts b/backend/src/users/users.resolver.ts index 19f8e88..81f4c0b 100644 --- a/backend/src/users/users.resolver.ts +++ b/backend/src/users/users.resolver.ts @@ -1,4 +1,4 @@ -import { Resolver, Query, Args, ID, Info, Mutation } from '@nestjs/graphql'; +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'; @@ -11,9 +11,16 @@ export class UsersResolver { constructor(private readonly usersService: UsersService) { } + // Add pagination skip and limit arguments @Query(() => [User], { name: 'users' }) - async getUsers(@Info() info: GraphQLResolveInfo): Promise { - const fields = graphqlFields(info); const projection = this.usersService.buildProjection(fields); return this.usersService.findAll(projection); + async getUsers( + @Info() info: GraphQLResolveInfo, + @Args('skip', { type: () => Int, defaultValue: 0 }) skip: number, + @Args('limit', { type: () => Int, defaultValue: 10 }) limit: number, + ): Promise { + const fields = graphqlFields(info); + const projection = this.usersService.buildProjection(fields); + return this.usersService.findAll(projection, skip, limit); } @Query(() => User, { name: 'user', nullable: true }) diff --git a/backend/src/users/users.service.ts b/backend/src/users/users.service.ts index 5742dbf..0c9ec5e 100644 --- a/backend/src/users/users.service.ts +++ b/backend/src/users/users.service.ts @@ -7,29 +7,14 @@ import { CreateUserInput } from './dto/create-user.input'; @Injectable() export class UsersService { - constructor( - @InjectModel(User.name) private readonly userModel: Model - ) { } + constructor(@InjectModel(User.name) private readonly userModel: Model) { } - async findAll(projection?: any): Promise { - return this.userModel.find({}, projection, { lean: false }).populate({ path: 'person', select: projection?.person }).exec(); - } + async findAll(projection?: any, skip: number = 0, limit: number = 10): Promise { return this.userModel.find({}, projection, { lean: false }).skip(skip).limit(limit).exec() } - async findById(id: Types.ObjectId, projection?: any): Promise { - return this.userModel.findById(id, projection, { lean: false }).populate({ path: 'person', select: projection?.person }).exec(); - } + async findById(id: Types.ObjectId, projection?: any): Promise { return this.userModel.findById(id, projection, { lean: false }).populate({ path: 'person', select: projection?.person }).exec() } - async create(input: CreateUserInput): Promise { - const user = new this.userModel(input); - return user.save(); - } + async create(input: CreateUserInput): Promise { const user = new this.userModel(input); return user.save() } + + buildProjection(fields: Record): any { const projection: any = {}; for (const key in fields) { projection[key] = 1 }; return projection } - buildProjection(fields: Record): any { - const projection: any = {}; - for (const key in fields) { - if (key === 'person' && typeof fields[key] === 'object') { for (const subField of Object.keys(fields[key])) { projection[`person.${subField}`] = 1 } } - else { projection[key] = 1 } - } - return projection; - } } diff --git a/frontend/README.md b/frontend/README.md index e215bc4..aa24e9a 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -34,3 +34,5 @@ You can check out [the Next.js GitHub repository](https://github.com/vercel/next The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details. + +new Date('2025-11-14T18:21:35.212Z').toLocaleString("en-US", { timeZone: "Europe/Istanbul", hour12: false, year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit" });