Browse Source

fix: Various fixes and improvements

Owen Diffey 1 year ago
parent
commit
aa92c2400a
56 changed files with 194 additions and 308 deletions
  1. 2 3
      backend/src/BaseModule.ts
  2. 16 12
      backend/src/Job.ts
  3. 3 2
      backend/src/JobContext.ts
  4. 12 22
      backend/src/JobQueue.ts
  5. 15 10
      backend/src/ModuleManager.ts
  6. 3 2
      backend/src/main.ts
  7. 0 9
      backend/src/modules/CacheModule.ts
  8. 16 26
      backend/src/modules/DataModule.ts
  9. 11 10
      backend/src/modules/DataModule/DataModuleJob.ts
  10. 9 3
      backend/src/modules/DataModule/GetDataJob.ts
  11. 1 2
      backend/src/modules/DataModule/models/abc/jobs/Create.ts
  12. 1 2
      backend/src/modules/DataModule/models/abc/jobs/DeleteById.ts
  13. 1 2
      backend/src/modules/DataModule/models/abc/jobs/FindById.ts
  14. 1 2
      backend/src/modules/DataModule/models/abc/jobs/UpdateById.ts
  15. 1 2
      backend/src/modules/DataModule/models/news/jobs/Create.ts
  16. 1 2
      backend/src/modules/DataModule/models/news/jobs/DeleteById.ts
  17. 1 2
      backend/src/modules/DataModule/models/news/jobs/FindById.ts
  18. 1 2
      backend/src/modules/DataModule/models/news/jobs/GetData.ts
  19. 3 3
      backend/src/modules/DataModule/models/news/jobs/Newest.ts
  20. 3 3
      backend/src/modules/DataModule/models/news/jobs/Published.ts
  21. 1 2
      backend/src/modules/DataModule/models/news/jobs/UpdateById.ts
  22. 1 2
      backend/src/modules/DataModule/models/sessions/jobs/Create.ts
  23. 1 2
      backend/src/modules/DataModule/models/sessions/jobs/DeleteById.ts
  24. 1 2
      backend/src/modules/DataModule/models/sessions/jobs/FindById.ts
  25. 1 2
      backend/src/modules/DataModule/models/sessions/jobs/UpdateById.ts
  26. 1 2
      backend/src/modules/DataModule/models/stations/jobs/Create.ts
  27. 1 2
      backend/src/modules/DataModule/models/stations/jobs/DeleteById.ts
  28. 1 2
      backend/src/modules/DataModule/models/stations/jobs/FindById.ts
  29. 1 2
      backend/src/modules/DataModule/models/stations/jobs/GetData.ts
  30. 5 3
      backend/src/modules/DataModule/models/stations/jobs/Index.ts
  31. 1 2
      backend/src/modules/DataModule/models/stations/jobs/UpdateById.ts
  32. 1 2
      backend/src/modules/DataModule/models/users/jobs/Create.ts
  33. 1 2
      backend/src/modules/DataModule/models/users/jobs/DeleteById.ts
  34. 6 3
      backend/src/modules/DataModule/models/users/jobs/FindById.ts
  35. 1 2
      backend/src/modules/DataModule/models/users/jobs/GetData.ts
  36. 1 2
      backend/src/modules/DataModule/models/users/jobs/GetModelPermissions.ts
  37. 1 2
      backend/src/modules/DataModule/models/users/jobs/GetPermissions.ts
  38. 1 2
      backend/src/modules/DataModule/models/users/jobs/UpdateById.ts
  39. 8 2
      backend/src/modules/DataModule/permissions/isDj.ts
  40. 7 1
      backend/src/modules/DataModule/permissions/isLoggedIn.ts
  41. 13 2
      backend/src/modules/DataModule/permissions/isOwner.ts
  42. 6 1
      backend/src/modules/DataModule/permissions/isPrivate.ts
  43. 6 1
      backend/src/modules/DataModule/permissions/isPublic.ts
  44. 6 1
      backend/src/modules/DataModule/permissions/isUnlisted.ts
  45. 0 9
      backend/src/modules/EventsModule.ts
  46. 1 4
      backend/src/modules/EventsModule/jobs/Subscribe.ts
  47. 3 6
      backend/src/modules/EventsModule/jobs/SubscribeMany.ts
  48. 1 4
      backend/src/modules/EventsModule/jobs/Unsubscribe.ts
  49. 1 4
      backend/src/modules/EventsModule/jobs/UnsubscribeAll.ts
  50. 2 5
      backend/src/modules/EventsModule/jobs/UnsubscribeMany.ts
  51. 0 8
      backend/src/modules/StationsModule.ts
  52. 11 11
      backend/src/modules/WebSocketModule.ts
  53. 1 1
      backend/src/types/JobOptions.ts
  54. 0 15
      backend/src/types/Models.ts
  55. 0 49
      backend/src/types/Modules.ts
  56. 0 25
      backend/src/types/Schemas.ts

+ 2 - 3
backend/src/BaseModule.ts

@@ -2,7 +2,6 @@ import { readdir } from "fs/promises";
 import path from "path";
 import path from "path";
 import LogBook, { Log } from "@/LogBook";
 import LogBook, { Log } from "@/LogBook";
 import ModuleManager from "@/ModuleManager";
 import ModuleManager from "@/ModuleManager";
