feat: added user-settings schema and user-settings module
This commit is contained in:
@@ -83,6 +83,15 @@ model User {
|
||||
displayName String?
|
||||
email 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 {
|
||||
|
||||
@@ -3,6 +3,7 @@ import { GraphQLModule } from '@nestjs/graphql';
|
||||
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
|
||||
import { UserModule } from './user/user.module';
|
||||
import { GQLComplexityPlugin } from './plugins/GQLComplexityPlugin';
|
||||
import { UserSettingsModule } from './user-settings/user-settings.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@@ -44,6 +45,7 @@ import { GQLComplexityPlugin } from './plugins/GQLComplexityPlugin';
|
||||
driver: ApolloDriver,
|
||||
}),
|
||||
UserModule,
|
||||
UserSettingsModule
|
||||
],
|
||||
providers: [GQLComplexityPlugin],
|
||||
})
|
||||
|
||||
@@ -8,6 +8,12 @@ export const EMAIL_FAILED = 'email/failed' as const;
|
||||
*/
|
||||
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.
|
||||
* (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 TE from 'fp-ts/TaskEither';
|
||||
import * as T from 'fp-ts/Task';
|
||||
import * as E from 'fp-ts/Either';
|
||||
import { User } from './user/user.model';
|
||||
import * as A from 'fp-ts/Array';
|
||||
import { JSON_INVALID } from './errors';
|
||||
|
||||
/**
|
||||
* A workaround to throw an exception in an expression.
|
||||
@@ -28,6 +30,19 @@ export const trace = <T>(val: T) => {
|
||||
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
|
||||
* optional transform function.
|
||||
|
||||
Reference in New Issue
Block a user