universo-platform-3d
103 строки · 2.6 Кб
1import * as mongoose from 'mongoose'
2import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'
3import { ApiProperty } from '@nestjs/swagger'
4import { User } from '../user.schema'
5
6export class UserEntityActionPublicData {
7@ApiProperty() // @ApiProperty must be included to be exposed by the API and flow to FE codegen
8_id = '' // Must not be undefined
9@ApiProperty()
10createdAt = new Date()
11@ApiProperty()
12updatedAt = new Date()
13@ApiProperty()
14actionType = ''
15@ApiProperty()
16entityType = ''
17@ApiProperty()
18forEntity = ''
19@ApiProperty()
20creator = ''
21@ApiProperty()
22rating = 5
23}
24
25export enum ENTITY_TYPE {
26USER = 'USER',
27SPACE = 'SPACE',
28ASSET = 'ASSET'
29}
30
31/**
32* @description Business logic:
33// Assets: Can be liked
34// Spaces: Can be rated
35// User: Can be followed
36// should we remove save, like? Seems like that functionality could be covered by tags/folders.
37*/
38export enum USER_ENTITY_ACTION_TYPE {
39LIKE = 'LIKE',
40RATING = 'RATING',
41SAVE = 'SAVE',
42FOLLOW = 'FOLLOW'
43}
44
45export type UserEntityActionDocument = UserEntityAction & Document
46
47/**
48* @description Likes, ratings, saves, etc. This is a generic class for an action that a user takes on another entity.
49I wasn't feeling certain that we want to call it a "like", so this keeps it general.
50Walkthrough: https://www.loom.com/share/76a6644fd0264ec696281285bcfbd22e
51* @date 2023-06-14 15:31
52*/
53@Schema({
54timestamps: true,
55toJSON: {
56virtuals: true
57}
58})
59export class UserEntityAction {
60@Prop({
61required: true,
62enum: USER_ENTITY_ACTION_TYPE
63})
64actionType: USER_ENTITY_ACTION_TYPE
65
66@Prop({
67required: true,
68enum: ENTITY_TYPE
69})
70@ApiProperty()
71entityType: ENTITY_TYPE
72
73@Prop({
74type: mongoose.Types.ObjectId,
75refPath: 'entityType',
76required: true
77})
78@ApiProperty()
79forEntity: mongoose.Types.ObjectId
80
81@Prop({ type: mongoose.Schema.Types.ObjectId, ref: 'User' })
82@ApiProperty()
83creator: User
84
85@Prop({
86required: function () {
87return this.actionType === USER_ENTITY_ACTION_TYPE.RATING
88},
89min: 1,
90max: 5
91})
92@ApiProperty()
93rating?: number // for rate actions
94}
95
96export const UserEntityActionSchema =
97SchemaFactory.createForClass(UserEntityAction)
98
99// Enforce uniqueness: a user can only take 1 action on an entity with the same actionType (e.g. a user can only like an entity once, BUT could rate it once as well. This allows us flexibility on future business logic, but we for sure know that a user would only be able to like once, rate once, etc.)
100UserEntityActionSchema.index(
101{ creator: 1, forEntity: 1, actionType: 1 },
102{ unique: true }
103)
104