feat: added user-settings schema and user-settings module
This commit is contained in:
@@ -83,6 +83,15 @@ model User {
|
|||||||
displayName String?
|
displayName String?
|
||||||
email String?
|
email String?
|
||||||
photoURL String?
|
photoURL String?
|
||||||
|
settings UserSettings?
|
||||||
|
}
|
||||||
|
|
||||||
|
model UserSettings {
|
||||||
|
id String @id @default(uuid())
|
||||||
|
userUid String @unique
|
||||||
|
user User @relation(fields: [userUid], references: [uid], onDelete: Cascade)
|
||||||
|
properties Json
|
||||||
|
updatedOn DateTime @updatedAt
|
||||||
}
|
}
|
||||||
|
|
||||||
enum TeamMemberRole {
|
enum TeamMemberRole {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { GraphQLModule } from '@nestjs/graphql';
|
|||||||
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
|
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
|
||||||
import { UserModule } from './user/user.module';
|
import { UserModule } from './user/user.module';
|
||||||
import { GQLComplexityPlugin } from './plugins/GQLComplexityPlugin';
|
import { GQLComplexityPlugin } from './plugins/GQLComplexityPlugin';
|
||||||
|
import { UserSettingsModule } from './user-settings/user-settings.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -44,6 +45,7 @@ import { GQLComplexityPlugin } from './plugins/GQLComplexityPlugin';
|
|||||||
driver: ApolloDriver,
|
driver: ApolloDriver,
|
||||||
}),
|
}),
|
||||||
UserModule,
|
UserModule,
|
||||||
|
UserSettingsModule
|
||||||
],
|
],
|
||||||
providers: [GQLComplexityPlugin],
|
providers: [GQLComplexityPlugin],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -8,6 +8,12 @@ export const EMAIL_FAILED = 'email/failed' as const;
|
|||||||
*/
|
*/
|
||||||
export const AUTH_FAIL = 'auth/fail';
|
export const AUTH_FAIL = 'auth/fail';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalid JSON
|
||||||
|
* (Utils)
|
||||||
|
*/
|
||||||
|
export const JSON_INVALID = 'json_invalid';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tried to delete an user data document from fb firestore but failed.
|
* Tried to delete an user data document from fb firestore but failed.
|
||||||
* (FirebaseService)
|
* (FirebaseService)
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import { Field, ID, ObjectType } from '@nestjs/graphql';
|
||||||
|
|
||||||
|
@ObjectType()
|
||||||
|
export class UserSettings {
|
||||||
|
@Field(() => ID, {
|
||||||
|
description: 'ID of the User Settings',
|
||||||
|
})
|
||||||
|
id: string;
|
||||||
|
|
||||||
|
@Field(() => ID, {
|
||||||
|
description: 'ID of the user this settings belongs to',
|
||||||
|
})
|
||||||
|
userUid: string;
|
||||||
|
|
||||||
|
@Field({
|
||||||
|
description: 'All properties present in the settings',
|
||||||
|
})
|
||||||
|
properties: string; // JSON string of the properties object (format:[{ key: "background", value: "system" }, ...] ) which will be received from the client
|
||||||
|
|
||||||
|
@Field({
|
||||||
|
description: 'Last updated date-time of the settings',
|
||||||
|
})
|
||||||
|
updatedOn: Date;
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { PrismaModule } from 'src/prisma/prisma.module';
|
||||||
|
import { PubSubModule } from 'src/pubsub/pubsub.module';
|
||||||
|
import { UserSettingsResolver } from './user-settings.resolver';
|
||||||
|
import { UserSettingsService } from './user-settings.service';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [PrismaModule, PubSubModule],
|
||||||
|
providers: [UserSettingsResolver, UserSettingsService],
|
||||||
|
})
|
||||||
|
export class UserSettingsModule {}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
import { UseGuards } from '@nestjs/common';
|
||||||
|
import { Args, Mutation, Resolver } from '@nestjs/graphql';
|
||||||
|
import { GqlUser } from 'src/decorators/gql-user.decorator';
|
||||||
|
import { GqlAuthGuard } from 'src/guards/gql-auth.guard';
|
||||||
|
import { User } from 'src/user/user.model';
|
||||||
|
import * as E from 'fp-ts/Either';
|
||||||
|
import { throwErr } from 'src/utils';
|
||||||
|
import { UserSettings } from './user-settings.model';
|
||||||
|
import { UserSettingsService } from './user-settings.service';
|
||||||
|
|
||||||
|
@Resolver()
|
||||||
|
export class UserSettingsResolver {
|
||||||
|
constructor(private readonly userSettingsService: UserSettingsService) {}
|
||||||
|
|
||||||
|
/* Mutations */
|
||||||
|
|
||||||
|
@Mutation(() => UserSettings, {
|
||||||
|
description: 'Creates a new user settings for given user',
|
||||||
|
})
|
||||||
|
@UseGuards(GqlAuthGuard)
|
||||||
|
async createUserSettings(
|
||||||
|
@GqlUser() user: User,
|
||||||
|
@Args({
|
||||||
|
name: 'properties',
|
||||||
|
description: 'JSON string of properties object',
|
||||||
|
})
|
||||||
|
properties: string,
|
||||||
|
) {
|
||||||
|
const userSettings = await this.userSettingsService.createUserSettings(
|
||||||
|
user,
|
||||||
|
properties,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (E.isLeft(userSettings)) throwErr(userSettings.left);
|
||||||
|
return userSettings.right;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Subscriptions */
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { PrismaService } from 'src/prisma/prisma.service';
|
||||||
|
import { PubSubService } from 'src/pubsub/pubsub.service';
|
||||||
|
import { User } from 'src/user/user.model';
|
||||||
|
import * as E from 'fp-ts/Either';
|
||||||
|
import { stringToJson } from 'src/utils';
|
||||||
|
import { UserSettings } from './user-settings.model';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class UserSettingsService {
|
||||||
|
constructor(
|
||||||
|
private readonly prisma: PrismaService,
|
||||||
|
private readonly pubsub: PubSubService,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async createUserSettings(user: User, properties: string) {
|
||||||
|
const jsonProperties = stringToJson(properties);
|
||||||
|
if (E.isLeft(jsonProperties)) return E.left(jsonProperties.left);
|
||||||
|
|
||||||
|
const dbUserSettings = await this.prisma.userSettings.create({
|
||||||
|
data: {
|
||||||
|
properties: jsonProperties.right,
|
||||||
|
userUid: user.uid,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const userSettings: UserSettings = {
|
||||||
|
id: dbUserSettings.id,
|
||||||
|
userUid: dbUserSettings.userUid,
|
||||||
|
properties,
|
||||||
|
updatedOn: dbUserSettings.updatedOn,
|
||||||
|
};
|
||||||
|
|
||||||
|
return E.right(userSettings);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,8 +4,10 @@ import { pipe } from 'fp-ts/lib/function';
|
|||||||
import * as O from 'fp-ts/Option';
|
import * as O from 'fp-ts/Option';
|
||||||
import * as TE from 'fp-ts/TaskEither';
|
import * as TE from 'fp-ts/TaskEither';
|
||||||
import * as T from 'fp-ts/Task';
|
import * as T from 'fp-ts/Task';
|
||||||
|
import * as E from 'fp-ts/Either';
|
||||||
import { User } from './user/user.model';
|
import { User } from './user/user.model';
|
||||||
import * as A from 'fp-ts/Array';
|
import * as A from 'fp-ts/Array';
|
||||||
|
import { JSON_INVALID } from './errors';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A workaround to throw an exception in an expression.
|
* A workaround to throw an exception in an expression.
|
||||||
@@ -28,6 +30,19 @@ export const trace = <T>(val: T) => {
|
|||||||
return val;
|
return val;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* String to JSON parser
|
||||||
|
* @param {str} str The string to parse
|
||||||
|
* @returns {E.Right<T> | E.Left<"json_invalid">} An Either of the parsed JSON
|
||||||
|
*/
|
||||||
|
export function stringToJson<T>(str: string): E.Right<T | any> | E.Left<string> {
|
||||||
|
try {
|
||||||
|
return E.right(JSON.parse(str));
|
||||||
|
} catch (err) {
|
||||||
|
return E.left(JSON_INVALID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Similar to `trace` but allows for labels and also an
|
* Similar to `trace` but allows for labels and also an
|
||||||
* optional transform function.
|
* optional transform function.
|
||||||
|
|||||||
Reference in New Issue
Block a user