summary refs log tree commit diff
path: root/util/src/entities
diff options
context:
space:
mode:
Diffstat (limited to 'util/src/entities')
-rw-r--r--util/src/entities/Application.ts109
-rw-r--r--util/src/entities/Attachment.ts43
-rw-r--r--util/src/entities/AuditLog.ts194
-rw-r--r--util/src/entities/Ban.ts41
-rw-r--r--util/src/entities/BaseClass.ts75
-rw-r--r--util/src/entities/Categories.ts33
-rw-r--r--util/src/entities/Channel.ts380
-rw-r--r--util/src/entities/ClientRelease.ts26
-rw-r--r--util/src/entities/Config.ts407
-rw-r--r--util/src/entities/ConnectedAccount.ts42
-rw-r--r--util/src/entities/Emoji.ts46
-rw-r--r--util/src/entities/Encryption.ts35
-rw-r--r--util/src/entities/Group.ts33
-rw-r--r--util/src/entities/Guild.ts363
-rw-r--r--util/src/entities/Invite.ts85
-rw-r--r--util/src/entities/Member.ts356
-rw-r--r--util/src/entities/Message.ts285
-rw-r--r--util/src/entities/Migration.ts18
-rw-r--r--util/src/entities/RateLimit.ts17
-rw-r--r--util/src/entities/ReadState.ts55
-rw-r--r--util/src/entities/Recipient.ts30
-rw-r--r--util/src/entities/Relationship.ts49
-rw-r--r--util/src/entities/Role.ts51
-rw-r--r--util/src/entities/Session.ts46
-rw-r--r--util/src/entities/Sticker.ts66
-rw-r--r--util/src/entities/StickerPack.ts31
-rw-r--r--util/src/entities/Team.ts27
-rw-r--r--util/src/entities/TeamMember.ts37
-rw-r--r--util/src/entities/Template.ts44
-rw-r--r--util/src/entities/User.ts403
-rw-r--r--util/src/entities/UserGroup.ts37
-rw-r--r--util/src/entities/VoiceState.ts77
-rw-r--r--util/src/entities/Webhook.ts76
-rw-r--r--util/src/entities/index.ts30
34 files changed, 0 insertions, 3647 deletions
diff --git a/util/src/entities/Application.ts b/util/src/entities/Application.ts
deleted file mode 100644
index fab3d93f..00000000
--- a/util/src/entities/Application.ts
+++ /dev/null
@@ -1,109 +0,0 @@
-import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
-import { BaseClass } from "./BaseClass";
-import { Guild } from "./Guild";
-import { Team } from "./Team";
-import { User } from "./User";
-
-@Entity("applications")
-export class Application extends BaseClass {
-	@Column()
-	name: string;
-
-	@Column({ nullable: true })
-	icon?: string;
-
-	@Column()
-	description: string;
-
-	@Column({ type: "simple-array", nullable: true })
-	rpc_origins?: string[];
-
-	@Column()
-	bot_public: boolean;
-
-	@Column()
-	bot_require_code_grant: boolean;
-
-	@Column({ nullable: true })
-	terms_of_service_url?: string;
-
-	@Column({ nullable: true })
-	privacy_policy_url?: string;
-
-	@JoinColumn({ name: "owner_id" })
-	@ManyToOne(() => User)
-	owner?: User;
-
-	@Column({ nullable: true })
-	summary?: string;
-
-	@Column()
-	verify_key: string;
-
-	@JoinColumn({ name: "team_id" })
-	@ManyToOne(() => Team, {
-		onDelete: "CASCADE",
-	})
-	team?: Team;
-
-	@JoinColumn({ name: "guild_id" })
-	@ManyToOne(() => Guild)
-	guild: Guild; // if this application is a game sold, this field will be the guild to which it has been linked
-
-	@Column({ nullable: true })
-	primary_sku_id?: string; // if this application is a game sold, this field will be the id of the "Game SKU" that is created,
-
-	@Column({ nullable: true })
-	slug?: string; // if this application is a game sold, this field will be the URL slug that links to the store page
-
-	@Column({ nullable: true })
-	cover_image?: string; // the application's default rich presence invite cover image hash
-
-	@Column()
-	flags: string; // the application's public flags
-}
-
-export interface ApplicationCommand {
-	id: string;
-	application_id: string;
-	name: string;
-	description: string;
-	options?: ApplicationCommandOption[];
-}
-
-export interface ApplicationCommandOption {
-	type: ApplicationCommandOptionType;
-	name: string;
-	description: string;
-	required?: boolean;
-	choices?: ApplicationCommandOptionChoice[];
-	options?: ApplicationCommandOption[];
-}
-
-export interface ApplicationCommandOptionChoice {
-	name: string;
-	value: string | number;
-}
-
-export enum ApplicationCommandOptionType {
-	SUB_COMMAND = 1,
-	SUB_COMMAND_GROUP = 2,
-	STRING = 3,
-	INTEGER = 4,
-	BOOLEAN = 5,
-	USER = 6,
-	CHANNEL = 7,
-	ROLE = 8,
-}
-
-export interface ApplicationCommandInteractionData {
-	id: string;
-	name: string;
-	options?: ApplicationCommandInteractionDataOption[];
-}
-
-export interface ApplicationCommandInteractionDataOption {
-	name: string;
-	value?: any;
-	options?: ApplicationCommandInteractionDataOption[];
-}
diff --git a/util/src/entities/Attachment.ts b/util/src/entities/Attachment.ts
deleted file mode 100644
index 7b4b17eb..00000000
--- a/util/src/entities/Attachment.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import { BeforeRemove, Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
-import { URL } from "url";
-import { deleteFile } from "../util/cdn";
-import { BaseClass } from "./BaseClass";
-
-@Entity("attachments")
-export class Attachment extends BaseClass {
-	@Column()
-	filename: string; // name of file attached
-
-	@Column()
-	size: number; // size of file in bytes
-
-	@Column()
-	url: string; // source url of file
-
-	@Column()
-	proxy_url: string; // a proxied url of file
-
-	@Column({ nullable: true })
-	height?: number; // height of file (if image)
-
-	@Column({ nullable: true })
-	width?: number; // width of file (if image)
-
-	@Column({ nullable: true })
-	content_type?: string;
-
-	@Column({ nullable: true })
-	@RelationId((attachment: Attachment) => attachment.message)
-	message_id: string;
-
-	@JoinColumn({ name: "message_id" })
-	@ManyToOne(() => require("./Message").Message, (message: import("./Message").Message) => message.attachments, {
-		onDelete: "CASCADE",
-	})
-	message: import("./Message").Message;
-
-	@BeforeRemove()
-	onDelete() {
-		return deleteFile(new URL(this.url).pathname);
-	}
-}
diff --git a/util/src/entities/AuditLog.ts b/util/src/entities/AuditLog.ts
deleted file mode 100644
index b003e7ba..00000000
--- a/util/src/entities/AuditLog.ts
+++ /dev/null
@@ -1,194 +0,0 @@
-import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
-import { BaseClass } from "./BaseClass";
-import { ChannelPermissionOverwrite } from "./Channel";
-import { User } from "./User";
-
-export enum AuditLogEvents {
-	// guild level
-	GUILD_UPDATE = 1, 
-	GUILD_IMPORT = 2,
-	GUILD_EXPORTED = 3,
-	GUILD_ARCHIVE = 4,
-	GUILD_UNARCHIVE = 5,
-	// join-leave
-	USER_JOIN = 6, 
-	USER_LEAVE = 7,
-	// channels
-	CHANNEL_CREATE = 10, 
-	CHANNEL_UPDATE = 11,
-	CHANNEL_DELETE = 12,
-	// permission overrides
-	CHANNEL_OVERWRITE_CREATE = 13, 
-	CHANNEL_OVERWRITE_UPDATE = 14,
-	CHANNEL_OVERWRITE_DELETE = 15,
-	// kick and ban
-	MEMBER_KICK = 20, 
-	MEMBER_PRUNE = 21,
-	MEMBER_BAN_ADD = 22,
-	MEMBER_BAN_REMOVE = 23,
-	// member updates
-	MEMBER_UPDATE = 24,
-	MEMBER_ROLE_UPDATE = 25,
-	MEMBER_MOVE = 26,
-	MEMBER_DISCONNECT = 27,
-	BOT_ADD = 28,
-	// roles
-	ROLE_CREATE = 30,
-	ROLE_UPDATE = 31,
-	ROLE_DELETE = 32,
-	ROLE_SWAP = 33,
-	// invites
-	INVITE_CREATE = 40,
-	INVITE_UPDATE = 41,
-	INVITE_DELETE = 42,
-	// webhooks
-	WEBHOOK_CREATE = 50,
-	WEBHOOK_UPDATE = 51,
-	WEBHOOK_DELETE = 52,
-	WEBHOOK_SWAP = 53,
-	// custom emojis
-	EMOJI_CREATE = 60,
-	EMOJI_UPDATE = 61,
-	EMOJI_DELETE = 62,
-	EMOJI_SWAP = 63,
-	// deletion
-	MESSAGE_CREATE = 70, // messages sent using non-primary seat of the user only
-	MESSAGE_EDIT = 71, // non-self edits only
-	MESSAGE_DELETE = 72,
-	MESSAGE_BULK_DELETE = 73,
-	// pinning
-	MESSAGE_PIN = 74,
-	MESSAGE_UNPIN = 75,
-	// integrations
-	INTEGRATION_CREATE = 80,
-	INTEGRATION_UPDATE = 81,
-	INTEGRATION_DELETE = 82,
-	// stage actions
-	STAGE_INSTANCE_CREATE = 83,
-	STAGE_INSTANCE_UPDATE = 84,
-	STAGE_INSTANCE_DELETE = 85,
-	// stickers
-	STICKER_CREATE = 90,
-	STICKER_UPDATE = 91,
-	STICKER_DELETE = 92,
-	STICKER_SWAP = 93,
-	// threads
-	THREAD_CREATE = 110,
-	THREAD_UPDATE = 111,
-	THREAD_DELETE = 112,
-	// application commands
-	APPLICATION_COMMAND_PERMISSION_UPDATE = 121,
-	// automod
-	POLICY_CREATE = 140, 
-	POLICY_UPDATE = 141,
-	POLICY_DELETE = 142,
-	MESSAGE_BLOCKED_BY_POLICIES = 143,  // in fosscord, blocked messages are stealth-dropped
-	// instance policies affecting the guild
-	GUILD_AFFECTED_BY_POLICIES = 216,
-	// message moves
-	IN_GUILD_MESSAGE_MOVE = 223,
-	CROSS_GUILD_MESSAGE_MOVE = 224,
-	// message routing
-	ROUTE_CREATE = 225, 
-	ROUTE_UPDATE = 226,
-}
-
-@Entity("audit_logs")
-export class AuditLog extends BaseClass {
-	@JoinColumn({ name: "target_id" })
-	@ManyToOne(() => User)
-	target?: User;
-
-	@Column({ nullable: true })
-	@RelationId((auditlog: AuditLog) => auditlog.user)
-	user_id: string;
-
-	@JoinColumn({ name: "user_id" })
-	@ManyToOne(() => User, (user: User) => user.id)
-	user: User;
-
-	@Column({ type: "int" })
-	action_type: AuditLogEvents;
-
-	@Column({ type: "simple-json", nullable: true })
-	options?: {
-		delete_member_days?: string;
-		members_removed?: string;
-		channel_id?: string;
-		messaged_id?: string;
-		count?: string;
-		id?: string;
-		type?: string;
-		role_name?: string;
-	};
-
-	@Column()
-	@Column({ type: "simple-json" })
-	changes: AuditLogChange[];
-
-	@Column({ nullable: true })
-	reason?: string;
-}
-
-export interface AuditLogChange {
-	new_value?: AuditLogChangeValue;
-	old_value?: AuditLogChangeValue;
-	key: string;
-}
-
-export interface AuditLogChangeValue {
-	name?: string;
-	description?: string;
-	icon_hash?: string;
-	splash_hash?: string;
-	discovery_splash_hash?: string;
-	banner_hash?: string;
-	owner_id?: string;
-	region?: string;
-	preferred_locale?: string;
-	afk_channel_id?: string;
-	afk_timeout?: number;
-	rules_channel_id?: string;
-	public_updates_channel_id?: string;
-	mfa_level?: number;
-	verification_level?: number;
-	explicit_content_filter?: number;
-	default_message_notifications?: number;
-	vanity_url_code?: string;
-	$add?: {}[];
-	$remove?: {}[];
-	prune_delete_days?: number;
-	widget_enabled?: boolean;
-	widget_channel_id?: string;
-	system_channel_id?: string;
-	position?: number;
-	topic?: string;
-	bitrate?: number;
-	permission_overwrites?: ChannelPermissionOverwrite[];
-	nsfw?: boolean;
-	application_id?: string;
-	rate_limit_per_user?: number;
-	permissions?: string;
-	color?: number;
-	hoist?: boolean;
-	mentionable?: boolean;
-	allow?: string;
-	deny?: string;
-	code?: string;
-	channel_id?: string;
-	inviter_id?: string;
-	max_uses?: number;
-	uses?: number;
-	max_age?: number;
-	temporary?: boolean;
-	deaf?: boolean;
-	mute?: boolean;
-	nick?: string;
-	avatar_hash?: string;
-	id?: string;
-	type?: number;
-	enable_emoticons?: boolean;
-	expire_behavior?: number;
-	expire_grace_period?: number;
-	user_limit?: number;
-}
diff --git a/util/src/entities/Ban.ts b/util/src/entities/Ban.ts
deleted file mode 100644
index 9504bd8e..00000000
--- a/util/src/entities/Ban.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
-import { BaseClass } from "./BaseClass";
-import { Guild } from "./Guild";
-import { User } from "./User";
-
-@Entity("bans")
-export class Ban extends BaseClass {
-	@Column({ nullable: true })
-	@RelationId((ban: Ban) => ban.user)
-	user_id: string;
-
-	@JoinColumn({ name: "user_id" })
-	@ManyToOne(() => User, {
-		onDelete: "CASCADE",
-	})
-	user: User;
-
-	@Column({ nullable: true })
-	@RelationId((ban: Ban) => ban.guild)
-	guild_id: string;
-
-	@JoinColumn({ name: "guild_id" })
-	@ManyToOne(() => Guild, {
-		onDelete: "CASCADE",
-	})
-	guild: Guild;
-
-	@Column({ nullable: true })
-	@RelationId((ban: Ban) => ban.executor)
-	executor_id: string;
-
-	@JoinColumn({ name: "executor_id" })
-	@ManyToOne(() => User)
-	executor: User;
-
-	@Column()
-	ip: string;
-
-	@Column({ nullable: true })
-	reason?: string;
-}
diff --git a/util/src/entities/BaseClass.ts b/util/src/entities/BaseClass.ts
deleted file mode 100644
index aabca016..00000000
--- a/util/src/entities/BaseClass.ts
+++ /dev/null
@@ -1,75 +0,0 @@
-import "reflect-metadata";
-import { BaseEntity, EntityMetadata, FindConditions, ObjectIdColumn, PrimaryColumn } from "typeorm";
-import { Snowflake } from "../util/Snowflake";
-import "missing-native-js-functions";
-
-export class BaseClassWithoutId extends BaseEntity {
-	constructor(props?: any) {
-		super();
-		this.assign(props);
-	}
-
-	private get construct(): any {
-		return this.constructor;
-	}
-
-	private get metadata() {
-		return this.construct.getRepository().metadata as EntityMetadata;
-	}
-
-	assign(props: any = {}) {
-		delete props.opts;
-		delete props.props;
-
-		const properties = new Set(
-			this.metadata.columns
-				.map((x: any) => x.propertyName)
-				.concat(this.metadata.relations.map((x) => x.propertyName))
-		);
-		// will not include relational properties
-
-		for (const key in props) {
-			if (!properties.has(key)) continue;
-			// @ts-ignore
-			const setter = this[`set${key.capitalize()}`]; // use setter function if it exists
-
-			if (setter) {
-				setter.call(this, props[key]);
-			} else {
-				// @ts-ignore
-				this[key] = props[key];
-			}
-		}
-	}
-
-	toJSON(): any {
-		return Object.fromEntries(
-			this.metadata.columns // @ts-ignore
-				.map((x) => [x.propertyName, this[x.propertyName]]) // @ts-ignore
-				.concat(this.metadata.relations.map((x) => [x.propertyName, this[x.propertyName]]))
-		);
-	}
-
-	static increment<T extends BaseClass>(conditions: FindConditions<T>, propertyPath: string, value: number | string) {
-		const repository = this.getRepository();
-		return repository.increment(conditions as T, propertyPath, value);
-	}
-
-	static decrement<T extends BaseClass>(conditions: FindConditions<T>, propertyPath: string, value: number | string) {
-		const repository = this.getRepository();
-		return repository.decrement(conditions as T, propertyPath, value);
-	}
-}
-
-export const PrimaryIdColumn = process.env.DATABASE?.startsWith("mongodb") ? ObjectIdColumn : PrimaryColumn;
-
-export class BaseClass extends BaseClassWithoutId {
-	@PrimaryIdColumn()
-	id: string;
-
-	assign(props: any = {}) {
-		super.assign(props);
-		if (!this.id) this.id = Snowflake.generate();
-		return this;
-	}
-}
diff --git a/util/src/entities/Categories.ts b/util/src/entities/Categories.ts
deleted file mode 100644
index 81fbc303..00000000
--- a/util/src/entities/Categories.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import { PrimaryColumn, Column, Entity} from "typeorm";
-import { BaseClassWithoutId } from "./BaseClass";
-
-// TODO: categories:
-// [{
-// 	"id": 16,
-// 	"default": "Anime & Manga",
-// 	"localizations": {
-// 			"de": "Anime & Manga",
-// 			"fr": "Anim\u00e9s et mangas",
-// 			"ru": "\u0410\u043d\u0438\u043c\u0435 \u0438 \u043c\u0430\u043d\u0433\u0430"
-// 		}
-// 	},
-// 	"is_primary": false/true
-// }]
-// Also populate discord default categories
-
-@Entity("categories")
-export class Categories extends BaseClassWithoutId { // Not using snowflake
-    
-    @PrimaryColumn()
-	id: number;
-
-    @Column({ nullable: true })
-    name: string;
-
-    @Column({ type: "simple-json" })
-    localizations: string;
-
-    @Column({ nullable: true })
-    is_primary: boolean;
-
-}
\ No newline at end of file
diff --git a/util/src/entities/Channel.ts b/util/src/entities/Channel.ts
deleted file mode 100644
index 69c08be7..00000000
--- a/util/src/entities/Channel.ts
+++ /dev/null
@@ -1,380 +0,0 @@
-import { Column, Entity, JoinColumn, ManyToOne, OneToMany, RelationId } from "typeorm";

-import { BaseClass } from "./BaseClass";

-import { Guild } from "./Guild";

-import { PublicUserProjection, User } from "./User";

-import { HTTPError } from "lambert-server";

-import { containsAll, emitEvent, getPermission, Snowflake, trimSpecial, InvisibleCharacters } from "../util";

-import { ChannelCreateEvent, ChannelRecipientRemoveEvent } from "../interfaces";

-import { Recipient } from "./Recipient";

-import { Message } from "./Message";

-import { ReadState } from "./ReadState";

-import { Invite } from "./Invite";

-import { VoiceState } from "./VoiceState";

-import { Webhook } from "./Webhook";

-import { DmChannelDTO } from "../dtos";

-

-export enum ChannelType {

-	GUILD_TEXT = 0, // a text channel within a guild

-	DM = 1, // a direct message between users

-	GUILD_VOICE = 2, // a voice channel within a guild

-	GROUP_DM = 3, // a direct message between multiple users

-	GUILD_CATEGORY = 4, // an organizational category that contains zero or more channels

-	GUILD_NEWS = 5, // a channel that users can follow and crosspost into a guild or route

-	GUILD_STORE = 6, // a channel in which game developers can sell their things

-	ENCRYPTED = 7, // end-to-end encrypted channel

-	ENCRYPTED_THREAD = 8, // end-to-end encrypted thread channel

-	TRANSACTIONAL = 9, // event chain style transactional channel

-	GUILD_NEWS_THREAD = 10, // a temporary sub-channel within a GUILD_NEWS channel

-	GUILD_PUBLIC_THREAD = 11, // a temporary sub-channel within a GUILD_TEXT channel

-	GUILD_PRIVATE_THREAD = 12, // a temporary sub-channel within a GUILD_TEXT channel that is only viewable by those invited and those with the MANAGE_THREADS permission

-	GUILD_STAGE_VOICE = 13, // a voice channel for hosting events with an audience

-	DIRECTORY = 14, // guild directory listing channel

-	GUILD_FORUM = 15, // forum composed of IM threads

-	TICKET_TRACKER = 33, // ticket tracker, individual ticket items shall have type 12

-	KANBAN = 34, // confluence like kanban board

-	VOICELESS_WHITEBOARD = 35, // whiteboard but without voice (whiteboard + voice is the same as stage)

-	CUSTOM_START = 64, // start custom channel types from here

-	UNHANDLED = 255 // unhandled unowned pass-through channel type

-}

-

-@Entity("channels")

-export class Channel extends BaseClass {

-	@Column()

-	created_at: Date;

-

-	@Column({ nullable: true })

-	name?: string;

-

-	@Column({ type: "text", nullable: true })

-	icon?: string | null;

-

-	@Column({ type: "int" })

-	type: ChannelType;

-

-	@OneToMany(() => Recipient, (recipient: Recipient) => recipient.channel, {

-		cascade: true,

-		orphanedRowAction: "delete",

-	})

-	recipients?: Recipient[];

-

-	@Column({ nullable: true })

-	last_message_id: string;

-

-	@Column({ nullable: true })

-	@RelationId((channel: Channel) => channel.guild)

-	guild_id?: string;

-

-	@JoinColumn({ name: "guild_id" })

-	@ManyToOne(() => Guild, {

-		onDelete: "CASCADE",

-	})

-	guild: Guild;

-

-	@Column({ nullable: true })

-	@RelationId((channel: Channel) => channel.parent)

-	parent_id: string;

-

-	@JoinColumn({ name: "parent_id" })

-	@ManyToOne(() => Channel)

-	parent?: Channel;

-

-	// for group DMs and owned custom channel types

-	@Column({ nullable: true })

-	@RelationId((channel: Channel) => channel.owner)

-	owner_id: string;

-

-	@JoinColumn({ name: "owner_id" })

-	@ManyToOne(() => User)

-	owner: User;

-

-	@Column({ nullable: true })

-	last_pin_timestamp?: number;

-

-	@Column({ nullable: true })

-	default_auto_archive_duration?: number;

-

-	@Column({ nullable: true })

-	position?: number;

-

-	@Column({ type: "simple-json", nullable: true })

-	permission_overwrites?: ChannelPermissionOverwrite[];

-

-	@Column({ nullable: true })

-	video_quality_mode?: number;

-

-	@Column({ nullable: true })

-	bitrate?: number;

-

-	@Column({ nullable: true })

-	user_limit?: number;

-

-	@Column({ nullable: true })

-	nsfw?: boolean;

-

-	@Column({ nullable: true })

-	rate_limit_per_user?: number;

-

-	@Column({ nullable: true })

-	topic?: string;

-

-	@OneToMany(() => Invite, (invite: Invite) => invite.channel, {

-		cascade: true,

-		orphanedRowAction: "delete",

-	})

-	invites?: Invite[];

-

-	@Column({ nullable: true })

-	retention_policy_id?: string;

-

-	@OneToMany(() => Message, (message: Message) => message.channel, {

-		cascade: true,

-		orphanedRowAction: "delete",

-	})

-	messages?: Message[];

-

-	@OneToMany(() => VoiceState, (voice_state: VoiceState) => voice_state.channel, {

-		cascade: true,

-		orphanedRowAction: "delete",

-	})

-	voice_states?: VoiceState[];

-

-	@OneToMany(() => ReadState, (read_state: ReadState) => read_state.channel, {

-		cascade: true,

-		orphanedRowAction: "delete",

-	})

-	read_states?: ReadState[];

-

-	@OneToMany(() => Webhook, (webhook: Webhook) => webhook.channel, {

-		cascade: true,

-		orphanedRowAction: "delete",

-	})

-	webhooks?: Webhook[];

-	

-	// TODO: DM channel

-	static async createChannel(

-		channel: Partial<Channel>,

-		user_id: string = "0",

-		opts?: {

-			keepId?: boolean;

-			skipExistsCheck?: boolean;

-			skipPermissionCheck?: boolean;

-			skipEventEmit?: boolean;

-			skipNameChecks?: boolean;

-		}

-	) {

-		if (!opts?.skipPermissionCheck) {

-			// Always check if user has permission first

-			const permissions = await getPermission(user_id, channel.guild_id);

-			permissions.hasThrow("MANAGE_CHANNELS");

-		}

-

-		if (!opts?.skipNameChecks) {

-			const guild = await Guild.findOneOrFail({ id: channel.guild_id });

-			if (!guild.features.includes("ALLOW_INVALID_CHANNEL_NAMES") && channel.name) {

-				for (var character of InvisibleCharacters)

-					if (channel.name.includes(character))

-						throw new HTTPError("Channel name cannot include invalid characters", 403);

-

-				if (channel.name.match(/\-\-+/g))

-					throw new HTTPError("Channel name cannot include multiple adjacent dashes.", 403)

-

-				if (channel.name.charAt(0) === "-" ||

-					channel.name.charAt(channel.name.length - 1) === "-")

-					throw new HTTPError("Channel name cannot start/end with dash.", 403)

-			}

-

-			if (!guild.features.includes("ALLOW_UNNAMED_CHANNELS")) {

-				if (!channel.name)

-					throw new HTTPError("Channel name cannot be empty.", 403);

-			}

-		}

-

-		switch (channel.type) {

-			case ChannelType.GUILD_TEXT:

-			case ChannelType.GUILD_NEWS:

-			case ChannelType.GUILD_VOICE:

-				if (channel.parent_id && !opts?.skipExistsCheck) {

-					const exists = await Channel.findOneOrFail({ id: channel.parent_id });

-					if (!exists) throw new HTTPError("Parent id channel doesn't exist", 400);

-					if (exists.guild_id !== channel.guild_id)

-						throw new HTTPError("The category channel needs to be in the guild");

-				}

-				break;

-			case ChannelType.GUILD_CATEGORY:

-			case ChannelType.UNHANDLED:

-				break;

-			case ChannelType.DM:

-			case ChannelType.GROUP_DM:

-				throw new HTTPError("You can't create a dm channel in a guild");

-			case ChannelType.GUILD_STORE:

-			default:

-				throw new HTTPError("Not yet supported");

-		}

-

-		if (!channel.permission_overwrites) channel.permission_overwrites = [];

-		// TODO: eagerly auto generate position of all guild channels

-

-		channel = {

-			...channel,

-			...(!opts?.keepId && { id: Snowflake.generate() }),

-			created_at: new Date(),

-			position: (channel.type === ChannelType.UNHANDLED ? 0 : channel.position) || 0,

-		};

-

-		await Promise.all([

-			new Channel(channel).save(),

-			!opts?.skipEventEmit

-				? emitEvent({

-					event: "CHANNEL_CREATE",

-					data: channel,

-					guild_id: channel.guild_id,

-				} as ChannelCreateEvent)

-				: Promise.resolve(),

-		]);

-

-		return channel;

-	}

-

-	static async createDMChannel(recipients: string[], creator_user_id: string, name?: string) {

-		recipients = recipients.unique().filter((x) => x !== creator_user_id);

-		const otherRecipientsUsers = await User.find({ where: recipients.map((x) => ({ id: x })) });

-

-		// TODO: check config for max number of recipients

-		/** if you want to disallow note to self channels, uncomment the conditional below

-		if (otherRecipientsUsers.length !== recipients.length) {

-			throw new HTTPError("Recipient/s not found");

-		}

-		**/

-

-		const type = recipients.length > 1 ? ChannelType.DM : ChannelType.GROUP_DM;

-

-		let channel = null;

-

-		const channelRecipients = [...recipients, creator_user_id];

-

-		const userRecipients = await Recipient.find({

-			where: { user_id: creator_user_id },

-			relations: ["channel", "channel.recipients"],

-		});

-

-		for (let ur of userRecipients) {

-			let re = ur.channel.recipients!.map((r) => r.user_id);

-			if (re.length === channelRecipients.length) {

-				if (containsAll(re, channelRecipients)) {

-					if (channel == null) {

-						channel = ur.channel;

-						await ur.assign({ closed: false }).save();

-					}

-				}

-			}

-		}

-

-		if (channel == null) {

-			name = trimSpecial(name);

-

-			channel = await new Channel({

-				name,

-				type,

-				owner_id: type === ChannelType.DM ? undefined : null, // 1:1 DMs are ownerless in fosscord-server

-				created_at: new Date(),

-				last_message_id: null,

-				recipients: channelRecipients.map(

-					(x) =>

-						new Recipient({ user_id: x, closed: !(type === ChannelType.GROUP_DM || x === creator_user_id) })

-				),

-			}).save();

-		}

-

-		const channel_dto = await DmChannelDTO.from(channel);

-

-		if (type === ChannelType.GROUP_DM) {

-			for (let recipient of channel.recipients!) {

-				await emitEvent({

-					event: "CHANNEL_CREATE",

-					data: channel_dto.excludedRecipients([recipient.user_id]),

-					user_id: recipient.user_id,

-				});

-			}

-		} else {

-			await emitEvent({ event: "CHANNEL_CREATE", data: channel_dto, user_id: creator_user_id });

-		}

-

-		if (recipients.length === 1) return channel_dto; 

-		else return channel_dto.excludedRecipients([creator_user_id]);

-	}

-

-	static async removeRecipientFromChannel(channel: Channel, user_id: string) {

-		await Recipient.delete({ channel_id: channel.id, user_id: user_id });

-		channel.recipients = channel.recipients?.filter((r) => r.user_id !== user_id);

-

-		if (channel.recipients?.length === 0) {

-			await Channel.deleteChannel(channel);

-			await emitEvent({

-				event: "CHANNEL_DELETE",

-				data: await DmChannelDTO.from(channel, [user_id]),

-				user_id: user_id,

-			});

-			return;

-		}

-

-		await emitEvent({

-			event: "CHANNEL_DELETE",

-			data: await DmChannelDTO.from(channel, [user_id]),

-			user_id: user_id,

-		});

-

-		//If the owner leave the server user is the new owner

-		if (channel.owner_id === user_id) {

-			channel.owner_id = "1"; // The channel is now owned by the server user

-			await emitEvent({

-				event: "CHANNEL_UPDATE",

-				data: await DmChannelDTO.from(channel, [user_id]),

-				channel_id: channel.id,

-			});

-		}

-

-		await channel.save();

-

-		await emitEvent({

-			event: "CHANNEL_RECIPIENT_REMOVE",

-			data: {

-				channel_id: channel.id,

-				user: await User.findOneOrFail({ where: { id: user_id }, select: PublicUserProjection }),

-			},

-			channel_id: channel.id,

-		} as ChannelRecipientRemoveEvent);

-	}

-

-	static async deleteChannel(channel: Channel) {

-		await Message.delete({ channel_id: channel.id }); //TODO we should also delete the attachments from the cdn but to do that we need to move cdn.ts in util

-		//TODO before deleting the channel we should check and delete other relations

-		await Channel.delete({ id: channel.id });

-	}

-

-	isDm() {

-		return this.type === ChannelType.DM || this.type === ChannelType.GROUP_DM;

-	}

-

-	// Does the channel support sending messages ( eg categories do not )

-	isWritable() {

-		const disallowedChannelTypes = [

-			ChannelType.GUILD_CATEGORY,

-			ChannelType.GUILD_STAGE_VOICE,

-			ChannelType.VOICELESS_WHITEBOARD,

-		];

-		return disallowedChannelTypes.indexOf(this.type) == -1;

-	}

-}

-

-export interface ChannelPermissionOverwrite {

-	allow: string;

-	deny: string;

-	id: string;

-	type: ChannelPermissionOverwriteType;

-}

-

-export enum ChannelPermissionOverwriteType {

-	role = 0,

-	member = 1,

-	group = 2,

-}

diff --git a/util/src/entities/ClientRelease.ts b/util/src/entities/ClientRelease.ts
deleted file mode 100644
index c5afd307..00000000
--- a/util/src/entities/ClientRelease.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import { Column, Entity} from "typeorm";
-import { BaseClass } from "./BaseClass";
-
-@Entity("client_release")
-export class Release extends BaseClass {
-	@Column()
-	name: string;
-
-	@Column()
-	pub_date: string;
-
-	@Column()
-	url: string;
-
-	@Column()
-	deb_url: string;
-
-	@Column()
-	osx_url: string;
-
-	@Column()
-	win_url: string;
-
-	@Column({ nullable: true })
-	notes?: string;
-}
diff --git a/util/src/entities/Config.ts b/util/src/entities/Config.ts
deleted file mode 100644
index 3756d686..00000000
--- a/util/src/entities/Config.ts
+++ /dev/null
@@ -1,407 +0,0 @@
-import { Column, Entity } from "typeorm";
-import { BaseClassWithoutId, PrimaryIdColumn } from "./BaseClass";
-import crypto from "crypto";
-import { Snowflake } from "../util/Snowflake";
-import { SessionsReplace } from "..";
-import { hostname } from "os";
-
-@Entity("config")
-export class ConfigEntity extends BaseClassWithoutId {
-	@PrimaryIdColumn()
-	key: string;
-
-	@Column({ type: "simple-json", nullable: true })
-	value: number | boolean | null | string | undefined;
-}
-
-export interface RateLimitOptions {
-	bot?: number;
-	count: number;
-	window: number;
-	onyIp?: boolean;
-}
-
-export interface Region {
-	id: string;
-	name: string;
-	endpoint: string;
-	location?: {
-		latitude: number;
-		longitude: number;
-	};
-	vip: boolean;
-	custom: boolean;
-	deprecated: boolean;
-}
-
-export interface KafkaBroker {
-	ip: string;
-	port: number;
-}
-
-export interface ConfigValue {
-	gateway: {
-		endpointClient: string | null;
-		endpointPrivate: string | null;
-		endpointPublic: string | null;
-	};
-	cdn: {
-		endpointClient: string | null;
-		endpointPublic: string | null;
-		endpointPrivate: string | null;
-	};
-	api: {
-		defaultVersion: string;
-		activeVersions: string[];
-		useFosscordEnhancements: boolean;
-	};
-	general: {
-		instanceName: string;
-		instanceDescription: string | null;
-		frontPage: string | null;
-		tosPage: string | null;
-		correspondenceEmail: string | null;
-		correspondenceUserID: string | null;
-		image: string | null;
-		instanceId: string;
-	};
-	limits: {
-		user: {
-			maxGuilds: number;
-			maxUsername: number;
-			maxFriends: number;
-		};
-		guild: {
-			maxRoles: number;
-			maxEmojis: number;
-			maxMembers: number;
-			maxChannels: number;
-			maxChannelsInCategory: number;
-			hideOfflineMember: number;
-		};
-		message: {
-			maxCharacters: number;
-			maxTTSCharacters: number;
-			maxReactions: number;
-			maxAttachmentSize: number;
-			maxBulkDelete: number;
-			maxEmbedDownloadSize: number;
-		};
-		channel: {
-			maxPins: number;
-			maxTopic: number;
-			maxWebhooks: number;
-		};
-		rate: {
-			disabled: boolean;
-			ip: Omit<RateLimitOptions, "bot_count">;
-			global: RateLimitOptions;
-			error: RateLimitOptions;
-			routes: {
-				guild: RateLimitOptions;
-				webhook: RateLimitOptions;
-				channel: RateLimitOptions;
-				auth: {
-					login: RateLimitOptions;
-					register: RateLimitOptions;
-				};
-				// TODO: rate limit configuration for all routes
-			};
-		};
-	};
-	security: {
-		autoUpdate: boolean | number;
-		requestSignature: string;
-		jwtSecret: string;
-		forwadedFor: string | null; // header to get the real user ip address
-		captcha: {
-			enabled: boolean;
-			service: "recaptcha" | "hcaptcha" | null; // TODO: hcaptcha, custom
-			sitekey: string | null;
-			secret: string | null;
-		};
-		ipdataApiKey: string | null;
-	};
-	login: {
-		requireCaptcha: boolean;
-	};
-	register: {
-		email: {
-			required: boolean;
-			allowlist: boolean;
-			blocklist: boolean;
-			domains: string[];
-		};
-		dateOfBirth: {
-			required: boolean;
-			minimum: number; // in years
-		};
-		disabled: boolean;
-		requireCaptcha: boolean;
-		requireInvite: boolean;
-		guestsRequireInvite: boolean;
-		allowNewRegistration: boolean;
-		allowMultipleAccounts: boolean;
-		blockProxies: boolean;
-		password: {
-			required: boolean;
-			minLength: number;
-			minNumbers: number;
-			minUpperCase: number;
-			minSymbols: number;
-		};
-		incrementingDiscriminators: boolean; // random otherwise
-	};
-	regions: {
-		default: string;
-		useDefaultAsOptimal: boolean;
-		available: Region[];
-	};
-	guild: {
-		discovery: {
-			showAllGuilds: boolean;
-			useRecommendation: boolean; // TODO: Recommendation, privacy concern?
-			offset: number;
-			limit: number;
-		};
-		autoJoin: {
-			enabled: boolean;
-			guilds: string[];
-			canLeave: boolean;
-		};
-	};
-	gif: {
-		enabled: boolean;
-		provider: "tenor"; // more coming soon
-		apiKey?: string;
-	};
-	rabbitmq: {
-		host: string | null;
-	};
-	kafka: {
-		brokers: KafkaBroker[] | null;
-	};
-	templates: {
-		enabled: Boolean;
-		allowTemplateCreation: Boolean;
-		allowDiscordTemplates: Boolean;
-		allowRaws: Boolean;
-	},
-	client: {
-		useTestClient: Boolean;
-		releases: {
-			useLocalRelease: Boolean; //TODO
-			upstreamVersion: string;
-		}
-	},
-	metrics: {
-		timeout: number;
-	},
-	sentry: {
-		enabled: boolean;
-		endpoint: string;
-		traceSampleRate: number;
-		environment: string;
-	}
-}
-
-export const DefaultConfigOptions: ConfigValue = {
-	gateway: {
-		endpointClient: null,
-		endpointPrivate: null,
-		endpointPublic: null,
-	},
-	cdn: {
-		endpointClient: null,
-		endpointPrivate: null,
-		endpointPublic: null,
-	},
-	api: {
-		defaultVersion: "9",
-		activeVersions: ["6", "7", "8", "9"],
-		useFosscordEnhancements: true,
-	},
-	general: {
-		instanceName: "Fosscord Instance",
-		instanceDescription: "This is a Fosscord instance made in pre-release days",
-		frontPage: null,
-		tosPage: null,
-		correspondenceEmail: "noreply@localhost.local",
-		correspondenceUserID: null,
-		image: null,
-		instanceId: Snowflake.generate(),
-	},
-	limits: {
-		user: {
-			maxGuilds: 1048576,
-			maxUsername: 127,
-			maxFriends: 5000,
-		},
-		guild: {
-			maxRoles: 1000,
-			maxEmojis: 2000,
-			maxMembers: 25000000,
-			maxChannels: 65535,
-			maxChannelsInCategory: 65535,
-			hideOfflineMember: 3,
-		},
-		message: {
-			maxCharacters: 1048576,
-			maxTTSCharacters: 160,
-			maxReactions: 2048,
-			maxAttachmentSize: 1024 * 1024 * 1024,
-			maxEmbedDownloadSize: 1024 * 1024 * 5,
-			maxBulkDelete: 1000,
-		},
-		channel: {
-			maxPins: 500,
-			maxTopic: 1024,
-			maxWebhooks: 100,
-		},
-		rate: {
-			disabled: true,
-			ip: {
-				count: 500,
-				window: 5,
-			},
-			global: {
-				count: 250,
-				window: 5,
-			},
-			error: {
-				count: 10,
-				window: 5,
-			},
-			routes: {
-				guild: {
-					count: 5,
-					window: 5,
-				},
-				webhook: {
-					count: 10,
-					window: 5,
-				},
-				channel: {
-					count: 10,
-					window: 5,
-				},
-				auth: {
-					login: {
-						count: 5,
-						window: 60,
-					},
-					register: {
-						count: 2,
-						window: 60 * 60 * 12,
-					},
-				},
-			},
-		},
-	},
-	security: {
-		autoUpdate: true,
-		requestSignature: crypto.randomBytes(32).toString("base64"),
-		jwtSecret: crypto.randomBytes(256).toString("base64"),
-		forwadedFor: null,
-		// forwadedFor: "X-Forwarded-For" // nginx/reverse proxy
-		// forwadedFor: "CF-Connecting-IP" // cloudflare:
-		captcha: {
-			enabled: false,
-			service: null,
-			sitekey: null,
-			secret: null,
-		},
-		ipdataApiKey: "eca677b284b3bac29eb72f5e496aa9047f26543605efe99ff2ce35c9",
-	},
-	login: {
-		requireCaptcha: false,
-	},
-	register: {
-		email: {
-			required: false,
-			allowlist: false,
-			blocklist: true,
-			domains: [], // TODO: efficiently save domain blocklist in database
-			// domains: fs.readFileSync(__dirname + "/blockedEmailDomains.txt", { encoding: "utf8" }).split("\n"),
-		},
-		dateOfBirth: {
-			required: true,
-			minimum: 13,
-		},
-		disabled: false,
-		requireInvite: false,
-		guestsRequireInvite: true,
-		requireCaptcha: true,
-		allowNewRegistration: true,
-		allowMultipleAccounts: true,
-		blockProxies: true,
-		password: {
-			required: false,
-			minLength: 8,
-			minNumbers: 2,
-			minUpperCase: 2,
-			minSymbols: 0,
-		},
-		incrementingDiscriminators: false,
-	},
-	regions: {
-		default: "fosscord",
-		useDefaultAsOptimal: true,
-		available: [
-			{
-				id: "fosscord",
-				name: "Fosscord",
-				endpoint: "127.0.0.1:3004",
-				vip: false,
-				custom: false,
-				deprecated: false,
-			},
-		],
-	},
-	guild: {
-		discovery: {
-			showAllGuilds: false,
-			useRecommendation: false,
-			offset: 0,
-			limit: 24,
-		},
-		autoJoin: {
-			enabled: true,
-			canLeave: true,
-			guilds: [],
-		},
-	},
-	gif: {
-		enabled: true,
-		provider: "tenor",
-		apiKey: "LIVDSRZULELA",
-	},
-	rabbitmq: {
-		host: null,
-	},
-	kafka: {
-		brokers: null,
-	},
-	templates: {
-		enabled: true,
-		allowTemplateCreation: true,
-		allowDiscordTemplates: true,
-		allowRaws: false
-	},
-	client: {
-		useTestClient: true,
-		releases: {
-			useLocalRelease: true,
-			upstreamVersion: "0.0.264"
-		}
-	},
-	metrics: {
-		timeout: 30000
-	},
-	sentry: {
-		enabled: false,
-		endpoint: "https://05e8e3d005f34b7d97e920ae5870a5e5@sentry.thearcanebrony.net/6",
-		traceSampleRate: 1.0,
-		environment: hostname()
-	}
-};
diff --git a/util/src/entities/ConnectedAccount.ts b/util/src/entities/ConnectedAccount.ts
deleted file mode 100644
index 09ae30ab..00000000
--- a/util/src/entities/ConnectedAccount.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
-import { BaseClass } from "./BaseClass";
-import { User } from "./User";
-
-export interface PublicConnectedAccount extends Pick<ConnectedAccount, "name" | "type" | "verified"> {}
-
-@Entity("connected_accounts")
-export class ConnectedAccount extends BaseClass {
-	@Column({ nullable: true })
-	@RelationId((account: ConnectedAccount) => account.user)
-	user_id: string;
-
-	@JoinColumn({ name: "user_id" })
-	@ManyToOne(() => User, {
-		onDelete: "CASCADE",
-	})
-	user: User;
-
-	@Column({ select: false })
-	access_token: string;
-
-	@Column({ select: false })
-	friend_sync: boolean;
-
-	@Column()
-	name: string;
-
-	@Column({ select: false })
-	revoked: boolean;
-
-	@Column({ select: false })
-	show_activity: boolean;
-
-	@Column()
-	type: string;
-
-	@Column()
-	verified: boolean;
-
-	@Column({ select: false })
-	visibility: number;
-}
diff --git a/util/src/entities/Emoji.ts b/util/src/entities/Emoji.ts
deleted file mode 100644
index a3615b7d..00000000
--- a/util/src/entities/Emoji.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
-import { User } from ".";
-import { BaseClass } from "./BaseClass";
-import { Guild } from "./Guild";
-import { Role } from "./Role";
-
-@Entity("emojis")
-export class Emoji extends BaseClass {
-	@Column()
-	animated: boolean;
-
-	@Column()
-	available: boolean; // whether this emoji can be used, may be false due to various reasons
-
-	@Column()
-	guild_id: string;
-
-	@JoinColumn({ name: "guild_id" })
-	@ManyToOne(() => Guild, {
-		onDelete: "CASCADE",
-	})
-	guild: Guild;
-
-	@Column({ nullable: true })
-	@RelationId((emoji: Emoji) => emoji.user)
-	user_id: string;
-
-	@JoinColumn({ name: "user_id" })
-	@ManyToOne(() => User)
-	user: User;
-
-	@Column()
-	managed: boolean;
-
-	@Column()
-	name: string;
-
-	@Column()
-	require_colons: boolean;
-
-	@Column({ type: "simple-array" })
-	roles: string[]; // roles this emoji is whitelisted to (new discord feature?)
-	
-	@Column({ type: "simple-array", nullable: true })
-	groups: string[]; // user groups this emoji is whitelisted to (Fosscord extension)
-}
diff --git a/util/src/entities/Encryption.ts b/util/src/entities/Encryption.ts
deleted file mode 100644
index 3b82ff84..00000000
--- a/util/src/entities/Encryption.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import { Column, Entity, JoinColumn, ManyToOne, OneToMany, RelationId } from "typeorm";
-import { BaseClass } from "./BaseClass";
-import { Guild } from "./Guild";
-import { PublicUserProjection, User } from "./User";
-import { HTTPError } from "lambert-server";
-import { containsAll, emitEvent, getPermission, Snowflake, trimSpecial, InvisibleCharacters } from "../util";
-import { BitField, BitFieldResolvable, BitFlag } from "../util/BitField";
-import { Recipient } from "./Recipient";
-import { Message } from "./Message";
-import { ReadState } from "./ReadState";
-import { Invite } from "./Invite";
-import { DmChannelDTO } from "../dtos";
-
-@Entity("security_settings")
-export class SecuritySettings extends BaseClass {
-
-  @Column({nullable: true})
-  guild_id: Snowflake;
-
-  @Column({nullable: true})
-  channel_id: Snowflake;
-
-  @Column()
-  encryption_permission_mask: BitField;
-
-  @Column()
-  allowed_algorithms: string[];
-
-  @Column()
-  current_algorithm: string;
-
-  @Column({nullable: true})
-  used_since_message: Snowflake;
-
-}
diff --git a/util/src/entities/Group.ts b/util/src/entities/Group.ts
deleted file mode 100644
index b24d38cf..00000000
--- a/util/src/entities/Group.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
-
-import { BaseClass } from "./BaseClass";
-
-@Entity("groups")
-export class UserGroup extends BaseClass {
-  @Column({ nullable: true })
-  parent?: BigInt;
-
-	@Column()
-	color: number;
-
-	@Column()
-	hoist: boolean;
-
- 	@Column()
-	mentionable: boolean;
-
-	@Column()
-	name: string;
-
-	@Column()
-	rights: BigInt;
-
-	@Column()
-	position: number;
-
-	@Column({ nullable: true })
-	icon: BigInt;
-
-	@Column({ nullable: true })
-	unicode_emoji: BigInt;
-}
diff --git a/util/src/entities/Guild.ts b/util/src/entities/Guild.ts
deleted file mode 100644
index 70bb41c5..00000000
--- a/util/src/entities/Guild.ts
+++ /dev/null
@@ -1,363 +0,0 @@
-import { Column, Entity, JoinColumn, ManyToMany, ManyToOne, OneToMany, OneToOne, RelationId } from "typeorm";
-import { Config, handleFile, Snowflake } from "..";
-import { Ban } from "./Ban";
-import { BaseClass } from "./BaseClass";
-import { Channel } from "./Channel";
-import { Emoji } from "./Emoji";
-import { Invite } from "./Invite";
-import { Member } from "./Member";
-import { Role } from "./Role";
-import { Sticker } from "./Sticker";
-import { Template } from "./Template";
-import { User } from "./User";
-import { VoiceState } from "./VoiceState";
-import { Webhook } from "./Webhook";
-
-// TODO: application_command_count, application_command_counts: {1: 0, 2: 0, 3: 0}
-// TODO: guild_scheduled_events
-// TODO: stage_instances
-// TODO: threads
-// TODO:
-// "keywords": [
-// 		"Genshin Impact",
-// 		"Paimon",
-// 		"Honkai Impact",
-// 		"ARPG",
-// 		"Open-World",
-// 		"Waifu",
-// 		"Anime",
-// 		"Genshin",
-// 		"miHoYo",
-// 		"Gacha"
-// 	],
-
-export const PublicGuildRelations = [
-	"channels",
-	"emojis",
-	"members",
-	"roles",
-	"stickers",
-	"voice_states",
-	"members.user",
-];
-
-@Entity("guilds")
-export class Guild extends BaseClass {
-	@Column({ nullable: true })
-	@RelationId((guild: Guild) => guild.afk_channel)
-	afk_channel_id?: string;
-
-	@JoinColumn({ name: "afk_channel_id" })
-	@ManyToOne(() => Channel)
-	afk_channel?: Channel;
-
-	@Column({ nullable: true })
-	afk_timeout?: number;
-
-	// * commented out -> use owner instead
-	// application id of the guild creator if it is bot-created
-	// @Column({ nullable: true })
-	// application?: string;
-
-	@JoinColumn({ name: "ban_ids" })
-	@OneToMany(() => Ban, (ban: Ban) => ban.guild, {
-		cascade: true,
-		orphanedRowAction: "delete",
-	})
-	bans: Ban[];
-
-	@Column({ nullable: true })
-	banner?: string;
-
-	@Column({ nullable: true })
-	default_message_notifications?: number;
-
-	@Column({ nullable: true })
-	description?: string;
-
-	@Column({ nullable: true })
-	discovery_splash?: string;
-
-	@Column({ nullable: true })
-	explicit_content_filter?: number;
-
-	@Column({ type: "simple-array" })
-	features: string[]; //TODO use enum
-	//TODO: https://discord.com/developers/docs/resources/guild#guild-object-guild-features
-
-	@Column({ nullable: true })
-	primary_category_id: number;
-
-	@Column({ nullable: true })
-	icon?: string;
-
-	@Column({ nullable: true })
-	large?: boolean;
-
-	@Column({ nullable: true })
-	max_members?: number; // e.g. default 100.000
-
-	@Column({ nullable: true })
-	max_presences?: number;
-
-	@Column({ nullable: true })
-	max_video_channel_users?: number; // ? default: 25, is this max 25 streaming or watching
-
-	@Column({ nullable: true })
-	member_count?: number;
-
-	@Column({ nullable: true })
-	presence_count?: number; // users online
-
-	@OneToMany(() => Member, (member: Member) => member.guild, {
-		cascade: true,
-		orphanedRowAction: "delete",
-		onDelete: "CASCADE",
-	})
-	members: Member[];
-
-	@JoinColumn({ name: "role_ids" })
-	@OneToMany(() => Role, (role: Role) => role.guild, {
-		cascade: true,
-		orphanedRowAction: "delete",
-		onDelete: "CASCADE",
-	})
-	roles: Role[];
-
-	@JoinColumn({ name: "channel_ids" })
-	@OneToMany(() => Channel, (channel: Channel) => channel.guild, {
-		cascade: true,
-		orphanedRowAction: "delete",
-	})
-	channels: Channel[];
-
-	@Column({ nullable: true })
-	@RelationId((guild: Guild) => guild.template)
-	template_id?: string;
-
-	@JoinColumn({ name: "template_id", referencedColumnName: "id" })
-	@ManyToOne(() => Template)
-	template: Template;
-
-	@JoinColumn({ name: "emoji_ids" })
-	@OneToMany(() => Emoji, (emoji: Emoji) => emoji.guild, {
-		cascade: true,
-		orphanedRowAction: "delete",
-		onDelete: "CASCADE",
-	})
-	emojis: Emoji[];
-
-	@JoinColumn({ name: "sticker_ids" })
-	@OneToMany(() => Sticker, (sticker: Sticker) => sticker.guild, {
-		cascade: true,
-		orphanedRowAction: "delete",
-		onDelete: "CASCADE",
-	})
-	stickers: Sticker[];
-
-	@JoinColumn({ name: "invite_ids" })
-	@OneToMany(() => Invite, (invite: Invite) => invite.guild, {
-		cascade: true,
-		orphanedRowAction: "delete",
-		onDelete: "CASCADE",
-	})
-	invites: Invite[];
-
-	@JoinColumn({ name: "voice_state_ids" })
-	@OneToMany(() => VoiceState, (voicestate: VoiceState) => voicestate.guild, {
-		cascade: true,
-		orphanedRowAction: "delete",
-		onDelete: "CASCADE",
-	})
-	voice_states: VoiceState[];
-
-	@JoinColumn({ name: "webhook_ids" })
-	@OneToMany(() => Webhook, (webhook: Webhook) => webhook.guild, {
-		cascade: true,
-		orphanedRowAction: "delete",
-		onDelete: "CASCADE",
-	})
-	webhooks: Webhook[];
-
-	@Column({ nullable: true })
-	mfa_level?: number;
-
-	@Column()
-	name: string;
-
-	@Column({ nullable: true })
-	@RelationId((guild: Guild) => guild.owner)
-	owner_id?: string; // optional to allow for ownerless guilds
-
-	@JoinColumn({ name: "owner_id", referencedColumnName: "id" })
-	@ManyToOne(() => User)
-	owner?: User; // optional to allow for ownerless guilds
-
-	@Column({ nullable: true })
-	preferred_locale?: string;
-
-	@Column({ nullable: true })
-	premium_subscription_count?: number;
-
-	@Column({ nullable: true })
-	premium_tier?: number; // crowd premium level
-
-	@Column({ nullable: true })
-	@RelationId((guild: Guild) => guild.public_updates_channel)
-	public_updates_channel_id: string;
-
-	@JoinColumn({ name: "public_updates_channel_id" })
-	@ManyToOne(() => Channel)
-	public_updates_channel?: Channel;
-
-	@Column({ nullable: true })
-	@RelationId((guild: Guild) => guild.rules_channel)
-	rules_channel_id?: string;
-
-	@JoinColumn({ name: "rules_channel_id" })
-	@ManyToOne(() => Channel)
-	rules_channel?: string;
-
-	@Column({ nullable: true })
-	region?: string;
-
-	@Column({ nullable: true })
-	splash?: string;
-
-	@Column({ nullable: true })
-	@RelationId((guild: Guild) => guild.system_channel)
-	system_channel_id?: string;
-
-	@JoinColumn({ name: "system_channel_id" })
-	@ManyToOne(() => Channel)
-	system_channel?: Channel;
-
-	@Column({ nullable: true })
-	system_channel_flags?: number;
-
-	@Column({ nullable: true })
-	unavailable?: boolean;
-
-	@Column({ nullable: true })
-	verification_level?: number;
-
-	@Column({ type: "simple-json" })
-	welcome_screen: {
-		enabled: boolean;
-		description: string;
-		welcome_channels: {
-			description: string;
-			emoji_id?: string;
-			emoji_name: string;
-			channel_id: string;
-		}[];
-	};
-
-	@Column({ nullable: true })
-	@RelationId((guild: Guild) => guild.widget_channel)
-	widget_channel_id?: string;
-
-	@JoinColumn({ name: "widget_channel_id" })
-	@ManyToOne(() => Channel)
-	widget_channel?: Channel;
-
-	@Column({ nullable: true })
-	widget_enabled?: boolean;
-
-	@Column({ nullable: true })
-	nsfw_level?: number;
-
-	@Column({ nullable: true })
-	nsfw?: boolean;
-	
-	// TODO: nested guilds
-	@Column({ nullable: true })
-	parent?: string;
-
-	// only for developer portal
-	permissions?: number;
-
-	static async createGuild(body: {
-		name?: string;
-		icon?: string | null;
-		owner_id?: string;
-		channels?: Partial<Channel>[];
-	}) {
-		const guild_id = Snowflake.generate();
-
-		const guild = await new Guild({
-			name: body.name || "Fosscord",
-			icon: await handleFile(`/icons/${guild_id}`, body.icon as string),
-			region: Config.get().regions.default,
-			owner_id: body.owner_id, // TODO: need to figure out a way for ownerless guilds and multiply-owned guilds
-			afk_timeout: 300,
-			default_message_notifications: 1, // defaults effect: setting the push default at mentions-only will save a lot
-			explicit_content_filter: 0,
-			features: [],
-			primary_category_id: null,
-			id: guild_id,
-			max_members: 250000,
-			max_presences: 250000,
-			max_video_channel_users: 200,
-			presence_count: 0,
-			member_count: 0, // will automatically be increased by addMember()
-			mfa_level: 0,
-			preferred_locale: "en-US",
-			premium_subscription_count: 0,
-			premium_tier: 0,
-			system_channel_flags: 4, // defaults effect: suppress the setup tips to save performance
-			unavailable: false,
-			nsfw: false,
-			nsfw_level: 0,
-			verification_level: 0,
-			welcome_screen: {
-				enabled: false,
-				description: "Fill in your description",
-				welcome_channels: [],
-			},
-			widget_enabled: true, // NB: don't set it as false to prevent artificial restrictions
-		}).save();
-
-		// we have to create the role _after_ the guild because else we would get a "SQLITE_CONSTRAINT: FOREIGN KEY constraint failed" error
-		// TODO: make the @everyone a pseudorole that is dynamically generated at runtime so we can save storage
-		await new Role({
-			id: guild_id,
-			guild_id: guild_id,
-			color: 0,
-			hoist: false,
-			managed: false,
-			// NB: in Fosscord, every role will be non-managed, as we use user-groups instead of roles for managed groups
-			mentionable: false,
-			name: "@everyone",
-			permissions: String("2251804225"),
-			position: 0,
-			icon: null,
-			unicode_emoji: null
-		}).save();
-
-		if (!body.channels || !body.channels.length) body.channels = [{ id: "01", type: 0, name: "general" }];
-
-		const ids = new Map();
-
-		body.channels.forEach((x) => {
-			if (x.id) {
-				ids.set(x.id, Snowflake.generate());
-			}
-		});
-
-		for (const channel of body.channels?.sort((a, b) => (a.parent_id ? 1 : -1))) {
-			var id = ids.get(channel.id) || Snowflake.generate();
-
-			var parent_id = ids.get(channel.parent_id);
-
-			await Channel.createChannel({ ...channel, guild_id, id, parent_id }, body.owner_id, {
-				keepId: true,
-				skipExistsCheck: true,
-				skipPermissionCheck: true,
-				skipEventEmit: true,
-			});
-		}
-
-		return guild;
-	}
-}
diff --git a/util/src/entities/Invite.ts b/util/src/entities/Invite.ts
deleted file mode 100644
index 6ac64ddc..00000000
--- a/util/src/entities/Invite.ts
+++ /dev/null
@@ -1,85 +0,0 @@
-import { Column, Entity, JoinColumn, ManyToOne, RelationId, PrimaryColumn } from "typeorm";
-import { Member } from "./Member";
-import { BaseClassWithoutId } from "./BaseClass";
-import { Channel } from "./Channel";
-import { Guild } from "./Guild";
-import { User } from "./User";
-
-export const PublicInviteRelation = ["inviter", "guild", "channel"];
-
-@Entity("invites")
-export class Invite extends BaseClassWithoutId {
-	@PrimaryColumn()
-	code: string;
-
-	@Column()
-	temporary: boolean;
-
-	@Column()
-	uses: number;
-
-	@Column()
-	max_uses: number;
-
-	@Column()
-	max_age: number;
-
-	@Column()
-	created_at: Date;
-
-	@Column()
-	expires_at: Date;
-
-	@Column({ nullable: true })
-	@RelationId((invite: Invite) => invite.guild)
-	guild_id: string;
-
-	@JoinColumn({ name: "guild_id" })
-	@ManyToOne(() => Guild, {
-		onDelete: "CASCADE",
-	})
-	guild: Guild;
-
-	@Column({ nullable: true })
-	@RelationId((invite: Invite) => invite.channel)
-	channel_id: string;
-
-	@JoinColumn({ name: "channel_id" })
-	@ManyToOne(() => Channel, {
-		onDelete: "CASCADE",
-	})
-	channel: Channel;
-
-	@Column({ nullable: true })
-	@RelationId((invite: Invite) => invite.inviter)
-	inviter_id: string;
-
-	@JoinColumn({ name: "inviter_id" })
-	@ManyToOne(() => User)
-	inviter: User;
-
-	@Column({ nullable: true })
-	@RelationId((invite: Invite) => invite.target_user)
-	target_user_id: string;
-
-	@JoinColumn({ name: "target_user_id" })
-	@ManyToOne(() => User, {
-		onDelete: "CASCADE",
-	})
-	target_user?: string; // could be used for "User specific invites" https://github.com/fosscord/fosscord/issues/62
-
-	@Column({ nullable: true })
-	target_user_type?: number;
-
-	@Column({ nullable: true })
-	vanity_url?: boolean;
-
-	static async joinGuild(user_id: string, code: string) {
-		const invite = await Invite.findOneOrFail({ code });
-		if (invite.uses++ >= invite.max_uses && invite.max_uses !== 0) await Invite.delete({ code });
-		else await invite.save();
-
-		await Member.addToGuild(user_id, invite.guild_id);
-		return invite;
-	}
-}
diff --git a/util/src/entities/Member.ts b/util/src/entities/Member.ts
deleted file mode 100644
index fe2d5590..00000000
--- a/util/src/entities/Member.ts
+++ /dev/null
@@ -1,356 +0,0 @@
-import { PublicUser, User } from "./User";
-import { BaseClass } from "./BaseClass";
-import {
-	Column,
-	Entity,
-	Index,
-	JoinColumn,
-	JoinTable,
-	ManyToMany,
-	ManyToOne,
-	PrimaryGeneratedColumn,
-	RelationId,
-} from "typeorm";
-import { Guild } from "./Guild";
-import { Config, emitEvent } from "../util";
-import {
-	GuildCreateEvent,
-	GuildDeleteEvent,
-	GuildMemberAddEvent,
-	GuildMemberRemoveEvent,
-	GuildMemberUpdateEvent,
-} from "../interfaces";
-import { HTTPError } from "lambert-server";
-import { Role } from "./Role";
-import { BaseClassWithoutId } from "./BaseClass";
-import { Ban, PublicGuildRelations } from ".";
-import { DiscordApiErrors } from "../util/Constants";
-
-export const MemberPrivateProjection: (keyof Member)[] = [
-	"id",
-	"guild",
-	"guild_id",
-	"deaf",
-	"joined_at",
-	"last_message_id",
-	"mute",
-	"nick",
-	"pending",
-	"premium_since",
-	"roles",
-	"settings",
-	"user",
-];
-
-@Entity("members")
-@Index(["id", "guild_id"], { unique: true })
-export class Member extends BaseClassWithoutId {
-	@PrimaryGeneratedColumn()
-	index: string;
-
-	@Column()
-	@RelationId((member: Member) => member.user)
-	id: string;
-
-	@JoinColumn({ name: "id" })
-	@ManyToOne(() => User, {
-		onDelete: "CASCADE",
-	})
-	user: User;
-
-	@Column()
-	@RelationId((member: Member) => member.guild)
-	guild_id: string;
-
-	@JoinColumn({ name: "guild_id" })
-	@ManyToOne(() => Guild, {
-		onDelete: "CASCADE",
-	})
-	guild: Guild;
-
-	@Column({ nullable: true })
-	nick?: string;
-	
-	@JoinTable({
-		name: "member_roles",
-		joinColumn: { name: "index", referencedColumnName: "index" },
-		inverseJoinColumn: {
-			name: "role_id",
-			referencedColumnName: "id",
-		},
-	})
-	@ManyToMany(() => Role, { cascade: true })
-	roles: Role[];
-
-	@Column()
-	joined_at: Date;
-
-	@Column({ type: "bigint", nullable: true })
-	premium_since?: number;
-
-	@Column()
-	deaf: boolean;
-
-	@Column()
-	mute: boolean;
-
-	@Column()
-	pending: boolean;
-
-	@Column({ type: "simple-json", select: false })
-	settings: UserGuildSettings;
-
-	@Column({ nullable: true })
-	last_message_id?: string;
-	
-	/**
-	@JoinColumn({ name: "id" })
-	@ManyToOne(() => User, {
-		onDelete: "DO NOTHING",
-	// do not auto-kick force-joined members just because their joiners left the server
-	}) **/
-	@Column({ nullable: true})
-	joined_by?: string;
-
-	// TODO: add this when we have proper read receipts
-	// @Column({ type: "simple-json" })
-	// read_state: ReadState;
-
-	static async IsInGuildOrFail(user_id: string, guild_id: string) {
-		if (await Member.count({ id: user_id, guild: { id: guild_id } })) return true;
-		throw new HTTPError("You are not member of this guild", 403);
-	}
-
-	static async removeFromGuild(user_id: string, guild_id: string) {
-		const guild = await Guild.findOneOrFail({ select: ["owner_id"], where: { id: guild_id } });
-		if (guild.owner_id === user_id) throw new Error("The owner cannot be removed of the guild");
-		const member = await Member.findOneOrFail({ where: { id: user_id, guild_id }, relations: ["user"] });
-
-		// use promise all to execute all promises at the same time -> save time
-		return Promise.all([
-			Member.delete({
-				id: user_id,
-				guild_id,
-			}),
-			Guild.decrement({ id: guild_id }, "member_count", -1),
-
-			emitEvent({
-				event: "GUILD_DELETE",
-				data: {
-					id: guild_id,
-				},
-				user_id: user_id,
-			} as GuildDeleteEvent),
-			emitEvent({
-				event: "GUILD_MEMBER_REMOVE",
-				data: { guild_id, user: member.user },
-				guild_id,
-			} as GuildMemberRemoveEvent),
-		]);
-	}
-
-	static async addRole(user_id: string, guild_id: string, role_id: string) {
-		const [member, role] = await Promise.all([
-			// @ts-ignore
-			Member.findOneOrFail({
-				where: { id: user_id, guild_id },
-				relations: ["user", "roles"], // we don't want to load  the role objects just the ids
-				select: ["index", "roles.id"],
-			}),
-			Role.findOneOrFail({ where: { id: role_id, guild_id }, select: ["id"] }),
-		]);
-		member.roles.push(new Role({ id: role_id }));
-
-		await Promise.all([
-			member.save(),
-			emitEvent({
-				event: "GUILD_MEMBER_UPDATE",
-				data: {
-					guild_id,
-					user: member.user,
-					roles: member.roles.map((x) => x.id),
-				},
-				guild_id,
-			} as GuildMemberUpdateEvent),
-		]);
-	}
-
-	static async removeRole(user_id: string, guild_id: string, role_id: string) {
-		const [member] = await Promise.all([
-			// @ts-ignore
-			Member.findOneOrFail({
-				where: { id: user_id, guild_id },
-				relations: ["user", "roles"], // we don't want to load  the role objects just the ids
-				select: ["roles.id", "index"],
-			}),
-			await Role.findOneOrFail({ id: role_id, guild_id }),
-		]);
-		member.roles = member.roles.filter((x) => x.id == role_id);
-
-		await Promise.all([
-			member.save(),
-			emitEvent({
-				event: "GUILD_MEMBER_UPDATE",
-				data: {
-					guild_id,
-					user: member.user,
-					roles: member.roles.map((x) => x.id),
-				},
-				guild_id,
-			} as GuildMemberUpdateEvent),
-		]);
-	}
-
-	static async changeNickname(user_id: string, guild_id: string, nickname: string) {
-		const member = await Member.findOneOrFail({
-			where: {
-				id: user_id,
-				guild_id,
-			},
-			relations: ["user"],
-		});
-		member.nick = nickname;
-
-		await Promise.all([
-			member.save(),
-
-			emitEvent({
-				event: "GUILD_MEMBER_UPDATE",
-				data: {
-					guild_id,
-					user: member.user,
-					nick: nickname,
-				},
-				guild_id,
-			} as GuildMemberUpdateEvent),
-		]);
-	}
-
-	static async addToGuild(user_id: string, guild_id: string) {
-		const user = await User.getPublicUser(user_id);
-		const isBanned = await Ban.count({ where: { guild_id, user_id } });
-		if (isBanned) {
-			throw DiscordApiErrors.USER_BANNED;
-		}
-		const { maxGuilds } = Config.get().limits.user;
-		const guild_count = await Member.count({ id: user_id });
-		if (guild_count >= maxGuilds) {
-			throw new HTTPError(`You are at the ${maxGuilds} server limit.`, 403);
-		}
-
-		const guild = await Guild.findOneOrFail({
-			where: {
-				id: guild_id,
-			},
-			relations: PublicGuildRelations,
-		});
-
-		if (await Member.count({ id: user.id, guild: { id: guild_id } }))
-			throw new HTTPError("You are already a member of this guild", 400);
-
-		const member = {
-			id: user_id,
-			guild_id,
-			nick: undefined,
-			roles: [guild_id], // @everyone role
-			joined_at: new Date(),
-			premium_since: (new Date()).getTime(),
-			deaf: false,
-			mute: false,
-			pending: false,
-		};
-
-		await Promise.all([
-			new Member({
-				...member,
-				roles: [new Role({ id: guild_id })],
-				// read_state: {},
-				settings: {
-					channel_overrides: [],
-					message_notifications: 0,
-					mobile_push: true,
-					muted: false,
-					suppress_everyone: false,
-					suppress_roles: false,
-					version: 0,
-				},
-				// Member.save is needed because else the roles relations wouldn't be updated
-			}).save(),
-			Guild.increment({ id: guild_id }, "member_count", 1),
-			emitEvent({
-				event: "GUILD_MEMBER_ADD",
-				data: {
-					...member,
-					user,
-					guild_id,
-				},
-				guild_id,
-			} as GuildMemberAddEvent),
-			emitEvent({
-				event: "GUILD_CREATE",
-				data: {
-					...guild,
-					members: [...guild.members, { ...member, user }],
-					member_count: (guild.member_count || 0) + 1,
-					guild_hashes: {},
-					guild_scheduled_events: [],
-					joined_at: member.joined_at,
-					presences: [],
-					stage_instances: [],
-					threads: [],
-				},
-				user_id,
-			} as GuildCreateEvent),
-		]);
-	}
-}
-
-export interface UserGuildSettings {
-	channel_overrides: {
-		channel_id: string;
-		message_notifications: number;
-		mute_config: MuteConfig;
-		muted: boolean;
-	}[];
-	message_notifications: number;
-	mobile_push: boolean;
-	mute_config: MuteConfig;
-	muted: boolean;
-	suppress_everyone: boolean;
-	suppress_roles: boolean;
-	version: number;
-}
-
-export interface MuteConfig {
-	end_time: number;
-	selected_time_window: number;
-}
-
-export type PublicMemberKeys =
-	| "id"
-	| "guild_id"
-	| "nick"
-	| "roles"
-	| "joined_at"
-	| "pending"
-	| "deaf"
-	| "mute"
-	| "premium_since";
-
-export const PublicMemberProjection: PublicMemberKeys[] = [
-	"id",
-	"guild_id",
-	"nick",
-	"roles",
-	"joined_at",
-	"pending",
-	"deaf",
-	"mute",
-	"premium_since",
-];
-
-// @ts-ignore
-export type PublicMember = Pick<Member, Omit<PublicMemberKeys, "roles">> & {
-	user: PublicUser;
-	roles: string[]; // only role ids not objects
-};
diff --git a/util/src/entities/Message.ts b/util/src/entities/Message.ts
deleted file mode 100644
index e18cf691..00000000
--- a/util/src/entities/Message.ts
+++ /dev/null
@@ -1,285 +0,0 @@
-import { User } from "./User";
-import { Member } from "./Member";
-import { Role } from "./Role";
-import { Channel } from "./Channel";
-import { InteractionType } from "../interfaces/Interaction";
-import { Application } from "./Application";
-import {
-	Column,
-	CreateDateColumn,
-	Entity,
-	FindConditions,
-	Index,
-	JoinColumn,
-	JoinTable,
-	ManyToMany,
-	ManyToOne,
-	OneToMany,
-	RelationId,
-	RemoveOptions,
-	UpdateDateColumn,
-} from "typeorm";
-import { BaseClass } from "./BaseClass";
-import { Guild } from "./Guild";
-import { Webhook } from "./Webhook";
-import { Sticker } from "./Sticker";
-import { Attachment } from "./Attachment";
-
-export enum MessageType {
-	DEFAULT = 0,
-	RECIPIENT_ADD = 1,
-	RECIPIENT_REMOVE = 2,
-	CALL = 3,
-	CHANNEL_NAME_CHANGE = 4,
-	CHANNEL_ICON_CHANGE = 5,
-	CHANNEL_PINNED_MESSAGE = 6,
-	GUILD_MEMBER_JOIN = 7,
-	USER_PREMIUM_GUILD_SUBSCRIPTION = 8,
-	USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1 = 9,
-	USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2 = 10,
-	USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3 = 11,
-	CHANNEL_FOLLOW_ADD = 12,
-	ACTION = 13, // /me messages
-	GUILD_DISCOVERY_DISQUALIFIED = 14,
-	GUILD_DISCOVERY_REQUALIFIED = 15,
-	ENCRYPTED = 16,
-	REPLY = 19,
-	APPLICATION_COMMAND = 20, // application command or self command invocation
-	ROUTE_ADDED = 41, // custom message routing: new route affecting that channel
-	ROUTE_DISABLED = 42, // custom message routing: given route no longer affecting that channel
-	SELF_COMMAND_SCRIPT = 43, // self command scripts
-	ENCRYPTION = 50,
-	CUSTOM_START = 63,
-	UNHANDLED = 255
-}
-
-@Entity("messages")
-@Index(["channel_id", "id"], { unique: true })
-export class Message extends BaseClass {
-	@Column({ nullable: true })
-	@RelationId((message: Message) => message.channel)
-	@Index()
-	channel_id: string;
-
-	@JoinColumn({ name: "channel_id" })
-	@ManyToOne(() => Channel, {
-		onDelete: "CASCADE",
-	})
-	channel: Channel;
-
-	@Column({ nullable: true })
-	@RelationId((message: Message) => message.guild)
-	guild_id?: string;
-
-	@JoinColumn({ name: "guild_id" })
-	@ManyToOne(() => Guild, {
-		onDelete: "CASCADE",
-	})
-	guild?: Guild;
-
-	@Column({ nullable: true })
-	@RelationId((message: Message) => message.author)
-	@Index()
-	author_id: string;
-
-	@JoinColumn({ name: "author_id", referencedColumnName: "id" })
-	@ManyToOne(() => User, {
-		onDelete: "CASCADE",
-	})
-	author?: User;
-
-	@Column({ nullable: true })
-	@RelationId((message: Message) => message.member)
-	member_id: string;
-
-	@JoinColumn({ name: "member_id", referencedColumnName: "id" })
-	@ManyToOne(() => User, {
-		onDelete: "CASCADE",
-	})
-	member?: Member;
-
-	@Column({ nullable: true })
-	@RelationId((message: Message) => message.webhook)
-	webhook_id: string;
-
-	@JoinColumn({ name: "webhook_id" })
-	@ManyToOne(() => Webhook)
-	webhook?: Webhook;
-
-	@Column({ nullable: true })
-	@RelationId((message: Message) => message.application)
-	application_id: string;
-
-	@JoinColumn({ name: "application_id" })
-	@ManyToOne(() => Application)
-	application?: Application;
-
-	@Column({ nullable: true })
-	content?: string;
-
-	@Column()
-	@CreateDateColumn()
-	timestamp: Date;
-
-	@Column({ nullable: true })
-	edited_timestamp?: Date;
-
-	@Column({ nullable: true })
-	tts?: boolean;
-
-	@Column({ nullable: true })
-	mention_everyone?: boolean;
-
-	@JoinTable({ name: "message_user_mentions" })
-	@ManyToMany(() => User)
-	mentions: User[];
-
-	@JoinTable({ name: "message_role_mentions" })
-	@ManyToMany(() => Role)
-	mention_roles: Role[];
-
-	@JoinTable({ name: "message_channel_mentions" })
-	@ManyToMany(() => Channel)
-	mention_channels: Channel[];
-
-	@JoinTable({ name: "message_stickers" })
-	@ManyToMany(() => Sticker, { cascade: true, onDelete: "CASCADE" })
-	sticker_items?: Sticker[];
-
-	@OneToMany(() => Attachment, (attachment: Attachment) => attachment.message, {
-		cascade: true,
-		orphanedRowAction: "delete",
-	})
-	attachments?: Attachment[];
-
-	@Column({ type: "simple-json" })
-	embeds: Embed[];
-
-	@Column({ type: "simple-json" })
-	reactions: Reaction[];
-
-	@Column({ type: "text", nullable: true })
-	nonce?: string;
-
-	@Column({ nullable: true })
-	pinned?: boolean;
-
-	@Column({ type: "int" })
-	type: MessageType;
-
-	@Column({ type: "simple-json", nullable: true })
-	activity?: {
-		type: number;
-		party_id: string;
-	};
-
-	@Column({ nullable: true })
-	flags?: string;
-	@Column({ type: "simple-json", nullable: true })
-	message_reference?: {
-		message_id: string;
-		channel_id?: string;
-		guild_id?: string;
-	};
-
-	@JoinColumn({ name: "message_reference_id" })
-	@ManyToOne(() => Message)
-	referenced_message?: Message;
-
-	@Column({ type: "simple-json", nullable: true })
-	interaction?: {
-		id: string;
-		type: InteractionType;
-		name: string;
-		user_id: string; // the user who invoked the interaction
-		// user: User; // TODO: autopopulate user
-	};
-
-	@Column({ type: "simple-json", nullable: true })
-	components?: MessageComponent[];
-}
-
-export interface MessageComponent {
-	type: number;
-	style?: number;
-	label?: string;
-	emoji?: PartialEmoji;
-	custom_id?: string;
-	url?: string;
-	disabled?: boolean;
-	components: MessageComponent[];
-}
-
-export enum MessageComponentType {
-	Script = 0, // self command script
-	ActionRow = 1,
-	Button = 2,
-}
-
-export interface Embed {
-	title?: string; //title of embed
-	type?: EmbedType; // type of embed (always "rich" for webhook embeds)
-	description?: string; // description of embed
-	url?: string; // url of embed
-	timestamp?: Date; // timestamp of embed content
-	color?: number; // color code of the embed
-	footer?: {
-		text: string;
-		icon_url?: string;
-		proxy_icon_url?: string;
-	}; // footer object	footer information
-	image?: EmbedImage; // image object	image information
-	thumbnail?: EmbedImage; // thumbnail object	thumbnail information
-	video?: EmbedImage; // video object	video information
-	provider?: {
-		name?: string;
-		url?: string;
-	}; // provider object	provider information
-	author?: {
-		name?: string;
-		url?: string;
-		icon_url?: string;
-		proxy_icon_url?: string;
-	}; // author object	author information
-	fields?: {
-		name: string;
-		value: string;
-		inline?: boolean;
-	}[];
-}
-
-export enum EmbedType {
-	rich = "rich",
-	image = "image",
-	video = "video",
-	gifv = "gifv",
-	article = "article",
-	link = "link",
-}
-
-export interface EmbedImage {
-	url?: string;
-	proxy_url?: string;
-	height?: number;
-	width?: number;
-}
-
-export interface Reaction {
-	count: number;
-	//// not saved in the database // me: boolean; // whether the current user reacted using this emoji
-	emoji: PartialEmoji;
-	user_ids: string[];
-}
-
-export interface PartialEmoji {
-	id?: string;
-	name: string;
-	animated?: boolean;
-}
-
-export interface AllowedMentions {
-	parse?: ("users" | "roles" | "everyone")[];
-	roles?: string[];
-	users?: string[];
-	replied_user?: boolean;
-}
diff --git a/util/src/entities/Migration.ts b/util/src/entities/Migration.ts
deleted file mode 100644
index 3f39ae72..00000000
--- a/util/src/entities/Migration.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { Column, Entity, ObjectIdColumn, PrimaryGeneratedColumn } from "typeorm";
-import { BaseClassWithoutId } from ".";
-
-export const PrimaryIdAutoGenerated = process.env.DATABASE?.startsWith("mongodb")
-	? ObjectIdColumn
-	: PrimaryGeneratedColumn;
-
-@Entity("migrations")
-export class Migration extends BaseClassWithoutId {
-	@PrimaryIdAutoGenerated()
-	id: number;
-
-	@Column({ type: "bigint" })
-	timestamp: number;
-
-	@Column()
-	name: string;
-}
diff --git a/util/src/entities/RateLimit.ts b/util/src/entities/RateLimit.ts
deleted file mode 100644
index f5916f6b..00000000
--- a/util/src/entities/RateLimit.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { Column, Entity } from "typeorm";
-import { BaseClass } from "./BaseClass";
-
-@Entity("rate_limits")
-export class RateLimit extends BaseClass {
-	@Column() // no relation as it also
-	executor_id: string;
-
-	@Column()
-	hits: number;
-
-	@Column()
-	blocked: boolean;
-
-	@Column()
-	expires_at: Date;
-}
diff --git a/util/src/entities/ReadState.ts b/util/src/entities/ReadState.ts
deleted file mode 100644
index b915573b..00000000
--- a/util/src/entities/ReadState.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-import { Column, Entity, Index, JoinColumn, ManyToOne, RelationId } from "typeorm";
-import { BaseClass } from "./BaseClass";
-import { Channel } from "./Channel";
-import { Message } from "./Message";
-import { User } from "./User";
-
-// for read receipts
-// notification cursor and public read receipt need to be forwards-only (the former to prevent re-pinging when marked as unread, and the latter to be acceptable as a legal acknowledgement in criminal proceedings), and private read marker needs to be advance-rewind capable
-// public read receipt ≥ notification cursor ≥ private fully read marker
-
-@Entity("read_states")
-@Index(["channel_id", "user_id"], { unique: true })
-export class ReadState extends BaseClass {
-	@Column()
-	@RelationId((read_state: ReadState) => read_state.channel)
-	channel_id: string;
-
-	@JoinColumn({ name: "channel_id" })
-	@ManyToOne(() => Channel, {
-		onDelete: "CASCADE",
-	})
-	channel: Channel;
-
-	@Column()
-	@RelationId((read_state: ReadState) => read_state.user)
-	user_id: string;
-
-	@JoinColumn({ name: "user_id" })
-	@ManyToOne(() => User, {
-		onDelete: "CASCADE",
-	})
-	user: User;
-
-	// fully read marker
-	@Column({ nullable: true })
-	last_message_id: string; 
-	
-	// public read receipt
-	@Column({ nullable: true })
-	public_ack: string;
-
-	// notification cursor / private read receipt
-	@Column({ nullable: true })
-	notifications_cursor: string;
-
-	@Column({ nullable: true })
-	last_pin_timestamp?: Date;
-
-	@Column({ nullable: true })
-	mention_count: number;
-
-	// @Column({ nullable: true })
-	// TODO: derive this from (last_message_id=notifications_cursor=public_ack)=true
-	manual: boolean;
-}
diff --git a/util/src/entities/Recipient.ts b/util/src/entities/Recipient.ts
deleted file mode 100644
index a945f938..00000000
--- a/util/src/entities/Recipient.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
-import { BaseClass } from "./BaseClass";
-
-@Entity("recipients")
-export class Recipient extends BaseClass {
-	@Column()
-	@RelationId((recipient: Recipient) => recipient.channel)
-	channel_id: string;
-
-	@JoinColumn({ name: "channel_id" })
-	@ManyToOne(() => require("./Channel").Channel, {
-		onDelete: "CASCADE",
-	})
-	channel: import("./Channel").Channel;
-
-	@Column()
-	@RelationId((recipient: Recipient) => recipient.user)
-	user_id: string;
-
-	@JoinColumn({ name: "user_id" })
-	@ManyToOne(() => require("./User").User, {
-		onDelete: "CASCADE",
-	})
-	user: import("./User").User;
-
-	@Column({ default: false })
-	closed: boolean;
-
-	// TODO: settings/mute/nick/added at/encryption keys/read_state
-}
diff --git a/util/src/entities/Relationship.ts b/util/src/entities/Relationship.ts
deleted file mode 100644
index c3592c76..00000000
--- a/util/src/entities/Relationship.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import { Column, Entity, Index, JoinColumn, ManyToOne, RelationId } from "typeorm";
-import { BaseClass } from "./BaseClass";
-import { User } from "./User";
-
-export enum RelationshipType {
-	outgoing = 4,
-	incoming = 3,
-	blocked = 2,
-	friends = 1,
-}
-
-@Entity("relationships")
-@Index(["from_id", "to_id"], { unique: true })
-export class Relationship extends BaseClass {
-	@Column({})
-	@RelationId((relationship: Relationship) => relationship.from)
-	from_id: string;
-
-	@JoinColumn({ name: "from_id" })
-	@ManyToOne(() => User, {
-		onDelete: "CASCADE",
-	})
-	from: User;
-
-	@Column({})
-	@RelationId((relationship: Relationship) => relationship.to)
-	to_id: string;
-
-	@JoinColumn({ name: "to_id" })
-	@ManyToOne(() => User, {
-		onDelete: "CASCADE",
-	})
-	to: User;
-
-	@Column({ nullable: true })
-	nickname?: string;
-
-	@Column({ type: "int" })
-	type: RelationshipType;
-
-	toPublicRelationship() {
-		return {
-			id: this.to?.id || this.to_id,
-			type: this.type,
-			nickname: this.nickname,
-			user: this.to?.toPublicUser(),
-		};
-	}
-}
diff --git a/util/src/entities/Role.ts b/util/src/entities/Role.ts
deleted file mode 100644
index 4b721b5b..00000000
--- a/util/src/entities/Role.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
-
-import { BaseClass } from "./BaseClass";
-import { Guild } from "./Guild";
-
-@Entity("roles")
-export class Role extends BaseClass {
-	@Column({ nullable: true })
-	@RelationId((role: Role) => role.guild)
-	guild_id: string;
-
-	@JoinColumn({ name: "guild_id" })
-	@ManyToOne(() => Guild, {
-		onDelete: "CASCADE",
-	})
-	guild: Guild;
-
-	@Column()
-	color: number;
-
-	@Column()
-	hoist: boolean;
-
-	@Column()
-	managed: boolean;
-
-	@Column()
-	mentionable: boolean;
-
-	@Column()
-	name: string;
-
-	@Column()
-	permissions: string;
-
-	@Column()
-	position: number;
-
-	@Column({ nullable: true })
-	icon: string;
-
-	@Column({ nullable: true })
-	unicode_emoji: string;
-
-	@Column({ type: "simple-json", nullable: true })
-	tags?: {
-		bot_id?: string;
-		integration_id?: string;
-		premium_subscriber?: boolean;
-	};
-}
diff --git a/util/src/entities/Session.ts b/util/src/entities/Session.ts
deleted file mode 100644
index 969efa89..00000000
--- a/util/src/entities/Session.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import { User } from "./User";
-import { BaseClass } from "./BaseClass";
-import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
-import { Status } from "../interfaces/Status";
-import { Activity } from "../interfaces/Activity";
-
-//TODO we need to remove all sessions on server start because if the server crashes without closing websockets it won't delete them
-
-@Entity("sessions")
-export class Session extends BaseClass {
-	@Column({ nullable: true })
-	@RelationId((session: Session) => session.user)
-	user_id: string;
-
-	@JoinColumn({ name: "user_id" })
-	@ManyToOne(() => User, {
-		onDelete: "CASCADE",
-	})
-	user: User;
-
-	//TODO check, should be 32 char long hex string
-	@Column({ nullable: false, select: false })
-	session_id: string;
-
-	@Column({ type: "simple-json", nullable: true })
-	activities: Activity[];
-
-	// TODO client_status
-	@Column({ type: "simple-json", select: false })
-	client_info: {
-		client: string;
-		os: string;
-		version: number;
-	};
-
-	@Column({ nullable: false, type: "varchar" })
-	status: Status; //TODO enum
-}
-
-export const PrivateSessionProjection: (keyof Session)[] = [
-	"user_id",
-	"session_id",
-	"activities",
-	"client_info",
-	"status",
-];
diff --git a/util/src/entities/Sticker.ts b/util/src/entities/Sticker.ts
deleted file mode 100644
index 37bc6fbe..00000000
--- a/util/src/entities/Sticker.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
-import { User } from "./User";
-import { BaseClass } from "./BaseClass";
-import { Guild } from "./Guild";
-
-export enum StickerType {
-	STANDARD = 1,
-	GUILD = 2,
-}
-
-export enum StickerFormatType {
-	GIF = 0, // gif is a custom format type and not in discord spec
-	PNG = 1,
-	APNG = 2,
-	LOTTIE = 3,
-}
-
-@Entity("stickers")
-export class Sticker extends BaseClass {
-	@Column()
-	name: string;
-
-	@Column({ nullable: true })
-	description?: string;
-
-	@Column({ nullable: true })
-	available?: boolean;
-
-	@Column({ nullable: true })
-	tags?: string;
-
-	@Column({ nullable: true })
-	@RelationId((sticker: Sticker) => sticker.pack)
-	pack_id?: string;
-
-	@JoinColumn({ name: "pack_id" })
-	@ManyToOne(() => require("./StickerPack").StickerPack, {
-		onDelete: "CASCADE",
-		nullable: true,
-	})
-	pack: import("./StickerPack").StickerPack;
-
-	@Column({ nullable: true })
-	guild_id?: string;
-
-	@JoinColumn({ name: "guild_id" })
-	@ManyToOne(() => Guild, {
-		onDelete: "CASCADE",
-	})
-	guild?: Guild;
-
-	@Column({ nullable: true })
-	user_id?: string;
-
-	@JoinColumn({ name: "user_id" })
-	@ManyToOne(() => User, {
-		onDelete: "CASCADE",
-	})
-	user?: User;
-
-	@Column({ type: "int" })
-	type: StickerType;
-
-	@Column({ type: "int" })
-	format_type: StickerFormatType;
-}
diff --git a/util/src/entities/StickerPack.ts b/util/src/entities/StickerPack.ts
deleted file mode 100644
index ec8c69a2..00000000
--- a/util/src/entities/StickerPack.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { Column, Entity, JoinColumn, ManyToOne, OneToMany, OneToOne, RelationId } from "typeorm";
-import { Sticker } from ".";
-import { BaseClass } from "./BaseClass";
-
-@Entity("sticker_packs")
-export class StickerPack extends BaseClass {
-	@Column()
-	name: string;
-
-	@Column({ nullable: true })
-	description?: string;
-
-	@Column({ nullable: true })
-	banner_asset_id?: string;
-
-	@OneToMany(() => Sticker, (sticker: Sticker) => sticker.pack, {
-		cascade: true,
-		orphanedRowAction: "delete",
-	})
-	stickers: Sticker[];
-
-	// sku_id: string
-
-	@Column({ nullable: true })
-	@RelationId((pack: StickerPack) => pack.cover_sticker)
-	cover_sticker_id?: string;
-
-	@ManyToOne(() => Sticker, { nullable: true })
-	@JoinColumn()
-	cover_sticker?: Sticker;
-}
diff --git a/util/src/entities/Team.ts b/util/src/entities/Team.ts
deleted file mode 100644
index 22140b7f..00000000
--- a/util/src/entities/Team.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import { Column, Entity, JoinColumn, ManyToMany, ManyToOne, OneToMany, RelationId } from "typeorm";
-import { BaseClass } from "./BaseClass";
-import { TeamMember } from "./TeamMember";
-import { User } from "./User";
-
-@Entity("teams")
-export class Team extends BaseClass {
-	@Column({ nullable: true })
-	icon?: string;
-
-	@JoinColumn({ name: "member_ids" })
-	@OneToMany(() => TeamMember, (member: TeamMember) => member.team, {
-		orphanedRowAction: "delete",
-	})
-	members: TeamMember[];
-
-	@Column()
-	name: string;
-
-	@Column({ nullable: true })
-	@RelationId((team: Team) => team.owner_user)
-	owner_user_id: string;
-
-	@JoinColumn({ name: "owner_user_id" })
-	@ManyToOne(() => User)
-	owner_user: User;
-}
diff --git a/util/src/entities/TeamMember.ts b/util/src/entities/TeamMember.ts
deleted file mode 100644
index b726e1e8..00000000
--- a/util/src/entities/TeamMember.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
-import { BaseClass } from "./BaseClass";
-import { User } from "./User";
-
-export enum TeamMemberState {
-	INVITED = 1,
-	ACCEPTED = 2,
-}
-
-@Entity("team_members")
-export class TeamMember extends BaseClass {
-	@Column({ type: "int" })
-	membership_state: TeamMemberState;
-
-	@Column({ type: "simple-array" })
-	permissions: string[];
-
-	@Column({ nullable: true })
-	@RelationId((member: TeamMember) => member.team)
-	team_id: string;
-
-	@JoinColumn({ name: "team_id" })
-	@ManyToOne(() => require("./Team").Team, (team: import("./Team").Team) => team.members, {
-		onDelete: "CASCADE",
-	})
-	team: import("./Team").Team;
-
-	@Column({ nullable: true })
-	@RelationId((member: TeamMember) => member.user)
-	user_id: string;
-
-	@JoinColumn({ name: "user_id" })
-	@ManyToOne(() => User, {
-		onDelete: "CASCADE",
-	})
-	user: User;
-}
diff --git a/util/src/entities/Template.ts b/util/src/entities/Template.ts
deleted file mode 100644
index 1d952283..00000000
--- a/util/src/entities/Template.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
-import { BaseClass } from "./BaseClass";
-import { Guild } from "./Guild";
-import { User } from "./User";
-
-@Entity("templates")
-export class Template extends BaseClass {
-	@Column({ unique: true })
-	code: string;
-
-	@Column()
-	name: string;
-
-	@Column({ nullable: true })
-	description?: string;
-
-	@Column({ nullable: true })
-	usage_count?: number;
-
-	@Column({ nullable: true })
-	@RelationId((template: Template) => template.creator)
-	creator_id: string;
-
-	@JoinColumn({ name: "creator_id" })
-	@ManyToOne(() => User)
-	creator: User;
-
-	@Column()
-	created_at: Date;
-
-	@Column()
-	updated_at: Date;
-
-	@Column({ nullable: true })
-	@RelationId((template: Template) => template.source_guild)
-	source_guild_id: string;
-
-	@JoinColumn({ name: "source_guild_id" })
-	@ManyToOne(() => Guild)
-	source_guild: Guild;
-
-	@Column({ type: "simple-json" })
-	serialized_source_guild: Guild;
-}
diff --git a/util/src/entities/User.ts b/util/src/entities/User.ts
deleted file mode 100644
index 9b1c494e..00000000
--- a/util/src/entities/User.ts
+++ /dev/null
@@ -1,403 +0,0 @@
-import { Column, Entity, FindOneOptions, JoinColumn, ManyToMany, OneToMany, RelationId } from "typeorm";
-import { BaseClass } from "./BaseClass";
-import { BitField } from "../util/BitField";
-import { Relationship } from "./Relationship";
-import { ConnectedAccount } from "./ConnectedAccount";
-import { Config, FieldErrors, Snowflake, trimSpecial } from "..";
-import { Member, Session } from ".";
-
-export enum PublicUserEnum {
-	username,
-	discriminator,
-	id,
-	public_flags,
-	avatar,
-	accent_color,
-	banner,
-	bio,
-	bot,
-	premium_since,
-}
-export type PublicUserKeys = keyof typeof PublicUserEnum;
-
-export enum PrivateUserEnum {
-	flags,
-	mfa_enabled,
-	email,
-	phone,
-	verified,
-	nsfw_allowed,
-	premium,
-	premium_type,
-	disabled,
-	settings,
-	// locale
-}
-export type PrivateUserKeys = keyof typeof PrivateUserEnum | PublicUserKeys;
-
-export const PublicUserProjection = Object.values(PublicUserEnum).filter(
-	(x) => typeof x === "string"
-) as PublicUserKeys[];
-export const PrivateUserProjection = [
-	...PublicUserProjection,
-	...Object.values(PrivateUserEnum).filter((x) => typeof x === "string"),
-] as PrivateUserKeys[];
-
-// Private user data that should never get sent to the client
-export type PublicUser = Pick<User, PublicUserKeys>;
-
-export interface UserPublic extends Pick<User, PublicUserKeys> {}
-
-export interface UserPrivate extends Pick<User, PrivateUserKeys> {
-	locale: string;
-}
-
-// TODO: add purchased_flags, premium_usage_flags
-
-@Entity("users")
-export class User extends BaseClass {
-	@Column()
-	username: string; // username max length 32, min 2 (should be configurable)
-
-	@Column()
-	discriminator: string; // opaque string: 4 digits on discord.com
-
-	setDiscriminator(val: string) {
-		const number = Number(val);
-		if (isNaN(number)) throw new Error("invalid discriminator");
-		if (number <= 0 || number >= 10000) throw new Error("discriminator must be between 1 and 9999");
-		this.discriminator = val.toString().padStart(4, "0");
-	}
-
-	@Column({ nullable: true })
-	avatar?: string; // hash of the user avatar
-
-	@Column({ nullable: true })
-	accent_color?: number; // banner color of user
-
-	@Column({ nullable: true })
-	banner?: string; // hash of the user banner
-
-	@Column({ nullable: true, select: false })
-	phone?: string; // phone number of the user
-
-	@Column({ select: false })
-	desktop: boolean; // if the user has desktop app installed
-
-	@Column({ select: false })
-	mobile: boolean; // if the user has mobile app installed
-
-	@Column()
-	premium: boolean; // if user bought individual premium
-	
-	@Column()
-	premium_type: number; // individual premium level
-
-	@Column()
-	bot: boolean; // if user is bot
-
-	@Column()
-	bio: string; // short description of the user (max 190 chars -> should be configurable)
-
-	@Column()
-	system: boolean; // shouldn't be used, the api sends this field type true, if the generated message comes from a system generated author
-
-	@Column({ select: false })
-	nsfw_allowed: boolean; // if the user can do age-restricted actions (NSFW channels/guilds/commands)
-	
-	@Column({ select: false })
-	mfa_enabled: boolean; // if multi factor authentication is enabled
-
-	@Column()
-	created_at: Date; // registration date
-
-	@Column({ nullable: true })
-	premium_since: Date; // premium date
-
-	@Column({ select: false })
-	verified: boolean; // if the user is offically verified
-
-	@Column()
-	disabled: boolean; // if the account is disabled
-
-	@Column()
-	deleted: boolean; // if the user was deleted
-
-	@Column({ nullable: true, select: false })
-	email?: string; // email of the user
-
-	@Column()
-	flags: string; // UserFlags
-
-	@Column()
-	public_flags: number;
-
-	@Column({ type: "bigint" })
-	rights: string; // Rights
-
-	@OneToMany(() => Session, (session: Session) => session.user)
-	sessions: Session[];
-
-	@JoinColumn({ name: "relationship_ids" })
-	@OneToMany(() => Relationship, (relationship: Relationship) => relationship.from, {
-		cascade: true,
-		orphanedRowAction: "delete",
-	})
-	relationships: Relationship[];
-
-	@JoinColumn({ name: "connected_account_ids" })
-	@OneToMany(() => ConnectedAccount, (account: ConnectedAccount) => account.user, {
-		cascade: true,
-		orphanedRowAction: "delete",
-	})
-	connected_accounts: ConnectedAccount[];
-
-	@Column({ type: "simple-json", select: false })
-	data: {
-		valid_tokens_since: Date; // all tokens with a previous issue date are invalid
-		hash?: string; // hash of the password, salt is saved in password (bcrypt)
-	};
-
-	@Column({ type: "simple-array", select: false })
-	fingerprints: string[]; // array of fingerprints -> used to prevent multiple accounts
-
-	@Column({ type: "simple-json", select: false })
-	settings: UserSettings;
-		
-	// workaround to prevent fossord-unaware clients from deleting settings not used by them
-	@Column({ type: "simple-json", select: false })
-	extended_settings: string;
-
-	@Column({ type: "simple-json" })
-	notes: { [key: string]: string };	//key is ID of user
-
-	toPublicUser() {
-		const user: any = {};
-		PublicUserProjection.forEach((x) => {
-			user[x] = this[x];
-		});
-		return user as PublicUser;
-	}
-
-	static async getPublicUser(user_id: string, opts?: FindOneOptions<User>) {
-		return await User.findOneOrFail(
-			{ id: user_id },
-			{
-				...opts,
-				select: [...PublicUserProjection, ...(opts?.select || [])],
-			}
-		);
-	}
-
-	private static async generateDiscriminator(username: string): Promise<string | undefined> {
-		if (Config.get().register.incrementingDiscriminators) {
-			// discriminator will be incrementally generated
-			
-			// First we need to figure out the currently highest discrimnator for the given username and then increment it
-			const users = await User.find({ where: { username }, select: ["discriminator"] });
-			const highestDiscriminator = Math.max(0, ...users.map((u) => Number(u.discriminator)));
-
-			const discriminator = highestDiscriminator + 1;
-			if (discriminator >= 10000) {
-				return undefined;
-			}
-
-			return discriminator.toString().padStart(4, "0");
-		} else {
-			// discriminator will be randomly generated
-
-			// randomly generates a discriminator between 1 and 9999 and checks max five times if it already exists
-			// TODO: is there any better way to generate a random discriminator only once, without checking if it already exists in the database?
-			for (let tries = 0; tries < 5; tries++) {
-				const discriminator = Math.randomIntBetween(1, 9999).toString().padStart(4, "0");
-				const exists = await User.findOne({ where: { discriminator, username: username }, select: ["id"] });
-				if (!exists) return discriminator;
-			}
-
-			return undefined;
-		}
-	}
-
-	static async register({
-		email,
-		username,
-		password,
-		date_of_birth,
-		req,
-	}: {
-		username: string;
-		password?: string;
-		email?: string;
-		date_of_birth?: Date; // "2000-04-03"
-		req?: any;
-	}) {
-		// trim special uf8 control characters -> Backspace, Newline, ...
-		username = trimSpecial(username);
-
-		const discriminator = await User.generateDiscriminator(username);
-		if (!discriminator) {
-			// We've failed to generate a valid and unused discriminator
-			throw FieldErrors({
-				username: {
-					code: "USERNAME_TOO_MANY_USERS",
-					message: req.t("auth:register.USERNAME_TOO_MANY_USERS"),
-				},
-			});
-		}
-
-		// TODO: save date_of_birth
-		// appearently discord doesn't save the date of birth and just calculate if nsfw is allowed
-		// if nsfw_allowed is null/undefined it'll require date_of_birth to set it to true/false
-		const language = req.language === "en" ? "en-US" : req.language || "en-US";
-
-		const user = new User({
-			created_at: new Date(),
-			username: username,
-			discriminator,
-			id: Snowflake.generate(),
-			bot: false,
-			system: false,
-			premium_since: new Date(),
-			desktop: false,
-			mobile: false,
-			premium: true,
-			premium_type: 2,
-			bio: "",
-			mfa_enabled: false,
-			verified: true,
-			disabled: false,
-			deleted: false,
-			email: email,
-			rights: "0", // TODO: grant rights correctly, as 0 actually stands for no rights at all
-			nsfw_allowed: true, // TODO: depending on age
-			public_flags: "0",
-			flags: "0", // TODO: generate
-			data: {
-				hash: password,
-				valid_tokens_since: new Date(),
-			},
-			settings: { ...defaultSettings, locale: language },
-			extended_settings: {},
-			fingerprints: [],
-			notes: {},
-		});
-
-		await user.save();
-
-		setImmediate(async () => {
-			if (Config.get().guild.autoJoin.enabled) {
-				for (const guild of Config.get().guild.autoJoin.guilds || []) {
-					await Member.addToGuild(user.id, guild).catch((e) => {});
-				}
-			}
-		});
-
-		return user;
-	}
-}
-
-export const defaultSettings: UserSettings = {
-	afk_timeout: 3600,
-	allow_accessibility_detection: true,
-	animate_emoji: true,
-	animate_stickers: 0,
-	contact_sync_enabled: false,
-	convert_emoticons: false,
-	custom_status: null,
-	default_guilds_restricted: false,
-	detect_platform_accounts: false,
-	developer_mode: true,
-	disable_games_tab: true,
-	enable_tts_command: false,
-	explicit_content_filter: 0,
-	friend_source_flags: { all: true },
-	gateway_connected: false,
-	gif_auto_play: true,
-	guild_folders: [],
-	guild_positions: [],
-	inline_attachment_media: true,
-	inline_embed_media: true,
-	locale: "en-US",
-	message_display_compact: true,
-	native_phone_integration_enabled: true,
-	render_embeds: true,
-	render_reactions: true,
-	restricted_guilds: [],
-	show_current_game: true,
-	status: "online",
-	stream_notifications_enabled: false,
-	theme: "dark",
-	timezone_offset: 0, // TODO: timezone from request
-};
-
-export interface UserSettings {
-	afk_timeout: number;
-	allow_accessibility_detection: boolean;
-	animate_emoji: boolean;
-	animate_stickers: number;
-	contact_sync_enabled: boolean;
-	convert_emoticons: boolean;
-	custom_status: {
-		emoji_id?: string;
-		emoji_name?: string;
-		expires_at?: number;
-		text?: string;
-	} | null;
-	default_guilds_restricted: boolean;
-	detect_platform_accounts: boolean;
-	developer_mode: boolean;
-	disable_games_tab: boolean;
-	enable_tts_command: boolean;
-	explicit_content_filter: number;
-	friend_source_flags: { all: boolean };
-	gateway_connected: boolean;
-	gif_auto_play: boolean;
-	// every top guild is displayed as a "folder"
-	guild_folders: {
-		color: number;
-		guild_ids: string[];
-		id: number;
-		name: string;
-	}[];
-	guild_positions: string[]; // guild ids ordered by position
-	inline_attachment_media: boolean;
-	inline_embed_media: boolean;
-	locale: string; // en_US
-	message_display_compact: boolean;
-	native_phone_integration_enabled: boolean;
-	render_embeds: boolean;
-	render_reactions: boolean;
-	restricted_guilds: string[];
-	show_current_game: boolean;
-	status: "online" | "offline" | "dnd" | "idle" | "invisible";
-	stream_notifications_enabled: boolean;
-	theme: "dark" | "white"; // dark
-	timezone_offset: number; // e.g -60
-}
-
-export const CUSTOM_USER_FLAG_OFFSET = BigInt(1) << BigInt(32);
-
-export class UserFlags extends BitField {
-	static FLAGS = {
-		DISCORD_EMPLOYEE: BigInt(1) << BigInt(0),
-		PARTNERED_SERVER_OWNER: BigInt(1) << BigInt(1),
-		HYPESQUAD_EVENTS: BigInt(1) << BigInt(2),
-		BUGHUNTER_LEVEL_1: BigInt(1) << BigInt(3),
-		MFA_SMS: BigInt(1) << BigInt(4),
-		PREMIUM_PROMO_DISMISSED: BigInt(1) << BigInt(5),
-		HOUSE_BRAVERY: BigInt(1) << BigInt(6),
-		HOUSE_BRILLIANCE: BigInt(1) << BigInt(7),
-		HOUSE_BALANCE: BigInt(1) << BigInt(8),
-		EARLY_SUPPORTER: BigInt(1) << BigInt(9),
-		TEAM_USER: BigInt(1) << BigInt(10),
-		TRUST_AND_SAFETY: BigInt(1) << BigInt(11),
-		SYSTEM: BigInt(1) << BigInt(12),
-		HAS_UNREAD_URGENT_MESSAGES: BigInt(1) << BigInt(13),
-		BUGHUNTER_LEVEL_2: BigInt(1) << BigInt(14),
-		UNDERAGE_DELETED: BigInt(1) << BigInt(15),
-		VERIFIED_BOT: BigInt(1) << BigInt(16),
-		EARLY_VERIFIED_BOT_DEVELOPER: BigInt(1) << BigInt(17),
-		CERTIFIED_MODERATOR: BigInt(1) << BigInt(18),
-		BOT_HTTP_INTERACTIONS: BigInt(1) << BigInt(19),
-	};
-}
diff --git a/util/src/entities/UserGroup.ts b/util/src/entities/UserGroup.ts
deleted file mode 100644
index 709b9d0b..00000000
--- a/util/src/entities/UserGroup.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
-
-import { BaseClass } from "./BaseClass";
-import { Guild } from "./Guild";
-import { User } from "./User";
-
-@Entity("groups")
-export class UserGroup extends BaseClass {
-	@Column()
-	color: number;
-
-	@Column()
-	hoist: boolean;
-	
-	@JoinColumn({ name: "controller", referencedColumnName: "id" })
-	@ManyToOne(() => User)
-	controller?: User;
-	 
-	@Column()
-	mentionable_by?: string;
-
-	@Column()
-	name: string;
-
-	@Column()
-	rights: string;
-
-	@Column({ nullable: true })
-	icon: string;
-	
-	@Column({ nullable: true })
-	parent?: string;
-	
-	@Column({ type: "simple-array", nullable: true})
-	associciations: string[];
-
-}
diff --git a/util/src/entities/VoiceState.ts b/util/src/entities/VoiceState.ts
deleted file mode 100644
index 75748a01..00000000
--- a/util/src/entities/VoiceState.ts
+++ /dev/null
@@ -1,77 +0,0 @@
-import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
-import { BaseClass } from "./BaseClass";
-import { Channel } from "./Channel";
-import { Guild } from "./Guild";
-import { User } from "./User";
-import { Member } from "./Member";
-
-//https://gist.github.com/vassjozsef/e482c65df6ee1facaace8b3c9ff66145#file-voice_state-ex
-@Entity("voice_states")
-export class VoiceState extends BaseClass {
-	@Column({ nullable: true })
-	@RelationId((voice_state: VoiceState) => voice_state.guild)
-	guild_id: string;
-
-	@JoinColumn({ name: "guild_id" })
-	@ManyToOne(() => Guild, {
-		onDelete: "CASCADE",
-	})
-	guild?: Guild;
-
-	@Column({ nullable: true })
-	@RelationId((voice_state: VoiceState) => voice_state.channel)
-	channel_id: string;
-
-	@JoinColumn({ name: "channel_id" })
-	@ManyToOne(() => Channel, {
-		onDelete: "CASCADE",
-	})
-	channel: Channel;
-
-	@Column({ nullable: true })
-	@RelationId((voice_state: VoiceState) => voice_state.user)
-	user_id: string;
-
-	@JoinColumn({ name: "user_id" })
-	@ManyToOne(() => User, {
-		onDelete: "CASCADE",
-	})
-	user: User;
-
-	// @JoinColumn([{ name: "user_id", referencedColumnName: "id" },{ name: "guild_id", referencedColumnName: "guild_id" }])
-	// @ManyToOne(() => Member, {
-	// 	onDelete: "CASCADE",
-	// })
-	//TODO find a way to make it work without breaking Guild.voice_states
-	member: Member;
-
-	@Column()
-	session_id: string;
-
-	@Column({ nullable: true })
-	token: string;
-
-	@Column()
-	deaf: boolean;
-
-	@Column()
-	mute: boolean;
-
-	@Column()
-	self_deaf: boolean;
-
-	@Column()
-	self_mute: boolean;
-
-	@Column({ nullable: true })
-	self_stream?: boolean;
-
-	@Column()
-	self_video: boolean;
-
-	@Column()
-	suppress: boolean; // whether this user is muted by the current user
-
-	@Column({ nullable: true, default: null })
-	request_to_speak_timestamp?: Date;
-}
diff --git a/util/src/entities/Webhook.ts b/util/src/entities/Webhook.ts
deleted file mode 100644
index 89538417..00000000
--- a/util/src/entities/Webhook.ts
+++ /dev/null
@@ -1,76 +0,0 @@
-import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm";
-import { Application } from "./Application";
-import { BaseClass } from "./BaseClass";
-import { Channel } from "./Channel";
-import { Guild } from "./Guild";
-import { User } from "./User";
-
-export enum WebhookType {
-	Incoming = 1,
-	ChannelFollower = 2,
-}
-
-@Entity("webhooks")
-export class Webhook extends BaseClass {
-	@Column({ type: "int" })
-	type: WebhookType;
-
-	@Column({ nullable: true })
-	name?: string;
-
-	@Column({ nullable: true })
-	avatar?: string;
-
-	@Column({ nullable: true })
-	token?: string;
-
-	@Column({ nullable: true })
-	@RelationId((webhook: Webhook) => webhook.guild)
-	guild_id: string;
-
-	@JoinColumn({ name: "guild_id" })
-	@ManyToOne(() => Guild, {
-		onDelete: "CASCADE",
-	})
-	guild: Guild;
-
-	@Column({ nullable: true })
-	@RelationId((webhook: Webhook) => webhook.channel)
-	channel_id: string;
-
-	@JoinColumn({ name: "channel_id" })
-	@ManyToOne(() => Channel, {
-		onDelete: "CASCADE",
-	})
-	channel: Channel;
-
-	@Column({ nullable: true })
-	@RelationId((webhook: Webhook) => webhook.application)
-	application_id: string;
-
-	@JoinColumn({ name: "application_id" })
-	@ManyToOne(() => Application, {
-		onDelete: "CASCADE",
-	})
-	application: Application;
-
-	@Column({ nullable: true })
-	@RelationId((webhook: Webhook) => webhook.user)
-	user_id: string;
-
-	@JoinColumn({ name: "user_id" })
-	@ManyToOne(() => User, {
-		onDelete: "CASCADE",
-	})
-	user: User;
-
-	@Column({ nullable: true })
-	@RelationId((webhook: Webhook) => webhook.guild)
-	source_guild_id: string;
-
-	@JoinColumn({ name: "source_guild_id" })
-	@ManyToOne(() => Guild, {
-		onDelete: "CASCADE",
-	})
-	source_guild: Guild;
-}
diff --git a/util/src/entities/index.ts b/util/src/entities/index.ts
deleted file mode 100644
index f023d5a6..00000000
--- a/util/src/entities/index.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-export * from "./Application";
-export * from "./Attachment";
-export * from "./AuditLog";
-export * from "./Ban";
-export * from "./BaseClass";
-export * from "./Categories";
-export * from "./Channel";
-export * from "./Config";
-export * from "./ConnectedAccount";
-export * from "./Emoji";
-export * from "./Guild";
-export * from "./Invite";
-export * from "./Member";
-export * from "./Message";
-export * from "./Migration";
-export * from "./RateLimit";
-export * from "./ReadState";
-export * from "./Recipient";
-export * from "./Relationship";
-export * from "./Role";
-export * from "./Session";
-export * from "./Sticker";
-export * from "./StickerPack";
-export * from "./Team";
-export * from "./TeamMember";
-export * from "./Template";
-export * from "./User";
-export * from "./VoiceState";
-export * from "./Webhook";
-export * from "./ClientRelease";
\ No newline at end of file