Procházet zdrojové kódy

feat: Add minified users view-based model

Owen Diffey před 1 rokem
rodič
revize
c917263eff

+ 6 - 2
backend/src/modules/DataModule.ts

@@ -244,6 +244,7 @@ export class DataModule extends BaseModule {
 
 		this._models = {
 			abc: await this._loadModel("abc"),
+			minifiedUsers: await this._loadModel("minifiedUsers"),
 			news: await this._loadModel("news"),
 			sessions: await this._loadModel("sessions"),
 			stations: await this._loadModel("stations"),
@@ -257,8 +258,11 @@ export class DataModule extends BaseModule {
 	private async _syncModelIndexes() {
 		if (!this._models) throw new Error("Models not loaded");
 
-		await forEachIn(Object.values(this._models), model =>
-			model.syncIndexes()
+		await forEachIn(
+			Object.values(this._models).filter(
+				model => model.schema.get("autoIndex") !== false
+			),
+			model => model.syncIndexes()
 		);
 	}
 

+ 9 - 0
backend/src/modules/DataModule/models/minifiedUsers/jobs/FindById.ts

@@ -0,0 +1,9 @@
+import FindByIdJob from "@/modules/DataModule/FindByIdJob";
+
+export default class FindById extends FindByIdJob {
+	protected static _modelName = "minifiedUsers";
+
+	protected static _hasPermission = true;
+
+	protected async _authorize() {}
+}

+ 28 - 0
backend/src/modules/DataModule/models/minifiedUsers/migrations/170526579600-create-minified-users-view.ts

@@ -0,0 +1,28 @@
+import Migration from "@/modules/DataModule/Migration";
+
+export default class Migration170526579600 extends Migration {
+	async up() {
+		// await this._getDb().createCollection("minifiedUsers", {
+		// 	viewOn: "users",
+		// 	pipeline: [
+		// 		{
+		// 			$project: {
+		// 				_id: 1,
+		// 				name: 1,
+		// 				username: 1,
+		// 				location: 1,
+		// 				bio: 1,
+		// 				role: 1,
+		// 				avatar: 1,
+		// 				createdAt: 1,
+		// 				updatedAt: 1
+		// 			}
+		// 		}
+		// 	]
+		// });
+	}
+
+	async down() {
+		await this._getDb().dropCollection("minifiedUsers");
+	}
+}

+ 72 - 0
backend/src/modules/DataModule/models/minifiedUsers/schema.ts

@@ -0,0 +1,72 @@
+import { Model, Schema, SchemaOptions, SchemaTypes } from "mongoose";
+import { UserSchema } from "../users/schema";
+import { UserRole } from "../users/UserRole";
+import { UserAvatarType } from "../users/UserAvatarType";
+import { UserAvatarColor } from "../users/UserAvatarColor";
+
+export type MinifiedUserSchema = Pick<
+	UserSchema,
+	| "_id"
+	| "name"
+	| "username"
+	| "location"
+	| "bio"
+	| "role"
+	| "avatar"
+	| "createdAt"
+	| "updatedAt"
+>;
+
+export type MinifiedUserModel = Model<MinifiedUserSchema>;
+
+export const schema = new Schema<MinifiedUserSchema, MinifiedUserModel>(
+	{
+		username: {
+			type: SchemaTypes.String,
+			required: true
+		},
+		role: {
+			type: SchemaTypes.String,
+			enum: Object.values(UserRole),
+			required: true
+		},
+		avatar: {
+			type: {
+				type: SchemaTypes.String,
+				enum: Object.values(UserAvatarType),
+				required: true
+			},
+			url: {
+				type: SchemaTypes.String,
+				required: false
+			},
+			color: {
+				type: SchemaTypes.String,
+				enum: Object.values(UserAvatarColor),
+				required: false
+			}
+		},
+		name: {
+			type: SchemaTypes.String,
+			required: true
+		},
+		location: {
+			type: SchemaTypes.String,
+			required: false
+		},
+		bio: {
+			type: SchemaTypes.String,
+			required: false
+		}
+	},
+	{
+		autoCreate: false,
+		autoIndex: false,
+		collection: "minifiedUsers",
+		patchHistory: { enabled: false }
+	}
+);
+
+export type UserSchemaType = typeof schema;
+
+export type UserSchemaOptions = SchemaOptions<UserSchema>;

+ 1 - 1
backend/src/modules/DataModule/models/news/schema.ts

@@ -82,7 +82,7 @@ export const schema = new Schema<NewsSchema, NewsModel, {}, NewsQueryHelpers>(
 		},
 		createdBy: {
 			type: SchemaTypes.ObjectId,
-			ref: "users",
+			ref: "minifiedUsers",
 			required: true
 		}
 	},

+ 1 - 1
backend/src/modules/DataModule/models/stations/schema.ts

@@ -82,7 +82,7 @@ export const schema = new Schema<StationSchema, StationModel>(
 		},
 		owner: {
 			type: SchemaTypes.ObjectId,
-			ref: "users",
+			ref: "minifiedUsers",
 			required: false
 		},
 		djs: [{ type: SchemaTypes.ObjectId, ref: "users" }],

+ 1 - 1
backend/src/modules/EventsModule/jobs/Subscribe.ts

@@ -16,7 +16,7 @@ export default class Subscribe extends Job {
 
 	protected override async _authorize() {
 		const [, moduleName, modelName, event, modelId] =
-			/^([a-z]+)\.([a-z]+)\.([A-z]+)\.?([A-z0-9]+)?$/.exec(
+			/^([a-z]+)\.([A-z]+)\.([A-z]+)\.?([A-z0-9]+)?$/.exec(
 				this._payload.channel
 			) ?? [];
 

+ 1 - 1
backend/src/modules/EventsModule/jobs/SubscribeMany.ts

@@ -23,7 +23,7 @@ export default class SubscribeMany extends Job {
 	protected override async _authorize() {
 		await forEachIn(this._payload.channels, async (channel: string) => {
 			const [, moduleName, modelName, event, modelId] =
-				/^([a-z]+)\.([a-z]+)\.([A-z]+)\.?([A-z0-9]+)?$/.exec(channel) ??
+				/^([a-z]+)\.([A-z]+)\.([A-z]+)\.?([A-z0-9]+)?$/.exec(channel) ??
 				[];
 
 			let permission = `event.${channel}`;

+ 9 - 17
frontend/src/components/UserLink.vue

@@ -1,45 +1,37 @@
 <script setup lang="ts">
 import { ref, onMounted } from "vue";
 import { useWebsocketsStore } from "@/stores/websockets";
-import { useUserAuthStore } from "@/stores/userAuth";
+import { useModels } from "@/composables/useModels";
 
 const props = defineProps({
 	userId: { type: String, default: "" },
 	link: { type: Boolean, default: true }
 });
 
-const user = ref<{ name: string; username?: string }>({
-	name: "Unknown"
-});
+const user = ref();
 
 const { socket } = useWebsocketsStore();
-const { getBasicUser } = useUserAuthStore();
+const { loadModels } = useModels();
 
 onMounted(() => {
-	socket.onConnect(() => {
-		getBasicUser(props.userId).then(basicUser => {
-			if (basicUser) {
-				const { name, username } = basicUser;
-				user.value = {
-					name,
-					username
-				};
-			}
-		});
+	socket.onConnect(async () => {
+		const [model] = await loadModels("minifiedUsers", props.userId);
+
+		if (model) user.value = model;
 	});
 });
 </script>
 
 <template>
 	<router-link
-		v-if="$props.link && user.username"
+		v-if="$props.link && user?.username"
 		:to="{ path: `/u/${user.username}` }"
 		:title="userId"
 	>
 		{{ user.name }}
 	</router-link>
 	<span v-else :title="userId">
-		{{ user.name }}
+		{{ user?.name ?? "Unknown" }}
 	</span>
 </template>
 

+ 4 - 2
frontend/src/pages/Home.vue

@@ -545,7 +545,9 @@ onBeforeUnmount(() => {
 												>
 												<user-link
 													v-else
-													:user-id="element.owner"
+													:user-id="
+														element.owner?._id
+													"
 												/>
 											</span>
 										</p>
@@ -823,7 +825,7 @@ onBeforeUnmount(() => {
 										>
 										<user-link
 											v-else
-											:user-id="station.owner"
+											:user-id="station.owner?._id"
 										/>
 									</span>
 								</p>