feat(server): user metadata (#9650)

* feat(server): user metadata

* add missing method to user mock

* update migration to include cascades

* update sql files

* test: fix e2e

* chore: clean up

---------

Co-authored-by: Daniel Dietzler <mail@ddietzler.dev>
This commit is contained in:
Jason Rasmussen
2024-05-22 08:13:36 -04:00
committed by GitHub
parent a4887bfa7e
commit 06ce8247cc
24 changed files with 267 additions and 126 deletions
@@ -0,0 +1,63 @@
import { UserEntity } from 'src/entities/user.entity';
import { Column, DeepPartial, Entity, ManyToOne, PrimaryColumn } from 'typeorm';
@Entity('user_metadata')
export class UserMetadataEntity<T extends keyof UserMetadata = UserMetadataKey> {
@PrimaryColumn({ type: 'uuid' })
userId!: string;
@ManyToOne(() => UserEntity, (user) => user.metadata, { onUpdate: 'CASCADE', onDelete: 'CASCADE' })
user!: UserEntity;
@PrimaryColumn({ type: 'varchar' })
key!: T;
@Column({ type: 'jsonb' })
value!: UserMetadata[T];
}
export enum UserAvatarColor {
PRIMARY = 'primary',
PINK = 'pink',
RED = 'red',
YELLOW = 'yellow',
BLUE = 'blue',
GREEN = 'green',
PURPLE = 'purple',
ORANGE = 'orange',
GRAY = 'gray',
AMBER = 'amber',
}
export interface UserPreferences {
memories: {
enabled: boolean;
};
avatar: {
color: UserAvatarColor;
};
}
export const getDefaultPreferences = (user: { email: string }): UserPreferences => {
const values = Object.values(UserAvatarColor);
const randomIndex = Math.floor(
[...user.email].map((letter) => letter.codePointAt(0) ?? 0).reduce((a, b) => a + b, 0) % values.length,
);
return {
memories: {
enabled: true,
},
avatar: {
color: values[randomIndex],
},
};
};
export enum UserMetadataKey {
PREFERENCES = 'preferences',
}
export interface UserMetadata extends Record<UserMetadataKey, Record<string, any>> {
[UserMetadataKey.PREFERENCES]: DeepPartial<UserPreferences>;
}