Browse Source

refactor: Split up model schema files

Owen Diffey 2 years ago
parent
commit
d046b239ac
37 changed files with 384 additions and 367 deletions
  1. 3 3
      backend/src/JobContext.ts
  2. 0 0
      backend/src/models/Migration.ts
  3. 1 1
      backend/src/models/migrations/1620330161000-news-markdown.ts
  4. 2 0
      backend/src/models/permissions/isDj.ts
  5. 1 0
      backend/src/models/permissions/isLoggedIn.ts
  6. 13 0
      backend/src/models/permissions/isOwner.ts
  7. 3 0
      backend/src/models/permissions/isPrivate.ts
  8. 3 0
      backend/src/models/permissions/isPublic.ts
  9. 3 0
      backend/src/models/permissions/isUnlisted.ts
  10. 0 0
      backend/src/models/plugins/documentVersion.ts
  11. 0 0
      backend/src/models/plugins/getData.ts
  12. 1 1
      backend/src/models/schemas/abc/schema.ts
  13. 5 0
      backend/src/models/schemas/news/NewsStatus.ts
  14. 36 0
      backend/src/models/schemas/news/config.ts
  15. 51 0
      backend/src/models/schemas/news/getData.ts
  16. 89 0
      backend/src/models/schemas/news/schema.ts
  17. 2 2
      backend/src/models/schemas/sessions/schema.ts
  18. 4 0
      backend/src/models/schemas/stations/StationAutofillMode.ts
  19. 5 0
      backend/src/models/schemas/stations/StationPrivacy.ts
  20. 4 0
      backend/src/models/schemas/stations/StationRequestsAccess.ts
  21. 7 0
      backend/src/models/schemas/stations/StationTheme.ts
  22. 4 0
      backend/src/models/schemas/stations/StationType.ts
  23. 25 0
      backend/src/models/schemas/stations/config.ts
  24. 57 0
      backend/src/models/schemas/stations/getData.ts
  25. 9 117
      backend/src/models/schemas/stations/schema.ts
  26. 8 0
      backend/src/models/schemas/users/UserAvatarColor.ts
  27. 4 0
      backend/src/models/schemas/users/UserAvatarType.ts
  28. 5 0
      backend/src/models/schemas/users/UserRole.ts
  29. 1 0
      backend/src/models/schemas/users/config.ts
  30. 6 22
      backend/src/models/schemas/users/schema.ts
  31. 4 21
      backend/src/modules/APIModule.ts
  32. 9 9
      backend/src/modules/DataModule.ts
  33. 1 1
      backend/src/permissions.ts
  34. 0 172
      backend/src/schemas/news.ts
  35. 1 1
      backend/src/types/JobOptions.ts
  36. 8 8
      backend/src/types/Models.ts
  37. 9 9
      backend/src/types/Schemas.ts

+ 3 - 3
backend/src/JobContext.ts

@@ -3,10 +3,10 @@ import BaseModule from "./BaseModule";
 import Job from "./Job";
 import Job from "./Job";
 import JobQueue from "./JobQueue";
 import JobQueue from "./JobQueue";
 import { Log } from "./LogBook";
 import { Log } from "./LogBook";
-import { SessionSchema } from "./schemas/session";
+import { SessionSchema } from "./models/schemas/session";
 import { JobOptions } from "./types/JobOptions";
 import { JobOptions } from "./types/JobOptions";
 import { Jobs, Modules } from "./types/Modules";
 import { Jobs, Modules } from "./types/Modules";