-import { Modules } from "@/types/Modules";
 import Job from "./Job";
 import Job from "./Job";
 
 
 export enum ModuleStatus {
 export enum ModuleStatus {
@@ -20,7 +19,7 @@ export default abstract class BaseModule {
 
 
 	protected _status: ModuleStatus;
 	protected _status: ModuleStatus;
 
 
-	protected _dependentModules: (keyof Modules)[];
+	protected _dependentModules: string[];
 
 
 	protected _jobs: Record<string, typeof Job>;
 	protected _jobs: Record<string, typeof Job>;
 
 
@@ -128,7 +127,7 @@ export default abstract class BaseModule {
 	 */
 	 */
 	public canRunJobs() {
 	public canRunJobs() {
 		return this.getDependentModules().reduce(
 		return this.getDependentModules().reduce(
-			(canRunJobs: boolean, moduleName: keyof Modules): boolean => {
+			(canRunJobs: boolean, moduleName: string): boolean => {
 				if (canRunJobs === false) return false;
 				if (canRunJobs === false) return false;
 
 
 				return !!ModuleManager.getModule(moduleName)?.canRunJobs();
 				return !!ModuleManager.getModule(moduleName)?.canRunJobs();

+ 16 - 12
backend/src/Job.ts

@@ -2,8 +2,8 @@ import JobContext from "@/JobContext";
 import JobStatistics from "@/JobStatistics";
 import JobStatistics from "@/JobStatistics";
 import LogBook, { Log } from "@/LogBook";
 import LogBook, { Log } from "@/LogBook";
 import { JobOptions } from "@/types/JobOptions";
 import { JobOptions } from "@/types/JobOptions";
-import { Modules } from "@/types/Modules";
 import WebSocketModule from "./modules/WebSocketModule";
 import WebSocketModule from "./modules/WebSocketModule";
+import BaseModule from "./BaseModule";
 
 
 export enum JobStatus {
 export enum JobStatus {
 	QUEUED = "QUEUED",
 	QUEUED = "QUEUED",
@@ -15,7 +15,7 @@ export enum JobStatus {
 export default abstract class Job {
 export default abstract class Job {
 	protected static _apiEnabled = true;
 	protected static _apiEnabled = true;
 
 
-	protected _module: Modules[keyof Modules];
+	protected _module: InstanceType<typeof BaseModule>;
 
 
 	protected _payload: any;
 	protected _payload: any;
 
 
@@ -51,9 +51,9 @@ export default abstract class Job {
 	 * @param options - Job options
 	 * @param options - Job options
 	 */
 	 */
 	public constructor(
 	public constructor(
-		module: Modules[keyof Modules],
-		payload: any,
-		options?: Omit<JobOptions, "runDirectly">
+		module: InstanceType<typeof BaseModule>,
+		payload: unknown,
+		options?: JobOptions
 	) {
 	) {
 		this._module = module;
 		this._module = module;
 		this._payload = payload;
 		this._payload = payload;
@@ -165,7 +165,7 @@ export default abstract class Job {
 	}
 	}
 
 
 	public isApiEnabled() {
 	public isApiEnabled() {
-		return this.constructor._apiEnabled;
+		return (this.constructor as typeof Job)._apiEnabled;
 	}
 	}
 
 
 	protected async _validate() {}
 	protected async _validate() {}
@@ -174,7 +174,7 @@ export default abstract class Job {
 		await this._context.assertPermission(this.getPath());
 		await this._context.assertPermission(this.getPath());
 	}
 	}
 
 
-	protected abstract _execute();
+	protected abstract _execute(): Promise<unknown>;
 
 
 	/**
 	/**
 	 * execute - Execute job
 	 * execute - Execute job
@@ -197,9 +197,11 @@ export default abstract class Job {
 
 
 			const data = await this._execute();
 			const data = await this._execute();
 
 
-			if (this._context.getSocketId() && this._context.getCallbackRef()) {
+			const socketId = this._context.getSocketId();
+
+			if (socketId && this._context.getCallbackRef()) {
 				await WebSocketModule.dispatch(
 				await WebSocketModule.dispatch(
-					this._context.getSocketId(),
+					socketId,
 					"jobCallback",
 					"jobCallback",
 					this._context.getCallbackRef(),
 					this._context.getCallbackRef(),
 					{
 					{
@@ -217,12 +219,14 @@ export default abstract class Job {
 			JobStatistics.updateStats(this.getPath(), "successful");
 			JobStatistics.updateStats(this.getPath(), "successful");
 
 
 			return data;
 			return data;
-		} catch (error: any) {
+		} catch (error: unknown) {
 			const message = error?.message ?? error;
 			const message = error?.message ?? error;
 
 
-			if (this._context.getSocketId() && this._context.getCallbackRef()) {
+			const socketId = this._context.getSocketId();
+
+			if (socketId && this._context.getCallbackRef()) {
 				await WebSocketModule.dispatch(
 				await WebSocketModule.dispatch(
-					this._context.getSocketId(),
+					socketId,
 					"jobCallback",
 					"jobCallback",
 					this._context.getCallbackRef(),
 					this._context.getCallbackRef(),
 					{
 					{

+ 3 - 2
backend/src/JobContext.ts

@@ -3,6 +3,7 @@ import Job from "@/Job";
 import { Log } from "@/LogBook";
 import { Log } from "@/LogBook";
 import { JobOptions } from "@/types/JobOptions";
 import { JobOptions } from "@/types/JobOptions";
 import DataModule from "@/modules/DataModule";
 import DataModule from "@/modules/DataModule";
+import { UserModel } from "@/modules/DataModule/models/users/schema";
 
 
 export default class JobContext {
 export default class JobContext {
 	public readonly job: Job;
 	public readonly job: Job;
@@ -54,7 +55,7 @@ export default class JobContext {
 
 
 	public executeJob(
 	public executeJob(
 		JobClass: typeof Job,
 		JobClass: typeof Job,
-		payload?: any,
+		payload?: unknown,
 		options?: JobOptions
 		options?: JobOptions
 	) {
 	) {
 		return new JobClass(payload, {
 		return new JobClass(payload, {
@@ -68,7 +69,7 @@ export default class JobContext {
 		if (!this._session?.userId)
 		if (!this._session?.userId)
 			throw new Error("No user found for session");
 			throw new Error("No user found for session");
 
 
-		const User = await DataModule.getModel("users");
+		const User = await DataModule.getModel<UserModel>("users");
 
 
 		const user = await User.findById(this._session.userId);
 		const user = await User.findById(this._session.userId);
 
 

+ 12 - 22
backend/src/JobQueue.ts

@@ -1,7 +1,5 @@
-import BaseModule from "@/BaseModule";
 import Job, { JobStatus } from "@/Job";
 import Job, { JobStatus } from "@/Job";
 import { JobOptions } from "@/types/JobOptions";
 import { JobOptions } from "@/types/JobOptions";
-import { Jobs, Modules } from "@/types/Modules";
 import ModuleManager from "./ModuleManager";
 import ModuleManager from "./ModuleManager";
 
 
 export class JobQueue {
 export class JobQueue {
@@ -20,8 +18,8 @@ export class JobQueue {
 	private _callbacks: Record<
 	private _callbacks: Record<
 		string,
 		string,
 		{
 		{
-			resolve: (value: any) => void;
-			reject: (reason?: any) => void;
+			resolve: (value: unknown) => void;
+			reject: (reason?: unknown) => void;
 		}
 		}
 	>;
 	>;
 
 
@@ -67,18 +65,14 @@ export class JobQueue {
 
 
 	/**
 	/**
 	 * runJob - Run a job
 	 * runJob - Run a job
-	 *
-	 * @param moduleName - Module name
-	 * @param jobName - Job name
-	 * @param params - Params
 	 */
 	 */
-	public async runJob<ModuleNameType extends keyof Jobs & keyof Modules>(
-		moduleName: ModuleNameType,
+	public async runJob(
+		moduleName: string,
 		jobName: string,
 		jobName: string,
-		payload: any,
+		payload?: unknown,
 		options?: JobOptions
 		options?: JobOptions
-	): Promise<ReturnType> {
-		return new Promise<ReturnType>((resolve, reject) => {
+	): Promise<unknown> {
+		return new Promise<unknown>((resolve, reject) => {
 			this.queueJob(
 			this.queueJob(
 				moduleName,
 				moduleName,
 				jobName,
 				jobName,
@@ -91,18 +85,14 @@ export class JobQueue {
 
 
 	/**
 	/**
 	 * queueJob - Queue a job
 	 * queueJob - Queue a job
-	 *
-	 * @param moduleName - Module name
-	 * @param jobName - Job name
-	 * @param params - Params
 	 */
 	 */
-	public async queueJob<ModuleNameType extends keyof Jobs & keyof Modules>(
-		moduleName: ModuleNameType,
+	public async queueJob(
+		moduleName: string,
 		jobName: string,
 		jobName: string,
-		payload: any,
+		payload: unknown,
 		callback: {
 		callback: {
-			resolve: (value: any) => void;
-			reject: (reason?: any) => void;
+			resolve: (value: unknown) => void;
+			reject: (reason?: unknown) => void;
 		},
 		},
 		options?: JobOptions
 		options?: JobOptions
 	): Promise<string> {
 	): Promise<string> {

+ 15 - 10
backend/src/ModuleManager.ts

@@ -1,9 +1,8 @@
-import { ModuleStatus } from "@/BaseModule";
+import BaseModule, { ModuleStatus } from "@/BaseModule";
 import JobQueue from "@/JobQueue";
 import JobQueue from "@/JobQueue";
-import { Modules } from "@/types/Modules";
 
 
 export class ModuleManager {
 export class ModuleManager {
-	private _modules?: Modules;
+	private _modules?: Record<string, BaseModule>;
 
 
 	/**
 	/**
 	 * getStatus - Get status of modules
 	 * getStatus - Get status of modules
@@ -22,8 +21,12 @@ export class ModuleManager {
 	 * Gets a module
 	 * Gets a module
 	 *
 	 *
 	 */
 	 */
-	public getModule(moduleName: keyof Modules) {
-		return this._modules && this._modules[moduleName];
+	public getModule<ModuleType extends BaseModule>(
+		moduleName: string
+	): ModuleType | undefined {
+		return (this._modules && this._modules[moduleName]) as
+			| ModuleType
+			| undefined;
 	}
 	}
 
 
 	/**
 	/**
@@ -32,15 +35,17 @@ export class ModuleManager {
 	 * @param moduleName - Name of the module
 	 * @param moduleName - Name of the module
 	 * @returns Module
 	 * @returns Module
 	 */
 	 */
-	private async _loadModule<T extends keyof Modules>(moduleName: T) {
-		const mapper = {
+	private async _loadModule<ModuleType extends BaseModule>(
+		moduleName: string
+	): Promise<ModuleType> {
+		const mapper: Record<string, string> = {
 			cache: "CacheModule",
 			cache: "CacheModule",
 			data: "DataModule",
 			data: "DataModule",
 			events: "EventsModule",
 			events: "EventsModule",
 			stations: "StationsModule",
 			stations: "StationsModule",
 			websocket: "WebSocketModule"
 			websocket: "WebSocketModule"
 		};
 		};
-		const { default: Module }: { default: Modules[T] } = await import(
+		const { default: Module }: { default: ModuleType } = await import(
 			`./modules/${mapper[moduleName]}`
 			`./modules/${mapper[moduleName]}`
 		);
 		);
 		return Module;
 		return Module;
@@ -64,7 +69,7 @@ export class ModuleManager {
 	/**
 	/**
 	 * startModule - Start module
 	 * startModule - Start module
 	 */
 	 */
-	private async _startModule(module: Modules[keyof Modules]) {
+	private async _startModule(module: BaseModule) {
 		switch (module.getStatus()) {
 		switch (module.getStatus()) {
 			case ModuleStatus.STARTING:
 			case ModuleStatus.STARTING:
 			case ModuleStatus.STARTED:
 			case ModuleStatus.STARTED:
@@ -147,7 +152,7 @@ export class ModuleManager {
 				].includes(module.getStatus())
 				].includes(module.getStatus())
 			);
 			);
 
 
-			const shutdownOrder: (keyof Modules)[] = [];
+			const shutdownOrder: string[] = [];
 
 
 			for (const [name, module] of modules) {
 			for (const [name, module] of modules) {
 				if (!shutdownOrder.includes(name)) shutdownOrder.push(name);
 				if (!shutdownOrder.includes(name)) shutdownOrder.push(name);

+ 3 - 2
backend/src/main.ts

@@ -6,6 +6,7 @@ import JobQueue from "@/JobQueue";
 import JobStatistics from "@/JobStatistics";
 import JobStatistics from "@/JobStatistics";
 import DataModule from "@/modules/DataModule";
 import DataModule from "@/modules/DataModule";
 import EventsModule from "./modules/EventsModule";
 import EventsModule from "./modules/EventsModule";
+import { NewsModel } from "./modules/DataModule/models/news/schema";
 
 
 process.removeAllListeners("uncaughtException");
 process.removeAllListeners("uncaughtException");
 process.on("uncaughtException", err => {
 process.on("uncaughtException", err => {
@@ -20,7 +21,7 @@ process.on("uncaughtException", err => {
 });
 });
 
 
 ModuleManager.startup().then(async () => {
 ModuleManager.startup().then(async () => {
-	const Model = await DataModule.getModel("news");
+	const Model = await DataModule.getModel<NewsModel>("news");
 	// console.log("Model", Model);
 	// console.log("Model", Model);
 	const abcs = await Model.findOne({}).newest();
 	const abcs = await Model.findOne({}).newest();
 	console.log("Abcs", abcs);
 	console.log("Abcs", abcs);
@@ -136,7 +137,7 @@ const runCommand = (line: string) => {
 			break;
 			break;
 		}
 		}
 		case "stats": {
 		case "stats": {
-			console.log("Job Queue Stats:");
+			console.log("Job Statistics:");
 			console.table(JobStatistics.getStats());
 			console.table(JobStatistics.getStats());
 			break;
 			break;
 		}
 		}

+ 0 - 9
backend/src/modules/CacheModule.ts

@@ -1,7 +1,6 @@
 import config from "config";
 import config from "config";
 import { RedisClientType, createClient } from "redis";
 import { RedisClientType, createClient } from "redis";
 import BaseModule, { ModuleStatus } from "@/BaseModule";
 import BaseModule, { ModuleStatus } from "@/BaseModule";
-import { UniqueMethods } from "@/types/Modules";
 
 
 export class CacheModule extends BaseModule {
 export class CacheModule extends BaseModule {
 	private _redisClient?: RedisClientType;
 	private _redisClient?: RedisClientType;
@@ -19,7 +18,6 @@ export class CacheModule extends BaseModule {
 	public override async startup() {
 	public override async startup() {
 		await super.startup();
 		await super.startup();
 
 
-		// @ts-ignore
 		this._redisClient = createClient({
 		this._redisClient = createClient({
 			...config.get("redis"),
 			...config.get("redis"),
 			reconnectStrategy: (retries: number, error) => {
 			reconnectStrategy: (retries: number, error) => {
@@ -143,11 +141,4 @@ export class CacheModule extends BaseModule {
 	}
 	}
 }
 }
 
 
-export type CacheModuleJobs = {
-	[Property in keyof UniqueMethods<CacheModule>]: {
-		payload: Parameters<UniqueMethods<CacheModule>[Property]>[1];
-		returns: Awaited<ReturnType<UniqueMethods<CacheModule>[Property]>>;
-	};
-};
-
 export default new CacheModule();
 export default new CacheModule();

+ 16 - 26
backend/src/modules/DataModule.ts

@@ -1,5 +1,5 @@
 import config from "config";
 import config from "config";
-import mongoose, { Connection, SchemaTypes } from "mongoose";
+import mongoose, { Connection, Model, Schema, SchemaTypes } from "mongoose";
 import { patchHistoryPlugin, patchEventEmitter } from "ts-patch-mongoose";
 import { patchHistoryPlugin, patchEventEmitter } from "ts-patch-mongoose";
 import { readdir } from "fs/promises";
 import { readdir } from "fs/promises";
 import path from "path";
 import path from "path";
@@ -8,16 +8,17 @@ import Migration from "@/modules/DataModule/Migration";
 import documentVersionPlugin from "@/modules/DataModule/plugins/documentVersion";
 import documentVersionPlugin from "@/modules/DataModule/plugins/documentVersion";
 import getDataPlugin from "@/modules/DataModule/plugins/getData";
 import getDataPlugin from "@/modules/DataModule/plugins/getData";
 import BaseModule, { ModuleStatus } from "@/BaseModule";
 import BaseModule, { ModuleStatus } from "@/BaseModule";
-import { UniqueMethods } from "@/types/Modules";
-import { Models } from "@/types/Models";
-import { Schemas } from "@/types/Schemas";
 import EventsModule from "./EventsModule";
 import EventsModule from "./EventsModule";
+import DataModuleJob from "./DataModule/DataModuleJob";
+import Job from "@/Job";
 
 
 export class DataModule extends BaseModule {
 export class DataModule extends BaseModule {
-	private _models?: Models;
+	private _models?: Record<string, Model<any>>;
 
 
 	private _mongoConnection?: Connection;
 	private _mongoConnection?: Connection;
 
 
+	declare _jobs: Record<string, typeof Job | typeof DataModuleJob>;
+
 	/**
 	/**
 	 * Data Module
 	 * Data Module
 	 */
 	 */
@@ -84,10 +85,7 @@ export class DataModule extends BaseModule {
 	/**
 	/**
 	 * registerEvents - Register events for schema with event module
 	 * registerEvents - Register events for schema with event module
 	 */
 	 */
-	private async _registerEvents<
-		ModelName extends keyof Models,
-		SchemaType extends Schemas[keyof ModelName]
-	>(modelName: ModelName, schema: SchemaType) {
+	private async _registerEvents(modelName: string, schema: Schema<any>) {
 		const { enabled, eventCreated, eventUpdated, eventDeleted } =
 		const { enabled, eventCreated, eventUpdated, eventDeleted } =
 			schema.get("patchHistory") ?? {};
 			schema.get("patchHistory") ?? {};
 
 
@@ -128,10 +126,7 @@ export class DataModule extends BaseModule {
 	/**
 	/**
 	 * registerEvents - Register events for schema with event module
 	 * registerEvents - Register events for schema with event module
 	 */
 	 */
-	private async _registerEventListeners<
-		ModelName extends keyof Models,
-		SchemaType extends Schemas[keyof ModelName]
-	>(schema: SchemaType) {
+	private async _registerEventListeners(schema: Schema<any>) {
 		const eventListeners = schema.get("eventListeners");
 		const eventListeners = schema.get("eventListeners");
 
 
 		if (
 		if (
@@ -153,12 +148,10 @@ export class DataModule extends BaseModule {
 	 * @param modelName - Name of the model
 	 * @param modelName - Name of the model
 	 * @returns Model
 	 * @returns Model
 	 */
 	 */
-	private async _loadModel<ModelName extends keyof Models>(
-		modelName: ModelName
-	): Promise<Models[ModelName]> {
+	private async _loadModel(modelName: string): Promise<Model<any>> {
 		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: Schema<any> } = await import(
 			`./DataModule/models/${modelName.toString()}/schema`
 			`./DataModule/models/${modelName.toString()}/schema`
 		);
 		);
 
 
@@ -274,13 +267,17 @@ export class DataModule extends BaseModule {
 	 *
 	 *
 	 * @returns Model
 	 * @returns Model
 	 */
 	 */
-	public async getModel<ModelName extends keyof Models>(name: ModelName) {
+	public async getModel<ModelType extends Model<any>>(
+		name: string
+	): Promise<ModelType> {
 		if (!this._models) throw new Error("Models not loaded");
 		if (!this._models) throw new Error("Models not loaded");
 
 
 		if (this.getStatus() !== ModuleStatus.STARTED)
 		if (this.getStatus() !== ModuleStatus.STARTED)
 			throw new Error("Module not started");
 			throw new Error("Module not started");
 
 
-		return this._models[name];
+		if (!this._models[name]) throw new Error("Model not found");
+
+		return this._models[name] as ModelType;
 	}
 	}
 
 
 	private async _loadModelMigrations(modelName: string) {
 	private async _loadModelMigrations(modelName: string) {
@@ -366,11 +363,4 @@ export class DataModule extends BaseModule {
 	}
 	}
 }
 }
 
 
-export type DataModuleJobs = {
-	[Property in keyof UniqueMethods<DataModule>]: {
-		payload: Parameters<UniqueMethods<DataModule>[Property]>[1];
-		returns: Awaited<ReturnType<UniqueMethods<DataModule>[Property]>>;
-	};
-};
-
 export default new DataModule();
 export default new DataModule();

+ 11 - 10
backend/src/modules/DataModule/DataModuleJob.ts

@@ -1,22 +1,18 @@
-import { isObjectIdOrHexString } from "mongoose";
+import { HydratedDocument, Model, isObjectIdOrHexString } from "mongoose";
 import Job from "@/Job";
 import Job from "@/Job";
 import DataModule from "../DataModule";
 import DataModule from "../DataModule";
-import { AnyModel, Models } from "@/types/Models";
 import { JobOptions } from "@/types/JobOptions";
 import { JobOptions } from "@/types/JobOptions";
 import { UserModel } from "./models/users/schema";
 import { UserModel } from "./models/users/schema";
 
 
 export default abstract class DataModuleJob extends Job {
 export default abstract class DataModuleJob extends Job {
-	protected static _modelName: keyof Models;
+	protected static _modelName: string;
 
 
 	protected static _hasPermission:
 	protected static _hasPermission:
 		| boolean
 		| boolean
 		| CallableFunction
 		| CallableFunction
 		| (boolean | CallableFunction)[] = false;
 		| (boolean | CallableFunction)[] = false;
 
 
-	public constructor(
-		payload: any,
-		options?: Omit<JobOptions, "runDirectly">
-	) {
+	public constructor(payload?: unknown, options?: JobOptions) {
 		super(DataModule, payload, options);
 		super(DataModule, payload, options);
 	}
 	}
 
 
@@ -25,7 +21,9 @@ export default abstract class DataModuleJob extends Job {
 	}
 	}
 
 
 	public override getName() {
 	public override getName() {
-		return `${this.constructor._modelName}.${super.getName()}`;
+		return `${
+			(this.constructor as typeof DataModuleJob)._modelName
+		}.${super.getName()}`;
 	}
 	}
 
 
 	public static getModelName() {
 	public static getModelName() {
@@ -33,10 +31,13 @@ export default abstract class DataModuleJob extends Job {
 	}
 	}
 
 
 	public getModelName() {
 	public getModelName() {
-		return this.constructor._modelName;
+		return (this.constructor as typeof DataModuleJob)._modelName;
 	}
 	}
 
 
-	public static async hasPermission(model: AnyModel, user?: UserModel) {
+	public static async hasPermission(
+		model: HydratedDocument<Model<any>>,
+		user?: UserModel
+	) {
 		const options = Array.isArray(this._hasPermission)
 		const options = Array.isArray(this._hasPermission)
 			? this._hasPermission
 			? this._hasPermission
 			: [this._hasPermission];
 			: [this._hasPermission];

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

@@ -1,6 +1,7 @@
+import { Model } from "mongoose";
 import DataModule from "../DataModule";
 import DataModule from "../DataModule";
 import DataModuleJob from "./DataModuleJob";
 import DataModuleJob from "./DataModuleJob";
-import { FilterType } from "./plugins/getData";
+import { FilterType, GetData } from "./plugins/getData";
 
 
 export default abstract class GetDataJob extends DataModuleJob {
 export default abstract class GetDataJob extends DataModuleJob {
 	protected override async _validate() {
 	protected override async _validate() {
@@ -16,7 +17,7 @@ export default abstract class GetDataJob extends DataModuleJob {
 		if (!Array.isArray(this._payload.properties))
 		if (!Array.isArray(this._payload.properties))
 			throw new Error("Properties must be an array");
 			throw new Error("Properties must be an array");
 
 
-		this._payload.properties.forEach(property => {
+		this._payload.properties.forEach((property: unknown) => {
 			if (typeof property !== "string")
 			if (typeof property !== "string")
 				throw new Error("Property must be a string");
 				throw new Error("Property must be a string");
 		});
 		});
@@ -62,7 +63,12 @@ export default abstract class GetDataJob extends DataModuleJob {
 	}
 	}
 
 
 	protected async _execute() {
 	protected async _execute() {
-		const model = await DataModule.getModel(this.getModelName());
+		const model = await DataModule.getModel<Model<any> & Partial<GetData>>(
+			this.getModelName()
+		);
+
+		if (typeof model.getData !== "function")
+			throw new Error("Get data not available for model");
 
 
 		return model.getData(this._payload);
 		return model.getData(this._payload);
 	}
 	}

+ 1 - 2
backend/src/modules/DataModule/models/abc/jobs/Create.ts

@@ -1,6 +1,5 @@
 import CreateJob from "@/modules/DataModule/CreateJob";
 import CreateJob from "@/modules/DataModule/CreateJob";
-import { Models } from "@/types/Models";
 
 
 export default class Create extends CreateJob {
 export default class Create extends CreateJob {
-	protected static _modelName: keyof Models = "abc";
+	protected static _modelName = "abc";
 }
 }

+ 1 - 2
backend/src/modules/DataModule/models/abc/jobs/DeleteById.ts

@@ -1,6 +1,5 @@
 import DeleteByIdJob from "@/modules/DataModule/DeleteByIdJob";
 import DeleteByIdJob from "@/modules/DataModule/DeleteByIdJob";
-import { Models } from "@/types/Models";
 
 
 export default class DeleteById extends DeleteByIdJob {
 export default class DeleteById extends DeleteByIdJob {
-	protected static _modelName: keyof Models = "abc";
+	protected static _modelName = "abc";
 }
 }

+ 1 - 2
backend/src/modules/DataModule/models/abc/jobs/FindById.ts

@@ -1,6 +1,5 @@
 import FindByIdJob from "@/modules/DataModule/FindByIdJob";
 import FindByIdJob from "@/modules/DataModule/FindByIdJob";
-import { Models } from "@/types/Models";
 
 
 export default class FindById extends FindByIdJob {
 export default class FindById extends FindByIdJob {
-	protected static _modelName: keyof Models = "abc";
+	protected static _modelName = "abc";
 }
 }

+ 1 - 2
backend/src/modules/DataModule/models/abc/jobs/UpdateById.ts

@@ -1,6 +1,5 @@
 import UpdateByIdJob from "@/modules/DataModule/UpdateByIdJob";
 import UpdateByIdJob from "@/modules/DataModule/UpdateByIdJob";
-import { Models } from "@/types/Models";
 
 
 export default class UpdateById extends UpdateByIdJob {
 export default class UpdateById extends UpdateByIdJob {
-	protected static _modelName: keyof Models = "abc";
+	protected static _modelName = "abc";
 }
 }

+ 1 - 2
backend/src/modules/DataModule/models/news/jobs/Create.ts

@@ -1,6 +1,5 @@
 import CreateJob from "@/modules/DataModule/CreateJob";
 import CreateJob from "@/modules/DataModule/CreateJob";
-import { Models } from "@/types/Models";
 
 
 export default class Create extends CreateJob {
 export default class Create extends CreateJob {
-	protected static _modelName: keyof Models = "news";
+	protected static _modelName = "news";
 }
 }

+ 1 - 2
backend/src/modules/DataModule/models/news/jobs/DeleteById.ts

@@ -1,6 +1,5 @@
 import DeleteByIdJob from "@/modules/DataModule/DeleteByIdJob";
 import DeleteByIdJob from "@/modules/DataModule/DeleteByIdJob";
-import { Models } from "@/types/Models";
 
 
 export default class DeleteById extends DeleteByIdJob {
 export default class DeleteById extends DeleteByIdJob {
-	protected static _modelName: keyof Models = "news";
+	protected static _modelName = "news";
 }
 }

+ 1 - 2
backend/src/modules/DataModule/models/news/jobs/FindById.ts

@@ -1,8 +1,7 @@
 import FindByIdJob from "@/modules/DataModule/FindByIdJob";
 import FindByIdJob from "@/modules/DataModule/FindByIdJob";
-import { Models } from "@/types/Models";
 
 
 export default class FindById extends FindByIdJob {
 export default class FindById extends FindByIdJob {
-	protected static _modelName: keyof Models = "news";
+	protected static _modelName = "news";
 
 
 	protected static _hasPermission = true;
 	protected static _hasPermission = true;
 }
 }

+ 1 - 2
backend/src/modules/DataModule/models/news/jobs/GetData.ts

@@ -1,6 +1,5 @@
 import GetDataJob from "@/modules/DataModule/GetDataJob";
 import GetDataJob from "@/modules/DataModule/GetDataJob";
-import { Models } from "@/types/Models";
 
 
 export default class GetData extends GetDataJob {
 export default class GetData extends GetDataJob {
-	protected static _modelName: keyof Models = "news";
+	protected static _modelName = "news";
 }
 }

+ 3 - 3
backend/src/modules/DataModule/models/news/jobs/Newest.ts

@@ -1,9 +1,9 @@
 import DataModule from "@/modules/DataModule";
 import DataModule from "@/modules/DataModule";
 import DataModuleJob from "@/modules/DataModule/DataModuleJob";
 import DataModuleJob from "@/modules/DataModule/DataModuleJob";
-import { Models } from "@/types/Models";
+import { NewsModel } from "../schema";
 
 
 export default class Newest extends DataModuleJob {
 export default class Newest extends DataModuleJob {
-	protected static _modelName: keyof Models = "news";
+	protected static _modelName = "news";
 
 
 	protected static _hasPermission = true;
 	protected static _hasPermission = true;
 
 
@@ -31,7 +31,7 @@ export default class Newest extends DataModuleJob {
 	}
 	}
 
 
 	protected async _execute() {
 	protected async _execute() {
-		const model = await DataModule.getModel(this.getModelName());
+		const model = await DataModule.getModel<NewsModel>(this.getModelName());
 
 
 		const query = model.find().newest(this._payload?.showToNewUsers);
 		const query = model.find().newest(this._payload?.showToNewUsers);
 
 

+ 3 - 3
backend/src/modules/DataModule/models/news/jobs/Published.ts

@@ -1,14 +1,14 @@
 import DataModule from "@/modules/DataModule";
 import DataModule from "@/modules/DataModule";
 import DataModuleJob from "@/modules/DataModule/DataModuleJob";
 import DataModuleJob from "@/modules/DataModule/DataModuleJob";
-import { Models } from "@/types/Models";
+import { NewsModel } from "../schema";
 
 
 export default class Published extends DataModuleJob {
 export default class Published extends DataModuleJob {
-	protected static _modelName: keyof Models = "news";
+	protected static _modelName = "news";
 
 
 	protected static _hasPermission = true;
 	protected static _hasPermission = true;
 
 
 	protected async _execute() {
 	protected async _execute() {
-		const model = await DataModule.getModel(this.getModelName());
+		const model = await DataModule.getModel<NewsModel>(this.getModelName());
 
 
 		return model.find().published();
 		return model.find().published();
 	}
 	}

+ 1 - 2
backend/src/modules/DataModule/models/news/jobs/UpdateById.ts

@@ -1,6 +1,5 @@
 import UpdateByIdJob from "@/modules/DataModule/UpdateByIdJob";
 import UpdateByIdJob from "@/modules/DataModule/UpdateByIdJob";
-import { Models } from "@/types/Models";
 
 
 export default class UpdateById extends UpdateByIdJob {
 export default class UpdateById extends UpdateByIdJob {
-	protected static _modelName: keyof Models = "news";
+	protected static _modelName = "news";
 }
 }

+ 1 - 2
backend/src/modules/DataModule/models/sessions/jobs/Create.ts

@@ -1,6 +1,5 @@
 import CreateJob from "@/modules/DataModule/CreateJob";
 import CreateJob from "@/modules/DataModule/CreateJob";
-import { Models } from "@/types/Models";
 
 
 export default class Create extends CreateJob {
 export default class Create extends CreateJob {
-	protected static _modelName: keyof Models = "sessions";
+	protected static _modelName = "sessions";
 }
 }

+ 1 - 2
backend/src/modules/DataModule/models/sessions/jobs/DeleteById.ts

@@ -1,6 +1,5 @@
 import DeleteByIdJob from "@/modules/DataModule/DeleteByIdJob";
 import DeleteByIdJob from "@/modules/DataModule/DeleteByIdJob";
-import { Models } from "@/types/Models";
 
 
 export default class DeleteById extends DeleteByIdJob {
 export default class DeleteById extends DeleteByIdJob {
-	protected static _modelName: keyof Models = "sessions";
+	protected static _modelName = "sessions";
 }
 }

+ 1 - 2
backend/src/modules/DataModule/models/sessions/jobs/FindById.ts

@@ -1,6 +1,5 @@
 import FindByIdJob from "@/modules/DataModule/FindByIdJob";
 import FindByIdJob from "@/modules/DataModule/FindByIdJob";
-import { Models } from "@/types/Models";
 
 
 export default class FindById extends FindByIdJob {
 export default class FindById extends FindByIdJob {
-	protected static _modelName: keyof Models = "sessions";
+	protected static _modelName = "sessions";
 }
 }

+ 1 - 2
backend/src/modules/DataModule/models/sessions/jobs/UpdateById.ts

@@ -1,6 +1,5 @@
 import UpdateByIdJob from "@/modules/DataModule/UpdateByIdJob";
 import UpdateByIdJob from "@/modules/DataModule/UpdateByIdJob";
-import { Models } from "@/types/Models";
 
 
 export default class UpdateById extends UpdateByIdJob {
 export default class UpdateById extends UpdateByIdJob {
-	protected static _modelName: keyof Models = "sessions";
+	protected static _modelName = "sessions";
 }
 }

+ 1 - 2
backend/src/modules/DataModule/models/stations/jobs/Create.ts

@@ -1,9 +1,8 @@
 import CreateJob from "@/modules/DataModule/CreateJob";
 import CreateJob from "@/modules/DataModule/CreateJob";
 import isLoggedIn from "@/modules/DataModule/permissions/isLoggedIn";
 import isLoggedIn from "@/modules/DataModule/permissions/isLoggedIn";
-import { Models } from "@/types/Models";
 
 
 export default class Create extends CreateJob {
 export default class Create extends CreateJob {
-	protected static _modelName: keyof Models = "stations";
+	protected static _modelName = "stations";
 
 
 	protected static _hasPermission = isLoggedIn;
 	protected static _hasPermission = isLoggedIn;
 }
 }

+ 1 - 2
backend/src/modules/DataModule/models/stations/jobs/DeleteById.ts

@@ -1,9 +1,8 @@
 import DeleteByIdJob from "@/modules/DataModule/DeleteByIdJob";
 import DeleteByIdJob from "@/modules/DataModule/DeleteByIdJob";
 import isOwner from "@/modules/DataModule/permissions/isOwner";
 import isOwner from "@/modules/DataModule/permissions/isOwner";
-import { Models } from "@/types/Models";
 
 
 export default class DeleteById extends DeleteByIdJob {
 export default class DeleteById extends DeleteByIdJob {
-	protected static _modelName: keyof Models = "stations";
+	protected static _modelName = "stations";
 
 
 	protected static _hasPermission = isOwner;
 	protected static _hasPermission = isOwner;
 }
 }

+ 1 - 2
backend/src/modules/DataModule/models/stations/jobs/FindById.ts

@@ -1,12 +1,11 @@
 import FindByIdJob from "@/modules/DataModule/FindByIdJob";
 import FindByIdJob from "@/modules/DataModule/FindByIdJob";
-import { Models } from "@/types/Models";
 import isDj from "@/modules/DataModule/permissions/isDj";
 import isDj from "@/modules/DataModule/permissions/isDj";
 import isPublic from "@/modules/DataModule/permissions/isPublic";
 import isPublic from "@/modules/DataModule/permissions/isPublic";
 import isUnlisted from "@/modules/DataModule/permissions/isUnlisted";
 import isUnlisted from "@/modules/DataModule/permissions/isUnlisted";
 import isOwner from "@/modules/DataModule/permissions/isOwner";
 import isOwner from "@/modules/DataModule/permissions/isOwner";
 
 
 export default class FindById extends FindByIdJob {
 export default class FindById extends FindByIdJob {
-	protected static _modelName: keyof Models = "stations";
+	protected static _modelName = "stations";
 
 
 	protected static _hasPermission = [isOwner, isDj, isPublic, isUnlisted];
 	protected static _hasPermission = [isOwner, isDj, isPublic, isUnlisted];
 }
 }

+ 1 - 2
backend/src/modules/DataModule/models/stations/jobs/GetData.ts

@@ -1,6 +1,5 @@
 import GetDataJob from "@/modules/DataModule/GetDataJob";
 import GetDataJob from "@/modules/DataModule/GetDataJob";
-import { Models } from "@/types/Models";
 
 
 export default class GetData extends GetDataJob {
 export default class GetData extends GetDataJob {
-	protected static _modelName: keyof Models = "stations";
+	protected static _modelName = "stations";
 }
 }

+ 5 - 3
backend/src/modules/DataModule/models/stations/jobs/Index.ts

@@ -3,10 +3,10 @@ import DataModuleJob from "@/modules/DataModule/DataModuleJob";
 import isDj from "@/modules/DataModule/permissions/isDj";
 import isDj from "@/modules/DataModule/permissions/isDj";
 import isOwner from "@/modules/DataModule/permissions/isOwner";
 import isOwner from "@/modules/DataModule/permissions/isOwner";
 import isPublic from "@/modules/DataModule/permissions/isPublic";
 import isPublic from "@/modules/DataModule/permissions/isPublic";
-import { Models } from "@/types/Models";
+import { StationModel } from "../schema";
 
 
 export default class Index extends DataModuleJob {
 export default class Index extends DataModuleJob {
-	protected static _modelName: keyof Models = "stations";
+	protected static _modelName = "stations";
 
 
 	protected static _hasPermission = true;
 	protected static _hasPermission = true;
 
 
@@ -29,7 +29,9 @@ export default class Index extends DataModuleJob {
 	protected override async _authorize() {}
 	protected override async _authorize() {}
 
 
 	protected async _execute() {
 	protected async _execute() {
-		const model = await DataModule.getModel(this.getModelName());
+		const model = await DataModule.getModel<StationModel>(
+			this.getModelName()
+		);
 
 
 		const data = await model.find();
 		const data = await model.find();
 
 

+ 1 - 2
backend/src/modules/DataModule/models/stations/jobs/UpdateById.ts

@@ -1,10 +1,9 @@
 import UpdateByIdJob from "@/modules/DataModule/UpdateByIdJob";
 import UpdateByIdJob from "@/modules/DataModule/UpdateByIdJob";
 import isDj from "@/modules/DataModule/permissions/isDj";
 import isDj from "@/modules/DataModule/permissions/isDj";
 import isOwner from "@/modules/DataModule/permissions/isOwner";
 import isOwner from "@/modules/DataModule/permissions/isOwner";
-import { Models } from "@/types/Models";
 
 
 export default class UpdateById extends UpdateByIdJob {
 export default class UpdateById extends UpdateByIdJob {
-	protected static _modelName: keyof Models = "stations";
+	protected static _modelName = "stations";
 
 
 	protected static _hasPermission = [isOwner, isDj];
 	protected static _hasPermission = [isOwner, isDj];
 }
 }

+ 1 - 2
backend/src/modules/DataModule/models/users/jobs/Create.ts

@@ -1,6 +1,5 @@
 import CreateJob from "@/modules/DataModule/CreateJob";
 import CreateJob from "@/modules/DataModule/CreateJob";
-import { Models } from "@/types/Models";
 
 
 export default class Create extends CreateJob {
 export default class Create extends CreateJob {
-	protected static _modelName: keyof Models = "users";
+	protected static _modelName = "users";
 }
 }

+ 1 - 2
backend/src/modules/DataModule/models/users/jobs/DeleteById.ts

@@ -1,6 +1,5 @@
 import DeleteByIdJob from "@/modules/DataModule/DeleteByIdJob";
 import DeleteByIdJob from "@/modules/DataModule/DeleteByIdJob";
-import { Models } from "@/types/Models";
 
 
 export default class DeleteById extends DeleteByIdJob {
 export default class DeleteById extends DeleteByIdJob {
-	protected static _modelName: keyof Models = "users";
+	protected static _modelName = "users";
 }
 }

+ 6 - 3
backend/src/modules/DataModule/models/users/jobs/FindById.ts

@@ -1,13 +1,16 @@
+import { HydratedDocument } from "mongoose";
 import FindByIdJob from "@/modules/DataModule/FindByIdJob";
 import FindByIdJob from "@/modules/DataModule/FindByIdJob";
-import { Models } from "@/types/Models";
 import { UserModel } from "../schema";
 import { UserModel } from "../schema";
 
 
 export default class FindById extends FindByIdJob {
 export default class FindById extends FindByIdJob {
-	protected static _modelName: keyof Models = "users";
+	protected static _modelName = "users";
 
 
 	protected static _hasPermission = this._isSelf;
 	protected static _hasPermission = this._isSelf;
 
 
-	protected static _isSelf(model: UserModel, user?: UserModel) {
+	protected static _isSelf(
+		model: HydratedDocument<UserModel>,
+		user?: HydratedDocument<UserModel>
+	) {
 		return model._id === user?._id;
 		return model._id === user?._id;
 	}
 	}
 }
 }

+ 1 - 2
backend/src/modules/DataModule/models/users/jobs/GetData.ts

@@ -1,6 +1,5 @@
 import GetDataJob from "@/modules/DataModule/GetDataJob";
 import GetDataJob from "@/modules/DataModule/GetDataJob";
-import { Models } from "@/types/Models";
 
 
 export default class GetData extends GetDataJob {
 export default class GetData extends GetDataJob {
-	protected static _modelName: keyof Models = "users";
+	protected static _modelName = "users";
 }
 }

+ 1 - 2
backend/src/modules/DataModule/models/users/jobs/GetModelPermissions.ts

@@ -1,13 +1,12 @@
 import { isObjectIdOrHexString } from "mongoose";
 import { isObjectIdOrHexString } from "mongoose";
 import CacheModule from "@/modules/CacheModule";
 import CacheModule from "@/modules/CacheModule";
 import DataModule from "@/modules/DataModule";
 import DataModule from "@/modules/DataModule";
-import { Models } from "@/types/Models";
 import ModuleManager from "@/ModuleManager";
 import ModuleManager from "@/ModuleManager";
 import GetPermissions from "./GetPermissions";
 import GetPermissions from "./GetPermissions";
 import DataModuleJob from "@/modules/DataModule/DataModuleJob";
 import DataModuleJob from "@/modules/DataModule/DataModuleJob";
 
 
 export default class GetModelPermissions extends DataModuleJob {
 export default class GetModelPermissions extends DataModuleJob {
-	protected static _modelName: keyof Models = "users";
+	protected static _modelName = "users";
 
 
 	protected static _hasPermission = true;
 	protected static _hasPermission = true;
 
 

+ 1 - 2
backend/src/modules/DataModule/models/users/jobs/GetPermissions.ts

@@ -1,11 +1,10 @@
 import CacheModule from "@/modules/CacheModule";
 import CacheModule from "@/modules/CacheModule";
-import { Models } from "@/types/Models";
 import permissions from "@/modules/DataModule/models/users/permissions";
 import permissions from "@/modules/DataModule/models/users/permissions";
 import { UserRole } from "../UserRole";
 import { UserRole } from "../UserRole";
 import DataModuleJob from "@/modules/DataModule/DataModuleJob";
 import DataModuleJob from "@/modules/DataModule/DataModuleJob";
 
 
 export default class GetPermissions extends DataModuleJob {
 export default class GetPermissions extends DataModuleJob {
-	protected static _modelName: keyof Models = "users";
+	protected static _modelName = "users";
 
 
 	protected static _hasPermission = true;
 	protected static _hasPermission = true;
 
 

+ 1 - 2
backend/src/modules/DataModule/models/users/jobs/UpdateById.ts

@@ -1,6 +1,5 @@
 import UpdateByIdJob from "@/modules/DataModule/UpdateByIdJob";
 import UpdateByIdJob from "@/modules/DataModule/UpdateByIdJob";
-import { Models } from "@/types/Models";
 
 
 export default class UpdateById extends UpdateByIdJob {
 export default class UpdateById extends UpdateByIdJob {
-	protected static _modelName: keyof Models = "users";
+	protected static _modelName = "users";
 }
 }

+ 8 - 2
backend/src/modules/DataModule/permissions/isDj.ts

@@ -1,2 +1,8 @@
-export default (model, user) =>
-	model && user && model.djs.includes(user._id.toString());
+import { HydratedDocument } from "mongoose";
+import { StationSchema } from "../models/stations/schema";
+import { UserSchema } from "../models/users/schema";
+
+export default (
+	model: HydratedDocument<StationSchema>,
+	user?: HydratedDocument<UserSchema>
+) => model && user && model.djs.includes(user._id);

+ 7 - 1
backend/src/modules/DataModule/permissions/isLoggedIn.ts

@@ -1 +1,7 @@
-export default (model, user) => !!user;
+import { HydratedDocument, Schema } from "mongoose";
+import { UserSchema } from "../models/users/schema";
+
+export default <ModelSchemaType extends Schema>(
+	model: HydratedDocument<ModelSchemaType>,
+	user?: HydratedDocument<UserSchema>
+) => !!user;

+ 13 - 2
backend/src/modules/DataModule/permissions/isOwner.ts

@@ -1,4 +1,15 @@
-export default (model, user) => {
+import { HydratedDocument, Schema, Types } from "mongoose";
+import { UserSchema } from "../models/users/schema";
+
+export default <
+	ModelSchemaType extends Schema & {
+		createdBy?: Types.ObjectId;
+		owner?: Types.ObjectId;
+	}
+>(
+	model: HydratedDocument<ModelSchemaType>,
+	user?: HydratedDocument<UserSchema>
+) => {
 	if (!(user && model)) return false;
 	if (!(user && model)) return false;
 
 
 	let ownerAttribute;
 	let ownerAttribute;
@@ -7,7 +18,7 @@ export default (model, user) => {
 	else if (model.schema.path("owner")) ownerAttribute = "owner";
 	else if (model.schema.path("owner")) ownerAttribute = "owner";
 
 
 	if (ownerAttribute)
 	if (ownerAttribute)
-		return model[ownerAttribute]?.toString() === user._id.toString();
+		return model.get(ownerAttribute)?.toString() === user._id.toString();
 
 
 	return false;
 	return false;
 };
 };

+ 6 - 1
backend/src/modules/DataModule/permissions/isPrivate.ts

@@ -1,3 +1,8 @@
+import { HydratedDocument, Schema } from "mongoose";
 import { StationPrivacy } from "@/modules/DataModule/models/stations/StationPrivacy";
 import { StationPrivacy } from "@/modules/DataModule/models/stations/StationPrivacy";
 
 
-export default model => model && model.privacy === StationPrivacy.PRIVATE;
+export default <
+	ModelSchemaType extends Schema & { privacy?: StationPrivacy.PRIVATE }
+>(
+	model: HydratedDocument<ModelSchemaType>
+) => model && model?.privacy === StationPrivacy.PRIVATE;

+ 6 - 1
backend/src/modules/DataModule/permissions/isPublic.ts

@@ -1,3 +1,8 @@
+import { HydratedDocument, Schema } from "mongoose";
 import { StationPrivacy } from "@/modules/DataModule/models/stations/StationPrivacy";
 import { StationPrivacy } from "@/modules/DataModule/models/stations/StationPrivacy";
 
 
-export default model => model && model.privacy === StationPrivacy.PUBLIC;
+export default <
+	ModelSchemaType extends Schema & { privacy?: StationPrivacy.PUBLIC }
+>(
+	model: HydratedDocument<ModelSchemaType>
+) => model && model?.privacy === StationPrivacy.PUBLIC;

+ 6 - 1
backend/src/modules/DataModule/permissions/isUnlisted.ts

@@ -1,3 +1,8 @@
+import { HydratedDocument, Schema } from "mongoose";
 import { StationPrivacy } from "@/modules/DataModule/models/stations/StationPrivacy";
 import { StationPrivacy } from "@/modules/DataModule/models/stations/StationPrivacy";
 
 
-export default model => model && model.privacy === StationPrivacy.UNLISTED;
+export default <
+	ModelSchemaType extends Schema & { privacy?: StationPrivacy.UNLISTED }
+>(
+	model: HydratedDocument<ModelSchemaType>
+) => model && model?.privacy === StationPrivacy.UNLISTED;

+ 0 - 9
backend/src/modules/EventsModule.ts

@@ -1,8 +1,6 @@
 import { createClient, RedisClientType } from "redis";
 import { createClient, RedisClientType } from "redis";
 import config from "config";
 import config from "config";
-import crypto from "node:crypto";
 import BaseModule, { ModuleStatus } from "@/BaseModule";
 import BaseModule, { ModuleStatus } from "@/BaseModule";
-import { UniqueMethods } from "@/types/Modules";
 import WebSocketModule from "./WebSocketModule";
 import WebSocketModule from "./WebSocketModule";
 
 
 export class EventsModule extends BaseModule {
 export class EventsModule extends BaseModule {
@@ -355,11 +353,4 @@ export class EventsModule extends BaseModule {
 	}
 	}
 }
 }
 
 
-export type EventsModuleJobs = {
-	[Property in keyof UniqueMethods<EventsModule>]: {
-		payload: Parameters<UniqueMethods<EventsModule>[Property]>[1];
-		returns: Awaited<ReturnType<UniqueMethods<EventsModule>[Property]>>;
-	};
-};
-
 export default new EventsModule();
 export default new EventsModule();

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

@@ -3,10 +3,7 @@ import EventsModule from "@/modules/EventsModule";
 import { JobOptions } from "@/types/JobOptions";
 import { JobOptions } from "@/types/JobOptions";
 
 
 export default class Subscribe extends Job {
 export default class Subscribe extends Job {
-	public constructor(
-		payload?: any,
-		options?: Omit<JobOptions, "runDirectly">
-	) {
+	public constructor(payload?: unknown, options?: JobOptions) {
 		super(EventsModule, payload, options);
 		super(EventsModule, payload, options);
 	}
 	}
 
 

+ 3 - 6
backend/src/modules/EventsModule/jobs/SubscribeMany.ts

@@ -3,10 +3,7 @@ import EventsModule from "@/modules/EventsModule";
 import { JobOptions } from "@/types/JobOptions";
 import { JobOptions } from "@/types/JobOptions";
 
 
 export default class SubscribeMany extends Job {
 export default class SubscribeMany extends Job {
-	public constructor(
-		payload?: any,
-		options?: Omit<JobOptions, "runDirectly">
-	) {
+	public constructor(payload?: unknown, options?: JobOptions) {
 		super(EventsModule, payload, options);
 		super(EventsModule, payload, options);
 	}
 	}
 
 
@@ -17,7 +14,7 @@ export default class SubscribeMany extends Job {
 		if (!Array.isArray(this._payload.channels))
 		if (!Array.isArray(this._payload.channels))
 			throw new Error("Channels must be an array");
 			throw new Error("Channels must be an array");
 
 
-		this._payload.channels.forEach(channel => {
+		this._payload.channels.forEach((channel: unknown) => {
 			if (typeof channel !== "string")
 			if (typeof channel !== "string")
 				throw new Error("Channel must be a string");
 				throw new Error("Channel must be a string");
 		});
 		});
@@ -25,7 +22,7 @@ export default class SubscribeMany extends Job {
 
 
 	protected override async _authorize() {
 	protected override async _authorize() {
 		await Promise.all(
 		await Promise.all(
-			this._payload.channels.map(async channel => {
+			this._payload.channels.map(async (channel: string) => {
 				const [, moduleName, modelName, event, modelId] =
 				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(
 						channel
 						channel

+ 1 - 4
backend/src/modules/EventsModule/jobs/Unsubscribe.ts

@@ -3,10 +3,7 @@ import EventsModule from "@/modules/EventsModule";
 import { JobOptions } from "@/types/JobOptions";
 import { JobOptions } from "@/types/JobOptions";
 
 
 export default class Unsubscribe extends Job {
 export default class Unsubscribe extends Job {
-	public constructor(
-		payload?: any,
-		options?: Omit<JobOptions, "runDirectly">
-	) {
+	public constructor(payload?: unknown, options?: JobOptions) {
 		super(EventsModule, payload, options);
 		super(EventsModule, payload, options);
 	}
 	}
 
 

+ 1 - 4
backend/src/modules/EventsModule/jobs/UnsubscribeAll.ts

@@ -3,10 +3,7 @@ import EventsModule from "@/modules/EventsModule";
 import { JobOptions } from "@/types/JobOptions";
 import { JobOptions } from "@/types/JobOptions";
 
 
 export default class UnsubscribeAll extends Job {
 export default class UnsubscribeAll extends Job {
-	public constructor(
-		payload?: any,
-		options?: Omit<JobOptions, "runDirectly">
-	) {
+	public constructor(payload?: unknown, options?: JobOptions) {
 		super(EventsModule, payload, options);
 		super(EventsModule, payload, options);
 	}
 	}
 
 

+ 2 - 5
backend/src/modules/EventsModule/jobs/UnsubscribeMany.ts

@@ -3,10 +3,7 @@ import EventsModule from "@/modules/EventsModule";
 import { JobOptions } from "@/types/JobOptions";
 import { JobOptions } from "@/types/JobOptions";
 
 
 export default class UnsubscribeMany extends Job {
 export default class UnsubscribeMany extends Job {
-	public constructor(
-		payload?: any,
-		options?: Omit<JobOptions, "runDirectly">
-	) {
+	public constructor(payload?: unknown, options?: JobOptions) {
 		super(EventsModule, payload, options);
 		super(EventsModule, payload, options);
 	}
 	}
 
 
@@ -17,7 +14,7 @@ export default class UnsubscribeMany extends Job {
 		if (!Array.isArray(this._payload.channels))
 		if (!Array.isArray(this._payload.channels))
 			throw new Error("Channels must be an array");
 			throw new Error("Channels must be an array");
 
 
-		this._payload.channels.forEach(channel => {
+		this._payload.channels.forEach((channel: unknown) => {
 			if (typeof channel !== "string")
 			if (typeof channel !== "string")
 				throw new Error("Channel must be a string");
 				throw new Error("Channel must be a string");
 		});
 		});

+ 0 - 8
backend/src/modules/StationsModule.ts

@@ -1,4 +1,3 @@
-import { UniqueMethods } from "@/types/Modules";
 import BaseModule from "@/BaseModule";
 import BaseModule from "@/BaseModule";
 
 
 export class StationsModule extends BaseModule {
 export class StationsModule extends BaseModule {
@@ -29,11 +28,4 @@ export class StationsModule extends BaseModule {
 	}
 	}
 }
 }
 
 
-export type StationsModuleJobs = {
-	[Property in keyof UniqueMethods<StationsModule>]: {
-		payload: Parameters<UniqueMethods<StationsModule>[Property]>[1];
-		returns: Awaited<ReturnType<UniqueMethods<StationsModule>[Property]>>;
-	};
-};
-
 export default new StationsModule();
 export default new StationsModule();

+ 11 - 11
backend/src/modules/WebSocketModule.ts

@@ -4,11 +4,12 @@ import http, { Server, IncomingMessage } from "node:http";
 import { RawData, WebSocketServer } from "ws";
 import { RawData, WebSocketServer } from "ws";
 import { Types, isObjectIdOrHexString } from "mongoose";
 import { Types, isObjectIdOrHexString } from "mongoose";
 import BaseModule from "@/BaseModule";
 import BaseModule from "@/BaseModule";
-import { UniqueMethods } from "@/types/Modules";
 import WebSocket from "@/WebSocket";
 import WebSocket from "@/WebSocket";
 import ModuleManager from "@/ModuleManager";
 import ModuleManager from "@/ModuleManager";
 import JobQueue from "@/JobQueue";
 import JobQueue from "@/JobQueue";
 import DataModule from "./DataModule";
 import DataModule from "./DataModule";
+import { UserModel } from "./DataModule/models/users/schema";
+import { SessionModel } from "./DataModule/models/sessions/schema";
 
 
 export class WebSocketModule extends BaseModule {
 export class WebSocketModule extends BaseModule {
 	private _httpServer?: Server;
 	private _httpServer?: Server;
@@ -121,7 +122,7 @@ export class WebSocketModule extends BaseModule {
 			});
 			});
 
 
 			if (session) {
 			if (session) {
-				const User = await DataModule.getModel("users");
+				const User = await DataModule.getModel<UserModel>("users");
 
 
 				user = await User.findById(session.userId);
 				user = await User.findById(session.userId);
 			}
 			}
@@ -230,7 +231,9 @@ export class WebSocketModule extends BaseModule {
 
 
 			let session;
 			let session;
 			if (socket.getSessionId()) {
 			if (socket.getSessionId()) {
-				const Session = await DataModule.getModel("sessions");
+				const Session = await DataModule.getModel<SessionModel>(
+					"sessions"
+				);
 
 
 				session = await Session.findByIdAndUpdate(
 				session = await Session.findByIdAndUpdate(
 					socket.getSessionId(),
 					socket.getSessionId(),
@@ -294,7 +297,11 @@ export class WebSocketModule extends BaseModule {
 	/**
 	/**
 	 * dispatch - Dispatch message to socket
 	 * dispatch - Dispatch message to socket
 	 */
 	 */
-	public async dispatch(socketId: string, channel: string, ...values) {
+	public async dispatch(
+		socketId: string,
+		channel: string,
+		...values: unknown[]
+	) {
 		const socket = await this.getSocket(socketId);
 		const socket = await this.getSocket(socketId);
 
 
 		if (!socket) return;
 		if (!socket) return;
@@ -315,11 +322,4 @@ export class WebSocketModule extends BaseModule {
 	}
 	}
 }
 }
 
 
-export type WebSocketModuleJobs = {
-	[Property in keyof UniqueMethods<WebSocketModule>]: {
-		payload: Parameters<UniqueMethods<WebSocketModule>[Property]>[1];
-		returns: Awaited<ReturnType<UniqueMethods<WebSocketModule>[Property]>>;
-	};
-};
-
 export default new WebSocketModule();
 export default new WebSocketModule();

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

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

+ 0 - 15
backend/src/types/Models.ts

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

+ 0 - 49
backend/src/types/Modules.ts

@@ -1,49 +0,0 @@
-import { CacheModule, CacheModuleJobs } from "@/modules/CacheModule";
-import { DataModule, DataModuleJobs } from "@/modules/DataModule";
-import { EventsModule, EventsModuleJobs } from "@/modules/EventsModule";
-import { StationsModule, StationsModuleJobs } from "@/modules/StationsModule";
-import {
-	WebSocketModule,
-	WebSocketModuleJobs
-} from "@/modules/WebSocketModule";
-import BaseModule from "@/BaseModule";
-
-export type Module = BaseModule;
-
-export type ModuleClass<Module extends typeof BaseModule> = {
-	new (): Module;
-};
-
-export type Jobs = {
-	cache: {
-		[Property in keyof CacheModuleJobs]: CacheModuleJobs[Property];
-	};
-	data: {
-		[Property in keyof DataModuleJobs]: DataModuleJobs[Property];
-	};
-	events: {
-		[Property in keyof EventsModuleJobs]: EventsModuleJobs[Property];
-	};
-	stations: {
-		[Property in keyof StationsModuleJobs]: StationsModuleJobs[Property];
-	};
-	websocket: {
-		[Property in keyof WebSocketModuleJobs]: WebSocketModuleJobs[Property];
-	};
-};
-
-export type Modules = {
-	cache: CacheModule & typeof BaseModule;
-	data: DataModule & typeof BaseModule;
-	events: EventsModule & typeof BaseModule;
-	stations: StationsModule & typeof BaseModule;
-	websocket: WebSocketModule & typeof BaseModule;
-};
-
-export type Methods<T> = {
-	[P in keyof T as T[P] extends (...args: any) => Awaited<any>
-		? P
-		: never]: T[P];
-};
-
-export type UniqueMethods<T> = Methods<Omit<T, keyof BaseModule>>;

+ 0 - 25
backend/src/types/Schemas.ts

@@ -1,25 +0,0 @@
-import { Types } from "mongoose";
-import { NewsSchemaType } from "@models/news/schema";
-import { SessionSchemaType } from "@models/sessions/schema";
-import { StationSchemaType } from "@models/stations/schema";
-import { UserSchemaType } from "@models/users/schema";
-import { AbcSchemaType } from "@models/abc/schema";
-import { DocumentVersion } from "@/modules/DataModule/plugins/documentVersion";
-
-// eslint-disable-next-line
-export interface BaseSchema extends DocumentVersion, TimestampsSchema {
-	_id: Types.ObjectId;
-}
-
-export interface TimestampsSchema {
-	createdAt: number;
-	updatedAt: number;
-}
-
-export type Schemas = {
-	abc: AbcSchemaType;
-	news: NewsSchemaType;
-	sessions: SessionSchemaType;
-	stations: StationSchemaType;
-	users: UserSchemaType;
-};