-import { UserSchema } from "./schemas/user";
+import { UserSchema } from "./models/schemas/user";
 import { Models } from "./types/Models";
 import { Models } from "./types/Models";
 
 
 export default class JobContext {
 export default class JobContext {
@@ -98,7 +98,7 @@ export default class JobContext {
 
 
 		if (this._user && !refresh) return this._user;
 		if (this._user && !refresh) return this._user;
 
 
-		const User = await this.getModel("user");
+		const User = await this.getModel("users");
 
 
 		this._user = await User.findById(this._session.userId);
 		this._user = await User.findById(this._session.userId);
 
 

+ 0 - 0
backend/src/Migration.ts → backend/src/models/Migration.ts


+ 1 - 1
backend/src/schemas/migrations/1620330161000-news-markdown.ts → backend/src/models/migrations/1620330161000-news-markdown.ts

@@ -1,4 +1,4 @@
-import Migration from "../../Migration";
+import Migration from "../Migration";
 
 
 export default class Migration1620330161000 extends Migration {
 export default class Migration1620330161000 extends Migration {
 	async up() {
 	async up() {

+ 2 - 0
backend/src/models/permissions/isDj.ts

@@ -0,0 +1,2 @@
+export default (model, user) =>
+	model && user && model.djs.contains(user._id.toString());

+ 1 - 0
backend/src/models/permissions/isLoggedIn.ts

@@ -0,0 +1 @@
+export default (model, user) => !!user;

+ 13 - 0
backend/src/models/permissions/isOwner.ts

@@ -0,0 +1,13 @@
+export default (model, user) => {
+	if (!(user && model)) return false;
+
+	let ownerAttribute;
+
+	if (model.schema.path("createdBy")) ownerAttribute = "createdBy";
+	else if (model.schema.path("owner")) ownerAttribute = "owner";
+
+	if (ownerAttribute)
+		return model[ownerAttribute].toString() === user._id.toString();
+
+	return false;
+};

+ 3 - 0
backend/src/models/permissions/isPrivate.ts

@@ -0,0 +1,3 @@
+import { StationPrivacy } from "../schemas/stations/StationPrivacy";
+
+export default model => model && model.privacy === StationPrivacy.PRIVATE;

+ 3 - 0
backend/src/models/permissions/isPublic.ts

@@ -0,0 +1,3 @@
+import { StationPrivacy } from "../schemas/stations/StationPrivacy";
+
+export default model => model && model.privacy === StationPrivacy.PUBLIC;

+ 3 - 0
backend/src/models/permissions/isUnlisted.ts

@@ -0,0 +1,3 @@
+import { StationPrivacy } from "../schemas/stations/StationPrivacy";
+
+export default model => model && model.privacy === StationPrivacy.UNLISTED;

+ 0 - 0
backend/src/schemas/plugins/documentVersion.ts → backend/src/models/plugins/documentVersion.ts


+ 0 - 0
backend/src/schemas/plugins/getData.ts → backend/src/models/plugins/getData.ts


+ 1 - 1
backend/src/schemas/abc.ts → backend/src/models/schemas/abc/schema.ts

@@ -1,5 +1,5 @@
 import { Model, Schema, SchemaTypes, Types } from "mongoose";
 import { Model, Schema, SchemaTypes, Types } from "mongoose";
-import { BaseSchema, TimestampsSchema } from "../types/Schemas";
+import { BaseSchema, TimestampsSchema } from "../../../types/Schemas";
 
 
 export interface AbcSchema extends Omit<BaseSchema, keyof TimestampsSchema> {
 export interface AbcSchema extends Omit<BaseSchema, keyof TimestampsSchema> {
 	name: string;
 	name: string;

+ 5 - 0
backend/src/models/schemas/news/NewsStatus.ts

@@ -0,0 +1,5 @@
+export enum NewsStatus {
+	DRAFT = "draft",
+	PUBLISHED = "published",
+	ARCHIVED = "archived"
+}

+ 36 - 0
backend/src/models/schemas/news/config.ts

@@ -0,0 +1,36 @@
+import JobContext from "../../../JobContext";
+import { NewsStatus } from "./NewsStatus";
+import getData from "./getData";
+
+export default {
+	documentVersion: 3,
+	query: {
+		published() {
+			return this.where({ status: NewsStatus.PUBLISHED });
+		},
+		newest(showToNewUsers = false) {
+			const query = this.published().sort({ createdAt: "desc" });
+			if (showToNewUsers)
+				return query.where({ showToNewUsers: !!showToNewUsers });
+			return query;
+		}
+	},
+	jobConfig: {
+		published: {
+			async method() {
+				return this.find().published();
+			},
+			hasPermission: true
+		},
+		newest: {
+			async method(
+				context: JobContext,
+				payload?: { showToNewUsers: boolean }
+			) {
+				return this.find().newest(payload?.showToNewUsers);
+			},
+			hasPermission: true
+		}
+	},
+	getData
+};

+ 51 - 0
backend/src/models/schemas/news/getData.ts

@@ -0,0 +1,51 @@
+export default {
+	enabled: true,
+	specialProperties: {
+		createdBy: [
+			{
+				$addFields: {
+					createdByOID: {
+						$convert: {
+							input: "$createdBy",
+							to: "objectId",
+							onError: "unknown",
+							onNull: "unknown"
+						}
+					}
+				}
+			},
+			{
+				$lookup: {
+					from: "users",
+					localField: "createdByOID",
+					foreignField: "_id",
+					as: "createdByUser"
+				}
+			},
+			{
+				$unwind: {
+					path: "$createdByUser",
+					preserveNullAndEmptyArrays: true
+				}
+			},
+			{
+				$addFields: {
+					createdByUsername: {
+						$ifNull: ["$createdByUser.username", "unknown"]
+					}
+				}
+			},
+			{
+				$project: {
+					createdByOID: 0,
+					createdByUser: 0
+				}
+			}
+		]
+	},
+	specialQueries: {
+		createdBy: newQuery => ({
+			$or: [newQuery, { createdByUsername: newQuery.createdBy }]
+		})
+	}
+};

+ 89 - 0
backend/src/models/schemas/news/schema.ts

@@ -0,0 +1,89 @@
+import {
+	HydratedDocument,
+	Model,
+	QueryWithHelpers,
+	Schema,
+	SchemaTypes,
+	Types
+} from "mongoose";
+import { GetData } from "../../plugins/getData";
+import { BaseSchema } from "../../../types/Schemas";
+import JobContext from "../../../JobContext";
+import { NewsStatus } from "./NewsStatus";
+import config from "./config";
+
+export interface NewsSchema extends BaseSchema {
+	title: string;
+	markdown: string;
+	status: NewsStatus;
+	showToNewUsers: boolean;
+	createdBy: Types.ObjectId;
+}
+
+export interface NewsQueryHelpers {
+	published(
+		this: QueryWithHelpers<
+			any,
+			HydratedDocument<NewsSchema>,
+			NewsQueryHelpers
+		>,
+		published?: boolean
+	): QueryWithHelpers<
+		HydratedDocument<NewsSchema>[],
+		HydratedDocument<NewsSchema>,
+		NewsQueryHelpers
+	>;
+	newest(
+		this: QueryWithHelpers<
+			any,
+			HydratedDocument<NewsSchema>,
+			NewsQueryHelpers
+		>,
+		showToNewUsers?: boolean
+	): QueryWithHelpers<
+		HydratedDocument<NewsSchema>[],
+		HydratedDocument<NewsSchema>,
+		NewsQueryHelpers
+	>;
+}
+
+export interface NewsModel
+	extends Model<NewsSchema, NewsQueryHelpers>,
+		GetData {
+	published: (context: JobContext) => Promise<NewsSchema[]>;
+	newest: (
+		context: JobContext,
+		payload: { showToNewUsers?: boolean }
+	) => Promise<NewsSchema[]>;
+}
+
+export const schema = new Schema<NewsSchema, NewsModel, {}, NewsQueryHelpers>(
+	{
+		title: {
+			type: SchemaTypes.String,
+			required: true
+		},
+		markdown: {
+			type: SchemaTypes.String,
+			required: true
+		},
+		status: {
+			type: SchemaTypes.String,
+			enum: Object.values(NewsStatus),
+			default: NewsStatus.DRAFT,
+			required: true
+		},
+		showToNewUsers: {
+			type: SchemaTypes.Boolean,
+			default: false,
+			required: true
+		},
+		createdBy: {
+			type: SchemaTypes.ObjectId,
+			required: true
+		}
+	},
+	config
+);
+
+export type NewsSchemaType = typeof schema;

+ 2 - 2
backend/src/schemas/session.ts → backend/src/models/schemas/sessions/schema.ts

@@ -1,5 +1,5 @@
 import { Model, Schema, SchemaTypes, Types } from "mongoose";
 import { Model, Schema, SchemaTypes, Types } from "mongoose";
-import { BaseSchema } from "../types/Schemas";
+import { BaseSchema } from "../../../types/Schemas";
 
 
 export interface SessionSchema extends BaseSchema {
 export interface SessionSchema extends BaseSchema {
 	userId: Types.ObjectId;
 	userId: Types.ObjectId;
@@ -10,7 +10,7 @@ export type SessionModel = Model<SessionSchema>;
 export const schema = new Schema<SessionSchema, SessionModel>({
 export const schema = new Schema<SessionSchema, SessionModel>({
 	userId: {
 	userId: {
 		type: SchemaTypes.ObjectId,
 		type: SchemaTypes.ObjectId,
-		ref: "user",
+		ref: "users",
 		required: true
 		required: true
 	}
 	}
 });
 });

+ 4 - 0
backend/src/models/schemas/stations/StationAutofillMode.ts

@@ -0,0 +1,4 @@
+export enum StationAutofillMode {
+	RANDOM = "random",
+	SEQUENTIAL = "sequential"
+}

+ 5 - 0
backend/src/models/schemas/stations/StationPrivacy.ts

@@ -0,0 +1,5 @@
+export enum StationPrivacy {
+	PUBLIC = "public",
+	UNLISTED = "unlisted",
+	PRIVATE = "private"
+}

+ 4 - 0
backend/src/models/schemas/stations/StationRequestsAccess.ts

@@ -0,0 +1,4 @@
+export enum StationRequestsAccess {
+	OWNER = "owner",
+	USER = "user"
+}

+ 7 - 0
backend/src/models/schemas/stations/StationTheme.ts

@@ -0,0 +1,7 @@
+export enum StationTheme {
+	BLUE = "blue",
+	PURPLE = "purple",
+	TEAL = "teal",
+	ORANGE = "orange",
+	RED = "red"
+}

+ 4 - 0
backend/src/models/schemas/stations/StationType.ts

@@ -0,0 +1,4 @@
+export enum StationType {
+	OFFICIAL = "official",
+	COMMUNITY = "community"
+}

+ 25 - 0
backend/src/models/schemas/stations/config.ts

@@ -0,0 +1,25 @@
+import isDj from "../../permissions/isDj";
+import isPublic from "../../permissions/isPublic";
+import isUnlisted from "../../permissions/isUnlisted";
+import isLoggedIn from "../../permissions/isLoggedIn";
+import isOwner from "../../permissions/isOwner";
+import getData from "./getData";
+
+export default {
+	documentVersion: 10,
+	jobConfig: {
+		create: {
+			hasPermission: isLoggedIn
+		},
+		findById: {
+			hasPermission: [isOwner, isDj, isPublic, isUnlisted]
+		},
+		updateById: {
+			hasPermission: [isOwner, isDj]
+		},
+		deleteById: {
+			hasPermission: [isOwner, isDj]
+		}
+	},
+	getData
+};

+ 57 - 0
backend/src/models/schemas/stations/getData.ts

@@ -0,0 +1,57 @@
+export default {
+	enabled: true,
+	specialProperties: {
+		owner: [
+			{
+				$addFields: {
+					ownerOID: {
+						$convert: {
+							input: "$owner",
+							to: "objectId",
+							onError: "unknown",
+							onNull: "unknown"
+						}
+					}
+				}
+			},
+			{
+				$lookup: {
+					from: "users",
+					localField: "ownerOID",
+					foreignField: "_id",
+					as: "ownerUser"
+				}
+			},
+			{
+				$unwind: {
+					path: "$ownerUser",
+					preserveNullAndEmptyArrays: true
+				}
+			},
+			{
+				$addFields: {
+					ownerUsername: {
+						$cond: [
+							{ $eq: [{ $type: "$owner" }, "string"] },
+							{
+								$ifNull: ["$ownerUser.username", "unknown"]
+							},
+							"none"
+						]
+					}
+				}
+			},
+			{
+				$project: {
+					ownerOID: 0,
+					ownerUser: 0
+				}
+			}
+		]
+	},
+	specialQueries: {
+		owner: newQuery => ({
+			$or: [newQuery, { ownerUsername: newQuery.owner }]
+		})
+	}
+};

+ 9 - 117
backend/src/schemas/station.ts → backend/src/models/schemas/stations/schema.ts

@@ -1,35 +1,12 @@
 import { Model, Schema, SchemaTypes, Types } from "mongoose";
 import { Model, Schema, SchemaTypes, Types } from "mongoose";
-import { GetData } from "./plugins/getData";
-import { BaseSchema } from "../types/Schemas";
-
-export enum StationType {
-	OFFICIAL = "official",
-	COMMUNITY = "community"
-}
-
-export enum StationPrivacy {
-	PUBLIC = "public",
-	UNLISTED = "unlisted",
-	PRIVATE = "private"
-}
-
-export enum StationTheme {
-	BLUE = "blue",
-	PURPLE = "purple",
-	TEAL = "teal",
-	ORANGE = "orange",
-	RED = "red"
-}
-
-export enum StationRequestsAccess {
-	OWNER = "owner",
-	USER = "user"
-}
-
-export enum StationAutofillMode {
-	RANDOM = "random",
-	SEQUENTIAL = "sequential"
-}
+import { GetData } from "../../plugins/getData";
+import { BaseSchema } from "../../../types/Schemas";
+import { StationType } from "./StationType";
+import { StationPrivacy } from "./StationPrivacy";
+import { StationTheme } from "./StationTheme";
+import { StationRequestsAccess } from "./StationRequestsAccess";
+import { StationAutofillMode } from "./StationAutofillMode";
+import config from "./config";
 
 
 export interface StationSchema extends BaseSchema {
 export interface StationSchema extends BaseSchema {
 	type: StationType;
 	type: StationType;
@@ -64,13 +41,6 @@ export interface StationSchema extends BaseSchema {
 
 
 export interface StationModel extends Model<StationSchema>, GetData {}
 export interface StationModel extends Model<StationSchema>, GetData {}
 
 
-const isDj = (model, user) =>
-	model && user && model.djs.contains(user._id.toString());
-
-const isPublic = model => model && model.privacy === StationPrivacy.PUBLIC;
-const isUnlisted = model => model && model.privacy === StationPrivacy.UNLISTED;
-const isPrivate = model => model && model.privacy === StationPrivacy.PRIVATE;
-
 export const schema = new Schema<StationSchema, StationModel>(
 export const schema = new Schema<StationSchema, StationModel>(
 	{
 	{
 		type: {
 		type: {
@@ -180,85 +150,7 @@ export const schema = new Schema<StationSchema, StationModel>(
 			}
 			}
 		}
 		}
 	},
 	},
-	{
-		// @ts-ignore
-		documentVersion: 10,
-		jobConfig: {
-			create: {
-				hasPermission: "loggedIn"
-			},
-			findById: {
-				hasPermission: ["owner", isDj, isPublic, isUnlisted]
-			},
-			updateById: {
-				hasPermission: ["owner", isDj]
-			},
-			deleteById: {
-				hasPermission: ["owner", isDj]
-			}
-		},
-		// @ts-ignore
-		getData: {
-			enabled: true,
-			specialProperties: {
-				owner: [
-					{
-						$addFields: {
-							ownerOID: {
-								$convert: {
-									input: "$owner",
-									to: "objectId",
-									onError: "unknown",
-									onNull: "unknown"
-								}
-							}
-						}
-					},
-					{
-						$lookup: {
-							from: "users",
-							localField: "ownerOID",
-							foreignField: "_id",
-							as: "ownerUser"
-						}
-					},
-					{
-						$unwind: {
-							path: "$ownerUser",
-							preserveNullAndEmptyArrays: true
-						}
-					},
-					{
-						$addFields: {
-							ownerUsername: {
-								$cond: [
-									{ $eq: [{ $type: "$owner" }, "string"] },
-									{
-										$ifNull: [
-											"$ownerUser.username",
-											"unknown"
-										]
-									},
-									"none"
-								]
-							}
-						}
-					},
-					{
-						$project: {
-							ownerOID: 0,
-							ownerUser: 0
-						}
-					}
-				]
-			},
-			specialQueries: {
-				owner: newQuery => ({
-					$or: [newQuery, { ownerUsername: newQuery.owner }]
-				})
-			}
-		}
-	}
+	config
 );
 );
 
 
 export type StationSchemaType = typeof schema;
 export type StationSchemaType = typeof schema;

+ 8 - 0
backend/src/models/schemas/users/UserAvatarColor.ts

@@ -0,0 +1,8 @@
+export enum UserAvatarColor {
+	BLUE = "blue",
+	GREEN = "green",
+	ORANGE = "orange",
+	PURPLE = "purple",
+	RED = "red",
+	TEAL = "teal"
+}

+ 4 - 0
backend/src/models/schemas/users/UserAvatarType.ts

@@ -0,0 +1,4 @@
+export enum UserAvatarType {
+	GRAVATAR = "gravatar",
+	INITIALS = "initials"
+}

+ 5 - 0
backend/src/models/schemas/users/UserRole.ts

@@ -0,0 +1,5 @@
+export enum UserRole {
+	ADMIN = "admin",
+	MODERATOR = "moderator",
+	USER = "user"
+}

+ 1 - 0
backend/src/models/schemas/users/config.ts

@@ -0,0 +1 @@
+export default { documentVersion: 4 };

+ 6 - 22
backend/src/schemas/user.ts → backend/src/models/schemas/users/schema.ts

@@ -1,25 +1,9 @@
 import { Model, Schema, SchemaTypes, Types } from "mongoose";
 import { Model, Schema, SchemaTypes, Types } from "mongoose";
-import { BaseSchema } from "../types/Schemas";
-
-export enum UserRole {
-	ADMIN = "admin",
-	MODERATOR = "moderator",
-	USER = "user"
-}
-
-export enum UserAvatarType {
-	GRAVATAR = "gravatar",
-	INITIALS = "initials"
-}
-
-export enum UserAvatarColor {
-	BLUE = "blue",
-	GREEN = "green",
-	ORANGE = "orange",
-	PURPLE = "purple",
-	RED = "red",
-	TEAL = "teal"
-}
+import { BaseSchema } from "../../../types/Schemas";
+import config from "./config";
+import { UserRole } from "./UserRole";
+import { UserAvatarType } from "./UserAvatarType";
+import { UserAvatarColor } from "./UserAvatarColor";
 
 
 export interface UserSchema extends BaseSchema {
 export interface UserSchema extends BaseSchema {
 	username: string;
 	username: string;
@@ -230,7 +214,7 @@ export const schema = new Schema<UserSchema, UserModel>(
 			}
 			}
 		}
 		}
 	},
 	},
-	{ documentVersion: 4 }
+	config
 );
 );
 
 
 export type UserSchemaType = typeof schema;
 export type UserSchemaType = typeof schema;

+ 4 - 21
backend/src/modules/APIModule.ts

@@ -5,8 +5,8 @@ import JobContext from "../JobContext";
 import BaseModule from "../BaseModule";
 import BaseModule from "../BaseModule";
 import { Jobs, Modules, UniqueMethods } from "../types/Modules";
 import { Jobs, Modules, UniqueMethods } from "../types/Modules";
 import WebSocket from "../WebSocket";
 import WebSocket from "../WebSocket";
-import { UserRole } from "../schemas/user";
-import { StationType } from "../schemas/station";
+import { UserRole } from "../models/schemas/users/UserRole";
+import { StationType } from "../models/schemas/stations/StationType";
 import permissions from "../permissions";
 import permissions from "../permissions";
 import Job from "../Job";
 import Job from "../Job";
 import { Models } from "../types/Models";
 import { Models } from "../types/Models";
@@ -77,7 +77,7 @@ export default class APIModule extends BaseModule {
 	): Promise<ReturnType> {
 	): Promise<ReturnType> {
 		let session;
 		let session;
 		if (sessionId) {
 		if (sessionId) {
-			const Session = await context.getModel("session");
+			const Session = await context.getModel("sessions");
 
 
 			session = await Session.findByIdAndUpdate(sessionId, {
 			session = await Session.findByIdAndUpdate(sessionId, {
 				updatedAt: Date.now()
 				updatedAt: Date.now()
@@ -127,7 +127,7 @@ export default class APIModule extends BaseModule {
 
 
 		let user;
 		let user;
 		if (sessionId) {
 		if (sessionId) {
-			const Session = await context.getModel("session");
+			const Session = await context.getModel("sessions");
 
 
 			const session = await Session.findByIdAndUpdate(sessionId, {
 			const session = await Session.findByIdAndUpdate(sessionId, {
 				updatedAt: Date.now()
 				updatedAt: Date.now()
@@ -257,23 +257,6 @@ export default class APIModule extends BaseModule {
 						async (previous, option) => {
 						async (previous, option) => {
 							if (await previous) return true;
 							if (await previous) return true;
 
 
-							if (option === "loggedIn" && user) return true;
-
-							if (option === "owner" && user && model) {
-								let ownerAttribute;
-
-								if (model.schema.path("createdBy"))
-									ownerAttribute = "createdBy";
-								else if (model.schema.path("owner"))
-									ownerAttribute = "owner";
-
-								if (ownerAttribute)
-									return (
-										model[ownerAttribute].toString() ===
-										user._id.toString()
-									);
-							}
-
 							if (typeof option === "boolean") return option;
 							if (typeof option === "boolean") return option;
 
 
 							if (typeof option === "function")
 							if (typeof option === "function")

+ 9 - 9
backend/src/modules/DataModule.ts

@@ -16,9 +16,9 @@ import BaseModule, { ModuleStatus } from "../BaseModule";
 import { UniqueMethods } from "../types/Modules";
 import { UniqueMethods } from "../types/Modules";
 import { AnyModel, Models } from "../types/Models";
 import { AnyModel, Models } from "../types/Models";
 import { Schemas } from "../types/Schemas";
 import { Schemas } from "../types/Schemas";
-import documentVersionPlugin from "../schemas/plugins/documentVersion";
-import getDataPlugin from "../schemas/plugins/getData";
-import Migration from "../Migration";
+import documentVersionPlugin from "../models/plugins/documentVersion";
+import getDataPlugin from "../models/plugins/getData";
+import Migration from "../models/Migration";
 
 
 /**
 /**
  * Experimental: function to get all nested keys from a MongoDB query object
  * Experimental: function to get all nested keys from a MongoDB query object
@@ -344,7 +344,7 @@ export default class DataModule extends BaseModule {
 		if (!this._mongoConnection) throw new Error("Mongo is not available");
 		if (!this._mongoConnection) throw new Error("Mongo is not available");
 
 
 		const { schema }: { schema: Schemas[ModelName] } = await import(
 		const { schema }: { schema: Schemas[ModelName] } = await import(
-			`../schemas/${modelName.toString()}`
+			`../models/schemas/${modelName.toString()}/schema`
 		);
 		);
 
 
 		schema.plugin(documentVersionPlugin);
 		schema.plugin(documentVersionPlugin);
@@ -385,9 +385,9 @@ export default class DataModule extends BaseModule {
 		this._models = {
 		this._models = {
 			abc: await this._loadModel("abc"),
 			abc: await this._loadModel("abc"),
 			news: await this._loadModel("news"),
 			news: await this._loadModel("news"),
-			session: await this._loadModel("session"),
-			station: await this._loadModel("station"),
-			user: await this._loadModel("user")
+			sessions: await this._loadModel("sessions"),
+			stations: await this._loadModel("stations"),
+			users: await this._loadModel("users")
 		};
 		};
 	}
 	}
 
 
@@ -425,13 +425,13 @@ export default class DataModule extends BaseModule {
 		if (!this._mongoConnection) throw new Error("Mongo is not available");
 		if (!this._mongoConnection) throw new Error("Mongo is not available");
 
 
 		const migrations = await readdir(
 		const migrations = await readdir(
-			path.resolve(__dirname, "../schemas/migrations/")
+			path.resolve(__dirname, "../models/migrations/")
 		);
 		);
 
 
 		return Promise.all(
 		return Promise.all(
 			migrations.map(async migrationFile => {
 			migrations.map(async migrationFile => {
 				const { default: Migrate }: { default: typeof Migration } =
 				const { default: Migrate }: { default: typeof Migration } =
-					await import(`../schemas/migrations/${migrationFile}`);
+					await import(`../models/migrations/${migrationFile}`);
 				return new Migrate(this._mongoConnection as Connection);
 				return new Migrate(this._mongoConnection as Connection);
 			})
 			})
 		);
 		);

+ 1 - 1
backend/src/permissions.ts

@@ -1,5 +1,5 @@
 import config from "config";
 import config from "config";
-import { UserRole } from "./schemas/user";
+import { UserRole } from "./models/schemas/users/UserRole";
 
 
 const temp = {
 const temp = {
 	"data.news.getData": true,
 	"data.news.getData": true,

+ 0 - 172
backend/src/schemas/news.ts

@@ -1,172 +0,0 @@
-import {
-	HydratedDocument,
-	Model,
-	QueryWithHelpers,
-	Schema,
-	SchemaTypes,
-	Types
-} from "mongoose";
-import { GetData } from "./plugins/getData";
-import { BaseSchema } from "../types/Schemas";
-import JobContext from "../JobContext";
-
-export enum NewsStatus {
-	DRAFT = "draft",
-	PUBLISHED = "published",
-	ARCHIVED = "archived"
-}
-
-export interface NewsSchema extends BaseSchema {
-	title: string;
-	markdown: string;
-	status: NewsStatus;
-	showToNewUsers: boolean;
-	createdBy: Types.ObjectId;
-}
-
-export interface NewsQueryHelpers {
-	published(
-		this: QueryWithHelpers<
-			any,
-			HydratedDocument<NewsSchema>,
-			NewsQueryHelpers
-		>,
-		published?: boolean
-	): QueryWithHelpers<
-		HydratedDocument<NewsSchema>[],
-		HydratedDocument<NewsSchema>,
-		NewsQueryHelpers
-	>;
-	newest(
-		this: QueryWithHelpers<
-			any,
-			HydratedDocument<NewsSchema>,
-			NewsQueryHelpers
-		>,
-		showToNewUsers?: boolean
-	): QueryWithHelpers<
-		HydratedDocument<NewsSchema>[],
-		HydratedDocument<NewsSchema>,
-		NewsQueryHelpers
-	>;
-}
-
-export interface NewsModel
-	extends Model<NewsSchema, NewsQueryHelpers>,
-		GetData {
-	published: (context: JobContext) => Promise<NewsSchema[]>;
-	newest: (
-		context: JobContext,
-		payload: { showToNewUsers?: boolean }
-	) => Promise<NewsSchema[]>;
-}
-
-export const schema = new Schema<NewsSchema, NewsModel, {}, NewsQueryHelpers>(
-	{
-		title: {
-			type: SchemaTypes.String,
-			required: true
-		},
-		markdown: {
-			type: SchemaTypes.String,
-			required: true
-		},
-		status: {
-			type: SchemaTypes.String,
-			enum: Object.values(NewsStatus),
-			default: NewsStatus.DRAFT,
-			required: true
-		},
-		showToNewUsers: {
-			type: SchemaTypes.Boolean,
-			default: false,
-			required: true
-		},
-		createdBy: {
-			type: SchemaTypes.ObjectId,
-			required: true
-		}
-	},
-	{
-		// @ts-ignore
-		documentVersion: 3,
-		query: {
-			published() {
-				return this.where({ status: NewsStatus.PUBLISHED });
-			},
-			newest(showToNewUsers = false) {
-				const query = this.published().sort({ createdAt: "desc" });
-				if (showToNewUsers) return query.where({ showToNewUsers });
-				return query;
-			}
-		},
-		jobConfig: {
-			published: {
-				async method() {
-					return this.find().published();
-				},
-				hasPermission: true
-			},
-			newest: {
-				async method(payload?: { showToNewUsers: boolean }) {
-					return this.find().newest(payload?.showToNewUsers);
-				},
-				hasPermission: true
-			}
-		},
-		// @ts-ignore need to somehow use GetDataSchemaOptions
-		getData: {
-			enabled: true,
-			specialProperties: {
-				createdBy: [
-					{
-						$addFields: {
-							createdByOID: {
-								$convert: {
-									input: "$createdBy",
-									to: "objectId",
-									onError: "unknown",
-									onNull: "unknown"
-								}
-							}
-						}
-					},
-					{
-						$lookup: {
-							from: "users",
-							localField: "createdByOID",
-							foreignField: "_id",
-							as: "createdByUser"
-						}
-					},
-					{
-						$unwind: {
-							path: "$createdByUser",
-							preserveNullAndEmptyArrays: true
-						}
-					},
-					{
-						$addFields: {
-							createdByUsername: {
-								$ifNull: ["$createdByUser.username", "unknown"]
-							}
-						}
-					},
-					{
-						$project: {
-							createdByOID: 0,
-							createdByUser: 0
-						}
-					}
-				]
-			},
-			specialQueries: {
-				createdBy: newQuery => ({
-					$or: [newQuery, { createdByUsername: newQuery.createdBy }]
-				})
-			}
-		}
-	}
-);
-
-export type NewsSchemaType = typeof schema;

+ 1 - 1
backend/src/types/JobOptions.ts

@@ -1,4 +1,4 @@
-import { SessionSchema } from "../schemas/session";
+import { SessionSchema } from "../models/schemas/session";
 
 
 export type JobOptions = {
 export type JobOptions = {
 	priority?: number;
 	priority?: number;

+ 8 - 8
backend/src/types/Models.ts

@@ -1,15 +1,15 @@
-import { AbcModel } from "../schemas/abc";
-import { NewsModel } from "../schemas/news";
-import { SessionModel } from "../schemas/session";
-import { StationModel } from "../schemas/station";
-import { UserModel } from "../schemas/user";
+import { AbcModel } from "../models/schemas/abc/schema";
+import { NewsModel } from "../models/schemas/news/schema";
+import { SessionModel } from "../models/schemas/sessions/schema";
+import { StationModel } from "../models/schemas/stations/schema";
+import { UserModel } from "../models/schemas/users/schema";
 
 
 export type Models = {
 export type Models = {
 	abc: AbcModel;
 	abc: AbcModel;
 	news: NewsModel;
 	news: NewsModel;
-	session: SessionModel;
-	station: StationModel;
-	user: UserModel;
+	sessions: SessionModel;
+	stations: StationModel;
+	users: UserModel;
 };
 };
 
 
 export type AnyModel = Models[keyof Models];
 export type AnyModel = Models[keyof Models];

+ 9 - 9
backend/src/types/Schemas.ts

@@ -1,10 +1,10 @@
 import { Types } from "mongoose";
 import { Types } from "mongoose";
-import { DocumentVersion } from "../schemas/plugins/documentVersion";
-import { AbcSchemaType } from "../schemas/abc";
-import { NewsSchemaType } from "../schemas/news";
-import { SessionSchemaType } from "../schemas/session";
-import { StationSchemaType } from "../schemas/station";
-import { UserSchemaType } from "../schemas/user";
+import { DocumentVersion } from "../models/plugins/documentVersion";
+import { AbcSchemaType } from "../models/schemas/abc/schema";
+import { NewsSchemaType } from "../models/schemas/news/schema";
+import { SessionSchemaType } from "../models/schemas/session/schema";
+import { StationSchemaType } from "../models/schemas/station/schema";
+import { UserSchemaType } from "../models/schemas/user/schema";
 
 
 // eslint-disable-next-line
 // eslint-disable-next-line
 export interface BaseSchema extends DocumentVersion, TimestampsSchema {
 export interface BaseSchema extends DocumentVersion, TimestampsSchema {
@@ -19,7 +19,7 @@ export interface TimestampsSchema {
 export type Schemas = {
 export type Schemas = {
 	abc: AbcSchemaType;
 	abc: AbcSchemaType;
 	news: NewsSchemaType;
 	news: NewsSchemaType;
-	session: SessionSchemaType;
-	station: StationSchemaType;
-	user: UserSchemaType;
+	sessions: SessionSchemaType;
+	stations: StationSchemaType;
+	users: UserSchemaType;
 };
 };