From e3ab697e6686712abb0102f76d4a2b68881f6926 Mon Sep 17 00:00:00 2001
From: s1idewhist1e <trombonedude05@gmail.com>
Date: Sat, 29 Apr 2023 23:10:20 -0700
Subject: [PATCH] Remove ts from backend and prepare rust environment

---
 packages/backend/.gitignore                   |   7 +
 packages/backend/.mocharc.json                |  10 -
 packages/backend/.swcrc                       |  25 -
 packages/backend/.vim/coc-settings.json       |   5 +
 packages/backend/Cargo.lock                   |  14 +
 packages/backend/Cargo.toml                   |  16 +
 packages/backend/crates/server/Cargo.toml     |   8 +
 packages/backend/crates/server/src/lib.rs     |  15 +
 packages/backend/jsconfig.json                |  13 -
 .../backend/native-utils/.cargo/config.toml   |   3 -
 packages/backend/native-utils/.gitignore      | 200 ----
 packages/backend/native-utils/.npmignore      |  13 -
 packages/backend/native-utils/Cargo.toml      |  18 -
 .../native-utils/__test__/index.spec.mjs      |   7 -
 packages/backend/native-utils/build.rs        |   5 -
 .../npm/android-arm-eabi/README.md            |   3 -
 .../npm/android-arm-eabi/package.json         |  18 -
 .../native-utils/npm/android-arm64/README.md  |   3 -
 .../npm/android-arm64/package.json            |  18 -
 .../native-utils/npm/darwin-arm64/README.md   |   3 -
 .../npm/darwin-arm64/package.json             |  18 -
 .../npm/darwin-universal/README.md            |   3 -
 .../npm/darwin-universal/package.json         |  15 -
 .../native-utils/npm/darwin-x64/README.md     |   3 -
 .../native-utils/npm/darwin-x64/package.json  |  18 -
 .../native-utils/npm/freebsd-x64/README.md    |   3 -
 .../native-utils/npm/freebsd-x64/package.json |  18 -
 .../npm/linux-arm-gnueabihf/README.md         |   3 -
 .../npm/linux-arm-gnueabihf/package.json      |  18 -
 .../npm/linux-arm64-gnu/README.md             |   3 -
 .../npm/linux-arm64-gnu/package.json          |  21 -
 .../npm/linux-arm64-musl/README.md            |   3 -
 .../npm/linux-arm64-musl/package.json         |  21 -
 .../native-utils/npm/linux-x64-gnu/README.md  |   3 -
 .../npm/linux-x64-gnu/package.json            |  21 -
 .../native-utils/npm/linux-x64-musl/README.md |   3 -
 .../npm/linux-x64-musl/package.json           |  21 -
 .../npm/win32-arm64-msvc/README.md            |   3 -
 .../npm/win32-arm64-msvc/package.json         |  18 -
 .../npm/win32-ia32-msvc/README.md             |   3 -
 .../npm/win32-ia32-msvc/package.json          |  18 -
 .../native-utils/npm/win32-x64-msvc/README.md |   3 -
 .../npm/win32-x64-msvc/package.json           |  18 -
 packages/backend/native-utils/package.json    |  44 -
 packages/backend/native-utils/rustfmt.toml    |   2 -
 packages/backend/native-utils/src/lib.rs      |   2 -
 .../backend/native-utils/src/mastodon_api.rs  |  70 --
 packages/backend/ormconfig.js                 |  15 -
 packages/backend/package.json                 | 194 +---
 packages/backend/rust-toolchain               |   1 +
 packages/backend/rustfmt.toml                 |   1 +
 packages/backend/src/@types/hcaptcha.d.ts     |  14 -
 .../backend/src/@types/http-signature.d.ts    |  98 --
 .../backend/src/@types/koa-json-body.d.ts     |  15 -
 .../koa-remove-trailing-slashes/index.d.ts    |   1 -
 packages/backend/src/@types/koa-slow.d.ts     |  14 -
 packages/backend/src/@types/os-utils.d.ts     |  33 -
 packages/backend/src/@types/package.json.d.ts |  10 -
 .../backend/src/@types/probe-image-size.d.ts  |  37 -
 packages/backend/src/bin/migrate.rs           |   4 +
 packages/backend/src/boot/index.ts            |  89 --
 packages/backend/src/boot/master.ts           | 189 ----
 packages/backend/src/boot/worker.ts           |  20 -
 packages/backend/src/config/index.ts          |   3 -
 packages/backend/src/config/load.ts           |  68 --
 packages/backend/src/config/types.ts          | 133 ---
 packages/backend/src/const.ts                 |  71 --
 packages/backend/src/daemons/janitor.ts       |  20 -
 packages/backend/src/daemons/queue-stats.ts   |  60 --
 packages/backend/src/daemons/server-stats.ts  |  79 --
 packages/backend/src/db/elasticsearch.ts      |  65 --
 packages/backend/src/db/logger.ts             |   3 -
 packages/backend/src/db/postgre.ts            | 262 -----
 packages/backend/src/db/redis.ts              |  18 -
 packages/backend/src/db/sonic.ts              |  49 -
 packages/backend/src/env.ts                   |  25 -
 packages/backend/src/global.d.ts              |   2 -
 packages/backend/src/index.ts                 |  13 -
 packages/backend/src/main.rs                  |   5 +
 packages/backend/src/mfm/from-html.ts         | 213 ----
 packages/backend/src/mfm/to-html.ts           | 174 ----
 packages/backend/src/misc/acct.ts             |  14 -
 packages/backend/src/misc/antenna-cache.ts    |  36 -
 packages/backend/src/misc/api-permissions.ts  |  35 -
 packages/backend/src/misc/app-lock.ts         |  33 -
 packages/backend/src/misc/before-shutdown.ts  | 103 --
 packages/backend/src/misc/cache.ts            |  88 --
 packages/backend/src/misc/captcha.ts          |  73 --
 .../backend/src/misc/check-hit-antenna.ts     | 137 ---
 packages/backend/src/misc/check-word-mute.ts  |  78 --
 packages/backend/src/misc/clone.ts            |  24 -
 .../backend/src/misc/content-disposition.ts   |   9 -
 packages/backend/src/misc/convert-host.ts     |  28 -
 .../backend/src/misc/count-same-renotes.ts    |  19 -
 packages/backend/src/misc/create-temp.ts      |  24 -
 packages/backend/src/misc/detect-url-mime.ts  |  15 -
 .../backend/src/misc/download-text-file.ts    |  25 -
 packages/backend/src/misc/download-url.ts     | 103 --
 packages/backend/src/misc/emoji-regex.ts      |   5 -
 .../misc/extract-custom-emojis-from-mfm.ts    |  10 -
 packages/backend/src/misc/extract-hashtags.ts |   9 -
 packages/backend/src/misc/extract-mentions.ts |  13 -
 packages/backend/src/misc/fetch-meta.ts       |  46 -
 .../backend/src/misc/fetch-proxy-account.ts   |  11 -
 packages/backend/src/misc/fetch.ts            | 171 ----
 packages/backend/src/misc/gen-id.ts           |  27 -
 packages/backend/src/misc/gen-identicon.ts    | 114 ---
 packages/backend/src/misc/gen-key-pair.ts     |  42 -
 packages/backend/src/misc/get-file-info.ts    | 443 ---------
 packages/backend/src/misc/get-ip-hash.ts      |  14 -
 packages/backend/src/misc/get-note-summary.ts |  52 -
 .../backend/src/misc/get-reaction-emoji.ts    |  28 -
 packages/backend/src/misc/hard-limits.ts      |  13 -
 packages/backend/src/misc/i18n.ts             |  29 -
 packages/backend/src/misc/id/aid.ts           |  25 -
 packages/backend/src/misc/id/meid.ts          |  26 -
 packages/backend/src/misc/id/meidg.ts         |  28 -
 packages/backend/src/misc/id/object-id.ts     |  26 -
 .../backend/src/misc/identifiable-error.ts    |  13 -
 .../src/misc/is-duplicate-key-value-error.ts  |   3 -
 .../backend/src/misc/is-instance-muted.ts     |  21 -
 packages/backend/src/misc/is-mime-image.ts    |  20 -
 packages/backend/src/misc/is-quote.ts         |  10 -
 packages/backend/src/misc/is-user-related.ts  |   7 -
 packages/backend/src/misc/keypair-store.ts    |  12 -
 packages/backend/src/misc/langmap.ts          | 666 -------------
 .../backend/src/misc/normalize-for-search.ts  |   6 -
 packages/backend/src/misc/nyaize.ts           |  21 -
 packages/backend/src/misc/password.ts         |  20 -
 packages/backend/src/misc/populate-emojis.ts  | 165 ----
 packages/backend/src/misc/post.ts             |  19 -
 packages/backend/src/misc/reaction-lib.ts     | 136 ---
 packages/backend/src/misc/safe-for-sql.ts     |   3 -
 packages/backend/src/misc/schema.ts           | 222 -----
 packages/backend/src/misc/secure-rndstr.ts    |  24 -
 .../backend/src/misc/should-block-instance.ts |  20 -
 .../backend/src/misc/show-machine-info.ts     |  17 -
 .../backend/src/misc/skipped-instances.ts     |  63 --
 packages/backend/src/misc/truncate.ts         |  17 -
 packages/backend/src/misc/webhook-cache.ts    |  49 -
 .../src/models/entities/abuse-user-report.ts  |  86 --
 .../src/models/entities/access-token.ts       |  97 --
 packages/backend/src/models/entities/ad.ts    |  59 --
 .../src/models/entities/announcement-read.ts  |  43 -
 .../src/models/entities/announcement.ts       |  43 -
 .../src/models/entities/antenna-note.ts       |  50 -
 .../backend/src/models/entities/antenna.ts    | 111 ---
 packages/backend/src/models/entities/app.ts   |  60 --
 .../models/entities/attestation-challenge.ts  |  53 -
 .../src/models/entities/auth-session.ts       |  50 -
 .../backend/src/models/entities/blocking.ts   |  49 -
 .../src/models/entities/channel-following.ts  |  50 -
 .../models/entities/channel-note-pining.ts    |  42 -
 .../backend/src/models/entities/channel.ts    |  82 --
 .../backend/src/models/entities/clip-note.ts  |  44 -
 packages/backend/src/models/entities/clip.ts  |  51 -
 .../backend/src/models/entities/drive-file.ts | 206 ----
 .../src/models/entities/drive-folder.ts       |  56 --
 packages/backend/src/models/entities/emoji.ts |  63 --
 .../src/models/entities/follow-request.ts     |  92 --
 .../backend/src/models/entities/following.ts  |  89 --
 .../src/models/entities/gallery-like.ts       |  40 -
 .../src/models/entities/gallery-post.ts       |  86 --
 .../backend/src/models/entities/hashtag.ts    |  87 --
 .../backend/src/models/entities/instance.ts   | 164 ----
 .../src/models/entities/messaging-message.ts  |  96 --
 packages/backend/src/models/entities/meta.ts  | 502 ----------
 .../src/models/entities/moderation-log.ts     |  39 -
 .../backend/src/models/entities/muted-note.ts |  55 --
 .../backend/src/models/entities/muting.ts     |  55 --
 .../src/models/entities/note-favorite.ts      |  42 -
 .../src/models/entities/note-reaction.ts      |  51 -
 .../src/models/entities/note-thread-muting.ts |  40 -
 .../src/models/entities/note-unread.ts        |  70 --
 .../src/models/entities/note-watching.ts      |  59 --
 packages/backend/src/models/entities/note.ts  | 249 -----
 .../src/models/entities/notification.ts       | 180 ----
 .../backend/src/models/entities/page-like.ts  |  40 -
 packages/backend/src/models/entities/page.ts  | 131 ---
 .../models/entities/password-reset-request.ts |  37 -
 .../backend/src/models/entities/poll-vote.ts  |  47 -
 packages/backend/src/models/entities/poll.ts  |  79 --
 .../backend/src/models/entities/promo-note.ts |  35 -
 .../backend/src/models/entities/promo-read.ts |  42 -
 .../models/entities/registration-tickets.ts   |  17 -
 .../src/models/entities/registry-item.ts      |  65 --
 packages/backend/src/models/entities/relay.ts |  19 -
 .../src/models/entities/renote-muting.ts      |  49 -
 .../backend/src/models/entities/signin.ts     |  42 -
 .../src/models/entities/sw-subscription.ts    |  49 -
 .../src/models/entities/used-username.ts      |  20 -
 .../models/entities/user-group-invitation.ts  |  49 -
 .../src/models/entities/user-group-joining.ts |  49 -
 .../backend/src/models/entities/user-group.ts |  53 -
 .../backend/src/models/entities/user-ip.ts    |  32 -
 .../src/models/entities/user-keypair.ts       |  33 -
 .../src/models/entities/user-list-joining.ts  |  49 -
 .../backend/src/models/entities/user-list.ts  |  40 -
 .../src/models/entities/user-note-pining.ts   |  42 -
 .../src/models/entities/user-pending.ts       |  32 -
 .../src/models/entities/user-profile.ts       | 239 -----
 .../src/models/entities/user-publickey.ts     |  41 -
 .../src/models/entities/user-security-key.ts  |  55 --
 packages/backend/src/models/entities/user.ts  | 274 ------
 .../backend/src/models/entities/webhook.ts    |  89 --
 packages/backend/src/models/id.ts             |   4 -
 packages/backend/src/models/index.ts          | 135 ---
 .../models/repositories/abuse-user-report.ts  |  39 -
 .../src/models/repositories/antenna.ts        |  36 -
 .../backend/src/models/repositories/app.ts    |  45 -
 .../src/models/repositories/auth-session.ts   |  21 -
 .../src/models/repositories/blocking.ts       |  29 -
 .../src/models/repositories/channel.ts        |  55 --
 .../backend/src/models/repositories/clip.ts   |  26 -
 .../src/models/repositories/drive-file.ts     | 224 -----
 .../src/models/repositories/drive-folder.ts   |  50 -
 .../backend/src/models/repositories/emoji.ts  |  25 -
 .../src/models/repositories/follow-request.ts |  20 -
 .../src/models/repositories/following.ts      |  90 --
 .../src/models/repositories/gallery-like.ts   |  19 -
 .../src/models/repositories/gallery-post.ts   |  41 -
 .../src/models/repositories/hashtag.ts        |  21 -
 .../src/models/repositories/instance.ts       |  44 -
 .../models/repositories/messaging-message.ts  |  48 -
 .../models/repositories/moderation-logs.ts    |  26 -
 .../backend/src/models/repositories/muting.ts |  30 -
 .../src/models/repositories/note-favorite.ts  |  31 -
 .../src/models/repositories/note-reaction.ts  |  56 --
 .../backend/src/models/repositories/note.ts   | 334 -------
 .../src/models/repositories/notification.ts   | 185 ----
 .../src/models/repositories/page-like.ts      |  23 -
 .../backend/src/models/repositories/page.ts   |  99 --
 .../backend/src/models/repositories/relay.ts  |   4 -
 .../src/models/repositories/renote-muting.ts  |  29 -
 .../backend/src/models/repositories/signin.ts |   8 -
 .../repositories/user-group-invitation.ts     |  23 -
 .../src/models/repositories/user-group.ts     |  23 -
 .../src/models/repositories/user-list.ts      |  22 -
 .../backend/src/models/repositories/user.ts   | 619 ------------
 packages/backend/src/models/schema/antenna.ts | 118 ---
 packages/backend/src/models/schema/app.ts     |  40 -
 .../backend/src/models/schema/blocking.ts     |  30 -
 packages/backend/src/models/schema/channel.ts |  61 --
 packages/backend/src/models/schema/clip.ts    |  45 -
 .../backend/src/models/schema/drive-file.ts   | 127 ---
 .../backend/src/models/schema/drive-folder.ts |  46 -
 packages/backend/src/models/schema/emoji.ts   |  49 -
 .../src/models/schema/federation-instance.ts  | 133 ---
 .../backend/src/models/schema/following.ts    |  42 -
 .../backend/src/models/schema/gallery-post.ts |  83 --
 packages/backend/src/models/schema/hashtag.ts |  41 -
 .../src/models/schema/messaging-message.ts    |  87 --
 packages/backend/src/models/schema/muting.ts  |  36 -
 .../src/models/schema/note-favorite.ts        |  30 -
 .../src/models/schema/note-reaction.ts        |  29 -
 packages/backend/src/models/schema/note.ts    | 200 ----
 .../backend/src/models/schema/notification.ts |  79 --
 packages/backend/src/models/schema/page.ts    |  66 --
 packages/backend/src/models/schema/queue.ts   |  30 -
 .../src/models/schema/renote-muting.ts        |  30 -
 .../backend/src/models/schema/user-group.ts   |  40 -
 .../backend/src/models/schema/user-list.ts    |  34 -
 packages/backend/src/models/schema/user.ts    | 583 -----------
 packages/backend/src/prelude/README.md        |   3 -
 packages/backend/src/prelude/array.ts         | 138 ---
 packages/backend/src/prelude/await-all.ts     |  23 -
 packages/backend/src/prelude/math.ts          |   3 -
 packages/backend/src/prelude/maybe.ts         |  20 -
 packages/backend/src/prelude/relation.ts      |   5 -
 packages/backend/src/prelude/string.ts        |  15 -
 packages/backend/src/prelude/symbol.ts        |   1 -
 packages/backend/src/prelude/time.ts          |  54 -
 packages/backend/src/prelude/url.ts           |  15 -
 packages/backend/src/prelude/xml.ts           |  38 -
 packages/backend/src/queue/get-job-info.ts    |  18 -
 packages/backend/src/queue/index.ts           | 545 -----------
 packages/backend/src/queue/initialize.ts      |  37 -
 packages/backend/src/queue/logger.ts          |   3 -
 .../processors/background/index-all-notes.ts  |  79 --
 .../src/queue/processors/background/index.ts  |  12 -
 .../src/queue/processors/db/delete-account.ts | 102 --
 .../queue/processors/db/delete-drive-files.ts |  61 --
 .../queue/processors/db/export-blocking.ts    | 105 --
 .../processors/db/export-custom-emojis.ts     | 130 ---
 .../queue/processors/db/export-following.ts   | 113 ---
 .../src/queue/processors/db/export-mute.ts    | 106 --
 .../src/queue/processors/db/export-notes.ts   | 132 ---
 .../queue/processors/db/export-user-lists.ts  |  81 --
 .../queue/processors/db/import-blocking.ts    |  79 --
 .../processors/db/import-custom-emojis.ts     |  91 --
 .../queue/processors/db/import-following.ts   | 116 ---
 .../src/queue/processors/db/import-muting.ts  |  89 --
 .../src/queue/processors/db/import-posts.ts   | 131 ---
 .../queue/processors/db/import-user-lists.ts  |  96 --
 .../backend/src/queue/processors/db/index.ts  |  43 -
 .../backend/src/queue/processors/deliver.ts   |  81 --
 .../processors/ended-poll-notification.ts     |  36 -
 .../backend/src/queue/processors/inbox.ts     | 175 ----
 .../object-storage/clean-remote-files.ts      |  53 -
 .../processors/object-storage/delete-file.ts  |  11 -
 .../queue/processors/object-storage/index.ts  |  19 -
 .../system/check-expired-mutings.ts           |  33 -
 .../queue/processors/system/clean-charts.ts   |  44 -
 .../src/queue/processors/system/clean.ts      |  21 -
 .../src/queue/processors/system/index.ts      |  24 -
 .../queue/processors/system/resync-charts.ts  |  24 -
 .../queue/processors/system/tick-charts.ts    |  44 -
 .../src/queue/processors/webhook-deliver.ts   |  66 --
 packages/backend/src/queue/queues.ts          |  41 -
 packages/backend/src/queue/types.ts           |  75 --
 .../src/remote/activitypub/ap-request.ts      | 152 ---
 .../src/remote/activitypub/audience.ts        | 104 --
 .../src/remote/activitypub/check-fetch.ts     |  97 --
 .../src/remote/activitypub/db-resolver.ts     | 189 ----
 .../src/remote/activitypub/deliver-manager.ts | 171 ----
 .../activitypub/kernel/accept/follow.ts       |  32 -
 .../remote/activitypub/kernel/accept/index.ts |  28 -
 .../remote/activitypub/kernel/add/index.ts    |  26 -
 .../activitypub/kernel/announce/index.ts      |  23 -
 .../activitypub/kernel/announce/note.ts       |  84 --
 .../remote/activitypub/kernel/block/index.ts  |  29 -
 .../remote/activitypub/kernel/create/index.ts |  51 -
 .../remote/activitypub/kernel/create/note.ts  |  51 -
 .../remote/activitypub/kernel/delete/actor.ts |  30 -
 .../remote/activitypub/kernel/delete/index.ts |  55 --
 .../remote/activitypub/kernel/delete/note.ts  |  44 -
 .../remote/activitypub/kernel/flag/index.ts   |  37 -
 .../src/remote/activitypub/kernel/follow.ts   |  23 -
 .../src/remote/activitypub/kernel/index.ts    | 111 ---
 .../src/remote/activitypub/kernel/like.ts     |  28 -
 .../remote/activitypub/kernel/move/index.ts   |  69 --
 .../src/remote/activitypub/kernel/read.ts     |  33 -
 .../activitypub/kernel/reject/follow.ts       |  33 -
 .../remote/activitypub/kernel/reject/index.ts |  28 -
 .../remote/activitypub/kernel/remove/index.ts |  26 -
 .../remote/activitypub/kernel/undo/accept.ts  |  30 -
 .../activitypub/kernel/undo/announce.ts       |  22 -
 .../remote/activitypub/kernel/undo/block.ts   |  24 -
 .../remote/activitypub/kernel/undo/follow.ts  |  44 -
 .../remote/activitypub/kernel/undo/index.ts   |  47 -
 .../remote/activitypub/kernel/undo/like.ts    |  22 -
 .../remote/activitypub/kernel/update/index.ts |  38 -
 .../backend/src/remote/activitypub/logger.ts  |   3 -
 .../src/remote/activitypub/misc/contexts.ts   | 525 ----------
 .../remote/activitypub/misc/get-note-html.ts  |   8 -
 .../remote/activitypub/misc/html-to-mfm.ts    |  11 -
 .../remote/activitypub/misc/ld-signature.ts   | 143 ---
 .../src/remote/activitypub/models/icon.ts     |   5 -
 .../remote/activitypub/models/identifier.ts   |   5 -
 .../src/remote/activitypub/models/image.ts    |  82 --
 .../src/remote/activitypub/models/mention.ts  |  36 -
 .../src/remote/activitypub/models/note.ts     | 499 ----------
 .../src/remote/activitypub/models/person.ts   | 698 -------------
 .../src/remote/activitypub/models/question.ts |  97 --
 .../src/remote/activitypub/models/tag.ts      |  25 -
 .../backend/src/remote/activitypub/perform.ts |  23 -
 .../src/remote/activitypub/renderer/accept.ts |   8 -
 .../src/remote/activitypub/renderer/add.ts    |   9 -
 .../remote/activitypub/renderer/announce.ts   |  37 -
 .../src/remote/activitypub/renderer/block.ts  |  20 -
 .../src/remote/activitypub/renderer/create.ts |  17 -
 .../src/remote/activitypub/renderer/delete.ts |   9 -
 .../remote/activitypub/renderer/document.ts   |   9 -
 .../src/remote/activitypub/renderer/emoji.ts  |  17 -
 .../src/remote/activitypub/renderer/flag.ts   |  20 -
 .../activitypub/renderer/follow-relay.ts      |  14 -
 .../activitypub/renderer/follow-user.ts       |  12 -
 .../src/remote/activitypub/renderer/follow.ts |  22 -
 .../remote/activitypub/renderer/hashtag.ts    |   7 -
 .../src/remote/activitypub/renderer/image.ts  |   9 -
 .../src/remote/activitypub/renderer/index.ts  |  73 --
 .../src/remote/activitypub/renderer/key.ts    |  14 -
 .../src/remote/activitypub/renderer/like.ts   |  37 -
 .../remote/activitypub/renderer/mention.ts    |  13 -
 .../src/remote/activitypub/renderer/note.ts   | 188 ----
 .../renderer/ordered-collection-page.ts       |  30 -
 .../renderer/ordered-collection.ts            |  34 -
 .../src/remote/activitypub/renderer/person.ts | 104 --
 .../remote/activitypub/renderer/question.ts   |  27 -
 .../src/remote/activitypub/renderer/read.ts   |  12 -
 .../src/remote/activitypub/renderer/reject.ts |   8 -
 .../src/remote/activitypub/renderer/remove.ts |   9 -
 .../remote/activitypub/renderer/tombstone.ts  |   4 -
 .../src/remote/activitypub/renderer/undo.ts   |  19 -
 .../src/remote/activitypub/renderer/update.ts |  15 -
 .../src/remote/activitypub/renderer/vote.ts   |  29 -
 .../backend/src/remote/activitypub/request.ts |  58 --
 .../src/remote/activitypub/resolver.ts        | 169 ----
 .../backend/src/remote/activitypub/type.ts    | 354 -------
 packages/backend/src/remote/logger.ts         |   3 -
 packages/backend/src/remote/resolve-user.ts   | 139 ---
 packages/backend/src/remote/webfinger.ts      |  41 -
 packages/backend/src/server/activitypub.ts    | 368 -------
 .../src/server/activitypub/featured.ts        |  61 --
 .../src/server/activitypub/followers.ts       | 119 ---
 .../src/server/activitypub/following.ts       | 119 ---
 .../backend/src/server/activitypub/outbox.ts  | 147 ---
 packages/backend/src/server/api/2fa.ts        | 417 --------
 .../backend/src/server/api/api-handler.ts     | 123 ---
 .../backend/src/server/api/authenticate.ts    | 103 --
 packages/backend/src/server/api/call.ts       | 192 ----
 .../server/api/common/generate-block-query.ts |  54 -
 .../api/common/generate-channel-query.ts      |  35 -
 .../api/common/generate-muted-note-query.ts   |  16 -
 .../generate-muted-note-thread-query.ts       |  24 -
 .../api/common/generate-muted-user-query.ts   |  81 --
 .../api/common/generate-native-user-token.ts  |   3 -
 .../api/common/generate-replies-query.ts      |  47 -
 .../api/common/generate-visibility-query.ts   |  61 --
 .../common/generated-muted-renote-query.ts    |  28 -
 .../backend/src/server/api/common/getters.ts  |  72 --
 .../src/server/api/common/inject-featured.ts  |  53 -
 .../src/server/api/common/inject-promo.ts     |  36 -
 .../src/server/api/common/is-native-token.ts  |   1 -
 .../api/common/make-pagination-query.ts       |  42 -
 .../api/common/read-messaging-message.ts      | 179 ----
 .../server/api/common/read-notification.ts    |  59 --
 .../backend/src/server/api/common/signin.ts   |  44 -
 .../backend/src/server/api/common/signup.ts   | 141 ---
 .../backend/src/server/api/compatibility.ts   |  20 -
 packages/backend/src/server/api/define.ts     | 105 --
 packages/backend/src/server/api/endpoints.ts  | 805 ---------------
 .../api/endpoints/admin/abuse-user-reports.ts | 144 ---
 .../api/endpoints/admin/accounts/create.ts    |  55 --
 .../api/endpoints/admin/accounts/delete.ts    |  58 --
 .../api/endpoints/admin/accounts/hosted.ts    | 116 ---
 .../server/api/endpoints/admin/ad/create.ts   |  46 -
 .../server/api/endpoints/admin/ad/delete.ts   |  34 -
 .../src/server/api/endpoints/admin/ad/list.ts |  32 -
 .../server/api/endpoints/admin/ad/update.ts   |  58 --
 .../endpoints/admin/announcements/create.ts   |  78 --
 .../endpoints/admin/announcements/delete.ts   |  34 -
 .../api/endpoints/admin/announcements/list.ts | 104 --
 .../endpoints/admin/announcements/update.ts   |  42 -
 .../api/endpoints/admin/delete-account.ts     |  29 -
 .../admin/delete-all-files-of-a-user.ts       |  28 -
 .../admin/drive-capacity-override.ts          |  43 -
 .../admin/drive/clean-remote-files.ts         |  19 -
 .../api/endpoints/admin/drive/cleanup.ts      |  27 -
 .../server/api/endpoints/admin/drive/files.ts |  89 --
 .../api/endpoints/admin/drive/show-file.ts    | 225 -----
 .../endpoints/admin/emoji/add-aliases-bulk.ts |  47 -
 .../server/api/endpoints/admin/emoji/add.ts   |  68 --
 .../server/api/endpoints/admin/emoji/copy.ts  |  88 --
 .../api/endpoints/admin/emoji/delete-bulk.ts  |  43 -
 .../api/endpoints/admin/emoji/delete.ts       |  42 -
 .../api/endpoints/admin/emoji/import-zip.ts   |  21 -
 .../api/endpoints/admin/emoji/list-remote.ts  | 105 --
 .../server/api/endpoints/admin/emoji/list.ts  | 107 --
 .../admin/emoji/remove-aliases-bulk.ts        |  47 -
 .../endpoints/admin/emoji/set-aliases-bulk.ts |  46 -
 .../admin/emoji/set-category-bulk.ts          |  45 -
 .../endpoints/admin/emoji/set-license-bulk.ts |  45 -
 .../api/endpoints/admin/emoji/update.ts       |  59 --
 .../admin/federation/delete-all-files.ts      |  28 -
 .../refresh-remote-instance-metadata.ts       |  29 -
 .../admin/federation/remove-all-following.ts  |  37 -
 .../admin/federation/update-instance.ts       |  34 -
 .../api/endpoints/admin/get-index-stats.ts    |  27 -
 .../api/endpoints/admin/get-table-stats.ts    |  49 -
 .../api/endpoints/admin/get-user-ips.ts       |  30 -
 .../src/server/api/endpoints/admin/invite.ts  |  50 -
 .../src/server/api/endpoints/admin/meta.ts    | 570 -----------
 .../api/endpoints/admin/moderators/add.ts     |  39 -
 .../api/endpoints/admin/moderators/remove.ts  |  35 -
 .../api/endpoints/admin/promo/create.ts       |  54 -
 .../server/api/endpoints/admin/queue/clear.ts |  22 -
 .../endpoints/admin/queue/deliver-delayed.ts  |  57 --
 .../endpoints/admin/queue/inbox-delayed.ts    |  57 --
 .../server/api/endpoints/admin/queue/stats.ts |  70 --
 .../server/api/endpoints/admin/relays/add.ts  |  65 --
 .../server/api/endpoints/admin/relays/list.ts |  51 -
 .../api/endpoints/admin/relays/remove.ts      |  21 -
 .../api/endpoints/admin/reset-password.ts     |  66 --
 .../admin/resolve-abuse-user-report.ts        |  47 -
 .../api/endpoints/admin/search/index-all.ts   |  28 -
 .../server/api/endpoints/admin/send-email.ts  |  23 -
 .../server/api/endpoints/admin/server-info.ts | 143 ---
 .../endpoints/admin/show-moderation-logs.ts   |  79 --
 .../server/api/endpoints/admin/show-user.ts   |  78 --
 .../server/api/endpoints/admin/show-users.ts  | 149 ---
 .../api/endpoints/admin/silence-user.ts       |  44 -
 .../api/endpoints/admin/suspend-user.ts       |  87 --
 .../api/endpoints/admin/unsilence-user.ts     |  40 -
 .../api/endpoints/admin/unsuspend-user.ts     |  37 -
 .../server/api/endpoints/admin/update-meta.ts | 543 -----------
 .../api/endpoints/admin/update-user-note.ts   |  33 -
 .../src/server/api/endpoints/admin/vacuum.ts  |  35 -
 .../src/server/api/endpoints/announcements.ts | 103 --
 .../server/api/endpoints/antennas/create.ts   | 141 ---
 .../server/api/endpoints/antennas/delete.ts   |  43 -
 .../src/server/api/endpoints/antennas/list.ts |  36 -
 .../server/api/endpoints/antennas/markread.ts |  43 -
 .../server/api/endpoints/antennas/notes.ts    |  97 --
 .../src/server/api/endpoints/antennas/show.ts |  48 -
 .../server/api/endpoints/antennas/update.ts   | 157 ---
 .../src/server/api/endpoints/ap/get.ts        |  36 -
 .../src/server/api/endpoints/ap/show.ts       | 164 ----
 .../src/server/api/endpoints/app/create.ts    |  67 --
 .../src/server/api/endpoints/app/show.ts      |  46 -
 .../src/server/api/endpoints/auth/accept.ts   |  76 --
 .../api/endpoints/auth/session/generate.ts    |  74 --
 .../server/api/endpoints/auth/session/show.ts |  63 --
 .../api/endpoints/auth/session/userkey.ts     |  99 --
 .../server/api/endpoints/blocking/create.ts   |  91 --
 .../server/api/endpoints/blocking/delete.ts   |  87 --
 .../src/server/api/endpoints/blocking/list.ts |  45 -
 .../server/api/endpoints/channels/create.ts   |  68 --
 .../server/api/endpoints/channels/featured.ts |  37 -
 .../server/api/endpoints/channels/follow.ts   |  48 -
 .../server/api/endpoints/channels/followed.ts |  59 --
 .../server/api/endpoints/channels/owned.ts    |  45 -
 .../src/server/api/endpoints/channels/show.ts |  45 -
 .../server/api/endpoints/channels/timeline.ts |  84 --
 .../server/api/endpoints/channels/unfollow.ts |  45 -
 .../server/api/endpoints/channels/update.ts   |  90 --
 .../api/endpoints/charts/active-users.ts      |  31 -
 .../server/api/endpoints/charts/ap-request.ts |  31 -
 .../src/server/api/endpoints/charts/drive.ts  |  31 -
 .../server/api/endpoints/charts/federation.ts |  31 -
 .../server/api/endpoints/charts/hashtag.ts    |  33 -
 .../server/api/endpoints/charts/instance.ts   |  33 -
 .../src/server/api/endpoints/charts/notes.ts  |  31 -
 .../server/api/endpoints/charts/user/drive.ts |  33 -
 .../api/endpoints/charts/user/following.ts    |  33 -
 .../server/api/endpoints/charts/user/notes.ts |  33 -
 .../api/endpoints/charts/user/reactions.ts    |  33 -
 .../src/server/api/endpoints/charts/users.ts  |  31 -
 .../server/api/endpoints/clips/add-note.ts    |  74 --
 .../src/server/api/endpoints/clips/create.ts  |  46 -
 .../src/server/api/endpoints/clips/delete.ts  |  40 -
 .../src/server/api/endpoints/clips/list.ts    |  36 -
 .../src/server/api/endpoints/clips/notes.ts   |  94 --
 .../server/api/endpoints/clips/remove-note.ts |  57 --
 .../src/server/api/endpoints/clips/show.ts    |  52 -
 .../src/server/api/endpoints/clips/update.ts  |  62 --
 .../endpoints/compatibility/custom-emojis.ts  |  37 -
 .../endpoints/compatibility/instance-info.ts  | 232 -----
 .../src/server/api/endpoints/custom-motd.ts   |  33 -
 .../api/endpoints/custom-splash-icons.ts      |  33 -
 .../backend/src/server/api/endpoints/drive.ts |  50 -
 .../src/server/api/endpoints/drive/files.ts   |  72 --
 .../endpoints/drive/files/attached-notes.ts   |  61 --
 .../endpoints/drive/files/caption-image.ts    |  42 -
 .../endpoints/drive/files/check-existence.ts  |  35 -
 .../api/endpoints/drive/files/create.ts       | 129 ---
 .../api/endpoints/drive/files/delete.ts       |  55 --
 .../api/endpoints/drive/files/find-by-hash.ts |  41 -
 .../server/api/endpoints/drive/files/find.ts  |  51 -
 .../server/api/endpoints/drive/files/show.ts  |  89 --
 .../api/endpoints/drive/files/update.ts       | 116 ---
 .../endpoints/drive/files/upload-from-url.ts  |  57 --
 .../src/server/api/endpoints/drive/folders.ts |  57 --
 .../api/endpoints/drive/folders/create.ts     |  69 --
 .../api/endpoints/drive/folders/delete.ts     |  60 --
 .../api/endpoints/drive/folders/find.ts       |  47 -
 .../api/endpoints/drive/folders/show.ts       |  50 -
 .../api/endpoints/drive/folders/update.ts     | 118 ---
 .../src/server/api/endpoints/drive/stream.ts  |  59 --
 .../api/endpoints/email-address/available.ts  |  38 -
 .../backend/src/server/api/endpoints/emoji.ts |  39 -
 .../src/server/api/endpoints/endpoint.ts      |  27 -
 .../src/server/api/endpoints/endpoints.ts     |  35 -
 .../api/endpoints/export-custom-emojis.ts     |  22 -
 .../api/endpoints/federation/followers.ts     |  46 -
 .../api/endpoints/federation/following.ts     |  46 -
 .../api/endpoints/federation/instances.ts     | 171 ----
 .../api/endpoints/federation/show-instance.ts |  36 -
 .../server/api/endpoints/federation/stats.ts  |  69 --
 .../federation/update-remote-user.ts          |  22 -
 .../server/api/endpoints/federation/users.ts  |  45 -
 .../src/server/api/endpoints/fetch-rss.ts     |  38 -
 .../server/api/endpoints/following/create.ts  | 107 --
 .../server/api/endpoints/following/delete.ts  |  84 --
 .../api/endpoints/following/invalidate.ts     |  84 --
 .../endpoints/following/requests/accept.ts    |  50 -
 .../endpoints/following/requests/cancel.ts    |  64 --
 .../api/endpoints/following/requests/list.ts  |  55 --
 .../endpoints/following/requests/reject.ts    |  41 -
 .../server/api/endpoints/gallery/featured.ts  |  40 -
 .../server/api/endpoints/gallery/popular.ts   |  37 -
 .../src/server/api/endpoints/gallery/posts.ts |  42 -
 .../api/endpoints/gallery/posts/create.ts     |  81 --
 .../api/endpoints/gallery/posts/delete.ts     |  40 -
 .../api/endpoints/gallery/posts/like.ts       |  61 --
 .../api/endpoints/gallery/posts/show.ts       |  45 -
 .../api/endpoints/gallery/posts/unlike.ts     |  54 -
 .../api/endpoints/gallery/posts/update.ts     |  84 --
 .../api/endpoints/get-online-users-count.ts   |  27 -
 .../src/server/api/endpoints/get-sounds.ts    |  30 -
 .../src/server/api/endpoints/hashtags/list.ts | 112 ---
 .../server/api/endpoints/hashtags/search.ts   |  42 -
 .../src/server/api/endpoints/hashtags/show.ts |  45 -
 .../server/api/endpoints/hashtags/trend.ts    | 178 ----
 .../server/api/endpoints/hashtags/users.ts    |  92 --
 .../backend/src/server/api/endpoints/i.ts     |  31 -
 .../src/server/api/endpoints/i/2fa/done.ts    |  42 -
 .../server/api/endpoints/i/2fa/key-done.ts    | 151 ---
 .../api/endpoints/i/2fa/password-less.ts      |  22 -
 .../api/endpoints/i/2fa/register-key.ts       |  61 --
 .../server/api/endpoints/i/2fa/register.ts    |  57 --
 .../server/api/endpoints/i/2fa/remove-key.ts  |  48 -
 .../server/api/endpoints/i/2fa/unregister.ts  |  33 -
 .../src/server/api/endpoints/i/apps.ts        |  56 --
 .../server/api/endpoints/i/authorized-apps.ts |  40 -
 .../server/api/endpoints/i/change-password.ts |  36 -
 .../server/api/endpoints/i/delete-account.ts  |  35 -
 .../server/api/endpoints/i/export-blocking.ts |  22 -
 .../api/endpoints/i/export-following.ts       |  25 -
 .../src/server/api/endpoints/i/export-mute.ts |  22 -
 .../server/api/endpoints/i/export-notes.ts    |  22 -
 .../api/endpoints/i/export-user-lists.ts      |  22 -
 .../src/server/api/endpoints/i/favorites.ts   |  47 -
 .../server/api/endpoints/i/gallery/likes.ts   |  60 --
 .../server/api/endpoints/i/gallery/posts.ts   |  45 -
 .../endpoints/i/get-word-muted-notes-count.ts |  38 -
 .../server/api/endpoints/i/import-blocking.ts |  60 --
 .../api/endpoints/i/import-following.ts       |  59 --
 .../server/api/endpoints/i/import-muting.ts   |  60 --
 .../server/api/endpoints/i/import-posts.ts    |  44 -
 .../api/endpoints/i/import-user-lists.ts      |  59 --
 .../src/server/api/endpoints/i/known-as.ts    | 101 --
 .../src/server/api/endpoints/i/move.ts        | 174 ----
 .../server/api/endpoints/i/notifications.ts   | 186 ----
 .../src/server/api/endpoints/i/page-likes.ts  |  58 --
 .../src/server/api/endpoints/i/pages.ts       |  45 -
 .../backend/src/server/api/endpoints/i/pin.ts |  63 --
 .../i/read-all-messaging-messages.ts          |  48 -
 .../api/endpoints/i/read-all-unread-notes.ts  |  28 -
 .../api/endpoints/i/read-announcement.ts      |  60 --
 .../api/endpoints/i/regenerate-token.ts       |  56 --
 .../api/endpoints/i/registry/get-all.ts       |  40 -
 .../api/endpoints/i/registry/get-detail.ts    |  52 -
 .../api/endpoints/i/registry/get-unsecure.ts  |  50 -
 .../server/api/endpoints/i/registry/get.ts    |  49 -
 .../endpoints/i/registry/keys-with-type.ts    |  54 -
 .../server/api/endpoints/i/registry/keys.ts   |  35 -
 .../server/api/endpoints/i/registry/remove.ts |  49 -
 .../server/api/endpoints/i/registry/scopes.ts |  32 -
 .../server/api/endpoints/i/registry/set.ts    |  62 --
 .../server/api/endpoints/i/revoke-token.ts    |  31 -
 .../server/api/endpoints/i/signin-history.ts  |  31 -
 .../src/server/api/endpoints/i/unpin.ts       |  47 -
 .../server/api/endpoints/i/update-email.ts    |  95 --
 .../src/server/api/endpoints/i/update.ts      | 307 ------
 .../api/endpoints/i/user-group-invites.ts     |  60 --
 .../server/api/endpoints/i/webhooks/create.ts |  46 -
 .../server/api/endpoints/i/webhooks/delete.ts |  43 -
 .../server/api/endpoints/i/webhooks/list.ts   |  24 -
 .../server/api/endpoints/i/webhooks/show.ts   |  40 -
 .../server/api/endpoints/i/webhooks/update.ts |  61 --
 .../server/api/endpoints/latest-version.ts    |  29 -
 .../server/api/endpoints/messaging/history.ts | 112 ---
 .../api/endpoints/messaging/messages.ts       | 182 ----
 .../endpoints/messaging/messages/create.ts    | 165 ----
 .../endpoints/messaging/messages/delete.ts    |  48 -
 .../api/endpoints/messaging/messages/read.ts  |  57 --
 .../backend/src/server/api/endpoints/meta.ts  | 530 ----------
 .../server/api/endpoints/miauth/gen-token.ts  |  69 --
 .../src/server/api/endpoints/mute/create.ts   |  95 --
 .../src/server/api/endpoints/mute/delete.ts   |  74 --
 .../src/server/api/endpoints/mute/list.ts     |  45 -
 .../src/server/api/endpoints/my/apps.ts       |  49 -
 .../backend/src/server/api/endpoints/notes.ts |  91 --
 .../server/api/endpoints/notes/children.ts    |  62 --
 .../src/server/api/endpoints/notes/clips.ts   |  59 --
 .../api/endpoints/notes/conversation.ts       |  81 --
 .../src/server/api/endpoints/notes/create.ts  | 308 ------
 .../src/server/api/endpoints/notes/delete.ts  |  57 --
 .../api/endpoints/notes/favorites/create.ts   |  62 --
 .../api/endpoints/notes/favorites/delete.ts   |  56 --
 .../server/api/endpoints/notes/featured.ts    |  82 --
 .../api/endpoints/notes/global-timeline.ts    | 121 ---
 .../api/endpoints/notes/hybrid-timeline.ts    | 177 ----
 .../api/endpoints/notes/local-timeline.ts     | 151 ---
 .../server/api/endpoints/notes/mentions.ts    | 108 --
 .../endpoints/notes/polls/recommendation.ts   |  85 --
 .../server/api/endpoints/notes/polls/vote.ts  | 184 ----
 .../server/api/endpoints/notes/reactions.ts   |  85 --
 .../api/endpoints/notes/reactions/create.ts   |  64 --
 .../api/endpoints/notes/reactions/delete.ts   |  54 -
 .../endpoints/notes/recommended-timeline.ts   | 154 ---
 .../src/server/api/endpoints/notes/renotes.ts |  94 --
 .../src/server/api/endpoints/notes/replies.ts |  78 --
 .../api/endpoints/notes/search-by-tag.ts      | 165 ----
 .../src/server/api/endpoints/notes/search.ts  | 254 -----
 .../src/server/api/endpoints/notes/show.ts    |  51 -
 .../src/server/api/endpoints/notes/state.ts   |  79 --
 .../endpoints/notes/thread-muting/create.ts   |  58 --
 .../endpoints/notes/thread-muting/delete.ts   |  41 -
 .../server/api/endpoints/notes/timeline.ts    | 169 ----
 .../server/api/endpoints/notes/translate.ts   |  94 --
 .../server/api/endpoints/notes/unrenote.ts    |  53 -
 .../api/endpoints/notes/user-list-timeline.ts | 164 ----
 .../api/endpoints/notes/watching/create.ts    |  38 -
 .../api/endpoints/notes/watching/delete.ts    |  38 -
 .../api/endpoints/notifications/create.ts     |  31 -
 .../notifications/mark-all-as-read.ts         |  35 -
 .../api/endpoints/notifications/read.ts       |  49 -
 .../src/server/api/endpoints/page-push.ts     |  48 -
 .../src/server/api/endpoints/pages/create.ts  | 123 ---
 .../src/server/api/endpoints/pages/delete.ts  |  45 -
 .../server/api/endpoints/pages/featured.ts    |  38 -
 .../src/server/api/endpoints/pages/like.ts    |  61 --
 .../src/server/api/endpoints/pages/show.ts    |  75 --
 .../src/server/api/endpoints/pages/unlike.ts  |  54 -
 .../src/server/api/endpoints/pages/update.ts  | 134 ---
 .../src/server/api/endpoints/patrons.ts       |  28 -
 .../backend/src/server/api/endpoints/ping.ts  |  32 -
 .../src/server/api/endpoints/pinned-users.ts  |  52 -
 .../src/server/api/endpoints/promo/read.ts    |  51 -
 .../api/endpoints/recommended-instances.ts    |  33 -
 .../src/server/api/endpoints/release.ts       |  28 -
 .../api/endpoints/renote-mute/create.ts       |  68 --
 .../api/endpoints/renote-mute/delete.ts       |  63 --
 .../server/api/endpoints/renote-mute/list.ts  |  46 -
 .../api/endpoints/request-reset-password.ts   |  76 --
 .../src/server/api/endpoints/reset-db.ts      |  29 -
 .../server/api/endpoints/reset-password.ts    |  44 -
 .../src/server/api/endpoints/server-info.ts   |  36 -
 .../backend/src/server/api/endpoints/stats.ts |  92 --
 .../src/server/api/endpoints/sw/register.ts   |  97 --
 .../api/endpoints/sw/show-registration.ts     |  59 --
 .../src/server/api/endpoints/sw/unregister.ts |  25 -
 .../api/endpoints/sw/update-registration.ts   |  44 -
 .../backend/src/server/api/endpoints/test.ts  |  25 -
 .../api/endpoints/username/available.ts       |  46 -
 .../backend/src/server/api/endpoints/users.ts | 134 ---
 .../src/server/api/endpoints/users/clips.ts   |  47 -
 .../server/api/endpoints/users/followers.ts   | 116 ---
 .../server/api/endpoints/users/following.ts   | 116 ---
 .../api/endpoints/users/gallery/posts.ts      |  45 -
 .../users/get-frequently-replied-users.ts     | 124 ---
 .../api/endpoints/users/groups/create.ts      |  49 -
 .../api/endpoints/users/groups/delete.ts      |  42 -
 .../users/groups/invitations/accept.ts        |  56 --
 .../users/groups/invitations/reject.ts        |  47 -
 .../api/endpoints/users/groups/invite.ts      | 108 --
 .../api/endpoints/users/groups/joined.ts      |  48 -
 .../api/endpoints/users/groups/leave.ts       |  53 -
 .../api/endpoints/users/groups/owned.ts       |  38 -
 .../server/api/endpoints/users/groups/pull.ts |  73 --
 .../server/api/endpoints/users/groups/show.ts |  58 --
 .../api/endpoints/users/groups/transfer.ts    |  85 --
 .../api/endpoints/users/groups/update.ts      |  55 --
 .../api/endpoints/users/lists/create.ts       |  40 -
 .../api/endpoints/users/lists/delete-all.ts   |  35 -
 .../api/endpoints/users/lists/delete.ts       |  42 -
 .../server/api/endpoints/users/lists/list.ts  |  38 -
 .../server/api/endpoints/users/lists/pull.ts  |  62 --
 .../server/api/endpoints/users/lists/push.ts  |  93 --
 .../server/api/endpoints/users/lists/show.ts  |  50 -
 .../api/endpoints/users/lists/update.ts       |  55 --
 .../src/server/api/endpoints/users/notes.ts   | 144 ---
 .../src/server/api/endpoints/users/pages.ts   |  48 -
 .../server/api/endpoints/users/reactions.ts   |  71 --
 .../api/endpoints/users/recommendation.ts     |  68 --
 .../server/api/endpoints/users/relation.ts    | 151 ---
 .../api/endpoints/users/report-abuse.ts       | 106 --
 .../users/search-by-username-and-host.ts      | 127 ---
 .../src/server/api/endpoints/users/search.ts  | 149 ---
 .../src/server/api/endpoints/users/show.ts    | 146 ---
 .../src/server/api/endpoints/users/stats.ts   | 225 -----
 packages/backend/src/server/api/error.ts      |  36 -
 packages/backend/src/server/api/index.ts      | 230 -----
 packages/backend/src/server/api/limiter.ts    |  85 --
 packages/backend/src/server/api/logger.ts     |   3 -
 .../mastodon/ApiMastodonCompatibleService.ts  | 140 ---
 .../server/api/mastodon/endpoints/account.ts  | 545 -----------
 .../src/server/api/mastodon/endpoints/auth.ts |  81 --
 .../server/api/mastodon/endpoints/filter.ts   |  84 --
 .../src/server/api/mastodon/endpoints/meta.ts | 111 ---
 .../api/mastodon/endpoints/notifications.ts   |  90 --
 .../server/api/mastodon/endpoints/search.ts   | 135 ---
 .../server/api/mastodon/endpoints/status.ts   | 445 ---------
 .../server/api/mastodon/endpoints/timeline.ts | 336 -------
 .../backend/src/server/api/openapi/errors.ts  |  71 --
 .../src/server/api/openapi/gen-spec.ts        | 226 -----
 .../backend/src/server/api/openapi/schemas.ts |  66 --
 .../backend/src/server/api/private/signin.ts  | 270 -----
 .../src/server/api/private/signup-pending.ts  |  38 -
 .../backend/src/server/api/private/signup.ts  | 123 ---
 .../backend/src/server/api/service/discord.ts | 333 -------
 .../backend/src/server/api/service/github.ts  | 296 ------
 .../backend/src/server/api/service/twitter.ts | 226 -----
 .../backend/src/server/api/stream/channel.ts  |  99 --
 .../src/server/api/stream/channels/admin.ts   |  14 -
 .../src/server/api/stream/channels/antenna.ts |  63 --
 .../src/server/api/stream/channels/channel.ts |  84 --
 .../src/server/api/stream/channels/drive.ts   |  14 -
 .../api/stream/channels/global-timeline.ts    |  82 --
 .../src/server/api/stream/channels/hashtag.ts |  52 -
 .../api/stream/channels/home-timeline.ts      |  80 --
 .../api/stream/channels/hybrid-timeline.ts    |  97 --
 .../src/server/api/stream/channels/index.ts   |  35 -
 .../api/stream/channels/local-timeline.ts     |  74 --
 .../src/server/api/stream/channels/main.ts    |  46 -
 .../api/stream/channels/messaging-index.ts    |  14 -
 .../server/api/stream/channels/messaging.ts   | 130 ---
 .../server/api/stream/channels/queue-stats.ts |  42 -
 .../stream/channels/recommended-timeline.ts   |  95 --
 .../api/stream/channels/server-stats.ts       |  42 -
 .../server/api/stream/channels/user-list.ts   |  72 --
 .../backend/src/server/api/stream/index.ts    | 621 ------------
 .../backend/src/server/api/stream/types.ts    | 292 ------
 packages/backend/src/server/api/streaming.ts  |  89 --
 .../src/server/file/assets/bad-egg.png        | Bin 1676 -> 0 bytes
 .../src/server/file/assets/cache-expired.png  | Bin 6048 -> 0 bytes
 .../backend/src/server/file/assets/dummy.png  | Bin 6285 -> 0 bytes
 .../src/server/file/assets/not-an-image.png   | Bin 2780 -> 0 bytes
 .../file/assets/thumbnail-not-available.png   | Bin 5705 -> 0 bytes
 .../src/server/file/assets/tombstone.png      | Bin 5028 -> 0 bytes
 packages/backend/src/server/file/index.ts     |  43 -
 .../src/server/file/send-drive-file.ts        | 152 ---
 packages/backend/src/server/index.ts          | 286 ------
 packages/backend/src/server/nodeinfo.ts       | 119 ---
 packages/backend/src/server/proxy/index.ts    |  29 -
 .../backend/src/server/proxy/proxy-media.ts   | 105 --
 packages/backend/src/server/web/bios.css      | 147 ---
 packages/backend/src/server/web/bios.js       |  89 --
 packages/backend/src/server/web/boot.js       | 319 ------
 packages/backend/src/server/web/cli.css       |  92 --
 packages/backend/src/server/web/cli.js        |  72 --
 packages/backend/src/server/web/feed.ts       |  65 --
 packages/backend/src/server/web/index.ts      | 677 -------------
 packages/backend/src/server/web/manifest.json |  74 --
 packages/backend/src/server/web/manifest.ts   |  18 -
 packages/backend/src/server/web/style.css     | 127 ---
 .../backend/src/server/web/url-preview.ts     |  88 --
 .../backend/src/server/web/views/base.pug     |  96 --
 .../backend/src/server/web/views/bios.pug     |  21 -
 .../backend/src/server/web/views/channel.pug  |  20 -
 packages/backend/src/server/web/views/cli.pug |  23 -
 .../backend/src/server/web/views/clip.pug     |  34 -
 .../backend/src/server/web/views/flush.pug    |  71 --
 .../src/server/web/views/gallery-post.pug     |  36 -
 .../src/server/web/views/info-card.pug        |  50 -
 .../backend/src/server/web/views/note.pug     |  56 --
 .../backend/src/server/web/views/page.pug     |  34 -
 .../backend/src/server/web/views/user.pug     |  42 -
 packages/backend/src/server/well-known.ts     | 191 ----
 .../src/services/add-note-to-antenna.ts       |  61 --
 .../backend/src/services/blocking/create.ts   | 165 ----
 .../backend/src/services/blocking/delete.ts   |  37 -
 .../src/services/chart/charts/active-users.ts |  59 --
 .../src/services/chart/charts/ap-request.ts   |  39 -
 .../src/services/chart/charts/drive.ts        |  43 -
 .../chart/charts/entities/active-users.ts     |  17 -
 .../chart/charts/entities/ap-request.ts       |  11 -
 .../services/chart/charts/entities/drive.ts   |  16 -
 .../chart/charts/entities/federation.ts       |  16 -
 .../services/chart/charts/entities/hashtag.ts |  10 -
 .../chart/charts/entities/instance.ts         |  32 -
 .../services/chart/charts/entities/notes.ts   |  22 -
 .../chart/charts/entities/per-user-drive.ts   |  14 -
 .../charts/entities/per-user-following.ts     |  20 -
 .../chart/charts/entities/per-user-notes.ts   |  15 -
 .../charts/entities/per-user-reactions.ts     |  10 -
 .../chart/charts/entities/test-grouped.ts     |  11 -
 .../charts/entities/test-intersection.ts      |  11 -
 .../chart/charts/entities/test-unique.ts      |   9 -
 .../services/chart/charts/entities/test.ts    |  11 -
 .../services/chart/charts/entities/users.ts   |  14 -
 .../src/services/chart/charts/federation.ts   | 142 ---
 .../src/services/chart/charts/hashtag.ts      |  36 -
 .../src/services/chart/charts/instance.ts     | 142 ---
 .../src/services/chart/charts/notes.ts        |  54 -
 .../services/chart/charts/per-user-drive.ts   |  48 -
 .../chart/charts/per-user-following.ts        |  69 --
 .../services/chart/charts/per-user-notes.ts   |  54 -
 .../chart/charts/per-user-reactions.ts        |  39 -
 .../src/services/chart/charts/test-grouped.ts |  41 -
 .../chart/charts/test-intersection.ts         |  33 -
 .../src/services/chart/charts/test-unique.ts  |  27 -
 .../backend/src/services/chart/charts/test.ts |  43 -
 .../src/services/chart/charts/users.ts        |  45 -
 packages/backend/src/services/chart/core.ts   | 922 ------------------
 .../backend/src/services/chart/entities.ts    |  57 --
 packages/backend/src/services/chart/index.ts  |  51 -
 .../src/services/create-notification.ts       |  91 --
 .../src/services/create-system-user.ts        |  71 --
 .../backend/src/services/delete-account.ts    |  23 -
 .../backend/src/services/detect-sensitive.ts  |  55 --
 .../backend/src/services/drive/add-file.ts    | 671 -------------
 .../backend/src/services/drive/delete-file.ts | 107 --
 .../drive/generate-video-thumbnail.ts         |  29 -
 .../src/services/drive/image-processor.ts     |  44 -
 .../src/services/drive/internal-storage.ts    |  35 -
 packages/backend/src/services/drive/logger.ts |   3 -
 packages/backend/src/services/drive/s3.ts     |  27 -
 .../src/services/drive/upload-from-url.ts     |  81 --
 .../src/services/fetch-instance-metadata.ts   | 321 ------
 .../backend/src/services/following/create.ts  | 276 ------
 .../backend/src/services/following/delete.ts  | 113 ---
 .../backend/src/services/following/reject.ts  | 134 ---
 .../services/following/requests/accept-all.ts |  24 -
 .../src/services/following/requests/accept.ts |  49 -
 .../src/services/following/requests/cancel.ts |  51 -
 .../src/services/following/requests/create.ts |  85 --
 packages/backend/src/services/i/pin.ts        | 118 ---
 packages/backend/src/services/i/update.ts     |  21 -
 .../src/services/insert-moderation-log.ts     |  17 -
 .../backend/src/services/instance-actor.ts    |  28 -
 packages/backend/src/services/logger.ts       | 199 ----
 .../backend/src/services/messages/create.ts   | 148 ---
 .../backend/src/services/messages/delete.ts   |  50 -
 packages/backend/src/services/note/create.ts  | 871 -----------------
 packages/backend/src/services/note/delete.ts  | 185 ----
 .../backend/src/services/note/polls/update.ts |  23 -
 .../backend/src/services/note/polls/vote.ts   |  87 --
 .../src/services/note/reaction/create.ts      | 169 ----
 .../src/services/note/reaction/delete.ts      |  70 --
 packages/backend/src/services/note/read.ts    | 173 ----
 packages/backend/src/services/note/unread.ts  |  59 --
 packages/backend/src/services/note/unwatch.ts |  10 -
 packages/backend/src/services/note/watch.ts   |  20 -
 .../backend/src/services/push-notification.ts | 116 ---
 .../register-or-fetch-instance-doc.ts         |  33 -
 packages/backend/src/services/relay.ts        | 109 ---
 .../src/services/send-email-notification.ts   |  36 -
 packages/backend/src/services/send-email.ts   | 132 ---
 packages/backend/src/services/stream.ts       | 226 -----
 packages/backend/src/services/suspend-user.ts |  47 -
 .../backend/src/services/unsuspend-user.ts    |  45 -
 .../backend/src/services/update-hashtag.ts    | 158 ---
 packages/backend/src/services/user-cache.ts   |  63 --
 .../backend/src/services/user-list/push.ts    |  27 -
 .../services/validate-email-for-account.ts    |  45 -
 packages/backend/src/types.ts                 |  25 -
 packages/backend/test/activitypub.ts          | 102 --
 packages/backend/test/ap-request.ts           |  75 --
 packages/backend/test/api-visibility.ts       | 535 ----------
 packages/backend/test/api.ts                  |  92 --
 packages/backend/test/block.ts                | 129 ---
 packages/backend/test/chart.ts                | 575 -----------
 packages/backend/test/docker-compose.yml      |  15 -
 packages/backend/test/endpoints.ts            | 865 ----------------
 packages/backend/test/extract-mentions.ts     |  50 -
 packages/backend/test/fetch-resource.ts       | 213 ----
 packages/backend/test/ff-visibility.ts        | 283 ------
 packages/backend/test/get-file-info.ts        | 209 ----
 packages/backend/test/loader.js               |  37 -
 packages/backend/test/mfm.ts                  | 127 ---
 packages/backend/test/misc/mock-resolver.ts   |  39 -
 packages/backend/test/mute.ts                 | 176 ----
 packages/backend/test/note.ts                 | 517 ----------
 packages/backend/test/prelude/maybe.ts        |  18 -
 packages/backend/test/prelude/url.ts          |  13 -
 packages/backend/test/reaction-lib.ts         |  83 --
 .../backend/test/resources/25000x25000.png    | Bin 75933 -> 0 bytes
 packages/backend/test/resources/Lenna.jpg     | Bin 25360 -> 0 bytes
 packages/backend/test/resources/Lenna.png     | Bin 473831 -> 0 bytes
 packages/backend/test/resources/anime.gif     | Bin 2248 -> 0 bytes
 packages/backend/test/resources/anime.png     | Bin 1868 -> 0 bytes
 packages/backend/test/resources/emptyfile     |   0
 packages/backend/test/resources/image.svg     |   1 -
 packages/backend/test/resources/rotate.jpg    | Bin 12624 -> 0 bytes
 .../backend/test/resources/with-alpha.png     | Bin 3772 -> 0 bytes
 .../backend/test/resources/with-xml-def.svg   |   2 -
 packages/backend/test/streaming.ts            | 766 ---------------
 packages/backend/test/thread-mute.ts          | 161 ---
 packages/backend/test/tsconfig.json           |  41 -
 packages/backend/test/user-notes.ts           |  98 --
 packages/backend/test/utils.ts                | 403 --------
 packages/backend/tsconfig.json                |  48 -
 965 files changed, 82 insertions(+), 75200 deletions(-)
 create mode 100644 packages/backend/.gitignore
 delete mode 100644 packages/backend/.mocharc.json
 delete mode 100644 packages/backend/.swcrc
 create mode 100644 packages/backend/.vim/coc-settings.json
 create mode 100644 packages/backend/Cargo.lock
 create mode 100644 packages/backend/Cargo.toml
 create mode 100644 packages/backend/crates/server/Cargo.toml
 create mode 100644 packages/backend/crates/server/src/lib.rs
 delete mode 100644 packages/backend/jsconfig.json
 delete mode 100644 packages/backend/native-utils/.cargo/config.toml
 delete mode 100644 packages/backend/native-utils/.gitignore
 delete mode 100644 packages/backend/native-utils/.npmignore
 delete mode 100644 packages/backend/native-utils/Cargo.toml
 delete mode 100644 packages/backend/native-utils/__test__/index.spec.mjs
 delete mode 100644 packages/backend/native-utils/build.rs
 delete mode 100644 packages/backend/native-utils/npm/android-arm-eabi/README.md
 delete mode 100644 packages/backend/native-utils/npm/android-arm-eabi/package.json
 delete mode 100644 packages/backend/native-utils/npm/android-arm64/README.md
 delete mode 100644 packages/backend/native-utils/npm/android-arm64/package.json
 delete mode 100644 packages/backend/native-utils/npm/darwin-arm64/README.md
 delete mode 100644 packages/backend/native-utils/npm/darwin-arm64/package.json
 delete mode 100644 packages/backend/native-utils/npm/darwin-universal/README.md
 delete mode 100644 packages/backend/native-utils/npm/darwin-universal/package.json
 delete mode 100644 packages/backend/native-utils/npm/darwin-x64/README.md
 delete mode 100644 packages/backend/native-utils/npm/darwin-x64/package.json
 delete mode 100644 packages/backend/native-utils/npm/freebsd-x64/README.md
 delete mode 100644 packages/backend/native-utils/npm/freebsd-x64/package.json
 delete mode 100644 packages/backend/native-utils/npm/linux-arm-gnueabihf/README.md
 delete mode 100644 packages/backend/native-utils/npm/linux-arm-gnueabihf/package.json
 delete mode 100644 packages/backend/native-utils/npm/linux-arm64-gnu/README.md
 delete mode 100644 packages/backend/native-utils/npm/linux-arm64-gnu/package.json
 delete mode 100644 packages/backend/native-utils/npm/linux-arm64-musl/README.md
 delete mode 100644 packages/backend/native-utils/npm/linux-arm64-musl/package.json
 delete mode 100644 packages/backend/native-utils/npm/linux-x64-gnu/README.md
 delete mode 100644 packages/backend/native-utils/npm/linux-x64-gnu/package.json
 delete mode 100644 packages/backend/native-utils/npm/linux-x64-musl/README.md
 delete mode 100644 packages/backend/native-utils/npm/linux-x64-musl/package.json
 delete mode 100644 packages/backend/native-utils/npm/win32-arm64-msvc/README.md
 delete mode 100644 packages/backend/native-utils/npm/win32-arm64-msvc/package.json
 delete mode 100644 packages/backend/native-utils/npm/win32-ia32-msvc/README.md
 delete mode 100644 packages/backend/native-utils/npm/win32-ia32-msvc/package.json
 delete mode 100644 packages/backend/native-utils/npm/win32-x64-msvc/README.md
 delete mode 100644 packages/backend/native-utils/npm/win32-x64-msvc/package.json
 delete mode 100644 packages/backend/native-utils/package.json
 delete mode 100644 packages/backend/native-utils/rustfmt.toml
 delete mode 100644 packages/backend/native-utils/src/lib.rs
 delete mode 100644 packages/backend/native-utils/src/mastodon_api.rs
 delete mode 100644 packages/backend/ormconfig.js
 create mode 100644 packages/backend/rust-toolchain
 create mode 100644 packages/backend/rustfmt.toml
 delete mode 100644 packages/backend/src/@types/hcaptcha.d.ts
 delete mode 100644 packages/backend/src/@types/http-signature.d.ts
 delete mode 100644 packages/backend/src/@types/koa-json-body.d.ts
 delete mode 100644 packages/backend/src/@types/koa-remove-trailing-slashes/index.d.ts
 delete mode 100644 packages/backend/src/@types/koa-slow.d.ts
 delete mode 100644 packages/backend/src/@types/os-utils.d.ts
 delete mode 100644 packages/backend/src/@types/package.json.d.ts
 delete mode 100644 packages/backend/src/@types/probe-image-size.d.ts
 create mode 100644 packages/backend/src/bin/migrate.rs
 delete mode 100644 packages/backend/src/boot/index.ts
 delete mode 100644 packages/backend/src/boot/master.ts
 delete mode 100644 packages/backend/src/boot/worker.ts
 delete mode 100644 packages/backend/src/config/index.ts
 delete mode 100644 packages/backend/src/config/load.ts
 delete mode 100644 packages/backend/src/config/types.ts
 delete mode 100644 packages/backend/src/const.ts
 delete mode 100644 packages/backend/src/daemons/janitor.ts
 delete mode 100644 packages/backend/src/daemons/queue-stats.ts
 delete mode 100644 packages/backend/src/daemons/server-stats.ts
 delete mode 100644 packages/backend/src/db/elasticsearch.ts
 delete mode 100644 packages/backend/src/db/logger.ts
 delete mode 100644 packages/backend/src/db/postgre.ts
 delete mode 100644 packages/backend/src/db/redis.ts
 delete mode 100644 packages/backend/src/db/sonic.ts
 delete mode 100644 packages/backend/src/env.ts
 delete mode 100644 packages/backend/src/global.d.ts
 delete mode 100644 packages/backend/src/index.ts
 create mode 100644 packages/backend/src/main.rs
 delete mode 100644 packages/backend/src/mfm/from-html.ts
 delete mode 100644 packages/backend/src/mfm/to-html.ts
 delete mode 100644 packages/backend/src/misc/acct.ts
 delete mode 100644 packages/backend/src/misc/antenna-cache.ts
 delete mode 100644 packages/backend/src/misc/api-permissions.ts
 delete mode 100644 packages/backend/src/misc/app-lock.ts
 delete mode 100644 packages/backend/src/misc/before-shutdown.ts
 delete mode 100644 packages/backend/src/misc/cache.ts
 delete mode 100644 packages/backend/src/misc/captcha.ts
 delete mode 100644 packages/backend/src/misc/check-hit-antenna.ts
 delete mode 100644 packages/backend/src/misc/check-word-mute.ts
 delete mode 100644 packages/backend/src/misc/clone.ts
 delete mode 100644 packages/backend/src/misc/content-disposition.ts
 delete mode 100644 packages/backend/src/misc/convert-host.ts
 delete mode 100644 packages/backend/src/misc/count-same-renotes.ts
 delete mode 100644 packages/backend/src/misc/create-temp.ts
 delete mode 100644 packages/backend/src/misc/detect-url-mime.ts
 delete mode 100644 packages/backend/src/misc/download-text-file.ts
 delete mode 100644 packages/backend/src/misc/download-url.ts
 delete mode 100644 packages/backend/src/misc/emoji-regex.ts
 delete mode 100644 packages/backend/src/misc/extract-custom-emojis-from-mfm.ts
 delete mode 100644 packages/backend/src/misc/extract-hashtags.ts
 delete mode 100644 packages/backend/src/misc/extract-mentions.ts
 delete mode 100644 packages/backend/src/misc/fetch-meta.ts
 delete mode 100644 packages/backend/src/misc/fetch-proxy-account.ts
 delete mode 100644 packages/backend/src/misc/fetch.ts
 delete mode 100644 packages/backend/src/misc/gen-id.ts
 delete mode 100644 packages/backend/src/misc/gen-identicon.ts
 delete mode 100644 packages/backend/src/misc/gen-key-pair.ts
 delete mode 100644 packages/backend/src/misc/get-file-info.ts
 delete mode 100644 packages/backend/src/misc/get-ip-hash.ts
 delete mode 100644 packages/backend/src/misc/get-note-summary.ts
 delete mode 100644 packages/backend/src/misc/get-reaction-emoji.ts
 delete mode 100644 packages/backend/src/misc/hard-limits.ts
 delete mode 100644 packages/backend/src/misc/i18n.ts
 delete mode 100644 packages/backend/src/misc/id/aid.ts
 delete mode 100644 packages/backend/src/misc/id/meid.ts
 delete mode 100644 packages/backend/src/misc/id/meidg.ts
 delete mode 100644 packages/backend/src/misc/id/object-id.ts
 delete mode 100644 packages/backend/src/misc/identifiable-error.ts
 delete mode 100644 packages/backend/src/misc/is-duplicate-key-value-error.ts
 delete mode 100644 packages/backend/src/misc/is-instance-muted.ts
 delete mode 100644 packages/backend/src/misc/is-mime-image.ts
 delete mode 100644 packages/backend/src/misc/is-quote.ts
 delete mode 100644 packages/backend/src/misc/is-user-related.ts
 delete mode 100644 packages/backend/src/misc/keypair-store.ts
 delete mode 100644 packages/backend/src/misc/langmap.ts
 delete mode 100644 packages/backend/src/misc/normalize-for-search.ts
 delete mode 100644 packages/backend/src/misc/nyaize.ts
 delete mode 100644 packages/backend/src/misc/password.ts
 delete mode 100644 packages/backend/src/misc/populate-emojis.ts
 delete mode 100644 packages/backend/src/misc/post.ts
 delete mode 100644 packages/backend/src/misc/reaction-lib.ts
 delete mode 100644 packages/backend/src/misc/safe-for-sql.ts
 delete mode 100644 packages/backend/src/misc/schema.ts
 delete mode 100644 packages/backend/src/misc/secure-rndstr.ts
 delete mode 100644 packages/backend/src/misc/should-block-instance.ts
 delete mode 100644 packages/backend/src/misc/show-machine-info.ts
 delete mode 100644 packages/backend/src/misc/skipped-instances.ts
 delete mode 100644 packages/backend/src/misc/truncate.ts
 delete mode 100644 packages/backend/src/misc/webhook-cache.ts
 delete mode 100644 packages/backend/src/models/entities/abuse-user-report.ts
 delete mode 100644 packages/backend/src/models/entities/access-token.ts
 delete mode 100644 packages/backend/src/models/entities/ad.ts
 delete mode 100644 packages/backend/src/models/entities/announcement-read.ts
 delete mode 100644 packages/backend/src/models/entities/announcement.ts
 delete mode 100644 packages/backend/src/models/entities/antenna-note.ts
 delete mode 100644 packages/backend/src/models/entities/antenna.ts
 delete mode 100644 packages/backend/src/models/entities/app.ts
 delete mode 100644 packages/backend/src/models/entities/attestation-challenge.ts
 delete mode 100644 packages/backend/src/models/entities/auth-session.ts
 delete mode 100644 packages/backend/src/models/entities/blocking.ts
 delete mode 100644 packages/backend/src/models/entities/channel-following.ts
 delete mode 100644 packages/backend/src/models/entities/channel-note-pining.ts
 delete mode 100644 packages/backend/src/models/entities/channel.ts
 delete mode 100644 packages/backend/src/models/entities/clip-note.ts
 delete mode 100644 packages/backend/src/models/entities/clip.ts
 delete mode 100644 packages/backend/src/models/entities/drive-file.ts
 delete mode 100644 packages/backend/src/models/entities/drive-folder.ts
 delete mode 100644 packages/backend/src/models/entities/emoji.ts
 delete mode 100644 packages/backend/src/models/entities/follow-request.ts
 delete mode 100644 packages/backend/src/models/entities/following.ts
 delete mode 100644 packages/backend/src/models/entities/gallery-like.ts
 delete mode 100644 packages/backend/src/models/entities/gallery-post.ts
 delete mode 100644 packages/backend/src/models/entities/hashtag.ts
 delete mode 100644 packages/backend/src/models/entities/instance.ts
 delete mode 100644 packages/backend/src/models/entities/messaging-message.ts
 delete mode 100644 packages/backend/src/models/entities/meta.ts
 delete mode 100644 packages/backend/src/models/entities/moderation-log.ts
 delete mode 100644 packages/backend/src/models/entities/muted-note.ts
 delete mode 100644 packages/backend/src/models/entities/muting.ts
 delete mode 100644 packages/backend/src/models/entities/note-favorite.ts
 delete mode 100644 packages/backend/src/models/entities/note-reaction.ts
 delete mode 100644 packages/backend/src/models/entities/note-thread-muting.ts
 delete mode 100644 packages/backend/src/models/entities/note-unread.ts
 delete mode 100644 packages/backend/src/models/entities/note-watching.ts
 delete mode 100644 packages/backend/src/models/entities/note.ts
 delete mode 100644 packages/backend/src/models/entities/notification.ts
 delete mode 100644 packages/backend/src/models/entities/page-like.ts
 delete mode 100644 packages/backend/src/models/entities/page.ts
 delete mode 100644 packages/backend/src/models/entities/password-reset-request.ts
 delete mode 100644 packages/backend/src/models/entities/poll-vote.ts
 delete mode 100644 packages/backend/src/models/entities/poll.ts
 delete mode 100644 packages/backend/src/models/entities/promo-note.ts
 delete mode 100644 packages/backend/src/models/entities/promo-read.ts
 delete mode 100644 packages/backend/src/models/entities/registration-tickets.ts
 delete mode 100644 packages/backend/src/models/entities/registry-item.ts
 delete mode 100644 packages/backend/src/models/entities/relay.ts
 delete mode 100644 packages/backend/src/models/entities/renote-muting.ts
 delete mode 100644 packages/backend/src/models/entities/signin.ts
 delete mode 100644 packages/backend/src/models/entities/sw-subscription.ts
 delete mode 100644 packages/backend/src/models/entities/used-username.ts
 delete mode 100644 packages/backend/src/models/entities/user-group-invitation.ts
 delete mode 100644 packages/backend/src/models/entities/user-group-joining.ts
 delete mode 100644 packages/backend/src/models/entities/user-group.ts
 delete mode 100644 packages/backend/src/models/entities/user-ip.ts
 delete mode 100644 packages/backend/src/models/entities/user-keypair.ts
 delete mode 100644 packages/backend/src/models/entities/user-list-joining.ts
 delete mode 100644 packages/backend/src/models/entities/user-list.ts
 delete mode 100644 packages/backend/src/models/entities/user-note-pining.ts
 delete mode 100644 packages/backend/src/models/entities/user-pending.ts
 delete mode 100644 packages/backend/src/models/entities/user-profile.ts
 delete mode 100644 packages/backend/src/models/entities/user-publickey.ts
 delete mode 100644 packages/backend/src/models/entities/user-security-key.ts
 delete mode 100644 packages/backend/src/models/entities/user.ts
 delete mode 100644 packages/backend/src/models/entities/webhook.ts
 delete mode 100644 packages/backend/src/models/id.ts
 delete mode 100644 packages/backend/src/models/index.ts
 delete mode 100644 packages/backend/src/models/repositories/abuse-user-report.ts
 delete mode 100644 packages/backend/src/models/repositories/antenna.ts
 delete mode 100644 packages/backend/src/models/repositories/app.ts
 delete mode 100644 packages/backend/src/models/repositories/auth-session.ts
 delete mode 100644 packages/backend/src/models/repositories/blocking.ts
 delete mode 100644 packages/backend/src/models/repositories/channel.ts
 delete mode 100644 packages/backend/src/models/repositories/clip.ts
 delete mode 100644 packages/backend/src/models/repositories/drive-file.ts
 delete mode 100644 packages/backend/src/models/repositories/drive-folder.ts
 delete mode 100644 packages/backend/src/models/repositories/emoji.ts
 delete mode 100644 packages/backend/src/models/repositories/follow-request.ts
 delete mode 100644 packages/backend/src/models/repositories/following.ts
 delete mode 100644 packages/backend/src/models/repositories/gallery-like.ts
 delete mode 100644 packages/backend/src/models/repositories/gallery-post.ts
 delete mode 100644 packages/backend/src/models/repositories/hashtag.ts
 delete mode 100644 packages/backend/src/models/repositories/instance.ts
 delete mode 100644 packages/backend/src/models/repositories/messaging-message.ts
 delete mode 100644 packages/backend/src/models/repositories/moderation-logs.ts
 delete mode 100644 packages/backend/src/models/repositories/muting.ts
 delete mode 100644 packages/backend/src/models/repositories/note-favorite.ts
 delete mode 100644 packages/backend/src/models/repositories/note-reaction.ts
 delete mode 100644 packages/backend/src/models/repositories/note.ts
 delete mode 100644 packages/backend/src/models/repositories/notification.ts
 delete mode 100644 packages/backend/src/models/repositories/page-like.ts
 delete mode 100644 packages/backend/src/models/repositories/page.ts
 delete mode 100644 packages/backend/src/models/repositories/relay.ts
 delete mode 100644 packages/backend/src/models/repositories/renote-muting.ts
 delete mode 100644 packages/backend/src/models/repositories/signin.ts
 delete mode 100644 packages/backend/src/models/repositories/user-group-invitation.ts
 delete mode 100644 packages/backend/src/models/repositories/user-group.ts
 delete mode 100644 packages/backend/src/models/repositories/user-list.ts
 delete mode 100644 packages/backend/src/models/repositories/user.ts
 delete mode 100644 packages/backend/src/models/schema/antenna.ts
 delete mode 100644 packages/backend/src/models/schema/app.ts
 delete mode 100644 packages/backend/src/models/schema/blocking.ts
 delete mode 100644 packages/backend/src/models/schema/channel.ts
 delete mode 100644 packages/backend/src/models/schema/clip.ts
 delete mode 100644 packages/backend/src/models/schema/drive-file.ts
 delete mode 100644 packages/backend/src/models/schema/drive-folder.ts
 delete mode 100644 packages/backend/src/models/schema/emoji.ts
 delete mode 100644 packages/backend/src/models/schema/federation-instance.ts
 delete mode 100644 packages/backend/src/models/schema/following.ts
 delete mode 100644 packages/backend/src/models/schema/gallery-post.ts
 delete mode 100644 packages/backend/src/models/schema/hashtag.ts
 delete mode 100644 packages/backend/src/models/schema/messaging-message.ts
 delete mode 100644 packages/backend/src/models/schema/muting.ts
 delete mode 100644 packages/backend/src/models/schema/note-favorite.ts
 delete mode 100644 packages/backend/src/models/schema/note-reaction.ts
 delete mode 100644 packages/backend/src/models/schema/note.ts
 delete mode 100644 packages/backend/src/models/schema/notification.ts
 delete mode 100644 packages/backend/src/models/schema/page.ts
 delete mode 100644 packages/backend/src/models/schema/queue.ts
 delete mode 100644 packages/backend/src/models/schema/renote-muting.ts
 delete mode 100644 packages/backend/src/models/schema/user-group.ts
 delete mode 100644 packages/backend/src/models/schema/user-list.ts
 delete mode 100644 packages/backend/src/models/schema/user.ts
 delete mode 100644 packages/backend/src/prelude/README.md
 delete mode 100644 packages/backend/src/prelude/array.ts
 delete mode 100644 packages/backend/src/prelude/await-all.ts
 delete mode 100644 packages/backend/src/prelude/math.ts
 delete mode 100644 packages/backend/src/prelude/maybe.ts
 delete mode 100644 packages/backend/src/prelude/relation.ts
 delete mode 100644 packages/backend/src/prelude/string.ts
 delete mode 100644 packages/backend/src/prelude/symbol.ts
 delete mode 100644 packages/backend/src/prelude/time.ts
 delete mode 100644 packages/backend/src/prelude/url.ts
 delete mode 100644 packages/backend/src/prelude/xml.ts
 delete mode 100644 packages/backend/src/queue/get-job-info.ts
 delete mode 100644 packages/backend/src/queue/index.ts
 delete mode 100644 packages/backend/src/queue/initialize.ts
 delete mode 100644 packages/backend/src/queue/logger.ts
 delete mode 100644 packages/backend/src/queue/processors/background/index-all-notes.ts
 delete mode 100644 packages/backend/src/queue/processors/background/index.ts
 delete mode 100644 packages/backend/src/queue/processors/db/delete-account.ts
 delete mode 100644 packages/backend/src/queue/processors/db/delete-drive-files.ts
 delete mode 100644 packages/backend/src/queue/processors/db/export-blocking.ts
 delete mode 100644 packages/backend/src/queue/processors/db/export-custom-emojis.ts
 delete mode 100644 packages/backend/src/queue/processors/db/export-following.ts
 delete mode 100644 packages/backend/src/queue/processors/db/export-mute.ts
 delete mode 100644 packages/backend/src/queue/processors/db/export-notes.ts
 delete mode 100644 packages/backend/src/queue/processors/db/export-user-lists.ts
 delete mode 100644 packages/backend/src/queue/processors/db/import-blocking.ts
 delete mode 100644 packages/backend/src/queue/processors/db/import-custom-emojis.ts
 delete mode 100644 packages/backend/src/queue/processors/db/import-following.ts
 delete mode 100644 packages/backend/src/queue/processors/db/import-muting.ts
 delete mode 100644 packages/backend/src/queue/processors/db/import-posts.ts
 delete mode 100644 packages/backend/src/queue/processors/db/import-user-lists.ts
 delete mode 100644 packages/backend/src/queue/processors/db/index.ts
 delete mode 100644 packages/backend/src/queue/processors/deliver.ts
 delete mode 100644 packages/backend/src/queue/processors/ended-poll-notification.ts
 delete mode 100644 packages/backend/src/queue/processors/inbox.ts
 delete mode 100644 packages/backend/src/queue/processors/object-storage/clean-remote-files.ts
 delete mode 100644 packages/backend/src/queue/processors/object-storage/delete-file.ts
 delete mode 100644 packages/backend/src/queue/processors/object-storage/index.ts
 delete mode 100644 packages/backend/src/queue/processors/system/check-expired-mutings.ts
 delete mode 100644 packages/backend/src/queue/processors/system/clean-charts.ts
 delete mode 100644 packages/backend/src/queue/processors/system/clean.ts
 delete mode 100644 packages/backend/src/queue/processors/system/index.ts
 delete mode 100644 packages/backend/src/queue/processors/system/resync-charts.ts
 delete mode 100644 packages/backend/src/queue/processors/system/tick-charts.ts
 delete mode 100644 packages/backend/src/queue/processors/webhook-deliver.ts
 delete mode 100644 packages/backend/src/queue/queues.ts
 delete mode 100644 packages/backend/src/queue/types.ts
 delete mode 100644 packages/backend/src/remote/activitypub/ap-request.ts
 delete mode 100644 packages/backend/src/remote/activitypub/audience.ts
 delete mode 100644 packages/backend/src/remote/activitypub/check-fetch.ts
 delete mode 100644 packages/backend/src/remote/activitypub/db-resolver.ts
 delete mode 100644 packages/backend/src/remote/activitypub/deliver-manager.ts
 delete mode 100644 packages/backend/src/remote/activitypub/kernel/accept/follow.ts
 delete mode 100644 packages/backend/src/remote/activitypub/kernel/accept/index.ts
 delete mode 100644 packages/backend/src/remote/activitypub/kernel/add/index.ts
 delete mode 100644 packages/backend/src/remote/activitypub/kernel/announce/index.ts
 delete mode 100644 packages/backend/src/remote/activitypub/kernel/announce/note.ts
 delete mode 100644 packages/backend/src/remote/activitypub/kernel/block/index.ts
 delete mode 100644 packages/backend/src/remote/activitypub/kernel/create/index.ts
 delete mode 100644 packages/backend/src/remote/activitypub/kernel/create/note.ts
 delete mode 100644 packages/backend/src/remote/activitypub/kernel/delete/actor.ts
 delete mode 100644 packages/backend/src/remote/activitypub/kernel/delete/index.ts
 delete mode 100644 packages/backend/src/remote/activitypub/kernel/delete/note.ts
 delete mode 100644 packages/backend/src/remote/activitypub/kernel/flag/index.ts
 delete mode 100644 packages/backend/src/remote/activitypub/kernel/follow.ts
 delete mode 100644 packages/backend/src/remote/activitypub/kernel/index.ts
 delete mode 100644 packages/backend/src/remote/activitypub/kernel/like.ts
 delete mode 100644 packages/backend/src/remote/activitypub/kernel/move/index.ts
 delete mode 100644 packages/backend/src/remote/activitypub/kernel/read.ts
 delete mode 100644 packages/backend/src/remote/activitypub/kernel/reject/follow.ts
 delete mode 100644 packages/backend/src/remote/activitypub/kernel/reject/index.ts
 delete mode 100644 packages/backend/src/remote/activitypub/kernel/remove/index.ts
 delete mode 100644 packages/backend/src/remote/activitypub/kernel/undo/accept.ts
 delete mode 100644 packages/backend/src/remote/activitypub/kernel/undo/announce.ts
 delete mode 100644 packages/backend/src/remote/activitypub/kernel/undo/block.ts
 delete mode 100644 packages/backend/src/remote/activitypub/kernel/undo/follow.ts
 delete mode 100644 packages/backend/src/remote/activitypub/kernel/undo/index.ts
 delete mode 100644 packages/backend/src/remote/activitypub/kernel/undo/like.ts
 delete mode 100644 packages/backend/src/remote/activitypub/kernel/update/index.ts
 delete mode 100644 packages/backend/src/remote/activitypub/logger.ts
 delete mode 100644 packages/backend/src/remote/activitypub/misc/contexts.ts
 delete mode 100644 packages/backend/src/remote/activitypub/misc/get-note-html.ts
 delete mode 100644 packages/backend/src/remote/activitypub/misc/html-to-mfm.ts
 delete mode 100644 packages/backend/src/remote/activitypub/misc/ld-signature.ts
 delete mode 100644 packages/backend/src/remote/activitypub/models/icon.ts
 delete mode 100644 packages/backend/src/remote/activitypub/models/identifier.ts
 delete mode 100644 packages/backend/src/remote/activitypub/models/image.ts
 delete mode 100644 packages/backend/src/remote/activitypub/models/mention.ts
 delete mode 100644 packages/backend/src/remote/activitypub/models/note.ts
 delete mode 100644 packages/backend/src/remote/activitypub/models/person.ts
 delete mode 100644 packages/backend/src/remote/activitypub/models/question.ts
 delete mode 100644 packages/backend/src/remote/activitypub/models/tag.ts
 delete mode 100644 packages/backend/src/remote/activitypub/perform.ts
 delete mode 100644 packages/backend/src/remote/activitypub/renderer/accept.ts
 delete mode 100644 packages/backend/src/remote/activitypub/renderer/add.ts
 delete mode 100644 packages/backend/src/remote/activitypub/renderer/announce.ts
 delete mode 100644 packages/backend/src/remote/activitypub/renderer/block.ts
 delete mode 100644 packages/backend/src/remote/activitypub/renderer/create.ts
 delete mode 100644 packages/backend/src/remote/activitypub/renderer/delete.ts
 delete mode 100644 packages/backend/src/remote/activitypub/renderer/document.ts
 delete mode 100644 packages/backend/src/remote/activitypub/renderer/emoji.ts
 delete mode 100644 packages/backend/src/remote/activitypub/renderer/flag.ts
 delete mode 100644 packages/backend/src/remote/activitypub/renderer/follow-relay.ts
 delete mode 100644 packages/backend/src/remote/activitypub/renderer/follow-user.ts
 delete mode 100644 packages/backend/src/remote/activitypub/renderer/follow.ts
 delete mode 100644 packages/backend/src/remote/activitypub/renderer/hashtag.ts
 delete mode 100644 packages/backend/src/remote/activitypub/renderer/image.ts
 delete mode 100644 packages/backend/src/remote/activitypub/renderer/index.ts
 delete mode 100644 packages/backend/src/remote/activitypub/renderer/key.ts
 delete mode 100644 packages/backend/src/remote/activitypub/renderer/like.ts
 delete mode 100644 packages/backend/src/remote/activitypub/renderer/mention.ts
 delete mode 100644 packages/backend/src/remote/activitypub/renderer/note.ts
 delete mode 100644 packages/backend/src/remote/activitypub/renderer/ordered-collection-page.ts
 delete mode 100644 packages/backend/src/remote/activitypub/renderer/ordered-collection.ts
 delete mode 100644 packages/backend/src/remote/activitypub/renderer/person.ts
 delete mode 100644 packages/backend/src/remote/activitypub/renderer/question.ts
 delete mode 100644 packages/backend/src/remote/activitypub/renderer/read.ts
 delete mode 100644 packages/backend/src/remote/activitypub/renderer/reject.ts
 delete mode 100644 packages/backend/src/remote/activitypub/renderer/remove.ts
 delete mode 100644 packages/backend/src/remote/activitypub/renderer/tombstone.ts
 delete mode 100644 packages/backend/src/remote/activitypub/renderer/undo.ts
 delete mode 100644 packages/backend/src/remote/activitypub/renderer/update.ts
 delete mode 100644 packages/backend/src/remote/activitypub/renderer/vote.ts
 delete mode 100644 packages/backend/src/remote/activitypub/request.ts
 delete mode 100644 packages/backend/src/remote/activitypub/resolver.ts
 delete mode 100644 packages/backend/src/remote/activitypub/type.ts
 delete mode 100644 packages/backend/src/remote/logger.ts
 delete mode 100644 packages/backend/src/remote/resolve-user.ts
 delete mode 100644 packages/backend/src/remote/webfinger.ts
 delete mode 100644 packages/backend/src/server/activitypub.ts
 delete mode 100644 packages/backend/src/server/activitypub/featured.ts
 delete mode 100644 packages/backend/src/server/activitypub/followers.ts
 delete mode 100644 packages/backend/src/server/activitypub/following.ts
 delete mode 100644 packages/backend/src/server/activitypub/outbox.ts
 delete mode 100644 packages/backend/src/server/api/2fa.ts
 delete mode 100644 packages/backend/src/server/api/api-handler.ts
 delete mode 100644 packages/backend/src/server/api/authenticate.ts
 delete mode 100644 packages/backend/src/server/api/call.ts
 delete mode 100644 packages/backend/src/server/api/common/generate-block-query.ts
 delete mode 100644 packages/backend/src/server/api/common/generate-channel-query.ts
 delete mode 100644 packages/backend/src/server/api/common/generate-muted-note-query.ts
 delete mode 100644 packages/backend/src/server/api/common/generate-muted-note-thread-query.ts
 delete mode 100644 packages/backend/src/server/api/common/generate-muted-user-query.ts
 delete mode 100644 packages/backend/src/server/api/common/generate-native-user-token.ts
 delete mode 100644 packages/backend/src/server/api/common/generate-replies-query.ts
 delete mode 100644 packages/backend/src/server/api/common/generate-visibility-query.ts
 delete mode 100644 packages/backend/src/server/api/common/generated-muted-renote-query.ts
 delete mode 100644 packages/backend/src/server/api/common/getters.ts
 delete mode 100644 packages/backend/src/server/api/common/inject-featured.ts
 delete mode 100644 packages/backend/src/server/api/common/inject-promo.ts
 delete mode 100644 packages/backend/src/server/api/common/is-native-token.ts
 delete mode 100644 packages/backend/src/server/api/common/make-pagination-query.ts
 delete mode 100644 packages/backend/src/server/api/common/read-messaging-message.ts
 delete mode 100644 packages/backend/src/server/api/common/read-notification.ts
 delete mode 100644 packages/backend/src/server/api/common/signin.ts
 delete mode 100644 packages/backend/src/server/api/common/signup.ts
 delete mode 100644 packages/backend/src/server/api/compatibility.ts
 delete mode 100644 packages/backend/src/server/api/define.ts
 delete mode 100644 packages/backend/src/server/api/endpoints.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/abuse-user-reports.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/accounts/create.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/accounts/delete.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/accounts/hosted.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/ad/create.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/ad/delete.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/ad/list.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/ad/update.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/announcements/create.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/announcements/delete.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/announcements/list.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/announcements/update.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/delete-account.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/delete-all-files-of-a-user.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/drive-capacity-override.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/drive/clean-remote-files.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/drive/cleanup.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/drive/files.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/drive/show-file.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/emoji/add-aliases-bulk.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/emoji/add.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/emoji/copy.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/emoji/delete-bulk.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/emoji/delete.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/emoji/import-zip.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/emoji/list-remote.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/emoji/list.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/emoji/remove-aliases-bulk.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/emoji/set-aliases-bulk.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/emoji/set-category-bulk.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/emoji/set-license-bulk.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/emoji/update.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/federation/delete-all-files.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/federation/refresh-remote-instance-metadata.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/federation/remove-all-following.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/federation/update-instance.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/get-index-stats.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/get-table-stats.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/get-user-ips.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/invite.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/meta.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/moderators/add.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/moderators/remove.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/promo/create.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/queue/clear.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/queue/deliver-delayed.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/queue/inbox-delayed.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/queue/stats.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/relays/add.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/relays/list.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/relays/remove.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/reset-password.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/resolve-abuse-user-report.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/search/index-all.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/send-email.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/server-info.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/show-moderation-logs.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/show-user.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/show-users.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/silence-user.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/suspend-user.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/unsilence-user.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/unsuspend-user.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/update-meta.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/update-user-note.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/admin/vacuum.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/announcements.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/antennas/create.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/antennas/delete.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/antennas/list.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/antennas/markread.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/antennas/notes.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/antennas/show.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/antennas/update.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/ap/get.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/ap/show.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/app/create.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/app/show.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/auth/accept.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/auth/session/generate.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/auth/session/show.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/auth/session/userkey.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/blocking/create.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/blocking/delete.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/blocking/list.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/channels/create.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/channels/featured.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/channels/follow.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/channels/followed.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/channels/owned.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/channels/show.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/channels/timeline.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/channels/unfollow.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/channels/update.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/charts/active-users.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/charts/ap-request.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/charts/drive.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/charts/federation.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/charts/hashtag.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/charts/instance.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/charts/notes.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/charts/user/drive.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/charts/user/following.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/charts/user/notes.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/charts/user/reactions.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/charts/users.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/clips/add-note.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/clips/create.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/clips/delete.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/clips/list.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/clips/notes.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/clips/remove-note.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/clips/show.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/clips/update.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/compatibility/custom-emojis.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/compatibility/instance-info.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/custom-motd.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/custom-splash-icons.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/drive.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/drive/files.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/drive/files/attached-notes.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/drive/files/caption-image.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/drive/files/check-existence.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/drive/files/create.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/drive/files/delete.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/drive/files/find-by-hash.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/drive/files/find.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/drive/files/show.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/drive/files/update.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/drive/files/upload-from-url.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/drive/folders.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/drive/folders/create.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/drive/folders/delete.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/drive/folders/find.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/drive/folders/show.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/drive/folders/update.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/drive/stream.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/email-address/available.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/emoji.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/endpoint.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/endpoints.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/export-custom-emojis.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/federation/followers.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/federation/following.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/federation/instances.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/federation/show-instance.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/federation/stats.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/federation/update-remote-user.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/federation/users.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/fetch-rss.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/following/create.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/following/delete.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/following/invalidate.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/following/requests/accept.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/following/requests/cancel.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/following/requests/list.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/following/requests/reject.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/gallery/featured.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/gallery/popular.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/gallery/posts.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/gallery/posts/create.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/gallery/posts/delete.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/gallery/posts/like.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/gallery/posts/show.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/gallery/posts/unlike.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/gallery/posts/update.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/get-online-users-count.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/get-sounds.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/hashtags/list.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/hashtags/search.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/hashtags/show.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/hashtags/trend.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/hashtags/users.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/2fa/done.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/2fa/key-done.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/2fa/password-less.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/2fa/register-key.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/2fa/register.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/2fa/remove-key.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/2fa/unregister.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/apps.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/authorized-apps.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/change-password.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/delete-account.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/export-blocking.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/export-following.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/export-mute.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/export-notes.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/export-user-lists.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/favorites.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/gallery/likes.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/gallery/posts.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/get-word-muted-notes-count.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/import-blocking.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/import-following.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/import-muting.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/import-posts.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/import-user-lists.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/known-as.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/move.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/notifications.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/page-likes.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/pages.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/pin.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/read-all-messaging-messages.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/read-all-unread-notes.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/read-announcement.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/regenerate-token.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/registry/get-all.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/registry/get-detail.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/registry/get-unsecure.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/registry/get.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/registry/keys-with-type.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/registry/keys.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/registry/remove.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/registry/scopes.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/registry/set.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/revoke-token.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/signin-history.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/unpin.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/update-email.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/update.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/user-group-invites.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/webhooks/create.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/webhooks/delete.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/webhooks/list.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/webhooks/show.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/i/webhooks/update.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/latest-version.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/messaging/history.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/messaging/messages.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/messaging/messages/create.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/messaging/messages/delete.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/messaging/messages/read.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/meta.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/miauth/gen-token.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/mute/create.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/mute/delete.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/mute/list.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/my/apps.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/notes.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/notes/children.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/notes/clips.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/notes/conversation.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/notes/create.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/notes/delete.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/notes/favorites/create.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/notes/favorites/delete.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/notes/featured.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/notes/global-timeline.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/notes/local-timeline.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/notes/mentions.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/notes/polls/recommendation.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/notes/polls/vote.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/notes/reactions.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/notes/reactions/create.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/notes/reactions/delete.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/notes/recommended-timeline.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/notes/renotes.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/notes/replies.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/notes/search-by-tag.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/notes/search.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/notes/show.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/notes/state.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/notes/thread-muting/create.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/notes/thread-muting/delete.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/notes/timeline.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/notes/translate.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/notes/unrenote.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/notes/watching/create.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/notes/watching/delete.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/notifications/create.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/notifications/mark-all-as-read.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/notifications/read.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/page-push.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/pages/create.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/pages/delete.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/pages/featured.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/pages/like.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/pages/show.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/pages/unlike.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/pages/update.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/patrons.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/ping.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/pinned-users.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/promo/read.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/recommended-instances.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/release.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/renote-mute/create.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/renote-mute/delete.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/renote-mute/list.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/request-reset-password.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/reset-db.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/reset-password.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/server-info.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/stats.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/sw/register.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/sw/show-registration.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/sw/unregister.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/sw/update-registration.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/test.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/username/available.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/users.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/users/clips.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/users/followers.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/users/following.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/users/gallery/posts.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/users/get-frequently-replied-users.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/users/groups/create.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/users/groups/delete.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/users/groups/invitations/accept.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/users/groups/invitations/reject.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/users/groups/invite.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/users/groups/joined.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/users/groups/leave.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/users/groups/owned.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/users/groups/pull.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/users/groups/show.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/users/groups/transfer.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/users/groups/update.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/users/lists/create.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/users/lists/delete-all.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/users/lists/delete.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/users/lists/list.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/users/lists/pull.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/users/lists/push.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/users/lists/show.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/users/lists/update.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/users/notes.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/users/pages.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/users/reactions.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/users/recommendation.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/users/relation.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/users/report-abuse.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/users/search.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/users/show.ts
 delete mode 100644 packages/backend/src/server/api/endpoints/users/stats.ts
 delete mode 100644 packages/backend/src/server/api/error.ts
 delete mode 100644 packages/backend/src/server/api/index.ts
 delete mode 100644 packages/backend/src/server/api/limiter.ts
 delete mode 100644 packages/backend/src/server/api/logger.ts
 delete mode 100644 packages/backend/src/server/api/mastodon/ApiMastodonCompatibleService.ts
 delete mode 100644 packages/backend/src/server/api/mastodon/endpoints/account.ts
 delete mode 100644 packages/backend/src/server/api/mastodon/endpoints/auth.ts
 delete mode 100644 packages/backend/src/server/api/mastodon/endpoints/filter.ts
 delete mode 100644 packages/backend/src/server/api/mastodon/endpoints/meta.ts
 delete mode 100644 packages/backend/src/server/api/mastodon/endpoints/notifications.ts
 delete mode 100644 packages/backend/src/server/api/mastodon/endpoints/search.ts
 delete mode 100644 packages/backend/src/server/api/mastodon/endpoints/status.ts
 delete mode 100644 packages/backend/src/server/api/mastodon/endpoints/timeline.ts
 delete mode 100644 packages/backend/src/server/api/openapi/errors.ts
 delete mode 100644 packages/backend/src/server/api/openapi/gen-spec.ts
 delete mode 100644 packages/backend/src/server/api/openapi/schemas.ts
 delete mode 100644 packages/backend/src/server/api/private/signin.ts
 delete mode 100644 packages/backend/src/server/api/private/signup-pending.ts
 delete mode 100644 packages/backend/src/server/api/private/signup.ts
 delete mode 100644 packages/backend/src/server/api/service/discord.ts
 delete mode 100644 packages/backend/src/server/api/service/github.ts
 delete mode 100644 packages/backend/src/server/api/service/twitter.ts
 delete mode 100644 packages/backend/src/server/api/stream/channel.ts
 delete mode 100644 packages/backend/src/server/api/stream/channels/admin.ts
 delete mode 100644 packages/backend/src/server/api/stream/channels/antenna.ts
 delete mode 100644 packages/backend/src/server/api/stream/channels/channel.ts
 delete mode 100644 packages/backend/src/server/api/stream/channels/drive.ts
 delete mode 100644 packages/backend/src/server/api/stream/channels/global-timeline.ts
 delete mode 100644 packages/backend/src/server/api/stream/channels/hashtag.ts
 delete mode 100644 packages/backend/src/server/api/stream/channels/home-timeline.ts
 delete mode 100644 packages/backend/src/server/api/stream/channels/hybrid-timeline.ts
 delete mode 100644 packages/backend/src/server/api/stream/channels/index.ts
 delete mode 100644 packages/backend/src/server/api/stream/channels/local-timeline.ts
 delete mode 100644 packages/backend/src/server/api/stream/channels/main.ts
 delete mode 100644 packages/backend/src/server/api/stream/channels/messaging-index.ts
 delete mode 100644 packages/backend/src/server/api/stream/channels/messaging.ts
 delete mode 100644 packages/backend/src/server/api/stream/channels/queue-stats.ts
 delete mode 100644 packages/backend/src/server/api/stream/channels/recommended-timeline.ts
 delete mode 100644 packages/backend/src/server/api/stream/channels/server-stats.ts
 delete mode 100644 packages/backend/src/server/api/stream/channels/user-list.ts
 delete mode 100644 packages/backend/src/server/api/stream/index.ts
 delete mode 100644 packages/backend/src/server/api/stream/types.ts
 delete mode 100644 packages/backend/src/server/api/streaming.ts
 delete mode 100644 packages/backend/src/server/file/assets/bad-egg.png
 delete mode 100644 packages/backend/src/server/file/assets/cache-expired.png
 delete mode 100644 packages/backend/src/server/file/assets/dummy.png
 delete mode 100644 packages/backend/src/server/file/assets/not-an-image.png
 delete mode 100644 packages/backend/src/server/file/assets/thumbnail-not-available.png
 delete mode 100644 packages/backend/src/server/file/assets/tombstone.png
 delete mode 100644 packages/backend/src/server/file/index.ts
 delete mode 100644 packages/backend/src/server/file/send-drive-file.ts
 delete mode 100644 packages/backend/src/server/index.ts
 delete mode 100644 packages/backend/src/server/nodeinfo.ts
 delete mode 100644 packages/backend/src/server/proxy/index.ts
 delete mode 100644 packages/backend/src/server/proxy/proxy-media.ts
 delete mode 100644 packages/backend/src/server/web/bios.css
 delete mode 100644 packages/backend/src/server/web/bios.js
 delete mode 100644 packages/backend/src/server/web/boot.js
 delete mode 100644 packages/backend/src/server/web/cli.css
 delete mode 100644 packages/backend/src/server/web/cli.js
 delete mode 100644 packages/backend/src/server/web/feed.ts
 delete mode 100644 packages/backend/src/server/web/index.ts
 delete mode 100644 packages/backend/src/server/web/manifest.json
 delete mode 100644 packages/backend/src/server/web/manifest.ts
 delete mode 100644 packages/backend/src/server/web/style.css
 delete mode 100644 packages/backend/src/server/web/url-preview.ts
 delete mode 100644 packages/backend/src/server/web/views/base.pug
 delete mode 100644 packages/backend/src/server/web/views/bios.pug
 delete mode 100644 packages/backend/src/server/web/views/channel.pug
 delete mode 100644 packages/backend/src/server/web/views/cli.pug
 delete mode 100644 packages/backend/src/server/web/views/clip.pug
 delete mode 100644 packages/backend/src/server/web/views/flush.pug
 delete mode 100644 packages/backend/src/server/web/views/gallery-post.pug
 delete mode 100644 packages/backend/src/server/web/views/info-card.pug
 delete mode 100644 packages/backend/src/server/web/views/note.pug
 delete mode 100644 packages/backend/src/server/web/views/page.pug
 delete mode 100644 packages/backend/src/server/web/views/user.pug
 delete mode 100644 packages/backend/src/server/well-known.ts
 delete mode 100644 packages/backend/src/services/add-note-to-antenna.ts
 delete mode 100644 packages/backend/src/services/blocking/create.ts
 delete mode 100644 packages/backend/src/services/blocking/delete.ts
 delete mode 100644 packages/backend/src/services/chart/charts/active-users.ts
 delete mode 100644 packages/backend/src/services/chart/charts/ap-request.ts
 delete mode 100644 packages/backend/src/services/chart/charts/drive.ts
 delete mode 100644 packages/backend/src/services/chart/charts/entities/active-users.ts
 delete mode 100644 packages/backend/src/services/chart/charts/entities/ap-request.ts
 delete mode 100644 packages/backend/src/services/chart/charts/entities/drive.ts
 delete mode 100644 packages/backend/src/services/chart/charts/entities/federation.ts
 delete mode 100644 packages/backend/src/services/chart/charts/entities/hashtag.ts
 delete mode 100644 packages/backend/src/services/chart/charts/entities/instance.ts
 delete mode 100644 packages/backend/src/services/chart/charts/entities/notes.ts
 delete mode 100644 packages/backend/src/services/chart/charts/entities/per-user-drive.ts
 delete mode 100644 packages/backend/src/services/chart/charts/entities/per-user-following.ts
 delete mode 100644 packages/backend/src/services/chart/charts/entities/per-user-notes.ts
 delete mode 100644 packages/backend/src/services/chart/charts/entities/per-user-reactions.ts
 delete mode 100644 packages/backend/src/services/chart/charts/entities/test-grouped.ts
 delete mode 100644 packages/backend/src/services/chart/charts/entities/test-intersection.ts
 delete mode 100644 packages/backend/src/services/chart/charts/entities/test-unique.ts
 delete mode 100644 packages/backend/src/services/chart/charts/entities/test.ts
 delete mode 100644 packages/backend/src/services/chart/charts/entities/users.ts
 delete mode 100644 packages/backend/src/services/chart/charts/federation.ts
 delete mode 100644 packages/backend/src/services/chart/charts/hashtag.ts
 delete mode 100644 packages/backend/src/services/chart/charts/instance.ts
 delete mode 100644 packages/backend/src/services/chart/charts/notes.ts
 delete mode 100644 packages/backend/src/services/chart/charts/per-user-drive.ts
 delete mode 100644 packages/backend/src/services/chart/charts/per-user-following.ts
 delete mode 100644 packages/backend/src/services/chart/charts/per-user-notes.ts
 delete mode 100644 packages/backend/src/services/chart/charts/per-user-reactions.ts
 delete mode 100644 packages/backend/src/services/chart/charts/test-grouped.ts
 delete mode 100644 packages/backend/src/services/chart/charts/test-intersection.ts
 delete mode 100644 packages/backend/src/services/chart/charts/test-unique.ts
 delete mode 100644 packages/backend/src/services/chart/charts/test.ts
 delete mode 100644 packages/backend/src/services/chart/charts/users.ts
 delete mode 100644 packages/backend/src/services/chart/core.ts
 delete mode 100644 packages/backend/src/services/chart/entities.ts
 delete mode 100644 packages/backend/src/services/chart/index.ts
 delete mode 100644 packages/backend/src/services/create-notification.ts
 delete mode 100644 packages/backend/src/services/create-system-user.ts
 delete mode 100644 packages/backend/src/services/delete-account.ts
 delete mode 100644 packages/backend/src/services/detect-sensitive.ts
 delete mode 100644 packages/backend/src/services/drive/add-file.ts
 delete mode 100644 packages/backend/src/services/drive/delete-file.ts
 delete mode 100644 packages/backend/src/services/drive/generate-video-thumbnail.ts
 delete mode 100644 packages/backend/src/services/drive/image-processor.ts
 delete mode 100644 packages/backend/src/services/drive/internal-storage.ts
 delete mode 100644 packages/backend/src/services/drive/logger.ts
 delete mode 100644 packages/backend/src/services/drive/s3.ts
 delete mode 100644 packages/backend/src/services/drive/upload-from-url.ts
 delete mode 100644 packages/backend/src/services/fetch-instance-metadata.ts
 delete mode 100644 packages/backend/src/services/following/create.ts
 delete mode 100644 packages/backend/src/services/following/delete.ts
 delete mode 100644 packages/backend/src/services/following/reject.ts
 delete mode 100644 packages/backend/src/services/following/requests/accept-all.ts
 delete mode 100644 packages/backend/src/services/following/requests/accept.ts
 delete mode 100644 packages/backend/src/services/following/requests/cancel.ts
 delete mode 100644 packages/backend/src/services/following/requests/create.ts
 delete mode 100644 packages/backend/src/services/i/pin.ts
 delete mode 100644 packages/backend/src/services/i/update.ts
 delete mode 100644 packages/backend/src/services/insert-moderation-log.ts
 delete mode 100644 packages/backend/src/services/instance-actor.ts
 delete mode 100644 packages/backend/src/services/logger.ts
 delete mode 100644 packages/backend/src/services/messages/create.ts
 delete mode 100644 packages/backend/src/services/messages/delete.ts
 delete mode 100644 packages/backend/src/services/note/create.ts
 delete mode 100644 packages/backend/src/services/note/delete.ts
 delete mode 100644 packages/backend/src/services/note/polls/update.ts
 delete mode 100644 packages/backend/src/services/note/polls/vote.ts
 delete mode 100644 packages/backend/src/services/note/reaction/create.ts
 delete mode 100644 packages/backend/src/services/note/reaction/delete.ts
 delete mode 100644 packages/backend/src/services/note/read.ts
 delete mode 100644 packages/backend/src/services/note/unread.ts
 delete mode 100644 packages/backend/src/services/note/unwatch.ts
 delete mode 100644 packages/backend/src/services/note/watch.ts
 delete mode 100644 packages/backend/src/services/push-notification.ts
 delete mode 100644 packages/backend/src/services/register-or-fetch-instance-doc.ts
 delete mode 100644 packages/backend/src/services/relay.ts
 delete mode 100644 packages/backend/src/services/send-email-notification.ts
 delete mode 100644 packages/backend/src/services/send-email.ts
 delete mode 100644 packages/backend/src/services/stream.ts
 delete mode 100644 packages/backend/src/services/suspend-user.ts
 delete mode 100644 packages/backend/src/services/unsuspend-user.ts
 delete mode 100644 packages/backend/src/services/update-hashtag.ts
 delete mode 100644 packages/backend/src/services/user-cache.ts
 delete mode 100644 packages/backend/src/services/user-list/push.ts
 delete mode 100644 packages/backend/src/services/validate-email-for-account.ts
 delete mode 100644 packages/backend/src/types.ts
 delete mode 100644 packages/backend/test/activitypub.ts
 delete mode 100644 packages/backend/test/ap-request.ts
 delete mode 100644 packages/backend/test/api-visibility.ts
 delete mode 100644 packages/backend/test/api.ts
 delete mode 100644 packages/backend/test/block.ts
 delete mode 100644 packages/backend/test/chart.ts
 delete mode 100644 packages/backend/test/docker-compose.yml
 delete mode 100644 packages/backend/test/endpoints.ts
 delete mode 100644 packages/backend/test/extract-mentions.ts
 delete mode 100644 packages/backend/test/fetch-resource.ts
 delete mode 100644 packages/backend/test/ff-visibility.ts
 delete mode 100644 packages/backend/test/get-file-info.ts
 delete mode 100644 packages/backend/test/loader.js
 delete mode 100644 packages/backend/test/mfm.ts
 delete mode 100644 packages/backend/test/misc/mock-resolver.ts
 delete mode 100644 packages/backend/test/mute.ts
 delete mode 100644 packages/backend/test/note.ts
 delete mode 100644 packages/backend/test/prelude/maybe.ts
 delete mode 100644 packages/backend/test/prelude/url.ts
 delete mode 100644 packages/backend/test/reaction-lib.ts
 delete mode 100644 packages/backend/test/resources/25000x25000.png
 delete mode 100644 packages/backend/test/resources/Lenna.jpg
 delete mode 100644 packages/backend/test/resources/Lenna.png
 delete mode 100644 packages/backend/test/resources/anime.gif
 delete mode 100644 packages/backend/test/resources/anime.png
 delete mode 100644 packages/backend/test/resources/emptyfile
 delete mode 100644 packages/backend/test/resources/image.svg
 delete mode 100644 packages/backend/test/resources/rotate.jpg
 delete mode 100644 packages/backend/test/resources/with-alpha.png
 delete mode 100644 packages/backend/test/resources/with-xml-def.svg
 delete mode 100644 packages/backend/test/streaming.ts
 delete mode 100644 packages/backend/test/thread-mute.ts
 delete mode 100644 packages/backend/test/tsconfig.json
 delete mode 100644 packages/backend/test/user-notes.ts
 delete mode 100644 packages/backend/test/utils.ts
 delete mode 100644 packages/backend/tsconfig.json

diff --git a/packages/backend/.gitignore b/packages/backend/.gitignore
new file mode 100644
index 0000000000..c4653682cf
--- /dev/null
+++ b/packages/backend/.gitignore
@@ -0,0 +1,7 @@
+# 
+*.profraw
+*.profdata
+
+# rust build dir
+target/
+
diff --git a/packages/backend/.mocharc.json b/packages/backend/.mocharc.json
deleted file mode 100644
index f836f9e900..0000000000
--- a/packages/backend/.mocharc.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-	"extension": ["ts","js","cjs","mjs"],
-	"node-option": [
-		"experimental-specifier-resolution=node",
-		"loader=./test/loader.js"
-	],
-	"slow": 1000,
-	"timeout": 30000,
-	"exit": true
-}
diff --git a/packages/backend/.swcrc b/packages/backend/.swcrc
deleted file mode 100644
index 39e112ff7c..0000000000
--- a/packages/backend/.swcrc
+++ /dev/null
@@ -1,25 +0,0 @@
-{
-  "$schema": "https://json.schemastore.org/swcrc",
-  "jsc": {
-    "parser": {
-      "syntax": "typescript",
-      "dynamicImport": true,
-      "decorators": true
-    },
-    "transform": {
-      "legacyDecorator": true,
-      "decoratorMetadata": true
-    },
-		"experimental": {
-			"keepImportAssertions": true
-		},
-		"baseUrl": ".",
-		"paths": {
-			"@/*": [
-				"./src/*"
-			]
-		},
-		"target": "es2022"
-  },
-  "minify": false
-}
diff --git a/packages/backend/.vim/coc-settings.json b/packages/backend/.vim/coc-settings.json
new file mode 100644
index 0000000000..b5c02503fb
--- /dev/null
+++ b/packages/backend/.vim/coc-settings.json
@@ -0,0 +1,5 @@
+{
+  "workspace.workspaceFolderCheckCwd": false,
+	"rust-analyzer.check.command": "clippy",
+	"rust-analyzer.check.extraArgs": "--profile test"
+}
diff --git a/packages/backend/Cargo.lock b/packages/backend/Cargo.lock
new file mode 100644
index 0000000000..76277eac5c
--- /dev/null
+++ b/packages/backend/Cargo.lock
@@ -0,0 +1,14 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "backend"
+version = "0.0.0"
+dependencies = [
+ "server",
+]
+
+[[package]]
+name = "server"
+version = "0.1.0"
diff --git a/packages/backend/Cargo.toml b/packages/backend/Cargo.toml
new file mode 100644
index 0000000000..893418cbcd
--- /dev/null
+++ b/packages/backend/Cargo.toml
@@ -0,0 +1,16 @@
+[package]
+name = "backend"
+version = "0.0.0"
+edition = "2021"
+default-run = "backend"
+
+[workspace]
+
+members = ["crates/*"]
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+server = { path = "crates/server" }
+
+[dev-dependencies]
diff --git a/packages/backend/crates/server/Cargo.toml b/packages/backend/crates/server/Cargo.toml
new file mode 100644
index 0000000000..dd022ab514
--- /dev/null
+++ b/packages/backend/crates/server/Cargo.toml
@@ -0,0 +1,8 @@
+[package]
+name = "server"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
diff --git a/packages/backend/crates/server/src/lib.rs b/packages/backend/crates/server/src/lib.rs
new file mode 100644
index 0000000000..9771df5f2e
--- /dev/null
+++ b/packages/backend/crates/server/src/lib.rs
@@ -0,0 +1,15 @@
+pub fn add(left: usize, right: usize) -> usize {
+  todo!();
+  left + right
+}
+
+#[cfg(test)]
+mod tests {
+  use super::*;
+
+  #[test]
+  fn it_works() {
+    let result = add(2, 2);
+    assert_eq!(result, 4);
+  }
+}
diff --git a/packages/backend/jsconfig.json b/packages/backend/jsconfig.json
deleted file mode 100644
index 1230aadd12..0000000000
--- a/packages/backend/jsconfig.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
-	"compilerOptions": {
-		"target": "es6",
-		"module": "commonjs",
-		"allowSyntheticDefaultImports": true
-	},
-	"exclude": [
-		"node_modules",
-		"jspm_packages",
-		"tmp",
-		"temp"
-	]
-}
diff --git a/packages/backend/native-utils/.cargo/config.toml b/packages/backend/native-utils/.cargo/config.toml
deleted file mode 100644
index 7ede30ee04..0000000000
--- a/packages/backend/native-utils/.cargo/config.toml
+++ /dev/null
@@ -1,3 +0,0 @@
-[target.aarch64-unknown-linux-musl]
-linker = "aarch64-linux-musl-gcc"
-rustflags = ["-C", "target-feature=-crt-static"]
\ No newline at end of file
diff --git a/packages/backend/native-utils/.gitignore b/packages/backend/native-utils/.gitignore
deleted file mode 100644
index 78b75d55ad..0000000000
--- a/packages/backend/native-utils/.gitignore
+++ /dev/null
@@ -1,200 +0,0 @@
-# Created by https://www.toptal.com/developers/gitignore/api/node
-# Edit at https://www.toptal.com/developers/gitignore?templates=node
-
-### Node ###
-# Logs
-logs
-*.log
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-lerna-debug.log*
-
-# Diagnostic reports (https://nodejs.org/api/report.html)
-report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
-
-# Runtime data
-pids
-*.pid
-*.seed
-*.pid.lock
-
-# Directory for instrumented libs generated by jscoverage/JSCover
-lib-cov
-
-# Coverage directory used by tools like istanbul
-coverage
-*.lcov
-
-# nyc test coverage
-.nyc_output
-
-# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
-.grunt
-
-# Bower dependency directory (https://bower.io/)
-bower_components
-
-# node-waf configuration
-.lock-wscript
-
-# Compiled binary addons (https://nodejs.org/api/addons.html)
-build/Release
-
-# Dependency directories
-node_modules/
-jspm_packages/
-
-# TypeScript v1 declaration files
-typings/
-
-# TypeScript cache
-*.tsbuildinfo
-
-# Optional npm cache directory
-.npm
-
-# Optional eslint cache
-.eslintcache
-
-# Microbundle cache
-.rpt2_cache/
-.rts2_cache_cjs/
-.rts2_cache_es/
-.rts2_cache_umd/
-
-# Optional REPL history
-.node_repl_history
-
-# Output of 'npm pack'
-*.tgz
-
-# Yarn Integrity file
-.yarn-integrity
-
-# dotenv environment variables file
-.env
-.env.test
-
-# parcel-bundler cache (https://parceljs.org/)
-.cache
-
-# Next.js build output
-.next
-
-# Nuxt.js build / generate output
-.nuxt
-dist
-
-# Gatsby files
-.cache/
-# Comment in the public line in if your project uses Gatsby and not Next.js
-# https://nextjs.org/blog/next-9-1#public-directory-support
-# public
-
-# vuepress build output
-.vuepress/dist
-
-# Serverless directories
-.serverless/
-
-# FuseBox cache
-.fusebox/
-
-# DynamoDB Local files
-.dynamodb/
-
-# TernJS port file
-.tern-port
-
-# Stores VSCode versions used for testing VSCode extensions
-.vscode-test
-
-# End of https://www.toptal.com/developers/gitignore/api/node
-
-# Created by https://www.toptal.com/developers/gitignore/api/macos
-# Edit at https://www.toptal.com/developers/gitignore?templates=macos
-
-### macOS ###
-# General
-.DS_Store
-.AppleDouble
-.LSOverride
-
-# Icon must end with two 
-Icon
-
-
-# Thumbnails
-._*
-
-# Files that might appear in the root of a volume
-.DocumentRevisions-V100
-.fseventsd
-.Spotlight-V100
-.TemporaryItems
-.Trashes
-.VolumeIcon.icns
-.com.apple.timemachine.donotpresent
-
-# Directories potentially created on remote AFP share
-.AppleDB
-.AppleDesktop
-Network Trash Folder
-Temporary Items
-.apdisk
-
-### macOS Patch ###
-# iCloud generated files
-*.icloud
-
-# End of https://www.toptal.com/developers/gitignore/api/macos
-
-# Created by https://www.toptal.com/developers/gitignore/api/windows
-# Edit at https://www.toptal.com/developers/gitignore?templates=windows
-
-### Windows ###
-# Windows thumbnail cache files
-Thumbs.db
-Thumbs.db:encryptable
-ehthumbs.db
-ehthumbs_vista.db
-
-# Dump file
-*.stackdump
-
-# Folder config file
-[Dd]esktop.ini
-
-# Recycle Bin used on file shares
-$RECYCLE.BIN/
-
-# Windows Installer files
-*.cab
-*.msi
-*.msix
-*.msm
-*.msp
-
-# Windows shortcuts
-*.lnk
-
-# End of https://www.toptal.com/developers/gitignore/api/windows
-
-# napi-rs generated files
-built/
-
-#Added by cargo
-
-/target
-Cargo.lock
-
-.pnp.*
-.yarn/*
-!.yarn/patches
-!.yarn/plugins
-!.yarn/releases
-!.yarn/sdks
-!.yarn/versions
-
-*.node
diff --git a/packages/backend/native-utils/.npmignore b/packages/backend/native-utils/.npmignore
deleted file mode 100644
index ec144db2a7..0000000000
--- a/packages/backend/native-utils/.npmignore
+++ /dev/null
@@ -1,13 +0,0 @@
-target
-Cargo.lock
-.cargo
-.github
-npm
-.eslintrc
-.prettierignore
-rustfmt.toml
-yarn.lock
-*.node
-.yarn
-__test__
-renovate.json
diff --git a/packages/backend/native-utils/Cargo.toml b/packages/backend/native-utils/Cargo.toml
deleted file mode 100644
index 4f7fb4c39a..0000000000
--- a/packages/backend/native-utils/Cargo.toml
+++ /dev/null
@@ -1,18 +0,0 @@
-[package]
-edition = "2021"
-name = "native-utils"
-version = "0.0.0"
-
-[lib]
-crate-type = ["cdylib"]
-
-[dependencies]
-# Default enable napi4 feature, see https://nodejs.org/api/n-api.html#node-api-version-matrix
-napi = { version = "2.12.0", default-features = false, features = ["napi4"] }
-napi-derive = "2.12.0"
-
-[build-dependencies]
-napi-build = "2.0.1"
-
-[profile.release]
-lto = true
diff --git a/packages/backend/native-utils/__test__/index.spec.mjs b/packages/backend/native-utils/__test__/index.spec.mjs
deleted file mode 100644
index 0d41e012dd..0000000000
--- a/packages/backend/native-utils/__test__/index.spec.mjs
+++ /dev/null
@@ -1,7 +0,0 @@
-import test from "ava";
-
-import { sum } from "../index.js";
-
-test("sum from native", (t) => {
-	t.is(sum(1, 2), 3);
-});
diff --git a/packages/backend/native-utils/build.rs b/packages/backend/native-utils/build.rs
deleted file mode 100644
index 1f866b6a3c..0000000000
--- a/packages/backend/native-utils/build.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-extern crate napi_build;
-
-fn main() {
-  napi_build::setup();
-}
diff --git a/packages/backend/native-utils/npm/android-arm-eabi/README.md b/packages/backend/native-utils/npm/android-arm-eabi/README.md
deleted file mode 100644
index 10199cb8ec..0000000000
--- a/packages/backend/native-utils/npm/android-arm-eabi/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# `native-utils-android-arm-eabi`
-
-This is the **armv7-linux-androideabi** binary for `native-utils`
diff --git a/packages/backend/native-utils/npm/android-arm-eabi/package.json b/packages/backend/native-utils/npm/android-arm-eabi/package.json
deleted file mode 100644
index b4404c410a..0000000000
--- a/packages/backend/native-utils/npm/android-arm-eabi/package.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-  "name": "native-utils-android-arm-eabi",
-  "version": "0.0.0",
-  "os": [
-    "android"
-  ],
-  "cpu": [
-    "arm"
-  ],
-  "main": "native-utils.android-arm-eabi.node",
-  "files": [
-    "native-utils.android-arm-eabi.node"
-  ],
-  "license": "MIT",
-  "engines": {
-    "node": ">= 10"
-  }
-}
\ No newline at end of file
diff --git a/packages/backend/native-utils/npm/android-arm64/README.md b/packages/backend/native-utils/npm/android-arm64/README.md
deleted file mode 100644
index c32c2fe710..0000000000
--- a/packages/backend/native-utils/npm/android-arm64/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# `native-utils-android-arm64`
-
-This is the **aarch64-linux-android** binary for `native-utils`
diff --git a/packages/backend/native-utils/npm/android-arm64/package.json b/packages/backend/native-utils/npm/android-arm64/package.json
deleted file mode 100644
index 9050ef37bd..0000000000
--- a/packages/backend/native-utils/npm/android-arm64/package.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-  "name": "native-utils-android-arm64",
-  "version": "0.0.0",
-  "os": [
-    "android"
-  ],
-  "cpu": [
-    "arm64"
-  ],
-  "main": "native-utils.android-arm64.node",
-  "files": [
-    "native-utils.android-arm64.node"
-  ],
-  "license": "MIT",
-  "engines": {
-    "node": ">= 10"
-  }
-}
\ No newline at end of file
diff --git a/packages/backend/native-utils/npm/darwin-arm64/README.md b/packages/backend/native-utils/npm/darwin-arm64/README.md
deleted file mode 100644
index 8703902223..0000000000
--- a/packages/backend/native-utils/npm/darwin-arm64/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# `native-utils-darwin-arm64`
-
-This is the **aarch64-apple-darwin** binary for `native-utils`
diff --git a/packages/backend/native-utils/npm/darwin-arm64/package.json b/packages/backend/native-utils/npm/darwin-arm64/package.json
deleted file mode 100644
index a7fcef289f..0000000000
--- a/packages/backend/native-utils/npm/darwin-arm64/package.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-  "name": "native-utils-darwin-arm64",
-  "version": "0.0.0",
-  "os": [
-    "darwin"
-  ],
-  "cpu": [
-    "arm64"
-  ],
-  "main": "native-utils.darwin-arm64.node",
-  "files": [
-    "native-utils.darwin-arm64.node"
-  ],
-  "license": "MIT",
-  "engines": {
-    "node": ">= 10"
-  }
-}
\ No newline at end of file
diff --git a/packages/backend/native-utils/npm/darwin-universal/README.md b/packages/backend/native-utils/npm/darwin-universal/README.md
deleted file mode 100644
index 098bb35906..0000000000
--- a/packages/backend/native-utils/npm/darwin-universal/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# `native-utils-darwin-universal`
-
-This is the **universal-apple-darwin** binary for `native-utils`
diff --git a/packages/backend/native-utils/npm/darwin-universal/package.json b/packages/backend/native-utils/npm/darwin-universal/package.json
deleted file mode 100644
index a46061d421..0000000000
--- a/packages/backend/native-utils/npm/darwin-universal/package.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "name": "native-utils-darwin-universal",
-  "version": "0.0.0",
-  "os": [
-    "darwin"
-  ],
-  "main": "native-utils.darwin-universal.node",
-  "files": [
-    "native-utils.darwin-universal.node"
-  ],
-  "license": "MIT",
-  "engines": {
-    "node": ">= 10"
-  }
-}
\ No newline at end of file
diff --git a/packages/backend/native-utils/npm/darwin-x64/README.md b/packages/backend/native-utils/npm/darwin-x64/README.md
deleted file mode 100644
index 0acf363352..0000000000
--- a/packages/backend/native-utils/npm/darwin-x64/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# `native-utils-darwin-x64`
-
-This is the **x86_64-apple-darwin** binary for `native-utils`
diff --git a/packages/backend/native-utils/npm/darwin-x64/package.json b/packages/backend/native-utils/npm/darwin-x64/package.json
deleted file mode 100644
index 6bbcf1d232..0000000000
--- a/packages/backend/native-utils/npm/darwin-x64/package.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-  "name": "native-utils-darwin-x64",
-  "version": "0.0.0",
-  "os": [
-    "darwin"
-  ],
-  "cpu": [
-    "x64"
-  ],
-  "main": "native-utils.darwin-x64.node",
-  "files": [
-    "native-utils.darwin-x64.node"
-  ],
-  "license": "MIT",
-  "engines": {
-    "node": ">= 10"
-  }
-}
\ No newline at end of file
diff --git a/packages/backend/native-utils/npm/freebsd-x64/README.md b/packages/backend/native-utils/npm/freebsd-x64/README.md
deleted file mode 100644
index 2b74996de7..0000000000
--- a/packages/backend/native-utils/npm/freebsd-x64/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# `native-utils-freebsd-x64`
-
-This is the **x86_64-unknown-freebsd** binary for `native-utils`
diff --git a/packages/backend/native-utils/npm/freebsd-x64/package.json b/packages/backend/native-utils/npm/freebsd-x64/package.json
deleted file mode 100644
index 654b8abf38..0000000000
--- a/packages/backend/native-utils/npm/freebsd-x64/package.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-  "name": "native-utils-freebsd-x64",
-  "version": "0.0.0",
-  "os": [
-    "freebsd"
-  ],
-  "cpu": [
-    "x64"
-  ],
-  "main": "native-utils.freebsd-x64.node",
-  "files": [
-    "native-utils.freebsd-x64.node"
-  ],
-  "license": "MIT",
-  "engines": {
-    "node": ">= 10"
-  }
-}
\ No newline at end of file
diff --git a/packages/backend/native-utils/npm/linux-arm-gnueabihf/README.md b/packages/backend/native-utils/npm/linux-arm-gnueabihf/README.md
deleted file mode 100644
index 2203036de0..0000000000
--- a/packages/backend/native-utils/npm/linux-arm-gnueabihf/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# `native-utils-linux-arm-gnueabihf`
-
-This is the **armv7-unknown-linux-gnueabihf** binary for `native-utils`
diff --git a/packages/backend/native-utils/npm/linux-arm-gnueabihf/package.json b/packages/backend/native-utils/npm/linux-arm-gnueabihf/package.json
deleted file mode 100644
index 1e206c078d..0000000000
--- a/packages/backend/native-utils/npm/linux-arm-gnueabihf/package.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-  "name": "native-utils-linux-arm-gnueabihf",
-  "version": "0.0.0",
-  "os": [
-    "linux"
-  ],
-  "cpu": [
-    "arm"
-  ],
-  "main": "native-utils.linux-arm-gnueabihf.node",
-  "files": [
-    "native-utils.linux-arm-gnueabihf.node"
-  ],
-  "license": "MIT",
-  "engines": {
-    "node": ">= 10"
-  }
-}
\ No newline at end of file
diff --git a/packages/backend/native-utils/npm/linux-arm64-gnu/README.md b/packages/backend/native-utils/npm/linux-arm64-gnu/README.md
deleted file mode 100644
index ad3a9333f5..0000000000
--- a/packages/backend/native-utils/npm/linux-arm64-gnu/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# `native-utils-linux-arm64-gnu`
-
-This is the **aarch64-unknown-linux-gnu** binary for `native-utils`
diff --git a/packages/backend/native-utils/npm/linux-arm64-gnu/package.json b/packages/backend/native-utils/npm/linux-arm64-gnu/package.json
deleted file mode 100644
index aa0b2a805f..0000000000
--- a/packages/backend/native-utils/npm/linux-arm64-gnu/package.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-  "name": "native-utils-linux-arm64-gnu",
-  "version": "0.0.0",
-  "os": [
-    "linux"
-  ],
-  "cpu": [
-    "arm64"
-  ],
-  "main": "native-utils.linux-arm64-gnu.node",
-  "files": [
-    "native-utils.linux-arm64-gnu.node"
-  ],
-  "license": "MIT",
-  "engines": {
-    "node": ">= 10"
-  },
-  "libc": [
-    "glibc"
-  ]
-}
\ No newline at end of file
diff --git a/packages/backend/native-utils/npm/linux-arm64-musl/README.md b/packages/backend/native-utils/npm/linux-arm64-musl/README.md
deleted file mode 100644
index df282532ff..0000000000
--- a/packages/backend/native-utils/npm/linux-arm64-musl/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# `native-utils-linux-arm64-musl`
-
-This is the **aarch64-unknown-linux-musl** binary for `native-utils`
diff --git a/packages/backend/native-utils/npm/linux-arm64-musl/package.json b/packages/backend/native-utils/npm/linux-arm64-musl/package.json
deleted file mode 100644
index 99e9387ee6..0000000000
--- a/packages/backend/native-utils/npm/linux-arm64-musl/package.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-  "name": "native-utils-linux-arm64-musl",
-  "version": "0.0.0",
-  "os": [
-    "linux"
-  ],
-  "cpu": [
-    "arm64"
-  ],
-  "main": "native-utils.linux-arm64-musl.node",
-  "files": [
-    "native-utils.linux-arm64-musl.node"
-  ],
-  "license": "MIT",
-  "engines": {
-    "node": ">= 10"
-  },
-  "libc": [
-    "musl"
-  ]
-}
\ No newline at end of file
diff --git a/packages/backend/native-utils/npm/linux-x64-gnu/README.md b/packages/backend/native-utils/npm/linux-x64-gnu/README.md
deleted file mode 100644
index 52eea85aab..0000000000
--- a/packages/backend/native-utils/npm/linux-x64-gnu/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# `native-utils-linux-x64-gnu`
-
-This is the **x86_64-unknown-linux-gnu** binary for `native-utils`
diff --git a/packages/backend/native-utils/npm/linux-x64-gnu/package.json b/packages/backend/native-utils/npm/linux-x64-gnu/package.json
deleted file mode 100644
index f99a5f664e..0000000000
--- a/packages/backend/native-utils/npm/linux-x64-gnu/package.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-  "name": "native-utils-linux-x64-gnu",
-  "version": "0.0.0",
-  "os": [
-    "linux"
-  ],
-  "cpu": [
-    "x64"
-  ],
-  "main": "native-utils.linux-x64-gnu.node",
-  "files": [
-    "native-utils.linux-x64-gnu.node"
-  ],
-  "license": "MIT",
-  "engines": {
-    "node": ">= 10"
-  },
-  "libc": [
-    "glibc"
-  ]
-}
\ No newline at end of file
diff --git a/packages/backend/native-utils/npm/linux-x64-musl/README.md b/packages/backend/native-utils/npm/linux-x64-musl/README.md
deleted file mode 100644
index 6664b23783..0000000000
--- a/packages/backend/native-utils/npm/linux-x64-musl/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# `native-utils-linux-x64-musl`
-
-This is the **x86_64-unknown-linux-musl** binary for `native-utils`
diff --git a/packages/backend/native-utils/npm/linux-x64-musl/package.json b/packages/backend/native-utils/npm/linux-x64-musl/package.json
deleted file mode 100644
index 56b520fff4..0000000000
--- a/packages/backend/native-utils/npm/linux-x64-musl/package.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-  "name": "native-utils-linux-x64-musl",
-  "version": "0.0.0",
-  "os": [
-    "linux"
-  ],
-  "cpu": [
-    "x64"
-  ],
-  "main": "native-utils.linux-x64-musl.node",
-  "files": [
-    "native-utils.linux-x64-musl.node"
-  ],
-  "license": "MIT",
-  "engines": {
-    "node": ">= 10"
-  },
-  "libc": [
-    "musl"
-  ]
-}
\ No newline at end of file
diff --git a/packages/backend/native-utils/npm/win32-arm64-msvc/README.md b/packages/backend/native-utils/npm/win32-arm64-msvc/README.md
deleted file mode 100644
index 7aec7e0a55..0000000000
--- a/packages/backend/native-utils/npm/win32-arm64-msvc/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# `native-utils-win32-arm64-msvc`
-
-This is the **aarch64-pc-windows-msvc** binary for `native-utils`
diff --git a/packages/backend/native-utils/npm/win32-arm64-msvc/package.json b/packages/backend/native-utils/npm/win32-arm64-msvc/package.json
deleted file mode 100644
index 865a771052..0000000000
--- a/packages/backend/native-utils/npm/win32-arm64-msvc/package.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-  "name": "native-utils-win32-arm64-msvc",
-  "version": "0.0.0",
-  "os": [
-    "win32"
-  ],
-  "cpu": [
-    "arm64"
-  ],
-  "main": "native-utils.win32-arm64-msvc.node",
-  "files": [
-    "native-utils.win32-arm64-msvc.node"
-  ],
-  "license": "MIT",
-  "engines": {
-    "node": ">= 10"
-  }
-}
\ No newline at end of file
diff --git a/packages/backend/native-utils/npm/win32-ia32-msvc/README.md b/packages/backend/native-utils/npm/win32-ia32-msvc/README.md
deleted file mode 100644
index 690de1975d..0000000000
--- a/packages/backend/native-utils/npm/win32-ia32-msvc/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# `native-utils-win32-ia32-msvc`
-
-This is the **i686-pc-windows-msvc** binary for `native-utils`
diff --git a/packages/backend/native-utils/npm/win32-ia32-msvc/package.json b/packages/backend/native-utils/npm/win32-ia32-msvc/package.json
deleted file mode 100644
index 994eff12fd..0000000000
--- a/packages/backend/native-utils/npm/win32-ia32-msvc/package.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-  "name": "native-utils-win32-ia32-msvc",
-  "version": "0.0.0",
-  "os": [
-    "win32"
-  ],
-  "cpu": [
-    "ia32"
-  ],
-  "main": "native-utils.win32-ia32-msvc.node",
-  "files": [
-    "native-utils.win32-ia32-msvc.node"
-  ],
-  "license": "MIT",
-  "engines": {
-    "node": ">= 10"
-  }
-}
\ No newline at end of file
diff --git a/packages/backend/native-utils/npm/win32-x64-msvc/README.md b/packages/backend/native-utils/npm/win32-x64-msvc/README.md
deleted file mode 100644
index e34a5ff172..0000000000
--- a/packages/backend/native-utils/npm/win32-x64-msvc/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# `native-utils-win32-x64-msvc`
-
-This is the **x86_64-pc-windows-msvc** binary for `native-utils`
diff --git a/packages/backend/native-utils/npm/win32-x64-msvc/package.json b/packages/backend/native-utils/npm/win32-x64-msvc/package.json
deleted file mode 100644
index 33b259b132..0000000000
--- a/packages/backend/native-utils/npm/win32-x64-msvc/package.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-  "name": "native-utils-win32-x64-msvc",
-  "version": "0.0.0",
-  "os": [
-    "win32"
-  ],
-  "cpu": [
-    "x64"
-  ],
-  "main": "native-utils.win32-x64-msvc.node",
-  "files": [
-    "native-utils.win32-x64-msvc.node"
-  ],
-  "license": "MIT",
-  "engines": {
-    "node": ">= 10"
-  }
-}
\ No newline at end of file
diff --git a/packages/backend/native-utils/package.json b/packages/backend/native-utils/package.json
deleted file mode 100644
index 787d1bd89f..0000000000
--- a/packages/backend/native-utils/package.json
+++ /dev/null
@@ -1,44 +0,0 @@
-{
-  "name": "native-utils",
-  "version": "0.0.0",
-  "main": "built/index.js",
-  "types": "built/index.d.ts",
-  "napi": {
-    "name": "native-utils",
-    "triples": {
-      "additional": [
-        "aarch64-apple-darwin",
-        "aarch64-linux-android",
-        "aarch64-unknown-linux-gnu",
-        "aarch64-unknown-linux-musl",
-        "aarch64-pc-windows-msvc",
-        "armv7-unknown-linux-gnueabihf",
-        "x86_64-unknown-linux-musl",
-        "x86_64-unknown-freebsd",
-        "i686-pc-windows-msvc",
-        "armv7-linux-androideabi",
-        "universal-apple-darwin"
-      ]
-    }
-  },
-  "license": "MIT",
-  "devDependencies": {
-    "@napi-rs/cli": "^2.15.0",
-    "ava": "^5.1.1"
-  },
-  "ava": {
-    "timeout": "3m"
-  },
-  "engines": {
-    "node": ">= 10"
-  },
-  "scripts": {
-    "artifacts": "napi artifacts",
-    "build": "napi build --platform --release ./built/",
-    "build:debug": "napi build --platform",
-    "prepublishOnly": "napi prepublish -t npm",
-    "test": "ava",
-    "universal": "napi universal",
-    "version": "napi version"
-  }
-}
diff --git a/packages/backend/native-utils/rustfmt.toml b/packages/backend/native-utils/rustfmt.toml
deleted file mode 100644
index cab5731eda..0000000000
--- a/packages/backend/native-utils/rustfmt.toml
+++ /dev/null
@@ -1,2 +0,0 @@
-tab_spaces = 2
-edition = "2021"
diff --git a/packages/backend/native-utils/src/lib.rs b/packages/backend/native-utils/src/lib.rs
deleted file mode 100644
index bc5b9fc7cf..0000000000
--- a/packages/backend/native-utils/src/lib.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-
-pub mod mastodon_api;
diff --git a/packages/backend/native-utils/src/mastodon_api.rs b/packages/backend/native-utils/src/mastodon_api.rs
deleted file mode 100644
index 36b4eb9849..0000000000
--- a/packages/backend/native-utils/src/mastodon_api.rs
+++ /dev/null
@@ -1,70 +0,0 @@
-use napi::{bindgen_prelude::*, Error, Status};
-use napi_derive::napi;
-
-static CHAR_COLLECTION: &str = "0123456789abcdefghijklmnopqrstuvwxyz";
-
-// -- NAPI exports --
-
-#[napi]
-pub enum IdConvertType {
-  MastodonId,
-  CalckeyId,
-}
-
-#[napi]
-pub fn convert_id(in_id: String, id_convert_type: IdConvertType) -> napi::Result<String> {
-  use IdConvertType::*;
-  match id_convert_type {
-    MastodonId => {
-      let mut out: i64 = 0;
-      for (i, c) in in_id.to_lowercase().chars().rev().enumerate() {
-        out += num_from_char(c)? as i64 * 36_i64.pow(i as u32);
-      }
-
-      Ok(out.to_string())
-    }
-    CalckeyId => {
-      let mut input: i64 = match in_id.parse() {
-        Ok(s) => s,
-        Err(_) => {
-          return Err(Error::new(
-            Status::InvalidArg,
-            "Unable to parse ID as MasstodonId",
-          ))
-        }
-      };
-      let mut out = String::new();
-
-      while input != 0 {
-        out.insert(0, char_from_num((input % 36) as u8)?);
-        input /= 36;
-      }
-
-      Ok(out)
-    }
-  }
-}
-
-// -- end --
-
-#[inline(always)]
-fn num_from_char(character: char) -> napi::Result<u8> {
-  for (i, c) in CHAR_COLLECTION.chars().enumerate() {
-    if c == character {
-      return Ok(i as u8);
-    }
-  }
-
-  Err(Error::new(
-    Status::InvalidArg,
-    "Invalid character in parsed base36 id",
-  ))
-}
-
-#[inline(always)]
-fn char_from_num(number: u8) -> napi::Result<char> {
-  CHAR_COLLECTION
-    .chars()
-    .nth(number as usize)
-    .ok_or(Error::from_status(Status::Unknown))
-}
diff --git a/packages/backend/ormconfig.js b/packages/backend/ormconfig.js
deleted file mode 100644
index 5f85cead8a..0000000000
--- a/packages/backend/ormconfig.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import { DataSource } from "typeorm";
-import config from "./built/config/index.js";
-import { entities } from "./built/db/postgre.js";
-
-export default new DataSource({
-	type: "postgres",
-	host: config.db.host,
-	port: config.db.port,
-	username: config.db.user,
-	password: config.db.pass,
-	database: config.db.db,
-	extra: config.db.extra,
-	entities: entities,
-	migrations: ["migration/*.js"],
-});
diff --git a/packages/backend/package.json b/packages/backend/package.json
index 442ef5e187..8e3c70e1ab 100644
--- a/packages/backend/package.json
+++ b/packages/backend/package.json
@@ -1,197 +1,15 @@
 {
 	"name": "backend",
-	"main": "./index.js",
 	"private": true,
 	"type": "module",
 	"scripts": {
-		"start": "pnpm node ./built/index.js",
+		"start": "cargo run --profile $( [ ${NODE_ENV:=dev} = 'production' ] && echo 'release' || echo $NODE_ENV )",
 		"start:test": "NODE_ENV=test pnpm node ./built/index.js",
-		"migrate": "typeorm migration:run -d ormconfig.js",
+		"check": "cargo check",
+		"migrate": "cargo run --bin migrate",
+		"build": "cargo build --profile $( [ ${NODE_ENV:=dev} = 'production' ] && echo 'release' || echo $NODE_ENV )",
 		"revertmigration": "typeorm migration:revert -d ormconfig.js",
-		"check:connect": "node ./check_connect.js",
-		"build": "napi build --platform --release --cargo-cwd native-utils ./native-utils/built/ && pnpm swc src -d built -D",
-		"watch": "pnpm swc src -d built -D -w",
-		"lint": "pnpm rome check \"src/**/*.ts\"",
-		"mocha": "cross-env NODE_ENV=test TS_NODE_FILES=true TS_NODE_TRANSPILE_ONLY=true TS_NODE_PROJECT=\"./test/tsconfig.json\" mocha",
-		"test": "pnpm run mocha"
-	},
-	"resolutions": {
-		"chokidar": "^3.3.1"
-	},
-	"optionalDependencies": {
-		"@swc/core-android-arm64": "1.3.11",
-		"@tensorflow/tfjs-node": "3.21.1"
-	},
-	"dependencies": {
-		"@bull-board/api": "^4.6.4",
-		"@bull-board/koa": "^4.6.4",
-		"@bull-board/ui": "^4.6.4",
-		"@calckey/megalodon": "5.1.24",
-		"@discordapp/twemoji": "14.0.2",
-		"@elastic/elasticsearch": "7.17.0",
-		"@koa/cors": "3.4.3",
-		"@koa/multer": "3.0.0",
-		"@koa/router": "9.0.1",
-		"@peertube/http-signature": "1.7.0",
-		"@redocly/openapi-core": "1.0.0-beta.120",
-		"@sinonjs/fake-timers": "9.1.2",
-		"@syuilo/aiscript": "0.11.1",
-		"@tensorflow/tfjs": "^4.2.0",
-		"ajv": "8.11.2",
-		"archiver": "5.3.1",
-		"argon2": "^0.30.3",
-		"autobind-decorator": "2.4.0",
-		"autolinker": "4.0.0",
-		"autwh": "0.1.0",
-		"aws-sdk": "2.1277.0",
-		"axios": "^1.3.2",
-		"bcryptjs": "2.4.3",
-		"blurhash": "1.1.5",
-		"bull": "4.10.2",
-		"cacheable-lookup": "7.0.0",
-		"calckey-js": "workspace:*",
-		"cbor": "8.1.0",
-		"chalk": "5.2.0",
-		"chalk-template": "0.4.0",
-		"chokidar": "3.5.3",
-		"cli-highlight": "2.1.11",
-		"color-convert": "2.0.1",
-		"content-disposition": "0.5.4",
-		"date-fns": "2.29.3",
-		"deep-email-validator": "0.1.21",
-		"escape-regexp": "0.0.1",
-		"feed": "4.2.2",
-		"file-type": "17.1.6",
-		"fluent-ffmpeg": "2.1.2",
-		"got": "12.5.3",
-		"hpagent": "0.1.2",
-		"ioredis": "5.2.4",
-		"ip-cidr": "3.0.11",
-		"is-svg": "4.3.2",
-		"js-yaml": "4.1.0",
-		"jsdom": "20.0.3",
-		"jsonld": "6.0.0",
-		"jsrsasign": "10.6.1",
-		"koa": "2.13.4",
-		"koa-body": "^6.0.1",
-		"koa-bodyparser": "4.3.0",
-		"koa-json-body": "5.3.0",
-		"koa-logger": "3.2.1",
-		"koa-mount": "4.0.0",
-		"koa-send": "5.0.1",
-		"koa-slow": "2.1.0",
-		"koa-views": "7.0.2",
-		"mfm-js": "0.23.2",
-		"mime-types": "2.1.35",
-		"multer": "1.4.4-lts.1",
-		"native-utils": "link:native-utils",
-		"nested-property": "4.0.0",
-		"node-fetch": "3.3.0",
-		"nodemailer": "6.8.0",
-		"nsfwjs": "2.4.2",
-		"oauth": "^0.10.0",
-		"os-utils": "0.0.14",
-		"parse5": "7.1.2",
-		"pg": "8.8.0",
-		"private-ip": "2.3.4",
-		"probe-image-size": "7.2.3",
-		"promise-limit": "2.7.0",
-		"punycode": "2.1.1",
-		"pureimage": "0.3.15",
-		"qrcode": "1.5.1",
-		"qs": "6.9.7",
-		"random-seed": "0.3.0",
-		"ratelimiter": "3.4.1",
-		"re2": "1.18.0",
-		"redis-lock": "0.1.4",
-		"reflect-metadata": "0.1.13",
-		"rename": "1.0.4",
-		"rndstr": "1.0.0",
-		"rss-parser": "3.12.0",
-		"sanitize-html": "2.8.1",
-		"seedrandom": "^3.0.5",
-		"semver": "7.3.8",
-		"sharp": "0.31.3",
-		"sonic-channel": "^1.3.1",
-		"speakeasy": "2.0.0",
-		"stringz": "2.1.0",
-		"summaly": "github:misskey-dev/summaly",
-		"syslog-pro": "1.0.0",
-		"systeminformation": "5.16.9",
-		"tesseract.js": "^3.0.3",
-		"tinycolor2": "1.5.2",
-		"tmp": "0.2.1",
-		"twemoji-parser": "14.0.0",
-		"typeorm": "0.3.11",
-		"ulid": "2.3.0",
-		"unzipper": "0.10.11",
-		"uuid": "9.0.0",
-		"web-push": "3.5.0",
-		"websocket": "1.0.34",
-		"xev": "3.0.2"
-	},
-	"devDependencies": {
-		"@swc/cli": "^0.1.62",
-		"@swc/core": "^1.3.50",
-		"@types/bcryptjs": "2.4.2",
-		"@types/bull": "3.15.9",
-		"@types/cbor": "6.0.0",
-		"@types/escape-regexp": "0.0.1",
-		"@types/fluent-ffmpeg": "2.1.20",
-		"@types/js-yaml": "4.0.5",
-		"@types/jsdom": "20.0.1",
-		"@types/jsonld": "1.5.8",
-		"@types/jsrsasign": "10.5.4",
-		"@types/koa": "2.13.5",
-		"@types/koa-bodyparser": "4.3.10",
-		"@types/koa-cors": "0.0.2",
-		"@types/koa-favicon": "2.0.21",
-		"@types/koa-logger": "3.1.2",
-		"@types/koa-mount": "4.0.2",
-		"@types/koa-send": "4.1.3",
-		"@types/koa-views": "7.0.0",
-		"@types/koa__cors": "3.3.0",
-		"@types/koa__multer": "2.0.4",
-		"@types/koa__router": "8.0.11",
-		"@types/mocha": "9.1.1",
-		"@types/node": "18.11.18",
-		"@types/node-fetch": "3.0.3",
-		"@types/nodemailer": "6.4.7",
-		"@types/oauth": "0.9.1",
-		"@types/pug": "2.0.6",
-		"@types/punycode": "2.1.0",
-		"@types/qrcode": "1.5.0",
-		"@types/qs": "6.9.7",
-		"@types/random-seed": "0.3.3",
-		"@types/ratelimiter": "3.4.4",
-		"@types/redis": "4.0.11",
-		"@types/rename": "1.0.4",
-		"@types/sanitize-html": "2.8.0",
-		"@types/semver": "7.3.13",
-		"@types/sharp": "0.31.1",
-		"@types/sinonjs__fake-timers": "8.1.2",
-		"@types/speakeasy": "2.0.7",
-		"@types/tinycolor2": "1.4.3",
-		"@types/tmp": "0.2.3",
-		"@types/uuid": "8.3.4",
-		"@types/web-push": "3.3.2",
-		"@types/websocket": "1.0.5",
-		"@types/ws": "8.5.3",
-		"autobind-decorator": "2.4.0",
-		"cross-env": "7.0.3",
-		"eslint": "^8.31.0",
-		"execa": "6.1.0",
-		"json5": "2.2.3",
-		"json5-loader": "4.0.1",
-		"mocha": "10.2.0",
-		"pug": "3.0.2",
-		"strict-event-emitter-types": "2.0.0",
-		"swc-loader": "^0.2.3",
-		"ts-loader": "9.4.2",
-		"ts-node": "10.9.1",
-		"tsconfig-paths": "4.1.2",
-		"typescript": "4.9.4",
-		"webpack": "^5.75.0",
-		"ws": "8.11.0"
+		"lint": "cargo check",
+		"test": "cargo test --workspace"
 	}
 }
diff --git a/packages/backend/rust-toolchain b/packages/backend/rust-toolchain
new file mode 100644
index 0000000000..bf867e0ae5
--- /dev/null
+++ b/packages/backend/rust-toolchain
@@ -0,0 +1 @@
+nightly
diff --git a/packages/backend/rustfmt.toml b/packages/backend/rustfmt.toml
new file mode 100644
index 0000000000..b196eaa2dc
--- /dev/null
+++ b/packages/backend/rustfmt.toml
@@ -0,0 +1 @@
+tab_spaces = 2
diff --git a/packages/backend/src/@types/hcaptcha.d.ts b/packages/backend/src/@types/hcaptcha.d.ts
deleted file mode 100644
index 21f65c678c..0000000000
--- a/packages/backend/src/@types/hcaptcha.d.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-declare module "hcaptcha" {
-	interface IVerifyResponse {
-		success: boolean;
-		challenge_ts: string;
-		hostname: string;
-		credit?: boolean;
-		"error-codes"?: unknown[];
-	}
-
-	export function verify(
-		secret: string,
-		token: string,
-	): Promise<IVerifyResponse>;
-}
diff --git a/packages/backend/src/@types/http-signature.d.ts b/packages/backend/src/@types/http-signature.d.ts
deleted file mode 100644
index 3bfece8cbf..0000000000
--- a/packages/backend/src/@types/http-signature.d.ts
+++ /dev/null
@@ -1,98 +0,0 @@
-declare module "@peertube/http-signature" {
-	import type { IncomingMessage, ClientRequest } from "node:http";
-
-	interface ISignature {
-		keyId: string;
-		algorithm: string;
-		headers: string[];
-		signature: string;
-	}
-
-	interface IOptions {
-		headers?: string[];
-		algorithm?: string;
-		strict?: boolean;
-		authorizationHeaderName?: string;
-	}
-
-	interface IParseRequestOptions extends IOptions {
-		clockSkew?: number;
-	}
-
-	interface IParsedSignature {
-		scheme: string;
-		params: ISignature;
-		signingString: string;
-		algorithm: string;
-		keyId: string;
-	}
-
-	type RequestSignerConstructorOptions =
-		| IRequestSignerConstructorOptionsFromProperties
-		| IRequestSignerConstructorOptionsFromFunction;
-
-	interface IRequestSignerConstructorOptionsFromProperties {
-		keyId: string;
-		key: string | Buffer;
-		algorithm?: string;
-	}
-
-	interface IRequestSignerConstructorOptionsFromFunction {
-		sign?: (data: string, cb: (err: any, sig: ISignature) => void) => void;
-	}
-
-	class RequestSigner {
-		constructor(options: RequestSignerConstructorOptions);
-
-		public writeHeader(header: string, value: string): string;
-
-		public writeDateHeader(): string;
-
-		public writeTarget(method: string, path: string): void;
-
-		public sign(cb: (err: any, authz: string) => void): void;
-	}
-
-	interface ISignRequestOptions extends IOptions {
-		keyId: string;
-		key: string;
-		httpVersion?: string;
-	}
-
-	export function parse(
-		request: IncomingMessage,
-		options?: IParseRequestOptions,
-	): IParsedSignature;
-	export function parseRequest(
-		request: IncomingMessage,
-		options?: IParseRequestOptions,
-	): IParsedSignature;
-
-	export function sign(
-		request: ClientRequest,
-		options: ISignRequestOptions,
-	): boolean;
-	export function signRequest(
-		request: ClientRequest,
-		options: ISignRequestOptions,
-	): boolean;
-	export function createSigner(): RequestSigner;
-	export function isSigner(obj: any): obj is RequestSigner;
-
-	export function sshKeyToPEM(key: string): string;
-	export function sshKeyFingerprint(key: string): string;
-	export function pemToRsaSSHKey(pem: string, comment: string): string;
-
-	export function verify(
-		parsedSignature: IParsedSignature,
-		pubkey: string | Buffer,
-	): boolean;
-	export function verifySignature(
-		parsedSignature: IParsedSignature,
-		pubkey: string | Buffer,
-	): boolean;
-	export function verifyHMAC(
-		parsedSignature: IParsedSignature,
-		secret: string,
-	): boolean;
-}
diff --git a/packages/backend/src/@types/koa-json-body.d.ts b/packages/backend/src/@types/koa-json-body.d.ts
deleted file mode 100644
index e5282d81bf..0000000000
--- a/packages/backend/src/@types/koa-json-body.d.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-declare module "koa-json-body" {
-	import type { Middleware } from "koa";
-
-	interface IKoaJsonBodyOptions {
-		strict: boolean;
-		limit: string;
-		fallback: boolean;
-	}
-
-	function koaJsonBody(opt?: IKoaJsonBodyOptions): Middleware;
-
-	namespace koaJsonBody {} // Hack
-
-	export = koaJsonBody;
-}
diff --git a/packages/backend/src/@types/koa-remove-trailing-slashes/index.d.ts b/packages/backend/src/@types/koa-remove-trailing-slashes/index.d.ts
deleted file mode 100644
index 429d1d53e0..0000000000
--- a/packages/backend/src/@types/koa-remove-trailing-slashes/index.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-declare module "koa-remove-trailing-slashes";
diff --git a/packages/backend/src/@types/koa-slow.d.ts b/packages/backend/src/@types/koa-slow.d.ts
deleted file mode 100644
index e24be51e2a..0000000000
--- a/packages/backend/src/@types/koa-slow.d.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-declare module "koa-slow" {
-	import type { Middleware } from "koa";
-
-	interface ISlowOptions {
-		url?: RegExp;
-		delay?: number;
-	}
-
-	function slow(options?: ISlowOptions): Middleware;
-
-	namespace slow {} // Hack
-
-	export = slow;
-}
diff --git a/packages/backend/src/@types/os-utils.d.ts b/packages/backend/src/@types/os-utils.d.ts
deleted file mode 100644
index 504096ae2b..0000000000
--- a/packages/backend/src/@types/os-utils.d.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-declare module "os-utils" {
-	type FreeCommandCallback = (usedmem: number) => void;
-
-	type HarddriveCallback = (total: number, free: number, used: number) => void;
-
-	type GetProcessesCallback = (result: string) => void;
-
-	type CPUCallback = (perc: number) => void;
-
-	export function platform(): NodeJS.Platform;
-	export function cpuCount(): number;
-	export function sysUptime(): number;
-	export function processUptime(): number;
-
-	export function freemem(): number;
-	export function totalmem(): number;
-	export function freememPercentage(): number;
-	export function freeCommand(callback: FreeCommandCallback): void;
-
-	export function harddrive(callback: HarddriveCallback): void;
-
-	export function getProcesses(callback: GetProcessesCallback): void;
-	export function getProcesses(
-		nProcess: number,
-		callback: GetProcessesCallback,
-	): void;
-
-	export function allLoadavg(): string;
-	export function loadavg(_time?: number): number;
-
-	export function cpuFree(callback: CPUCallback): void;
-	export function cpuUsage(callback: CPUCallback): void;
-}
diff --git a/packages/backend/src/@types/package.json.d.ts b/packages/backend/src/@types/package.json.d.ts
deleted file mode 100644
index d8ec636446..0000000000
--- a/packages/backend/src/@types/package.json.d.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-declare module "*/package.json" {
-	interface IRepository {
-		type: string;
-		url: string;
-	}
-
-	export const name: string;
-	export const version: string;
-	export const repository: IRepository;
-}
diff --git a/packages/backend/src/@types/probe-image-size.d.ts b/packages/backend/src/@types/probe-image-size.d.ts
deleted file mode 100644
index 4ed13df7fa..0000000000
--- a/packages/backend/src/@types/probe-image-size.d.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-declare module "probe-image-size" {
-	import type { ReadStream } from "node:fs";
-
-	type ProbeOptions = {
-		retries: 1;
-		timeout: 30000;
-	};
-
-	type ProbeResult = {
-		width: number;
-		height: number;
-		length?: number;
-		type: string;
-		mime: string;
-		wUnits: "in" | "mm" | "cm" | "pt" | "pc" | "px" | "em" | "ex";
-		hUnits: "in" | "mm" | "cm" | "pt" | "pc" | "px" | "em" | "ex";
-		url?: string;
-	};
-
-	function probeImageSize(
-		src: string | ReadStream,
-		options?: ProbeOptions,
-	): Promise<ProbeResult>;
-	function probeImageSize(
-		src: string | ReadStream,
-		callback: (err: Error | null, result?: ProbeResult) => void,
-	): void;
-	function probeImageSize(
-		src: string | ReadStream,
-		options: ProbeOptions,
-		callback: (err: Error | null, result?: ProbeResult) => void,
-	): void;
-
-	namespace probeImageSize {} // Hack
-
-	export = probeImageSize;
-}
diff --git a/packages/backend/src/bin/migrate.rs b/packages/backend/src/bin/migrate.rs
new file mode 100644
index 0000000000..299db6482a
--- /dev/null
+++ b/packages/backend/src/bin/migrate.rs
@@ -0,0 +1,4 @@
+
+fn main() {
+	todo!();
+}
diff --git a/packages/backend/src/boot/index.ts b/packages/backend/src/boot/index.ts
deleted file mode 100644
index e4f2ed7b1b..0000000000
--- a/packages/backend/src/boot/index.ts
+++ /dev/null
@@ -1,89 +0,0 @@
-import cluster from "node:cluster";
-import chalk from "chalk";
-import Xev from "xev";
-
-import Logger from "@/services/logger.js";
-import { envOption } from "../env.js";
-
-// for typeorm
-import "reflect-metadata";
-import { masterMain } from "./master.js";
-import { workerMain } from "./worker.js";
-import os from "node:os";
-
-const logger = new Logger("core", "cyan");
-const clusterLogger = logger.createSubLogger("cluster", "orange", false);
-const ev = new Xev();
-
-/**
- * Init process
- */
-export default async function () {
-	process.title = `Calckey (${cluster.isPrimary ? "master" : "worker"})`;
-
-	if (cluster.isPrimary || envOption.disableClustering) {
-		await masterMain();
-		if (cluster.isPrimary) {
-			ev.mount();
-		}
-	}
-
-	if (cluster.isWorker || envOption.disableClustering) {
-		await workerMain();
-	}
-
-	if (cluster.isPrimary) {
-		// Leave the master process with a marginally lower priority but not too low.
-		os.setPriority(2);
-	}
-	if (cluster.isWorker) {
-		// Set workers to a much lower priority so that the master process will be
-		// able to respond to api calls even if the workers gank everything.
-		os.setPriority(10);
-	}
-
-	// For when Calckey is started in a child process during unit testing.
-	// Otherwise, process.send cannot be used, so start it.
-	if (process.send) {
-		process.send("ok");
-	}
-}
-
-//#region Events
-
-// Listen new workers
-cluster.on("fork", (worker) => {
-	clusterLogger.debug(`Process forked: [${worker.id}]`);
-});
-
-// Listen online workers
-cluster.on("online", (worker) => {
-	clusterLogger.debug(`Process is now online: [${worker.id}]`);
-});
-
-// Listen for dying workers
-cluster.on("exit", (worker) => {
-	// Replace the dead worker,
-	// we're not sentimental
-	clusterLogger.error(chalk.red(`[${worker.id}] died :(`));
-	cluster.fork();
-});
-
-// Display detail of unhandled promise rejection
-if (!envOption.quiet) {
-	process.on("unhandledRejection", console.dir);
-}
-
-// Display detail of uncaught exception
-process.on("uncaughtException", (err) => {
-	try {
-		logger.error(err);
-	} catch {}
-});
-
-// Dying away...
-process.on("exit", (code) => {
-	logger.info(`The process is going to exit with code ${code}`);
-});
-
-//#endregion
diff --git a/packages/backend/src/boot/master.ts b/packages/backend/src/boot/master.ts
deleted file mode 100644
index 193f02429d..0000000000
--- a/packages/backend/src/boot/master.ts
+++ /dev/null
@@ -1,189 +0,0 @@
-import * as fs from "node:fs";
-import { fileURLToPath } from "node:url";
-import { dirname } from "node:path";
-import * as os from "node:os";
-import cluster from "node:cluster";
-import chalk from "chalk";
-import chalkTemplate from "chalk-template";
-import semver from "semver";
-
-import Logger from "@/services/logger.js";
-import loadConfig from "@/config/load.js";
-import type { Config } from "@/config/types.js";
-import { lessThan } from "@/prelude/array.js";
-import { envOption } from "../env.js";
-import { showMachineInfo } from "@/misc/show-machine-info.js";
-import { db, initDb } from "../db/postgre.js";
-
-const _filename = fileURLToPath(import.meta.url);
-const _dirname = dirname(_filename);
-
-const meta = JSON.parse(
-	fs.readFileSync(`${_dirname}/../../../../built/meta.json`, "utf-8"),
-);
-
-const logger = new Logger("core", "cyan");
-const bootLogger = logger.createSubLogger("boot", "magenta", false);
-
-const themeColor = chalk.hex("#31748f");
-
-function greet() {
-	if (!envOption.quiet) {
-		//#region Calckey logo
-		const v = `v${meta.version}`;
-		console.log(themeColor("   ___      _      _              "));
-		console.log(themeColor("  / __\\__ _| | ___| | _____ _   _ "));
-		console.log(themeColor(" / /  / _` | |/ __| |/ / _  | | |"));
-		console.log(themeColor("/ /__| (_| | | (__|   <  __/ |_| |"));
-		console.log(themeColor("\\____/\\__,_|_|\\___|_|\\_\\___|\\__, |"));
-		console.log(themeColor("                            (___/ "));
-		//#endregion
-
-		console.log(
-			" Calckey is an open-source decentralized microblogging platform.",
-		);
-		console.log(
-			chalk.rgb(
-				255,
-				136,
-				0,
-			)(
-				" If you like Calckey, please consider starring or contributing to the repo. https://codeberg.org/calckey/calckey",
-			),
-		);
-
-		console.log("");
-		console.log(
-			chalkTemplate`--- ${os.hostname()} {gray (PID: ${process.pid.toString()})} ---`,
-		);
-	}
-
-	bootLogger.info("Welcome to Calckey!");
-	bootLogger.info(`Calckey v${meta.version}`, null, true);
-}
-
-/**
- * Init master process
- */
-export async function masterMain() {
-	let config!: Config;
-
-	// initialize app
-	try {
-		greet();
-		showEnvironment();
-		await showMachineInfo(bootLogger);
-		showNodejsVersion();
-		config = loadConfigBoot();
-		await connectDb();
-	} catch (e) {
-		bootLogger.error("Fatal error occurred during initialization", null, true);
-		process.exit(1);
-	}
-
-	bootLogger.succ("Calckey initialized");
-
-	if (!envOption.disableClustering) {
-		await spawnWorkers(config.clusterLimit);
-	}
-
-	bootLogger.succ(
-		`Now listening on port ${config.port} on ${config.url}`,
-		null,
-		true,
-	);
-
-	if (!envOption.noDaemons) {
-		import("../daemons/server-stats.js").then((x) => x.default());
-		import("../daemons/queue-stats.js").then((x) => x.default());
-		import("../daemons/janitor.js").then((x) => x.default());
-	}
-}
-
-function showEnvironment(): void {
-	const env = process.env.NODE_ENV;
-	const logger = bootLogger.createSubLogger("env");
-	logger.info(
-		typeof env === "undefined" ? "NODE_ENV is not set" : `NODE_ENV: ${env}`,
-	);
-
-	if (env !== "production") {
-		logger.warn("The environment is not in production mode.");
-		logger.warn("DO NOT USE FOR PRODUCTION PURPOSE!", null, true);
-	}
-}
-
-function showNodejsVersion(): void {
-	const nodejsLogger = bootLogger.createSubLogger("nodejs");
-
-	nodejsLogger.info(`Version ${process.version} detected.`);
-
-	const minVersion = fs
-		.readFileSync(`${_dirname}/../../../../.node-version`, "utf-8")
-		.trim();
-	if (semver.lt(process.version, minVersion)) {
-		nodejsLogger.error(`At least Node.js ${minVersion} required!`);
-		process.exit(1);
-	}
-}
-
-function loadConfigBoot(): Config {
-	const configLogger = bootLogger.createSubLogger("config");
-	let config;
-
-	try {
-		config = loadConfig();
-	} catch (exception) {
-		if (exception.code === "ENOENT") {
-			configLogger.error("Configuration file not found", null, true);
-			process.exit(1);
-		} else if (e instanceof Error) {
-			configLogger.error(e.message);
-			process.exit(1);
-		}
-		throw exception;
-	}
-
-	configLogger.succ("Loaded");
-
-	return config;
-}
-
-async function connectDb(): Promise<void> {
-	const dbLogger = bootLogger.createSubLogger("db");
-
-	// Try to connect to DB
-	try {
-		dbLogger.info("Connecting...");
-		await initDb();
-		const v = await db
-			.query("SHOW server_version")
-			.then((x) => x[0].server_version);
-		dbLogger.succ(`Connected: v${v}`);
-	} catch (e) {
-		dbLogger.error("Cannot connect", null, true);
-		dbLogger.error(e);
-		process.exit(1);
-	}
-}
-
-async function spawnWorkers(limit: number = 1) {
-	const workers = Math.min(limit, os.cpus().length);
-	bootLogger.info(`Starting ${workers} worker${workers === 1 ? "" : "s"}...`);
-	await Promise.all([...Array(workers)].map(spawnWorker));
-	bootLogger.succ("All workers started");
-}
-
-function spawnWorker(): Promise<void> {
-	return new Promise((res) => {
-		const worker = cluster.fork();
-		worker.on("message", (message) => {
-			if (message === "listenFailed") {
-				bootLogger.error("The server Listen failed due to the previous error.");
-				process.exit(1);
-			}
-			if (message !== "ready") return;
-			res();
-		});
-	});
-}
diff --git a/packages/backend/src/boot/worker.ts b/packages/backend/src/boot/worker.ts
deleted file mode 100644
index 70442b096e..0000000000
--- a/packages/backend/src/boot/worker.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import cluster from "node:cluster";
-import { initDb } from "../db/postgre.js";
-
-/**
- * Init worker process
- */
-export async function workerMain() {
-	await initDb();
-
-	// start server
-	await import("../server/index.js").then((x) => x.default());
-
-	// start job queue
-	import("../queue/index.js").then((x) => x.default());
-
-	if (cluster.isWorker) {
-		// Send a 'ready' message to parent process
-		process.send!("ready");
-	}
-}
diff --git a/packages/backend/src/config/index.ts b/packages/backend/src/config/index.ts
deleted file mode 100644
index ae197b09ca..0000000000
--- a/packages/backend/src/config/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import load from "./load.js";
-
-export default load();
diff --git a/packages/backend/src/config/load.ts b/packages/backend/src/config/load.ts
deleted file mode 100644
index 9b8ee5edbb..0000000000
--- a/packages/backend/src/config/load.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * Config loader
- */
-
-import * as fs from "node:fs";
-import { fileURLToPath } from "node:url";
-import { dirname } from "node:path";
-import * as yaml from "js-yaml";
-import type { Source, Mixin } from "./types.js";
-
-const _filename = fileURLToPath(import.meta.url);
-const _dirname = dirname(_filename);
-
-/**
- * Path of configuration directory
- */
-const dir = `${_dirname}/../../../../.config`;
-
-/**
- * Path of configuration file
- */
-const path =
-	process.env.NODE_ENV === "test" ? `${dir}/test.yml` : `${dir}/default.yml`;
-
-export default function load() {
-	const meta = JSON.parse(
-		fs.readFileSync(`${_dirname}/../../../../built/meta.json`, "utf-8"),
-	);
-	const clientManifest = JSON.parse(
-		fs.readFileSync(
-			`${_dirname}/../../../../built/_client_dist_/manifest.json`,
-			"utf-8",
-		),
-	);
-	const config = yaml.load(fs.readFileSync(path, "utf-8")) as Source;
-
-	const mixin = {} as Mixin;
-
-	const url = tryCreateUrl(config.url);
-
-	config.url = url.origin;
-
-	config.port = config.port || parseInt(process.env.PORT || "", 10);
-
-	mixin.version = meta.version;
-	mixin.host = url.host;
-	mixin.hostname = url.hostname;
-	mixin.scheme = url.protocol.replace(/:$/, "");
-	mixin.wsScheme = mixin.scheme.replace("http", "ws");
-	mixin.wsUrl = `${mixin.wsScheme}://${mixin.host}`;
-	mixin.apiUrl = `${mixin.scheme}://${mixin.host}/api`;
-	mixin.authUrl = `${mixin.scheme}://${mixin.host}/auth`;
-	mixin.driveUrl = `${mixin.scheme}://${mixin.host}/files`;
-	mixin.userAgent = `Calckey/${meta.version} (${config.url})`;
-	mixin.clientEntry = clientManifest["src/init.ts"];
-
-	if (!config.redis.prefix) config.redis.prefix = mixin.host;
-
-	return Object.assign(config, mixin);
-}
-
-function tryCreateUrl(url: string) {
-	try {
-		return new URL(url);
-	} catch (e) {
-		throw new Error(`url="${url}" is not a valid URL.`);
-	}
-}
diff --git a/packages/backend/src/config/types.ts b/packages/backend/src/config/types.ts
deleted file mode 100644
index a7cdc89cf2..0000000000
--- a/packages/backend/src/config/types.ts
+++ /dev/null
@@ -1,133 +0,0 @@
-/**
- * ユーザーが設定する必要のある情報
- */
-export type Source = {
-	repository_url?: string;
-	feedback_url?: string;
-	url: string;
-	port: number;
-	disableHsts?: boolean;
-	db: {
-		host: string;
-		port: number;
-		db: string;
-		user: string;
-		pass: string;
-		disableCache?: boolean;
-		extra?: { [x: string]: string };
-	};
-	redis: {
-		host: string;
-		port: number;
-		family?: number;
-		pass: string;
-		db?: number;
-		prefix?: string;
-	};
-	elasticsearch: {
-		host: string;
-		port: number;
-		ssl?: boolean;
-		user?: string;
-		pass?: string;
-		index?: string;
-	};
-	sonic: {
-		host: string;
-		port: number;
-		auth?: string;
-		collection?: string;
-		bucket?: string;
-	};
-
-	proxy?: string;
-	proxySmtp?: string;
-	proxyBypassHosts?: string[];
-
-	allowedPrivateNetworks?: string[];
-
-	maxFileSize?: number;
-
-	accesslog?: string;
-
-	clusterLimit?: number;
-
-	id: string;
-
-	outgoingAddressFamily?: "ipv4" | "ipv6" | "dual";
-
-	deliverJobConcurrency?: number;
-	inboxJobConcurrency?: number;
-	deliverJobPerSec?: number;
-	inboxJobPerSec?: number;
-	deliverJobMaxAttempts?: number;
-	inboxJobMaxAttempts?: number;
-
-	syslog: {
-		host: string;
-		port: number;
-	};
-
-	mediaProxy?: string;
-	proxyRemoteFiles?: boolean;
-
-	twa: {
-		nameSpace?: string;
-		packageName?: string;
-		sha256CertFingerprints?: string[];
-	};
-
-	// Managed hosting stuff
-	maxUserSignups?: number;
-	isManagedHosting?: boolean;
-	maxNoteLength?: number;
-	maxCaptionLength?: number;
-	deepl: {
-		managed?: boolean;
-		authKey?: string;
-		isPro?: boolean;
-	};
-	email: {
-		managed?: boolean;
-		address?: string;
-		host?: string;
-		port?: number;
-		user?: string;
-		pass?: string;
-		useImplicitSslTls?: boolean;
-	};
-	objectStorage: {
-		managed?: boolean;
-		baseUrl?: string;
-		bucket?: string;
-		prefix?: string;
-		endpoint?: string;
-		region?: string;
-		accessKey?: string;
-		secretKey?: string;
-		useSsl?: boolean;
-		connnectOverProxy?: boolean;
-		setPublicReadOnUpload?: boolean;
-		s3ForcePathStyle?: boolean;
-	};
-	summalyProxyUrl?: string;
-};
-
-/**
- * Misskeyが自動的に(ユーザーが設定した情報から推論して)設定する情報
- */
-export type Mixin = {
-	version: string;
-	host: string;
-	hostname: string;
-	scheme: string;
-	wsScheme: string;
-	apiUrl: string;
-	wsUrl: string;
-	authUrl: string;
-	driveUrl: string;
-	userAgent: string;
-	clientEntry: string;
-};
-
-export type Config = Source & Mixin;
diff --git a/packages/backend/src/const.ts b/packages/backend/src/const.ts
deleted file mode 100644
index 7e8f96444e..0000000000
--- a/packages/backend/src/const.ts
+++ /dev/null
@@ -1,71 +0,0 @@
-import config from "@/config/index.js";
-import { DB_MAX_IMAGE_COMMENT_LENGTH } from "@/misc/hard-limits.js";
-
-export const MAX_NOTE_TEXT_LENGTH =
-	config.maxNoteLength != null ? config.maxNoteLength : 3000; // <- should we increase this?
-export const MAX_CAPTION_TEXT_LENGTH = Math.min(
-	config.maxCaptionLength ?? 1500,
-	DB_MAX_IMAGE_COMMENT_LENGTH,
-);
-
-export const SECOND = 1000;
-export const SEC = 1000; // why do we need this duplicate here?
-export const MINUTE = 60 * SEC;
-export const MIN = 60 * SEC; // why do we need this duplicate here?
-export const HOUR = 60 * MIN;
-export const DAY = 24 * HOUR;
-
-export const USER_ONLINE_THRESHOLD = 10 * MINUTE;
-export const USER_ACTIVE_THRESHOLD = 3 * DAY;
-
-// List of file types allowed to be viewed directly in the browser
-// Anything not included here will be responded as application/octet-stream
-// SVG is not allowed because it generates XSS <- we need to fix this and later allow it to be viewed directly
-export const FILE_TYPE_BROWSERSAFE = [
-	// Images
-	"image/png",
-	"image/gif", // TODO: deprecated, but still used by old notes, new gifs should be converted to webp in the future
-	"image/jpeg",
-	"image/webp", // TODO: make this the default image format
-	"image/apng",
-	"image/bmp",
-	"image/tiff",
-	"image/x-icon",
-	"image/avif", // not as good supported now, but its good to introduce initial support for the future
-
-	// OggS
-	"audio/opus",
-	"video/ogg",
-	"audio/ogg",
-	"application/ogg",
-
-	// ISO/IEC base media file format
-	"video/quicktime",
-	"video/mp4", // TODO: we need to check for av1 later
-	"video/vnd.avi", // also av1
-	"audio/mp4",
-	"video/x-m4v",
-	"audio/x-m4a",
-	"video/3gpp",
-	"video/3gpp2",
-	"video/3gp2",
-	"audio/3gpp",
-	"audio/3gpp2",
-	"audio/3gp2",
-
-	"video/mpeg",
-	"audio/mpeg",
-
-	"video/webm",
-	"audio/webm",
-
-	"audio/aac",
-	"audio/x-flac",
-	"audio/flac",
-	"audio/vnd.wave",
-];
-/*
-https://github.com/sindresorhus/file-type/blob/main/supported.js
-https://github.com/sindresorhus/file-type/blob/main/core.js
-https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Containers
-*/
diff --git a/packages/backend/src/daemons/janitor.ts b/packages/backend/src/daemons/janitor.ts
deleted file mode 100644
index 2050d54d4c..0000000000
--- a/packages/backend/src/daemons/janitor.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-// TODO: 消したい
-
-const interval = 30 * 60 * 1000;
-import { AttestationChallenges } from "@/models/index.js";
-import { LessThan } from "typeorm";
-
-/**
- * Clean up database occasionally
- */
-export default function () {
-	async function tick() {
-		await AttestationChallenges.delete({
-			createdAt: LessThan(new Date(new Date().getTime() - 5 * 60 * 1000)),
-		});
-	}
-
-	tick();
-
-	setInterval(tick, interval);
-}
diff --git a/packages/backend/src/daemons/queue-stats.ts b/packages/backend/src/daemons/queue-stats.ts
deleted file mode 100644
index 381b52a916..0000000000
--- a/packages/backend/src/daemons/queue-stats.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-import Xev from "xev";
-import { deliverQueue, inboxQueue } from "../queue/queues.js";
-
-const ev = new Xev();
-
-const interval = 10000;
-
-/**
- * Report queue stats regularly
- */
-export default function () {
-	const log = [] as any[];
-
-	ev.on("requestQueueStatsLog", (x) => {
-		ev.emit(`queueStatsLog:${x.id}`, log.slice(0, x.length || 50));
-	});
-
-	let activeDeliverJobs = 0;
-	let activeInboxJobs = 0;
-
-	deliverQueue.on("global:active", () => {
-		activeDeliverJobs++;
-	});
-
-	inboxQueue.on("global:active", () => {
-		activeInboxJobs++;
-	});
-
-	async function tick() {
-		const deliverJobCounts = await deliverQueue.getJobCounts();
-		const inboxJobCounts = await inboxQueue.getJobCounts();
-
-		const stats = {
-			deliver: {
-				activeSincePrevTick: activeDeliverJobs,
-				active: deliverJobCounts.active,
-				waiting: deliverJobCounts.waiting,
-				delayed: deliverJobCounts.delayed,
-			},
-			inbox: {
-				activeSincePrevTick: activeInboxJobs,
-				active: inboxJobCounts.active,
-				waiting: inboxJobCounts.waiting,
-				delayed: inboxJobCounts.delayed,
-			},
-		};
-
-		ev.emit("queueStats", stats);
-
-		log.unshift(stats);
-		if (log.length > 200) log.pop();
-
-		activeDeliverJobs = 0;
-		activeInboxJobs = 0;
-	}
-
-	tick();
-
-	setInterval(tick, interval);
-}
diff --git a/packages/backend/src/daemons/server-stats.ts b/packages/backend/src/daemons/server-stats.ts
deleted file mode 100644
index b0bf1288fd..0000000000
--- a/packages/backend/src/daemons/server-stats.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-import si from "systeminformation";
-import Xev from "xev";
-import * as osUtils from "os-utils";
-
-const ev = new Xev();
-
-const interval = 2000;
-
-const roundCpu = (num: number) => Math.round(num * 1000) / 1000;
-const round = (num: number) => Math.round(num * 10) / 10;
-
-/**
- * Report server stats regularly
- */
-export default function () {
-	const log = [] as any[];
-
-	ev.on("requestServerStatsLog", (x) => {
-		ev.emit(`serverStatsLog:${x.id}`, log.slice(0, x.length || 50));
-	});
-
-	async function tick() {
-		const cpu = await cpuUsage();
-		const memStats = await mem();
-		const netStats = await net();
-		const fsStats = await fs();
-
-		const stats = {
-			cpu: roundCpu(cpu),
-			mem: {
-				used: round(memStats.used - memStats.buffers - memStats.cached),
-				active: round(memStats.active),
-			},
-			net: {
-				rx: round(Math.max(0, netStats.rx_sec)),
-				tx: round(Math.max(0, netStats.tx_sec)),
-			},
-			fs: {
-				r: round(Math.max(0, fsStats.rIO_sec ?? 0)),
-				w: round(Math.max(0, fsStats.wIO_sec ?? 0)),
-			},
-		};
-		ev.emit("serverStats", stats);
-		log.unshift(stats);
-		if (log.length > 200) log.pop();
-	}
-
-	tick();
-
-	setInterval(tick, interval);
-}
-
-// CPU STAT
-function cpuUsage(): Promise<number> {
-	return new Promise((res, rej) => {
-		osUtils.cpuUsage((cpuUsage) => {
-			res(cpuUsage);
-		});
-	});
-}
-
-// MEMORY STAT
-async function mem() {
-	const data = await si.mem();
-	return data;
-}
-
-// NETWORK STAT
-async function net() {
-	const iface = await si.networkInterfaceDefault();
-	const data = await si.networkStats(iface);
-	return data[0];
-}
-
-// FS STAT
-async function fs() {
-	const data = await si.disksIO().catch(() => ({ rIO_sec: 0, wIO_sec: 0 }));
-	return data || { rIO_sec: 0, wIO_sec: 0 };
-}
diff --git a/packages/backend/src/db/elasticsearch.ts b/packages/backend/src/db/elasticsearch.ts
deleted file mode 100644
index 2640e7f918..0000000000
--- a/packages/backend/src/db/elasticsearch.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-import * as elasticsearch from "@elastic/elasticsearch";
-import config from "@/config/index.js";
-
-const index = {
-	settings: {
-		analysis: {
-			analyzer: {
-				ngram: {
-					tokenizer: "ngram",
-				},
-			},
-		},
-	},
-	mappings: {
-		properties: {
-			text: {
-				type: "text",
-				index: true,
-				analyzer: "ngram",
-			},
-			userId: {
-				type: "keyword",
-				index: true,
-			},
-			userHost: {
-				type: "keyword",
-				index: true,
-			},
-		},
-	},
-};
-
-// Init ElasticSearch connection
-const client = config.elasticsearch
-	? new elasticsearch.Client({
-			node: `${config.elasticsearch.ssl ? "https://" : "http://"}${
-				config.elasticsearch.host
-			}:${config.elasticsearch.port}`,
-			auth:
-				config.elasticsearch.user && config.elasticsearch.pass
-					? {
-							username: config.elasticsearch.user,
-							password: config.elasticsearch.pass,
-					  }
-					: undefined,
-			pingTimeout: 30000,
-	  })
-	: null;
-
-if (client) {
-	client.indices
-		.exists({
-			index: config.elasticsearch.index || "misskey_note",
-		})
-		.then((exist) => {
-			if (!exist.body) {
-				client.indices.create({
-					index: config.elasticsearch.index || "misskey_note",
-					body: index,
-				});
-			}
-		});
-}
-
-export default client;
diff --git a/packages/backend/src/db/logger.ts b/packages/backend/src/db/logger.ts
deleted file mode 100644
index 28ec65dd24..0000000000
--- a/packages/backend/src/db/logger.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import Logger from "@/services/logger.js";
-
-export const dbLogger = new Logger("db");
diff --git a/packages/backend/src/db/postgre.ts b/packages/backend/src/db/postgre.ts
deleted file mode 100644
index bdeb910e84..0000000000
--- a/packages/backend/src/db/postgre.ts
+++ /dev/null
@@ -1,262 +0,0 @@
-// https://github.com/typeorm/typeorm/issues/2400
-import pg from "pg";
-pg.types.setTypeParser(20, Number);
-
-import type { Logger } from "typeorm";
-import { DataSource } from "typeorm";
-import * as highlight from "cli-highlight";
-import config from "@/config/index.js";
-
-import { User } from "@/models/entities/user.js";
-import { DriveFile } from "@/models/entities/drive-file.js";
-import { DriveFolder } from "@/models/entities/drive-folder.js";
-import { AccessToken } from "@/models/entities/access-token.js";
-import { App } from "@/models/entities/app.js";
-import { PollVote } from "@/models/entities/poll-vote.js";
-import { Note } from "@/models/entities/note.js";
-import { NoteReaction } from "@/models/entities/note-reaction.js";
-import { NoteWatching } from "@/models/entities/note-watching.js";
-import { NoteThreadMuting } from "@/models/entities/note-thread-muting.js";
-import { NoteUnread } from "@/models/entities/note-unread.js";
-import { Notification } from "@/models/entities/notification.js";
-import { Meta } from "@/models/entities/meta.js";
-import { Following } from "@/models/entities/following.js";
-import { Instance } from "@/models/entities/instance.js";
-import { Muting } from "@/models/entities/muting.js";
-import { RenoteMuting } from "@/models/entities/renote-muting.js";
-import { SwSubscription } from "@/models/entities/sw-subscription.js";
-import { Blocking } from "@/models/entities/blocking.js";
-import { UserList } from "@/models/entities/user-list.js";
-import { UserListJoining } from "@/models/entities/user-list-joining.js";
-import { UserGroup } from "@/models/entities/user-group.js";
-import { UserGroupJoining } from "@/models/entities/user-group-joining.js";
-import { UserGroupInvitation } from "@/models/entities/user-group-invitation.js";
-import { Hashtag } from "@/models/entities/hashtag.js";
-import { NoteFavorite } from "@/models/entities/note-favorite.js";
-import { AbuseUserReport } from "@/models/entities/abuse-user-report.js";
-import { RegistrationTicket } from "@/models/entities/registration-tickets.js";
-import { MessagingMessage } from "@/models/entities/messaging-message.js";
-import { Signin } from "@/models/entities/signin.js";
-import { AuthSession } from "@/models/entities/auth-session.js";
-import { FollowRequest } from "@/models/entities/follow-request.js";
-import { Emoji } from "@/models/entities/emoji.js";
-import { UserNotePining } from "@/models/entities/user-note-pining.js";
-import { Poll } from "@/models/entities/poll.js";
-import { UserKeypair } from "@/models/entities/user-keypair.js";
-import { UserPublickey } from "@/models/entities/user-publickey.js";
-import { UserProfile } from "@/models/entities/user-profile.js";
-import { UserSecurityKey } from "@/models/entities/user-security-key.js";
-import { AttestationChallenge } from "@/models/entities/attestation-challenge.js";
-import { Page } from "@/models/entities/page.js";
-import { PageLike } from "@/models/entities/page-like.js";
-import { GalleryPost } from "@/models/entities/gallery-post.js";
-import { GalleryLike } from "@/models/entities/gallery-like.js";
-import { ModerationLog } from "@/models/entities/moderation-log.js";
-import { UsedUsername } from "@/models/entities/used-username.js";
-import { Announcement } from "@/models/entities/announcement.js";
-import { AnnouncementRead } from "@/models/entities/announcement-read.js";
-import { Clip } from "@/models/entities/clip.js";
-import { ClipNote } from "@/models/entities/clip-note.js";
-import { Antenna } from "@/models/entities/antenna.js";
-import { AntennaNote } from "@/models/entities/antenna-note.js";
-import { PromoNote } from "@/models/entities/promo-note.js";
-import { PromoRead } from "@/models/entities/promo-read.js";
-import { Relay } from "@/models/entities/relay.js";
-import { MutedNote } from "@/models/entities/muted-note.js";
-import { Channel } from "@/models/entities/channel.js";
-import { ChannelFollowing } from "@/models/entities/channel-following.js";
-import { ChannelNotePining } from "@/models/entities/channel-note-pining.js";
-import { RegistryItem } from "@/models/entities/registry-item.js";
-import { Ad } from "@/models/entities/ad.js";
-import { PasswordResetRequest } from "@/models/entities/password-reset-request.js";
-import { UserPending } from "@/models/entities/user-pending.js";
-import { Webhook } from "@/models/entities/webhook.js";
-import { UserIp } from "@/models/entities/user-ip.js";
-
-import { entities as charts } from "@/services/chart/entities.js";
-import { envOption } from "../env.js";
-import { dbLogger } from "./logger.js";
-import { redisClient } from "./redis.js";
-
-const sqlLogger = dbLogger.createSubLogger("sql", "gray", false);
-
-class MyCustomLogger implements Logger {
-	private highlight(sql: string) {
-		return highlight.highlight(sql, {
-			language: "sql",
-			ignoreIllegals: true,
-		});
-	}
-
-	public logQuery(query: string, parameters?: any[]) {
-		sqlLogger.info(this.highlight(query).substring(0, 100));
-	}
-
-	public logQueryError(error: string, query: string, parameters?: any[]) {
-		sqlLogger.error(this.highlight(query));
-	}
-
-	public logQuerySlow(time: number, query: string, parameters?: any[]) {
-		sqlLogger.warn(this.highlight(query));
-	}
-
-	public logSchemaBuild(message: string) {
-		sqlLogger.info(message);
-	}
-
-	public log(message: string) {
-		sqlLogger.info(message);
-	}
-
-	public logMigration(message: string) {
-		sqlLogger.info(message);
-	}
-}
-
-export const entities = [
-	Announcement,
-	AnnouncementRead,
-	Meta,
-	Instance,
-	App,
-	AuthSession,
-	AccessToken,
-	User,
-	UserProfile,
-	UserKeypair,
-	UserPublickey,
-	UserList,
-	UserListJoining,
-	UserGroup,
-	UserGroupJoining,
-	UserGroupInvitation,
-	UserNotePining,
-	UserSecurityKey,
-	UsedUsername,
-	AttestationChallenge,
-	Following,
-	FollowRequest,
-	Muting,
-	RenoteMuting,
-	Blocking,
-	Note,
-	NoteFavorite,
-	NoteReaction,
-	NoteWatching,
-	NoteThreadMuting,
-	NoteUnread,
-	Page,
-	PageLike,
-	GalleryPost,
-	GalleryLike,
-	DriveFile,
-	DriveFolder,
-	Poll,
-	PollVote,
-	Notification,
-	Emoji,
-	Hashtag,
-	SwSubscription,
-	AbuseUserReport,
-	RegistrationTicket,
-	MessagingMessage,
-	Signin,
-	ModerationLog,
-	Clip,
-	ClipNote,
-	Antenna,
-	AntennaNote,
-	PromoNote,
-	PromoRead,
-	Relay,
-	MutedNote,
-	Channel,
-	ChannelFollowing,
-	ChannelNotePining,
-	RegistryItem,
-	Ad,
-	PasswordResetRequest,
-	UserPending,
-	Webhook,
-	UserIp,
-	...charts,
-];
-
-const log = process.env.NODE_ENV !== "production";
-
-export const db = new DataSource({
-	type: "postgres",
-	host: config.db.host,
-	port: config.db.port,
-	username: config.db.user,
-	password: config.db.pass,
-	database: config.db.db,
-	extra: {
-		statement_timeout: 1000 * 10,
-		...config.db.extra,
-	},
-	synchronize: process.env.NODE_ENV === "test",
-	dropSchema: process.env.NODE_ENV === "test",
-	cache: !config.db.disableCache
-		? {
-				type: "ioredis",
-				options: {
-					host: config.redis.host,
-					port: config.redis.port,
-					family: config.redis.family == null ? 0 : config.redis.family,
-					password: config.redis.pass,
-					keyPrefix: `${config.redis.prefix}:query:`,
-					db: config.redis.db || 0,
-				},
-		  }
-		: false,
-	logging: log,
-	logger: log ? new MyCustomLogger() : undefined,
-	maxQueryExecutionTime: 300,
-	entities: entities,
-	migrations: ["../../migration/*.js"],
-});
-
-export async function initDb(force = false) {
-	if (force) {
-		if (db.isInitialized) {
-			await db.destroy();
-		}
-		await db.initialize();
-		return;
-	}
-
-	if (db.isInitialized) {
-		// nop
-	} else {
-		await db.initialize();
-	}
-}
-
-export async function resetDb() {
-	const reset = async () => {
-		await redisClient.flushdb();
-		const tables = await db.query(`SELECT relname AS "table"
-		FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
-		WHERE nspname NOT IN ('pg_catalog', 'information_schema')
-			AND C.relkind = 'r'
-			AND nspname !~ '^pg_toast';`);
-		for (const table of tables) {
-			await db.query(`DELETE FROM "${table.table}" CASCADE`);
-		}
-	};
-
-	for (let i = 1; i <= 3; i++) {
-		try {
-			await reset();
-		} catch (e) {
-			if (i === 3) {
-				throw e;
-			} else {
-				await new Promise((resolve) => setTimeout(resolve, 1000));
-				continue;
-			}
-		}
-		break;
-	}
-}
diff --git a/packages/backend/src/db/redis.ts b/packages/backend/src/db/redis.ts
deleted file mode 100644
index 6ad3de386f..0000000000
--- a/packages/backend/src/db/redis.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import Redis from "ioredis";
-import config from "@/config/index.js";
-
-export function createConnection() {
-	return new Redis({
-		port: config.redis.port,
-		host: config.redis.host,
-		family: config.redis.family == null ? 0 : config.redis.family,
-		password: config.redis.pass,
-		keyPrefix: `${config.redis.prefix}:`,
-		db: config.redis.db || 0,
-	});
-}
-
-export const subscriber = createConnection();
-subscriber.subscribe(config.host);
-
-export const redisClient = createConnection();
diff --git a/packages/backend/src/db/sonic.ts b/packages/backend/src/db/sonic.ts
deleted file mode 100644
index 590c479247..0000000000
--- a/packages/backend/src/db/sonic.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import * as SonicChannel from "sonic-channel";
-import { dbLogger } from "./logger.js";
-
-import config from "@/config/index.js";
-
-const logger = dbLogger.createSubLogger("sonic", "gray", false);
-
-logger.info("Connecting to Sonic");
-
-const handlers = (type: string): SonicChannel.Handlers => ({
-	connected: () => {
-		logger.succ(`Connected to Sonic ${type}`);
-	},
-	disconnected: (error) => {
-		logger.warn(`Disconnected from Sonic ${type}, error: ${error}`);
-	},
-	error: (error) => {
-		logger.warn(`Sonic ${type} error: ${error}`);
-	},
-	retrying: () => {
-		logger.info(`Sonic ${type} retrying`);
-	},
-	timeout: () => {
-		logger.warn(`Sonic ${type} timeout`);
-	},
-});
-
-const hasConfig =
-	config.sonic && (config.sonic.host || config.sonic.port || config.sonic.auth);
-
-const host = hasConfig ? config.sonic.host ?? "localhost" : "";
-const port = hasConfig ? config.sonic.port ?? 1491 : 0;
-const auth = hasConfig ? config.sonic.auth ?? "SecretPassword" : "";
-const collection = hasConfig ? config.sonic.collection ?? "main" : "";
-const bucket = hasConfig ? config.sonic.bucket ?? "default" : "";
-
-export default hasConfig
-	? {
-			search: new SonicChannel.Search({ host, port, auth }).connect(
-				handlers("search"),
-			),
-			ingest: new SonicChannel.Ingest({ host, port, auth }).connect(
-				handlers("ingest"),
-			),
-
-			collection,
-			bucket,
-	  }
-	: null;
diff --git a/packages/backend/src/env.ts b/packages/backend/src/env.ts
deleted file mode 100644
index a788a0fba2..0000000000
--- a/packages/backend/src/env.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-const envOption = {
-	onlyQueue: false,
-	onlyServer: false,
-	noDaemons: false,
-	disableClustering: false,
-	verbose: false,
-	withLogTime: false,
-	quiet: false,
-	slow: false,
-};
-
-for (const key of Object.keys(envOption) as (keyof typeof envOption)[]) {
-	if (
-		process.env[
-			`MK_${key.replace(/[A-Z]/g, (letter) => `_${letter}`).toUpperCase()}`
-		]
-	)
-		envOption[key] = true;
-}
-
-if (process.env.NODE_ENV === "test") envOption.disableClustering = true;
-if (process.env.NODE_ENV === "test") envOption.quiet = true;
-if (process.env.NODE_ENV === "test") envOption.noDaemons = true;
-
-export { envOption };
diff --git a/packages/backend/src/global.d.ts b/packages/backend/src/global.d.ts
deleted file mode 100644
index 503e26eb60..0000000000
--- a/packages/backend/src/global.d.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-// rome-ignore lint/suspicious/noExplicitAny: i have no idea
-type FIXME = any;
diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts
deleted file mode 100644
index 278f630f70..0000000000
--- a/packages/backend/src/index.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-/**
- * Misskey Entry Point!
- */
-
-import { EventEmitter } from "node:events";
-import boot from "./boot/index.js";
-
-Error.stackTraceLimit = Infinity;
-EventEmitter.defaultMaxListeners = 128;
-
-boot().catch((err) => {
-	console.error(err);
-});
diff --git a/packages/backend/src/main.rs b/packages/backend/src/main.rs
new file mode 100644
index 0000000000..336d023394
--- /dev/null
+++ b/packages/backend/src/main.rs
@@ -0,0 +1,5 @@
+
+
+fn main() {
+
+}
diff --git a/packages/backend/src/mfm/from-html.ts b/packages/backend/src/mfm/from-html.ts
deleted file mode 100644
index 7c956e9058..0000000000
--- a/packages/backend/src/mfm/from-html.ts
+++ /dev/null
@@ -1,213 +0,0 @@
-import { URL } from "node:url";
-import * as parse5 from "parse5";
-import * as TreeAdapter from "../../node_modules/parse5/dist/tree-adapters/default.js";
-
-const treeAdapter = TreeAdapter.defaultTreeAdapter;
-
-const urlRegex = /^https?:\/\/[\w\/:%#@$&?!()\[\]~.,=+\-]+/;
-const urlRegexFull = /^https?:\/\/[\w\/:%#@$&?!()\[\]~.,=+\-]+$/;
-
-export function fromHtml(html: string, hashtagNames?: string[]): string {
-	// some AP servers like Pixelfed use br tags as well as newlines
-	html = html.replace(/<br\s?\/?>\r?\n/gi, "\n");
-
-	const dom = parse5.parseFragment(html);
-
-	let text = "";
-
-	for (const n of dom.childNodes) {
-		analyze(n);
-	}
-
-	return text.trim();
-
-	function getText(node: TreeAdapter.Node): string {
-		if (treeAdapter.isTextNode(node)) return node.value;
-		if (!treeAdapter.isElementNode(node)) return "";
-		if (node.nodeName === "br") return "\n";
-
-		if (node.childNodes) {
-			return node.childNodes.map((n) => getText(n)).join("");
-		}
-
-		return "";
-	}
-
-	function appendChildren(childNodes: TreeAdapter.ChildNode[]): void {
-		if (childNodes) {
-			for (const n of childNodes) {
-				analyze(n);
-			}
-		}
-	}
-
-	function analyze(node: TreeAdapter.Node) {
-		if (treeAdapter.isTextNode(node)) {
-			text += node.value;
-			return;
-		}
-
-		// Skip comment or document type node
-		if (!treeAdapter.isElementNode(node)) return;
-
-		switch (node.nodeName) {
-			case "br": {
-				text += "\n";
-				break;
-			}
-
-			case "a": {
-				const txt = getText(node);
-				const rel = node.attrs.find((x) => x.name === "rel");
-				const href = node.attrs.find((x) => x.name === "href");
-
-				// ハッシュタグ
-				if (
-					hashtagNames &&
-					href &&
-					hashtagNames.map((x) => x.toLowerCase()).includes(txt.toLowerCase())
-				) {
-					text += txt;
-					// メンション
-				} else if (txt.startsWith("@") && !rel?.value.match(/^me /)) {
-					const part = txt.split("@");
-
-					if (part.length === 2 && href) {
-						//#region ホスト名部分が省略されているので復元する
-						const acct = `${txt}@${new URL(href.value).hostname}`;
-						text += acct;
-						//#endregion
-					} else if (part.length === 3) {
-						text += txt;
-					}
-					// その他
-				} else {
-					const generateLink = () => {
-						if (!(href || txt)) {
-							return "";
-						}
-						if (!href) {
-							return txt;
-						}
-						if (!txt || txt === href.value) {
-							// #6383: Missing text node
-							if (href.value.match(urlRegexFull)) {
-								return href.value;
-							} else {
-								return `<${href.value}>`;
-							}
-						}
-						if (href.value.match(urlRegex) && !href.value.match(urlRegexFull)) {
-							return `[${txt}](<${href.value}>)`; // #6846
-						} else {
-							return `[${txt}](${href.value})`;
-						}
-					};
-
-					text += generateLink();
-				}
-				break;
-			}
-
-			case "h1": {
-				text += "【";
-				appendChildren(node.childNodes);
-				text += "】\n";
-				break;
-			}
-
-			case "b":
-			case "strong": {
-				text += "**";
-				appendChildren(node.childNodes);
-				text += "**";
-				break;
-			}
-
-			case "small": {
-				text += "<small>";
-				appendChildren(node.childNodes);
-				text += "</small>";
-				break;
-			}
-
-			case "s":
-			case "del": {
-				text += "~~";
-				appendChildren(node.childNodes);
-				text += "~~";
-				break;
-			}
-
-			case "i":
-			case "em": {
-				text += "<i>";
-				appendChildren(node.childNodes);
-				text += "</i>";
-				break;
-			}
-
-			// block code (<pre><code>)
-			case "pre": {
-				if (
-					node.childNodes.length === 1 &&
-					node.childNodes[0].nodeName === "code"
-				) {
-					text += "\n```\n";
-					text += getText(node.childNodes[0]);
-					text += "\n```\n";
-				} else {
-					appendChildren(node.childNodes);
-				}
-				break;
-			}
-
-			// inline code (<code>)
-			case "code": {
-				text += "`";
-				appendChildren(node.childNodes);
-				text += "`";
-				break;
-			}
-
-			case "blockquote": {
-				const t = getText(node);
-				if (t) {
-					text += "\n> ";
-					text += t.split("\n").join("\n> ");
-				}
-				break;
-			}
-
-			case "p":
-			case "h2":
-			case "h3":
-			case "h4":
-			case "h5":
-			case "h6": {
-				text += "\n\n";
-				appendChildren(node.childNodes);
-				break;
-			}
-
-			// other block elements
-			case "div":
-			case "header":
-			case "footer":
-			case "article":
-			case "li":
-			case "dt":
-			case "dd": {
-				text += "\n";
-				appendChildren(node.childNodes);
-				break;
-			}
-
-			default: {
-				// includes inline elements
-				appendChildren(node.childNodes);
-				break;
-			}
-		}
-	}
-}
diff --git a/packages/backend/src/mfm/to-html.ts b/packages/backend/src/mfm/to-html.ts
deleted file mode 100644
index 8d8a4a8889..0000000000
--- a/packages/backend/src/mfm/to-html.ts
+++ /dev/null
@@ -1,174 +0,0 @@
-import { JSDOM } from "jsdom";
-import type * as mfm from "mfm-js";
-import config from "@/config/index.js";
-import { intersperse } from "@/prelude/array.js";
-import type { IMentionedRemoteUsers } from "@/models/entities/note.js";
-
-export function toHtml(
-	nodes: mfm.MfmNode[] | null,
-	mentionedRemoteUsers: IMentionedRemoteUsers = [],
-) {
-	if (nodes == null) {
-		return null;
-	}
-
-	const { window } = new JSDOM("");
-
-	const doc = window.document;
-
-	function appendChildren(children: mfm.MfmNode[], targetElement: any): void {
-		if (children) {
-			for (const child of children.map((x) => (handlers as any)[x.type](x)))
-				targetElement.appendChild(child);
-		}
-	}
-
-	const handlers: {
-		[K in mfm.MfmNode["type"]]: (node: mfm.NodeType<K>) => any;
-	} = {
-		bold(node) {
-			const el = doc.createElement("b");
-			appendChildren(node.children, el);
-			return el;
-		},
-
-		small(node) {
-			const el = doc.createElement("small");
-			appendChildren(node.children, el);
-			return el;
-		},
-
-		strike(node) {
-			const el = doc.createElement("del");
-			appendChildren(node.children, el);
-			return el;
-		},
-
-		italic(node) {
-			const el = doc.createElement("i");
-			appendChildren(node.children, el);
-			return el;
-		},
-
-		fn(node) {
-			const el = doc.createElement("i");
-			appendChildren(node.children, el);
-			return el;
-		},
-
-		blockCode(node) {
-			const pre = doc.createElement("pre");
-			const inner = doc.createElement("code");
-			inner.textContent = node.props.code;
-			pre.appendChild(inner);
-			return pre;
-		},
-
-		center(node) {
-			const el = doc.createElement("div");
-			appendChildren(node.children, el);
-			return el;
-		},
-
-		emojiCode(node) {
-			return doc.createTextNode(`\u200B:${node.props.name}:\u200B`);
-		},
-
-		unicodeEmoji(node) {
-			return doc.createTextNode(node.props.emoji);
-		},
-
-		hashtag(node) {
-			const a = doc.createElement("a");
-			a.href = `${config.url}/tags/${node.props.hashtag}`;
-			a.textContent = `#${node.props.hashtag}`;
-			a.setAttribute("rel", "tag");
-			return a;
-		},
-
-		inlineCode(node) {
-			const el = doc.createElement("code");
-			el.textContent = node.props.code;
-			return el;
-		},
-
-		mathInline(node) {
-			const el = doc.createElement("code");
-			el.textContent = node.props.formula;
-			return el;
-		},
-
-		mathBlock(node) {
-			const el = doc.createElement("code");
-			el.textContent = node.props.formula;
-			return el;
-		},
-
-		link(node) {
-			const a = doc.createElement("a");
-			a.href = node.props.url;
-			appendChildren(node.children, a);
-			return a;
-		},
-
-		mention(node) {
-			const a = doc.createElement("a");
-			const { username, host, acct } = node.props;
-			const remoteUserInfo = mentionedRemoteUsers.find(
-				(remoteUser) =>
-					remoteUser.username === username && remoteUser.host === host,
-			);
-			a.href = remoteUserInfo
-				? remoteUserInfo.url
-					? remoteUserInfo.url
-					: remoteUserInfo.uri
-				: `${config.url}/${acct}`;
-			a.className = "u-url mention";
-			a.textContent = acct;
-			return a;
-		},
-
-		quote(node) {
-			const el = doc.createElement("blockquote");
-			appendChildren(node.children, el);
-			return el;
-		},
-
-		text(node) {
-			const el = doc.createElement("span");
-			const nodes = node.props.text
-				.split(/\r\n|\r|\n/)
-				.map((x) => doc.createTextNode(x));
-
-			for (const x of intersperse<FIXME | "br">("br", nodes)) {
-				el.appendChild(x === "br" ? doc.createElement("br") : x);
-			}
-
-			return el;
-		},
-
-		url(node) {
-			const a = doc.createElement("a");
-			a.href = node.props.url;
-			a.textContent = node.props.url;
-			return a;
-		},
-
-		search(node) {
-			const a = doc.createElement("a");
-			a.href = `https://search.annoyingorange.xyz/search?q=${node.props.query}`;
-			a.textContent = node.props.content;
-			return a;
-		},
-
-		plain(node) {
-			const el = doc.createElement("span");
-			appendChildren(node.children, el);
-			return el;
-		},
-	};
-
-	appendChildren(nodes, doc.body);
-
-	return `<p>${doc.body.innerHTML}</p>`;
-}
diff --git a/packages/backend/src/misc/acct.ts b/packages/backend/src/misc/acct.ts
deleted file mode 100644
index 5b7767a106..0000000000
--- a/packages/backend/src/misc/acct.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-export type Acct = {
-	username: string;
-	host: string | null;
-};
-
-export function parse(acct: string): Acct {
-	if (acct.startsWith("@")) acct = acct.substr(1);
-	const split = acct.split("@", 2);
-	return { username: split[0], host: split[1] || null };
-}
-
-export function toString(acct: Acct): string {
-	return acct.host == null ? acct.username : `${acct.username}@${acct.host}`;
-}
diff --git a/packages/backend/src/misc/antenna-cache.ts b/packages/backend/src/misc/antenna-cache.ts
deleted file mode 100644
index 7f199c3967..0000000000
--- a/packages/backend/src/misc/antenna-cache.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import { Antennas } from "@/models/index.js";
-import type { Antenna } from "@/models/entities/antenna.js";
-import { subscriber } from "@/db/redis.js";
-
-let antennasFetched = false;
-let antennas: Antenna[] = [];
-
-export async function getAntennas() {
-	if (!antennasFetched) {
-		antennas = await Antennas.find();
-		antennasFetched = true;
-	}
-
-	return antennas;
-}
-
-subscriber.on("message", async (_, data) => {
-	const obj = JSON.parse(data);
-
-	if (obj.channel === "internal") {
-		const { type, body } = obj.message;
-		switch (type) {
-			case "antennaCreated":
-				antennas.push(body);
-				break;
-			case "antennaUpdated":
-				antennas[antennas.findIndex((a) => a.id === body.id)] = body;
-				break;
-			case "antennaDeleted":
-				antennas = antennas.filter((a) => a.id !== body.id);
-				break;
-			default:
-				break;
-		}
-	}
-});
diff --git a/packages/backend/src/misc/api-permissions.ts b/packages/backend/src/misc/api-permissions.ts
deleted file mode 100644
index 9e040262f1..0000000000
--- a/packages/backend/src/misc/api-permissions.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-export const kinds = [
-	"read:account",
-	"write:account",
-	"read:blocks",
-	"write:blocks",
-	"read:drive",
-	"write:drive",
-	"read:favorites",
-	"write:favorites",
-	"read:following",
-	"write:following",
-	"read:messaging",
-	"write:messaging",
-	"read:mutes",
-	"write:mutes",
-	"write:notes",
-	"read:notifications",
-	"write:notifications",
-	"read:reactions",
-	"write:reactions",
-	"write:votes",
-	"read:pages",
-	"write:pages",
-	"write:page-likes",
-	"read:page-likes",
-	"read:user-groups",
-	"write:user-groups",
-	"read:channels",
-	"write:channels",
-	"read:gallery",
-	"write:gallery",
-	"read:gallery-likes",
-	"write:gallery-likes",
-];
-// IF YOU ADD KINDS(PERMISSIONS), YOU MUST ADD TRANSLATIONS (under _permissions).
diff --git a/packages/backend/src/misc/app-lock.ts b/packages/backend/src/misc/app-lock.ts
deleted file mode 100644
index 05bcf54244..0000000000
--- a/packages/backend/src/misc/app-lock.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import { redisClient } from "../db/redis.js";
-import { promisify } from "node:util";
-import redisLock from "redis-lock";
-
-/**
- * Retry delay (ms) for lock acquisition
- */
-const retryDelay = 100;
-
-const lock: (key: string, timeout?: number) => Promise<() => void> = redisClient
-	? promisify(redisLock(redisClient, retryDelay))
-	: async () => () => {};
-
-/**
- * Get AP Object lock
- * @param uri AP object ID
- * @param timeout Lock timeout (ms), The timeout releases previous lock.
- * @returns Unlock function
- */
-export function getApLock(uri: string, timeout = 30 * 1000) {
-	return lock(`ap-object:${uri}`, timeout);
-}
-
-export function getFetchInstanceMetadataLock(
-	host: string,
-	timeout = 30 * 1000,
-) {
-	return lock(`instance:${host}`, timeout);
-}
-
-export function getChartInsertLock(lockKey: string, timeout = 30 * 1000) {
-	return lock(`chart-insert:${lockKey}`, timeout);
-}
diff --git a/packages/backend/src/misc/before-shutdown.ts b/packages/backend/src/misc/before-shutdown.ts
deleted file mode 100644
index 0820418356..0000000000
--- a/packages/backend/src/misc/before-shutdown.ts
+++ /dev/null
@@ -1,103 +0,0 @@
-// https://gist.github.com/nfantone/1eaa803772025df69d07f4dbf5df7e58
-
-"use strict";
-
-/**
- * @callback BeforeShutdownListener
- * @param {string} [signalOrEvent] The exit signal or event name received on the process.
- */
-
-/**
- * System signals the app will listen to initiate shutdown.
- * @const {string[]}
- */
-const SHUTDOWN_SIGNALS = ["SIGINT", "SIGTERM"];
-
-/**
- * Time in milliseconds to wait before forcing shutdown.
- * @const {number}
- */
-const SHUTDOWN_TIMEOUT = 15000;
-
-/**
- * A queue of listener callbacks to execute before shutting
- * down the process.
- * @type {BeforeShutdownListener[]}
- */
-const shutdownListeners: ((signalOrEvent: string) => void)[] = [];
-
-/**
- * Listen for signals and execute given `fn` function once.
- * @param  {string[]} signals System signals to listen to.
- * @param  {function(string)} fn Function to execute on shutdown.
- */
-const processOnce = (
-	signals: string[],
-	fn: (signalOrEvent: string) => void,
-) => {
-	for (const sig of signals) {
-		process.once(sig, fn);
-	}
-};
-
-/**
- * Sets a forced shutdown mechanism that will exit the process after `timeout` milliseconds.
- * @param {number} timeout Time to wait before forcing shutdown (milliseconds)
- */
-const forceExitAfter = (timeout: number) => () => {
-	setTimeout(() => {
-		// Force shutdown after timeout
-		console.warn(
-			`Could not close resources gracefully after ${timeout}ms: forcing shutdown`,
-		);
-		return process.exit(1);
-	}, timeout).unref();
-};
-
-/**
- * Main process shutdown handler. Will invoke every previously registered async shutdown listener
- * in the queue and exit with a code of `0`. Any `Promise` rejections from any listener will
- * be logged out as a warning, but won't prevent other callbacks from executing.
- * @param {string} signalOrEvent The exit signal or event name received on the process.
- */
-async function shutdownHandler(signalOrEvent: string) {
-	if (process.env.NODE_ENV === "test") return process.exit(0);
-
-	console.warn(`Shutting down: received [${signalOrEvent}] signal`);
-
-	for (const listener of shutdownListeners) {
-		try {
-			await listener(signalOrEvent);
-		} catch (err) {
-			if (err instanceof Error) {
-				console.warn(
-					`A shutdown handler failed before completing with: ${
-						err.message || err
-					}`,
-				);
-			}
-		}
-	}
-
-	return process.exit(0);
-}
-
-/**
- * Registers a new shutdown listener to be invoked before exiting
- * the main process. Listener handlers are guaranteed to be called in the order
- * they were registered.
- * @param {BeforeShutdownListener} listener The shutdown listener to register.
- * @returns {BeforeShutdownListener} Echoes back the supplied `listener`.
- */
-export function beforeShutdown(listener: () => void) {
-	shutdownListeners.push(listener);
-	return listener;
-}
-
-// Register shutdown callback that kills the process after `SHUTDOWN_TIMEOUT` milliseconds
-// This prevents custom shutdown handlers from hanging the process indefinitely
-processOnce(SHUTDOWN_SIGNALS, forceExitAfter(SHUTDOWN_TIMEOUT));
-
-// Register process shutdown callback
-// Will listen to incoming signal events and execute all registered handlers in the stack
-processOnce(SHUTDOWN_SIGNALS, shutdownHandler);
diff --git a/packages/backend/src/misc/cache.ts b/packages/backend/src/misc/cache.ts
deleted file mode 100644
index 9abebc91cb..0000000000
--- a/packages/backend/src/misc/cache.ts
+++ /dev/null
@@ -1,88 +0,0 @@
-export class Cache<T> {
-	public cache: Map<string | null, { date: number; value: T }>;
-	private lifetime: number;
-
-	constructor(lifetime: Cache<never>["lifetime"]) {
-		this.cache = new Map();
-		this.lifetime = lifetime;
-	}
-
-	public set(key: string | null, value: T): void {
-		this.cache.set(key, {
-			date: Date.now(),
-			value,
-		});
-	}
-
-	public get(key: string | null): T | undefined {
-		const cached = this.cache.get(key);
-		if (cached == null) return undefined;
-		if (Date.now() - cached.date > this.lifetime) {
-			this.cache.delete(key);
-			return undefined;
-		}
-		return cached.value;
-	}
-
-	public delete(key: string | null) {
-		this.cache.delete(key);
-	}
-
-	/**
-	 * キャッシュがあればそれを返し、無ければfetcherを呼び出して結果をキャッシュ&返します
-	 * optional: キャッシュが存在してもvalidatorでfalseを返すとキャッシュ無効扱いにします
-	 */
-	public async fetch(
-		key: string | null,
-		fetcher: () => Promise<T>,
-		validator?: (cachedValue: T) => boolean,
-	): Promise<T> {
-		const cachedValue = this.get(key);
-		if (cachedValue !== undefined) {
-			if (validator) {
-				if (validator(cachedValue)) {
-					// Cache HIT
-					return cachedValue;
-				}
-			} else {
-				// Cache HIT
-				return cachedValue;
-			}
-		}
-
-		// Cache MISS
-		const value = await fetcher();
-		this.set(key, value);
-		return value;
-	}
-
-	/**
-	 * キャッシュがあればそれを返し、無ければfetcherを呼び出して結果をキャッシュ&返します
-	 * optional: キャッシュが存在してもvalidatorでfalseを返すとキャッシュ無効扱いにします
-	 */
-	public async fetchMaybe(
-		key: string | null,
-		fetcher: () => Promise<T | undefined>,
-		validator?: (cachedValue: T) => boolean,
-	): Promise<T | undefined> {
-		const cachedValue = this.get(key);
-		if (cachedValue !== undefined) {
-			if (validator) {
-				if (validator(cachedValue)) {
-					// Cache HIT
-					return cachedValue;
-				}
-			} else {
-				// Cache HIT
-				return cachedValue;
-			}
-		}
-
-		// Cache MISS
-		const value = await fetcher();
-		if (value !== undefined) {
-			this.set(key, value);
-		}
-		return value;
-	}
-}
diff --git a/packages/backend/src/misc/captcha.ts b/packages/backend/src/misc/captcha.ts
deleted file mode 100644
index 8ea4abedb6..0000000000
--- a/packages/backend/src/misc/captcha.ts
+++ /dev/null
@@ -1,73 +0,0 @@
-import fetch from "node-fetch";
-import { URLSearchParams } from "node:url";
-import { getAgentByUrl } from "./fetch.js";
-import config from "@/config/index.js";
-
-export async function verifyRecaptcha(secret: string, response: string) {
-	const result = await getCaptchaResponse(
-		"https://www.recaptcha.net/recaptcha/api/siteverify",
-		secret,
-		response,
-	).catch((e) => {
-		throw new Error(`recaptcha-request-failed: ${e.message}`);
-	});
-
-	if (result.success !== true) {
-		const errorCodes = result["error-codes"]
-			? result["error-codes"]?.join(", ")
-			: "";
-		throw new Error(`recaptcha-failed: ${errorCodes}`);
-	}
-}
-
-export async function verifyHcaptcha(secret: string, response: string) {
-	const result = await getCaptchaResponse(
-		"https://hcaptcha.com/siteverify",
-		secret,
-		response,
-	).catch((e) => {
-		throw new Error(`hcaptcha-request-failed: ${e.message}`);
-	});
-
-	if (result.success !== true) {
-		const errorCodes = result["error-codes"]
-			? result["error-codes"]?.join(", ")
-			: "";
-		throw new Error(`hcaptcha-failed: ${errorCodes}`);
-	}
-}
-
-type CaptchaResponse = {
-	success: boolean;
-	"error-codes"?: string[];
-};
-
-async function getCaptchaResponse(
-	url: string,
-	secret: string,
-	response: string,
-): Promise<CaptchaResponse> {
-	const params = new URLSearchParams({
-		secret,
-		response,
-	});
-
-	const res = await fetch(url, {
-		method: "POST",
-		body: params,
-		headers: {
-			"User-Agent": config.userAgent,
-		},
-		// TODO
-		//timeout: 10 * 1000,
-		agent: getAgentByUrl,
-	}).catch((e) => {
-		throw new Error(`${e.message || e}`);
-	});
-
-	if (!res.ok) {
-		throw new Error(`${res.status}`);
-	}
-
-	return (await res.json()) as CaptchaResponse;
-}
diff --git a/packages/backend/src/misc/check-hit-antenna.ts b/packages/backend/src/misc/check-hit-antenna.ts
deleted file mode 100644
index adcdd190f8..0000000000
--- a/packages/backend/src/misc/check-hit-antenna.ts
+++ /dev/null
@@ -1,137 +0,0 @@
-import type { Antenna } from "@/models/entities/antenna.js";
-import type { Note } from "@/models/entities/note.js";
-import type { User } from "@/models/entities/user.js";
-import {
-	UserListJoinings,
-	UserGroupJoinings,
-	Blockings,
-} from "@/models/index.js";
-import { getFullApAccount } from "./convert-host.js";
-import * as Acct from "@/misc/acct.js";
-import type { Packed } from "./schema.js";
-import { Cache } from "./cache.js";
-
-const blockingCache = new Cache<User["id"][]>(1000 * 60 * 5);
-
-// NOTE: フォローしているユーザーのノート、リストのユーザーのノート、グループのユーザーのノート指定はパフォーマンス上の理由で無効になっている
-
-/**
- * noteUserFollowers / antennaUserFollowing はどちらか一方が指定されていればよい
- */
-export async function checkHitAntenna(
-	antenna: Antenna,
-	note: Note | Packed<"Note">,
-	noteUser: { id: User["id"]; username: string; host: string | null },
-	noteUserFollowers?: User["id"][],
-	antennaUserFollowing?: User["id"][],
-): Promise<boolean> {
-	if (note.visibility === "specified") return false;
-
-	// アンテナ作成者がノート作成者にブロックされていたらスキップ
-	const blockings = await blockingCache.fetch(noteUser.id, () =>
-		Blockings.findBy({ blockerId: noteUser.id }).then((res) =>
-			res.map((x) => x.blockeeId),
-		),
-	);
-	if (blockings.some((blocking) => blocking === antenna.userId)) return false;
-
-	if (note.visibility === "followers") {
-		if (noteUserFollowers && !noteUserFollowers.includes(antenna.userId))
-			return false;
-		if (antennaUserFollowing && !antennaUserFollowing.includes(note.userId))
-			return false;
-	}
-
-	if (!antenna.withReplies && note.replyId != null) return false;
-
-	if (antenna.src === "home") {
-		if (noteUserFollowers && !noteUserFollowers.includes(antenna.userId))
-			return false;
-		if (antennaUserFollowing && !antennaUserFollowing.includes(note.userId))
-			return false;
-	} else if (antenna.src === "list") {
-		const listUsers = (
-			await UserListJoinings.findBy({
-				userListId: antenna.userListId!,
-			})
-		).map((x) => x.userId);
-
-		if (!listUsers.includes(note.userId)) return false;
-	} else if (antenna.src === "group") {
-		const joining = await UserGroupJoinings.findOneByOrFail({
-			id: antenna.userGroupJoiningId!,
-		});
-
-		const groupUsers = (
-			await UserGroupJoinings.findBy({
-				userGroupId: joining.userGroupId,
-			})
-		).map((x) => x.userId);
-
-		if (!groupUsers.includes(note.userId)) return false;
-	} else if (antenna.src === "users") {
-		const accts = antenna.users.map((x) => {
-			const { username, host } = Acct.parse(x);
-			return getFullApAccount(username, host).toLowerCase();
-		});
-		if (
-			!accts.includes(
-				getFullApAccount(noteUser.username, noteUser.host).toLowerCase(),
-			)
-		)
-			return false;
-	} else if (antenna.src === "instances") {
-		const instances = antenna.instances
-			.filter((x) => x !== "")
-			.map((host) => {
-				return host.toLowerCase();
-			});
-		if (!instances.includes(noteUser.host?.toLowerCase() ?? "")) return false;
-	}
-
-	const keywords = antenna.keywords
-		// Clean up
-		.map((xs) => xs.filter((x) => x !== ""))
-		.filter((xs) => xs.length > 0);
-
-	if (keywords.length > 0) {
-		if (note.text == null) return false;
-
-		const matched = keywords.some((and) =>
-			and.every((keyword) =>
-				antenna.caseSensitive
-					? note.text!.includes(keyword)
-					: note.text!.toLowerCase().includes(keyword.toLowerCase()),
-			),
-		);
-
-		if (!matched) return false;
-	}
-
-	const excludeKeywords = antenna.excludeKeywords
-		// Clean up
-		.map((xs) => xs.filter((x) => x !== ""))
-		.filter((xs) => xs.length > 0);
-
-	if (excludeKeywords.length > 0) {
-		if (note.text == null) return false;
-
-		const matched = excludeKeywords.some((and) =>
-			and.every((keyword) =>
-				antenna.caseSensitive
-					? note.text!.includes(keyword)
-					: note.text!.toLowerCase().includes(keyword.toLowerCase()),
-			),
-		);
-
-		if (matched) return false;
-	}
-
-	if (antenna.withFile) {
-		if (note.fileIds && note.fileIds.length === 0) return false;
-	}
-
-	// TODO: eval expression
-
-	return true;
-}
diff --git a/packages/backend/src/misc/check-word-mute.ts b/packages/backend/src/misc/check-word-mute.ts
deleted file mode 100644
index 53193d851a..0000000000
--- a/packages/backend/src/misc/check-word-mute.ts
+++ /dev/null
@@ -1,78 +0,0 @@
-import RE2 from "re2";
-import type { Note } from "@/models/entities/note.js";
-import type { User } from "@/models/entities/user.js";
-
-type NoteLike = {
-	userId: Note["userId"];
-	text: Note["text"];
-	cw?: Note["cw"];
-};
-
-type UserLike = {
-	id: User["id"];
-};
-
-export type Muted = {
-	muted: boolean;
-	matched: string[];
-};
-
-const NotMuted = { muted: false, matched: [] };
-
-function escapeRegExp(x: string) {
-	return x.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
-}
-
-export async function getWordMute(
-	note: NoteLike,
-	me: UserLike | null | undefined,
-	mutedWords: Array<string | string[]>,
-): Promise<Muted> {
-	// 自分自身
-	if (me && note.userId === me.id) {
-		return NotMuted;
-	}
-
-	if (mutedWords.length > 0) {
-		const text = ((note.cw ?? "") + "\n" + (note.text ?? "")).trim();
-
-		if (text === "") {
-			return NotMuted;
-		}
-
-		for (const mutePattern of mutedWords) {
-			let mute: RE2;
-			let matched: string[];
-			if (Array.isArray(mutePattern)) {
-				matched = mutePattern.filter((keyword) => keyword !== "");
-
-				if (matched.length === 0) {
-					continue;
-				}
-				mute = new RE2(
-					`\\b${matched.map(escapeRegExp).join("\\b.*\\b")}\\b`,
-					"g",
-				);
-			} else {
-				const regexp = mutePattern.match(/^\/(.+)\/(.*)$/);
-				// This should never happen due to input sanitisation.
-				if (!regexp) {
-					console.warn(`Found invalid regex in word mutes: ${mutePattern}`);
-					continue;
-				}
-				mute = new RE2(regexp[1], regexp[2]);
-				matched = [mutePattern];
-			}
-
-			try {
-				if (mute.test(text)) {
-					return { muted: true, matched };
-				}
-			} catch (err) {
-				// This should never happen due to input sanitisation.
-			}
-		}
-	}
-
-	return NotMuted;
-}
diff --git a/packages/backend/src/misc/clone.ts b/packages/backend/src/misc/clone.ts
deleted file mode 100644
index 4322e2e28f..0000000000
--- a/packages/backend/src/misc/clone.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-// structredCloneが遅いため
-// SEE: http://var.blog.jp/archives/86038606.html
-
-type Cloneable =
-	| string
-	| number
-	| boolean
-	| null
-	| { [key: string]: Cloneable }
-	| Cloneable[];
-
-export function deepClone<T extends Cloneable>(x: T): T {
-	if (typeof x === "object") {
-		if (x === null) return x;
-		if (Array.isArray(x)) return x.map(deepClone) as T;
-		const obj = {} as Record<string, Cloneable>;
-		for (const [k, v] of Object.entries(x)) {
-			obj[k] = deepClone(v);
-		}
-		return obj as T;
-	} else {
-		return x;
-	}
-}
diff --git a/packages/backend/src/misc/content-disposition.ts b/packages/backend/src/misc/content-disposition.ts
deleted file mode 100644
index 25d6f58177..0000000000
--- a/packages/backend/src/misc/content-disposition.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import cd from "content-disposition";
-
-export function contentDisposition(
-	type: "inline" | "attachment",
-	filename: string,
-): string {
-	const fallback = filename.replace(/[^\w.-]/g, "_");
-	return cd(filename, { type, fallback });
-}
diff --git a/packages/backend/src/misc/convert-host.ts b/packages/backend/src/misc/convert-host.ts
deleted file mode 100644
index 856ce3c127..0000000000
--- a/packages/backend/src/misc/convert-host.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import { URL } from "node:url";
-import config from "@/config/index.js";
-import { toASCII } from "punycode";
-
-export function getFullApAccount(username: string, host: string | null) {
-	return host
-		? `${username}@${toPuny(host)}`
-		: `${username}@${toPuny(config.host)}`;
-}
-
-export function isSelfHost(host: string) {
-	if (host == null) return true;
-	return toPuny(config.host) === toPuny(host);
-}
-
-export function extractDbHost(uri: string) {
-	const url = new URL(uri);
-	return toPuny(url.hostname);
-}
-
-export function toPuny(host: string) {
-	return toASCII(host.toLowerCase());
-}
-
-export function toPunyNullable(host: string | null | undefined): string | null {
-	if (host == null) return null;
-	return toASCII(host.toLowerCase());
-}
diff --git a/packages/backend/src/misc/count-same-renotes.ts b/packages/backend/src/misc/count-same-renotes.ts
deleted file mode 100644
index 45a6c1d35a..0000000000
--- a/packages/backend/src/misc/count-same-renotes.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import { Notes } from "@/models/index.js";
-
-export async function countSameRenotes(
-	userId: string,
-	renoteId: string,
-	excludeNoteId: string | undefined,
-): Promise<number> {
-	// 指定したユーザーの指定したノートのリノートがいくつあるか数える
-	const query = Notes.createQueryBuilder("note")
-		.where("note.userId = :userId", { userId })
-		.andWhere("note.renoteId = :renoteId", { renoteId });
-
-	// 指定した投稿を除く
-	if (excludeNoteId) {
-		query.andWhere("note.id != :excludeNoteId", { excludeNoteId });
-	}
-
-	return await query.getCount();
-}
diff --git a/packages/backend/src/misc/create-temp.ts b/packages/backend/src/misc/create-temp.ts
deleted file mode 100644
index 16c85ee7bd..0000000000
--- a/packages/backend/src/misc/create-temp.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import * as tmp from "tmp";
-
-export function createTemp(): Promise<[string, () => void]> {
-	return new Promise<[string, () => void]>((res, rej) => {
-		tmp.file((e, path, fd, cleanup) => {
-			if (e) return rej(e);
-			res([path, cleanup]);
-		});
-	});
-}
-
-export function createTempDir(): Promise<[string, () => void]> {
-	return new Promise<[string, () => void]>((res, rej) => {
-		tmp.dir(
-			{
-				unsafeCleanup: true,
-			},
-			(e, path, cleanup) => {
-				if (e) return rej(e);
-				res([path, cleanup]);
-			},
-		);
-	});
-}
diff --git a/packages/backend/src/misc/detect-url-mime.ts b/packages/backend/src/misc/detect-url-mime.ts
deleted file mode 100644
index 9f0e4325d9..0000000000
--- a/packages/backend/src/misc/detect-url-mime.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { createTemp } from "./create-temp.js";
-import { downloadUrl } from "./download-url.js";
-import { detectType } from "./get-file-info.js";
-
-export async function detectUrlMime(url: string) {
-	const [path, cleanup] = await createTemp();
-
-	try {
-		await downloadUrl(url, path);
-		const { mime } = await detectType(path);
-		return mime;
-	} finally {
-		cleanup();
-	}
-}
diff --git a/packages/backend/src/misc/download-text-file.ts b/packages/backend/src/misc/download-text-file.ts
deleted file mode 100644
index 9d3821b20f..0000000000
--- a/packages/backend/src/misc/download-text-file.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import * as fs from "node:fs";
-import * as util from "node:util";
-import Logger from "@/services/logger.js";
-import { createTemp } from "./create-temp.js";
-import { downloadUrl } from "./download-url.js";
-
-const logger = new Logger("download-text-file");
-
-export async function downloadTextFile(url: string): Promise<string> {
-	// Create temp file
-	const [path, cleanup] = await createTemp();
-
-	logger.info(`Temp file is ${path}`);
-
-	try {
-		// write content at URL to temp file
-		await downloadUrl(url, path);
-
-		const text = await util.promisify(fs.readFile)(path, "utf8");
-
-		return text;
-	} finally {
-		cleanup();
-	}
-}
diff --git a/packages/backend/src/misc/download-url.ts b/packages/backend/src/misc/download-url.ts
deleted file mode 100644
index 7fafb635ba..0000000000
--- a/packages/backend/src/misc/download-url.ts
+++ /dev/null
@@ -1,103 +0,0 @@
-import * as fs from "node:fs";
-import * as stream from "node:stream";
-import * as util from "node:util";
-import got, * as Got from "got";
-import { httpAgent, httpsAgent, StatusError } from "./fetch.js";
-import config from "@/config/index.js";
-import chalk from "chalk";
-import Logger from "@/services/logger.js";
-import IPCIDR from "ip-cidr";
-import PrivateIp from "private-ip";
-
-const pipeline = util.promisify(stream.pipeline);
-
-export async function downloadUrl(url: string, path: string): Promise<void> {
-	const logger = new Logger("download");
-
-	logger.info(`Downloading ${chalk.cyan(url)} ...`);
-
-	const timeout = 30 * 1000;
-	const operationTimeout = 60 * 1000;
-	const maxSize = config.maxFileSize || 262144000;
-
-	const req = got
-		.stream(url, {
-			headers: {
-				"User-Agent": config.userAgent,
-			},
-			timeout: {
-				lookup: timeout,
-				connect: timeout,
-				secureConnect: timeout,
-				socket: timeout, // read timeout
-				response: timeout,
-				send: timeout,
-				request: operationTimeout, // whole operation timeout
-			},
-			agent: {
-				http: httpAgent,
-				https: httpsAgent,
-			},
-			http2: false, // default
-			retry: {
-				limit: 0,
-			},
-		})
-		.on("response", (res: Got.Response) => {
-			if (
-				(process.env.NODE_ENV === "production" ||
-					process.env.NODE_ENV === "test") &&
-				!config.proxy &&
-				res.ip
-			) {
-				if (isPrivateIp(res.ip)) {
-					logger.warn(`Blocked address: ${res.ip}`);
-					req.destroy();
-				}
-			}
-
-			const contentLength = res.headers["content-length"];
-			if (contentLength != null) {
-				const size = Number(contentLength);
-				if (size > maxSize) {
-					logger.warn(`maxSize exceeded (${size} > ${maxSize}) on response`);
-					req.destroy();
-				}
-			}
-		})
-		.on("downloadProgress", (progress: Got.Progress) => {
-			if (progress.transferred > maxSize) {
-				logger.warn(
-					`maxSize exceeded (${progress.transferred} > ${maxSize}) on downloadProgress`,
-				);
-				req.destroy();
-			}
-		});
-
-	try {
-		await pipeline(req, fs.createWriteStream(path));
-	} catch (e) {
-		if (e instanceof Got.HTTPError) {
-			throw new StatusError(
-				`${e.response.statusCode} ${e.response.statusMessage}`,
-				e.response.statusCode,
-				e.response.statusMessage,
-			);
-		} else {
-			throw e;
-		}
-	}
-
-	logger.succ(`Download finished: ${chalk.cyan(url)}`);
-}
-
-function isPrivateIp(ip: string): boolean {
-	for (const net of config.allowedPrivateNetworks || []) {
-		const cidr = new IPCIDR(net);
-		if (cidr.contains(ip)) {
-			return false;
-		}
-	}
-
-	return PrivateIp(ip);
-}
diff --git a/packages/backend/src/misc/emoji-regex.ts b/packages/backend/src/misc/emoji-regex.ts
deleted file mode 100644
index 08b44788de..0000000000
--- a/packages/backend/src/misc/emoji-regex.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import twemoji from "twemoji-parser/dist/lib/regex.js";
-const twemojiRegex = twemoji.default;
-
-export const emojiRegex = new RegExp(`(${twemojiRegex.source})`);
-export const emojiRegexAtStartToEnd = new RegExp(`^(${twemojiRegex.source})$`);
diff --git a/packages/backend/src/misc/extract-custom-emojis-from-mfm.ts b/packages/backend/src/misc/extract-custom-emojis-from-mfm.ts
deleted file mode 100644
index 7de32e6d60..0000000000
--- a/packages/backend/src/misc/extract-custom-emojis-from-mfm.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import * as mfm from "mfm-js";
-import { unique } from "@/prelude/array.js";
-
-export function extractCustomEmojisFromMfm(nodes: mfm.MfmNode[]): string[] {
-	const emojiNodes = mfm.extract(nodes, (node) => {
-		return node.type === "emojiCode" && node.props.name.length <= 100;
-	});
-
-	return unique(emojiNodes.map((x) => x.props.name));
-}
diff --git a/packages/backend/src/misc/extract-hashtags.ts b/packages/backend/src/misc/extract-hashtags.ts
deleted file mode 100644
index 826e36221b..0000000000
--- a/packages/backend/src/misc/extract-hashtags.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import * as mfm from "mfm-js";
-import { unique } from "@/prelude/array.js";
-
-export function extractHashtags(nodes: mfm.MfmNode[]): string[] {
-	const hashtagNodes = mfm.extract(nodes, (node) => node.type === "hashtag");
-	const hashtags = unique(hashtagNodes.map((x) => x.props.hashtag));
-
-	return hashtags;
-}
diff --git a/packages/backend/src/misc/extract-mentions.ts b/packages/backend/src/misc/extract-mentions.ts
deleted file mode 100644
index 259f78e576..0000000000
--- a/packages/backend/src/misc/extract-mentions.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-// test is located in test/extract-mentions
-
-import * as mfm from "mfm-js";
-
-export function extractMentions(
-	nodes: mfm.MfmNode[],
-): mfm.MfmMention["props"][] {
-	// TODO: 重複を削除
-	const mentionNodes = mfm.extract(nodes, (node) => node.type === "mention");
-	const mentions = mentionNodes.map((x) => x.props);
-
-	return mentions;
-}
diff --git a/packages/backend/src/misc/fetch-meta.ts b/packages/backend/src/misc/fetch-meta.ts
deleted file mode 100644
index 32c45813ca..0000000000
--- a/packages/backend/src/misc/fetch-meta.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import { db } from "@/db/postgre.js";
-import { Meta } from "@/models/entities/meta.js";
-
-let cache: Meta;
-
-export async function fetchMeta(noCache = false): Promise<Meta> {
-	if (!noCache && cache) return cache;
-
-	return await db.transaction(async (transactionalEntityManager) => {
-		// New IDs are prioritized because multiple records may have been created due to past bugs.
-		const metas = await transactionalEntityManager.find(Meta, {
-			order: {
-				id: "DESC",
-			},
-		});
-
-		const meta = metas[0];
-
-		if (meta) {
-			cache = meta;
-			return meta;
-		} else {
-			// If fetchMeta is called at the same time when meta is empty, this part may be called at the same time, so use fail-safe upsert.
-			const saved = await transactionalEntityManager
-				.upsert(
-					Meta,
-					{
-						id: "x",
-					},
-					["id"],
-				)
-				.then((x) =>
-					transactionalEntityManager.findOneByOrFail(Meta, x.identifiers[0]),
-				);
-
-			cache = saved;
-			return saved;
-		}
-	});
-}
-
-setInterval(() => {
-	fetchMeta(true).then((meta) => {
-		cache = meta;
-	});
-}, 1000 * 10);
diff --git a/packages/backend/src/misc/fetch-proxy-account.ts b/packages/backend/src/misc/fetch-proxy-account.ts
deleted file mode 100644
index a277db6fb9..0000000000
--- a/packages/backend/src/misc/fetch-proxy-account.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import { fetchMeta } from "./fetch-meta.js";
-import type { ILocalUser } from "@/models/entities/user.js";
-import { Users } from "@/models/index.js";
-
-export async function fetchProxyAccount(): Promise<ILocalUser | null> {
-	const meta = await fetchMeta();
-	if (meta.proxyAccountId == null) return null;
-	return (await Users.findOneByOrFail({
-		id: meta.proxyAccountId,
-	})) as ILocalUser;
-}
diff --git a/packages/backend/src/misc/fetch.ts b/packages/backend/src/misc/fetch.ts
deleted file mode 100644
index 0e673ba3a8..0000000000
--- a/packages/backend/src/misc/fetch.ts
+++ /dev/null
@@ -1,171 +0,0 @@
-import * as http from "node:http";
-import * as https from "node:https";
-import type { URL } from "node:url";
-import CacheableLookup from "cacheable-lookup";
-import fetch from "node-fetch";
-import { HttpProxyAgent, HttpsProxyAgent } from "hpagent";
-import config from "@/config/index.js";
-
-export async function getJson(
-	url: string,
-	accept = "application/json, */*",
-	timeout = 10000,
-	headers?: Record<string, string>,
-) {
-	const res = await getResponse({
-		url,
-		method: "GET",
-		headers: Object.assign(
-			{
-				"User-Agent": config.userAgent,
-				Accept: accept,
-			},
-			headers || {},
-		),
-		timeout,
-	});
-
-	return await res.json();
-}
-
-export async function getHtml(
-	url: string,
-	accept = "text/html, */*",
-	timeout = 10000,
-	headers?: Record<string, string>,
-) {
-	const res = await getResponse({
-		url,
-		method: "GET",
-		headers: Object.assign(
-			{
-				"User-Agent": config.userAgent,
-				Accept: accept,
-			},
-			headers || {},
-		),
-		timeout,
-	});
-
-	return await res.text();
-}
-
-export async function getResponse(args: {
-	url: string;
-	method: string;
-	body?: string;
-	headers: Record<string, string>;
-	timeout?: number;
-	size?: number;
-}) {
-	const timeout = args.timeout || 10 * 1000;
-
-	const controller = new AbortController();
-	setTimeout(() => {
-		controller.abort();
-	}, timeout * 6);
-
-	const res = await fetch(args.url, {
-		method: args.method,
-		headers: args.headers,
-		body: args.body,
-		timeout,
-		size: args.size || 10 * 1024 * 1024,
-		agent: getAgentByUrl,
-		signal: controller.signal,
-	});
-
-	if (!res.ok) {
-		throw new StatusError(
-			`${res.status} ${res.statusText}`,
-			res.status,
-			res.statusText,
-		);
-	}
-
-	return res;
-}
-
-const cache = new CacheableLookup({
-	maxTtl: 3600, // 1hours
-	errorTtl: 30, // 30secs
-	lookup: false, // nativeのdns.lookupにfallbackしない
-});
-
-/**
- * Get http non-proxy agent
- */
-const _http = new http.Agent({
-	keepAlive: true,
-	keepAliveMsecs: 30 * 1000,
-	lookup: cache.lookup,
-} as http.AgentOptions);
-
-/**
- * Get https non-proxy agent
- */
-const _https = new https.Agent({
-	keepAlive: true,
-	keepAliveMsecs: 30 * 1000,
-	lookup: cache.lookup,
-} as https.AgentOptions);
-
-const maxSockets = Math.max(256, config.deliverJobConcurrency || 128);
-
-/**
- * Get http proxy or non-proxy agent
- */
-export const httpAgent = config.proxy
-	? new HttpProxyAgent({
-			keepAlive: true,
-			keepAliveMsecs: 30 * 1000,
-			maxSockets,
-			maxFreeSockets: 256,
-			scheduling: "lifo",
-			proxy: config.proxy,
-	  })
-	: _http;
-
-/**
- * Get https proxy or non-proxy agent
- */
-export const httpsAgent = config.proxy
-	? new HttpsProxyAgent({
-			keepAlive: true,
-			keepAliveMsecs: 30 * 1000,
-			maxSockets,
-			maxFreeSockets: 256,
-			scheduling: "lifo",
-			proxy: config.proxy,
-	  })
-	: _https;
-
-/**
- * Get agent by URL
- * @param url URL
- * @param bypassProxy Allways bypass proxy
- */
-export function getAgentByUrl(url: URL, bypassProxy = false) {
-	if (bypassProxy || (config.proxyBypassHosts || []).includes(url.hostname)) {
-		return url.protocol === "http:" ? _http : _https;
-	} else {
-		return url.protocol === "http:" ? httpAgent : httpsAgent;
-	}
-}
-
-export class StatusError extends Error {
-	public statusCode: number;
-	public statusMessage?: string;
-	public isClientError: boolean;
-
-	constructor(message: string, statusCode: number, statusMessage?: string) {
-		super(message);
-		this.name = "StatusError";
-		this.statusCode = statusCode;
-		this.statusMessage = statusMessage;
-		this.isClientError =
-			typeof this.statusCode === "number" &&
-			this.statusCode >= 400 &&
-			this.statusCode < 500;
-	}
-}
diff --git a/packages/backend/src/misc/gen-id.ts b/packages/backend/src/misc/gen-id.ts
deleted file mode 100644
index b7cc0965a1..0000000000
--- a/packages/backend/src/misc/gen-id.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import { ulid } from "ulid";
-import { genAid } from "./id/aid.js";
-import { genMeid } from "./id/meid.js";
-import { genMeidg } from "./id/meidg.js";
-import { genObjectId } from "./id/object-id.js";
-import config from "@/config/index.js";
-
-const metohd = config.id.toLowerCase();
-
-export function genId(date?: Date): string {
-	if (!date || date > new Date()) date = new Date();
-
-	switch (metohd) {
-		case "aid":
-			return genAid(date);
-		case "meid":
-			return genMeid(date);
-		case "meidg":
-			return genMeidg(date);
-		case "ulid":
-			return ulid(date.getTime());
-		case "objectid":
-			return genObjectId(date);
-		default:
-			throw new Error("unrecognized id generation method");
-	}
-}
diff --git a/packages/backend/src/misc/gen-identicon.ts b/packages/backend/src/misc/gen-identicon.ts
deleted file mode 100644
index 1e51dfe2ac..0000000000
--- a/packages/backend/src/misc/gen-identicon.ts
+++ /dev/null
@@ -1,114 +0,0 @@
-/**
- * Identicon generator
- * https://en.wikipedia.org/wiki/Identicon
- */
-
-import type { WriteStream } from "node:fs";
-import * as p from "pureimage";
-import gen from "random-seed";
-
-const size = 128; // px
-const n = 5; // resolution
-const margin = size / 4;
-const colors = [
-	["#eb6f92", "#b4637a"],
-	["#f6c177", "#ea9d34"],
-	["#ebbcba", "#d7827e"],
-	["#9ccfd8", "#56949f"],
-	["#c4a7e7", "#907aa9"],
-	["#eb6f92", "#f6c177"],
-	["#eb6f92", "#ebbcba"],
-	["#eb6f92", "#31748f"],
-	["#eb6f92", "#9ccfd8"],
-	["#eb6f92", "#c4a7e7"],
-	["#f6c177", "#eb6f92"],
-	["#f6c177", "#ebbcba"],
-	["#f6c177", "#31748f"],
-	["#f6c177", "#9ccfd8"],
-	["#f6c177", "#c4a7e7"],
-	["#ebbcba", "#eb6f92"],
-	["#ebbcba", "#f6c177"],
-	["#ebbcba", "#31748f"],
-	["#ebbcba", "#9ccfd8"],
-	["#ebbcba", "#c4a7e7"],
-	["#31748f", "#eb6f92"],
-	["#31748f", "#f6c177"],
-	["#31748f", "#ebbcba"],
-	["#31748f", "#9ccfd8"],
-	["#31748f", "#c4a7e7"],
-	["#9ccfd8", "#eb6f92"],
-	["#9ccfd8", "#f6c177"],
-	["#9ccfd8", "#ebbcba"],
-	["#9ccfd8", "#31748f"],
-	["#9ccfd8", "#c4a7e7"],
-	["#c4a7e7", "#eb6f92"],
-	["#c4a7e7", "#f6c177"],
-	["#c4a7e7", "#ebbcba"],
-	["#c4a7e7", "#31748f"],
-	["#c4a7e7", "#9ccfd8"],
-];
-
-const actualSize = size - margin * 2;
-const cellSize = actualSize / n;
-const sideN = Math.floor(n / 2);
-
-/**
- * Generate buffer of an identicon by seed
- */
-export function genIdenticon(seed: string, stream: WriteStream): Promise<void> {
-	const rand = gen.create(seed);
-	const canvas = p.make(size, size, undefined);
-	const ctx = canvas.getContext("2d");
-
-	const bgColors = colors[rand(colors.length)];
-
-	const bg = ctx.createLinearGradient(0, 0, size, size);
-	bg.addColorStop(0, bgColors[0]);
-	bg.addColorStop(1, bgColors[1]);
-
-	ctx.fillStyle = bg;
-	ctx.beginPath();
-	ctx.fillRect(0, 0, size, size);
-
-	ctx.fillStyle = "#ffffff";
-
-	// side bitmap (filled by false)
-	const side: boolean[][] = new Array(sideN);
-	for (let i = 0; i < side.length; i++) {
-		side[i] = new Array(n).fill(false);
-	}
-
-	// 1*n (filled by false)
-	const center: boolean[] = new Array(n).fill(false);
-
-	for (let x = 0; x < side.length; x++) {
-		for (let y = 0; y < side[x].length; y++) {
-			side[x][y] = rand(3) === 0;
-		}
-	}
-
-	for (let i = 0; i < center.length; i++) {
-		center[i] = rand(3) === 0;
-	}
-
-	// Draw
-	for (let x = 0; x < n; x++) {
-		for (let y = 0; y < n; y++) {
-			const isXCenter = x === (n - 1) / 2;
-			if (isXCenter && !center[y]) continue;
-
-			const isLeftSide = x < (n - 1) / 2;
-			if (isLeftSide && !side[x][y]) continue;
-
-			const isRightSide = x > (n - 1) / 2;
-			if (isRightSide && !side[sideN - (x - sideN)][y]) continue;
-
-			const actualX = margin + cellSize * x;
-			const actualY = margin + cellSize * y;
-			ctx.beginPath();
-			ctx.fillRect(actualX, actualY, cellSize, cellSize);
-		}
-	}
-
-	return p.encodePNGToStream(canvas, stream);
-}
diff --git a/packages/backend/src/misc/gen-key-pair.ts b/packages/backend/src/misc/gen-key-pair.ts
deleted file mode 100644
index 8ae4175e30..0000000000
--- a/packages/backend/src/misc/gen-key-pair.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import * as crypto from "node:crypto";
-import * as util from "node:util";
-
-const generateKeyPair = util.promisify(crypto.generateKeyPair);
-
-export async function genRsaKeyPair(modulusLength = 2048) {
-	return await generateKeyPair("rsa", {
-		modulusLength,
-		publicKeyEncoding: {
-			type: "spki",
-			format: "pem",
-		},
-		privateKeyEncoding: {
-			type: "pkcs8",
-			format: "pem",
-			cipher: undefined,
-			passphrase: undefined,
-		},
-	});
-}
-
-export async function genEcKeyPair(
-	namedCurve:
-		| "prime256v1"
-		| "secp384r1"
-		| "secp521r1"
-		| "curve25519" = "prime256v1",
-) {
-	return await generateKeyPair("ec", {
-		namedCurve,
-		publicKeyEncoding: {
-			type: "spki",
-			format: "pem",
-		},
-		privateKeyEncoding: {
-			type: "pkcs8",
-			format: "pem",
-			cipher: undefined,
-			passphrase: undefined,
-		},
-	});
-}
diff --git a/packages/backend/src/misc/get-file-info.ts b/packages/backend/src/misc/get-file-info.ts
deleted file mode 100644
index a63de286ea..0000000000
--- a/packages/backend/src/misc/get-file-info.ts
+++ /dev/null
@@ -1,443 +0,0 @@
-import * as fs from "node:fs";
-import * as crypto from "node:crypto";
-import { join } from "node:path";
-import * as stream from "node:stream";
-import * as util from "node:util";
-import { FSWatcher } from "chokidar";
-import { fileTypeFromFile } from "file-type";
-import FFmpeg from "fluent-ffmpeg";
-import isSvg from "is-svg";
-import probeImageSize from "probe-image-size";
-import { type predictionType } from "nsfwjs";
-import sharp from "sharp";
-import { encode } from "blurhash";
-import { detectSensitive } from "@/services/detect-sensitive.js";
-import { createTempDir } from "./create-temp.js";
-
-const pipeline = util.promisify(stream.pipeline);
-
-export type FileInfo = {
-	size: number;
-	md5: string;
-	type: {
-		mime: string;
-		ext: string | null;
-	};
-	width?: number;
-	height?: number;
-	orientation?: number;
-	blurhash?: string;
-	sensitive: boolean;
-	porn: boolean;
-	warnings: string[];
-};
-
-const TYPE_OCTET_STREAM = {
-	mime: "application/octet-stream",
-	ext: null,
-};
-
-const TYPE_SVG = {
-	mime: "image/svg+xml",
-	ext: "svg",
-};
-
-/**
- * Get file information
- */
-export async function getFileInfo(
-	path: string,
-	opts: {
-		skipSensitiveDetection: boolean;
-		sensitiveThreshold?: number;
-		sensitiveThresholdForPorn?: number;
-		enableSensitiveMediaDetectionForVideos?: boolean;
-	},
-): Promise<FileInfo> {
-	const warnings = [] as string[];
-
-	const size = await getFileSize(path);
-	const md5 = await calcHash(path);
-
-	let type = await detectType(path);
-
-	// image dimensions
-	let width: number | undefined;
-	let height: number | undefined;
-	let orientation: number | undefined;
-
-	if (
-		[
-			"image/jpeg",
-			"image/gif",
-			"image/png",
-			"image/apng",
-			"image/webp",
-			"image/bmp",
-			"image/tiff",
-			"image/svg+xml",
-			"image/vnd.adobe.photoshop",
-			"image/avif",
-		].includes(type.mime)
-	) {
-		const imageSize = await detectImageSize(path).catch((e) => {
-			warnings.push(`detectImageSize failed: ${e}`);
-			return undefined;
-		});
-
-		// うまく判定できない画像は octet-stream にする
-		if (!imageSize) {
-			warnings.push("cannot detect image dimensions");
-			type = TYPE_OCTET_STREAM;
-		} else if (imageSize.wUnits === "px") {
-			width = imageSize.width;
-			height = imageSize.height;
-			orientation = imageSize.orientation;
-
-			// 制限を超えている画像は octet-stream にする
-			if (imageSize.width > 16383 || imageSize.height > 16383) {
-				warnings.push("image dimensions exceeds limits");
-				type = TYPE_OCTET_STREAM;
-			}
-		} else {
-			warnings.push(`unsupported unit type: ${imageSize.wUnits}`);
-		}
-	}
-
-	let blurhash: string | undefined;
-
-	if (
-		[
-			"image/jpeg",
-			"image/gif",
-			"image/png",
-			"image/apng",
-			"image/webp",
-			"image/svg+xml",
-			"image/avif",
-		].includes(type.mime)
-	) {
-		blurhash = await getBlurhash(path).catch((e) => {
-			warnings.push(`getBlurhash failed: ${e}`);
-			return undefined;
-		});
-	}
-
-	let sensitive = false;
-	let porn = false;
-
-	if (!opts.skipSensitiveDetection) {
-		await detectSensitivity(
-			path,
-			type.mime,
-			opts.sensitiveThreshold ?? 0.5,
-			opts.sensitiveThresholdForPorn ?? 0.75,
-			opts.enableSensitiveMediaDetectionForVideos ?? false,
-		).then(
-			(value) => {
-				[sensitive, porn] = value;
-			},
-			(error) => {
-				warnings.push(`detectSensitivity failed: ${error}`);
-			},
-		);
-	}
-
-	return {
-		size,
-		md5,
-		type,
-		width,
-		height,
-		orientation,
-		blurhash,
-		sensitive,
-		porn,
-		warnings,
-	};
-}
-
-async function detectSensitivity(
-	source: string,
-	mime: string,
-	sensitiveThreshold: number,
-	sensitiveThresholdForPorn: number,
-	analyzeVideo: boolean,
-): Promise<[sensitive: boolean, porn: boolean]> {
-	let sensitive = false;
-	let porn = false;
-
-	function judgePrediction(
-		result: readonly predictionType[],
-	): [sensitive: boolean, porn: boolean] {
-		let sensitive = false;
-		let porn = false;
-
-		if (
-			(result.find((x) => x.className === "Sexy")?.probability ?? 0) >
-			sensitiveThreshold
-		)
-			sensitive = true;
-		if (
-			(result.find((x) => x.className === "Hentai")?.probability ?? 0) >
-			sensitiveThreshold
-		)
-			sensitive = true;
-		if (
-			(result.find((x) => x.className === "Porn")?.probability ?? 0) >
-			sensitiveThreshold
-		)
-			sensitive = true;
-
-		if (
-			(result.find((x) => x.className === "Porn")?.probability ?? 0) >
-			sensitiveThresholdForPorn
-		)
-			porn = true;
-
-		return [sensitive, porn];
-	}
-
-	if (["image/jpeg", "image/png", "image/webp"].includes(mime)) {
-		const result = await detectSensitive(source);
-		if (result) {
-			[sensitive, porn] = judgePrediction(result);
-		}
-	} else if (
-		analyzeVideo &&
-		(mime === "image/apng" || mime.startsWith("video/"))
-	) {
-		const [outDir, disposeOutDir] = await createTempDir();
-		try {
-			const command = FFmpeg()
-				.input(source)
-				.inputOptions([
-					"-skip_frame",
-					"nokey", // 可能ならキーフレームのみを取得してほしいとする(そうなるとは限らない)
-					"-lowres",
-					"3", // 元の画質でデコードする必要はないので 1/8 画質でデコードしてもよいとする(そうなるとは限らない)
-				])
-				.noAudio()
-				.videoFilters([
-					{
-						filter: "select", // フレームのフィルタリング
-						options: {
-							e: "eq(pict_type,PICT_TYPE_I)", // I-Frame のみをフィルタする(VP9 とかはデコードしてみないとわからないっぽい)
-						},
-					},
-					{
-						filter: "blackframe", // 暗いフレームの検出
-						options: {
-							amount: "0", // 暗さに関わらず全てのフレームで測定値を取る
-						},
-					},
-					{
-						filter: "metadata",
-						options: {
-							mode: "select", // フレーム選択モード
-							key: "lavfi.blackframe.pblack", // フレームにおける暗部の百分率(前のフィルタからのメタデータを参照する)
-							value: "50",
-							function: "less", // 50% 未満のフレームを選択する(50% 以上暗部があるフレームだと誤検知を招くかもしれないので)
-						},
-					},
-					{
-						filter: "scale",
-						options: {
-							w: 299,
-							h: 299,
-						},
-					},
-				])
-				.format("image2")
-				.output(join(outDir, "%d.png"))
-				.outputOptions(["-vsync", "0"]); // 可変フレームレートにすることで穴埋めをさせない
-			const results: ReturnType<typeof judgePrediction>[] = [];
-			let frameIndex = 0;
-			let targetIndex = 0;
-			let nextIndex = 1;
-			for await (const path of asyncIterateFrames(outDir, command)) {
-				try {
-					const index = frameIndex++;
-					if (index !== targetIndex) {
-						continue;
-					}
-					targetIndex = nextIndex;
-					nextIndex += index; // fibonacci sequence によってフレーム数制限を掛ける
-					const result = await detectSensitive(path);
-					if (result) {
-						results.push(judgePrediction(result));
-					}
-				} finally {
-					fs.promises.unlink(path);
-				}
-			}
-			sensitive =
-				results.filter((x) => x[0]).length >=
-				Math.ceil(results.length * sensitiveThreshold);
-			porn =
-				results.filter((x) => x[1]).length >=
-				Math.ceil(results.length * sensitiveThresholdForPorn);
-		} finally {
-			disposeOutDir();
-		}
-	}
-
-	return [sensitive, porn];
-}
-
-async function* asyncIterateFrames(
-	cwd: string,
-	command: FFmpeg.FfmpegCommand,
-): AsyncGenerator<string, void> {
-	const watcher = new FSWatcher({
-		cwd,
-		disableGlobbing: true,
-	});
-	let finished = false;
-	command.once("end", () => {
-		finished = true;
-		watcher.close();
-	});
-	command.run();
-	for (let i = 1; true; i++) {
-		const current = `${i}.png`;
-		const next = `${i + 1}.png`;
-		const framePath = join(cwd, current);
-		if (await exists(join(cwd, next))) {
-			yield framePath;
-		} else if (!finished) {
-			watcher.add(next);
-			await new Promise<void>((resolve, reject) => {
-				watcher.on("add", function onAdd(path) {
-					if (path === next) {
-						// 次フレームの書き出しが始まっているなら、現在フレームの書き出しは終わっている
-						watcher.unwatch(current);
-						watcher.off("add", onAdd);
-						resolve();
-					}
-				});
-				command.once("end", resolve); // 全てのフレームを処理し終わったなら、最終フレームである現在フレームの書き出しは終わっている
-				command.once("error", reject);
-			});
-			yield framePath;
-		} else if (await exists(framePath)) {
-			yield framePath;
-		} else {
-			return;
-		}
-	}
-}
-
-function exists(path: string): Promise<boolean> {
-	return fs.promises.access(path).then(
-		() => true,
-		() => false,
-	);
-}
-
-/**
- * Detect MIME Type and extension
- */
-export async function detectType(path: string): Promise<{
-	mime: string;
-	ext: string | null;
-}> {
-	// Check 0 byte
-	const fileSize = await getFileSize(path);
-	if (fileSize === 0) {
-		return TYPE_OCTET_STREAM;
-	}
-
-	const type = await fileTypeFromFile(path);
-
-	if (type) {
-		// XMLはSVGかもしれない
-		if (type.mime === "application/xml" && (await checkSvg(path))) {
-			return TYPE_SVG;
-		}
-
-		return {
-			mime: type.mime,
-			ext: type.ext,
-		};
-	}
-
-	// 種類が不明でもSVGかもしれない
-	if (await checkSvg(path)) {
-		return TYPE_SVG;
-	}
-
-	// それでも種類が不明なら application/octet-stream にする
-	return TYPE_OCTET_STREAM;
-}
-
-/**
- * Check the file is SVG or not
- */
-export async function checkSvg(path: string) {
-	try {
-		const size = await getFileSize(path);
-		if (size > 1 * 1024 * 1024) return false;
-		return isSvg(fs.readFileSync(path));
-	} catch {
-		return false;
-	}
-}
-
-/**
- * Get file size
- */
-export async function getFileSize(path: string): Promise<number> {
-	const getStat = util.promisify(fs.stat);
-	return (await getStat(path)).size;
-}
-
-/**
- * Calculate MD5 hash
- */
-async function calcHash(path: string): Promise<string> {
-	const hash = crypto.createHash("md5").setEncoding("hex");
-	await pipeline(fs.createReadStream(path), hash);
-	return hash.read();
-}
-
-/**
- * Detect dimensions of image
- */
-async function detectImageSize(path: string): Promise<{
-	width: number;
-	height: number;
-	wUnits: string;
-	hUnits: string;
-	orientation?: number;
-}> {
-	const readable = fs.createReadStream(path);
-	const imageSize = await probeImageSize(readable);
-	readable.destroy();
-	return imageSize;
-}
-
-/**
- * Calculate average color of image
- */
-function getBlurhash(path: string): Promise<string> {
-	return new Promise((resolve, reject) => {
-		sharp(path)
-			.raw()
-			.ensureAlpha()
-			.resize(64, 64, { fit: "inside" })
-			.toBuffer((err, buffer, { width, height }) => {
-				if (err) return reject(err);
-
-				let hash;
-
-				try {
-					hash = encode(new Uint8ClampedArray(buffer), width, height, 7, 7);
-				} catch (e) {
-					return reject(e);
-				}
-
-				resolve(hash);
-			});
-	});
-}
diff --git a/packages/backend/src/misc/get-ip-hash.ts b/packages/backend/src/misc/get-ip-hash.ts
deleted file mode 100644
index 3bafaee5df..0000000000
--- a/packages/backend/src/misc/get-ip-hash.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import IPCIDR from "ip-cidr";
-
-export function getIpHash(ip: string) {
-	try {
-		// because a single person may control many IPv6 addresses,
-		// only a /64 subnet prefix of any IP will be taken into account.
-		// (this means for IPv4 the entire address is used)
-		const prefix = IPCIDR.createAddress(ip).mask(64);
-		return `ip-${BigInt(`0b${prefix}`).toString(36)}`;
-	} catch (e) {
-		const prefix = IPCIDR.createAddress(ip.replace(/:[0-9]+$/, "")).mask(64);
-		return `ip-${BigInt(`0b${prefix}`).toString(36)}`;
-	}
-}
diff --git a/packages/backend/src/misc/get-note-summary.ts b/packages/backend/src/misc/get-note-summary.ts
deleted file mode 100644
index 446e3fc140..0000000000
--- a/packages/backend/src/misc/get-note-summary.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-import type { Packed } from "./schema.js";
-
-/**
- * 投稿を表す文字列を取得します。
- * @param {*} note (packされた)投稿
- */
-export const getNoteSummary = (note: Packed<"Note">): string => {
-	if (note.deletedAt) {
-		return "❌";
-	}
-
-	let summary = "";
-
-	// 本文
-	if (note.cw != null) {
-		summary += note.cw;
-	} else {
-		summary += note.text ? note.text : "";
-	}
-
-	// ファイルが添付されているとき
-	if ((note.files || []).length !== 0) {
-		summary += ` (📎${note.files!.length})`;
-	}
-
-	// 投票が添付されているとき
-	if (note.poll) {
-		summary += " (📊)";
-	}
-
-	/*
-	// 返信のとき
-	if (note.replyId) {
-		if (note.reply) {
-			summary += `\n\nRE: ${getNoteSummary(note.reply)}`;
-		} else {
-			summary += '\n\nRE: ...';
-		}
-	}
-
-	// Renoteのとき
-	if (note.renoteId) {
-		if (note.renote) {
-			summary += `\n\nRN: ${getNoteSummary(note.renote)}`;
-		} else {
-			summary += '\n\nRN: ...';
-		}
-	}
-	*/
-
-	return summary.trim();
-};
diff --git a/packages/backend/src/misc/get-reaction-emoji.ts b/packages/backend/src/misc/get-reaction-emoji.ts
deleted file mode 100644
index 71521c4ae8..0000000000
--- a/packages/backend/src/misc/get-reaction-emoji.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-export default function (reaction: string): string {
-	switch (reaction) {
-		case "like":
-			return "👍";
-		case "love":
-			return "❤️";
-		case "laugh":
-			return "😆";
-		case "hmm":
-			return "🤔";
-		case "surprise":
-			return "😮";
-		case "congrats":
-			return "🎉";
-		case "angry":
-			return "💢";
-		case "confused":
-			return "😥";
-		case "rip":
-			return "😇";
-		case "pudding":
-			return "🍮";
-		case "star":
-			return "⭐";
-		default:
-			return reaction;
-	}
-}
diff --git a/packages/backend/src/misc/hard-limits.ts b/packages/backend/src/misc/hard-limits.ts
deleted file mode 100644
index 51d2c0f5d2..0000000000
--- a/packages/backend/src/misc/hard-limits.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-// If you change DB_* values, you must also change the DB schema.
-
-/**
- * Maximum note text length that can be stored in DB.
- * Surrogate pairs count as one
- */
-export const DB_MAX_NOTE_TEXT_LENGTH = 8192;
-
-/**
- * Maximum image description length that can be stored in DB.
- * Surrogate pairs count as one
- */
-export const DB_MAX_IMAGE_COMMENT_LENGTH = 8192;
diff --git a/packages/backend/src/misc/i18n.ts b/packages/backend/src/misc/i18n.ts
deleted file mode 100644
index 742bdb0f69..0000000000
--- a/packages/backend/src/misc/i18n.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-export class I18n<T extends Record<string, any>> {
-	public locale: T;
-
-	constructor(locale: T) {
-		this.locale = locale;
-
-		//#region BIND
-		this.t = this.t.bind(this);
-		//#endregion
-	}
-
-	// string にしているのは、ドット区切りでのパス指定を許可するため
-	// なるべくこのメソッド使うよりもlocale直接参照の方がvueのキャッシュ効いてパフォーマンスが良いかも
-	public t(key: string, args?: Record<string, any>): string {
-		try {
-			let str = key.split(".").reduce((o, i) => o[i], this.locale) as string;
-
-			if (args) {
-				for (const [k, v] of Object.entries(args)) {
-					str = str.replace(`{${k}}`, v);
-				}
-			}
-			return str;
-		} catch (e) {
-			console.warn(`missing localization '${key}'`);
-			return key;
-		}
-	}
-}
diff --git a/packages/backend/src/misc/id/aid.ts b/packages/backend/src/misc/id/aid.ts
deleted file mode 100644
index a12360360b..0000000000
--- a/packages/backend/src/misc/id/aid.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-// AID
-// 長さ8の[2000年1月1日からの経過ミリ秒をbase36でエンコードしたもの] + 長さ2の[ノイズ文字列]
-
-import * as crypto from "node:crypto";
-
-const TIME2000 = 946684800000;
-let counter = crypto.randomBytes(2).readUInt16LE(0);
-
-function getTime(time: number) {
-	time = time - TIME2000;
-	if (time < 0) time = 0;
-
-	return time.toString(36).padStart(8, "0");
-}
-
-function getNoise() {
-	return counter.toString(36).padStart(2, "0").slice(-2);
-}
-
-export function genAid(date: Date): string {
-	const t = date.getTime();
-	if (isNaN(t)) throw "Failed to create AID: Invalid Date";
-	counter++;
-	return getTime(t) + getNoise();
-}
diff --git a/packages/backend/src/misc/id/meid.ts b/packages/backend/src/misc/id/meid.ts
deleted file mode 100644
index ee78eb8d14..0000000000
--- a/packages/backend/src/misc/id/meid.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-const CHARS = "0123456789abcdef";
-
-function getTime(time: number) {
-	if (time < 0) time = 0;
-	if (time === 0) {
-		return CHARS[0];
-	}
-
-	time += 0x800000000000;
-
-	return time.toString(16).padStart(12, CHARS[0]);
-}
-
-function getRandom() {
-	let str = "";
-
-	for (let i = 0; i < 12; i++) {
-		str += CHARS[Math.floor(Math.random() * CHARS.length)];
-	}
-
-	return str;
-}
-
-export function genMeid(date: Date): string {
-	return getTime(date.getTime()) + getRandom();
-}
diff --git a/packages/backend/src/misc/id/meidg.ts b/packages/backend/src/misc/id/meidg.ts
deleted file mode 100644
index 4fd39a8b41..0000000000
--- a/packages/backend/src/misc/id/meidg.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-const CHARS = "0123456789abcdef";
-
-//  4bit Fixed hex value 'g'
-// 44bit UNIX Time ms in Hex
-// 48bit Random value in Hex
-
-function getTime(time: number) {
-	if (time < 0) time = 0;
-	if (time === 0) {
-		return CHARS[0];
-	}
-
-	return time.toString(16).padStart(11, CHARS[0]);
-}
-
-function getRandom() {
-	let str = "";
-
-	for (let i = 0; i < 12; i++) {
-		str += CHARS[Math.floor(Math.random() * CHARS.length)];
-	}
-
-	return str;
-}
-
-export function genMeidg(date: Date): string {
-	return `g${getTime(date.getTime())}${getRandom()}`;
-}
diff --git a/packages/backend/src/misc/id/object-id.ts b/packages/backend/src/misc/id/object-id.ts
deleted file mode 100644
index 45822f0acc..0000000000
--- a/packages/backend/src/misc/id/object-id.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-const CHARS = "0123456789abcdef";
-
-function getTime(time: number) {
-	if (time < 0) time = 0;
-	if (time === 0) {
-		return CHARS[0];
-	}
-
-	time = Math.floor(time / 1000);
-
-	return time.toString(16).padStart(8, CHARS[0]);
-}
-
-function getRandom() {
-	let str = "";
-
-	for (let i = 0; i < 16; i++) {
-		str += CHARS[Math.floor(Math.random() * CHARS.length)];
-	}
-
-	return str;
-}
-
-export function genObjectId(date: Date): string {
-	return getTime(date.getTime()) + getRandom();
-}
diff --git a/packages/backend/src/misc/identifiable-error.ts b/packages/backend/src/misc/identifiable-error.ts
deleted file mode 100644
index be6eb5bd8d..0000000000
--- a/packages/backend/src/misc/identifiable-error.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-/**
- * ID付きエラー
- */
-export class IdentifiableError extends Error {
-	public message: string;
-	public id: string;
-
-	constructor(id: string, message?: string) {
-		super(message);
-		this.message = message || "";
-		this.id = id;
-	}
-}
diff --git a/packages/backend/src/misc/is-duplicate-key-value-error.ts b/packages/backend/src/misc/is-duplicate-key-value-error.ts
deleted file mode 100644
index 18d22bb77c..0000000000
--- a/packages/backend/src/misc/is-duplicate-key-value-error.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export function isDuplicateKeyValueError(e: unknown | Error): boolean {
-	return (e as Error).message?.startsWith("duplicate key value");
-}
diff --git a/packages/backend/src/misc/is-instance-muted.ts b/packages/backend/src/misc/is-instance-muted.ts
deleted file mode 100644
index 1547d4555c..0000000000
--- a/packages/backend/src/misc/is-instance-muted.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import type { Packed } from "./schema.js";
-
-export function isInstanceMuted(
-	note: Packed<"Note">,
-	mutedInstances: Set<string>,
-): boolean {
-	if (mutedInstances.has(note?.user?.host ?? "")) return true;
-	if (mutedInstances.has(note?.reply?.user?.host ?? "")) return true;
-	if (mutedInstances.has(note?.renote?.user?.host ?? "")) return true;
-
-	return false;
-}
-
-export function isUserFromMutedInstance(
-	notif: Packed<"Notification">,
-	mutedInstances: Set<string>,
-): boolean {
-	if (mutedInstances.has(notif?.user?.host ?? "")) return true;
-
-	return false;
-}
diff --git a/packages/backend/src/misc/is-mime-image.ts b/packages/backend/src/misc/is-mime-image.ts
deleted file mode 100644
index a8ba62ec20..0000000000
--- a/packages/backend/src/misc/is-mime-image.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { FILE_TYPE_BROWSERSAFE } from "@/const.js";
-
-const dictionary = {
-	"safe-file": FILE_TYPE_BROWSERSAFE,
-	"sharp-convertible-image": [
-		"image/jpeg",
-		"image/png",
-		"image/gif",
-		"image/apng",
-		"image/vnd.mozilla.apng",
-		"image/webp",
-		"image/svg+xml",
-		"image/avif",
-	],
-};
-
-export const isMimeImage = (
-	mime: string,
-	type: keyof typeof dictionary,
-): boolean => dictionary[type].includes(mime);
diff --git a/packages/backend/src/misc/is-quote.ts b/packages/backend/src/misc/is-quote.ts
deleted file mode 100644
index fe83a56a55..0000000000
--- a/packages/backend/src/misc/is-quote.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import type { Note } from "@/models/entities/note.js";
-
-export default function (note: Note): boolean {
-	return (
-		note.renoteId != null &&
-		(note.text != null ||
-			note.hasPoll ||
-			(note.fileIds != null && note.fileIds.length > 0))
-	);
-}
diff --git a/packages/backend/src/misc/is-user-related.ts b/packages/backend/src/misc/is-user-related.ts
deleted file mode 100644
index 64591cfef3..0000000000
--- a/packages/backend/src/misc/is-user-related.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-export function isUserRelated(note: any, ids: Set<string>): boolean {
-	if (ids.has(note.userId)) return true; // note author is muted
-	if (note.mentions?.some((user: string) => ids.has(user))) return true; // any of mentioned users are muted
-	if (note.reply && isUserRelated(note.reply, ids)) return true; // also check reply target
-	if (note.renote && isUserRelated(note.renote, ids)) return true; // also check renote target
-	return false;
-}
diff --git a/packages/backend/src/misc/keypair-store.ts b/packages/backend/src/misc/keypair-store.ts
deleted file mode 100644
index 4551bfd988..0000000000
--- a/packages/backend/src/misc/keypair-store.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { UserKeypairs } from "@/models/index.js";
-import type { User } from "@/models/entities/user.js";
-import type { UserKeypair } from "@/models/entities/user-keypair.js";
-import { Cache } from "./cache.js";
-
-const cache = new Cache<UserKeypair>(Infinity);
-
-export async function getUserKeypair(userId: User["id"]): Promise<UserKeypair> {
-	return await cache.fetch(userId, () =>
-		UserKeypairs.findOneByOrFail({ userId: userId }),
-	);
-}
diff --git a/packages/backend/src/misc/langmap.ts b/packages/backend/src/misc/langmap.ts
deleted file mode 100644
index 106130d3c3..0000000000
--- a/packages/backend/src/misc/langmap.ts
+++ /dev/null
@@ -1,666 +0,0 @@
-// TODO: sharedに置いてフロントエンドのと統合したい
-export const langmap = {
-	ach: {
-		nativeName: "Lwo",
-	},
-	ady: {
-		nativeName: "Адыгэбзэ",
-	},
-	af: {
-		nativeName: "Afrikaans",
-	},
-	"af-NA": {
-		nativeName: "Afrikaans (Namibia)",
-	},
-	"af-ZA": {
-		nativeName: "Afrikaans (South Africa)",
-	},
-	ak: {
-		nativeName: "Tɕɥi",
-	},
-	ar: {
-		nativeName: "العربية",
-	},
-	"ar-AR": {
-		nativeName: "العربية",
-	},
-	"ar-MA": {
-		nativeName: "العربية",
-	},
-	"ar-SA": {
-		nativeName: "العربية (السعودية)",
-	},
-	"ay-BO": {
-		nativeName: "Aymar aru",
-	},
-	az: {
-		nativeName: "Azərbaycan dili",
-	},
-	"az-AZ": {
-		nativeName: "Azərbaycan dili",
-	},
-	"be-BY": {
-		nativeName: "Беларуская",
-	},
-	bg: {
-		nativeName: "Български",
-	},
-	"bg-BG": {
-		nativeName: "Български",
-	},
-	bn: {
-		nativeName: "বাংলা",
-	},
-	"bn-IN": {
-		nativeName: "বাংলা (ভারত)",
-	},
-	"bn-BD": {
-		nativeName: "বাংলা(বাংলাদেশ)",
-	},
-	br: {
-		nativeName: "Brezhoneg",
-	},
-	"bs-BA": {
-		nativeName: "Bosanski",
-	},
-	ca: {
-		nativeName: "Català",
-	},
-	"ca-ES": {
-		nativeName: "Català",
-	},
-	cak: {
-		nativeName: "Maya Kaqchikel",
-	},
-	"ck-US": {
-		nativeName: "ᏣᎳᎩ (tsalagi)",
-	},
-	cs: {
-		nativeName: "Čeština",
-	},
-	"cs-CZ": {
-		nativeName: "Čeština",
-	},
-	cy: {
-		nativeName: "Cymraeg",
-	},
-	"cy-GB": {
-		nativeName: "Cymraeg",
-	},
-	da: {
-		nativeName: "Dansk",
-	},
-	"da-DK": {
-		nativeName: "Dansk",
-	},
-	de: {
-		nativeName: "Deutsch",
-	},
-	"de-AT": {
-		nativeName: "Deutsch (Österreich)",
-	},
-	"de-DE": {
-		nativeName: "Deutsch (Deutschland)",
-	},
-	"de-CH": {
-		nativeName: "Deutsch (Schweiz)",
-	},
-	dsb: {
-		nativeName: "Dolnoserbšćina",
-	},
-	el: {
-		nativeName: "Ελληνικά",
-	},
-	"el-GR": {
-		nativeName: "Ελληνικά",
-	},
-	en: {
-		nativeName: "English",
-	},
-	"en-GB": {
-		nativeName: "English (UK)",
-	},
-	"en-AU": {
-		nativeName: "English (Australia)",
-	},
-	"en-CA": {
-		nativeName: "English (Canada)",
-	},
-	"en-IE": {
-		nativeName: "English (Ireland)",
-	},
-	"en-IN": {
-		nativeName: "English (India)",
-	},
-	"en-PI": {
-		nativeName: "English (Pirate)",
-	},
-	"en-SG": {
-		nativeName: "English (Singapore)",
-	},
-	"en-UD": {
-		nativeName: "English (Upside Down)",
-	},
-	"en-US": {
-		nativeName: "English (US)",
-	},
-	"en-ZA": {
-		nativeName: "English (South Africa)",
-	},
-	"en@pirate": {
-		nativeName: "English (Pirate)",
-	},
-	eo: {
-		nativeName: "Esperanto",
-	},
-	"eo-EO": {
-		nativeName: "Esperanto",
-	},
-	es: {
-		nativeName: "Español",
-	},
-	"es-AR": {
-		nativeName: "Español (Argentine)",
-	},
-	"es-419": {
-		nativeName: "Español (Latinoamérica)",
-	},
-	"es-CL": {
-		nativeName: "Español (Chile)",
-	},
-	"es-CO": {
-		nativeName: "Español (Colombia)",
-	},
-	"es-EC": {
-		nativeName: "Español (Ecuador)",
-	},
-	"es-ES": {
-		nativeName: "Español (España)",
-	},
-	"es-LA": {
-		nativeName: "Español (Latinoamérica)",
-	},
-	"es-NI": {
-		nativeName: "Español (Nicaragua)",
-	},
-	"es-MX": {
-		nativeName: "Español (México)",
-	},
-	"es-US": {
-		nativeName: "Español (Estados Unidos)",
-	},
-	"es-VE": {
-		nativeName: "Español (Venezuela)",
-	},
-	et: {
-		nativeName: "eesti keel",
-	},
-	"et-EE": {
-		nativeName: "Eesti (Estonia)",
-	},
-	eu: {
-		nativeName: "Euskara",
-	},
-	"eu-ES": {
-		nativeName: "Euskara",
-	},
-	fa: {
-		nativeName: "فارسی",
-	},
-	"fa-IR": {
-		nativeName: "فارسی",
-	},
-	"fb-LT": {
-		nativeName: "Leet Speak",
-	},
-	ff: {
-		nativeName: "Fulah",
-	},
-	fi: {
-		nativeName: "Suomi",
-	},
-	"fi-FI": {
-		nativeName: "Suomi",
-	},
-	fo: {
-		nativeName: "Føroyskt",
-	},
-	"fo-FO": {
-		nativeName: "Føroyskt (Færeyjar)",
-	},
-	fr: {
-		nativeName: "Français",
-	},
-	"fr-CA": {
-		nativeName: "Français (Canada)",
-	},
-	"fr-FR": {
-		nativeName: "Français (France)",
-	},
-	"fr-BE": {
-		nativeName: "Français (Belgique)",
-	},
-	"fr-CH": {
-		nativeName: "Français (Suisse)",
-	},
-	"fy-NL": {
-		nativeName: "Frysk",
-	},
-	ga: {
-		nativeName: "Gaeilge",
-	},
-	"ga-IE": {
-		nativeName: "Gaeilge",
-	},
-	gd: {
-		nativeName: "Gàidhlig",
-	},
-	gl: {
-		nativeName: "Galego",
-	},
-	"gl-ES": {
-		nativeName: "Galego",
-	},
-	"gn-PY": {
-		nativeName: "Avañe'ẽ",
-	},
-	"gu-IN": {
-		nativeName: "ગુજરાતી",
-	},
-	gv: {
-		nativeName: "Gaelg",
-	},
-	"gx-GR": {
-		nativeName: "Ἑλληνική ἀρχαία",
-	},
-	he: {
-		nativeName: "עברית‏",
-	},
-	"he-IL": {
-		nativeName: "עברית‏",
-	},
-	hi: {
-		nativeName: "हिन्दी",
-	},
-	"hi-IN": {
-		nativeName: "हिन्दी",
-	},
-	hr: {
-		nativeName: "Hrvatski",
-	},
-	"hr-HR": {
-		nativeName: "Hrvatski",
-	},
-	hsb: {
-		nativeName: "Hornjoserbšćina",
-	},
-	ht: {
-		nativeName: "Kreyòl",
-	},
-	hu: {
-		nativeName: "Magyar",
-	},
-	"hu-HU": {
-		nativeName: "Magyar",
-	},
-	hy: {
-		nativeName: "Հայերեն",
-	},
-	"hy-AM": {
-		nativeName: "Հայերեն (Հայաստան)",
-	},
-	id: {
-		nativeName: "Bahasa Indonesia",
-	},
-	"id-ID": {
-		nativeName: "Bahasa Indonesia",
-	},
-	is: {
-		nativeName: "Íslenska",
-	},
-	"is-IS": {
-		nativeName: "Íslenska (Iceland)",
-	},
-	it: {
-		nativeName: "Italiano",
-	},
-	"it-IT": {
-		nativeName: "Italiano",
-	},
-	ja: {
-		nativeName: "日本語",
-	},
-	"ja-JP": {
-		nativeName: "日本語 (日本)",
-	},
-	"jv-ID": {
-		nativeName: "Basa Jawa",
-	},
-	"ka-GE": {
-		nativeName: "ქართული",
-	},
-	"kk-KZ": {
-		nativeName: "Қазақша",
-	},
-	km: {
-		nativeName: "ភាសាខ្មែរ",
-	},
-	kl: {
-		nativeName: "kalaallisut",
-	},
-	"km-KH": {
-		nativeName: "ភាសាខ្មែរ",
-	},
-	kab: {
-		nativeName: "Taqbaylit",
-	},
-	kn: {
-		nativeName: "ಕನ್ನಡ",
-	},
-	"kn-IN": {
-		nativeName: "ಕನ್ನಡ (India)",
-	},
-	ko: {
-		nativeName: "한국어",
-	},
-	"ko-KR": {
-		nativeName: "한국어 (한국)",
-	},
-	"ku-TR": {
-		nativeName: "Kurdî",
-	},
-	kw: {
-		nativeName: "Kernewek",
-	},
-	la: {
-		nativeName: "Latin",
-	},
-	"la-VA": {
-		nativeName: "Latin",
-	},
-	lb: {
-		nativeName: "Lëtzebuergesch",
-	},
-	"li-NL": {
-		nativeName: "Lèmbörgs",
-	},
-	lt: {
-		nativeName: "Lietuvių",
-	},
-	"lt-LT": {
-		nativeName: "Lietuvių",
-	},
-	lv: {
-		nativeName: "Latviešu",
-	},
-	"lv-LV": {
-		nativeName: "Latviešu",
-	},
-	mai: {
-		nativeName: "मैथिली, মৈথিলী",
-	},
-	"mg-MG": {
-		nativeName: "Malagasy",
-	},
-	mk: {
-		nativeName: "Македонски",
-	},
-	"mk-MK": {
-		nativeName: "Македонски (Македонски)",
-	},
-	ml: {
-		nativeName: "മലയാളം",
-	},
-	"ml-IN": {
-		nativeName: "മലയാളം",
-	},
-	"mn-MN": {
-		nativeName: "Монгол",
-	},
-	mr: {
-		nativeName: "मराठी",
-	},
-	"mr-IN": {
-		nativeName: "मराठी",
-	},
-	ms: {
-		nativeName: "Bahasa Melayu",
-	},
-	"ms-MY": {
-		nativeName: "Bahasa Melayu",
-	},
-	mt: {
-		nativeName: "Malti",
-	},
-	"mt-MT": {
-		nativeName: "Malti",
-	},
-	my: {
-		nativeName: "ဗမာစကာ",
-	},
-	no: {
-		nativeName: "Norsk",
-	},
-	nb: {
-		nativeName: "Norsk (bokmål)",
-	},
-	"nb-NO": {
-		nativeName: "Norsk (bokmål)",
-	},
-	ne: {
-		nativeName: "नेपाली",
-	},
-	"ne-NP": {
-		nativeName: "नेपाली",
-	},
-	nl: {
-		nativeName: "Nederlands",
-	},
-	"nl-BE": {
-		nativeName: "Nederlands (België)",
-	},
-	"nl-NL": {
-		nativeName: "Nederlands (Nederland)",
-	},
-	"nn-NO": {
-		nativeName: "Norsk (nynorsk)",
-	},
-	oc: {
-		nativeName: "Occitan",
-	},
-	"or-IN": {
-		nativeName: "ଓଡ଼ିଆ",
-	},
-	pa: {
-		nativeName: "ਪੰਜਾਬੀ",
-	},
-	"pa-IN": {
-		nativeName: "ਪੰਜਾਬੀ (ਭਾਰਤ ਨੂੰ)",
-	},
-	pl: {
-		nativeName: "Polski",
-	},
-	"pl-PL": {
-		nativeName: "Polski",
-	},
-	"ps-AF": {
-		nativeName: "پښتو",
-	},
-	pt: {
-		nativeName: "Português",
-	},
-	"pt-BR": {
-		nativeName: "Português (Brasil)",
-	},
-	"pt-PT": {
-		nativeName: "Português (Portugal)",
-	},
-	"qu-PE": {
-		nativeName: "Qhichwa",
-	},
-	"rm-CH": {
-		nativeName: "Rumantsch",
-	},
-	ro: {
-		nativeName: "Română",
-	},
-	"ro-RO": {
-		nativeName: "Română",
-	},
-	ru: {
-		nativeName: "Русский",
-	},
-	"ru-RU": {
-		nativeName: "Русский",
-	},
-	"sa-IN": {
-		nativeName: "संस्कृतम्",
-	},
-	"se-NO": {
-		nativeName: "Davvisámegiella",
-	},
-	sh: {
-		nativeName: "српскохрватски",
-	},
-	"si-LK": {
-		nativeName: "සිංහල",
-	},
-	sk: {
-		nativeName: "Slovenčina",
-	},
-	"sk-SK": {
-		nativeName: "Slovenčina (Slovakia)",
-	},
-	sl: {
-		nativeName: "Slovenščina",
-	},
-	"sl-SI": {
-		nativeName: "Slovenščina",
-	},
-	"so-SO": {
-		nativeName: "Soomaaliga",
-	},
-	sq: {
-		nativeName: "Shqip",
-	},
-	"sq-AL": {
-		nativeName: "Shqip",
-	},
-	sr: {
-		nativeName: "Српски",
-	},
-	"sr-RS": {
-		nativeName: "Српски (Serbia)",
-	},
-	su: {
-		nativeName: "Basa Sunda",
-	},
-	sv: {
-		nativeName: "Svenska",
-	},
-	"sv-SE": {
-		nativeName: "Svenska",
-	},
-	sw: {
-		nativeName: "Kiswahili",
-	},
-	"sw-KE": {
-		nativeName: "Kiswahili",
-	},
-	ta: {
-		nativeName: "தமிழ்",
-	},
-	"ta-IN": {
-		nativeName: "தமிழ்",
-	},
-	te: {
-		nativeName: "తెలుగు",
-	},
-	"te-IN": {
-		nativeName: "తెలుగు",
-	},
-	tg: {
-		nativeName: "забо́ни тоҷикӣ́",
-	},
-	"tg-TJ": {
-		nativeName: "тоҷикӣ",
-	},
-	th: {
-		nativeName: "ภาษาไทย",
-	},
-	"th-TH": {
-		nativeName: "ภาษาไทย (ประเทศไทย)",
-	},
-	fil: {
-		nativeName: "Filipino",
-	},
-	tlh: {
-		nativeName: "tlhIngan-Hol",
-	},
-	tr: {
-		nativeName: "Türkçe",
-	},
-	"tr-TR": {
-		nativeName: "Türkçe",
-	},
-	"tt-RU": {
-		nativeName: "татарча",
-	},
-	uk: {
-		nativeName: "Українська",
-	},
-	"uk-UA": {
-		nativeName: "Українська",
-	},
-	ur: {
-		nativeName: "اردو",
-	},
-	"ur-PK": {
-		nativeName: "اردو",
-	},
-	uz: {
-		nativeName: "O'zbek",
-	},
-	"uz-UZ": {
-		nativeName: "O'zbek",
-	},
-	vi: {
-		nativeName: "Tiếng Việt",
-	},
-	"vi-VN": {
-		nativeName: "Tiếng Việt",
-	},
-	"xh-ZA": {
-		nativeName: "isiXhosa",
-	},
-	yi: {
-		nativeName: "ייִדיש",
-	},
-	"yi-DE": {
-		nativeName: "ייִדיש (German)",
-	},
-	zh: {
-		nativeName: "中文",
-	},
-	"zh-Hans": {
-		nativeName: "中文简体",
-	},
-	"zh-Hant": {
-		nativeName: "中文繁體",
-	},
-	"zh-CN": {
-		nativeName: "中文(中国大陆)",
-	},
-	"zh-HK": {
-		nativeName: "中文(香港)",
-	},
-	"zh-SG": {
-		nativeName: "中文(新加坡)",
-	},
-	"zh-TW": {
-		nativeName: "中文(台灣)",
-	},
-	"zu-ZA": {
-		nativeName: "isiZulu",
-	},
-};
diff --git a/packages/backend/src/misc/normalize-for-search.ts b/packages/backend/src/misc/normalize-for-search.ts
deleted file mode 100644
index 6882a1243e..0000000000
--- a/packages/backend/src/misc/normalize-for-search.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-export function normalizeForSearch(tag: string): string {
-	// ref.
-	// - https://analytics-note.xyz/programming/unicode-normalization-forms/
-	// - https://maku77.github.io/js/string/normalize.html
-	return tag.normalize("NFKC").toLowerCase();
-}
diff --git a/packages/backend/src/misc/nyaize.ts b/packages/backend/src/misc/nyaize.ts
deleted file mode 100644
index b85f1d918e..0000000000
--- a/packages/backend/src/misc/nyaize.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-export function nyaize(text: string): string {
-	return (
-		text
-			// ja-JP
-			.replaceAll("な", "にゃ")
-			.replaceAll("ナ", "ニャ")
-			.replaceAll("ナ", "ニャ")
-			// en-US
-			.replace(/(?<=n)a/gi, (x) => (x === "A" ? "YA" : "ya"))
-			.replace(/(?<=morn)ing/gi, (x) => (x === "ING" ? "YAN" : "yan"))
-			.replace(/(?<=every)one/gi, (x) => (x === "ONE" ? "NYAN" : "nyan"))
-			// ko-KR
-			.replace(/[나-낳]/g, (match) =>
-				String.fromCharCode(
-					match.charCodeAt(0)! + "냐".charCodeAt(0) - "나".charCodeAt(0),
-				),
-			)
-			.replace(/(다$)|(다(?=\.))|(다(?= ))|(다(?=!))|(다(?=\?))/gm, "다냥")
-			.replace(/(야(?=\?))|(야$)|(야(?= ))/gm, "냥")
-	);
-}
diff --git a/packages/backend/src/misc/password.ts b/packages/backend/src/misc/password.ts
deleted file mode 100644
index c63f89f5c9..0000000000
--- a/packages/backend/src/misc/password.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import bcrypt from "bcryptjs";
-import * as argon2 from "argon2";
-
-export async function hashPassword(password: string): Promise<string> {
-	return argon2.hash(password);
-}
-
-export async function comparePassword(
-	password: string,
-	hash: string,
-): Promise<boolean> {
-	if (isOldAlgorithm(hash)) return bcrypt.compare(password, hash);
-
-	return argon2.verify(hash, password);
-}
-
-export function isOldAlgorithm(hash: string): boolean {
-	// bcrypt hashes start with $2[ab]$
-	return hash.startsWith("$2");
-}
diff --git a/packages/backend/src/misc/populate-emojis.ts b/packages/backend/src/misc/populate-emojis.ts
deleted file mode 100644
index 3f20f9f10d..0000000000
--- a/packages/backend/src/misc/populate-emojis.ts
+++ /dev/null
@@ -1,165 +0,0 @@
-import { In, IsNull } from "typeorm";
-import { Emojis } from "@/models/index.js";
-import type { Emoji } from "@/models/entities/emoji.js";
-import type { Note } from "@/models/entities/note.js";
-import { Cache } from "./cache.js";
-import { isSelfHost, toPunyNullable } from "./convert-host.js";
-import { decodeReaction } from "./reaction-lib.js";
-import config from "@/config/index.js";
-import { query } from "@/prelude/url.js";
-
-const cache = new Cache<Emoji | null>(1000 * 60 * 60 * 12);
-
-/**
- * 添付用絵文字情報
- */
-type PopulatedEmoji = {
-	name: string;
-	url: string;
-};
-
-function normalizeHost(
-	src: string | undefined,
-	noteUserHost: string | null,
-): string | null {
-	// クエリに使うホスト
-	let host =
-		src === "."
-			? null // .はローカルホスト (ここがマッチするのはリアクションのみ)
-			: src === undefined
-			? noteUserHost // ノートなどでホスト省略表記の場合はローカルホスト (ここがリアクションにマッチすることはない)
-			: isSelfHost(src)
-			? null // 自ホスト指定
-			: src || noteUserHost; // 指定されたホスト || ノートなどの所有者のホスト (こっちがリアクションにマッチすることはない)
-
-	host = toPunyNullable(host);
-
-	return host;
-}
-
-function parseEmojiStr(emojiName: string, noteUserHost: string | null) {
-	const match = emojiName.match(/^(\w+)(?:@([\w.-]+))?$/);
-	if (!match) return { name: null, host: null };
-
-	const name = match[1];
-
-	// ホスト正規化
-	const host = toPunyNullable(normalizeHost(match[2], noteUserHost));
-
-	return { name, host };
-}
-
-/**
- * 添付用絵文字情報を解決する
- * @param emojiName ノートやユーザープロフィールに添付された、またはリアクションのカスタム絵文字名 (:は含めない, リアクションでローカルホストの場合は@.を付ける (これはdecodeReactionで可能))
- * @param noteUserHost ノートやユーザープロフィールの所有者のホスト
- * @returns 絵文字情報, nullは未マッチを意味する
- */
-export async function populateEmoji(
-	emojiName: string,
-	noteUserHost: string | null,
-): Promise<PopulatedEmoji | null> {
-	const { name, host } = parseEmojiStr(emojiName, noteUserHost);
-	if (name == null) return null;
-
-	const queryOrNull = async () =>
-		(await Emojis.findOneBy({
-			name,
-			host: host ?? IsNull(),
-		})) || null;
-
-	const emoji = await cache.fetch(`${name} ${host}`, queryOrNull);
-
-	if (emoji == null) return null;
-
-	const isLocal = emoji.host == null;
-	const emojiUrl = emoji.publicUrl || emoji.originalUrl; // || emoji.originalUrl してるのは後方互換性のため
-	const url = isLocal
-		? emojiUrl
-		: `${config.url}/proxy/${encodeURIComponent(
-				new URL(emojiUrl).pathname,
-		  )}?${query({ url: emojiUrl })}`;
-
-	return {
-		name: emojiName,
-		url,
-	};
-}
-
-/**
- * 複数の添付用絵文字情報を解決する (キャシュ付き, 存在しないものは結果から除外される)
- */
-export async function populateEmojis(
-	emojiNames: string[],
-	noteUserHost: string | null,
-): Promise<PopulatedEmoji[]> {
-	const emojis = await Promise.all(
-		emojiNames.map((x) => populateEmoji(x, noteUserHost)),
-	);
-	return emojis.filter((x): x is PopulatedEmoji => x != null);
-}
-
-export function aggregateNoteEmojis(notes: Note[]) {
-	let emojis: { name: string | null; host: string | null }[] = [];
-	for (const note of notes) {
-		emojis = emojis.concat(
-			note.emojis.map((e) => parseEmojiStr(e, note.userHost)),
-		);
-		if (note.renote) {
-			emojis = emojis.concat(
-				note.renote.emojis.map((e) => parseEmojiStr(e, note.renote!.userHost)),
-			);
-			if (note.renote.user) {
-				emojis = emojis.concat(
-					note.renote.user.emojis.map((e) =>
-						parseEmojiStr(e, note.renote!.userHost),
-					),
-				);
-			}
-		}
-		const customReactions = Object.keys(note.reactions)
-			.map((x) => decodeReaction(x))
-			.filter((x) => x.name != null) as typeof emojis;
-		emojis = emojis.concat(customReactions);
-		if (note.user) {
-			emojis = emojis.concat(
-				note.user.emojis.map((e) => parseEmojiStr(e, note.userHost)),
-			);
-		}
-	}
-	return emojis.filter((x) => x.name != null) as {
-		name: string;
-		host: string | null;
-	}[];
-}
-
-/**
- * 与えられた絵文字のリストをデータベースから取得し、キャッシュに追加します
- */
-export async function prefetchEmojis(
-	emojis: { name: string; host: string | null }[],
-): Promise<void> {
-	const notCachedEmojis = emojis.filter(
-		(emoji) => cache.get(`${emoji.name} ${emoji.host}`) == null,
-	);
-	const emojisQuery: any[] = [];
-	const hosts = new Set(notCachedEmojis.map((e) => e.host));
-	for (const host of hosts) {
-		emojisQuery.push({
-			name: In(
-				notCachedEmojis.filter((e) => e.host === host).map((e) => e.name),
-			),
-			host: host ?? IsNull(),
-		});
-	}
-	const _emojis =
-		emojisQuery.length > 0
-			? await Emojis.find({
-					where: emojisQuery,
-					select: ["name", "host", "originalUrl", "publicUrl"],
-			  })
-			: [];
-	for (const emoji of _emojis) {
-		cache.set(`${emoji.name} ${emoji.host}`, emoji);
-	}
-}
diff --git a/packages/backend/src/misc/post.ts b/packages/backend/src/misc/post.ts
deleted file mode 100644
index 90f4f75283..0000000000
--- a/packages/backend/src/misc/post.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-export type Post = {
-	text: string | null;
-	cw: string | null;
-	localOnly: boolean;
-	createdAt: Date;
-};
-
-export function parse(acct: any): Post {
-	return {
-		text: acct.text,
-		cw: acct.cw,
-		localOnly: acct.localOnly,
-		createdAt: new Date(acct.createdAt),
-	};
-}
-
-export function toJson(acct: Post): string {
-	return { text: acct.text, cw: acct.cw, localOnly: acct.localOnly }.toString();
-}
diff --git a/packages/backend/src/misc/reaction-lib.ts b/packages/backend/src/misc/reaction-lib.ts
deleted file mode 100644
index e25b2d6614..0000000000
--- a/packages/backend/src/misc/reaction-lib.ts
+++ /dev/null
@@ -1,136 +0,0 @@
-import { emojiRegex } from "./emoji-regex.js";
-import { fetchMeta } from "./fetch-meta.js";
-import { Emojis } from "@/models/index.js";
-import { toPunyNullable } from "./convert-host.js";
-import { IsNull } from "typeorm";
-
-const legacies = new Map([
-	["like", "👍"],
-	["love", "❤️"],
-	["laugh", "😆"],
-	["hmm", "🤔"],
-	["surprise", "😮"],
-	["congrats", "🎉"],
-	["angry", "💢"],
-	["confused", "😥"],
-	["rip", "😇"],
-	["pudding", "🍮"],
-	["star", "⭐"],
-]);
-
-export async function getFallbackReaction() {
-	const meta = await fetchMeta();
-	return meta.defaultReaction;
-}
-
-export function convertLegacyReactions(reactions: Record<string, number>) {
-	const _reactions = new Map();
-	const decodedReactions = new Map();
-
-	for (const reaction in reactions) {
-		if (reactions[reaction] <= 0) continue;
-
-		let decodedReaction;
-		if (decodedReactions.has(reaction)) {
-			decodedReaction = decodedReactions.get(reaction);
-		} else {
-			decodedReaction = decodeReaction(reaction);
-			decodedReactions.set(reaction, decodedReaction);
-		}
-
-		let emoji = legacies.get(decodedReaction.reaction);
-		if (emoji) {
-			_reactions.set(emoji, (_reactions.get(emoji) || 0) + reactions[reaction]);
-		} else {
-			_reactions.set(
-				reaction,
-				(_reactions.get(reaction) || 0) + reactions[reaction],
-			);
-		}
-	}
-
-	const _reactions2 = new Map();
-	for (const [reaction, count] of _reactions) {
-		const decodedReaction = decodedReactions.get(reaction);
-		_reactions2.set(decodedReaction.reaction, count);
-	}
-
-	return Object.fromEntries(_reactions2);
-}
-
-export async function toDbReaction(
-	reaction?: string | null,
-	reacterHost?: string | null,
-): Promise<string> {
-	if (!reaction) return await getFallbackReaction();
-
-	reacterHost = toPunyNullable(reacterHost);
-
-	// Convert string-type reactions to unicode
-	const emoji = legacies.get(reaction) || (reaction === "♥️" ? "❤️" : null);
-	if (emoji) return emoji;
-
-	// Allow unicode reactions
-	const match = emojiRegex.exec(reaction);
-	if (match) {
-		const unicode = match[0];
-		return unicode;
-	}
-
-	const custom = reaction.match(/^:([\w+-]+)(?:@\.)?:$/);
-	if (custom) {
-		const name = custom[1];
-		const emoji = await Emojis.findOneBy({
-			host: reacterHost || IsNull(),
-			name,
-		});
-
-		if (emoji) return reacterHost ? `:${name}@${reacterHost}:` : `:${name}:`;
-	}
-
-	return await getFallbackReaction();
-}
-
-type DecodedReaction = {
-	/**
-	 * リアクション名 (Unicode Emoji or ':name@hostname' or ':name@.')
-	 */
-	reaction: string;
-
-	/**
-	 * name (カスタム絵文字の場合name, Emojiクエリに使う)
-	 */
-	name?: string;
-
-	/**
-	 * host (カスタム絵文字の場合host, Emojiクエリに使う)
-	 */
-	host?: string | null;
-};
-
-export function decodeReaction(str: string): DecodedReaction {
-	const custom = str.match(/^:([\w+-]+)(?:@([\w.-]+))?:$/);
-
-	if (custom) {
-		const name = custom[1];
-		const host = custom[2] || null;
-
-		return {
-			reaction: `:${name}@${host || "."}:`, // ローカル分は@以降を省略するのではなく.にする
-			name,
-			host,
-		};
-	}
-
-	return {
-		reaction: str,
-		name: undefined,
-		host: undefined,
-	};
-}
-
-export function convertLegacyReaction(reaction: string): string {
-	const decoded = decodeReaction(reaction).reaction;
-	if (legacies.has(decoded)) return legacies.get(decoded)!;
-	return decoded;
-}
diff --git a/packages/backend/src/misc/safe-for-sql.ts b/packages/backend/src/misc/safe-for-sql.ts
deleted file mode 100644
index 02eb7f0a26..0000000000
--- a/packages/backend/src/misc/safe-for-sql.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export function safeForSql(text: string): boolean {
-	return !/[\0\x08\x09\x1a\n\r"'\\\%]/g.test(text);
-}
diff --git a/packages/backend/src/misc/schema.ts b/packages/backend/src/misc/schema.ts
deleted file mode 100644
index 7eaeb92e04..0000000000
--- a/packages/backend/src/misc/schema.ts
+++ /dev/null
@@ -1,222 +0,0 @@
-import {
-	packedUserLiteSchema,
-	packedUserDetailedNotMeOnlySchema,
-	packedMeDetailedOnlySchema,
-	packedUserDetailedNotMeSchema,
-	packedMeDetailedSchema,
-	packedUserDetailedSchema,
-	packedUserSchema,
-} from "@/models/schema/user.js";
-import { packedNoteSchema } from "@/models/schema/note.js";
-import { packedUserListSchema } from "@/models/schema/user-list.js";
-import { packedAppSchema } from "@/models/schema/app.js";
-import { packedMessagingMessageSchema } from "@/models/schema/messaging-message.js";
-import { packedNotificationSchema } from "@/models/schema/notification.js";
-import { packedDriveFileSchema } from "@/models/schema/drive-file.js";
-import { packedDriveFolderSchema } from "@/models/schema/drive-folder.js";
-import { packedFollowingSchema } from "@/models/schema/following.js";
-import { packedMutingSchema } from "@/models/schema/muting.js";
-import { packedRenoteMutingSchema } from "@/models/schema/renote-muting.js";
-import { packedBlockingSchema } from "@/models/schema/blocking.js";
-import { packedNoteReactionSchema } from "@/models/schema/note-reaction.js";
-import { packedHashtagSchema } from "@/models/schema/hashtag.js";
-import { packedPageSchema } from "@/models/schema/page.js";
-import { packedUserGroupSchema } from "@/models/schema/user-group.js";
-import { packedNoteFavoriteSchema } from "@/models/schema/note-favorite.js";
-import { packedChannelSchema } from "@/models/schema/channel.js";
-import { packedAntennaSchema } from "@/models/schema/antenna.js";
-import { packedClipSchema } from "@/models/schema/clip.js";
-import { packedFederationInstanceSchema } from "@/models/schema/federation-instance.js";
-import { packedQueueCountSchema } from "@/models/schema/queue.js";
-import { packedGalleryPostSchema } from "@/models/schema/gallery-post.js";
-import { packedEmojiSchema } from "@/models/schema/emoji.js";
-
-export const refs = {
-	UserLite: packedUserLiteSchema,
-	UserDetailedNotMeOnly: packedUserDetailedNotMeOnlySchema,
-	MeDetailedOnly: packedMeDetailedOnlySchema,
-	UserDetailedNotMe: packedUserDetailedNotMeSchema,
-	MeDetailed: packedMeDetailedSchema,
-	UserDetailed: packedUserDetailedSchema,
-	User: packedUserSchema,
-
-	UserList: packedUserListSchema,
-	UserGroup: packedUserGroupSchema,
-	App: packedAppSchema,
-	MessagingMessage: packedMessagingMessageSchema,
-	Note: packedNoteSchema,
-	NoteReaction: packedNoteReactionSchema,
-	NoteFavorite: packedNoteFavoriteSchema,
-	Notification: packedNotificationSchema,
-	DriveFile: packedDriveFileSchema,
-	DriveFolder: packedDriveFolderSchema,
-	Following: packedFollowingSchema,
-	Muting: packedMutingSchema,
-	RenoteMuting: packedRenoteMutingSchema,
-	Blocking: packedBlockingSchema,
-	Hashtag: packedHashtagSchema,
-	Page: packedPageSchema,
-	Channel: packedChannelSchema,
-	QueueCount: packedQueueCountSchema,
-	Antenna: packedAntennaSchema,
-	Clip: packedClipSchema,
-	FederationInstance: packedFederationInstanceSchema,
-	GalleryPost: packedGalleryPostSchema,
-	Emoji: packedEmojiSchema,
-};
-
-export type Packed<x extends keyof typeof refs> = SchemaType<typeof refs[x]>;
-
-type TypeStringef =
-	| "null"
-	| "boolean"
-	| "integer"
-	| "number"
-	| "string"
-	| "array"
-	| "object"
-	| "any";
-type StringDefToType<T extends TypeStringef> = T extends "null"
-	? null
-	: T extends "boolean"
-	? boolean
-	: T extends "integer"
-	? number
-	: T extends "number"
-	? number
-	: T extends "string"
-	? string | Date
-	: T extends "array"
-	? ReadonlyArray<any>
-	: T extends "object"
-	? Record<string, any>
-	: any;
-
-// https://swagger.io/specification/?sbsearch=optional#schema-object
-type OfSchema = {
-	readonly anyOf?: ReadonlyArray<Schema>;
-	readonly oneOf?: ReadonlyArray<Schema>;
-	readonly allOf?: ReadonlyArray<Schema>;
-};
-
-export interface Schema extends OfSchema {
-	readonly type?: TypeStringef;
-	readonly nullable?: boolean;
-	readonly optional?: boolean;
-	readonly items?: Schema;
-	readonly properties?: Obj;
-	readonly required?: ReadonlyArray<
-		Extract<keyof NonNullable<this["properties"]>, string>
-	>;
-	readonly description?: string;
-	readonly example?: any;
-	readonly format?: string;
-	readonly ref?: keyof typeof refs;
-	readonly enum?: ReadonlyArray<string>;
-	readonly default?:
-		| (this["type"] extends TypeStringef ? StringDefToType<this["type"]> : any)
-		| null;
-	readonly maxLength?: number;
-	readonly minLength?: number;
-	readonly maximum?: number;
-	readonly minimum?: number;
-	readonly pattern?: string;
-}
-
-type RequiredPropertyNames<s extends Obj> = {
-	[K in keyof s]: // K is not optional
-	s[K]["optional"] extends false
-		? K
-		: // K has default value
-		s[K]["default"] extends
-				| null
-				| string
-				| number
-				| boolean
-				| Record<string, unknown>
-		? K
-		: never;
-}[keyof s];
-
-export type Obj = Record<string, Schema>;
-
-// https://github.com/misskey-dev/misskey/issues/8535
-// To avoid excessive stack depth error,
-// deceive TypeScript with UnionToIntersection (or more precisely, `infer` expression within it).
-export type ObjType<
-	s extends Obj,
-	RequiredProps extends keyof s,
-> = UnionToIntersection<
-	{
-		-readonly [R in RequiredPropertyNames<s>]-?: SchemaType<s[R]>;
-	} & {
-		-readonly [R in RequiredProps]-?: SchemaType<s[R]>;
-	} & {
-		-readonly [P in keyof s]?: SchemaType<s[P]>;
-	}
->;
-
-type NullOrUndefined<p extends Schema, T> =
-	| (p["nullable"] extends true ? null : never)
-	| (p["optional"] extends true ? undefined : never)
-	| T;
-
-// https://stackoverflow.com/questions/54938141/typescript-convert-union-to-intersection
-// Get intersection from union
-type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
-	k: infer I,
-) => void
-	? I
-	: never;
-
-// https://github.com/misskey-dev/misskey/pull/8144#discussion_r785287552
-// To get union, we use `Foo extends any ? Hoge<Foo> : never`
-type UnionSchemaType<
-	a extends readonly any[],
-	X extends Schema = a[number],
-> = X extends any ? SchemaType<X> : never;
-type ArrayUnion<T> = T extends any ? Array<T> : never;
-
-export type SchemaTypeDef<p extends Schema> = p["type"] extends "null"
-	? null
-	: p["type"] extends "integer"
-	? number
-	: p["type"] extends "number"
-	? number
-	: p["type"] extends "string"
-	? p["enum"] extends readonly string[]
-		? p["enum"][number]
-		: p["format"] extends "date-time"
-		? string
-		: // Dateにする??
-		  string
-	: p["type"] extends "boolean"
-	? boolean
-	: p["type"] extends "object"
-	? p["ref"] extends keyof typeof refs
-		? Packed<p["ref"]>
-		: p["properties"] extends NonNullable<Obj>
-		? ObjType<p["properties"], NonNullable<p["required"]>[number]>
-		: p["anyOf"] extends ReadonlyArray<Schema>
-		? UnionSchemaType<p["anyOf"]> &
-				Partial<UnionToIntersection<UnionSchemaType<p["anyOf"]>>>
-		: p["allOf"] extends ReadonlyArray<Schema>
-		? UnionToIntersection<UnionSchemaType<p["allOf"]>>
-		: any
-	: p["type"] extends "array"
-	? p["items"] extends OfSchema
-		? p["items"]["anyOf"] extends ReadonlyArray<Schema>
-			? UnionSchemaType<NonNullable<p["items"]["anyOf"]>>[]
-			: p["items"]["oneOf"] extends ReadonlyArray<Schema>
-			? ArrayUnion<UnionSchemaType<NonNullable<p["items"]["oneOf"]>>>
-			: p["items"]["allOf"] extends ReadonlyArray<Schema>
-			? UnionToIntersection<UnionSchemaType<NonNullable<p["items"]["allOf"]>>>[]
-			: never
-		: p["items"] extends NonNullable<Schema>
-		? SchemaTypeDef<p["items"]>[]
-		: any[]
-	: p["oneOf"] extends ReadonlyArray<Schema>
-	? UnionSchemaType<p["oneOf"]>
-	: any;
-
-export type SchemaType<p extends Schema> = NullOrUndefined<p, SchemaTypeDef<p>>;
diff --git a/packages/backend/src/misc/secure-rndstr.ts b/packages/backend/src/misc/secure-rndstr.ts
deleted file mode 100644
index 7f5754e1c5..0000000000
--- a/packages/backend/src/misc/secure-rndstr.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import * as crypto from "node:crypto";
-
-const L_CHARS = "0123456789abcdefghijklmnopqrstuvwxyz";
-const LU_CHARS =
-	"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
-
-export function secureRndstr(length = 32, useLU = true): string {
-	const chars = useLU ? LU_CHARS : L_CHARS;
-	const chars_len = chars.length;
-
-	let str = "";
-
-	for (let i = 0; i < length; i++) {
-		let rand = Math.floor(
-			(crypto.randomBytes(1).readUInt8(0) / 0xff) * chars_len,
-		);
-		if (rand === chars_len) {
-			rand = chars_len - 1;
-		}
-		str += chars.charAt(rand);
-	}
-
-	return str;
-}
diff --git a/packages/backend/src/misc/should-block-instance.ts b/packages/backend/src/misc/should-block-instance.ts
deleted file mode 100644
index 6e46232428..0000000000
--- a/packages/backend/src/misc/should-block-instance.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import type { Instance } from "@/models/entities/instance.js";
-import type { Meta } from "@/models/entities/meta.js";
-
-/**
- * Returns whether a specific host (punycoded) should be blocked.
- *
- * @param host punycoded instance host
- * @param meta a resolved Meta table
- * @returns whether the given host should be blocked
- */
-export async function shouldBlockInstance(
-	host: Instance["host"],
-	meta?: Meta,
-): Promise<boolean> {
-	const { blockedHosts } = meta ?? (await fetchMeta());
-	return blockedHosts.some(
-		(blockedHost) => host === blockedHost || host.endsWith(`.${blockedHost}`),
-	);
-}
diff --git a/packages/backend/src/misc/show-machine-info.ts b/packages/backend/src/misc/show-machine-info.ts
deleted file mode 100644
index d3a28cbd37..0000000000
--- a/packages/backend/src/misc/show-machine-info.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import * as os from "node:os";
-import sysUtils from "systeminformation";
-import type Logger from "@/services/logger.js";
-
-export async function showMachineInfo(parentLogger: Logger) {
-	const logger = parentLogger.createSubLogger("machine");
-	logger.debug(`Hostname: ${os.hostname()}`);
-	logger.debug(`Platform: ${process.platform} Arch: ${process.arch}`);
-	const mem = await sysUtils.mem();
-	const totalmem = (mem.total / 1024 / 1024 / 1024).toFixed(1);
-	const availmem = (mem.available / 1024 / 1024 / 1024).toFixed(1);
-	logger.debug(
-		`CPU: ${
-			os.cpus().length
-		} core MEM: ${totalmem}GB (available: ${availmem}GB)`,
-	);
-}
diff --git a/packages/backend/src/misc/skipped-instances.ts b/packages/backend/src/misc/skipped-instances.ts
deleted file mode 100644
index 785393022a..0000000000
--- a/packages/backend/src/misc/skipped-instances.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-import { Brackets } from "typeorm";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { Instances } from "@/models/index.js";
-import type { Instance } from "@/models/entities/instance.js";
-import { DAY } from "@/const.js";
-import { shouldBlockInstance } from "./should-block-instance.js";
-
-// Threshold from last contact after which an instance will be considered
-// "dead" and should no longer get activities delivered to it.
-const deadThreshold = 7 * DAY;
-
-/**
- * Returns the subset of hosts which should be skipped.
- *
- * @param hosts array of punycoded instance hosts
- * @returns array of punycoed instance hosts that should be skipped (subset of hosts parameter)
- */
-export async function skippedInstances(
-	hosts: Instance["host"][],
-): Promise<Instance["host"][]> {
-	// first check for blocked instances since that info may already be in memory
-	const meta = await fetchMeta();
-	const shouldSkip = await Promise.all(
-		hosts.map((host) => shouldBlockInstance(host, meta)),
-	);
-	const skipped = hosts.filter((_, i) => shouldSkip[i]);
-
-	// if possible return early and skip accessing the database
-	if (skipped.length === hosts.length) return hosts;
-
-	const deadTime = new Date(Date.now() - deadThreshold);
-
-	return skipped.concat(
-		await Instances.createQueryBuilder("instance")
-			.where("instance.host in (:...hosts)", {
-				// don't check hosts again that we already know are suspended
-				// also avoids adding duplicates to the list
-				hosts: hosts.filter((host) => !skipped.includes(host)),
-			})
-			.andWhere(
-				new Brackets((qb) => {
-					qb.where("instance.isSuspended");
-				}),
-			)
-			.select("host")
-			.getRawMany(),
-	);
-}
-
-/**
- * Returns whether a specific host (punycoded) should be skipped.
- * Convenience wrapper around skippedInstances which should only be used if there is a single host to check.
- * If you have multiple hosts, consider using skippedInstances instead to do a bulk check.
- *
- * @param host punycoded instance host
- * @returns whether the given host should be skipped
- */
-export async function shouldSkipInstance(
-	host: Instance["host"],
-): Promise<boolean> {
-	const skipped = await skippedInstances([host]);
-	return skipped.length > 0;
-}
diff --git a/packages/backend/src/misc/truncate.ts b/packages/backend/src/misc/truncate.ts
deleted file mode 100644
index 6bc58941a2..0000000000
--- a/packages/backend/src/misc/truncate.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { substring } from "stringz";
-
-export function truncate(input: string, size: number): string;
-export function truncate(
-	input: string | undefined,
-	size: number,
-): string | undefined;
-export function truncate(
-	input: string | undefined,
-	size: number,
-): string | undefined {
-	if (!input) {
-		return input;
-	} else {
-		return substring(input, 0, size);
-	}
-}
diff --git a/packages/backend/src/misc/webhook-cache.ts b/packages/backend/src/misc/webhook-cache.ts
deleted file mode 100644
index 1eda5eaecd..0000000000
--- a/packages/backend/src/misc/webhook-cache.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import { Webhooks } from "@/models/index.js";
-import type { Webhook } from "@/models/entities/webhook.js";
-import { subscriber } from "@/db/redis.js";
-
-let webhooksFetched = false;
-let webhooks: Webhook[] = [];
-
-export async function getActiveWebhooks() {
-	if (!webhooksFetched) {
-		webhooks = await Webhooks.findBy({
-			active: true,
-		});
-		webhooksFetched = true;
-	}
-
-	return webhooks;
-}
-
-subscriber.on("message", async (_, data) => {
-	const obj = JSON.parse(data);
-
-	if (obj.channel === "internal") {
-		const { type, body } = obj.message;
-		switch (type) {
-			case "webhookCreated":
-				if (body.active) {
-					webhooks.push(body);
-				}
-				break;
-			case "webhookUpdated":
-				if (body.active) {
-					const i = webhooks.findIndex((a) => a.id === body.id);
-					if (i > -1) {
-						webhooks[i] = body;
-					} else {
-						webhooks.push(body);
-					}
-				} else {
-					webhooks = webhooks.filter((a) => a.id !== body.id);
-				}
-				break;
-			case "webhookDeleted":
-				webhooks = webhooks.filter((a) => a.id !== body.id);
-				break;
-			default:
-				break;
-		}
-	}
-});
diff --git a/packages/backend/src/models/entities/abuse-user-report.ts b/packages/backend/src/models/entities/abuse-user-report.ts
deleted file mode 100644
index 655fdd3ca6..0000000000
--- a/packages/backend/src/models/entities/abuse-user-report.ts
+++ /dev/null
@@ -1,86 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-} from "typeorm";
-import { User } from "./user.js";
-import { id } from "../id.js";
-
-@Entity()
-export class AbuseUserReport {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Index()
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the AbuseUserReport.',
-	})
-	public createdAt: Date;
-
-	@Index()
-	@Column(id())
-	public targetUserId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public targetUser: User | null;
-
-	@Index()
-	@Column(id())
-	public reporterId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public reporter: User | null;
-
-	@Column({
-		...id(),
-		nullable: true,
-	})
-	public assigneeId: User["id"] | null;
-
-	@ManyToOne(type => User, {
-		onDelete: 'SET NULL',
-	})
-	@JoinColumn()
-	public assignee: User | null;
-
-	@Index()
-	@Column('boolean', {
-		default: false,
-	})
-	public resolved: boolean;
-
-	@Column('boolean', {
-		default: false
-	})
-	public forwarded: boolean;
-
-	@Column('varchar', {
-		length: 2048,
-	})
-	public comment: string;
-
-	//#region Denormalized fields
-	@Index()
-	@Column('varchar', {
-		length: 128, nullable: true,
-		comment: '[Denormalized]',
-	})
-	public targetUserHost: string | null;
-
-	@Index()
-	@Column('varchar', {
-		length: 128, nullable: true,
-		comment: '[Denormalized]',
-	})
-	public reporterHost: string | null;
-	//#endregion
-}
diff --git a/packages/backend/src/models/entities/access-token.ts b/packages/backend/src/models/entities/access-token.ts
deleted file mode 100644
index 83d7bbda86..0000000000
--- a/packages/backend/src/models/entities/access-token.ts
+++ /dev/null
@@ -1,97 +0,0 @@
-import {
-	Entity,
-	PrimaryColumn,
-	Index,
-	Column,
-	ManyToOne,
-	JoinColumn,
-} from "typeorm";
-import { User } from "./user.js";
-import { App } from "./app.js";
-import { id } from "../id.js";
-
-@Entity()
-export class AccessToken {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the AccessToken.',
-	})
-	public createdAt: Date;
-
-	@Column('timestamp with time zone', {
-		nullable: true,
-	})
-	public lastUsedAt: Date | null;
-
-	@Index()
-	@Column('varchar', {
-		length: 128,
-	})
-	public token: string;
-
-	@Index()
-	@Column('varchar', {
-		length: 128,
-		nullable: true,
-	})
-	public session: string | null;
-
-	@Index()
-	@Column('varchar', {
-		length: 128,
-	})
-	public hash: string;
-
-	@Index()
-	@Column(id())
-	public userId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	@Column({
-		...id(),
-		nullable: true,
-	})
-	public appId: App["id"] | null;
-
-	@ManyToOne(type => App, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public app: App | null;
-
-	@Column('varchar', {
-		length: 128,
-		nullable: true,
-	})
-	public name: string | null;
-
-	@Column('varchar', {
-		length: 512,
-		nullable: true,
-	})
-	public description: string | null;
-
-	@Column('varchar', {
-		length: 512,
-		nullable: true,
-	})
-	public iconUrl: string | null;
-
-	@Column('varchar', {
-		length: 64, array: true,
-		default: '{}',
-	})
-	public permission: string[];
-
-	@Column('boolean', {
-		default: false,
-	})
-	public fetched: boolean;
-}
diff --git a/packages/backend/src/models/entities/ad.ts b/packages/backend/src/models/entities/ad.ts
deleted file mode 100644
index fa42973652..0000000000
--- a/packages/backend/src/models/entities/ad.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import { Entity, Index, Column, PrimaryColumn } from "typeorm";
-import { id } from "../id.js";
-
-@Entity()
-export class Ad {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Index()
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the Ad.',
-	})
-	public createdAt: Date;
-
-	@Index()
-	@Column('timestamp with time zone', {
-		comment: 'The expired date of the Ad.',
-	})
-	public expiresAt: Date;
-
-	@Column('varchar', {
-		length: 32, nullable: false,
-	})
-	public place: string;
-
-	// 今は使われていないが将来的に活用される可能性はある
-	@Column('varchar', {
-		length: 32, nullable: false,
-	})
-	public priority: string;
-
-	@Column('integer', {
-		default: 1, nullable: false,
-	})
-	public ratio: number;
-
-	@Column('varchar', {
-		length: 1024, nullable: false,
-	})
-	public url: string;
-
-	@Column('varchar', {
-		length: 1024, nullable: false,
-	})
-	public imageUrl: string;
-
-	@Column('varchar', {
-		length: 8192, nullable: false,
-	})
-	public memo: string;
-
-	constructor(data: Partial<Ad>) {
-		if (data == null) return;
-
-		for (const [k, v] of Object.entries(data)) {
-			(this as any)[k] = v;
-		}
-	}
-}
diff --git a/packages/backend/src/models/entities/announcement-read.ts b/packages/backend/src/models/entities/announcement-read.ts
deleted file mode 100644
index 87d0f0e9ed..0000000000
--- a/packages/backend/src/models/entities/announcement-read.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-} from "typeorm";
-import { User } from "./user.js";
-import { Announcement } from "./announcement.js";
-import { id } from "../id.js";
-
-@Entity()
-@Index(['userId', 'announcementId'], { unique: true })
-export class AnnouncementRead {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the AnnouncementRead.',
-	})
-	public createdAt: Date;
-
-	@Index()
-	@Column(id())
-	public userId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	@Index()
-	@Column(id())
-	public announcementId: Announcement["id"];
-
-	@ManyToOne(type => Announcement, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public announcement: Announcement | null;
-}
diff --git a/packages/backend/src/models/entities/announcement.ts b/packages/backend/src/models/entities/announcement.ts
deleted file mode 100644
index 9d45af0149..0000000000
--- a/packages/backend/src/models/entities/announcement.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import { Entity, Index, Column, PrimaryColumn } from "typeorm";
-import { id } from "../id.js";
-
-@Entity()
-export class Announcement {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Index()
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the Announcement.',
-	})
-	public createdAt: Date;
-
-	@Column('timestamp with time zone', {
-		comment: 'The updated date of the Announcement.',
-		nullable: true,
-	})
-	public updatedAt: Date | null;
-
-	@Column('varchar', {
-		length: 8192, nullable: false,
-	})
-	public text: string;
-
-	@Column('varchar', {
-		length: 256, nullable: false,
-	})
-	public title: string;
-
-	@Column('varchar', {
-		length: 1024, nullable: true,
-	})
-	public imageUrl: string | null;
-
-	constructor(data: Partial<Announcement>) {
-		if (data == null) return;
-
-		for (const [k, v] of Object.entries(data)) {
-			(this as any)[k] = v;
-		}
-	}
-}
diff --git a/packages/backend/src/models/entities/antenna-note.ts b/packages/backend/src/models/entities/antenna-note.ts
deleted file mode 100644
index c47c796bbf..0000000000
--- a/packages/backend/src/models/entities/antenna-note.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import {
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-	PrimaryColumn,
-} from "typeorm";
-import { Note } from "./note.js";
-import { Antenna } from "./antenna.js";
-import { id } from "../id.js";
-
-@Entity()
-@Index(['noteId', 'antennaId'], { unique: true })
-export class AntennaNote {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Index()
-	@Column({
-		...id(),
-		comment: 'The note ID.',
-	})
-	public noteId: Note["id"];
-
-	@ManyToOne(type => Note, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public note: Note | null;
-
-	@Index()
-	@Column({
-		...id(),
-		comment: 'The antenna ID.',
-	})
-	public antennaId: Antenna["id"];
-
-	@ManyToOne(type => Antenna, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public antenna: Antenna | null;
-
-	@Index()
-	@Column('boolean', {
-		default: false,
-	})
-	public read: boolean;
-}
diff --git a/packages/backend/src/models/entities/antenna.ts b/packages/backend/src/models/entities/antenna.ts
deleted file mode 100644
index c653b2a051..0000000000
--- a/packages/backend/src/models/entities/antenna.ts
+++ /dev/null
@@ -1,111 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-} from "typeorm";
-import { User } from "./user.js";
-import { id } from "../id.js";
-import { UserList } from "./user-list.js";
-import { UserGroupJoining } from "./user-group-joining.js";
-
-@Entity()
-export class Antenna {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the Antenna.',
-	})
-	public createdAt: Date;
-
-	@Index()
-	@Column({
-		...id(),
-		comment: 'The owner ID.',
-	})
-	public userId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	@Column('varchar', {
-		length: 128,
-		comment: 'The name of the Antenna.',
-	})
-	public name: string;
-
-	@Column('enum', { enum: ['home', 'all', 'users', 'list', 'group', 'instances'] })
-	public src: "home" | "all" | "users" | "list" | "group" | "instances";
-
-	@Column({
-		...id(),
-		nullable: true,
-	})
-	public userListId: UserList["id"] | null;
-
-	@ManyToOne(type => UserList, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public userList: UserList | null;
-
-	@Column({
-		...id(),
-		nullable: true,
-	})
-	public userGroupJoiningId: UserGroupJoining["id"] | null;
-
-	@ManyToOne(type => UserGroupJoining, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public userGroupJoining: UserGroupJoining | null;
-
-	@Column('varchar', {
-		length: 1024, array: true,
-		default: '{}',
-	})
-	public users: string[];
-
-	@Column('jsonb', {
-		default: [],
-	})
-	public instances: string[];
-
-	@Column('jsonb', {
-		default: [],
-	})
-	public keywords: string[][];
-
-	@Column('jsonb', {
-		default: [],
-	})
-	public excludeKeywords: string[][];
-
-	@Column('boolean', {
-		default: false,
-	})
-	public caseSensitive: boolean;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public withReplies: boolean;
-
-	@Column('boolean')
-	public withFile: boolean;
-
-	@Column('varchar', {
-		length: 2048, nullable: true,
-	})
-	public expression: string | null;
-
-	@Column('boolean')
-	public notify: boolean;
-}
diff --git a/packages/backend/src/models/entities/app.ts b/packages/backend/src/models/entities/app.ts
deleted file mode 100644
index bb33eede4f..0000000000
--- a/packages/backend/src/models/entities/app.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-import { Entity, PrimaryColumn, Column, Index, ManyToOne } from "typeorm";
-import { User } from "./user.js";
-import { id } from "../id.js";
-
-@Entity()
-export class App {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Index()
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the App.',
-	})
-	public createdAt: Date;
-
-	@Index()
-	@Column({
-		...id(),
-		nullable: true,
-		comment: 'The owner ID.',
-	})
-	public userId: User["id"] | null;
-
-	@ManyToOne(type => User, {
-		onDelete: 'SET NULL',
-		nullable: true,
-	})
-	public user: User | null;
-
-	@Index()
-	@Column('varchar', {
-		length: 64,
-		comment: 'The secret key of the App.',
-	})
-	public secret: string;
-
-	@Column('varchar', {
-		length: 128,
-		comment: 'The name of the App.',
-	})
-	public name: string;
-
-	@Column('varchar', {
-		length: 512,
-		comment: 'The description of the App.',
-	})
-	public description: string;
-
-	@Column('varchar', {
-		length: 64, array: true,
-		comment: 'The permission of the App.',
-	})
-	public permission: string[];
-
-	@Column('varchar', {
-		length: 512, nullable: true,
-		comment: 'The callbackUrl of the App.',
-	})
-	public callbackUrl: string | null;
-}
diff --git a/packages/backend/src/models/entities/attestation-challenge.ts b/packages/backend/src/models/entities/attestation-challenge.ts
deleted file mode 100644
index 7a87d42be0..0000000000
--- a/packages/backend/src/models/entities/attestation-challenge.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	JoinColumn,
-	Column,
-	ManyToOne,
-	Index,
-} from "typeorm";
-import { User } from "./user.js";
-import { id } from "../id.js";
-
-@Entity()
-export class AttestationChallenge {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Index()
-	@PrimaryColumn(id())
-	public userId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	@Index()
-	@Column('varchar', {
-		length: 64,
-		comment: 'Hex-encoded sha256 hash of the challenge.',
-	})
-	public challenge: string;
-
-	@Column('timestamp with time zone', {
-		comment: 'The date challenge was created for expiry purposes.',
-	})
-	public createdAt: Date;
-
-	@Column('boolean', {
-		comment:
-			'Indicates that the challenge is only for registration purposes if true to prevent the challenge for being used as authentication.',
-		default: false,
-	})
-	public registrationChallenge: boolean;
-
-	constructor(data: Partial<AttestationChallenge>) {
-		if (data == null) return;
-
-		for (const [k, v] of Object.entries(data)) {
-			(this as any)[k] = v;
-		}
-	}
-}
diff --git a/packages/backend/src/models/entities/auth-session.ts b/packages/backend/src/models/entities/auth-session.ts
deleted file mode 100644
index b762f84625..0000000000
--- a/packages/backend/src/models/entities/auth-session.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import {
-	Entity,
-	PrimaryColumn,
-	Index,
-	Column,
-	ManyToOne,
-	JoinColumn,
-} from "typeorm";
-import { User } from "./user.js";
-import { App } from "./app.js";
-import { id } from "../id.js";
-
-@Entity()
-export class AuthSession {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the AuthSession.',
-	})
-	public createdAt: Date;
-
-	@Index()
-	@Column('varchar', {
-		length: 128,
-	})
-	public token: string;
-
-	@Column({
-		...id(),
-		nullable: true,
-	})
-	public userId: User["id"] | null;
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-		nullable: true,
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	@Column(id())
-	public appId: App["id"];
-
-	@ManyToOne(type => App, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public app: App | null;
-}
diff --git a/packages/backend/src/models/entities/blocking.ts b/packages/backend/src/models/entities/blocking.ts
deleted file mode 100644
index 3a44a4d656..0000000000
--- a/packages/backend/src/models/entities/blocking.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-} from "typeorm";
-import { User } from "./user.js";
-import { id } from "../id.js";
-
-@Entity()
-@Index(['blockerId', 'blockeeId'], { unique: true })
-export class Blocking {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Index()
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the Blocking.',
-	})
-	public createdAt: Date;
-
-	@Index()
-	@Column({
-		...id(),
-		comment: 'The blockee user ID.',
-	})
-	public blockeeId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public blockee: User | null;
-
-	@Index()
-	@Column({
-		...id(),
-		comment: 'The blocker user ID.',
-	})
-	public blockerId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public blocker: User | null;
-}
diff --git a/packages/backend/src/models/entities/channel-following.ts b/packages/backend/src/models/entities/channel-following.ts
deleted file mode 100644
index 04ec193e19..0000000000
--- a/packages/backend/src/models/entities/channel-following.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-} from "typeorm";
-import { User } from "./user.js";
-import { id } from "../id.js";
-import { Channel } from "./channel.js";
-
-@Entity()
-@Index(['followerId', 'followeeId'], { unique: true })
-export class ChannelFollowing {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Index()
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the ChannelFollowing.',
-	})
-	public createdAt: Date;
-
-	@Index()
-	@Column({
-		...id(),
-		comment: 'The followee channel ID.',
-	})
-	public followeeId: Channel["id"];
-
-	@ManyToOne(type => Channel, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public followee: Channel | null;
-
-	@Index()
-	@Column({
-		...id(),
-		comment: 'The follower user ID.',
-	})
-	public followerId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public follower: User | null;
-}
diff --git a/packages/backend/src/models/entities/channel-note-pining.ts b/packages/backend/src/models/entities/channel-note-pining.ts
deleted file mode 100644
index bd13f4ca39..0000000000
--- a/packages/backend/src/models/entities/channel-note-pining.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-} from "typeorm";
-import { Note } from "./note.js";
-import { Channel } from "./channel.js";
-import { id } from "../id.js";
-
-@Entity()
-@Index(['channelId', 'noteId'], { unique: true })
-export class ChannelNotePining {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the ChannelNotePining.',
-	})
-	public createdAt: Date;
-
-	@Index()
-	@Column(id())
-	public channelId: Channel["id"];
-
-	@ManyToOne(type => Channel, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public channel: Channel | null;
-
-	@Column(id())
-	public noteId: Note["id"];
-
-	@ManyToOne(type => Note, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public note: Note | null;
-}
diff --git a/packages/backend/src/models/entities/channel.ts b/packages/backend/src/models/entities/channel.ts
deleted file mode 100644
index 7f9851dbf9..0000000000
--- a/packages/backend/src/models/entities/channel.ts
+++ /dev/null
@@ -1,82 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-} from "typeorm";
-import { User } from "./user.js";
-import { id } from "../id.js";
-import { DriveFile } from "./drive-file.js";
-
-@Entity()
-export class Channel {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Index()
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the Channel.',
-	})
-	public createdAt: Date;
-
-	@Index()
-	@Column('timestamp with time zone', {
-		nullable: true,
-	})
-	public lastNotedAt: Date | null;
-
-	@Index()
-	@Column({
-		...id(),
-		nullable: true,
-		comment: 'The owner ID.',
-	})
-	public userId: User["id"] | null;
-
-	@ManyToOne(type => User, {
-		onDelete: 'SET NULL',
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	@Column('varchar', {
-		length: 128,
-		comment: 'The name of the Channel.',
-	})
-	public name: string;
-
-	@Column('varchar', {
-		length: 2048, nullable: true,
-		comment: 'The description of the Channel.',
-	})
-	public description: string | null;
-
-	@Column({
-		...id(),
-		nullable: true,
-		comment: 'The ID of banner Channel.',
-	})
-	public bannerId: DriveFile["id"] | null;
-
-	@ManyToOne(type => DriveFile, {
-		onDelete: 'SET NULL',
-	})
-	@JoinColumn()
-	public banner: DriveFile | null;
-
-	@Index()
-	@Column('integer', {
-		default: 0,
-		comment: 'The count of notes.',
-	})
-	public notesCount: number;
-
-	@Index()
-	@Column('integer', {
-		default: 0,
-		comment: 'The count of users.',
-	})
-	public usersCount: number;
-}
diff --git a/packages/backend/src/models/entities/clip-note.ts b/packages/backend/src/models/entities/clip-note.ts
deleted file mode 100644
index bc51daaf4d..0000000000
--- a/packages/backend/src/models/entities/clip-note.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import {
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-	PrimaryColumn,
-} from "typeorm";
-import { Note } from "./note.js";
-import { Clip } from "./clip.js";
-import { id } from "../id.js";
-
-@Entity()
-@Index(['noteId', 'clipId'], { unique: true })
-export class ClipNote {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Index()
-	@Column({
-		...id(),
-		comment: 'The note ID.',
-	})
-	public noteId: Note["id"];
-
-	@ManyToOne(type => Note, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public note: Note | null;
-
-	@Index()
-	@Column({
-		...id(),
-		comment: 'The clip ID.',
-	})
-	public clipId: Clip["id"];
-
-	@ManyToOne(type => Clip, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public clip: Clip | null;
-}
diff --git a/packages/backend/src/models/entities/clip.ts b/packages/backend/src/models/entities/clip.ts
deleted file mode 100644
index 10591cbeef..0000000000
--- a/packages/backend/src/models/entities/clip.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-} from "typeorm";
-import { User } from "./user.js";
-import { id } from "../id.js";
-
-@Entity()
-export class Clip {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the Clip.',
-	})
-	public createdAt: Date;
-
-	@Index()
-	@Column({
-		...id(),
-		comment: 'The owner ID.',
-	})
-	public userId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	@Column('varchar', {
-		length: 128,
-		comment: 'The name of the Clip.',
-	})
-	public name: string;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public isPublic: boolean;
-
-	@Column('varchar', {
-		length: 2048, nullable: true,
-		comment: 'The description of the Clip.',
-	})
-	public description: string | null;
-}
diff --git a/packages/backend/src/models/entities/drive-file.ts b/packages/backend/src/models/entities/drive-file.ts
deleted file mode 100644
index 32e19bc6ee..0000000000
--- a/packages/backend/src/models/entities/drive-file.ts
+++ /dev/null
@@ -1,206 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-} from "typeorm";
-import { id } from "../id.js";
-import { User } from "./user.js";
-import { DriveFolder } from "./drive-folder.js";
-import { DB_MAX_IMAGE_COMMENT_LENGTH } from "@/misc/hard-limits.js";
-
-@Entity()
-@Index(['userId', 'folderId', 'id'])
-export class DriveFile {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Index()
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the DriveFile.',
-	})
-	public createdAt: Date;
-
-	@Index()
-	@Column({
-		...id(),
-		nullable: true,
-		comment: 'The owner ID.',
-	})
-	public userId: User["id"] | null;
-
-	@ManyToOne(type => User, {
-		onDelete: 'SET NULL',
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	@Index()
-	@Column('varchar', {
-		length: 128, nullable: true,
-		comment: 'The host of owner. It will be null if the user in local.',
-	})
-	public userHost: string | null;
-
-	@Index()
-	@Column('varchar', {
-		length: 32,
-		comment: 'The MD5 hash of the DriveFile.',
-	})
-	public md5: string;
-
-	@Column('varchar', {
-		length: 256,
-		comment: 'The file name of the DriveFile.',
-	})
-	public name: string;
-
-	@Index()
-	@Column('varchar', {
-		length: 128,
-		comment: 'The content type (MIME) of the DriveFile.',
-	})
-	public type: string;
-
-	@Column('integer', {
-		comment: 'The file size (bytes) of the DriveFile.',
-	})
-	public size: number;
-
-	@Column('varchar', {
-		length: DB_MAX_IMAGE_COMMENT_LENGTH,
-		nullable: true,
-		comment: 'The comment of the DriveFile.',
-	})
-	public comment: string | null;
-
-	@Column('varchar', {
-		length: 128, nullable: true,
-		comment: 'The BlurHash string.',
-	})
-	public blurhash: string | null;
-
-	@Column('jsonb', {
-		default: {},
-		comment: 'The any properties of the DriveFile. For example, it includes image width/height.',
-	})
-	public properties: {
-		width?: number;
-		height?: number;
-		orientation?: number;
-		avgColor?: string;
-	};
-
-	@Column('boolean')
-	public storedInternal: boolean;
-
-	@Column('varchar', {
-		length: 512,
-		comment: 'The URL of the DriveFile.',
-	})
-	public url: string;
-
-	@Column('varchar', {
-		length: 512, nullable: true,
-		comment: 'The URL of the thumbnail of the DriveFile.',
-	})
-	public thumbnailUrl: string | null;
-
-	@Column('varchar', {
-		length: 512, nullable: true,
-		comment: 'The URL of the webpublic of the DriveFile.',
-	})
-	public webpublicUrl: string | null;
-
-	@Column('varchar', {
-		length: 128, nullable: true,
-	})
-	public webpublicType: string | null;
-
-	@Index({ unique: true })
-	@Column('varchar', {
-		length: 256, nullable: true,
-	})
-	public accessKey: string | null;
-
-	@Index({ unique: true })
-	@Column('varchar', {
-		length: 256, nullable: true,
-	})
-	public thumbnailAccessKey: string | null;
-
-	@Index({ unique: true })
-	@Column('varchar', {
-		length: 256, nullable: true,
-	})
-	public webpublicAccessKey: string | null;
-
-	@Index()
-	@Column('varchar', {
-		length: 512, nullable: true,
-		comment: 'The URI of the DriveFile. it will be null when the DriveFile is local.',
-	})
-	public uri: string | null;
-
-	@Column('varchar', {
-		length: 512, nullable: true,
-	})
-	public src: string | null;
-
-	@Index()
-	@Column({
-		...id(),
-		nullable: true,
-		comment: 'The parent folder ID. If null, it means the DriveFile is located in root.',
-	})
-	public folderId: DriveFolder["id"] | null;
-
-	@ManyToOne(type => DriveFolder, {
-		onDelete: 'SET NULL',
-	})
-	@JoinColumn()
-	public folder: DriveFolder | null;
-
-	@Index()
-	@Column('boolean', {
-		default: false,
-		comment: 'Whether the DriveFile is NSFW.',
-	})
-	public isSensitive: boolean;
-
-	@Index()
-	@Column('boolean', {
-		default: false,
-		comment: 'Whether the DriveFile is NSFW. (predict)',
-	})
-	public maybeSensitive: boolean;
-
-	@Index()
-	@Column('boolean', {
-		default: false,
-	})
-	public maybePorn: boolean;
-
-	/**
-	 * 外部の(信頼されていない)URLへの直リンクか否か
-	 */
-	@Index()
-	@Column('boolean', {
-		default: false,
-		comment: 'Whether the DriveFile is direct link to remote server.',
-	})
-	public isLink: boolean;
-
-	@Column('jsonb', {
-		default: {},
-		nullable: true,
-	})
-	public requestHeaders: Record<string, string> | null;
-
-	@Column('varchar', {
-		length: 128, nullable: true,
-	})
-	public requestIp: string | null;
-}
diff --git a/packages/backend/src/models/entities/drive-folder.ts b/packages/backend/src/models/entities/drive-folder.ts
deleted file mode 100644
index 77031ce4ea..0000000000
--- a/packages/backend/src/models/entities/drive-folder.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-import {
-	JoinColumn,
-	ManyToOne,
-	Entity,
-	PrimaryColumn,
-	Index,
-	Column,
-} from "typeorm";
-import { User } from "./user.js";
-import { id } from "../id.js";
-
-@Entity()
-export class DriveFolder {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Index()
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the DriveFolder.',
-	})
-	public createdAt: Date;
-
-	@Column('varchar', {
-		length: 128,
-		comment: 'The name of the DriveFolder.',
-	})
-	public name: string;
-
-	@Index()
-	@Column({
-		...id(),
-		nullable: true,
-		comment: 'The owner ID.',
-	})
-	public userId: User["id"] | null;
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	@Index()
-	@Column({
-		...id(),
-		nullable: true,
-		comment: 'The parent folder ID. If null, it means the DriveFolder is located in root.',
-	})
-	public parentId: DriveFolder["id"] | null;
-
-	@ManyToOne(type => DriveFolder, {
-		onDelete: 'SET NULL',
-	})
-	@JoinColumn()
-	public parent: DriveFolder | null;
-}
diff --git a/packages/backend/src/models/entities/emoji.ts b/packages/backend/src/models/entities/emoji.ts
deleted file mode 100644
index 2315686968..0000000000
--- a/packages/backend/src/models/entities/emoji.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-import { PrimaryColumn, Entity, Index, Column } from "typeorm";
-import { id } from "../id.js";
-
-@Entity()
-@Index(['name', 'host'], { unique: true })
-export class Emoji {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Column('timestamp with time zone', {
-		nullable: true,
-	})
-	public updatedAt: Date | null;
-
-	@Index()
-	@Column('varchar', {
-		length: 128,
-	})
-	public name: string;
-
-	@Index()
-	@Column('varchar', {
-		length: 128, nullable: true,
-	})
-	public host: string | null;
-
-	@Column('varchar', {
-		length: 128, nullable: true,
-	})
-	public category: string | null;
-
-	@Column('varchar', {
-		length: 512,
-	})
-	public originalUrl: string;
-
-	@Column('varchar', {
-		length: 512,
-		default: '',
-	})
-	public publicUrl: string;
-
-	@Column('varchar', {
-		length: 512, nullable: true,
-	})
-	public uri: string | null;
-
-	// publicUrlの方のtypeが入る
-	@Column('varchar', {
-		length: 64, nullable: true,
-	})
-	public type: string | null;
-
-	@Column('varchar', {
-		array: true, length: 128, default: '{}',
-	})
-	public aliases: string[];
-
-	@Column('varchar', {
-		length: 1024, nullable: true,
-	})
-	public license: string | null;
-}
diff --git a/packages/backend/src/models/entities/follow-request.ts b/packages/backend/src/models/entities/follow-request.ts
deleted file mode 100644
index 658fed5a5e..0000000000
--- a/packages/backend/src/models/entities/follow-request.ts
+++ /dev/null
@@ -1,92 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-} from "typeorm";
-import { User } from "./user.js";
-import { id } from "../id.js";
-
-@Entity()
-@Index(['followerId', 'followeeId'], { unique: true })
-export class FollowRequest {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the FollowRequest.',
-	})
-	public createdAt: Date;
-
-	@Index()
-	@Column({
-		...id(),
-		comment: 'The followee user ID.',
-	})
-	public followeeId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public followee: User | null;
-
-	@Index()
-	@Column({
-		...id(),
-		comment: 'The follower user ID.',
-	})
-	public followerId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public follower: User | null;
-
-	@Column('varchar', {
-		length: 128, nullable: true,
-		comment: 'id of Follow Activity.',
-	})
-	public requestId: string | null;
-
-	//#region Denormalized fields
-	@Column('varchar', {
-		length: 128, nullable: true,
-		comment: '[Denormalized]',
-	})
-	public followerHost: string | null;
-
-	@Column('varchar', {
-		length: 512, nullable: true,
-		comment: '[Denormalized]',
-	})
-	public followerInbox: string | null;
-
-	@Column('varchar', {
-		length: 512, nullable: true,
-		comment: '[Denormalized]',
-	})
-	public followerSharedInbox: string | null;
-
-	@Column('varchar', {
-		length: 128, nullable: true,
-		comment: '[Denormalized]',
-	})
-	public followeeHost: string | null;
-
-	@Column('varchar', {
-		length: 512, nullable: true,
-		comment: '[Denormalized]',
-	})
-	public followeeInbox: string | null;
-
-	@Column('varchar', {
-		length: 512, nullable: true,
-		comment: '[Denormalized]',
-	})
-	public followeeSharedInbox: string | null;
-	//#endregion
-}
diff --git a/packages/backend/src/models/entities/following.ts b/packages/backend/src/models/entities/following.ts
deleted file mode 100644
index 11f633fcd8..0000000000
--- a/packages/backend/src/models/entities/following.ts
+++ /dev/null
@@ -1,89 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-} from "typeorm";
-import { User } from "./user.js";
-import { id } from "../id.js";
-
-@Entity()
-@Index(['followerId', 'followeeId'], { unique: true })
-export class Following {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Index()
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the Following.',
-	})
-	public createdAt: Date;
-
-	@Index()
-	@Column({
-		...id(),
-		comment: 'The followee user ID.',
-	})
-	public followeeId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public followee: User | null;
-
-	@Index()
-	@Column({
-		...id(),
-		comment: 'The follower user ID.',
-	})
-	public followerId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public follower: User | null;
-
-	//#region Denormalized fields
-	@Index()
-	@Column('varchar', {
-		length: 128, nullable: true,
-		comment: '[Denormalized]',
-	})
-	public followerHost: string | null;
-
-	@Column('varchar', {
-		length: 512, nullable: true,
-		comment: '[Denormalized]',
-	})
-	public followerInbox: string | null;
-
-	@Column('varchar', {
-		length: 512, nullable: true,
-		comment: '[Denormalized]',
-	})
-	public followerSharedInbox: string | null;
-
-	@Index()
-	@Column('varchar', {
-		length: 128, nullable: true,
-		comment: '[Denormalized]',
-	})
-	public followeeHost: string | null;
-
-	@Column('varchar', {
-		length: 512, nullable: true,
-		comment: '[Denormalized]',
-	})
-	public followeeInbox: string | null;
-
-	@Column('varchar', {
-		length: 512, nullable: true,
-		comment: '[Denormalized]',
-	})
-	public followeeSharedInbox: string | null;
-	//#endregion
-}
diff --git a/packages/backend/src/models/entities/gallery-like.ts b/packages/backend/src/models/entities/gallery-like.ts
deleted file mode 100644
index e74e3c3ce5..0000000000
--- a/packages/backend/src/models/entities/gallery-like.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-} from "typeorm";
-import { User } from "./user.js";
-import { id } from "../id.js";
-import { GalleryPost } from "./gallery-post.js";
-
-@Entity()
-@Index(['userId', 'postId'], { unique: true })
-export class GalleryLike {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Column('timestamp with time zone')
-	public createdAt: Date;
-
-	@Index()
-	@Column(id())
-	public userId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	@Column(id())
-	public postId: GalleryPost["id"];
-
-	@ManyToOne(type => GalleryPost, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public post: GalleryPost | null;
-}
diff --git a/packages/backend/src/models/entities/gallery-post.ts b/packages/backend/src/models/entities/gallery-post.ts
deleted file mode 100644
index a79bb88353..0000000000
--- a/packages/backend/src/models/entities/gallery-post.ts
+++ /dev/null
@@ -1,86 +0,0 @@
-import {
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	PrimaryColumn,
-	ManyToOne,
-} from "typeorm";
-import { User } from "./user.js";
-import { id } from "../id.js";
-import type { DriveFile } from "./drive-file.js";
-
-@Entity()
-export class GalleryPost {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Index()
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the GalleryPost.',
-	})
-	public createdAt: Date;
-
-	@Index()
-	@Column('timestamp with time zone', {
-		comment: 'The updated date of the GalleryPost.',
-	})
-	public updatedAt: Date;
-
-	@Column('varchar', {
-		length: 256,
-	})
-	public title: string;
-
-	@Column('varchar', {
-		length: 2048, nullable: true,
-	})
-	public description: string | null;
-
-	@Index()
-	@Column({
-		...id(),
-		comment: 'The ID of author.',
-	})
-	public userId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	@Index()
-	@Column({
-		...id(),
-		array: true, default: '{}',
-	})
-	public fileIds: DriveFile["id"][];
-
-	@Index()
-	@Column('boolean', {
-		default: false,
-		comment: 'Whether the post is sensitive.',
-	})
-	public isSensitive: boolean;
-
-	@Index()
-	@Column('integer', {
-		default: 0,
-	})
-	public likedCount: number;
-
-	@Index()
-	@Column('varchar', {
-		length: 128, array: true, default: '{}',
-	})
-	public tags: string[];
-
-	constructor(data: Partial<GalleryPost>) {
-		if (data == null) return;
-
-		for (const [k, v] of Object.entries(data)) {
-			(this as any)[k] = v;
-		}
-	}
-}
diff --git a/packages/backend/src/models/entities/hashtag.ts b/packages/backend/src/models/entities/hashtag.ts
deleted file mode 100644
index 06fa004be4..0000000000
--- a/packages/backend/src/models/entities/hashtag.ts
+++ /dev/null
@@ -1,87 +0,0 @@
-import { Entity, PrimaryColumn, Index, Column } from "typeorm";
-import type { User } from "./user.js";
-import { id } from "../id.js";
-
-@Entity()
-export class Hashtag {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Index({ unique: true })
-	@Column('varchar', {
-		length: 128,
-	})
-	public name: string;
-
-	@Column({
-		...id(),
-		array: true,
-	})
-	public mentionedUserIds: User["id"][];
-
-	@Index()
-	@Column('integer', {
-		default: 0,
-	})
-	public mentionedUsersCount: number;
-
-	@Column({
-		...id(),
-		array: true,
-	})
-	public mentionedLocalUserIds: User["id"][];
-
-	@Index()
-	@Column('integer', {
-		default: 0,
-	})
-	public mentionedLocalUsersCount: number;
-
-	@Column({
-		...id(),
-		array: true,
-	})
-	public mentionedRemoteUserIds: User["id"][];
-
-	@Index()
-	@Column('integer', {
-		default: 0,
-	})
-	public mentionedRemoteUsersCount: number;
-
-	@Column({
-		...id(),
-		array: true,
-	})
-	public attachedUserIds: User["id"][];
-
-	@Index()
-	@Column('integer', {
-		default: 0,
-	})
-	public attachedUsersCount: number;
-
-	@Column({
-		...id(),
-		array: true,
-	})
-	public attachedLocalUserIds: User["id"][];
-
-	@Index()
-	@Column('integer', {
-		default: 0,
-	})
-	public attachedLocalUsersCount: number;
-
-	@Column({
-		...id(),
-		array: true,
-	})
-	public attachedRemoteUserIds: User["id"][];
-
-	@Index()
-	@Column('integer', {
-		default: 0,
-	})
-	public attachedRemoteUsersCount: number;
-}
diff --git a/packages/backend/src/models/entities/instance.ts b/packages/backend/src/models/entities/instance.ts
deleted file mode 100644
index 2b118455db..0000000000
--- a/packages/backend/src/models/entities/instance.ts
+++ /dev/null
@@ -1,164 +0,0 @@
-import { Entity, PrimaryColumn, Index, Column } from "typeorm";
-import { id } from "../id.js";
-
-@Entity()
-export class Instance {
-	@PrimaryColumn(id())
-	public id: string;
-
-	/**
-	 * このインスタンスを捕捉した日時
-	 */
-	@Index()
-	@Column('timestamp with time zone', {
-		comment: 'The caught date of the Instance.',
-	})
-	public caughtAt: Date;
-
-	/**
-	 * ホスト
-	 */
-	@Index({ unique: true })
-	@Column('varchar', {
-		length: 128,
-		comment: 'The host of the Instance.',
-	})
-	public host: string;
-
-	/**
-	 * インスタンスのユーザー数
-	 */
-	@Column('integer', {
-		default: 0,
-		comment: 'The count of the users of the Instance.',
-	})
-	public usersCount: number;
-
-	/**
-	 * インスタンスの投稿数
-	 */
-	@Column('integer', {
-		default: 0,
-		comment: 'The count of the notes of the Instance.',
-	})
-	public notesCount: number;
-
-	/**
-	 * このインスタンスのユーザーからフォローされている、自インスタンスのユーザーの数
-	 */
-	@Column('integer', {
-		default: 0,
-	})
-	public followingCount: number;
-
-	/**
-	 * このインスタンスのユーザーをフォローしている、自インスタンスのユーザーの数
-	 */
-	@Column('integer', {
-		default: 0,
-	})
-	public followersCount: number;
-
-	/**
-	 * 直近のリクエスト送信日時
-	 */
-	@Column('timestamp with time zone', {
-		nullable: true,
-	})
-	public latestRequestSentAt: Date | null;
-
-	/**
-	 * 直近のリクエスト送信時のHTTPステータスコード
-	 */
-	@Column('integer', {
-		nullable: true,
-	})
-	public latestStatus: number | null;
-
-	/**
-	 * 直近のリクエスト受信日時
-	 */
-	@Column('timestamp with time zone', {
-		nullable: true,
-	})
-	public latestRequestReceivedAt: Date | null;
-
-	/**
-	 * このインスタンスと最後にやり取りした日時
-	 */
-	@Column('timestamp with time zone')
-	public lastCommunicatedAt: Date;
-
-	/**
-	 * このインスタンスと不通かどうか
-	 */
-	@Column('boolean', {
-		default: false,
-	})
-	public isNotResponding: boolean;
-
-	/**
-	 * このインスタンスへの配信を停止するか
-	 */
-	@Index()
-	@Column('boolean', {
-		default: false,
-	})
-	public isSuspended: boolean;
-
-	@Column('varchar', {
-		length: 64, nullable: true,
-		comment: 'The software of the Instance.',
-	})
-	public softwareName: string | null;
-
-	@Column('varchar', {
-		length: 64, nullable: true,
-	})
-	public softwareVersion: string | null;
-
-	@Column('boolean', {
-		nullable: true,
-	})
-	public openRegistrations: boolean | null;
-
-	@Column('varchar', {
-		length: 256, nullable: true,
-	})
-	public name: string | null;
-
-	@Column('varchar', {
-		length: 4096, nullable: true,
-	})
-	public description: string | null;
-
-	@Column('varchar', {
-		length: 128, nullable: true,
-	})
-	public maintainerName: string | null;
-
-	@Column('varchar', {
-		length: 256, nullable: true,
-	})
-	public maintainerEmail: string | null;
-
-	@Column('varchar', {
-		length: 256, nullable: true,
-	})
-	public iconUrl: string | null;
-
-	@Column('varchar', {
-		length: 256, nullable: true,
-	})
-	public faviconUrl: string | null;
-
-	@Column('varchar', {
-		length: 64, nullable: true,
-	})
-	public themeColor: string | null;
-
-	@Column('timestamp with time zone', {
-		nullable: true,
-	})
-	public infoUpdatedAt: Date | null;
-}
diff --git a/packages/backend/src/models/entities/messaging-message.ts b/packages/backend/src/models/entities/messaging-message.ts
deleted file mode 100644
index 9cf197fa3b..0000000000
--- a/packages/backend/src/models/entities/messaging-message.ts
+++ /dev/null
@@ -1,96 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-} from "typeorm";
-import { User } from "./user.js";
-import { DriveFile } from "./drive-file.js";
-import { id } from "../id.js";
-import { UserGroup } from "./user-group.js";
-
-@Entity()
-export class MessagingMessage {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Index()
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the MessagingMessage.',
-	})
-	public createdAt: Date;
-
-	@Index()
-	@Column({
-		...id(),
-		comment: 'The sender user ID.',
-	})
-	public userId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	@Index()
-	@Column({
-		...id(), nullable: true,
-		comment: 'The recipient user ID.',
-	})
-	public recipientId: User["id"] | null;
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public recipient: User | null;
-
-	@Index()
-	@Column({
-		...id(), nullable: true,
-		comment: 'The recipient group ID.',
-	})
-	public groupId: UserGroup["id"] | null;
-
-	@ManyToOne(type => UserGroup, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public group: UserGroup | null;
-
-	@Column('varchar', {
-		length: 4096, nullable: true,
-	})
-	public text: string | null;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public isRead: boolean;
-
-	@Column('varchar', {
-		length: 512, nullable: true,
-	})
-	public uri: string | null;
-
-	@Column({
-		...id(),
-		array: true, default: '{}',
-	})
-	public reads: User["id"][];
-
-	@Column({
-		...id(),
-		nullable: true,
-	})
-	public fileId: DriveFile["id"] | null;
-
-	@ManyToOne(type => DriveFile, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public file: DriveFile | null;
-}
diff --git a/packages/backend/src/models/entities/meta.ts b/packages/backend/src/models/entities/meta.ts
deleted file mode 100644
index 26a7c9c193..0000000000
--- a/packages/backend/src/models/entities/meta.ts
+++ /dev/null
@@ -1,502 +0,0 @@
-import { Entity, Column, PrimaryColumn, ManyToOne, JoinColumn } from "typeorm";
-import { id } from "../id.js";
-import { User } from "./user.js";
-import type { Clip } from "./clip.js";
-
-@Entity()
-export class Meta {
-	@PrimaryColumn({
-		type: 'varchar',
-		length: 32,
-	})
-	public id: string;
-
-	@Column('varchar', {
-		length: 128, nullable: true,
-	})
-	public name: string | null;
-
-	@Column('varchar', {
-		length: 1024, nullable: true,
-	})
-	public description: string | null;
-
-	/**
-	 * メンテナの名前
-	 */
-	@Column('varchar', {
-		length: 128, nullable: true,
-	})
-	public maintainerName: string | null;
-
-	/**
-	 * メンテナの連絡先
-	 */
-	@Column('varchar', {
-		length: 128, nullable: true,
-	})
-	public maintainerEmail: string | null;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public disableRegistration: boolean;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public disableLocalTimeline: boolean;
-
-	@Column('boolean', {
-		default: true,
-	})
-	public disableRecommendedTimeline: boolean;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public disableGlobalTimeline: boolean;
-
-	@Column('varchar', {
-		length: 256, default: '⭐',
-	})
-	public defaultReaction: string;
-
-	@Column('varchar', {
-		length: 64, array: true, default: '{}',
-	})
-	public langs: string[];
-
-	@Column('varchar', {
-		length: 256, array: true, default: '{}',
-	})
-	public pinnedUsers: string[];
-
-	@Column('varchar', {
-		length: 256, array: true, default: '{}',
-	})
-	public recommendedInstances: string[];
-
-	@Column('varchar', {
-		length: 256, array: true, default: '{}',
-	})
-	public customMOTD: string[];
-
-	@Column('varchar', {
-		length: 256, array: true, default: '{}',
-	})
-	public customSplashIcons: string[];
-
-	@Column('varchar', {
-		length: 256, array: true, default: '{}',
-	})
-	public hiddenTags: string[];
-
-	@Column('varchar', {
-		length: 256, array: true, default: '{}',
-	})
-	public blockedHosts: string[];
-
-	@Column('boolean', {
-		default: false,
-	})
-	public secureMode: boolean;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public privateMode: boolean;
-
-	@Column('varchar', {
-		length: 256, array: true, default: '{}',
-	})
-	public allowedHosts: string[];
-
-	@Column('varchar', {
-		length: 512, array: true, default: '{/featured,/channels,/explore,/pages,/about-calckey}',
-	})
-	public pinnedPages: string[];
-
-	@Column({
-		...id(),
-		nullable: true,
-	})
-	public pinnedClipId: Clip["id"] | null;
-
-	@Column('varchar', {
-		length: 512,
-		nullable: true,
-	})
-	public themeColor: string | null;
-
-	@Column('varchar', {
-		length: 512,
-		nullable: true,
-		default: '/assets/ai.png',
-	})
-	public mascotImageUrl: string | null;
-
-	@Column('varchar', {
-		length: 512,
-		nullable: true,
-	})
-	public bannerUrl: string | null;
-
-	@Column('varchar', {
-		length: 512,
-		nullable: true,
-	})
-	public backgroundImageUrl: string | null;
-
-	@Column('varchar', {
-		length: 512,
-		nullable: true,
-	})
-	public logoImageUrl: string | null;
-
-	@Column('varchar', {
-		length: 512,
-		nullable: true,
-		default: 'https://xn--931a.moe/aiart/yubitun.png',
-	})
-	public errorImageUrl: string | null;
-
-	@Column('varchar', {
-		length: 512,
-		nullable: true,
-	})
-	public iconUrl: string | null;
-
-	@Column('boolean', {
-		default: true,
-	})
-	public cacheRemoteFiles: boolean;
-
-	@Column({
-		...id(),
-		nullable: true,
-	})
-	public proxyAccountId: User["id"] | null;
-
-	@ManyToOne(type => User, {
-		onDelete: 'SET NULL',
-	})
-	@JoinColumn()
-	public proxyAccount: User | null;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public emailRequiredForSignup: boolean;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public enableHcaptcha: boolean;
-
-	@Column('varchar', {
-		length: 64,
-		nullable: true,
-	})
-	public hcaptchaSiteKey: string | null;
-
-	@Column('varchar', {
-		length: 64,
-		nullable: true,
-	})
-	public hcaptchaSecretKey: string | null;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public enableRecaptcha: boolean;
-
-	@Column('varchar', {
-		length: 64,
-		nullable: true,
-	})
-	public recaptchaSiteKey: string | null;
-
-	@Column('varchar', {
-		length: 64,
-		nullable: true,
-	})
-	public recaptchaSecretKey: string | null;
-
-	@Column('enum', {
-		enum: ['none', 'all', 'local', 'remote'],
-		default: 'none',
-	})
-	public sensitiveMediaDetection: "none" | "all" | "local" | "remote";
-
-	@Column('enum', {
-		enum: ['medium', 'low', 'high', 'veryLow', 'veryHigh'],
-		default: 'medium',
-	})
-	public sensitiveMediaDetectionSensitivity:
-		| "medium"
-		| "low"
-		| "high"
-		| "veryLow"
-		| "veryHigh";
-
-	@Column('boolean', {
-		default: false,
-	})
-	public setSensitiveFlagAutomatically: boolean;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public enableSensitiveMediaDetectionForVideos: boolean;
-
-	@Column('integer', {
-		default: 1024,
-		comment: 'Drive capacity of a local user (MB)',
-	})
-	public localDriveCapacityMb: number;
-
-	@Column('integer', {
-		default: 32,
-		comment: 'Drive capacity of a remote user (MB)',
-	})
-	public remoteDriveCapacityMb: number;
-
-	@Column('varchar', {
-		length: 128,
-		nullable: true,
-	})
-	public summalyProxy: string | null;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public enableEmail: boolean;
-
-	@Column('varchar', {
-		length: 128,
-		nullable: true,
-	})
-	public email: string | null;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public smtpSecure: boolean;
-
-	@Column('varchar', {
-		length: 128,
-		nullable: true,
-	})
-	public smtpHost: string | null;
-
-	@Column('integer', {
-		nullable: true,
-	})
-	public smtpPort: number | null;
-
-	@Column('varchar', {
-		length: 128,
-		nullable: true,
-	})
-	public smtpUser: string | null;
-
-	@Column('varchar', {
-		length: 128,
-		nullable: true,
-	})
-	public smtpPass: string | null;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public enableServiceWorker: boolean;
-
-	@Column('varchar', {
-		length: 128,
-		nullable: true,
-	})
-	public swPublicKey: string | null;
-
-	@Column('varchar', {
-		length: 128,
-		nullable: true,
-	})
-	public swPrivateKey: string | null;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public enableTwitterIntegration: boolean;
-
-	@Column('varchar', {
-		length: 128,
-		nullable: true,
-	})
-	public twitterConsumerKey: string | null;
-
-	@Column('varchar', {
-		length: 128,
-		nullable: true,
-	})
-	public twitterConsumerSecret: string | null;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public enableGithubIntegration: boolean;
-
-	@Column('varchar', {
-		length: 128,
-		nullable: true,
-	})
-	public githubClientId: string | null;
-
-	@Column('varchar', {
-		length: 128,
-		nullable: true,
-	})
-	public githubClientSecret: string | null;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public enableDiscordIntegration: boolean;
-
-	@Column('varchar', {
-		length: 128,
-		nullable: true,
-	})
-	public discordClientId: string | null;
-
-	@Column('varchar', {
-		length: 128,
-		nullable: true,
-	})
-	public discordClientSecret: string | null;
-
-	@Column('varchar', {
-		length: 128,
-		nullable: true,
-	})
-	public deeplAuthKey: string | null;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public deeplIsPro: boolean;
-
-	@Column('varchar', {
-		length: 512,
-		nullable: true,
-	})
-	public ToSUrl: string | null;
-
-	@Column('varchar', {
-		length: 512,
-		default: 'https://codeberg.org/calckey/calckey',
-		nullable: false,
-	})
-	public repositoryUrl: string;
-
-	@Column('varchar', {
-		length: 512,
-		default: 'https://codeberg.org/calckey/calckey/issues/new',
-		nullable: true,
-	})
-	public feedbackUrl: string | null;
-
-	@Column('varchar', {
-		length: 8192,
-		nullable: true,
-	})
-	public defaultLightTheme: string | null;
-
-	@Column('varchar', {
-		length: 8192,
-		nullable: true,
-	})
-	public defaultDarkTheme: string | null;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public useObjectStorage: boolean;
-
-	@Column('varchar', {
-		length: 512,
-		nullable: true,
-	})
-	public objectStorageBucket: string | null;
-
-	@Column('varchar', {
-		length: 512,
-		nullable: true,
-	})
-	public objectStoragePrefix: string | null;
-
-	@Column('varchar', {
-		length: 512,
-		nullable: true,
-	})
-	public objectStorageBaseUrl: string | null;
-
-	@Column('varchar', {
-		length: 512,
-		nullable: true,
-	})
-	public objectStorageEndpoint: string | null;
-
-	@Column('varchar', {
-		length: 512,
-		nullable: true,
-	})
-	public objectStorageRegion: string | null;
-
-	@Column('varchar', {
-		length: 512,
-		nullable: true,
-	})
-	public objectStorageAccessKey: string | null;
-
-	@Column('varchar', {
-		length: 512,
-		nullable: true,
-	})
-	public objectStorageSecretKey: string | null;
-
-	@Column('integer', {
-		nullable: true,
-	})
-	public objectStoragePort: number | null;
-
-	@Column('boolean', {
-		default: true,
-	})
-	public objectStorageUseSSL: boolean;
-
-	@Column('boolean', {
-		default: true,
-	})
-	public objectStorageUseProxy: boolean;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public objectStorageSetPublicRead: boolean;
-
-	@Column('boolean', {
-		default: true,
-	})
-	public objectStorageS3ForcePathStyle: boolean;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public enableIpLogging: boolean;
-
-	@Column('boolean', {
-		default: true,
-	})
-	public enableActiveEmailValidation: boolean;
-}
diff --git a/packages/backend/src/models/entities/moderation-log.ts b/packages/backend/src/models/entities/moderation-log.ts
deleted file mode 100644
index cc745e0d20..0000000000
--- a/packages/backend/src/models/entities/moderation-log.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-} from "typeorm";
-import { User } from "./user.js";
-import { id } from "../id.js";
-
-@Entity()
-export class ModerationLog {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the ModerationLog.',
-	})
-	public createdAt: Date;
-
-	@Index()
-	@Column(id())
-	public userId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	@Column('varchar', {
-		length: 128,
-	})
-	public type: string;
-
-	@Column('jsonb')
-	public info: Record<string, any>;
-}
diff --git a/packages/backend/src/models/entities/muted-note.ts b/packages/backend/src/models/entities/muted-note.ts
deleted file mode 100644
index 11a6ae95d0..0000000000
--- a/packages/backend/src/models/entities/muted-note.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-import {
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-	PrimaryColumn,
-} from "typeorm";
-import { Note } from "./note.js";
-import { User } from "./user.js";
-import { id } from "../id.js";
-import { mutedNoteReasons } from "../../types.js";
-
-@Entity()
-@Index(['noteId', 'userId'], { unique: true })
-export class MutedNote {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Index()
-	@Column({
-		...id(),
-		comment: 'The note ID.',
-	})
-	public noteId: Note["id"];
-
-	@ManyToOne(type => Note, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public note: Note | null;
-
-	@Index()
-	@Column({
-		...id(),
-		comment: 'The user ID.',
-	})
-	public userId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	/**
-	 * ミュートされた理由。
-	 */
-	@Index()
-	@Column('enum', {
-		enum: mutedNoteReasons,
-		comment: 'The reason of the MutedNote.',
-	})
-	public reason: typeof mutedNoteReasons[number];
-}
diff --git a/packages/backend/src/models/entities/muting.ts b/packages/backend/src/models/entities/muting.ts
deleted file mode 100644
index 561bcfb95f..0000000000
--- a/packages/backend/src/models/entities/muting.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-} from "typeorm";
-import { User } from "./user.js";
-import { id } from "../id.js";
-
-@Entity()
-@Index(['muterId', 'muteeId'], { unique: true })
-export class Muting {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Index()
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the Muting.',
-	})
-	public createdAt: Date;
-
-	@Index()
-	@Column('timestamp with time zone', {
-		nullable: true,
-	})
-	public expiresAt: Date | null;
-
-	@Index()
-	@Column({
-		...id(),
-		comment: 'The mutee user ID.',
-	})
-	public muteeId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public mutee: User | null;
-
-	@Index()
-	@Column({
-		...id(),
-		comment: 'The muter user ID.',
-	})
-	public muterId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public muter: User | null;
-}
diff --git a/packages/backend/src/models/entities/note-favorite.ts b/packages/backend/src/models/entities/note-favorite.ts
deleted file mode 100644
index ab12d8b1b3..0000000000
--- a/packages/backend/src/models/entities/note-favorite.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-} from "typeorm";
-import { Note } from "./note.js";
-import { User } from "./user.js";
-import { id } from "../id.js";
-
-@Entity()
-@Index(['userId', 'noteId'], { unique: true })
-export class NoteFavorite {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the NoteFavorite.',
-	})
-	public createdAt: Date;
-
-	@Index()
-	@Column(id())
-	public userId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	@Column(id())
-	public noteId: Note["id"];
-
-	@ManyToOne(type => Note, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public note: Note | null;
-}
diff --git a/packages/backend/src/models/entities/note-reaction.ts b/packages/backend/src/models/entities/note-reaction.ts
deleted file mode 100644
index 0e51c33b16..0000000000
--- a/packages/backend/src/models/entities/note-reaction.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-} from "typeorm";
-import { User } from "./user.js";
-import { Note } from "./note.js";
-import { id } from "../id.js";
-
-@Entity()
-@Index(['userId', 'noteId'], { unique: true })
-export class NoteReaction {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Index()
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the NoteReaction.',
-	})
-	public createdAt: Date;
-
-	@Index()
-	@Column(id())
-	public userId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public user?: User | null;
-
-	@Index()
-	@Column(id())
-	public noteId: Note["id"];
-
-	@ManyToOne(type => Note, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public note?: Note | null;
-
-	// TODO: 対象noteのuserIdを非正規化したい(「受け取ったリアクション一覧」のようなものを(JOIN無しで)実装したいため)
-
-	@Column('varchar', {
-		length: 260,
-	})
-	public reaction: string;
-}
diff --git a/packages/backend/src/models/entities/note-thread-muting.ts b/packages/backend/src/models/entities/note-thread-muting.ts
deleted file mode 100644
index 2985b195f0..0000000000
--- a/packages/backend/src/models/entities/note-thread-muting.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-} from "typeorm";
-import { User } from "./user.js";
-import { Note } from "./note.js";
-import { id } from "../id.js";
-
-@Entity()
-@Index(['userId', 'threadId'], { unique: true })
-export class NoteThreadMuting {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Column('timestamp with time zone', {
-	})
-	public createdAt: Date;
-
-	@Index()
-	@Column({
-		...id(),
-	})
-	public userId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	@Index()
-	@Column('varchar', {
-		length: 256,
-	})
-	public threadId: string;
-}
diff --git a/packages/backend/src/models/entities/note-unread.ts b/packages/backend/src/models/entities/note-unread.ts
deleted file mode 100644
index d5bba72212..0000000000
--- a/packages/backend/src/models/entities/note-unread.ts
+++ /dev/null
@@ -1,70 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-} from "typeorm";
-import { User } from "./user.js";
-import { Note } from "./note.js";
-import { id } from "../id.js";
-import type { Channel } from "./channel.js";
-
-@Entity()
-@Index(['userId', 'noteId'], { unique: true })
-export class NoteUnread {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Index()
-	@Column(id())
-	public userId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	@Index()
-	@Column(id())
-	public noteId: Note["id"];
-
-	@ManyToOne(type => Note, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public note: Note | null;
-
-	/**
-	 * メンションか否か
-	 */
-	@Index()
-	@Column('boolean')
-	public isMentioned: boolean;
-
-	/**
-	 * ダイレクト投稿か否か
-	 */
-	@Index()
-	@Column('boolean')
-	public isSpecified: boolean;
-
-	//#region Denormalized fields
-	@Index()
-	@Column({
-		...id(),
-		comment: '[Denormalized]',
-	})
-	public noteUserId: User["id"];
-
-	@Index()
-	@Column({
-		...id(),
-		nullable: true,
-		comment: '[Denormalized]',
-	})
-	public noteChannelId: Channel["id"] | null;
-	//#endregion
-}
diff --git a/packages/backend/src/models/entities/note-watching.ts b/packages/backend/src/models/entities/note-watching.ts
deleted file mode 100644
index 7ac3e8e297..0000000000
--- a/packages/backend/src/models/entities/note-watching.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-} from "typeorm";
-import { User } from "./user.js";
-import { Note } from "./note.js";
-import { id } from "../id.js";
-
-@Entity()
-@Index(['userId', 'noteId'], { unique: true })
-export class NoteWatching {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Index()
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the NoteWatching.',
-	})
-	public createdAt: Date;
-
-	@Index()
-	@Column({
-		...id(),
-		comment: 'The watcher ID.',
-	})
-	public userId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	@Index()
-	@Column({
-		...id(),
-		comment: 'The target Note ID.',
-	})
-	public noteId: Note["id"];
-
-	@ManyToOne(type => Note, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public note: Note | null;
-
-	//#region Denormalized fields
-	@Index()
-	@Column({
-		...id(),
-		comment: '[Denormalized]',
-	})
-	public noteUserId: Note["userId"];
-	//#endregion
-}
diff --git a/packages/backend/src/models/entities/note.ts b/packages/backend/src/models/entities/note.ts
deleted file mode 100644
index fd6b170c0e..0000000000
--- a/packages/backend/src/models/entities/note.ts
+++ /dev/null
@@ -1,249 +0,0 @@
-import {
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	PrimaryColumn,
-	ManyToOne,
-} from "typeorm";
-import { User } from "./user.js";
-import type { DriveFile } from "./drive-file.js";
-import { id } from "../id.js";
-import { noteVisibilities } from "../../types.js";
-import { Channel } from "./channel.js";
-
-@Entity()
-@Index('IDX_NOTE_TAGS', { synchronize: false })
-@Index('IDX_NOTE_MENTIONS', { synchronize: false })
-@Index('IDX_NOTE_VISIBLE_USER_IDS', { synchronize: false })
-export class Note {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Index()
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the Note.',
-	})
-	public createdAt: Date;
-
-	@Index()
-	@Column({
-		...id(),
-		nullable: true,
-		comment: 'The ID of reply target.',
-	})
-	public replyId: Note["id"] | null;
-
-	@ManyToOne(type => Note, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public reply: Note | null;
-
-	@Index()
-	@Column({
-		...id(),
-		nullable: true,
-		comment: 'The ID of renote target.',
-	})
-	public renoteId: Note["id"] | null;
-
-	@ManyToOne(type => Note, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public renote: Note | null;
-
-	@Index()
-	@Column('varchar', {
-		length: 256, nullable: true,
-	})
-	public threadId: string | null;
-
-	@Column('text', {
-		nullable: true,
-	})
-	public text: string | null;
-
-	@Column('varchar', {
-		length: 256, nullable: true,
-	})
-	public name: string | null;
-
-	@Column('varchar', {
-		length: 512, nullable: true,
-	})
-	public cw: string | null;
-
-	@Index()
-	@Column({
-		...id(),
-		comment: 'The ID of author.',
-	})
-	public userId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public localOnly: boolean;
-
-	@Column('smallint', {
-		default: 0,
-	})
-	public renoteCount: number;
-
-	@Column('smallint', {
-		default: 0,
-	})
-	public repliesCount: number;
-
-	@Column('jsonb', {
-		default: {},
-	})
-	public reactions: Record<string, number>;
-
-	/**
-	 * public ... 公開
-	 * home ... ホームタイムライン(ユーザーページのタイムライン含む)のみに流す
-	 * followers ... フォロワーのみ
-	 * specified ... visibleUserIds で指定したユーザーのみ
-	 */
-	@Column('enum', { enum: noteVisibilities })
-	public visibility: typeof noteVisibilities[number];
-
-	@Index({ unique: true })
-	@Column('varchar', {
-		length: 512, nullable: true,
-		comment: 'The URI of a note. it will be null when the note is local.',
-	})
-	public uri: string | null;
-
-	@Column('varchar', {
-		length: 512, nullable: true,
-		comment: 'The human readable url of a note. it will be null when the note is local.',
-	})
-	public url: string | null;
-
-	@Column('integer', {
-		default: 0, select: false,
-	})
-	public score: number;
-
-	@Index()
-	@Column({
-		...id(),
-		array: true, default: '{}',
-	})
-	public fileIds: DriveFile["id"][];
-
-	@Index()
-	@Column('varchar', {
-		length: 256, array: true, default: '{}',
-	})
-	public attachedFileTypes: string[];
-
-	@Index()
-	@Column({
-		...id(),
-		array: true, default: '{}',
-	})
-	public visibleUserIds: User["id"][];
-
-	@Index()
-	@Column({
-		...id(),
-		array: true, default: '{}',
-	})
-	public mentions: User["id"][];
-
-	@Column('text', {
-		default: '[]',
-	})
-	public mentionedRemoteUsers: string;
-
-	@Column('varchar', {
-		length: 128, array: true, default: '{}',
-	})
-	public emojis: string[];
-
-	@Index()
-	@Column('varchar', {
-		length: 128, array: true, default: '{}',
-	})
-	public tags: string[];
-
-	@Column('boolean', {
-		default: false,
-	})
-	public hasPoll: boolean;
-
-	@Index()
-	@Column({
-		...id(),
-		nullable: true,
-		comment: 'The ID of source channel.',
-	})
-	public channelId: Channel["id"] | null;
-
-	@ManyToOne(type => Channel, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public channel: Channel | null;
-
-	//#region Denormalized fields
-	@Index()
-	@Column('varchar', {
-		length: 128, nullable: true,
-		comment: '[Denormalized]',
-	})
-	public userHost: string | null;
-
-	@Column({
-		...id(),
-		nullable: true,
-		comment: '[Denormalized]',
-	})
-	public replyUserId: User["id"] | null;
-
-	@Column('varchar', {
-		length: 128, nullable: true,
-		comment: '[Denormalized]',
-	})
-	public replyUserHost: string | null;
-
-	@Column({
-		...id(),
-		nullable: true,
-		comment: '[Denormalized]',
-	})
-	public renoteUserId: User["id"] | null;
-
-	@Column('varchar', {
-		length: 128, nullable: true,
-		comment: '[Denormalized]',
-	})
-	public renoteUserHost: string | null;
-	//#endregion
-
-	constructor(data: Partial<Note>) {
-		if (data == null) return;
-
-		for (const [k, v] of Object.entries(data)) {
-			(this as any)[k] = v;
-		}
-	}
-}
-
-export type IMentionedRemoteUsers = {
-	uri: string;
-	url?: string;
-	username: string;
-	host: string;
-}[];
diff --git a/packages/backend/src/models/entities/notification.ts b/packages/backend/src/models/entities/notification.ts
deleted file mode 100644
index 2c55e988f1..0000000000
--- a/packages/backend/src/models/entities/notification.ts
+++ /dev/null
@@ -1,180 +0,0 @@
-import {
-	Entity,
-	Index,
-	JoinColumn,
-	ManyToOne,
-	Column,
-	PrimaryColumn,
-} from "typeorm";
-import { User } from "./user.js";
-import { id } from "../id.js";
-import { Note } from "./note.js";
-import { FollowRequest } from "./follow-request.js";
-import { UserGroupInvitation } from "./user-group-invitation.js";
-import { AccessToken } from "./access-token.js";
-import { notificationTypes } from "@/types.js";
-
-@Entity()
-export class Notification {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Index()
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the Notification.',
-	})
-	public createdAt: Date;
-
-	/**
-	 * Notification Recipient ID
-	 */
-	@Index()
-	@Column({
-		...id(),
-		comment: 'The ID of recipient user of the Notification.',
-	})
-	public notifieeId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public notifiee: User | null;
-
-	/**
-	 * Notification sender (initiator)
-	 */
-	@Index()
-	@Column({
-		...id(),
-		nullable: true,
-		comment: 'The ID of sender user of the Notification.',
-	})
-	public notifierId: User["id"] | null;
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public notifier: User | null;
-
-	/**
-	 * Notification types:
-	 * follow - Follow request
-	 * mention - User was referenced in a post.
-	 * reply - A post that a user made (or was watching) has been replied to.
-	 * renote - A post that a user made (or was watching) has been renoted.
-	 * quote - A post that a user made (or was watching) has been quoted and renoted.
-	 * reaction - (自分または自分がWatchしている)投稿にリアクションされた
-	 * pollVote - (自分または自分がWatchしている)投稿のアンケートに投票された
-	 * pollEnded - 自分のアンケートもしくは自分が投票したアンケートが終了した
-	 * receiveFollowRequest - フォローリクエストされた
-	 * followRequestAccepted - A follow request has been accepted.
-	 * groupInvited - グループに招待された
-	 * app - App notifications.
-	 */
-	@Index()
-	@Column('enum', {
-		enum: notificationTypes,
-		comment: 'The type of the Notification.',
-	})
-	public type: typeof notificationTypes[number];
-
-	/**
-	 * Whether the notification was read.
-	 */
-	@Index()
-	@Column('boolean', {
-		default: false,
-		comment: 'Whether the notification was read.',
-	})
-	public isRead: boolean;
-
-	@Column({
-		...id(),
-		nullable: true,
-	})
-	public noteId: Note["id"] | null;
-
-	@ManyToOne(type => Note, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public note: Note | null;
-
-	@Column({
-		...id(),
-		nullable: true,
-	})
-	public followRequestId: FollowRequest["id"] | null;
-
-	@ManyToOne(type => FollowRequest, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public followRequest: FollowRequest | null;
-
-	@Column({
-		...id(),
-		nullable: true,
-	})
-	public userGroupInvitationId: UserGroupInvitation["id"] | null;
-
-	@ManyToOne(type => UserGroupInvitation, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public userGroupInvitation: UserGroupInvitation | null;
-
-	@Column('varchar', {
-		length: 128, nullable: true,
-	})
-	public reaction: string | null;
-
-	@Column('integer', {
-		nullable: true,
-	})
-	public choice: number | null;
-
-	/**
-	 * App notification body
-	 */
-	@Column('varchar', {
-		length: 2048, nullable: true,
-	})
-	public customBody: string | null;
-
-	/**
-	 * App notification header
-	 * (If omitted, it is expected to be displayed with the app name)
-	 */
-	@Column('varchar', {
-		length: 256, nullable: true,
-	})
-	public customHeader: string | null;
-
-	/**
-	 * App notification icon (URL)
-	 * (If omitted, it is expected to be displayed as an app icon)
-	 */
-	@Column('varchar', {
-		length: 1024, nullable: true,
-	})
-	public customIcon: string | null;
-
-	/**
-	 * App notification app (token for)
-	 */
-	@Index()
-	@Column({
-		...id(),
-		nullable: true,
-	})
-	public appAccessTokenId: AccessToken["id"] | null;
-
-	@ManyToOne(type => AccessToken, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public appAccessToken: AccessToken | null;
-}
diff --git a/packages/backend/src/models/entities/page-like.ts b/packages/backend/src/models/entities/page-like.ts
deleted file mode 100644
index 75f4dc49b0..0000000000
--- a/packages/backend/src/models/entities/page-like.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-} from "typeorm";
-import { User } from "./user.js";
-import { id } from "../id.js";
-import { Page } from "./page.js";
-
-@Entity()
-@Index(['userId', 'pageId'], { unique: true })
-export class PageLike {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Column('timestamp with time zone')
-	public createdAt: Date;
-
-	@Index()
-	@Column(id())
-	public userId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	@Column(id())
-	public pageId: Page["id"];
-
-	@ManyToOne(type => Page, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public page: Page | null;
-}
diff --git a/packages/backend/src/models/entities/page.ts b/packages/backend/src/models/entities/page.ts
deleted file mode 100644
index 5fe9f52088..0000000000
--- a/packages/backend/src/models/entities/page.ts
+++ /dev/null
@@ -1,131 +0,0 @@
-import {
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	PrimaryColumn,
-	ManyToOne,
-} from "typeorm";
-import { User } from "./user.js";
-import { id } from "../id.js";
-import { DriveFile } from "./drive-file.js";
-
-@Entity()
-@Index(['userId', 'name'], { unique: true })
-export class Page {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Index()
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the Page.',
-	})
-	public createdAt: Date;
-
-	@Index()
-	@Column('timestamp with time zone', {
-		comment: 'The updated date of the Page.',
-	})
-	public updatedAt: Date;
-
-	@Column('varchar', {
-		length: 256,
-	})
-	public title: string;
-
-	@Index()
-	@Column('varchar', {
-		length: 256,
-	})
-	public name: string;
-
-	@Column('varchar', {
-		length: 256, nullable: true,
-	})
-	public summary: string | null;
-
-	@Column('boolean')
-	public alignCenter: boolean;
-
-	@Column('boolean')
-	public isPublic: boolean;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public hideTitleWhenPinned: boolean;
-
-	@Column('varchar', {
-		length: 32,
-	})
-	public font: string;
-
-	@Index()
-	@Column({
-		...id(),
-		comment: 'The ID of author.',
-	})
-	public userId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	@Column({
-		...id(),
-		nullable: true,
-	})
-	public eyeCatchingImageId: DriveFile["id"] | null;
-
-	@ManyToOne(type => DriveFile, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public eyeCatchingImage: DriveFile | null;
-
-	@Column('jsonb', {
-		default: [],
-	})
-	public content: Record<string, any>[];
-
-	@Column('jsonb', {
-		default: [],
-	})
-	public variables: Record<string, any>[];
-
-	@Column('varchar', {
-		length: 16384,
-		default: '',
-	})
-	public script: string;
-
-	/**
-	 * public ... 公開
-	 * followers ... フォロワーのみ
-	 * specified ... visibleUserIds で指定したユーザーのみ
-	 */
-	@Column('enum', { enum: ['public', 'followers', 'specified'] })
-	public visibility: "public" | "followers" | "specified";
-
-	@Index()
-	@Column({
-		...id(),
-		array: true, default: '{}',
-	})
-	public visibleUserIds: User["id"][];
-
-	@Column('integer', {
-		default: 0,
-	})
-	public likedCount: number;
-
-	constructor(data: Partial<Page>) {
-		if (data == null) return;
-
-		for (const [k, v] of Object.entries(data)) {
-			(this as any)[k] = v;
-		}
-	}
-}
diff --git a/packages/backend/src/models/entities/password-reset-request.ts b/packages/backend/src/models/entities/password-reset-request.ts
deleted file mode 100644
index 4c681d4f70..0000000000
--- a/packages/backend/src/models/entities/password-reset-request.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	Column,
-	ManyToOne,
-	JoinColumn,
-} from "typeorm";
-import { id } from "../id.js";
-import { User } from "./user.js";
-
-@Entity()
-export class PasswordResetRequest {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Column('timestamp with time zone')
-	public createdAt: Date;
-
-	@Index({ unique: true })
-	@Column('varchar', {
-		length: 256,
-	})
-	public token: string;
-
-	@Index()
-	@Column({
-		...id(),
-	})
-	public userId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public user: User | null;
-}
diff --git a/packages/backend/src/models/entities/poll-vote.ts b/packages/backend/src/models/entities/poll-vote.ts
deleted file mode 100644
index 0649951cf4..0000000000
--- a/packages/backend/src/models/entities/poll-vote.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-} from "typeorm";
-import { User } from "./user.js";
-import { Note } from "./note.js";
-import { id } from "../id.js";
-
-@Entity()
-@Index(['userId', 'noteId', 'choice'], { unique: true })
-export class PollVote {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Index()
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the PollVote.',
-	})
-	public createdAt: Date;
-
-	@Index()
-	@Column(id())
-	public userId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	@Index()
-	@Column(id())
-	public noteId: Note["id"];
-
-	@ManyToOne(type => Note, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public note: Note | null;
-
-	@Column('integer')
-	public choice: number;
-}
diff --git a/packages/backend/src/models/entities/poll.ts b/packages/backend/src/models/entities/poll.ts
deleted file mode 100644
index 28a70b3c7b..0000000000
--- a/packages/backend/src/models/entities/poll.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	OneToOne,
-} from "typeorm";
-import { id } from "../id.js";
-import { Note } from "./note.js";
-import type { User } from "./user.js";
-import { noteVisibilities } from "../../types.js";
-
-@Entity()
-export class Poll {
-	@PrimaryColumn(id())
-	public noteId: Note["id"];
-
-	@OneToOne(type => Note, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public note: Note | null;
-
-	@Column('timestamp with time zone', {
-		nullable: true,
-	})
-	public expiresAt: Date | null;
-
-	@Column('boolean')
-	public multiple: boolean;
-
-	@Column('varchar', {
-		length: 256, array: true, default: '{}',
-	})
-	public choices: string[];
-
-	@Column('integer', {
-		array: true,
-	})
-	public votes: number[];
-
-	//#region Denormalized fields
-	@Column('enum', {
-		enum: noteVisibilities,
-		comment: '[Denormalized]',
-	})
-	public noteVisibility: typeof noteVisibilities[number];
-
-	@Index()
-	@Column({
-		...id(),
-		comment: '[Denormalized]',
-	})
-	public userId: User["id"];
-
-	@Index()
-	@Column('varchar', {
-		length: 128, nullable: true,
-		comment: '[Denormalized]',
-	})
-	public userHost: string | null;
-	//#endregion
-
-	constructor(data: Partial<Poll>) {
-		if (data == null) return;
-
-		for (const [k, v] of Object.entries(data)) {
-			(this as any)[k] = v;
-		}
-	}
-}
-
-export type IPoll = {
-	choices: string[];
-	votes?: number[];
-	multiple: boolean;
-	expiresAt: Date | null;
-};
diff --git a/packages/backend/src/models/entities/promo-note.ts b/packages/backend/src/models/entities/promo-note.ts
deleted file mode 100644
index 4daacd246a..0000000000
--- a/packages/backend/src/models/entities/promo-note.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	OneToOne,
-} from "typeorm";
-import { Note } from "./note.js";
-import type { User } from "./user.js";
-import { id } from "../id.js";
-
-@Entity()
-export class PromoNote {
-	@PrimaryColumn(id())
-	public noteId: Note["id"];
-
-	@OneToOne(type => Note, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public note: Note | null;
-
-	@Column('timestamp with time zone')
-	public expiresAt: Date;
-
-	//#region Denormalized fields
-	@Index()
-	@Column({
-		...id(),
-		comment: '[Denormalized]',
-	})
-	public userId: User["id"];
-	//#endregion
-}
diff --git a/packages/backend/src/models/entities/promo-read.ts b/packages/backend/src/models/entities/promo-read.ts
deleted file mode 100644
index 5938bfde9d..0000000000
--- a/packages/backend/src/models/entities/promo-read.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-} from "typeorm";
-import { Note } from "./note.js";
-import { User } from "./user.js";
-import { id } from "../id.js";
-
-@Entity()
-@Index(['userId', 'noteId'], { unique: true })
-export class PromoRead {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the PromoRead.',
-	})
-	public createdAt: Date;
-
-	@Index()
-	@Column(id())
-	public userId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	@Column(id())
-	public noteId: Note["id"];
-
-	@ManyToOne(type => Note, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public note: Note | null;
-}
diff --git a/packages/backend/src/models/entities/registration-tickets.ts b/packages/backend/src/models/entities/registration-tickets.ts
deleted file mode 100644
index af785fbc0d..0000000000
--- a/packages/backend/src/models/entities/registration-tickets.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { PrimaryColumn, Entity, Index, Column } from "typeorm";
-import { id } from "../id.js";
-
-@Entity()
-export class RegistrationTicket {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Column('timestamp with time zone')
-	public createdAt: Date;
-
-	@Index({ unique: true })
-	@Column('varchar', {
-		length: 64,
-	})
-	public code: string;
-}
diff --git a/packages/backend/src/models/entities/registry-item.ts b/packages/backend/src/models/entities/registry-item.ts
deleted file mode 100644
index 655573883a..0000000000
--- a/packages/backend/src/models/entities/registry-item.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-} from "typeorm";
-import { User } from "./user.js";
-import { id } from "../id.js";
-
-// TODO: 同じdomain、同じscope、同じkeyのレコードは二つ以上存在しないように制約付けたい
-@Entity()
-export class RegistryItem {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the RegistryItem.',
-	})
-	public createdAt: Date;
-
-	@Column('timestamp with time zone', {
-		comment: 'The updated date of the RegistryItem.',
-	})
-	public updatedAt: Date;
-
-	@Index()
-	@Column({
-		...id(),
-		comment: 'The owner ID.',
-	})
-	public userId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	@Column('varchar', {
-		length: 1024,
-		comment: 'The key of the RegistryItem.',
-	})
-	public key: string;
-
-	@Column('jsonb', {
-		default: {}, nullable: true,
-		comment: 'The value of the RegistryItem.',
-	})
-	public value: any | null;
-
-	@Index()
-	@Column('varchar', {
-		length: 1024, array: true, default: '{}',
-	})
-	public scope: string[];
-
-	// サードパーティアプリに開放するときのためのカラム
-	@Index()
-	@Column('varchar', {
-		length: 512, nullable: true,
-	})
-	public domain: string | null;
-}
diff --git a/packages/backend/src/models/entities/relay.ts b/packages/backend/src/models/entities/relay.ts
deleted file mode 100644
index 82c0779ff8..0000000000
--- a/packages/backend/src/models/entities/relay.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import { PrimaryColumn, Entity, Index, Column } from "typeorm";
-import { id } from "../id.js";
-
-@Entity()
-export class Relay {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Index({ unique: true })
-	@Column('varchar', {
-		length: 512, nullable: false,
-	})
-	public inbox: string;
-
-	@Column('enum', {
-		enum: ['requesting', 'accepted', 'rejected'],
-	})
-	public status: "requesting" | "accepted" | "rejected";
-}
diff --git a/packages/backend/src/models/entities/renote-muting.ts b/packages/backend/src/models/entities/renote-muting.ts
deleted file mode 100644
index 64ec7f583f..0000000000
--- a/packages/backend/src/models/entities/renote-muting.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-} from "typeorm";
-import { id } from "../id.js";
-import { User } from "./user.js";
-
-@Entity()
-@Index(["muterId", "muteeId"], { unique: true })
-export class RenoteMuting {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Index()
-	@Column("timestamp with time zone", {
-		comment: "The created date of the Muting.",
-	})
-	public createdAt: Date;
-
-	@Index()
-	@Column({
-		...id(),
-		comment: "The mutee user ID.",
-	})
-	public muteeId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: "CASCADE",
-	})
-	@JoinColumn()
-	public mutee: User | null;
-
-	@Index()
-	@Column({
-		...id(),
-		comment: "The muter user ID.",
-	})
-	public muterId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: "CASCADE",
-	})
-	@JoinColumn()
-	public muter: User | null;
-}
diff --git a/packages/backend/src/models/entities/signin.ts b/packages/backend/src/models/entities/signin.ts
deleted file mode 100644
index 7859918238..0000000000
--- a/packages/backend/src/models/entities/signin.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-} from "typeorm";
-import { User } from "./user.js";
-import { id } from "../id.js";
-
-@Entity()
-export class Signin {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the Signin.',
-	})
-	public createdAt: Date;
-
-	@Index()
-	@Column(id())
-	public userId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	@Column('varchar', {
-		length: 128,
-	})
-	public ip: string;
-
-	@Column('jsonb')
-	public headers: Record<string, any>;
-
-	@Column('boolean')
-	public success: boolean;
-}
diff --git a/packages/backend/src/models/entities/sw-subscription.ts b/packages/backend/src/models/entities/sw-subscription.ts
deleted file mode 100644
index 8f18688eab..0000000000
--- a/packages/backend/src/models/entities/sw-subscription.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-} from "typeorm";
-import { User } from "./user.js";
-import { id } from "../id.js";
-
-@Entity()
-export class SwSubscription {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Column('timestamp with time zone')
-	public createdAt: Date;
-
-	@Index()
-	@Column(id())
-	public userId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	@Column('varchar', {
-		length: 512,
-	})
-	public endpoint: string;
-
-	@Column('varchar', {
-		length: 256,
-	})
-	public auth: string;
-
-	@Column('varchar', {
-		length: 128,
-	})
-	public publickey: string;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public sendReadMessage: boolean;
-}
diff --git a/packages/backend/src/models/entities/used-username.ts b/packages/backend/src/models/entities/used-username.ts
deleted file mode 100644
index a069205a5f..0000000000
--- a/packages/backend/src/models/entities/used-username.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { PrimaryColumn, Entity, Column } from "typeorm";
-
-@Entity()
-export class UsedUsername {
-	@PrimaryColumn('varchar', {
-		length: 128,
-	})
-	public username: string;
-
-	@Column('timestamp with time zone')
-	public createdAt: Date;
-
-	constructor(data: Partial<UsedUsername>) {
-		if (data == null) return;
-
-		for (const [k, v] of Object.entries(data)) {
-			(this as any)[k] = v;
-		}
-	}
-}
diff --git a/packages/backend/src/models/entities/user-group-invitation.ts b/packages/backend/src/models/entities/user-group-invitation.ts
deleted file mode 100644
index 8037b30e1b..0000000000
--- a/packages/backend/src/models/entities/user-group-invitation.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-} from "typeorm";
-import { User } from "./user.js";
-import { UserGroup } from "./user-group.js";
-import { id } from "../id.js";
-
-@Entity()
-@Index(['userId', 'userGroupId'], { unique: true })
-export class UserGroupInvitation {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the UserGroupInvitation.',
-	})
-	public createdAt: Date;
-
-	@Index()
-	@Column({
-		...id(),
-		comment: 'The user ID.',
-	})
-	public userId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	@Index()
-	@Column({
-		...id(),
-		comment: 'The group ID.',
-	})
-	public userGroupId: UserGroup["id"];
-
-	@ManyToOne(type => UserGroup, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public userGroup: UserGroup | null;
-}
diff --git a/packages/backend/src/models/entities/user-group-joining.ts b/packages/backend/src/models/entities/user-group-joining.ts
deleted file mode 100644
index 6d503b274e..0000000000
--- a/packages/backend/src/models/entities/user-group-joining.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-} from "typeorm";
-import { User } from "./user.js";
-import { UserGroup } from "./user-group.js";
-import { id } from "../id.js";
-
-@Entity()
-@Index(['userId', 'userGroupId'], { unique: true })
-export class UserGroupJoining {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the UserGroupJoining.',
-	})
-	public createdAt: Date;
-
-	@Index()
-	@Column({
-		...id(),
-		comment: 'The user ID.',
-	})
-	public userId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	@Index()
-	@Column({
-		...id(),
-		comment: 'The group ID.',
-	})
-	public userGroupId: UserGroup["id"];
-
-	@ManyToOne(type => UserGroup, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public userGroup: UserGroup | null;
-}
diff --git a/packages/backend/src/models/entities/user-group.ts b/packages/backend/src/models/entities/user-group.ts
deleted file mode 100644
index 38e5af3346..0000000000
--- a/packages/backend/src/models/entities/user-group.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-import {
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	PrimaryColumn,
-	ManyToOne,
-} from "typeorm";
-import { User } from "./user.js";
-import { id } from "../id.js";
-
-@Entity()
-export class UserGroup {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Index()
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the UserGroup.',
-	})
-	public createdAt: Date;
-
-	@Column('varchar', {
-		length: 256,
-	})
-	public name: string;
-
-	@Index()
-	@Column({
-		...id(),
-		comment: 'The ID of owner.',
-	})
-	public userId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public isPrivate: boolean;
-
-	constructor(data: Partial<UserGroup>) {
-		if (data == null) return;
-
-		for (const [k, v] of Object.entries(data)) {
-			(this as any)[k] = v;
-		}
-	}
-}
diff --git a/packages/backend/src/models/entities/user-ip.ts b/packages/backend/src/models/entities/user-ip.ts
deleted file mode 100644
index 6b88d52216..0000000000
--- a/packages/backend/src/models/entities/user-ip.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-	PrimaryGeneratedColumn,
-} from "typeorm";
-import { id } from "../id.js";
-import { Note } from "./note.js";
-import type { User } from "./user.js";
-
-@Entity()
-@Index(['userId', 'ip'], { unique: true })
-export class UserIp {
-	@PrimaryGeneratedColumn()
-	public id: string;
-
-	@Column('timestamp with time zone', {
-	})
-	public createdAt: Date;
-
-	@Index()
-	@Column(id())
-	public userId: User["id"];
-
-	@Column('varchar', {
-		length: 128,
-	})
-	public ip: string;
-}
diff --git a/packages/backend/src/models/entities/user-keypair.ts b/packages/backend/src/models/entities/user-keypair.ts
deleted file mode 100644
index 212e742b9e..0000000000
--- a/packages/backend/src/models/entities/user-keypair.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import { PrimaryColumn, Entity, JoinColumn, Column, OneToOne } from "typeorm";
-import { User } from "./user.js";
-import { id } from "../id.js";
-
-@Entity()
-export class UserKeypair {
-	@PrimaryColumn(id())
-	public userId: User["id"];
-
-	@OneToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	@Column('varchar', {
-		length: 4096,
-	})
-	public publicKey: string;
-
-	@Column('varchar', {
-		length: 4096,
-	})
-	public privateKey: string;
-
-	constructor(data: Partial<UserKeypair>) {
-		if (data == null) return;
-
-		for (const [k, v] of Object.entries(data)) {
-			(this as any)[k] = v;
-		}
-	}
-}
diff --git a/packages/backend/src/models/entities/user-list-joining.ts b/packages/backend/src/models/entities/user-list-joining.ts
deleted file mode 100644
index e52fa7b399..0000000000
--- a/packages/backend/src/models/entities/user-list-joining.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-} from "typeorm";
-import { User } from "./user.js";
-import { UserList } from "./user-list.js";
-import { id } from "../id.js";
-
-@Entity()
-@Index(['userId', 'userListId'], { unique: true })
-export class UserListJoining {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the UserListJoining.',
-	})
-	public createdAt: Date;
-
-	@Index()
-	@Column({
-		...id(),
-		comment: 'The user ID.',
-	})
-	public userId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	@Index()
-	@Column({
-		...id(),
-		comment: 'The list ID.',
-	})
-	public userListId: UserList["id"];
-
-	@ManyToOne(type => UserList, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public userList: UserList | null;
-}
diff --git a/packages/backend/src/models/entities/user-list.ts b/packages/backend/src/models/entities/user-list.ts
deleted file mode 100644
index 7c43452308..0000000000
--- a/packages/backend/src/models/entities/user-list.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-} from "typeorm";
-import { User } from "./user.js";
-import { id } from "../id.js";
-
-@Entity()
-export class UserList {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the UserList.',
-	})
-	public createdAt: Date;
-
-	@Index()
-	@Column({
-		...id(),
-		comment: 'The owner ID.',
-	})
-	public userId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	@Column('varchar', {
-		length: 128,
-		comment: 'The name of the UserList.',
-	})
-	public name: string;
-}
diff --git a/packages/backend/src/models/entities/user-note-pining.ts b/packages/backend/src/models/entities/user-note-pining.ts
deleted file mode 100644
index dc6d61f7e5..0000000000
--- a/packages/backend/src/models/entities/user-note-pining.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-} from "typeorm";
-import { Note } from "./note.js";
-import { User } from "./user.js";
-import { id } from "../id.js";
-
-@Entity()
-@Index(['userId', 'noteId'], { unique: true })
-export class UserNotePining {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the UserNotePinings.',
-	})
-	public createdAt: Date;
-
-	@Index()
-	@Column(id())
-	public userId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	@Column(id())
-	public noteId: Note["id"];
-
-	@ManyToOne(type => Note, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public note: Note | null;
-}
diff --git a/packages/backend/src/models/entities/user-pending.ts b/packages/backend/src/models/entities/user-pending.ts
deleted file mode 100644
index cac85d1c02..0000000000
--- a/packages/backend/src/models/entities/user-pending.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import { PrimaryColumn, Entity, Index, Column } from "typeorm";
-import { id } from "../id.js";
-
-@Entity()
-export class UserPending {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Column('timestamp with time zone')
-	public createdAt: Date;
-
-	@Index({ unique: true })
-	@Column('varchar', {
-		length: 128,
-	})
-	public code: string;
-
-	@Column('varchar', {
-		length: 128,
-	})
-	public username: string;
-
-	@Column('varchar', {
-		length: 128,
-	})
-	public email: string;
-
-	@Column('varchar', {
-		length: 128,
-	})
-	public password: string;
-}
diff --git a/packages/backend/src/models/entities/user-profile.ts b/packages/backend/src/models/entities/user-profile.ts
deleted file mode 100644
index cc3d238679..0000000000
--- a/packages/backend/src/models/entities/user-profile.ts
+++ /dev/null
@@ -1,239 +0,0 @@
-import {
-	Entity,
-	Column,
-	Index,
-	OneToOne,
-	JoinColumn,
-	PrimaryColumn,
-} from "typeorm";
-import { ffVisibility, notificationTypes } from "@/types.js";
-import { id } from "../id.js";
-import { User } from "./user.js";
-import { Page } from "./page.js";
-
-// TODO: このテーブルで管理している情報すべてレジストリで管理するようにしても良いかも
-//       ただ、「emailVerified が true なユーザーを find する」のようなクエリは書けなくなるからウーン
-@Entity()
-export class UserProfile {
-	@PrimaryColumn(id())
-	public userId: User["id"];
-
-	@OneToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	@Column('varchar', {
-		length: 128, nullable: true,
-		comment: 'The location of the User.',
-	})
-	public location: string | null;
-
-	@Column('char', {
-		length: 10, nullable: true,
-		comment: 'The birthday (YYYY-MM-DD) of the User.',
-	})
-	public birthday: string | null;
-
-	@Column('varchar', {
-		length: 2048, nullable: true,
-		comment: 'The description (bio) of the User.',
-	})
-	public description: string | null;
-
-	@Column('jsonb', {
-		default: [],
-	})
-	public fields: {
-		name: string;
-		value: string;
-	}[];
-
-	@Column('varchar', {
-		length: 32, nullable: true,
-	})
-	public lang: string | null;
-
-	@Column('varchar', {
-		length: 512, nullable: true,
-		comment: 'Remote URL of the user.',
-	})
-	public url: string | null;
-
-	@Column('varchar', {
-		length: 128, nullable: true,
-		comment: 'The email address of the User.',
-	})
-	public email: string | null;
-
-	@Column('varchar', {
-		length: 128, nullable: true,
-	})
-	public emailVerifyCode: string | null;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public emailVerified: boolean;
-
-	@Column('jsonb', {
-		default: ['follow', 'receiveFollowRequest', 'groupInvited'],
-	})
-	public emailNotificationTypes: string[];
-
-	@Column('boolean', {
-		default: false,
-	})
-	public publicReactions: boolean;
-
-	@Column('enum', {
-		enum: ffVisibility,
-		default: 'public',
-	})
-	public ffVisibility: typeof ffVisibility[number];
-
-	@Column('varchar', {
-		length: 128, nullable: true,
-	})
-	public twoFactorTempSecret: string | null;
-
-	@Column('varchar', {
-		length: 128, nullable: true,
-	})
-	public twoFactorSecret: string | null;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public twoFactorEnabled: boolean;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public securityKeysAvailable: boolean;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public usePasswordLessLogin: boolean;
-
-	@Column('varchar', {
-		length: 128, nullable: true,
-		comment: 'The password hash of the User. It will be null if the origin of the user is local.',
-	})
-	public password: string | null;
-
-	@Column('varchar', {
-		length: 8192, default: '',
-	})
-	public moderationNote: string | null;
-
-	// TODO: そのうち消す
-	@Column('jsonb', {
-		default: {},
-		comment: 'The client-specific data of the User.',
-	})
-	public clientData: Record<string, any>;
-
-	// TODO: そのうち消す
-	@Column('jsonb', {
-		default: {},
-		comment: 'The room data of the User.',
-	})
-	public room: Record<string, any>;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public autoAcceptFollowed: boolean;
-
-	@Column('boolean', {
-		default: false,
-		comment: 'Whether reject index by crawler.',
-	})
-	public noCrawle: boolean;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public alwaysMarkNsfw: boolean;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public autoSensitive: boolean;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public carefulBot: boolean;
-
-	@Column('boolean', {
-		default: true,
-	})
-	public injectFeaturedNote: boolean;
-
-	@Column('boolean', {
-		default: true,
-	})
-	public receiveAnnouncementEmail: boolean;
-
-	@Column({
-		...id(),
-		nullable: true,
-	})
-	public pinnedPageId: Page["id"] | null;
-
-	@OneToOne(type => Page, {
-		onDelete: 'SET NULL',
-	})
-	@JoinColumn()
-	public pinnedPage: Page | null;
-
-	@Column('jsonb', {
-		default: {},
-	})
-	public integrations: Record<string, any>;
-
-	@Index()
-	@Column('boolean', {
-		default: false, select: false,
-	})
-	public enableWordMute: boolean;
-
-	@Column('jsonb', {
-		default: [],
-	})
-	public mutedWords: string[][];
-
-	@Column('jsonb', {
-		default: [],
-		comment: 'List of instances muted by the user.',
-	})
-	public mutedInstances: string[];
-
-	@Column('enum', {
-		enum: notificationTypes,
-		array: true,
-		default: [],
-	})
-	public mutingNotificationTypes: typeof notificationTypes[number][];
-
-	//#region Denormalized fields
-	@Index()
-	@Column('varchar', {
-		length: 128, nullable: true,
-		comment: '[Denormalized]',
-	})
-	public userHost: string | null;
-	//#endregion
-
-	constructor(data: Partial<UserProfile>) {
-		if (data == null) return;
-
-		for (const [k, v] of Object.entries(data)) {
-			(this as any)[k] = v;
-		}
-	}
-}
diff --git a/packages/backend/src/models/entities/user-publickey.ts b/packages/backend/src/models/entities/user-publickey.ts
deleted file mode 100644
index d1a9239d11..0000000000
--- a/packages/backend/src/models/entities/user-publickey.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	OneToOne,
-} from "typeorm";
-import { User } from "./user.js";
-import { id } from "../id.js";
-
-@Entity()
-export class UserPublickey {
-	@PrimaryColumn(id())
-	public userId: User["id"];
-
-	@OneToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	@Index({ unique: true })
-	@Column('varchar', {
-		length: 256,
-	})
-	public keyId: string;
-
-	@Column('varchar', {
-		length: 4096,
-	})
-	public keyPem: string;
-
-	constructor(data: Partial<UserPublickey>) {
-		if (data == null) return;
-
-		for (const [k, v] of Object.entries(data)) {
-			(this as any)[k] = v;
-		}
-	}
-}
diff --git a/packages/backend/src/models/entities/user-security-key.ts b/packages/backend/src/models/entities/user-security-key.ts
deleted file mode 100644
index 3b9d925d9e..0000000000
--- a/packages/backend/src/models/entities/user-security-key.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	JoinColumn,
-	Column,
-	ManyToOne,
-	Index,
-} from "typeorm";
-import { User } from "./user.js";
-import { id } from "../id.js";
-
-@Entity()
-export class UserSecurityKey {
-	@PrimaryColumn('varchar', {
-		comment: 'Variable-length id given to navigator.credentials.get()',
-	})
-	public id: string;
-
-	@Index()
-	@Column(id())
-	public userId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	@Index()
-	@Column('varchar', {
-		comment:
-			'Variable-length public key used to verify attestations (hex-encoded).',
-	})
-	public publicKey: string;
-
-	@Column('timestamp with time zone', {
-		comment:
-			'The date of the last time the UserSecurityKey was successfully validated.',
-	})
-	public lastUsed: Date;
-
-	@Column('varchar', {
-		comment: 'User-defined name for this key',
-		length: 30,
-	})
-	public name: string;
-
-	constructor(data: Partial<UserSecurityKey>) {
-		if (data == null) return;
-
-		for (const [k, v] of Object.entries(data)) {
-			(this as any)[k] = v;
-		}
-	}
-}
diff --git a/packages/backend/src/models/entities/user.ts b/packages/backend/src/models/entities/user.ts
deleted file mode 100644
index c23f4f28d7..0000000000
--- a/packages/backend/src/models/entities/user.ts
+++ /dev/null
@@ -1,274 +0,0 @@
-import {
-	Entity,
-	Column,
-	Index,
-	OneToOne,
-	JoinColumn,
-	PrimaryColumn,
-} from "typeorm";
-import { id } from "../id.js";
-import { DriveFile } from "./drive-file.js";
-
-@Entity()
-@Index(['usernameLower', 'host'], { unique: true })
-export class User {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Index()
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the User.',
-	})
-	public createdAt: Date;
-
-	@Index()
-	@Column('timestamp with time zone', {
-		nullable: true,
-		comment: 'The updated date of the User.',
-	})
-	public updatedAt: Date | null;
-
-	@Column('timestamp with time zone', {
-		nullable: true,
-	})
-	public lastFetchedAt: Date | null;
-
-	@Index()
-	@Column('timestamp with time zone', {
-		nullable: true,
-	})
-	public lastActiveDate: Date | null;
-
-	@Column('boolean', {
-		default: false,
-	})
-	public hideOnlineStatus: boolean;
-
-	@Column('varchar', {
-		length: 128,
-		comment: 'The username of the User.',
-	})
-	public username: string;
-
-	@Index()
-	@Column('varchar', {
-		length: 128, select: false,
-		comment: 'The username (lowercased) of the User.',
-	})
-	public usernameLower: string;
-
-	@Column('varchar', {
-		length: 128, nullable: true,
-		comment: 'The name of the User.',
-	})
-	public name: string | null;
-
-	@Column('integer', {
-		default: 0,
-		comment: 'The count of followers.',
-	})
-	public followersCount: number;
-
-	@Column('integer', {
-		default: 0,
-		comment: 'The count of following.',
-	})
-	public followingCount: number;
-
-	@Column('varchar', {
-		length: 512,
-		nullable: true,
-		comment: 'The URI of the new account of the User',
-	})
-	public movedToUri: string | null;
-
-	@Column('simple-array', {
-		nullable: true,
-		comment: 'URIs the user is known as too',
-	})
-	public alsoKnownAs: string[] | null;
-
-	@Column('integer', {
-		default: 0,
-		comment: 'The count of notes.',
-	})
-	public notesCount: number;
-
-	@Column({
-		...id(),
-		nullable: true,
-		comment: 'The ID of avatar DriveFile.',
-	})
-	public avatarId: DriveFile["id"] | null;
-
-	@OneToOne(type => DriveFile, {
-		onDelete: 'SET NULL',
-	})
-	@JoinColumn()
-	public avatar: DriveFile | null;
-
-	@Column({
-		...id(),
-		nullable: true,
-		comment: 'The ID of banner DriveFile.',
-	})
-	public bannerId: DriveFile["id"] | null;
-
-	@OneToOne(type => DriveFile, {
-		onDelete: 'SET NULL',
-	})
-	@JoinColumn()
-	public banner: DriveFile | null;
-
-	@Index()
-	@Column('varchar', {
-		length: 128, array: true, default: '{}',
-	})
-	public tags: string[];
-
-	@Column('boolean', {
-		default: false,
-		comment: 'Whether the User is suspended.',
-	})
-	public isSuspended: boolean;
-
-	@Column('boolean', {
-		default: false,
-		comment: 'Whether the User is silenced.',
-	})
-	public isSilenced: boolean;
-
-	@Column('boolean', {
-		default: false,
-		comment: 'Whether the User is locked.',
-	})
-	public isLocked: boolean;
-
-	@Column('boolean', {
-		default: false,
-		comment: 'Whether the User is a bot.',
-	})
-	public isBot: boolean;
-
-	@Column('boolean', {
-		default: false,
-		comment: 'Whether the User is a cat.',
-	})
-	public isCat: boolean;
-
-	@Column('boolean', {
-		default: true,
-		comment: 'Whether to speak as a cat if isCat.',
-	})
-	public speakAsCat: boolean;
-
-	@Column('boolean', {
-		default: false,
-		comment: 'Whether the User is the admin.',
-	})
-	public isAdmin: boolean;
-
-	@Column('boolean', {
-		default: false,
-		comment: 'Whether the User is a moderator.',
-	})
-	public isModerator: boolean;
-
-	@Index()
-	@Column('boolean', {
-		default: true,
-		comment: 'Whether the User is explorable.',
-	})
-	public isExplorable: boolean;
-
-	// アカウントが削除されたかどうかのフラグだが、完全に削除される際は物理削除なので実質削除されるまでの「削除が進行しているかどうか」のフラグ
-	@Column('boolean', {
-		default: false,
-		comment: 'Whether the User is deleted.',
-	})
-	public isDeleted: boolean;
-
-	@Column('varchar', {
-		length: 128, array: true, default: '{}',
-	})
-	public emojis: string[];
-
-	@Index()
-	@Column('varchar', {
-		length: 128, nullable: true,
-		comment: 'The host of the User. It will be null if the origin of the user is local.',
-	})
-	public host: string | null;
-
-	@Column('varchar', {
-		length: 512, nullable: true,
-		comment: 'The inbox URL of the User. It will be null if the origin of the user is local.',
-	})
-	public inbox: string | null;
-
-	@Column('varchar', {
-		length: 512, nullable: true,
-		comment: 'The sharedInbox URL of the User. It will be null if the origin of the user is local.',
-	})
-	public sharedInbox: string | null;
-
-	@Column('varchar', {
-		length: 512, nullable: true,
-		comment: 'The featured URL of the User. It will be null if the origin of the user is local.',
-	})
-	public featured: string | null;
-
-	@Index()
-	@Column('varchar', {
-		length: 512, nullable: true,
-		comment: 'The URI of the User. It will be null if the origin of the user is local.',
-	})
-	public uri: string | null;
-
-	@Column('varchar', {
-		length: 512, nullable: true,
-		comment: 'The URI of the user Follower Collection. It will be null if the origin of the user is local.',
-	})
-	public followersUri: string | null;
-
-	@Column('boolean', {
-		default: false,
-		comment: 'Whether to show users replying to other users in the timeline.',
-	})
-	public showTimelineReplies: boolean;
-
-	@Index({ unique: true })
-	@Column('char', {
-		length: 16, nullable: true, unique: true,
-		comment: 'The native access token of the User. It will be null if the origin of the user is local.',
-	})
-	public token: string | null;
-
-	@Column('integer', {
-		nullable: true,
-		comment: 'Overrides user drive capacity limit',
-	})
-	public driveCapacityOverrideMb: number | null;
-
-	constructor(data: Partial<User>) {
-		if (data == null) return;
-
-		for (const [k, v] of Object.entries(data)) {
-			(this as any)[k] = v;
-		}
-	}
-}
-
-export interface ILocalUser extends User {
-	host: null;
-}
-
-export interface IRemoteUser extends User {
-	host: string;
-}
-
-export type CacheableLocalUser = ILocalUser;
-
-export type CacheableRemoteUser = IRemoteUser;
-
-export type CacheableUser = CacheableLocalUser | CacheableRemoteUser;
diff --git a/packages/backend/src/models/entities/webhook.ts b/packages/backend/src/models/entities/webhook.ts
deleted file mode 100644
index 5db51c3a3c..0000000000
--- a/packages/backend/src/models/entities/webhook.ts
+++ /dev/null
@@ -1,89 +0,0 @@
-import {
-	PrimaryColumn,
-	Entity,
-	Index,
-	JoinColumn,
-	Column,
-	ManyToOne,
-} from "typeorm";
-import { User } from "./user.js";
-import { id } from "../id.js";
-
-export const webhookEventTypes = [
-	"mention",
-	"unfollow",
-	"follow",
-	"followed",
-	"note",
-	"reply",
-	"renote",
-	"reaction",
-] as const;
-
-@Entity()
-export class Webhook {
-	@PrimaryColumn(id())
-	public id: string;
-
-	@Column('timestamp with time zone', {
-		comment: 'The created date of the Antenna.',
-	})
-	public createdAt: Date;
-
-	@Index()
-	@Column({
-		...id(),
-		comment: 'The owner ID.',
-	})
-	public userId: User["id"];
-
-	@ManyToOne(type => User, {
-		onDelete: 'CASCADE',
-	})
-	@JoinColumn()
-	public user: User | null;
-
-	@Column('varchar', {
-		length: 128,
-		comment: 'The name of the Antenna.',
-	})
-	public name: string;
-
-	@Index()
-	@Column('varchar', {
-		length: 128, array: true, default: '{}',
-	})
-	public on: typeof webhookEventTypes[number][];
-
-	@Column('varchar', {
-		length: 1024,
-	})
-	public url: string;
-
-	@Column('varchar', {
-		length: 1024,
-	})
-	public secret: string;
-
-	@Index()
-	@Column('boolean', {
-		default: true,
-	})
-	public active: boolean;
-
-	/**
-	 * 直近のリクエスト送信日時
-	 */
-	@Column('timestamp with time zone', {
-		nullable: true,
-	})
-	public latestSentAt: Date | null;
-
-	/**
-	 * 直近のリクエスト送信時のHTTPステータスコード
-	 */
-	@Column('integer', {
-		nullable: true,
-	})
-	public latestStatus: number | null;
-}
diff --git a/packages/backend/src/models/id.ts b/packages/backend/src/models/id.ts
deleted file mode 100644
index 7e5a787984..0000000000
--- a/packages/backend/src/models/id.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export const id = () => ({
-	type: "varchar" as const,
-	length: 32,
-});
diff --git a/packages/backend/src/models/index.ts b/packages/backend/src/models/index.ts
deleted file mode 100644
index f68166c17f..0000000000
--- a/packages/backend/src/models/index.ts
+++ /dev/null
@@ -1,135 +0,0 @@
-import {} from "typeorm";
-import { db } from "@/db/postgre.js";
-
-import { Announcement } from "./entities/announcement.js";
-import { AnnouncementRead } from "./entities/announcement-read.js";
-import { Instance } from "./entities/instance.js";
-import { Poll } from "./entities/poll.js";
-import { PollVote } from "./entities/poll-vote.js";
-import { Meta } from "./entities/meta.js";
-import { SwSubscription } from "./entities/sw-subscription.js";
-import { NoteWatching } from "./entities/note-watching.js";
-import { NoteThreadMuting } from "./entities/note-thread-muting.js";
-import { NoteUnread } from "./entities/note-unread.js";
-import { RegistrationTicket } from "./entities/registration-tickets.js";
-import { UserRepository } from "./repositories/user.js";
-import { NoteRepository } from "./repositories/note.js";
-import { DriveFileRepository } from "./repositories/drive-file.js";
-import { DriveFolderRepository } from "./repositories/drive-folder.js";
-import { AccessToken } from "./entities/access-token.js";
-import { UserNotePining } from "./entities/user-note-pining.js";
-import { SigninRepository } from "./repositories/signin.js";
-import { MessagingMessageRepository } from "./repositories/messaging-message.js";
-import { UserListRepository } from "./repositories/user-list.js";
-import { UserListJoining } from "./entities/user-list-joining.js";
-import { UserGroupRepository } from "./repositories/user-group.js";
-import { UserGroupJoining } from "./entities/user-group-joining.js";
-import { UserGroupInvitationRepository } from "./repositories/user-group-invitation.js";
-import { FollowRequestRepository } from "./repositories/follow-request.js";
-import { MutingRepository } from "./repositories/muting.js";
-import { RenoteMutingRepository } from "./repositories/renote-muting.js";
-import { BlockingRepository } from "./repositories/blocking.js";
-import { NoteReactionRepository } from "./repositories/note-reaction.js";
-import { NotificationRepository } from "./repositories/notification.js";
-import { NoteFavoriteRepository } from "./repositories/note-favorite.js";
-import { UserPublickey } from "./entities/user-publickey.js";
-import { UserKeypair } from "./entities/user-keypair.js";
-import { AppRepository } from "./repositories/app.js";
-import { FollowingRepository } from "./repositories/following.js";
-import { AbuseUserReportRepository } from "./repositories/abuse-user-report.js";
-import { AuthSessionRepository } from "./repositories/auth-session.js";
-import { UserProfile } from "./entities/user-profile.js";
-import { AttestationChallenge } from "./entities/attestation-challenge.js";
-import { UserSecurityKey } from "./entities/user-security-key.js";
-import { HashtagRepository } from "./repositories/hashtag.js";
-import { PageRepository } from "./repositories/page.js";
-import { PageLikeRepository } from "./repositories/page-like.js";
-import { GalleryPostRepository } from "./repositories/gallery-post.js";
-import { GalleryLikeRepository } from "./repositories/gallery-like.js";
-import { ModerationLogRepository } from "./repositories/moderation-logs.js";
-import { UsedUsername } from "./entities/used-username.js";
-import { ClipRepository } from "./repositories/clip.js";
-import { ClipNote } from "./entities/clip-note.js";
-import { AntennaRepository } from "./repositories/antenna.js";
-import { AntennaNote } from "./entities/antenna-note.js";
-import { PromoNote } from "./entities/promo-note.js";
-import { PromoRead } from "./entities/promo-read.js";
-import { EmojiRepository } from "./repositories/emoji.js";
-import { RelayRepository } from "./repositories/relay.js";
-import { ChannelRepository } from "./repositories/channel.js";
-import { MutedNote } from "./entities/muted-note.js";
-import { ChannelFollowing } from "./entities/channel-following.js";
-import { ChannelNotePining } from "./entities/channel-note-pining.js";
-import { RegistryItem } from "./entities/registry-item.js";
-import { Ad } from "./entities/ad.js";
-import { PasswordResetRequest } from "./entities/password-reset-request.js";
-import { UserPending } from "./entities/user-pending.js";
-import { InstanceRepository } from "./repositories/instance.js";
-import { Webhook } from "./entities/webhook.js";
-import { UserIp } from "./entities/user-ip.js";
-
-export const Announcements = db.getRepository(Announcement);
-export const AnnouncementReads = db.getRepository(AnnouncementRead);
-export const Apps = AppRepository;
-export const Notes = NoteRepository;
-export const NoteFavorites = NoteFavoriteRepository;
-export const NoteWatchings = db.getRepository(NoteWatching);
-export const NoteThreadMutings = db.getRepository(NoteThreadMuting);
-export const NoteReactions = NoteReactionRepository;
-export const NoteUnreads = db.getRepository(NoteUnread);
-export const Polls = db.getRepository(Poll);
-export const PollVotes = db.getRepository(PollVote);
-export const Users = UserRepository;
-export const UserProfiles = db.getRepository(UserProfile);
-export const UserKeypairs = db.getRepository(UserKeypair);
-export const UserPendings = db.getRepository(UserPending);
-export const AttestationChallenges = db.getRepository(AttestationChallenge);
-export const UserSecurityKeys = db.getRepository(UserSecurityKey);
-export const UserPublickeys = db.getRepository(UserPublickey);
-export const UserLists = UserListRepository;
-export const UserListJoinings = db.getRepository(UserListJoining);
-export const UserGroups = UserGroupRepository;
-export const UserGroupJoinings = db.getRepository(UserGroupJoining);
-export const UserGroupInvitations = UserGroupInvitationRepository;
-export const UserNotePinings = db.getRepository(UserNotePining);
-export const UserIps = db.getRepository(UserIp);
-export const UsedUsernames = db.getRepository(UsedUsername);
-export const Followings = FollowingRepository;
-export const FollowRequests = FollowRequestRepository;
-export const Instances = InstanceRepository;
-export const Emojis = EmojiRepository;
-export const DriveFiles = DriveFileRepository;
-export const DriveFolders = DriveFolderRepository;
-export const Notifications = NotificationRepository;
-export const Metas = db.getRepository(Meta);
-export const Mutings = MutingRepository;
-export const RenoteMutings = RenoteMutingRepository;
-export const Blockings = BlockingRepository;
-export const SwSubscriptions = db.getRepository(SwSubscription);
-export const Hashtags = HashtagRepository;
-export const AbuseUserReports = AbuseUserReportRepository;
-export const RegistrationTickets = db.getRepository(RegistrationTicket);
-export const AuthSessions = AuthSessionRepository;
-export const AccessTokens = db.getRepository(AccessToken);
-export const Signins = SigninRepository;
-export const MessagingMessages = MessagingMessageRepository;
-export const Pages = PageRepository;
-export const PageLikes = PageLikeRepository;
-export const GalleryPosts = GalleryPostRepository;
-export const GalleryLikes = GalleryLikeRepository;
-export const ModerationLogs = ModerationLogRepository;
-export const Clips = ClipRepository;
-export const ClipNotes = db.getRepository(ClipNote);
-export const Antennas = AntennaRepository;
-export const AntennaNotes = db.getRepository(AntennaNote);
-export const PromoNotes = db.getRepository(PromoNote);
-export const PromoReads = db.getRepository(PromoRead);
-export const Relays = RelayRepository;
-export const MutedNotes = db.getRepository(MutedNote);
-export const Channels = ChannelRepository;
-export const ChannelFollowings = db.getRepository(ChannelFollowing);
-export const ChannelNotePinings = db.getRepository(ChannelNotePining);
-export const RegistryItems = db.getRepository(RegistryItem);
-export const Webhooks = db.getRepository(Webhook);
-export const Ads = db.getRepository(Ad);
-export const PasswordResetRequests = db.getRepository(PasswordResetRequest);
diff --git a/packages/backend/src/models/repositories/abuse-user-report.ts b/packages/backend/src/models/repositories/abuse-user-report.ts
deleted file mode 100644
index 07afef48c4..0000000000
--- a/packages/backend/src/models/repositories/abuse-user-report.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-import { db } from "@/db/postgre.js";
-import { Users } from "../index.js";
-import { AbuseUserReport } from "@/models/entities/abuse-user-report.js";
-import { awaitAll } from "@/prelude/await-all.js";
-
-export const AbuseUserReportRepository = db
-	.getRepository(AbuseUserReport)
-	.extend({
-		async pack(src: AbuseUserReport["id"] | AbuseUserReport) {
-			const report =
-				typeof src === "object" ? src : await this.findOneByOrFail({ id: src });
-
-			return await awaitAll({
-				id: report.id,
-				createdAt: report.createdAt.toISOString(),
-				comment: report.comment,
-				resolved: report.resolved,
-				reporterId: report.reporterId,
-				targetUserId: report.targetUserId,
-				assigneeId: report.assigneeId,
-				reporter: Users.pack(report.reporter || report.reporterId, null, {
-					detail: true,
-				}),
-				targetUser: Users.pack(report.targetUser || report.targetUserId, null, {
-					detail: true,
-				}),
-				assignee: report.assigneeId
-					? Users.pack(report.assignee || report.assigneeId, null, {
-							detail: true,
-					  })
-					: null,
-				forwarded: report.forwarded,
-			});
-		},
-
-		packMany(reports: any[]) {
-			return Promise.all(reports.map((x) => this.pack(x)));
-		},
-	});
diff --git a/packages/backend/src/models/repositories/antenna.ts b/packages/backend/src/models/repositories/antenna.ts
deleted file mode 100644
index c325e25895..0000000000
--- a/packages/backend/src/models/repositories/antenna.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import { db } from "@/db/postgre.js";
-import { Antenna } from "@/models/entities/antenna.js";
-import type { Packed } from "@/misc/schema.js";
-import { AntennaNotes, UserGroupJoinings } from "../index.js";
-
-export const AntennaRepository = db.getRepository(Antenna).extend({
-	async pack(src: Antenna["id"] | Antenna): Promise<Packed<"Antenna">> {
-		const antenna =
-			typeof src === "object" ? src : await this.findOneByOrFail({ id: src });
-
-		const hasUnreadNote =
-			(await AntennaNotes.findOneBy({ antennaId: antenna.id, read: false })) !=
-			null;
-		const userGroupJoining = antenna.userGroupJoiningId
-			? await UserGroupJoinings.findOneBy({ id: antenna.userGroupJoiningId })
-			: null;
-
-		return {
-			id: antenna.id,
-			createdAt: antenna.createdAt.toISOString(),
-			name: antenna.name,
-			keywords: antenna.keywords,
-			excludeKeywords: antenna.excludeKeywords,
-			src: antenna.src,
-			userListId: antenna.userListId,
-			userGroupId: userGroupJoining ? userGroupJoining.userGroupId : null,
-			users: antenna.users,
-			instances: antenna.instances,
-			caseSensitive: antenna.caseSensitive,
-			notify: antenna.notify,
-			withReplies: antenna.withReplies,
-			withFile: antenna.withFile,
-			hasUnreadNote,
-		};
-	},
-});
diff --git a/packages/backend/src/models/repositories/app.ts b/packages/backend/src/models/repositories/app.ts
deleted file mode 100644
index af3dfb81a1..0000000000
--- a/packages/backend/src/models/repositories/app.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import { db } from "@/db/postgre.js";
-import { App } from "@/models/entities/app.js";
-import { AccessTokens } from "../index.js";
-import type { Packed } from "@/misc/schema.js";
-import type { User } from "../entities/user.js";
-
-export const AppRepository = db.getRepository(App).extend({
-	async pack(
-		src: App["id"] | App,
-		me?: { id: User["id"] } | null | undefined,
-		options?: {
-			detail?: boolean;
-			includeSecret?: boolean;
-			includeProfileImageIds?: boolean;
-		},
-	): Promise<Packed<"App">> {
-		const opts = Object.assign(
-			{
-				detail: false,
-				includeSecret: false,
-				includeProfileImageIds: false,
-			},
-			options,
-		);
-
-		const app =
-			typeof src === "object" ? src : await this.findOneByOrFail({ id: src });
-
-		return {
-			id: app.id,
-			name: app.name,
-			callbackUrl: app.callbackUrl,
-			permission: app.permission,
-			...(opts.includeSecret ? { secret: app.secret } : {}),
-			...(me
-				? {
-						isAuthorized: await AccessTokens.countBy({
-							appId: app.id,
-							userId: me.id,
-						}).then((count) => count > 0),
-				  }
-				: {}),
-		};
-	},
-});
diff --git a/packages/backend/src/models/repositories/auth-session.ts b/packages/backend/src/models/repositories/auth-session.ts
deleted file mode 100644
index d3e1d45d6d..0000000000
--- a/packages/backend/src/models/repositories/auth-session.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { db } from "@/db/postgre.js";
-import { Apps } from "../index.js";
-import { AuthSession } from "@/models/entities/auth-session.js";
-import { awaitAll } from "@/prelude/await-all.js";
-import type { User } from "@/models/entities/user.js";
-
-export const AuthSessionRepository = db.getRepository(AuthSession).extend({
-	async pack(
-		src: AuthSession["id"] | AuthSession,
-		me?: { id: User["id"] } | null | undefined,
-	) {
-		const session =
-			typeof src === "object" ? src : await this.findOneByOrFail({ id: src });
-
-		return await awaitAll({
-			id: session.id,
-			app: Apps.pack(session.appId, me),
-			token: session.token,
-		});
-	},
-});
diff --git a/packages/backend/src/models/repositories/blocking.ts b/packages/backend/src/models/repositories/blocking.ts
deleted file mode 100644
index 3dfa74e763..0000000000
--- a/packages/backend/src/models/repositories/blocking.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import { db } from "@/db/postgre.js";
-import { Users } from "../index.js";
-import { Blocking } from "@/models/entities/blocking.js";
-import { awaitAll } from "@/prelude/await-all.js";
-import type { Packed } from "@/misc/schema.js";
-import type { User } from "@/models/entities/user.js";
-
-export const BlockingRepository = db.getRepository(Blocking).extend({
-	async pack(
-		src: Blocking["id"] | Blocking,
-		me?: { id: User["id"] } | null | undefined,
-	): Promise<Packed<"Blocking">> {
-		const blocking =
-			typeof src === "object" ? src : await this.findOneByOrFail({ id: src });
-
-		return await awaitAll({
-			id: blocking.id,
-			createdAt: blocking.createdAt.toISOString(),
-			blockeeId: blocking.blockeeId,
-			blockee: Users.pack(blocking.blockeeId, me, {
-				detail: true,
-			}),
-		});
-	},
-
-	packMany(blockings: any[], me: { id: User["id"] }) {
-		return Promise.all(blockings.map((x) => this.pack(x, me)));
-	},
-});
diff --git a/packages/backend/src/models/repositories/channel.ts b/packages/backend/src/models/repositories/channel.ts
deleted file mode 100644
index 7800a65940..0000000000
--- a/packages/backend/src/models/repositories/channel.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-import { db } from "@/db/postgre.js";
-import { Channel } from "@/models/entities/channel.js";
-import type { Packed } from "@/misc/schema.js";
-import { DriveFiles, ChannelFollowings, NoteUnreads } from "../index.js";
-import type { User } from "@/models/entities/user.js";
-
-export const ChannelRepository = db.getRepository(Channel).extend({
-	async pack(
-		src: Channel["id"] | Channel,
-		me?: { id: User["id"] } | null | undefined,
-	): Promise<Packed<"Channel">> {
-		const channel =
-			typeof src === "object" ? src : await this.findOneByOrFail({ id: src });
-		const meId = me ? me.id : null;
-
-		const banner = channel.bannerId
-			? await DriveFiles.findOneBy({ id: channel.bannerId })
-			: null;
-
-		const hasUnreadNote = meId
-			? (await NoteUnreads.findOneBy({
-					noteChannelId: channel.id,
-					userId: meId,
-			  })) != null
-			: undefined;
-
-		const following = meId
-			? await ChannelFollowings.findOneBy({
-					followerId: meId,
-					followeeId: channel.id,
-			  })
-			: null;
-
-		return {
-			id: channel.id,
-			createdAt: channel.createdAt.toISOString(),
-			lastNotedAt: channel.lastNotedAt
-				? channel.lastNotedAt.toISOString()
-				: null,
-			name: channel.name,
-			description: channel.description,
-			userId: channel.userId,
-			bannerUrl: banner ? DriveFiles.getPublicUrl(banner, false) : null,
-			usersCount: channel.usersCount,
-			notesCount: channel.notesCount,
-
-			...(me
-				? {
-						isFollowing: following != null,
-						hasUnreadNote,
-				  }
-				: {}),
-		};
-	},
-});
diff --git a/packages/backend/src/models/repositories/clip.ts b/packages/backend/src/models/repositories/clip.ts
deleted file mode 100644
index 0c21691bff..0000000000
--- a/packages/backend/src/models/repositories/clip.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import { db } from "@/db/postgre.js";
-import { Clip } from "@/models/entities/clip.js";
-import type { Packed } from "@/misc/schema.js";
-import { Users } from "../index.js";
-import { awaitAll } from "@/prelude/await-all.js";
-
-export const ClipRepository = db.getRepository(Clip).extend({
-	async pack(src: Clip["id"] | Clip): Promise<Packed<"Clip">> {
-		const clip =
-			typeof src === "object" ? src : await this.findOneByOrFail({ id: src });
-
-		return await awaitAll({
-			id: clip.id,
-			createdAt: clip.createdAt.toISOString(),
-			userId: clip.userId,
-			user: Users.pack(clip.user || clip.userId),
-			name: clip.name,
-			description: clip.description,
-			isPublic: clip.isPublic,
-		});
-	},
-
-	packMany(clips: Clip[]) {
-		return Promise.all(clips.map((x) => this.pack(x)));
-	},
-});
diff --git a/packages/backend/src/models/repositories/drive-file.ts b/packages/backend/src/models/repositories/drive-file.ts
deleted file mode 100644
index 3918f7947b..0000000000
--- a/packages/backend/src/models/repositories/drive-file.ts
+++ /dev/null
@@ -1,224 +0,0 @@
-import { db } from "@/db/postgre.js";
-import { DriveFile } from "@/models/entities/drive-file.js";
-import type { User } from "@/models/entities/user.js";
-import { toPuny } from "@/misc/convert-host.js";
-import { awaitAll, Promiseable } from "@/prelude/await-all.js";
-import type { Packed } from "@/misc/schema.js";
-import config from "@/config/index.js";
-import { query, appendQuery } from "@/prelude/url.js";
-import { Meta } from "@/models/entities/meta.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { Users, DriveFolders } from "../index.js";
-import { deepClone } from "@/misc/clone.js";
-
-type PackOptions = {
-	detail?: boolean;
-	self?: boolean;
-	withUser?: boolean;
-};
-
-export const DriveFileRepository = db.getRepository(DriveFile).extend({
-	validateFileName(name: string): boolean {
-		return (
-			name.trim().length > 0 &&
-			name.length <= 200 &&
-			name.indexOf("\\") === -1 &&
-			name.indexOf("/") === -1 &&
-			name.indexOf("..") === -1
-		);
-	},
-
-	getPublicProperties(file: DriveFile): DriveFile["properties"] {
-		if (file.properties.orientation != null) {
-			const properties = deepClone(file.properties);
-			if (file.properties.orientation >= 5) {
-				[properties.width, properties.height] = [
-					properties.height,
-					properties.width,
-				];
-			}
-			properties.orientation = undefined;
-			return properties;
-		}
-
-		return file.properties;
-	},
-
-	getPublicUrl(file: DriveFile, thumbnail = false): string | null {
-		// リモートかつメディアプロキシ
-		if (
-			file.uri != null &&
-			file.userHost != null &&
-			config.mediaProxy != null
-		) {
-			return appendQuery(
-				config.mediaProxy,
-				query({
-					url: file.uri,
-					thumbnail: thumbnail ? "1" : undefined,
-				}),
-			);
-		}
-
-		// リモートかつ期限切れはローカルプロキシを試みる
-		if (file.uri != null && file.isLink && config.proxyRemoteFiles) {
-			const key = thumbnail ? file.thumbnailAccessKey : file.webpublicAccessKey;
-
-			if (key && !key.match("/")) {
-				// 古いものはここにオブジェクトストレージキーが入ってるので除外
-				return `${config.url}/files/${key}`;
-			}
-		}
-
-		const isImage =
-			file.type &&
-			[
-				"image/png",
-				"image/apng",
-				"image/gif",
-				"image/jpeg",
-				"image/webp",
-				"image/svg+xml",
-				"image/avif",
-			].includes(file.type);
-
-		return thumbnail
-			? file.thumbnailUrl || (isImage ? file.webpublicUrl || file.url : null)
-			: file.webpublicUrl || file.url;
-	},
-
-	async calcDriveUsageOf(
-		user: User["id"] | { id: User["id"] },
-	): Promise<number> {
-		const id = typeof user === "object" ? user.id : user;
-
-		const { sum } = await this.createQueryBuilder("file")
-			.where("file.userId = :id", { id: id })
-			.andWhere("file.isLink = FALSE")
-			.select("SUM(file.size)", "sum")
-			.getRawOne();
-
-		return parseInt(sum, 10) || 0;
-	},
-
-	async calcDriveUsageOfHost(host: string): Promise<number> {
-		const { sum } = await this.createQueryBuilder("file")
-			.where("file.userHost = :host", { host: toPuny(host) })
-			.andWhere("file.isLink = FALSE")
-			.select("SUM(file.size)", "sum")
-			.getRawOne();
-
-		return parseInt(sum, 10) || 0;
-	},
-
-	async calcDriveUsageOfLocal(): Promise<number> {
-		const { sum } = await this.createQueryBuilder("file")
-			.where("file.userHost IS NULL")
-			.andWhere("file.isLink = FALSE")
-			.select("SUM(file.size)", "sum")
-			.getRawOne();
-
-		return parseInt(sum, 10) || 0;
-	},
-
-	async calcDriveUsageOfRemote(): Promise<number> {
-		const { sum } = await this.createQueryBuilder("file")
-			.where("file.userHost IS NOT NULL")
-			.andWhere("file.isLink = FALSE")
-			.select("SUM(file.size)", "sum")
-			.getRawOne();
-
-		return parseInt(sum, 10) || 0;
-	},
-
-	async pack(
-		src: DriveFile["id"] | DriveFile,
-		options?: PackOptions,
-	): Promise<Packed<"DriveFile">> {
-		const opts = Object.assign(
-			{
-				detail: false,
-				self: false,
-			},
-			options,
-		);
-
-		const file =
-			typeof src === "object" ? src : await this.findOneByOrFail({ id: src });
-
-		return await awaitAll<Packed<"DriveFile">>({
-			id: file.id,
-			createdAt: file.createdAt.toISOString(),
-			name: file.name,
-			type: file.type,
-			md5: file.md5,
-			size: file.size,
-			isSensitive: file.isSensitive,
-			blurhash: file.blurhash,
-			properties: opts.self ? file.properties : this.getPublicProperties(file),
-			url: opts.self ? file.url : this.getPublicUrl(file, false),
-			thumbnailUrl: this.getPublicUrl(file, true),
-			comment: file.comment,
-			folderId: file.folderId,
-			folder:
-				opts.detail && file.folderId
-					? DriveFolders.pack(file.folderId, {
-							detail: true,
-					  })
-					: null,
-			userId: opts.withUser ? file.userId : null,
-			user: opts.withUser && file.userId ? Users.pack(file.userId) : null,
-		});
-	},
-
-	async packNullable(
-		src: DriveFile["id"] | DriveFile,
-		options?: PackOptions,
-	): Promise<Packed<"DriveFile"> | null> {
-		const opts = Object.assign(
-			{
-				detail: false,
-				self: false,
-			},
-			options,
-		);
-
-		const file =
-			typeof src === "object" ? src : await this.findOneBy({ id: src });
-		if (file == null) return null;
-
-		return await awaitAll<Packed<"DriveFile">>({
-			id: file.id,
-			createdAt: file.createdAt.toISOString(),
-			name: file.name,
-			type: file.type,
-			md5: file.md5,
-			size: file.size,
-			isSensitive: file.isSensitive,
-			blurhash: file.blurhash,
-			properties: opts.self ? file.properties : this.getPublicProperties(file),
-			url: opts.self ? file.url : this.getPublicUrl(file, false),
-			thumbnailUrl: this.getPublicUrl(file, true),
-			comment: file.comment,
-			folderId: file.folderId,
-			folder:
-				opts.detail && file.folderId
-					? DriveFolders.pack(file.folderId, {
-							detail: true,
-					  })
-					: null,
-			userId: opts.withUser ? file.userId : null,
-			user: opts.withUser && file.userId ? Users.pack(file.userId) : null,
-		});
-	},
-
-	async packMany(
-		files: (DriveFile["id"] | DriveFile)[],
-		options?: PackOptions,
-	): Promise<Packed<"DriveFile">[]> {
-		const items = await Promise.all(
-			files.map((f) => this.packNullable(f, options)),
-		);
-		return items.filter((x): x is Packed<"DriveFile"> => x != null);
-	},
-});
diff --git a/packages/backend/src/models/repositories/drive-folder.ts b/packages/backend/src/models/repositories/drive-folder.ts
deleted file mode 100644
index 9823561d0b..0000000000
--- a/packages/backend/src/models/repositories/drive-folder.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import { db } from "@/db/postgre.js";
-import { DriveFolders, DriveFiles } from "../index.js";
-import { DriveFolder } from "@/models/entities/drive-folder.js";
-import { awaitAll } from "@/prelude/await-all.js";
-import type { Packed } from "@/misc/schema.js";
-
-export const DriveFolderRepository = db.getRepository(DriveFolder).extend({
-	async pack(
-		src: DriveFolder["id"] | DriveFolder,
-		options?: {
-			detail: boolean;
-		},
-	): Promise<Packed<"DriveFolder">> {
-		const opts = Object.assign(
-			{
-				detail: false,
-			},
-			options,
-		);
-
-		const folder =
-			typeof src === "object" ? src : await this.findOneByOrFail({ id: src });
-
-		return await awaitAll({
-			id: folder.id,
-			createdAt: folder.createdAt.toISOString(),
-			name: folder.name,
-			parentId: folder.parentId,
-
-			...(opts.detail
-				? {
-						foldersCount: DriveFolders.countBy({
-							parentId: folder.id,
-						}),
-						filesCount: DriveFiles.countBy({
-							folderId: folder.id,
-						}),
-
-						...(folder.parentId
-							? {
-									parent: this.pack(folder.parentId, {
-										detail: true,
-									}),
-							  }
-							: {}),
-				  }
-				: {}),
-		});
-	},
-});
diff --git a/packages/backend/src/models/repositories/emoji.ts b/packages/backend/src/models/repositories/emoji.ts
deleted file mode 100644
index 6eabfe9558..0000000000
--- a/packages/backend/src/models/repositories/emoji.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { db } from "@/db/postgre.js";
-import { Emoji } from "@/models/entities/emoji.js";
-import type { Packed } from "@/misc/schema.js";
-
-export const EmojiRepository = db.getRepository(Emoji).extend({
-	async pack(src: Emoji["id"] | Emoji): Promise<Packed<"Emoji">> {
-		const emoji =
-			typeof src === "object" ? src : await this.findOneByOrFail({ id: src });
-
-		return {
-			id: emoji.id,
-			aliases: emoji.aliases,
-			name: emoji.name,
-			category: emoji.category,
-			host: emoji.host,
-			// || emoji.originalUrl してるのは後方互換性のため
-			url: emoji.publicUrl || emoji.originalUrl,
-			license: emoji.license,
-		};
-	},
-
-	packMany(emojis: any[]) {
-		return Promise.all(emojis.map((x) => this.pack(x)));
-	},
-});
diff --git a/packages/backend/src/models/repositories/follow-request.ts b/packages/backend/src/models/repositories/follow-request.ts
deleted file mode 100644
index cef6ea7228..0000000000
--- a/packages/backend/src/models/repositories/follow-request.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { db } from "@/db/postgre.js";
-import { FollowRequest } from "@/models/entities/follow-request.js";
-import { Users } from "../index.js";
-import type { User } from "@/models/entities/user.js";
-
-export const FollowRequestRepository = db.getRepository(FollowRequest).extend({
-	async pack(
-		src: FollowRequest["id"] | FollowRequest,
-		me?: { id: User["id"] } | null | undefined,
-	) {
-		const request =
-			typeof src === "object" ? src : await this.findOneByOrFail({ id: src });
-
-		return {
-			id: request.id,
-			follower: await Users.pack(request.followerId, me),
-			followee: await Users.pack(request.followeeId, me),
-		};
-	},
-});
diff --git a/packages/backend/src/models/repositories/following.ts b/packages/backend/src/models/repositories/following.ts
deleted file mode 100644
index b102365e09..0000000000
--- a/packages/backend/src/models/repositories/following.ts
+++ /dev/null
@@ -1,90 +0,0 @@
-import { db } from "@/db/postgre.js";
-import { Users } from "../index.js";
-import { Following } from "@/models/entities/following.js";
-import { awaitAll } from "@/prelude/await-all.js";
-import type { Packed } from "@/misc/schema.js";
-import type { User } from "@/models/entities/user.js";
-
-type LocalFollowerFollowing = Following & {
-	followerHost: null;
-	followerInbox: null;
-	followerSharedInbox: null;
-};
-
-type RemoteFollowerFollowing = Following & {
-	followerHost: string;
-	followerInbox: string;
-	followerSharedInbox: string;
-};
-
-type LocalFolloweeFollowing = Following & {
-	followeeHost: null;
-	followeeInbox: null;
-	followeeSharedInbox: null;
-};
-
-type RemoteFolloweeFollowing = Following & {
-	followeeHost: string;
-	followeeInbox: string;
-	followeeSharedInbox: string;
-};
-
-export const FollowingRepository = db.getRepository(Following).extend({
-	isLocalFollower(following: Following): following is LocalFollowerFollowing {
-		return following.followerHost == null;
-	},
-
-	isRemoteFollower(following: Following): following is RemoteFollowerFollowing {
-		return following.followerHost != null;
-	},
-
-	isLocalFollowee(following: Following): following is LocalFolloweeFollowing {
-		return following.followeeHost == null;
-	},
-
-	isRemoteFollowee(following: Following): following is RemoteFolloweeFollowing {
-		return following.followeeHost != null;
-	},
-
-	async pack(
-		src: Following["id"] | Following,
-		me?: { id: User["id"] } | null | undefined,
-		opts?: {
-			populateFollowee?: boolean;
-			populateFollower?: boolean;
-		},
-	): Promise<Packed<"Following">> {
-		const following =
-			typeof src === "object" ? src : await this.findOneByOrFail({ id: src });
-
-		if (opts == null) opts = {};
-
-		return await awaitAll({
-			id: following.id,
-			createdAt: following.createdAt.toISOString(),
-			followeeId: following.followeeId,
-			followerId: following.followerId,
-			followee: opts.populateFollowee
-				? Users.pack(following.followee || following.followeeId, me, {
-						detail: true,
-				  })
-				: undefined,
-			follower: opts.populateFollower
-				? Users.pack(following.follower || following.followerId, me, {
-						detail: true,
-				  })
-				: undefined,
-		});
-	},
-
-	packMany(
-		followings: any[],
-		me?: { id: User["id"] } | null | undefined,
-		opts?: {
-			populateFollowee?: boolean;
-			populateFollower?: boolean;
-		},
-	) {
-		return Promise.all(followings.map((x) => this.pack(x, me, opts)));
-	},
-});
diff --git a/packages/backend/src/models/repositories/gallery-like.ts b/packages/backend/src/models/repositories/gallery-like.ts
deleted file mode 100644
index c8920d1ee6..0000000000
--- a/packages/backend/src/models/repositories/gallery-like.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import { db } from "@/db/postgre.js";
-import { GalleryLike } from "@/models/entities/gallery-like.js";
-import { GalleryPosts } from "../index.js";
-
-export const GalleryLikeRepository = db.getRepository(GalleryLike).extend({
-	async pack(src: GalleryLike["id"] | GalleryLike, me?: any) {
-		const like =
-			typeof src === "object" ? src : await this.findOneByOrFail({ id: src });
-
-		return {
-			id: like.id,
-			post: await GalleryPosts.pack(like.post || like.postId, me),
-		};
-	},
-
-	packMany(likes: any[], me: any) {
-		return Promise.all(likes.map((x) => this.pack(x, me)));
-	},
-});
diff --git a/packages/backend/src/models/repositories/gallery-post.ts b/packages/backend/src/models/repositories/gallery-post.ts
deleted file mode 100644
index b4206b0bf4..0000000000
--- a/packages/backend/src/models/repositories/gallery-post.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import { db } from "@/db/postgre.js";
-import { GalleryPost } from "@/models/entities/gallery-post.js";
-import type { Packed } from "@/misc/schema.js";
-import { Users, DriveFiles, GalleryLikes } from "../index.js";
-import { awaitAll } from "@/prelude/await-all.js";
-import type { User } from "@/models/entities/user.js";
-
-export const GalleryPostRepository = db.getRepository(GalleryPost).extend({
-	async pack(
-		src: GalleryPost["id"] | GalleryPost,
-		me?: { id: User["id"] } | null | undefined,
-	): Promise<Packed<"GalleryPost">> {
-		const meId = me ? me.id : null;
-		const post =
-			typeof src === "object" ? src : await this.findOneByOrFail({ id: src });
-
-		return await awaitAll({
-			id: post.id,
-			createdAt: post.createdAt.toISOString(),
-			updatedAt: post.updatedAt.toISOString(),
-			userId: post.userId,
-			user: Users.pack(post.user || post.userId, me),
-			title: post.title,
-			description: post.description,
-			fileIds: post.fileIds,
-			files: DriveFiles.packMany(post.fileIds),
-			tags: post.tags.length > 0 ? post.tags : undefined,
-			isSensitive: post.isSensitive,
-			likedCount: post.likedCount,
-			isLiked: meId
-				? await GalleryLikes.findOneBy({ postId: post.id, userId: meId }).then(
-						(x) => x != null,
-				  )
-				: undefined,
-		});
-	},
-
-	packMany(posts: GalleryPost[], me?: { id: User["id"] } | null | undefined) {
-		return Promise.all(posts.map((x) => this.pack(x, me)));
-	},
-});
diff --git a/packages/backend/src/models/repositories/hashtag.ts b/packages/backend/src/models/repositories/hashtag.ts
deleted file mode 100644
index 7bd76c1c70..0000000000
--- a/packages/backend/src/models/repositories/hashtag.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { db } from "@/db/postgre.js";
-import { Hashtag } from "@/models/entities/hashtag.js";
-import type { Packed } from "@/misc/schema.js";
-
-export const HashtagRepository = db.getRepository(Hashtag).extend({
-	async pack(src: Hashtag): Promise<Packed<"Hashtag">> {
-		return {
-			tag: src.name,
-			mentionedUsersCount: src.mentionedUsersCount,
-			mentionedLocalUsersCount: src.mentionedLocalUsersCount,
-			mentionedRemoteUsersCount: src.mentionedRemoteUsersCount,
-			attachedUsersCount: src.attachedUsersCount,
-			attachedLocalUsersCount: src.attachedLocalUsersCount,
-			attachedRemoteUsersCount: src.attachedRemoteUsersCount,
-		};
-	},
-
-	packMany(hashtags: Hashtag[]) {
-		return Promise.all(hashtags.map((x) => this.pack(x)));
-	},
-});
diff --git a/packages/backend/src/models/repositories/instance.ts b/packages/backend/src/models/repositories/instance.ts
deleted file mode 100644
index fb4498911a..0000000000
--- a/packages/backend/src/models/repositories/instance.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import { db } from "@/db/postgre.js";
-import { Instance } from "@/models/entities/instance.js";
-import type { Packed } from "@/misc/schema.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { shouldBlockInstance } from "@/misc/should-block-instance.js";
-
-export const InstanceRepository = db.getRepository(Instance).extend({
-	async pack(instance: Instance): Promise<Packed<"FederationInstance">> {
-		const meta = await fetchMeta();
-		return {
-			id: instance.id,
-			caughtAt: instance.caughtAt.toISOString(),
-			host: instance.host,
-			usersCount: instance.usersCount,
-			notesCount: instance.notesCount,
-			followingCount: instance.followingCount,
-			followersCount: instance.followersCount,
-			latestRequestSentAt: instance.latestRequestSentAt
-				? instance.latestRequestSentAt.toISOString()
-				: null,
-			lastCommunicatedAt: instance.lastCommunicatedAt.toISOString(),
-			isNotResponding: instance.isNotResponding,
-			isSuspended: instance.isSuspended,
-			isBlocked: await shouldBlockInstance(instance.host),
-			softwareName: instance.softwareName,
-			softwareVersion: instance.softwareVersion,
-			openRegistrations: instance.openRegistrations,
-			name: instance.name,
-			description: instance.description,
-			maintainerName: instance.maintainerName,
-			maintainerEmail: instance.maintainerEmail,
-			iconUrl: instance.iconUrl,
-			faviconUrl: instance.faviconUrl,
-			themeColor: instance.themeColor,
-			infoUpdatedAt: instance.infoUpdatedAt
-				? instance.infoUpdatedAt.toISOString()
-				: null,
-		};
-	},
-
-	packMany(instances: Instance[]) {
-		return Promise.all(instances.map((x) => this.pack(x)));
-	},
-});
diff --git a/packages/backend/src/models/repositories/messaging-message.ts b/packages/backend/src/models/repositories/messaging-message.ts
deleted file mode 100644
index 6c0987bf08..0000000000
--- a/packages/backend/src/models/repositories/messaging-message.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-import { db } from "@/db/postgre.js";
-import { MessagingMessage } from "@/models/entities/messaging-message.js";
-import { Users, DriveFiles, UserGroups } from "../index.js";
-import type { Packed } from "@/misc/schema.js";
-import type { User } from "@/models/entities/user.js";
-
-export const MessagingMessageRepository = db
-	.getRepository(MessagingMessage)
-	.extend({
-		async pack(
-			src: MessagingMessage["id"] | MessagingMessage,
-			me?: { id: User["id"] } | null | undefined,
-			options?: {
-				populateRecipient?: boolean;
-				populateGroup?: boolean;
-			},
-		): Promise<Packed<"MessagingMessage">> {
-			const opts = options || {
-				populateRecipient: true,
-				populateGroup: true,
-			};
-
-			const message =
-				typeof src === "object" ? src : await this.findOneByOrFail({ id: src });
-
-			return {
-				id: message.id,
-				createdAt: message.createdAt.toISOString(),
-				text: message.text,
-				userId: message.userId,
-				user: await Users.pack(message.user || message.userId, me),
-				recipientId: message.recipientId,
-				recipient:
-					message.recipientId && opts.populateRecipient
-						? await Users.pack(message.recipient || message.recipientId, me)
-						: undefined,
-				groupId: message.groupId,
-				group:
-					message.groupId && opts.populateGroup
-						? await UserGroups.pack(message.group || message.groupId)
-						: undefined,
-				fileId: message.fileId,
-				file: message.fileId ? await DriveFiles.pack(message.fileId) : null,
-				isRead: message.isRead,
-				reads: message.reads,
-			};
-		},
-	});
diff --git a/packages/backend/src/models/repositories/moderation-logs.ts b/packages/backend/src/models/repositories/moderation-logs.ts
deleted file mode 100644
index 3858b9509b..0000000000
--- a/packages/backend/src/models/repositories/moderation-logs.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import { db } from "@/db/postgre.js";
-import { Users } from "../index.js";
-import { ModerationLog } from "@/models/entities/moderation-log.js";
-import { awaitAll } from "@/prelude/await-all.js";
-
-export const ModerationLogRepository = db.getRepository(ModerationLog).extend({
-	async pack(src: ModerationLog["id"] | ModerationLog) {
-		const log =
-			typeof src === "object" ? src : await this.findOneByOrFail({ id: src });
-
-		return await awaitAll({
-			id: log.id,
-			createdAt: log.createdAt.toISOString(),
-			type: log.type,
-			info: log.info,
-			userId: log.userId,
-			user: Users.pack(log.user || log.userId, null, {
-				detail: true,
-			}),
-		});
-	},
-
-	packMany(reports: any[]) {
-		return Promise.all(reports.map((x) => this.pack(x)));
-	},
-});
diff --git a/packages/backend/src/models/repositories/muting.ts b/packages/backend/src/models/repositories/muting.ts
deleted file mode 100644
index 4d0201d5a0..0000000000
--- a/packages/backend/src/models/repositories/muting.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import { db } from "@/db/postgre.js";
-import { Users } from "../index.js";
-import { Muting } from "@/models/entities/muting.js";
-import { awaitAll } from "@/prelude/await-all.js";
-import type { Packed } from "@/misc/schema.js";
-import type { User } from "@/models/entities/user.js";
-
-export const MutingRepository = db.getRepository(Muting).extend({
-	async pack(
-		src: Muting["id"] | Muting,
-		me?: { id: User["id"] } | null | undefined,
-	): Promise<Packed<"Muting">> {
-		const muting =
-			typeof src === "object" ? src : await this.findOneByOrFail({ id: src });
-
-		return await awaitAll({
-			id: muting.id,
-			createdAt: muting.createdAt.toISOString(),
-			expiresAt: muting.expiresAt ? muting.expiresAt.toISOString() : null,
-			muteeId: muting.muteeId,
-			mutee: Users.pack(muting.muteeId, me, {
-				detail: true,
-			}),
-		});
-	},
-
-	packMany(mutings: any[], me: { id: User["id"] }) {
-		return Promise.all(mutings.map((x) => this.pack(x, me)));
-	},
-});
diff --git a/packages/backend/src/models/repositories/note-favorite.ts b/packages/backend/src/models/repositories/note-favorite.ts
deleted file mode 100644
index ba43e3c3b4..0000000000
--- a/packages/backend/src/models/repositories/note-favorite.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { db } from "@/db/postgre.js";
-import { NoteFavorite } from "@/models/entities/note-favorite.js";
-import { Notes } from "../index.js";
-import type { User } from "@/models/entities/user.js";
-
-export const NoteFavoriteRepository = db.getRepository(NoteFavorite).extend({
-	async pack(
-		src: NoteFavorite["id"] | NoteFavorite,
-		me?: { id: User["id"] } | null | undefined,
-	) {
-		const favorite =
-			typeof src === "object" ? src : await this.findOneByOrFail({ id: src });
-
-		return {
-			id: favorite.id,
-			createdAt: favorite.createdAt.toISOString(),
-			noteId: favorite.noteId,
-			// may throw error
-			note: await Notes.pack(favorite.note || favorite.noteId, me),
-		};
-	},
-
-	packMany(favorites: any[], me: { id: User["id"] }) {
-		return Promise.allSettled(favorites.map((x) => this.pack(x, me))).then(
-			(promises) =>
-				promises.flatMap((result) =>
-					result.status === "fulfilled" ? [result.value] : [],
-				),
-		);
-	},
-});
diff --git a/packages/backend/src/models/repositories/note-reaction.ts b/packages/backend/src/models/repositories/note-reaction.ts
deleted file mode 100644
index 6d1dfbd6fd..0000000000
--- a/packages/backend/src/models/repositories/note-reaction.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-import { db } from "@/db/postgre.js";
-import { NoteReaction } from "@/models/entities/note-reaction.js";
-import { Notes, Users } from "../index.js";
-import type { Packed } from "@/misc/schema.js";
-import { convertLegacyReaction } from "@/misc/reaction-lib.js";
-import type { User } from "@/models/entities/user.js";
-
-export const NoteReactionRepository = db.getRepository(NoteReaction).extend({
-	async pack(
-		src: NoteReaction["id"] | NoteReaction,
-		me?: { id: User["id"] } | null | undefined,
-		options?: {
-			withNote: boolean;
-		},
-	): Promise<Packed<"NoteReaction">> {
-		const opts = Object.assign(
-			{
-				withNote: false,
-			},
-			options,
-		);
-
-		const reaction =
-			typeof src === "object" ? src : await this.findOneByOrFail({ id: src });
-
-		return {
-			id: reaction.id,
-			createdAt: reaction.createdAt.toISOString(),
-			user: await Users.pack(reaction.user ?? reaction.userId, me),
-			type: convertLegacyReaction(reaction.reaction),
-			...(opts.withNote
-				? {
-						// may throw error
-						note: await Notes.pack(reaction.note ?? reaction.noteId, me),
-				  }
-				: {}),
-		};
-	},
-
-	async packMany(
-		src: NoteReaction[],
-		me?: { id: User["id"] } | null | undefined,
-		options?: {
-			withNote: booleam;
-		},
-	): Promise<Packed<"NoteReaction">[]> {
-		const reactions = await Promise.allSettled(
-			src.map((reaction) => this.pack(reaction, me, options)),
-		);
-
-		// filter out rejected promises, only keep fulfilled values
-		return reactions.flatMap((result) =>
-			result.status === "fulfilled" ? [result.value] : [],
-		);
-	},
-});
diff --git a/packages/backend/src/models/repositories/note.ts b/packages/backend/src/models/repositories/note.ts
deleted file mode 100644
index 5e56a817bc..0000000000
--- a/packages/backend/src/models/repositories/note.ts
+++ /dev/null
@@ -1,334 +0,0 @@
-import { In } from "typeorm";
-import * as mfm from "mfm-js";
-import { Note } from "@/models/entities/note.js";
-import type { User } from "@/models/entities/user.js";
-import {
-	Users,
-	PollVotes,
-	DriveFiles,
-	NoteReactions,
-	Followings,
-	Polls,
-	Channels,
-} from "../index.js";
-import type { Packed } from "@/misc/schema.js";
-import { nyaize } from "@/misc/nyaize.js";
-import { awaitAll } from "@/prelude/await-all.js";
-import {
-	convertLegacyReaction,
-	convertLegacyReactions,
-	decodeReaction,
-} from "@/misc/reaction-lib.js";
-import type { NoteReaction } from "@/models/entities/note-reaction.js";
-import {
-	aggregateNoteEmojis,
-	populateEmojis,
-	prefetchEmojis,
-} from "@/misc/populate-emojis.js";
-import { db } from "@/db/postgre.js";
-import { IdentifiableError } from "@/misc/identifiable-error.js";
-
-async function populatePoll(note: Note, meId: User["id"] | null) {
-	const poll = await Polls.findOneByOrFail({ noteId: note.id });
-	const choices = poll.choices.map((c) => ({
-		text: c,
-		votes: poll.votes[poll.choices.indexOf(c)],
-		isVoted: false,
-	}));
-
-	if (meId) {
-		if (poll.multiple) {
-			const votes = await PollVotes.findBy({
-				userId: meId,
-				noteId: note.id,
-			});
-
-			const myChoices = votes.map((v) => v.choice);
-			for (const myChoice of myChoices) {
-				choices[myChoice].isVoted = true;
-			}
-		} else {
-			const vote = await PollVotes.findOneBy({
-				userId: meId,
-				noteId: note.id,
-			});
-
-			if (vote) {
-				choices[vote.choice].isVoted = true;
-			}
-		}
-	}
-
-	return {
-		multiple: poll.multiple,
-		expiresAt: poll.expiresAt,
-		choices,
-	};
-}
-
-async function populateMyReaction(
-	note: Note,
-	meId: User["id"],
-	_hint_?: {
-		myReactions: Map<Note["id"], NoteReaction | null>;
-	},
-) {
-	if (_hint_?.myReactions) {
-		const reaction = _hint_.myReactions.get(note.id);
-		if (reaction) {
-			return convertLegacyReaction(reaction.reaction);
-		} else if (reaction === null) {
-			return undefined;
-		}
-		// 実装上抜けがあるだけかもしれないので、「ヒントに含まれてなかったら(=undefinedなら)return」のようにはしない
-	}
-
-	const reaction = await NoteReactions.findOneBy({
-		userId: meId,
-		noteId: note.id,
-	});
-
-	if (reaction) {
-		return convertLegacyReaction(reaction.reaction);
-	}
-
-	return undefined;
-}
-
-export const NoteRepository = db.getRepository(Note).extend({
-	async isVisibleForMe(note: Note, meId: User["id"] | null): Promise<boolean> {
-		// This code must always be synchronized with the checks in generateVisibilityQuery.
-		// visibility が specified かつ自分が指定されていなかったら非表示
-		if (note.visibility === "specified") {
-			if (meId == null) {
-				return false;
-			} else if (meId === note.userId) {
-				return true;
-			} else {
-				// 指定されているかどうか
-				return note.visibleUserIds.some((id: any) => meId === id);
-			}
-		}
-
-		// visibility が followers かつ自分が投稿者のフォロワーでなかったら非表示
-		if (note.visibility === "followers") {
-			if (meId == null) {
-				return false;
-			} else if (meId === note.userId) {
-				return true;
-			} else if (note.reply && meId === note.reply.userId) {
-				// 自分の投稿に対するリプライ
-				return true;
-			} else if (note.mentions?.some((id) => meId === id)) {
-				// 自分へのメンション
-				return true;
-			} else {
-				// フォロワーかどうか
-				const [following, user] = await Promise.all([
-					Followings.count({
-						where: {
-							followeeId: note.userId,
-							followerId: meId,
-						},
-						take: 1,
-					}),
-					Users.findOneByOrFail({ id: meId }),
-				]);
-
-				/* If we know the following, everyhting is fine.
-
-				But if we do not know the following, it might be that both the
-				author of the note and the author of the like are remote users,
-				in which case we can never know the following. Instead we have
-				to assume that the users are following each other.
-				*/
-				return following > 0 || (note.userHost != null && user.host != null);
-			}
-		}
-
-		return true;
-	},
-
-	async pack(
-		src: Note["id"] | Note,
-		me?: { id: User["id"] } | null | undefined,
-		options?: {
-			detail?: boolean;
-			_hint_?: {
-				myReactions: Map<Note["id"], NoteReaction | null>;
-			};
-		},
-	): Promise<Packed<"Note">> {
-		const opts = Object.assign(
-			{
-				detail: true,
-			},
-			options,
-		);
-
-		const meId = me ? me.id : null;
-		const note =
-			typeof src === "object" ? src : await this.findOneByOrFail({ id: src });
-		const host = note.userHost;
-
-		if (!(await this.isVisibleForMe(note, meId))) {
-			throw new IdentifiableError(
-				"9725d0ce-ba28-4dde-95a7-2cbb2c15de24",
-				"No such note.",
-			);
-		}
-
-		let text = note.text;
-
-		if (note.name && (note.url ?? note.uri)) {
-			text = `【${note.name}】\n${(note.text || "").trim()}\n\n${
-				note.url ?? note.uri
-			}`;
-		}
-
-		const channel = note.channelId
-			? note.channel
-				? note.channel
-				: await Channels.findOneBy({ id: note.channelId })
-			: null;
-
-		const reactionEmojiNames = Object.keys(note.reactions)
-			.filter((x) => x?.startsWith(":"))
-			.map((x) => decodeReaction(x).reaction)
-			.map((x) => x.replace(/:/g, ""));
-
-		const noteEmoji = await populateEmojis(
-			note.emojis.concat(reactionEmojiNames),
-			host,
-		);
-		const reactionEmoji = await populateEmojis(reactionEmojiNames, host);
-		const packed: Packed<"Note"> = await awaitAll({
-			id: note.id,
-			createdAt: note.createdAt.toISOString(),
-			userId: note.userId,
-			user: Users.pack(note.user ?? note.userId, me, {
-				detail: false,
-			}),
-			text: text,
-			cw: note.cw,
-			visibility: note.visibility,
-			localOnly: note.localOnly || undefined,
-			visibleUserIds:
-				note.visibility === "specified" ? note.visibleUserIds : undefined,
-			renoteCount: note.renoteCount,
-			repliesCount: note.repliesCount,
-			reactions: convertLegacyReactions(note.reactions),
-			reactionEmojis: reactionEmoji,
-			emojis: noteEmoji,
-			tags: note.tags.length > 0 ? note.tags : undefined,
-			fileIds: note.fileIds,
-			files: DriveFiles.packMany(note.fileIds),
-			replyId: note.replyId,
-			renoteId: note.renoteId,
-			channelId: note.channelId || undefined,
-			channel: channel
-				? {
-						id: channel.id,
-						name: channel.name,
-				  }
-				: undefined,
-			mentions: note.mentions.length > 0 ? note.mentions : undefined,
-			uri: note.uri || undefined,
-			url: note.url || undefined,
-
-			...(opts.detail
-				? {
-						reply: note.replyId
-							? this.pack(note.reply || note.replyId, me, {
-									detail: false,
-									_hint_: options?._hint_,
-							  })
-							: undefined,
-
-						renote: note.renoteId
-							? this.pack(note.renote || note.renoteId, me, {
-									detail: true,
-									_hint_: options?._hint_,
-							  })
-							: undefined,
-
-						poll: note.hasPoll ? populatePoll(note, meId) : undefined,
-
-						...(meId
-							? {
-									myReaction: populateMyReaction(note, meId, options?._hint_),
-							  }
-							: {}),
-				  }
-				: {}),
-		});
-
-		if (packed.user.isCat && packed.user.speakAsCat && packed.text) {
-			const tokens = packed.text ? mfm.parse(packed.text) : [];
-			function nyaizeNode(node: mfm.MfmNode) {
-				if (node.type === "quote") return;
-				if (node.type === "text") node.props.text = nyaize(node.props.text);
-
-				if (node.children) {
-					for (const child of node.children) {
-						nyaizeNode(child);
-					}
-				}
-			}
-
-			for (const node of tokens) nyaizeNode(node);
-
-			packed.text = mfm.toString(tokens);
-		}
-
-		return packed;
-	},
-
-	async packMany(
-		notes: Note[],
-		me?: { id: User["id"] } | null | undefined,
-		options?: {
-			detail?: boolean;
-		},
-	) {
-		if (notes.length === 0) return [];
-
-		const meId = me ? me.id : null;
-		const myReactionsMap = new Map<Note["id"], NoteReaction | null>();
-		if (meId) {
-			const renoteIds = notes
-				.filter((n) => n.renoteId != null)
-				.map((n) => n.renoteId!);
-			const targets = [...notes.map((n) => n.id), ...renoteIds];
-			const myReactions = await NoteReactions.findBy({
-				userId: meId,
-				noteId: In(targets),
-			});
-
-			for (const target of targets) {
-				myReactionsMap.set(
-					target,
-					myReactions.find((reaction) => reaction.noteId === target) || null,
-				);
-			}
-		}
-
-		await prefetchEmojis(aggregateNoteEmojis(notes));
-
-		const promises = await Promise.allSettled(
-			notes.map((n) =>
-				this.pack(n, me, {
-					...options,
-					_hint_: {
-						myReactions: myReactionsMap,
-					},
-				}),
-			),
-		);
-
-		// filter out rejected promises, only keep fulfilled values
-		return promises.flatMap((result) =>
-			result.status === "fulfilled" ? [result.value] : [],
-		);
-	},
-});
diff --git a/packages/backend/src/models/repositories/notification.ts b/packages/backend/src/models/repositories/notification.ts
deleted file mode 100644
index 1538e67d86..0000000000
--- a/packages/backend/src/models/repositories/notification.ts
+++ /dev/null
@@ -1,185 +0,0 @@
-import { In, Repository } from "typeorm";
-import { Notification } from "@/models/entities/notification.js";
-import { awaitAll } from "@/prelude/await-all.js";
-import type { Packed } from "@/misc/schema.js";
-import type { Note } from "@/models/entities/note.js";
-import type { NoteReaction } from "@/models/entities/note-reaction.js";
-import type { User } from "@/models/entities/user.js";
-import { aggregateNoteEmojis, prefetchEmojis } from "@/misc/populate-emojis.js";
-import { notificationTypes } from "@/types.js";
-import { db } from "@/db/postgre.js";
-import {
-	Users,
-	Notes,
-	UserGroupInvitations,
-	AccessTokens,
-	NoteReactions,
-} from "../index.js";
-
-export const NotificationRepository = db.getRepository(Notification).extend({
-	async pack(
-		src: Notification["id"] | Notification,
-		options: {
-			_hintForEachNotes_?: {
-				myReactions: Map<Note["id"], NoteReaction | null>;
-			};
-		},
-	): Promise<Packed<"Notification">> {
-		const notification =
-			typeof src === "object" ? src : await this.findOneByOrFail({ id: src });
-		const token = notification.appAccessTokenId
-			? await AccessTokens.findOneByOrFail({
-					id: notification.appAccessTokenId,
-			  })
-			: null;
-
-		return await awaitAll({
-			id: notification.id,
-			createdAt: notification.createdAt.toISOString(),
-			type: notification.type,
-			isRead: notification.isRead,
-			userId: notification.notifierId,
-			user: notification.notifierId
-				? Users.pack(notification.notifier || notification.notifierId)
-				: null,
-			...(notification.type === "mention"
-				? {
-						note: Notes.pack(
-							notification.note || notification.noteId!,
-							{ id: notification.notifieeId },
-							{
-								detail: true,
-								_hint_: options._hintForEachNotes_,
-							},
-						),
-				  }
-				: {}),
-			...(notification.type === "reply"
-				? {
-						note: Notes.pack(
-							notification.note || notification.noteId!,
-							{ id: notification.notifieeId },
-							{
-								detail: true,
-								_hint_: options._hintForEachNotes_,
-							},
-						),
-				  }
-				: {}),
-			...(notification.type === "renote"
-				? {
-						note: Notes.pack(
-							notification.note || notification.noteId!,
-							{ id: notification.notifieeId },
-							{
-								detail: true,
-								_hint_: options._hintForEachNotes_,
-							},
-						),
-				  }
-				: {}),
-			...(notification.type === "quote"
-				? {
-						note: Notes.pack(
-							notification.note || notification.noteId!,
-							{ id: notification.notifieeId },
-							{
-								detail: true,
-								_hint_: options._hintForEachNotes_,
-							},
-						),
-				  }
-				: {}),
-			...(notification.type === "reaction"
-				? {
-						note: Notes.pack(
-							notification.note || notification.noteId!,
-							{ id: notification.notifieeId },
-							{
-								detail: true,
-								_hint_: options._hintForEachNotes_,
-							},
-						),
-						reaction: notification.reaction,
-				  }
-				: {}),
-			...(notification.type === "pollVote"
-				? {
-						note: Notes.pack(
-							notification.note || notification.noteId!,
-							{ id: notification.notifieeId },
-							{
-								detail: true,
-								_hint_: options._hintForEachNotes_,
-							},
-						),
-						choice: notification.choice,
-				  }
-				: {}),
-			...(notification.type === "pollEnded"
-				? {
-						note: Notes.pack(
-							notification.note || notification.noteId!,
-							{ id: notification.notifieeId },
-							{
-								detail: true,
-								_hint_: options._hintForEachNotes_,
-							},
-						),
-				  }
-				: {}),
-			...(notification.type === "groupInvited"
-				? {
-						invitation: UserGroupInvitations.pack(
-							notification.userGroupInvitationId!,
-						),
-				  }
-				: {}),
-			...(notification.type === "app"
-				? {
-						body: notification.customBody,
-						header: notification.customHeader || token?.name,
-						icon: notification.customIcon || token?.iconUrl,
-				  }
-				: {}),
-		});
-	},
-
-	async packMany(notifications: Notification[], meId: User["id"]) {
-		if (notifications.length === 0) return [];
-
-		const notes = notifications
-			.filter((x) => x.note != null)
-			.map((x) => x.note!);
-		const noteIds = notes.map((n) => n.id);
-		const myReactionsMap = new Map<Note["id"], NoteReaction | null>();
-		const renoteIds = notes
-			.filter((n) => n.renoteId != null)
-			.map((n) => n.renoteId!);
-		const targets = [...noteIds, ...renoteIds];
-		const myReactions = await NoteReactions.findBy({
-			userId: meId,
-			noteId: In(targets),
-		});
-
-		for (const target of targets) {
-			myReactionsMap.set(
-				target,
-				myReactions.find((reaction) => reaction.noteId === target) || null,
-			);
-		}
-
-		await prefetchEmojis(aggregateNoteEmojis(notes));
-
-		const results = await Promise.all(
-			notifications.map((x) =>
-				this.pack(x, {
-					_hintForEachNotes_: {
-						myReactions: myReactionsMap,
-					},
-				}).catch((e) => null),
-			),
-		);
-		return results.filter((x) => x != null);
-	},
-});
diff --git a/packages/backend/src/models/repositories/page-like.ts b/packages/backend/src/models/repositories/page-like.ts
deleted file mode 100644
index f78ef81b02..0000000000
--- a/packages/backend/src/models/repositories/page-like.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import { db } from "@/db/postgre.js";
-import { PageLike } from "@/models/entities/page-like.js";
-import type { User } from "@/models/entities/user.js";
-import { Pages } from "../index.js";
-
-export const PageLikeRepository = db.getRepository(PageLike).extend({
-	async pack(
-		src: PageLike["id"] | PageLike,
-		me?: { id: User["id"] } | null | undefined,
-	) {
-		const like =
-			typeof src === "object" ? src : await this.findOneByOrFail({ id: src });
-
-		return {
-			id: like.id,
-			page: await Pages.pack(like.page || like.pageId, me),
-		};
-	},
-
-	packMany(likes: PageLike[], me: { id: User["id"] }) {
-		return Promise.all(likes.map((x) => this.pack(x, me)));
-	},
-});
diff --git a/packages/backend/src/models/repositories/page.ts b/packages/backend/src/models/repositories/page.ts
deleted file mode 100644
index d9241c3629..0000000000
--- a/packages/backend/src/models/repositories/page.ts
+++ /dev/null
@@ -1,99 +0,0 @@
-import { db } from "@/db/postgre.js";
-import { Page } from "@/models/entities/page.js";
-import type { Packed } from "@/misc/schema.js";
-import { awaitAll } from "@/prelude/await-all.js";
-import type { DriveFile } from "@/models/entities/drive-file.js";
-import type { User } from "@/models/entities/user.js";
-import { Users, DriveFiles, PageLikes } from "../index.js";
-
-export const PageRepository = db.getRepository(Page).extend({
-	async pack(
-		src: Page["id"] | Page,
-		me?: { id: User["id"] } | null | undefined,
-	): Promise<Packed<"Page">> {
-		const meId = me ? me.id : null;
-		const page =
-			typeof src === "object" ? src : await this.findOneByOrFail({ id: src });
-
-		const attachedFiles: Promise<DriveFile | null>[] = [];
-		const collectFile = (xs: any[]) => {
-			for (const x of xs) {
-				if (x.type === "image") {
-					attachedFiles.push(
-						DriveFiles.findOneBy({
-							id: x.fileId,
-							userId: page.userId,
-						}),
-					);
-				}
-				if (x.children) {
-					collectFile(x.children);
-				}
-			}
-		};
-		collectFile(page.content);
-
-		// 後方互換性のため
-		let migrated = false;
-		const migrate = (xs: any[]) => {
-			for (const x of xs) {
-				if (x.type === "input") {
-					if (x.inputType === "text") {
-						x.type = "textInput";
-					}
-					if (x.inputType === "number") {
-						x.type = "numberInput";
-						if (x.default) x.default = parseInt(x.default, 10);
-					}
-					migrated = true;
-				}
-				if (x.children) {
-					migrate(x.children);
-				}
-			}
-		};
-		migrate(page.content);
-		if (migrated) {
-			this.update(page.id, {
-				content: page.content,
-			});
-		}
-
-		return await awaitAll({
-			id: page.id,
-			createdAt: page.createdAt.toISOString(),
-			updatedAt: page.updatedAt.toISOString(),
-			userId: page.userId,
-			user: Users.pack(page.user || page.userId, me), // { detail: true } すると無限ループするので注意
-			content: page.content,
-			variables: page.variables,
-			title: page.title,
-			isPublic: page.isPublic,
-			name: page.name,
-			summary: page.summary,
-			hideTitleWhenPinned: page.hideTitleWhenPinned,
-			alignCenter: page.alignCenter,
-			font: page.font,
-			script: page.script,
-			eyeCatchingImageId: page.eyeCatchingImageId,
-			eyeCatchingImage: page.eyeCatchingImageId
-				? await DriveFiles.pack(page.eyeCatchingImageId)
-				: null,
-			attachedFiles: DriveFiles.packMany(
-				(
-					await Promise.all(attachedFiles)
-				).filter((x): x is DriveFile => x != null),
-			),
-			likedCount: page.likedCount,
-			isLiked: meId
-				? await PageLikes.findOneBy({ pageId: page.id, userId: meId }).then(
-						(x) => x != null,
-				  )
-				: undefined,
-		});
-	},
-
-	packMany(pages: Page[], me?: { id: User["id"] } | null | undefined) {
-		return Promise.all(pages.map((x) => this.pack(x, me)));
-	},
-});
diff --git a/packages/backend/src/models/repositories/relay.ts b/packages/backend/src/models/repositories/relay.ts
deleted file mode 100644
index 633861496a..0000000000
--- a/packages/backend/src/models/repositories/relay.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-import { db } from "@/db/postgre.js";
-import { Relay } from "@/models/entities/relay.js";
-
-export const RelayRepository = db.getRepository(Relay).extend({});
diff --git a/packages/backend/src/models/repositories/renote-muting.ts b/packages/backend/src/models/repositories/renote-muting.ts
deleted file mode 100644
index 18fd343a05..0000000000
--- a/packages/backend/src/models/repositories/renote-muting.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import { db } from "@/db/postgre.js";
-import { Packed } from "@/misc/schema.js";
-import { RenoteMuting } from "@/models/entities/renote-muting.js";
-import { User } from "@/models/entities/user.js";
-import { awaitAll } from "@/prelude/await-all.js";
-import { Users } from "../index.js";
-
-export const RenoteMutingRepository = db.getRepository(RenoteMuting).extend({
-	async pack(
-		src: RenoteMuting["id"] | RenoteMuting,
-		me?: { id: User["id"] } | null | undefined,
-	): Promise<Packed<"RenoteMuting">> {
-		const muting =
-			typeof src === "object" ? src : await this.findOneByOrFail({ id: src });
-
-		return await awaitAll({
-			id: muting.id,
-			createdAt: muting.createdAt.toISOString(),
-			muteeId: muting.muteeId,
-			mutee: Users.pack(muting.muteeId, me, {
-				detail: true,
-			}),
-		});
-	},
-
-	packMany(mutings: any[], me: { id: User["id"] }) {
-		return Promise.all(mutings.map((x) => this.pack(x, me)));
-	},
-});
diff --git a/packages/backend/src/models/repositories/signin.ts b/packages/backend/src/models/repositories/signin.ts
deleted file mode 100644
index 06cf2c2108..0000000000
--- a/packages/backend/src/models/repositories/signin.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import { db } from "@/db/postgre.js";
-import { Signin } from "@/models/entities/signin.js";
-
-export const SigninRepository = db.getRepository(Signin).extend({
-	async pack(src: Signin) {
-		return src;
-	},
-});
diff --git a/packages/backend/src/models/repositories/user-group-invitation.ts b/packages/backend/src/models/repositories/user-group-invitation.ts
deleted file mode 100644
index 920fb9ba29..0000000000
--- a/packages/backend/src/models/repositories/user-group-invitation.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import { db } from "@/db/postgre.js";
-import { UserGroupInvitation } from "@/models/entities/user-group-invitation.js";
-import { UserGroups } from "../index.js";
-
-export const UserGroupInvitationRepository = db
-	.getRepository(UserGroupInvitation)
-	.extend({
-		async pack(src: UserGroupInvitation["id"] | UserGroupInvitation) {
-			const invitation =
-				typeof src === "object" ? src : await this.findOneByOrFail({ id: src });
-
-			return {
-				id: invitation.id,
-				group: await UserGroups.pack(
-					invitation.userGroup || invitation.userGroupId,
-				),
-			};
-		},
-
-		packMany(invitations: any[]) {
-			return Promise.all(invitations.map((x) => this.pack(x)));
-		},
-	});
diff --git a/packages/backend/src/models/repositories/user-group.ts b/packages/backend/src/models/repositories/user-group.ts
deleted file mode 100644
index daec94490e..0000000000
--- a/packages/backend/src/models/repositories/user-group.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import { db } from "@/db/postgre.js";
-import { UserGroup } from "@/models/entities/user-group.js";
-import { UserGroupJoinings } from "../index.js";
-import type { Packed } from "@/misc/schema.js";
-
-export const UserGroupRepository = db.getRepository(UserGroup).extend({
-	async pack(src: UserGroup["id"] | UserGroup): Promise<Packed<"UserGroup">> {
-		const userGroup =
-			typeof src === "object" ? src : await this.findOneByOrFail({ id: src });
-
-		const users = await UserGroupJoinings.findBy({
-			userGroupId: userGroup.id,
-		});
-
-		return {
-			id: userGroup.id,
-			createdAt: userGroup.createdAt.toISOString(),
-			name: userGroup.name,
-			ownerId: userGroup.userId,
-			userIds: users.map((x) => x.userId),
-		};
-	},
-});
diff --git a/packages/backend/src/models/repositories/user-list.ts b/packages/backend/src/models/repositories/user-list.ts
deleted file mode 100644
index e3abeac3f6..0000000000
--- a/packages/backend/src/models/repositories/user-list.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import { db } from "@/db/postgre.js";
-import { UserList } from "@/models/entities/user-list.js";
-import { UserListJoinings } from "../index.js";
-import type { Packed } from "@/misc/schema.js";
-
-export const UserListRepository = db.getRepository(UserList).extend({
-	async pack(src: UserList["id"] | UserList): Promise<Packed<"UserList">> {
-		const userList =
-			typeof src === "object" ? src : await this.findOneByOrFail({ id: src });
-
-		const users = await UserListJoinings.findBy({
-			userListId: userList.id,
-		});
-
-		return {
-			id: userList.id,
-			createdAt: userList.createdAt.toISOString(),
-			name: userList.name,
-			userIds: users.map((x) => x.userId),
-		};
-	},
-});
diff --git a/packages/backend/src/models/repositories/user.ts b/packages/backend/src/models/repositories/user.ts
deleted file mode 100644
index f6fcdae296..0000000000
--- a/packages/backend/src/models/repositories/user.ts
+++ /dev/null
@@ -1,619 +0,0 @@
-import { URL } from "url";
-import { In, Not } from "typeorm";
-import Ajv from "ajv";
-import type { ILocalUser, IRemoteUser } from "@/models/entities/user.js";
-import { User } from "@/models/entities/user.js";
-import config from "@/config/index.js";
-import type { Packed } from "@/misc/schema.js";
-import type { Promiseable } from "@/prelude/await-all.js";
-import { awaitAll } from "@/prelude/await-all.js";
-import { populateEmojis } from "@/misc/populate-emojis.js";
-import { getAntennas } from "@/misc/antenna-cache.js";
-import { USER_ACTIVE_THRESHOLD, USER_ONLINE_THRESHOLD } from "@/const.js";
-import { Cache } from "@/misc/cache.js";
-import { db } from "@/db/postgre.js";
-import { isActor, getApId } from "@/remote/activitypub/type.js";
-import DbResolver from "@/remote/activitypub/db-resolver.js";
-import Resolver from "@/remote/activitypub/resolver.js";
-import { createPerson } from "@/remote/activitypub/models/person.js";
-import {
-	AnnouncementReads,
-	Announcements,
-	AntennaNotes,
-	Blockings,
-	ChannelFollowings,
-	DriveFiles,
-	Followings,
-	FollowRequests,
-	Instances,
-	MessagingMessages,
-	Mutings,
-	RenoteMutings,
-	Notes,
-	NoteUnreads,
-	Notifications,
-	Pages,
-	UserGroupJoinings,
-	UserNotePinings,
-	UserProfiles,
-	UserSecurityKeys,
-} from "../index.js";
-import type { Instance } from "../entities/instance.js";
-
-const userInstanceCache = new Cache<Instance | null>(1000 * 60 * 60 * 3);
-
-type IsUserDetailed<Detailed extends boolean> = Detailed extends true
-	? Packed<"UserDetailed">
-	: Packed<"UserLite">;
-type IsMeAndIsUserDetailed<
-	ExpectsMe extends boolean | null,
-	Detailed extends boolean,
-> = Detailed extends true
-	? ExpectsMe extends true
-		? Packed<"MeDetailed">
-		: ExpectsMe extends false
-		? Packed<"UserDetailedNotMe">
-		: Packed<"UserDetailed">
-	: Packed<"UserLite">;
-
-const ajv = new Ajv();
-
-const localUsernameSchema = {
-	type: "string",
-	pattern: /^\w{1,20}$/.toString().slice(1, -1),
-} as const;
-const passwordSchema = { type: "string", minLength: 1 } as const;
-const nameSchema = { type: "string", minLength: 1, maxLength: 50 } as const;
-const descriptionSchema = {
-	type: "string",
-	minLength: 1,
-	maxLength: 2048,
-} as const;
-const locationSchema = { type: "string", minLength: 1, maxLength: 50 } as const;
-const birthdaySchema = {
-	type: "string",
-	pattern: /^([0-9]{4})-([0-9]{2})-([0-9]{2})$/.toString().slice(1, -1),
-} as const;
-
-function isLocalUser(user: User): user is ILocalUser;
-function isLocalUser<T extends { host: User["host"] }>(
-	user: T,
-): user is T & { host: null };
-/**
- * Returns true if the user is local.
- *
- * @param user The user to check.
- * @returns True if the user is local.
- */
-function isLocalUser(user: User | { host: User["host"] }): boolean {
-	return user.host == null;
-}
-
-function isRemoteUser(user: User): user is IRemoteUser;
-function isRemoteUser<T extends { host: User["host"] }>(
-	user: T,
-): user is T & { host: string };
-/**
- * Returns true if the user is remote.
- *
- * @param user The user to check.
- * @returns True if the user is remote.
- */
-function isRemoteUser(user: User | { host: User["host"] }): boolean {
-	return !isLocalUser(user);
-}
-
-export const UserRepository = db.getRepository(User).extend({
-	localUsernameSchema,
-	passwordSchema,
-	nameSchema,
-	descriptionSchema,
-	locationSchema,
-	birthdaySchema,
-
-	//#region Validators
-	validateLocalUsername: ajv.compile(localUsernameSchema),
-	validatePassword: ajv.compile(passwordSchema),
-	validateName: ajv.compile(nameSchema),
-	validateDescription: ajv.compile(descriptionSchema),
-	validateLocation: ajv.compile(locationSchema),
-	validateBirthday: ajv.compile(birthdaySchema),
-	//#endregion
-
-	async getRelation(me: User["id"], target: User["id"]) {
-		return awaitAll({
-			id: target,
-			isFollowing: Followings.count({
-				where: {
-					followerId: me,
-					followeeId: target,
-				},
-				take: 1,
-			}).then((n) => n > 0),
-			isFollowed: Followings.count({
-				where: {
-					followerId: target,
-					followeeId: me,
-				},
-				take: 1,
-			}).then((n) => n > 0),
-			hasPendingFollowRequestFromYou: FollowRequests.count({
-				where: {
-					followerId: me,
-					followeeId: target,
-				},
-				take: 1,
-			}).then((n) => n > 0),
-			hasPendingFollowRequestToYou: FollowRequests.count({
-				where: {
-					followerId: target,
-					followeeId: me,
-				},
-				take: 1,
-			}).then((n) => n > 0),
-			isBlocking: Blockings.count({
-				where: {
-					blockerId: me,
-					blockeeId: target,
-				},
-				take: 1,
-			}).then((n) => n > 0),
-			isBlocked: Blockings.count({
-				where: {
-					blockerId: target,
-					blockeeId: me,
-				},
-				take: 1,
-			}).then((n) => n > 0),
-			isMuted: Mutings.count({
-				where: {
-					muterId: me,
-					muteeId: target,
-				},
-				take: 1,
-			}).then((n) => n > 0),
-			isRenoteMuted: RenoteMutings.count({
-				where: {
-					muterId: me,
-					muteeId: target,
-				},
-				take: 1,
-			}).then((n) => n > 0),
-		});
-	},
-
-	async getHasUnreadMessagingMessage(userId: User["id"]): Promise<boolean> {
-		const mute = await Mutings.findBy({
-			muterId: userId,
-		});
-
-		const joinings = await UserGroupJoinings.findBy({ userId: userId });
-
-		const groupQs = Promise.all(
-			joinings.map((j) =>
-				MessagingMessages.createQueryBuilder("message")
-					.where("message.groupId = :groupId", { groupId: j.userGroupId })
-					.andWhere("message.userId != :userId", { userId: userId })
-					.andWhere("NOT (:userId = ANY(message.reads))", { userId: userId })
-					.andWhere("message.createdAt > :joinedAt", { joinedAt: j.createdAt }) // 自分が加入する前の会話については、未読扱いしない
-					.getOne()
-					.then((x) => x != null),
-			),
-		);
-
-		const [withUser, withGroups] = await Promise.all([
-			MessagingMessages.count({
-				where: {
-					recipientId: userId,
-					isRead: false,
-					...(mute.length > 0
-						? { userId: Not(In(mute.map((x) => x.muteeId))) }
-						: {}),
-				},
-				take: 1,
-			}).then((count) => count > 0),
-			groupQs,
-		]);
-
-		return withUser || withGroups.some((x) => x);
-	},
-
-	async getHasUnreadAnnouncement(userId: User["id"]): Promise<boolean> {
-		const reads = await AnnouncementReads.findBy({
-			userId: userId,
-		});
-
-		const count = await Announcements.countBy(
-			reads.length > 0
-				? {
-						id: Not(In(reads.map((read) => read.announcementId))),
-				  }
-				: {},
-		);
-
-		return count > 0;
-	},
-
-	async userFromURI(uri: string): Promise<User | null> {
-		const dbResolver = new DbResolver();
-		let local = await dbResolver.getUserFromApId(uri);
-		if (local) {
-			return local;
-		}
-
-		// fetching Object once from remote
-		const resolver = new Resolver();
-		const object = (await resolver.resolve(uri)) as any;
-
-		// /@user If a URI other than the id is specified,
-		// the URI is determined here
-		if (uri !== object.id) {
-			local = await dbResolver.getUserFromApId(object.id);
-			if (local != null) return local;
-		}
-
-		return isActor(object) ? await createPerson(getApId(object)) : null;
-	},
-
-	async getHasUnreadAntenna(userId: User["id"]): Promise<boolean> {
-		const myAntennas = (await getAntennas()).filter((a) => a.userId === userId);
-
-		const unread =
-			myAntennas.length > 0
-				? await AntennaNotes.findOneBy({
-						antennaId: In(myAntennas.map((x) => x.id)),
-						read: false,
-				  })
-				: null;
-
-		return unread != null;
-	},
-
-	async getHasUnreadChannel(userId: User["id"]): Promise<boolean> {
-		const channels = await ChannelFollowings.findBy({ followerId: userId });
-
-		const unread =
-			channels.length > 0
-				? await NoteUnreads.findOneBy({
-						userId: userId,
-						noteChannelId: In(channels.map((x) => x.followeeId)),
-				  })
-				: null;
-
-		return unread != null;
-	},
-
-	async getHasUnreadNotification(userId: User["id"]): Promise<boolean> {
-		const mute = await Mutings.findBy({
-			muterId: userId,
-		});
-		const mutedUserIds = mute.map((m) => m.muteeId);
-
-		const count = await Notifications.count({
-			where: {
-				notifieeId: userId,
-				...(mutedUserIds.length > 0
-					? { notifierId: Not(In(mutedUserIds)) }
-					: {}),
-				isRead: false,
-			},
-			take: 1,
-		});
-
-		return count > 0;
-	},
-
-	async getHasPendingReceivedFollowRequest(
-		userId: User["id"],
-	): Promise<boolean> {
-		const count = await FollowRequests.countBy({
-			followeeId: userId,
-		});
-
-		return count > 0;
-	},
-
-	getOnlineStatus(user: User): "unknown" | "online" | "active" | "offline" {
-		if (user.hideOnlineStatus) return "unknown";
-		if (user.lastActiveDate == null) return "unknown";
-		const elapsed = Date.now() - user.lastActiveDate.getTime();
-		return elapsed < USER_ONLINE_THRESHOLD
-			? "online"
-			: elapsed < USER_ACTIVE_THRESHOLD
-			? "active"
-			: "offline";
-	},
-
-	async getAvatarUrl(user: User): Promise<string> {
-		if (user.avatar) {
-			return (
-				DriveFiles.getPublicUrl(user.avatar, true) ||
-				this.getIdenticonUrl(user.id)
-			);
-		} else if (user.avatarId) {
-			const avatar = await DriveFiles.findOneByOrFail({ id: user.avatarId });
-			return (
-				DriveFiles.getPublicUrl(avatar, true) || this.getIdenticonUrl(user.id)
-			);
-		} else {
-			return this.getIdenticonUrl(user.id);
-		}
-	},
-
-	getAvatarUrlSync(user: User): string {
-		if (user.avatar) {
-			return (
-				DriveFiles.getPublicUrl(user.avatar, true) ||
-				this.getIdenticonUrl(user.id)
-			);
-		} else {
-			return this.getIdenticonUrl(user.id);
-		}
-	},
-
-	getIdenticonUrl(userId: User["id"]): string {
-		return `${config.url}/identicon/${userId}`;
-	},
-
-	async pack<
-		ExpectsMe extends boolean | null = null,
-		D extends boolean = false,
-	>(
-		src: User["id"] | User,
-		me?: { id: User["id"] } | null | undefined,
-		options?: {
-			detail?: D;
-			includeSecrets?: boolean;
-		},
-	): Promise<IsMeAndIsUserDetailed<ExpectsMe, D>> {
-		const opts = Object.assign(
-			{
-				detail: false,
-				includeSecrets: false,
-			},
-			options,
-		);
-
-		let user: User;
-
-		if (typeof src === "object") {
-			user = src;
-			if (src.avatar === undefined && src.avatarId)
-				src.avatar = (await DriveFiles.findOneBy({ id: src.avatarId })) ?? null;
-			if (src.banner === undefined && src.bannerId)
-				src.banner = (await DriveFiles.findOneBy({ id: src.bannerId })) ?? null;
-		} else {
-			user = await this.findOneOrFail({
-				where: { id: src },
-				relations: {
-					avatar: true,
-					banner: true,
-				},
-			});
-		}
-
-		const meId = me ? me.id : null;
-		const isMe = meId === user.id;
-
-		const relation =
-			meId && !isMe && opts.detail
-				? await this.getRelation(meId, user.id)
-				: null;
-		const pins = opts.detail
-			? await UserNotePinings.createQueryBuilder("pin")
-					.where("pin.userId = :userId", { userId: user.id })
-					.innerJoinAndSelect("pin.note", "note")
-					.orderBy("pin.id", "DESC")
-					.getMany()
-			: [];
-		const profile = opts.detail
-			? await UserProfiles.findOneByOrFail({ userId: user.id })
-			: null;
-
-		const followingCount =
-			profile == null
-				? null
-				: profile.ffVisibility === "public" || isMe
-				? user.followingCount
-				: profile.ffVisibility === "followers" &&
-				  relation &&
-				  relation.isFollowing
-				? user.followingCount
-				: null;
-
-		const followersCount =
-			profile == null
-				? null
-				: profile.ffVisibility === "public" || isMe
-				? user.followersCount
-				: profile.ffVisibility === "followers" &&
-				  relation &&
-				  relation.isFollowing
-				? user.followersCount
-				: null;
-
-		const falsy = opts.detail ? false : undefined;
-
-		const packed = {
-			id: user.id,
-			name: user.name,
-			username: user.username,
-			host: user.host,
-			avatarUrl: this.getAvatarUrlSync(user),
-			avatarBlurhash: user.avatar?.blurhash || null,
-			avatarColor: null, // 後方互換性のため
-			isAdmin: user.isAdmin || falsy,
-			isModerator: user.isModerator || falsy,
-			isBot: user.isBot || falsy,
-			isCat: user.isCat || falsy,
-			speakAsCat: user.speakAsCat || falsy,
-			instance: user.host
-				? userInstanceCache
-						.fetch(
-							user.host,
-							() => Instances.findOneBy({ host: user.host! }),
-							(v) => v != null,
-						)
-						.then((instance) =>
-							instance
-								? {
-										name: instance.name,
-										softwareName: instance.softwareName,
-										softwareVersion: instance.softwareVersion,
-										iconUrl: instance.iconUrl,
-										faviconUrl: instance.faviconUrl,
-										themeColor: instance.themeColor,
-								  }
-								: undefined,
-						)
-				: undefined,
-			emojis: populateEmojis(user.emojis, user.host),
-			onlineStatus: this.getOnlineStatus(user),
-			driveCapacityOverrideMb: user.driveCapacityOverrideMb,
-
-			...(opts.detail
-				? {
-						url: profile!.url,
-						uri: user.uri,
-						movedToUri: user.movedToUri
-							? await this.userFromURI(user.movedToUri)
-							: null,
-						alsoKnownAs: user.alsoKnownAs,
-						createdAt: user.createdAt.toISOString(),
-						updatedAt: user.updatedAt ? user.updatedAt.toISOString() : null,
-						lastFetchedAt: user.lastFetchedAt
-							? user.lastFetchedAt.toISOString()
-							: null,
-						bannerUrl: user.banner
-							? DriveFiles.getPublicUrl(user.banner, false)
-							: null,
-						bannerBlurhash: user.banner?.blurhash || null,
-						bannerColor: null, // 後方互換性のため
-						isLocked: user.isLocked,
-						isSilenced: user.isSilenced || falsy,
-						isSuspended: user.isSuspended || falsy,
-						description: profile!.description,
-						location: profile!.location,
-						birthday: profile!.birthday,
-						lang: profile!.lang,
-						fields: profile!.fields,
-						followersCount: followersCount || 0,
-						followingCount: followingCount || 0,
-						notesCount: user.notesCount,
-						pinnedNoteIds: pins.map((pin) => pin.noteId),
-						pinnedNotes: Notes.packMany(
-							pins.map((pin) => pin.note!),
-							me,
-							{
-								detail: true,
-							},
-						),
-						pinnedPageId: profile!.pinnedPageId,
-						pinnedPage: profile!.pinnedPageId
-							? Pages.pack(profile!.pinnedPageId, me)
-							: null,
-						publicReactions: profile!.publicReactions,
-						ffVisibility: profile!.ffVisibility,
-						twoFactorEnabled: profile!.twoFactorEnabled,
-						usePasswordLessLogin: profile!.usePasswordLessLogin,
-						securityKeys: profile!.twoFactorEnabled
-							? UserSecurityKeys.countBy({
-									userId: user.id,
-							  }).then((result) => result >= 1)
-							: false,
-				  }
-				: {}),
-
-			...(opts.detail && isMe
-				? {
-						avatarId: user.avatarId,
-						bannerId: user.bannerId,
-						injectFeaturedNote: profile!.injectFeaturedNote,
-						receiveAnnouncementEmail: profile!.receiveAnnouncementEmail,
-						alwaysMarkNsfw: profile!.alwaysMarkNsfw,
-						autoSensitive: profile!.autoSensitive,
-						carefulBot: profile!.carefulBot,
-						autoAcceptFollowed: profile!.autoAcceptFollowed,
-						noCrawle: profile!.noCrawle,
-						isExplorable: user.isExplorable,
-						isDeleted: user.isDeleted,
-						hideOnlineStatus: user.hideOnlineStatus,
-						hasUnreadSpecifiedNotes: NoteUnreads.count({
-							where: { userId: user.id, isSpecified: true },
-							take: 1,
-						}).then((count) => count > 0),
-						hasUnreadMentions: NoteUnreads.count({
-							where: { userId: user.id, isMentioned: true },
-							take: 1,
-						}).then((count) => count > 0),
-						hasUnreadAnnouncement: this.getHasUnreadAnnouncement(user.id),
-						hasUnreadAntenna: this.getHasUnreadAntenna(user.id),
-						hasUnreadChannel: this.getHasUnreadChannel(user.id),
-						hasUnreadMessagingMessage: this.getHasUnreadMessagingMessage(
-							user.id,
-						),
-						hasUnreadNotification: this.getHasUnreadNotification(user.id),
-						hasPendingReceivedFollowRequest:
-							this.getHasPendingReceivedFollowRequest(user.id),
-						integrations: profile!.integrations,
-						mutedWords: profile!.mutedWords,
-						mutedInstances: profile!.mutedInstances,
-						mutingNotificationTypes: profile!.mutingNotificationTypes,
-						emailNotificationTypes: profile!.emailNotificationTypes,
-						showTimelineReplies: user.showTimelineReplies || falsy,
-				  }
-				: {}),
-
-			...(opts.includeSecrets
-				? {
-						email: profile!.email,
-						emailVerified: profile!.emailVerified,
-						securityKeysList: profile!.twoFactorEnabled
-							? UserSecurityKeys.find({
-									where: {
-										userId: user.id,
-									},
-									select: {
-										id: true,
-										name: true,
-										lastUsed: true,
-									},
-							  })
-							: [],
-				  }
-				: {}),
-
-			...(relation
-				? {
-						isFollowing: relation.isFollowing,
-						isFollowed: relation.isFollowed,
-						hasPendingFollowRequestFromYou:
-							relation.hasPendingFollowRequestFromYou,
-						hasPendingFollowRequestToYou: relation.hasPendingFollowRequestToYou,
-						isBlocking: relation.isBlocking,
-						isBlocked: relation.isBlocked,
-						isMuted: relation.isMuted,
-						isRenoteMuted: relation.isRenoteMuted,
-				  }
-				: {}),
-		} as Promiseable<Packed<"User">> as Promiseable<
-			IsMeAndIsUserDetailed<ExpectsMe, D>
-		>;
-
-		return await awaitAll(packed);
-	},
-
-	packMany<D extends boolean = false>(
-		users: (User["id"] | User)[],
-		me?: { id: User["id"] } | null | undefined,
-		options?: {
-			detail?: D;
-			includeSecrets?: boolean;
-		},
-	): Promise<IsUserDetailed<D>[]> {
-		return Promise.all(users.map((u) => this.pack(u, me, options)));
-	},
-
-	isLocalUser,
-	isRemoteUser,
-});
diff --git a/packages/backend/src/models/schema/antenna.ts b/packages/backend/src/models/schema/antenna.ts
deleted file mode 100644
index 990e2daa2c..0000000000
--- a/packages/backend/src/models/schema/antenna.ts
+++ /dev/null
@@ -1,118 +0,0 @@
-export const packedAntennaSchema = {
-	type: "object",
-	properties: {
-		id: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "id",
-		},
-		createdAt: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "date-time",
-		},
-		name: {
-			type: "string",
-			optional: false,
-			nullable: false,
-		},
-		keywords: {
-			type: "array",
-			optional: false,
-			nullable: false,
-			items: {
-				type: "array",
-				optional: false,
-				nullable: false,
-				items: {
-					type: "string",
-					optional: false,
-					nullable: false,
-				},
-			},
-		},
-		excludeKeywords: {
-			type: "array",
-			optional: false,
-			nullable: false,
-			items: {
-				type: "array",
-				optional: false,
-				nullable: false,
-				items: {
-					type: "string",
-					optional: false,
-					nullable: false,
-				},
-			},
-		},
-		src: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			enum: ["home", "all", "users", "list", "group", "instances"],
-		},
-		userListId: {
-			type: "string",
-			optional: false,
-			nullable: true,
-			format: "id",
-		},
-		userGroupId: {
-			type: "string",
-			optional: false,
-			nullable: true,
-			format: "id",
-		},
-		users: {
-			type: "array",
-			optional: false,
-			nullable: false,
-			items: {
-				type: "string",
-				optional: false,
-				nullable: false,
-			},
-		},
-		instances: {
-			type: "array",
-			optional: false,
-			nullable: false,
-			items: {
-				type: "string",
-				optional: false,
-				nullable: false,
-			},
-		},
-		caseSensitive: {
-			type: "boolean",
-			optional: false,
-			nullable: false,
-			default: false,
-		},
-		notify: {
-			type: "boolean",
-			optional: false,
-			nullable: false,
-		},
-		withReplies: {
-			type: "boolean",
-			optional: false,
-			nullable: false,
-			default: false,
-		},
-		withFile: {
-			type: "boolean",
-			optional: false,
-			nullable: false,
-		},
-		hasUnreadNote: {
-			type: "boolean",
-			optional: false,
-			nullable: false,
-			default: false,
-		},
-	},
-} as const;
diff --git a/packages/backend/src/models/schema/app.ts b/packages/backend/src/models/schema/app.ts
deleted file mode 100644
index 8ec71159a3..0000000000
--- a/packages/backend/src/models/schema/app.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-export const packedAppSchema = {
-	type: "object",
-	properties: {
-		id: {
-			type: "string",
-			optional: false,
-			nullable: false,
-		},
-		name: {
-			type: "string",
-			optional: false,
-			nullable: false,
-		},
-		callbackUrl: {
-			type: "string",
-			optional: false,
-			nullable: true,
-		},
-		permission: {
-			type: "array",
-			optional: false,
-			nullable: false,
-			items: {
-				type: "string",
-				optional: false,
-				nullable: false,
-			},
-		},
-		secret: {
-			type: "string",
-			optional: true,
-			nullable: false,
-		},
-		isAuthorized: {
-			type: "boolean",
-			optional: true,
-			nullable: false,
-		},
-	},
-} as const;
diff --git a/packages/backend/src/models/schema/blocking.ts b/packages/backend/src/models/schema/blocking.ts
deleted file mode 100644
index 1d491e9395..0000000000
--- a/packages/backend/src/models/schema/blocking.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-export const packedBlockingSchema = {
-	type: "object",
-	properties: {
-		id: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "id",
-			example: "xxxxxxxxxx",
-		},
-		createdAt: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "date-time",
-		},
-		blockeeId: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "id",
-		},
-		blockee: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "UserDetailed",
-		},
-	},
-} as const;
diff --git a/packages/backend/src/models/schema/channel.ts b/packages/backend/src/models/schema/channel.ts
deleted file mode 100644
index 67833cb0dd..0000000000
--- a/packages/backend/src/models/schema/channel.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-export const packedChannelSchema = {
-	type: "object",
-	properties: {
-		id: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "id",
-			example: "xxxxxxxxxx",
-		},
-		createdAt: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "date-time",
-		},
-		lastNotedAt: {
-			type: "string",
-			optional: false,
-			nullable: true,
-			format: "date-time",
-		},
-		name: {
-			type: "string",
-			optional: false,
-			nullable: false,
-		},
-		description: {
-			type: "string",
-			nullable: true,
-			optional: false,
-		},
-		bannerUrl: {
-			type: "string",
-			format: "url",
-			nullable: true,
-			optional: false,
-		},
-		notesCount: {
-			type: "number",
-			nullable: false,
-			optional: false,
-		},
-		usersCount: {
-			type: "number",
-			nullable: false,
-			optional: false,
-		},
-		isFollowing: {
-			type: "boolean",
-			optional: true,
-			nullable: false,
-		},
-		userId: {
-			type: "string",
-			nullable: true,
-			optional: false,
-			format: "id",
-		},
-	},
-} as const;
diff --git a/packages/backend/src/models/schema/clip.ts b/packages/backend/src/models/schema/clip.ts
deleted file mode 100644
index 651303ad9f..0000000000
--- a/packages/backend/src/models/schema/clip.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-export const packedClipSchema = {
-	type: "object",
-	properties: {
-		id: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "id",
-			example: "xxxxxxxxxx",
-		},
-		createdAt: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "date-time",
-		},
-		userId: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "id",
-		},
-		user: {
-			type: "object",
-			ref: "UserLite",
-			optional: false,
-			nullable: false,
-		},
-		name: {
-			type: "string",
-			optional: false,
-			nullable: false,
-		},
-		description: {
-			type: "string",
-			optional: false,
-			nullable: true,
-		},
-		isPublic: {
-			type: "boolean",
-			optional: false,
-			nullable: false,
-		},
-	},
-} as const;
diff --git a/packages/backend/src/models/schema/drive-file.ts b/packages/backend/src/models/schema/drive-file.ts
deleted file mode 100644
index 30db9e7d48..0000000000
--- a/packages/backend/src/models/schema/drive-file.ts
+++ /dev/null
@@ -1,127 +0,0 @@
-export const packedDriveFileSchema = {
-	type: "object",
-	properties: {
-		id: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "id",
-			example: "xxxxxxxxxx",
-		},
-		createdAt: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "date-time",
-		},
-		name: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			example: "lenna.jpg",
-		},
-		type: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			example: "image/jpeg",
-		},
-		md5: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "md5",
-			example: "15eca7fba0480996e2245f5185bf39f2",
-		},
-		size: {
-			type: "number",
-			optional: false,
-			nullable: false,
-			example: 51469,
-		},
-		isSensitive: {
-			type: "boolean",
-			optional: false,
-			nullable: false,
-		},
-		blurhash: {
-			type: "string",
-			optional: false,
-			nullable: true,
-		},
-		properties: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			properties: {
-				width: {
-					type: "number",
-					optional: true,
-					nullable: false,
-					example: 1280,
-				},
-				height: {
-					type: "number",
-					optional: true,
-					nullable: false,
-					example: 720,
-				},
-				orientation: {
-					type: "number",
-					optional: true,
-					nullable: false,
-					example: 8,
-				},
-				avgColor: {
-					type: "string",
-					optional: true,
-					nullable: false,
-					example: "rgb(40,65,87)",
-				},
-			},
-		},
-		url: {
-			type: "string",
-			optional: false,
-			nullable: true,
-			format: "url",
-		},
-		thumbnailUrl: {
-			type: "string",
-			optional: false,
-			nullable: true,
-			format: "url",
-		},
-		comment: {
-			type: "string",
-			optional: false,
-			nullable: true,
-		},
-		folderId: {
-			type: "string",
-			optional: false,
-			nullable: true,
-			format: "id",
-			example: "xxxxxxxxxx",
-		},
-		folder: {
-			type: "object",
-			optional: true,
-			nullable: true,
-			ref: "DriveFolder",
-		},
-		userId: {
-			type: "string",
-			optional: false,
-			nullable: true,
-			format: "id",
-			example: "xxxxxxxxxx",
-		},
-		user: {
-			type: "object",
-			optional: true,
-			nullable: true,
-			ref: "UserLite",
-		},
-	},
-} as const;
diff --git a/packages/backend/src/models/schema/drive-folder.ts b/packages/backend/src/models/schema/drive-folder.ts
deleted file mode 100644
index 2298b5420c..0000000000
--- a/packages/backend/src/models/schema/drive-folder.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-export const packedDriveFolderSchema = {
-	type: "object",
-	properties: {
-		id: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "id",
-			example: "xxxxxxxxxx",
-		},
-		createdAt: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "date-time",
-		},
-		name: {
-			type: "string",
-			optional: false,
-			nullable: false,
-		},
-		foldersCount: {
-			type: "number",
-			optional: true,
-			nullable: false,
-		},
-		filesCount: {
-			type: "number",
-			optional: true,
-			nullable: false,
-		},
-		parentId: {
-			type: "string",
-			optional: false,
-			nullable: true,
-			format: "id",
-			example: "xxxxxxxxxx",
-		},
-		parent: {
-			type: "object",
-			optional: true,
-			nullable: true,
-			ref: "DriveFolder",
-		},
-	},
-} as const;
diff --git a/packages/backend/src/models/schema/emoji.ts b/packages/backend/src/models/schema/emoji.ts
deleted file mode 100644
index 8994381b31..0000000000
--- a/packages/backend/src/models/schema/emoji.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-export const packedEmojiSchema = {
-	type: "object",
-	properties: {
-		id: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "id",
-			example: "xxxxxxxxxx",
-		},
-		aliases: {
-			type: "array",
-			optional: false,
-			nullable: false,
-			items: {
-				type: "string",
-				optional: false,
-				nullable: false,
-				format: "id",
-			},
-		},
-		name: {
-			type: "string",
-			optional: false,
-			nullable: false,
-		},
-		category: {
-			type: "string",
-			optional: false,
-			nullable: true,
-		},
-		host: {
-			type: "string",
-			optional: false,
-			nullable: true,
-			description: "The local host is represented with `null`.",
-		},
-		url: {
-			type: "string",
-			optional: false,
-			nullable: false,
-		},
-		license: {
-			type: "string",
-			optional: false,
-			nullable: true,
-		},
-	},
-} as const;
diff --git a/packages/backend/src/models/schema/federation-instance.ts b/packages/backend/src/models/schema/federation-instance.ts
deleted file mode 100644
index ed3369bf11..0000000000
--- a/packages/backend/src/models/schema/federation-instance.ts
+++ /dev/null
@@ -1,133 +0,0 @@
-import config from "@/config/index.js";
-
-export const packedFederationInstanceSchema = {
-	type: "object",
-	properties: {
-		id: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "id",
-		},
-		caughtAt: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "date-time",
-		},
-		host: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			example: "calckey.example.com",
-		},
-		usersCount: {
-			type: "number",
-			optional: false,
-			nullable: false,
-		},
-		notesCount: {
-			type: "number",
-			optional: false,
-			nullable: false,
-		},
-		followingCount: {
-			type: "number",
-			optional: false,
-			nullable: false,
-		},
-		followersCount: {
-			type: "number",
-			optional: false,
-			nullable: false,
-		},
-		latestRequestSentAt: {
-			type: "string",
-			optional: false,
-			nullable: true,
-			format: "date-time",
-		},
-		lastCommunicatedAt: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "date-time",
-		},
-		isNotResponding: {
-			type: "boolean",
-			optional: false,
-			nullable: false,
-		},
-		isSuspended: {
-			type: "boolean",
-			optional: false,
-			nullable: false,
-		},
-		isBlocked: {
-			type: "boolean",
-			optional: false,
-			nullable: false,
-		},
-		softwareName: {
-			type: "string",
-			optional: false,
-			nullable: true,
-			example: "calckey",
-		},
-		softwareVersion: {
-			type: "string",
-			optional: false,
-			nullable: true,
-			example: config.version,
-		},
-		openRegistrations: {
-			type: "boolean",
-			optional: false,
-			nullable: true,
-			example: true,
-		},
-		name: {
-			type: "string",
-			optional: false,
-			nullable: true,
-		},
-		description: {
-			type: "string",
-			optional: false,
-			nullable: true,
-		},
-		maintainerName: {
-			type: "string",
-			optional: false,
-			nullable: true,
-		},
-		maintainerEmail: {
-			type: "string",
-			optional: false,
-			nullable: true,
-		},
-		iconUrl: {
-			type: "string",
-			optional: false,
-			nullable: true,
-			format: "url",
-		},
-		faviconUrl: {
-			type: "string",
-			optional: false,
-			nullable: true,
-			format: "url",
-		},
-		themeColor: {
-			type: "string",
-			optional: false,
-			nullable: true,
-		},
-		infoUpdatedAt: {
-			type: "string",
-			optional: false,
-			nullable: true,
-			format: "date-time",
-		},
-	},
-} as const;
diff --git a/packages/backend/src/models/schema/following.ts b/packages/backend/src/models/schema/following.ts
deleted file mode 100644
index f53cafaba5..0000000000
--- a/packages/backend/src/models/schema/following.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-export const packedFollowingSchema = {
-	type: "object",
-	properties: {
-		id: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "id",
-			example: "xxxxxxxxxx",
-		},
-		createdAt: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "date-time",
-		},
-		followeeId: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "id",
-		},
-		followee: {
-			type: "object",
-			optional: true,
-			nullable: false,
-			ref: "UserDetailed",
-		},
-		followerId: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "id",
-		},
-		follower: {
-			type: "object",
-			optional: true,
-			nullable: false,
-			ref: "UserDetailed",
-		},
-	},
-} as const;
diff --git a/packages/backend/src/models/schema/gallery-post.ts b/packages/backend/src/models/schema/gallery-post.ts
deleted file mode 100644
index 9ac348e1fb..0000000000
--- a/packages/backend/src/models/schema/gallery-post.ts
+++ /dev/null
@@ -1,83 +0,0 @@
-export const packedGalleryPostSchema = {
-	type: "object",
-	properties: {
-		id: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "id",
-			example: "xxxxxxxxxx",
-		},
-		createdAt: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "date-time",
-		},
-		updatedAt: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "date-time",
-		},
-		title: {
-			type: "string",
-			optional: false,
-			nullable: false,
-		},
-		description: {
-			type: "string",
-			optional: false,
-			nullable: true,
-		},
-		userId: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "id",
-		},
-		user: {
-			type: "object",
-			ref: "UserLite",
-			optional: false,
-			nullable: false,
-		},
-		fileIds: {
-			type: "array",
-			optional: true,
-			nullable: false,
-			items: {
-				type: "string",
-				optional: false,
-				nullable: false,
-				format: "id",
-			},
-		},
-		files: {
-			type: "array",
-			optional: true,
-			nullable: false,
-			items: {
-				type: "object",
-				optional: false,
-				nullable: false,
-				ref: "DriveFile",
-			},
-		},
-		tags: {
-			type: "array",
-			optional: true,
-			nullable: false,
-			items: {
-				type: "string",
-				optional: false,
-				nullable: false,
-			},
-		},
-		isSensitive: {
-			type: "boolean",
-			optional: false,
-			nullable: false,
-		},
-	},
-} as const;
diff --git a/packages/backend/src/models/schema/hashtag.ts b/packages/backend/src/models/schema/hashtag.ts
deleted file mode 100644
index dacc515070..0000000000
--- a/packages/backend/src/models/schema/hashtag.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-export const packedHashtagSchema = {
-	type: "object",
-	properties: {
-		tag: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			example: "calckey",
-		},
-		mentionedUsersCount: {
-			type: "number",
-			optional: false,
-			nullable: false,
-		},
-		mentionedLocalUsersCount: {
-			type: "number",
-			optional: false,
-			nullable: false,
-		},
-		mentionedRemoteUsersCount: {
-			type: "number",
-			optional: false,
-			nullable: false,
-		},
-		attachedUsersCount: {
-			type: "number",
-			optional: false,
-			nullable: false,
-		},
-		attachedLocalUsersCount: {
-			type: "number",
-			optional: false,
-			nullable: false,
-		},
-		attachedRemoteUsersCount: {
-			type: "number",
-			optional: false,
-			nullable: false,
-		},
-	},
-} as const;
diff --git a/packages/backend/src/models/schema/messaging-message.ts b/packages/backend/src/models/schema/messaging-message.ts
deleted file mode 100644
index d598e6dbc6..0000000000
--- a/packages/backend/src/models/schema/messaging-message.ts
+++ /dev/null
@@ -1,87 +0,0 @@
-export const packedMessagingMessageSchema = {
-	type: "object",
-	properties: {
-		id: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "id",
-			example: "xxxxxxxxxx",
-		},
-		createdAt: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "date-time",
-		},
-		userId: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "id",
-		},
-		user: {
-			type: "object",
-			ref: "UserLite",
-			optional: true,
-			nullable: false,
-		},
-		text: {
-			type: "string",
-			optional: false,
-			nullable: true,
-		},
-		fileId: {
-			type: "string",
-			optional: true,
-			nullable: true,
-			format: "id",
-		},
-		file: {
-			type: "object",
-			optional: true,
-			nullable: true,
-			ref: "DriveFile",
-		},
-		recipientId: {
-			type: "string",
-			optional: false,
-			nullable: true,
-			format: "id",
-		},
-		recipient: {
-			type: "object",
-			optional: true,
-			nullable: true,
-			ref: "UserLite",
-		},
-		groupId: {
-			type: "string",
-			optional: false,
-			nullable: true,
-			format: "id",
-		},
-		group: {
-			type: "object",
-			optional: true,
-			nullable: true,
-			ref: "UserGroup",
-		},
-		isRead: {
-			type: "boolean",
-			optional: true,
-			nullable: false,
-		},
-		reads: {
-			type: "array",
-			optional: true,
-			nullable: false,
-			items: {
-				type: "string",
-				optional: false,
-				nullable: false,
-				format: "id",
-			},
-		},
-	},
-} as const;
diff --git a/packages/backend/src/models/schema/muting.ts b/packages/backend/src/models/schema/muting.ts
deleted file mode 100644
index d5815f86d1..0000000000
--- a/packages/backend/src/models/schema/muting.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-export const packedMutingSchema = {
-	type: "object",
-	properties: {
-		id: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "id",
-			example: "xxxxxxxxxx",
-		},
-		createdAt: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "date-time",
-		},
-		expiresAt: {
-			type: "string",
-			optional: false,
-			nullable: true,
-			format: "date-time",
-		},
-		muteeId: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "id",
-		},
-		mutee: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "UserDetailed",
-		},
-	},
-} as const;
diff --git a/packages/backend/src/models/schema/note-favorite.ts b/packages/backend/src/models/schema/note-favorite.ts
deleted file mode 100644
index 17a42baf0e..0000000000
--- a/packages/backend/src/models/schema/note-favorite.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-export const packedNoteFavoriteSchema = {
-	type: "object",
-	properties: {
-		id: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "id",
-			example: "xxxxxxxxxx",
-		},
-		createdAt: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "date-time",
-		},
-		note: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Note",
-		},
-		noteId: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "id",
-		},
-	},
-} as const;
diff --git a/packages/backend/src/models/schema/note-reaction.ts b/packages/backend/src/models/schema/note-reaction.ts
deleted file mode 100644
index 1080bdcf51..0000000000
--- a/packages/backend/src/models/schema/note-reaction.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-export const packedNoteReactionSchema = {
-	type: "object",
-	properties: {
-		id: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "id",
-			example: "xxxxxxxxxx",
-		},
-		createdAt: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "date-time",
-		},
-		user: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "UserLite",
-		},
-		type: {
-			type: "string",
-			optional: false,
-			nullable: false,
-		},
-	},
-} as const;
diff --git a/packages/backend/src/models/schema/note.ts b/packages/backend/src/models/schema/note.ts
deleted file mode 100644
index e17f054e8e..0000000000
--- a/packages/backend/src/models/schema/note.ts
+++ /dev/null
@@ -1,200 +0,0 @@
-export const packedNoteSchema = {
-	type: "object",
-	properties: {
-		id: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "id",
-			example: "xxxxxxxxxx",
-		},
-		createdAt: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "date-time",
-		},
-		text: {
-			type: "string",
-			optional: false,
-			nullable: true,
-		},
-		cw: {
-			type: "string",
-			optional: true,
-			nullable: true,
-		},
-		userId: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "id",
-		},
-		user: {
-			type: "object",
-			ref: "UserLite",
-			optional: false,
-			nullable: false,
-		},
-		replyId: {
-			type: "string",
-			optional: true,
-			nullable: true,
-			format: "id",
-			example: "xxxxxxxxxx",
-		},
-		renoteId: {
-			type: "string",
-			optional: true,
-			nullable: true,
-			format: "id",
-			example: "xxxxxxxxxx",
-		},
-		reply: {
-			type: "object",
-			optional: true,
-			nullable: true,
-			ref: "Note",
-		},
-		renote: {
-			type: "object",
-			optional: true,
-			nullable: true,
-			ref: "Note",
-		},
-		visibility: {
-			type: "string",
-			optional: false,
-			nullable: false,
-		},
-		mentions: {
-			type: "array",
-			optional: true,
-			nullable: false,
-			items: {
-				type: "string",
-				optional: false,
-				nullable: false,
-				format: "id",
-			},
-		},
-		visibleUserIds: {
-			type: "array",
-			optional: true,
-			nullable: false,
-			items: {
-				type: "string",
-				optional: false,
-				nullable: false,
-				format: "id",
-			},
-		},
-		fileIds: {
-			type: "array",
-			optional: true,
-			nullable: false,
-			items: {
-				type: "string",
-				optional: false,
-				nullable: false,
-				format: "id",
-			},
-		},
-		files: {
-			type: "array",
-			optional: true,
-			nullable: false,
-			items: {
-				type: "object",
-				optional: false,
-				nullable: false,
-				ref: "DriveFile",
-			},
-		},
-		tags: {
-			type: "array",
-			optional: true,
-			nullable: false,
-			items: {
-				type: "string",
-				optional: false,
-				nullable: false,
-			},
-		},
-		poll: {
-			type: "object",
-			optional: true,
-			nullable: true,
-		},
-		channelId: {
-			type: "string",
-			optional: true,
-			nullable: true,
-			format: "id",
-			example: "xxxxxxxxxx",
-		},
-		channel: {
-			type: "object",
-			optional: true,
-			nullable: true,
-			items: {
-				type: "object",
-				optional: false,
-				nullable: false,
-				properties: {
-					id: {
-						type: "string",
-						optional: false,
-						nullable: false,
-					},
-					name: {
-						type: "string",
-						optional: false,
-						nullable: true,
-					},
-				},
-			},
-		},
-		localOnly: {
-			type: "boolean",
-			optional: true,
-			nullable: false,
-		},
-		emojis: {
-			type: "object",
-			optional: true,
-			nullable: true,
-		},
-		reactions: {
-			type: "object",
-			optional: false,
-			nullable: false,
-		},
-		renoteCount: {
-			type: "number",
-			optional: false,
-			nullable: false,
-		},
-		repliesCount: {
-			type: "number",
-			optional: false,
-			nullable: false,
-		},
-		uri: {
-			type: "string",
-			optional: true,
-			nullable: false,
-		},
-		url: {
-			type: "string",
-			optional: true,
-			nullable: false,
-		},
-
-		myReaction: {
-			type: "object",
-			optional: true,
-			nullable: true,
-		},
-	},
-} as const;
diff --git a/packages/backend/src/models/schema/notification.ts b/packages/backend/src/models/schema/notification.ts
deleted file mode 100644
index 97fd16339c..0000000000
--- a/packages/backend/src/models/schema/notification.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-import { notificationTypes } from "@/types.js";
-
-export const packedNotificationSchema = {
-	type: "object",
-	properties: {
-		id: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "id",
-			example: "xxxxxxxxxx",
-		},
-		createdAt: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "date-time",
-		},
-		isRead: {
-			type: "boolean",
-			optional: false,
-			nullable: false,
-		},
-		type: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			enum: [...notificationTypes],
-		},
-		user: {
-			type: "object",
-			ref: "UserLite",
-			optional: true,
-			nullable: true,
-		},
-		userId: {
-			type: "string",
-			optional: true,
-			nullable: true,
-			format: "id",
-		},
-		note: {
-			type: "object",
-			ref: "Note",
-			optional: true,
-			nullable: true,
-		},
-		reaction: {
-			type: "string",
-			optional: true,
-			nullable: true,
-		},
-		choice: {
-			type: "number",
-			optional: true,
-			nullable: true,
-		},
-		invitation: {
-			type: "object",
-			optional: true,
-			nullable: true,
-		},
-		body: {
-			type: "string",
-			optional: true,
-			nullable: true,
-		},
-		header: {
-			type: "string",
-			optional: true,
-			nullable: true,
-		},
-		icon: {
-			type: "string",
-			optional: true,
-			nullable: true,
-		},
-	},
-} as const;
diff --git a/packages/backend/src/models/schema/page.ts b/packages/backend/src/models/schema/page.ts
deleted file mode 100644
index a1b9144b59..0000000000
--- a/packages/backend/src/models/schema/page.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-export const packedPageSchema = {
-	type: "object",
-	properties: {
-		id: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "id",
-			example: "xxxxxxxxxx",
-		},
-		createdAt: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "date-time",
-		},
-		updatedAt: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "date-time",
-		},
-		title: {
-			type: "string",
-			optional: false,
-			nullable: false,
-		},
-		name: {
-			type: "string",
-			optional: false,
-			nullable: false,
-		},
-		summary: {
-			type: "string",
-			optional: false,
-			nullable: true,
-		},
-		content: {
-			type: "array",
-			optional: false,
-			nullable: false,
-		},
-		variables: {
-			type: "array",
-			optional: false,
-			nullable: false,
-		},
-		userId: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "id",
-		},
-		user: {
-			type: "object",
-			ref: "UserLite",
-			optional: false,
-			nullable: false,
-		},
-		isPublic: {
-			type: "boolean",
-			optional: false,
-			nullable: false,
-		},
-	},
-} as const;
diff --git a/packages/backend/src/models/schema/queue.ts b/packages/backend/src/models/schema/queue.ts
deleted file mode 100644
index 954ac688be..0000000000
--- a/packages/backend/src/models/schema/queue.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-export const packedQueueCountSchema = {
-	type: "object",
-	properties: {
-		waiting: {
-			type: "number",
-			optional: false,
-			nullable: false,
-		},
-		active: {
-			type: "number",
-			optional: false,
-			nullable: false,
-		},
-		completed: {
-			type: "number",
-			optional: false,
-			nullable: false,
-		},
-		failed: {
-			type: "number",
-			optional: false,
-			nullable: false,
-		},
-		delayed: {
-			type: "number",
-			optional: false,
-			nullable: false,
-		},
-	},
-} as const;
diff --git a/packages/backend/src/models/schema/renote-muting.ts b/packages/backend/src/models/schema/renote-muting.ts
deleted file mode 100644
index 2a5824e32b..0000000000
--- a/packages/backend/src/models/schema/renote-muting.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-export const packedRenoteMutingSchema = {
-	type: "object",
-	properties: {
-		id: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "id",
-			example: "xxxxxxxxxx",
-		},
-		createdAt: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "date-time",
-		},
-		muteeId: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "id",
-		},
-		mutee: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "UserDetailed",
-		},
-	},
-} as const;
diff --git a/packages/backend/src/models/schema/user-group.ts b/packages/backend/src/models/schema/user-group.ts
deleted file mode 100644
index a4a85f9699..0000000000
--- a/packages/backend/src/models/schema/user-group.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-export const packedUserGroupSchema = {
-	type: "object",
-	properties: {
-		id: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "id",
-			example: "xxxxxxxxxx",
-		},
-		createdAt: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "date-time",
-		},
-		name: {
-			type: "string",
-			optional: false,
-			nullable: false,
-		},
-		ownerId: {
-			type: "string",
-			nullable: false,
-			optional: false,
-			format: "id",
-		},
-		userIds: {
-			type: "array",
-			nullable: false,
-			optional: true,
-			items: {
-				type: "string",
-				nullable: false,
-				optional: false,
-				format: "id",
-			},
-		},
-	},
-} as const;
diff --git a/packages/backend/src/models/schema/user-list.ts b/packages/backend/src/models/schema/user-list.ts
deleted file mode 100644
index 1e203b63ae..0000000000
--- a/packages/backend/src/models/schema/user-list.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-export const packedUserListSchema = {
-	type: "object",
-	properties: {
-		id: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "id",
-			example: "xxxxxxxxxx",
-		},
-		createdAt: {
-			type: "string",
-			optional: false,
-			nullable: false,
-			format: "date-time",
-		},
-		name: {
-			type: "string",
-			optional: false,
-			nullable: false,
-		},
-		userIds: {
-			type: "array",
-			nullable: false,
-			optional: true,
-			items: {
-				type: "string",
-				nullable: false,
-				optional: false,
-				format: "id",
-			},
-		},
-	},
-} as const;
diff --git a/packages/backend/src/models/schema/user.ts b/packages/backend/src/models/schema/user.ts
deleted file mode 100644
index 80e94fe508..0000000000
--- a/packages/backend/src/models/schema/user.ts
+++ /dev/null
@@ -1,583 +0,0 @@
-export const packedUserLiteSchema = {
-	type: "object",
-	properties: {
-		id: {
-			type: "string",
-			nullable: false,
-			optional: false,
-			format: "id",
-			example: "xxxxxxxxxx",
-		},
-		name: {
-			type: "string",
-			nullable: true,
-			optional: false,
-			example: "藍",
-		},
-		username: {
-			type: "string",
-			nullable: false,
-			optional: false,
-			example: "calc",
-		},
-		host: {
-			type: "string",
-			nullable: true,
-			optional: false,
-			example: "misskey.example.com",
-			description: "The local host is represented with `null`.",
-		},
-		avatarUrl: {
-			type: "string",
-			format: "url",
-			nullable: true,
-			optional: false,
-		},
-		avatarBlurhash: {
-			type: "any",
-			nullable: true,
-			optional: false,
-		},
-		avatarColor: {
-			type: "any",
-			nullable: true,
-			optional: false,
-			default: null,
-		},
-		isAdmin: {
-			type: "boolean",
-			nullable: false,
-			optional: true,
-			default: false,
-		},
-		isModerator: {
-			type: "boolean",
-			nullable: false,
-			optional: true,
-			default: false,
-		},
-		isBot: {
-			type: "boolean",
-			nullable: false,
-			optional: true,
-		},
-		isCat: {
-			type: "boolean",
-			nullable: false,
-			optional: true,
-		},
-		speakAsCat: {
-			type: "boolean",
-			nullable: false,
-			optional: true,
-		},
-		emojis: {
-			type: "array",
-			nullable: false,
-			optional: false,
-			items: {
-				type: "object",
-				nullable: false,
-				optional: false,
-				properties: {
-					name: {
-						type: "string",
-						nullable: false,
-						optional: false,
-					},
-					url: {
-						type: "string",
-						nullable: false,
-						optional: false,
-						format: "url",
-					},
-				},
-			},
-		},
-		onlineStatus: {
-			type: "string",
-			format: "url",
-			nullable: true,
-			optional: false,
-			enum: ["unknown", "online", "active", "offline"],
-		},
-	},
-} as const;
-
-export const packedUserDetailedNotMeOnlySchema = {
-	type: "object",
-	properties: {
-		url: {
-			type: "string",
-			format: "url",
-			nullable: true,
-			optional: false,
-		},
-		uri: {
-			type: "string",
-			format: "uri",
-			nullable: true,
-			optional: false,
-		},
-		movedToUri: {
-			type: "string",
-			format: "uri",
-			nullable: true,
-			optional: false,
-		},
-		alsoKnownAs: {
-			type: "array",
-			format: "uri",
-			nullable: true,
-			optional: false,
-		},
-		createdAt: {
-			type: "string",
-			nullable: false,
-			optional: false,
-			format: "date-time",
-		},
-		updatedAt: {
-			type: "string",
-			nullable: true,
-			optional: false,
-			format: "date-time",
-		},
-		lastFetchedAt: {
-			type: "string",
-			nullable: true,
-			optional: false,
-			format: "date-time",
-		},
-		bannerUrl: {
-			type: "string",
-			format: "url",
-			nullable: true,
-			optional: false,
-		},
-		bannerBlurhash: {
-			type: "any",
-			nullable: true,
-			optional: false,
-		},
-		bannerColor: {
-			type: "any",
-			nullable: true,
-			optional: false,
-			default: null,
-		},
-		isLocked: {
-			type: "boolean",
-			nullable: false,
-			optional: false,
-		},
-		isSilenced: {
-			type: "boolean",
-			nullable: false,
-			optional: false,
-		},
-		isSuspended: {
-			type: "boolean",
-			nullable: false,
-			optional: false,
-			example: false,
-		},
-		description: {
-			type: "string",
-			nullable: true,
-			optional: false,
-			example: "Hi masters, I am Ai!",
-		},
-		location: {
-			type: "string",
-			nullable: true,
-			optional: false,
-		},
-		birthday: {
-			type: "string",
-			nullable: true,
-			optional: false,
-			example: "2018-03-12",
-		},
-		lang: {
-			type: "string",
-			nullable: true,
-			optional: false,
-			example: "ja-JP",
-		},
-		fields: {
-			type: "array",
-			nullable: false,
-			optional: false,
-			items: {
-				type: "object",
-				nullable: false,
-				optional: false,
-				properties: {
-					name: {
-						type: "string",
-						nullable: false,
-						optional: false,
-					},
-					value: {
-						type: "string",
-						nullable: false,
-						optional: false,
-					},
-				},
-				maxLength: 4,
-			},
-		},
-		followersCount: {
-			type: "number",
-			nullable: false,
-			optional: false,
-		},
-		followingCount: {
-			type: "number",
-			nullable: false,
-			optional: false,
-		},
-		notesCount: {
-			type: "number",
-			nullable: false,
-			optional: false,
-		},
-		pinnedNoteIds: {
-			type: "array",
-			nullable: false,
-			optional: false,
-			items: {
-				type: "string",
-				nullable: false,
-				optional: false,
-				format: "id",
-			},
-		},
-		pinnedNotes: {
-			type: "array",
-			nullable: false,
-			optional: false,
-			items: {
-				type: "object",
-				nullable: false,
-				optional: false,
-				ref: "Note",
-			},
-		},
-		pinnedPageId: {
-			type: "string",
-			nullable: true,
-			optional: false,
-		},
-		pinnedPage: {
-			type: "object",
-			nullable: true,
-			optional: false,
-			ref: "Page",
-		},
-		publicReactions: {
-			type: "boolean",
-			nullable: false,
-			optional: false,
-		},
-		twoFactorEnabled: {
-			type: "boolean",
-			nullable: false,
-			optional: false,
-			default: false,
-		},
-		usePasswordLessLogin: {
-			type: "boolean",
-			nullable: false,
-			optional: false,
-			default: false,
-		},
-		securityKeys: {
-			type: "boolean",
-			nullable: false,
-			optional: false,
-			default: false,
-		},
-		//#region relations
-		isFollowing: {
-			type: "boolean",
-			nullable: false,
-			optional: true,
-		},
-		isFollowed: {
-			type: "boolean",
-			nullable: false,
-			optional: true,
-		},
-		hasPendingFollowRequestFromYou: {
-			type: "boolean",
-			nullable: false,
-			optional: true,
-		},
-		hasPendingFollowRequestToYou: {
-			type: "boolean",
-			nullable: false,
-			optional: true,
-		},
-		isBlocking: {
-			type: "boolean",
-			nullable: false,
-			optional: true,
-		},
-		isBlocked: {
-			type: "boolean",
-			nullable: false,
-			optional: true,
-		},
-		isMuted: {
-			type: "boolean",
-			nullable: false,
-			optional: true,
-		},
-		isRenoteMuted: {
-			type: "boolean",
-			nullable: false,
-			optional: true,
-		},
-		//#endregion
-	},
-} as const;
-
-export const packedMeDetailedOnlySchema = {
-	type: "object",
-	properties: {
-		avatarId: {
-			type: "string",
-			nullable: true,
-			optional: false,
-			format: "id",
-		},
-		bannerId: {
-			type: "string",
-			nullable: true,
-			optional: false,
-			format: "id",
-		},
-		injectFeaturedNote: {
-			type: "boolean",
-			nullable: true,
-			optional: false,
-		},
-		receiveAnnouncementEmail: {
-			type: "boolean",
-			nullable: true,
-			optional: false,
-		},
-		alwaysMarkNsfw: {
-			type: "boolean",
-			nullable: true,
-			optional: false,
-		},
-		autoSensitive: {
-			type: "boolean",
-			nullable: true,
-			optional: false,
-		},
-		carefulBot: {
-			type: "boolean",
-			nullable: true,
-			optional: false,
-		},
-		autoAcceptFollowed: {
-			type: "boolean",
-			nullable: true,
-			optional: false,
-		},
-		noCrawle: {
-			type: "boolean",
-			nullable: true,
-			optional: false,
-		},
-		isExplorable: {
-			type: "boolean",
-			nullable: false,
-			optional: false,
-		},
-		isDeleted: {
-			type: "boolean",
-			nullable: false,
-			optional: false,
-		},
-		hideOnlineStatus: {
-			type: "boolean",
-			nullable: false,
-			optional: false,
-		},
-		hasUnreadSpecifiedNotes: {
-			type: "boolean",
-			nullable: false,
-			optional: false,
-		},
-		hasUnreadMentions: {
-			type: "boolean",
-			nullable: false,
-			optional: false,
-		},
-		hasUnreadAnnouncement: {
-			type: "boolean",
-			nullable: false,
-			optional: false,
-		},
-		hasUnreadAntenna: {
-			type: "boolean",
-			nullable: false,
-			optional: false,
-		},
-		hasUnreadChannel: {
-			type: "boolean",
-			nullable: false,
-			optional: false,
-		},
-		hasUnreadMessagingMessage: {
-			type: "boolean",
-			nullable: false,
-			optional: false,
-		},
-		hasUnreadNotification: {
-			type: "boolean",
-			nullable: false,
-			optional: false,
-		},
-		hasPendingReceivedFollowRequest: {
-			type: "boolean",
-			nullable: false,
-			optional: false,
-		},
-		integrations: {
-			type: "object",
-			nullable: true,
-			optional: false,
-		},
-		mutedWords: {
-			type: "array",
-			nullable: false,
-			optional: false,
-			items: {
-				type: "array",
-				nullable: false,
-				optional: false,
-				items: {
-					type: "string",
-					nullable: false,
-					optional: false,
-				},
-			},
-		},
-		mutedInstances: {
-			type: "array",
-			nullable: true,
-			optional: false,
-			items: {
-				type: "string",
-				nullable: false,
-				optional: false,
-			},
-		},
-		mutingNotificationTypes: {
-			type: "array",
-			nullable: true,
-			optional: false,
-			items: {
-				type: "string",
-				nullable: false,
-				optional: false,
-			},
-		},
-		emailNotificationTypes: {
-			type: "array",
-			nullable: true,
-			optional: false,
-			items: {
-				type: "string",
-				nullable: false,
-				optional: false,
-			},
-		},
-		//#region secrets
-		email: {
-			type: "string",
-			nullable: true,
-			optional: true,
-		},
-		emailVerified: {
-			type: "boolean",
-			nullable: true,
-			optional: true,
-		},
-		securityKeysList: {
-			type: "array",
-			nullable: false,
-			optional: true,
-			items: {
-				type: "object",
-				nullable: false,
-				optional: false,
-			},
-		},
-		//#endregion
-	},
-} as const;
-
-export const packedUserDetailedNotMeSchema = {
-	type: "object",
-	allOf: [
-		{
-			type: "object",
-			ref: "UserLite",
-		},
-		{
-			type: "object",
-			ref: "UserDetailedNotMeOnly",
-		},
-	],
-} as const;
-
-export const packedMeDetailedSchema = {
-	type: "object",
-	allOf: [
-		{
-			type: "object",
-			ref: "UserLite",
-		},
-		{
-			type: "object",
-			ref: "UserDetailedNotMeOnly",
-		},
-		{
-			type: "object",
-			ref: "MeDetailedOnly",
-		},
-	],
-} as const;
-
-export const packedUserDetailedSchema = {
-	oneOf: [
-		{
-			type: "object",
-			ref: "UserDetailedNotMe",
-		},
-		{
-			type: "object",
-			ref: "MeDetailed",
-		},
-	],
-} as const;
-
-export const packedUserSchema = {
-	oneOf: [
-		{
-			type: "object",
-			ref: "UserLite",
-		},
-		{
-			type: "object",
-			ref: "UserDetailed",
-		},
-	],
-} as const;
diff --git a/packages/backend/src/prelude/README.md b/packages/backend/src/prelude/README.md
deleted file mode 100644
index bb728cfb1b..0000000000
--- a/packages/backend/src/prelude/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Prelude
-このディレクトリのコードはJavaScriptの表現能力を補うためのコードです。
-Misskey固有の処理とは独立したコードの集まりですが、Misskeyのコードを読みやすくすることを目的としています。
diff --git a/packages/backend/src/prelude/array.ts b/packages/backend/src/prelude/array.ts
deleted file mode 100644
index 71a24c89b7..0000000000
--- a/packages/backend/src/prelude/array.ts
+++ /dev/null
@@ -1,138 +0,0 @@
-import type { EndoRelation, Predicate } from "./relation.js";
-
-/**
- * Count the number of elements that satisfy the predicate
- */
-
-export function countIf<T>(f: Predicate<T>, xs: T[]): number {
-	return xs.filter(f).length;
-}
-
-/**
- * Count the number of elements that is equal to the element
- */
-export function count<T>(a: T, xs: T[]): number {
-	return countIf((x) => x === a, xs);
-}
-
-/**
- * Concatenate an array of arrays
- */
-export function concat<T>(xss: T[][]): T[] {
-	return ([] as T[]).concat(...xss);
-}
-
-/**
- * Intersperse the element between the elements of the array
- * @param sep The element to be interspersed
- */
-export function intersperse<T>(sep: T, xs: T[]): T[] {
-	return concat(xs.map((x) => [sep, x])).slice(1);
-}
-
-/**
- * Returns the array of elements that is not equal to the element
- */
-export function erase<T>(a: T, xs: T[]): T[] {
-	return xs.filter((x) => x !== a);
-}
-
-/**
- * Finds the array of all elements in the first array not contained in the second array.
- * The order of result values are determined by the first array.
- */
-export function difference<T>(xs: T[], ys: T[]): T[] {
-	return xs.filter((x) => !ys.includes(x));
-}
-
-/**
- * Remove all but the first element from every group of equivalent elements
- */
-export function unique<T>(xs: T[]): T[] {
-	return [...new Set(xs)];
-}
-
-export function sum(xs: number[]): number {
-	return xs.reduce((a, b) => a + b, 0);
-}
-
-export function maximum(xs: number[]): number {
-	return Math.max(...xs);
-}
-
-/**
- * Splits an array based on the equivalence relation.
- * The concatenation of the result is equal to the argument.
- */
-export function groupBy<T>(f: EndoRelation<T>, xs: T[]): T[][] {
-	const groups = [] as T[][];
-	for (const x of xs) {
-		if (groups.length !== 0 && f(groups[groups.length - 1][0], x)) {
-			groups[groups.length - 1].push(x);
-		} else {
-			groups.push([x]);
-		}
-	}
-	return groups;
-}
-
-/**
- * Splits an array based on the equivalence relation induced by the function.
- * The concatenation of the result is equal to the argument.
- */
-export function groupOn<T, S>(f: (x: T) => S, xs: T[]): T[][] {
-	return groupBy((a, b) => f(a) === f(b), xs);
-}
-
-export function groupByX<T>(collections: T[], keySelector: (x: T) => string) {
-	return collections.reduce((obj: Record<string, T[]>, item: T) => {
-		const key = keySelector(item);
-		if (!Object.prototype.hasOwnProperty.call(obj, key)) {
-			obj[key] = [];
-		}
-
-		obj[key].push(item);
-
-		return obj;
-	}, {});
-}
-
-/**
- * Compare two arrays by lexicographical order
- */
-export function lessThan(xs: number[], ys: number[]): boolean {
-	for (let i = 0; i < Math.min(xs.length, ys.length); i++) {
-		if (xs[i] < ys[i]) return true;
-		if (xs[i] > ys[i]) return false;
-	}
-	return xs.length < ys.length;
-}
-
-/**
- * Returns the longest prefix of elements that satisfy the predicate
- */
-export function takeWhile<T>(f: Predicate<T>, xs: T[]): T[] {
-	const ys = [];
-	for (const x of xs) {
-		if (f(x)) {
-			ys.push(x);
-		} else {
-			break;
-		}
-	}
-	return ys;
-}
-
-export function cumulativeSum(xs: number[]): number[] {
-	const ys = Array.from(xs); // deep copy
-	for (let i = 1; i < ys.length; i++) ys[i] += ys[i - 1];
-	return ys;
-}
-
-export function toArray<T>(x: T | T[] | undefined): T[] {
-	return Array.isArray(x) ? x : x != null ? [x] : [];
-}
-
-export function toSingle<T>(x: T | T[] | undefined): T | undefined {
-	return Array.isArray(x) ? x[0] : x;
-}
diff --git a/packages/backend/src/prelude/await-all.ts b/packages/backend/src/prelude/await-all.ts
deleted file mode 100644
index ce11eb87b4..0000000000
--- a/packages/backend/src/prelude/await-all.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-export type Promiseable<T> = {
-	[K in keyof T]: Promise<T[K]> | T[K];
-};
-
-export async function awaitAll<T>(obj: Promiseable<T>): Promise<T> {
-	const target = {} as T;
-	const keys = Object.keys(obj) as unknown as (keyof T)[];
-	const values = Object.values(obj) as any[];
-
-	const resolvedValues = await Promise.all(
-		values.map((value) =>
-			!value?.constructor || value.constructor.name !== "Object"
-				? value
-				: awaitAll(value),
-		),
-	);
-
-	for (let i = 0; i < keys.length; i++) {
-		target[keys[i]] = resolvedValues[i];
-	}
-
-	return target;
-}
diff --git a/packages/backend/src/prelude/math.ts b/packages/backend/src/prelude/math.ts
deleted file mode 100644
index 07b94bec30..0000000000
--- a/packages/backend/src/prelude/math.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export function gcd(a: number, b: number): number {
-	return b === 0 ? a : gcd(b, a % b);
-}
diff --git a/packages/backend/src/prelude/maybe.ts b/packages/backend/src/prelude/maybe.ts
deleted file mode 100644
index df7c4ed52a..0000000000
--- a/packages/backend/src/prelude/maybe.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-export interface IMaybe<T> {
-	isJust(): this is IJust<T>;
-}
-
-export interface IJust<T> extends IMaybe<T> {
-	get(): T;
-}
-
-export function just<T>(value: T): IJust<T> {
-	return {
-		isJust: () => true,
-		get: () => value,
-	};
-}
-
-export function nothing<T>(): IMaybe<T> {
-	return {
-		isJust: () => false,
-	};
-}
diff --git a/packages/backend/src/prelude/relation.ts b/packages/backend/src/prelude/relation.ts
deleted file mode 100644
index 1f4703f52f..0000000000
--- a/packages/backend/src/prelude/relation.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-export type Predicate<T> = (a: T) => boolean;
-
-export type Relation<T, U> = (a: T, b: U) => boolean;
-
-export type EndoRelation<T> = Relation<T, T>;
diff --git a/packages/backend/src/prelude/string.ts b/packages/backend/src/prelude/string.ts
deleted file mode 100644
index 9588825cb7..0000000000
--- a/packages/backend/src/prelude/string.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-export function concat(xs: string[]): string {
-	return xs.join("");
-}
-
-export function capitalize(s: string): string {
-	return toUpperCase(s.charAt(0)) + toLowerCase(s.slice(1));
-}
-
-export function toUpperCase(s: string): string {
-	return s.toUpperCase();
-}
-
-export function toLowerCase(s: string): string {
-	return s.toLowerCase();
-}
diff --git a/packages/backend/src/prelude/symbol.ts b/packages/backend/src/prelude/symbol.ts
deleted file mode 100644
index 5b88467d46..0000000000
--- a/packages/backend/src/prelude/symbol.ts
+++ /dev/null
@@ -1 +0,0 @@
-export const fallback = Symbol("fallback");
diff --git a/packages/backend/src/prelude/time.ts b/packages/backend/src/prelude/time.ts
deleted file mode 100644
index 5901b9c484..0000000000
--- a/packages/backend/src/prelude/time.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-const dateTimeIntervals = {
-	day: 86400000,
-	hour: 3600000,
-	ms: 1,
-};
-
-export function dateUTC(time: number[]): Date {
-	const d =
-		time.length === 2
-			? Date.UTC(time[0], time[1])
-			: time.length === 3
-			? Date.UTC(time[0], time[1], time[2])
-			: time.length === 4
-			? Date.UTC(time[0], time[1], time[2], time[3])
-			: time.length === 5
-			? Date.UTC(time[0], time[1], time[2], time[3], time[4])
-			: time.length === 6
-			? Date.UTC(time[0], time[1], time[2], time[3], time[4], time[5])
-			: time.length === 7
-			? Date.UTC(time[0], time[1], time[2], time[3], time[4], time[5], time[6])
-			: null;
-
-	if (!d) throw new Error("wrong number of arguments");
-
-	return new Date(d);
-}
-
-export function isTimeSame(a: Date, b: Date): boolean {
-	return a.getTime() === b.getTime();
-}
-
-export function isTimeBefore(a: Date, b: Date): boolean {
-	return a.getTime() - b.getTime() < 0;
-}
-
-export function isTimeAfter(a: Date, b: Date): boolean {
-	return a.getTime() - b.getTime() > 0;
-}
-
-export function addTime(
-	x: Date,
-	value: number,
-	span: keyof typeof dateTimeIntervals = "ms",
-): Date {
-	return new Date(x.getTime() + value * dateTimeIntervals[span]);
-}
-
-export function subtractTime(
-	x: Date,
-	value: number,
-	span: keyof typeof dateTimeIntervals = "ms",
-): Date {
-	return new Date(x.getTime() - value * dateTimeIntervals[span]);
-}
diff --git a/packages/backend/src/prelude/url.ts b/packages/backend/src/prelude/url.ts
deleted file mode 100644
index 9e3f3f7c12..0000000000
--- a/packages/backend/src/prelude/url.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-export function query(obj: Record<string, unknown>): string {
-	const params = Object.entries(obj)
-		.filter(([, v]) => (Array.isArray(v) ? v.length : v !== undefined))
-		.reduce((a, [k, v]) => ((a[k] = v), a), {} as Record<string, any>);
-
-	return Object.entries(params)
-		.map((e) => `${e[0]}=${encodeURIComponent(e[1])}`)
-		.join("&");
-}
-
-export function appendQuery(url: string, query: string): string {
-	return `${url}${
-		/\?/.test(url) ? (url.endsWith("?") ? "" : "&") : "?"
-	}${query}`;
-}
diff --git a/packages/backend/src/prelude/xml.ts b/packages/backend/src/prelude/xml.ts
deleted file mode 100644
index 9dcc4c96fd..0000000000
--- a/packages/backend/src/prelude/xml.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-const map: Record<string, string> = {
-	"&": "&amp;",
-	"<": "&lt;",
-	">": "&gt;",
-	'"': "&quot;",
-	"'": "&apos;",
-};
-
-const beginingOfCDATA = "<![CDATA[";
-const endOfCDATA = "]]>";
-
-export function escapeValue(x: string): string {
-	let insideOfCDATA = false;
-	let builder = "";
-	for (let i = 0; i < x.length; ) {
-		if (insideOfCDATA) {
-			if (x.slice(i, i + beginingOfCDATA.length) === beginingOfCDATA) {
-				insideOfCDATA = true;
-				i += beginingOfCDATA.length;
-			} else {
-				builder += x[i++];
-			}
-		} else {
-			if (x.slice(i, i + endOfCDATA.length) === endOfCDATA) {
-				insideOfCDATA = false;
-				i += endOfCDATA.length;
-			} else {
-				const b = x[i++];
-				builder += map[b] || b;
-			}
-		}
-	}
-	return builder;
-}
-
-export function escapeAttribute(x: string): string {
-	return Object.entries(map).reduce((a, [k, v]) => a.replace(k, v), x);
-}
diff --git a/packages/backend/src/queue/get-job-info.ts b/packages/backend/src/queue/get-job-info.ts
deleted file mode 100644
index ae3532cdae..0000000000
--- a/packages/backend/src/queue/get-job-info.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import type Bull from "bull";
-
-export function getJobInfo(job: Bull.Job, increment = false) {
-	const age = Date.now() - job.timestamp;
-
-	const formated =
-		age > 60000
-			? `${Math.floor(age / 1000 / 60)}m`
-			: age > 10000
-			? `${Math.floor(age / 1000)}s`
-			: `${age}ms`;
-
-	// onActiveとかonCompletedのattemptsMadeがなぜか0始まりなのでインクリメントする
-	const currentAttempts = job.attemptsMade + (increment ? 1 : 0);
-	const maxAttempts = job.opts ? job.opts.attempts : 0;
-
-	return `id=${job.id} attempts=${currentAttempts}/${maxAttempts} age=${formated}`;
-}
diff --git a/packages/backend/src/queue/index.ts b/packages/backend/src/queue/index.ts
deleted file mode 100644
index 035556e487..0000000000
--- a/packages/backend/src/queue/index.ts
+++ /dev/null
@@ -1,545 +0,0 @@
-import type httpSignature from "@peertube/http-signature";
-import { v4 as uuid } from "uuid";
-
-import config from "@/config/index.js";
-import type { DriveFile } from "@/models/entities/drive-file.js";
-import type { IActivity } from "@/remote/activitypub/type.js";
-import type { Webhook, webhookEventTypes } from "@/models/entities/webhook.js";
-import { envOption } from "../env.js";
-
-import processDeliver from "./processors/deliver.js";
-import processInbox from "./processors/inbox.js";
-import processDb from "./processors/db/index.js";
-import processObjectStorage from "./processors/object-storage/index.js";
-import processSystemQueue from "./processors/system/index.js";
-import processWebhookDeliver from "./processors/webhook-deliver.js";
-import processBackground from "./processors/background/index.js";
-import { endedPollNotification } from "./processors/ended-poll-notification.js";
-import { queueLogger } from "./logger.js";
-import { getJobInfo } from "./get-job-info.js";
-import {
-	systemQueue,
-	dbQueue,
-	deliverQueue,
-	inboxQueue,
-	objectStorageQueue,
-	endedPollNotificationQueue,
-	webhookDeliverQueue,
-	backgroundQueue,
-} from "./queues.js";
-import type { ThinUser } from "./types.js";
-
-function renderError(e: Error): any {
-	return {
-		stack: e.stack,
-		message: e.message,
-		name: e.name,
-	};
-}
-
-const systemLogger = queueLogger.createSubLogger("system");
-const deliverLogger = queueLogger.createSubLogger("deliver");
-const webhookLogger = queueLogger.createSubLogger("webhook");
-const inboxLogger = queueLogger.createSubLogger("inbox");
-const dbLogger = queueLogger.createSubLogger("db");
-const objectStorageLogger = queueLogger.createSubLogger("objectStorage");
-
-systemQueue
-	.on("waiting", (jobId) => systemLogger.debug(`waiting id=${jobId}`))
-	.on("active", (job) => systemLogger.debug(`active id=${job.id}`))
-	.on("completed", (job, result) =>
-		systemLogger.debug(`completed(${result}) id=${job.id}`),
-	)
-	.on("failed", (job, err) =>
-		systemLogger.warn(`failed(${err}) id=${job.id}`, {
-			job,
-			e: renderError(err),
-		}),
-	)
-	.on("error", (job: any, err: Error) =>
-		systemLogger.error(`error ${err}`, { job, e: renderError(err) }),
-	)
-	.on("stalled", (job) => systemLogger.warn(`stalled id=${job.id}`));
-
-deliverQueue
-	.on("waiting", (jobId) => deliverLogger.debug(`waiting id=${jobId}`))
-	.on("active", (job) =>
-		deliverLogger.debug(`active ${getJobInfo(job, true)} to=${job.data.to}`),
-	)
-	.on("completed", (job, result) =>
-		deliverLogger.debug(
-			`completed(${result}) ${getJobInfo(job, true)} to=${job.data.to}`,
-		),
-	)
-	.on("failed", (job, err) =>
-		deliverLogger.warn(`failed(${err}) ${getJobInfo(job)} to=${job.data.to}`),
-	)
-	.on("error", (job: any, err: Error) =>
-		deliverLogger.error(`error ${err}`, { job, e: renderError(err) }),
-	)
-	.on("stalled", (job) =>
-		deliverLogger.warn(`stalled ${getJobInfo(job)} to=${job.data.to}`),
-	);
-
-inboxQueue
-	.on("waiting", (jobId) => inboxLogger.debug(`waiting id=${jobId}`))
-	.on("active", (job) => inboxLogger.debug(`active ${getJobInfo(job, true)}`))
-	.on("completed", (job, result) =>
-		inboxLogger.debug(`completed(${result}) ${getJobInfo(job, true)}`),
-	)
-	.on("failed", (job, err) =>
-		inboxLogger.warn(
-			`failed(${err}) ${getJobInfo(job)} activity=${
-				job.data.activity ? job.data.activity.id : "none"
-			}`,
-			{ job, e: renderError(err) },
-		),
-	)
-	.on("error", (job: any, err: Error) =>
-		inboxLogger.error(`error ${err}`, { job, e: renderError(err) }),
-	)
-	.on("stalled", (job) =>
-		inboxLogger.warn(
-			`stalled ${getJobInfo(job)} activity=${
-				job.data.activity ? job.data.activity.id : "none"
-			}`,
-		),
-	);
-
-dbQueue
-	.on("waiting", (jobId) => dbLogger.debug(`waiting id=${jobId}`))
-	.on("active", (job) => dbLogger.debug(`active id=${job.id}`))
-	.on("completed", (job, result) =>
-		dbLogger.debug(`completed(${result}) id=${job.id}`),
-	)
-	.on("failed", (job, err) =>
-		dbLogger.warn(`failed(${err}) id=${job.id}`, { job, e: renderError(err) }),
-	)
-	.on("error", (job: any, err: Error) =>
-		dbLogger.error(`error ${err}`, { job, e: renderError(err) }),
-	)
-	.on("stalled", (job) => dbLogger.warn(`stalled id=${job.id}`));
-
-objectStorageQueue
-	.on("waiting", (jobId) => objectStorageLogger.debug(`waiting id=${jobId}`))
-	.on("active", (job) => objectStorageLogger.debug(`active id=${job.id}`))
-	.on("completed", (job, result) =>
-		objectStorageLogger.debug(`completed(${result}) id=${job.id}`),
-	)
-	.on("failed", (job, err) =>
-		objectStorageLogger.warn(`failed(${err}) id=${job.id}`, {
-			job,
-			e: renderError(err),
-		}),
-	)
-	.on("error", (job: any, err: Error) =>
-		objectStorageLogger.error(`error ${err}`, { job, e: renderError(err) }),
-	)
-	.on("stalled", (job) => objectStorageLogger.warn(`stalled id=${job.id}`));
-
-webhookDeliverQueue
-	.on("waiting", (jobId) => webhookLogger.debug(`waiting id=${jobId}`))
-	.on("active", (job) =>
-		webhookLogger.debug(`active ${getJobInfo(job, true)} to=${job.data.to}`),
-	)
-	.on("completed", (job, result) =>
-		webhookLogger.debug(
-			`completed(${result}) ${getJobInfo(job, true)} to=${job.data.to}`,
-		),
-	)
-	.on("failed", (job, err) =>
-		webhookLogger.warn(`failed(${err}) ${getJobInfo(job)} to=${job.data.to}`),
-	)
-	.on("error", (job: any, err: Error) =>
-		webhookLogger.error(`error ${err}`, { job, e: renderError(err) }),
-	)
-	.on("stalled", (job) =>
-		webhookLogger.warn(`stalled ${getJobInfo(job)} to=${job.data.to}`),
-	);
-
-export function deliver(user: ThinUser, content: unknown, to: string | null) {
-	if (content == null) return null;
-	if (to == null) return null;
-
-	const data = {
-		user: {
-			id: user.id,
-		},
-		content,
-		to,
-	};
-
-	return deliverQueue.add(data, {
-		attempts: config.deliverJobMaxAttempts || 12,
-		timeout: 1 * 60 * 1000, // 1min
-		backoff: {
-			type: "apBackoff",
-		},
-		removeOnComplete: true,
-		removeOnFail: true,
-	});
-}
-
-export function inbox(
-	activity: IActivity,
-	signature: httpSignature.IParsedSignature,
-) {
-	const data = {
-		activity: activity,
-		signature,
-	};
-
-	return inboxQueue.add(data, {
-		attempts: config.inboxJobMaxAttempts || 8,
-		timeout: 5 * 60 * 1000, // 5min
-		backoff: {
-			type: "apBackoff",
-		},
-		removeOnComplete: true,
-		removeOnFail: true,
-	});
-}
-
-export function createDeleteDriveFilesJob(user: ThinUser) {
-	return dbQueue.add(
-		"deleteDriveFiles",
-		{
-			user: user,
-		},
-		{
-			removeOnComplete: true,
-			removeOnFail: true,
-		},
-	);
-}
-
-export function createExportCustomEmojisJob(user: ThinUser) {
-	return dbQueue.add(
-		"exportCustomEmojis",
-		{
-			user: user,
-		},
-		{
-			removeOnComplete: true,
-			removeOnFail: true,
-		},
-	);
-}
-
-export function createExportNotesJob(user: ThinUser) {
-	return dbQueue.add(
-		"exportNotes",
-		{
-			user: user,
-		},
-		{
-			removeOnComplete: true,
-			removeOnFail: true,
-		},
-	);
-}
-
-export function createExportFollowingJob(
-	user: ThinUser,
-	excludeMuting = false,
-	excludeInactive = false,
-) {
-	return dbQueue.add(
-		"exportFollowing",
-		{
-			user: user,
-			excludeMuting,
-			excludeInactive,
-		},
-		{
-			removeOnComplete: true,
-			removeOnFail: true,
-		},
-	);
-}
-
-export function createExportMuteJob(user: ThinUser) {
-	return dbQueue.add(
-		"exportMute",
-		{
-			user: user,
-		},
-		{
-			removeOnComplete: true,
-			removeOnFail: true,
-		},
-	);
-}
-
-export function createExportBlockingJob(user: ThinUser) {
-	return dbQueue.add(
-		"exportBlocking",
-		{
-			user: user,
-		},
-		{
-			removeOnComplete: true,
-			removeOnFail: true,
-		},
-	);
-}
-
-export function createExportUserListsJob(user: ThinUser) {
-	return dbQueue.add(
-		"exportUserLists",
-		{
-			user: user,
-		},
-		{
-			removeOnComplete: true,
-			removeOnFail: true,
-		},
-	);
-}
-
-export function createImportFollowingJob(
-	user: ThinUser,
-	fileId: DriveFile["id"],
-) {
-	return dbQueue.add(
-		"importFollowing",
-		{
-			user: user,
-			fileId: fileId,
-		},
-		{
-			removeOnComplete: true,
-			removeOnFail: true,
-		},
-	);
-}
-
-export function createImportPostsJob(
-	user: ThinUser,
-	fileId: DriveFile["id"],
-	signatureCheck: boolean,
-) {
-	return dbQueue.add(
-		"importPosts",
-		{
-			user: user,
-			fileId: fileId,
-			signatureCheck: signatureCheck,
-		},
-		{
-			removeOnComplete: true,
-			removeOnFail: true,
-		},
-	);
-}
-
-export function createImportMutingJob(user: ThinUser, fileId: DriveFile["id"]) {
-	return dbQueue.add(
-		"importMuting",
-		{
-			user: user,
-			fileId: fileId,
-		},
-		{
-			removeOnComplete: true,
-			removeOnFail: true,
-		},
-	);
-}
-
-export function createImportBlockingJob(
-	user: ThinUser,
-	fileId: DriveFile["id"],
-) {
-	return dbQueue.add(
-		"importBlocking",
-		{
-			user: user,
-			fileId: fileId,
-		},
-		{
-			removeOnComplete: true,
-			removeOnFail: true,
-		},
-	);
-}
-
-export function createImportUserListsJob(
-	user: ThinUser,
-	fileId: DriveFile["id"],
-) {
-	return dbQueue.add(
-		"importUserLists",
-		{
-			user: user,
-			fileId: fileId,
-		},
-		{
-			removeOnComplete: true,
-			removeOnFail: true,
-		},
-	);
-}
-
-export function createImportCustomEmojisJob(
-	user: ThinUser,
-	fileId: DriveFile["id"],
-) {
-	return dbQueue.add(
-		"importCustomEmojis",
-		{
-			user: user,
-			fileId: fileId,
-		},
-		{
-			removeOnComplete: true,
-			removeOnFail: true,
-		},
-	);
-}
-
-export function createDeleteAccountJob(
-	user: ThinUser,
-	opts: { soft?: boolean } = {},
-) {
-	return dbQueue.add(
-		"deleteAccount",
-		{
-			user: user,
-			soft: opts.soft,
-		},
-		{
-			removeOnComplete: true,
-			removeOnFail: true,
-		},
-	);
-}
-
-export function createDeleteObjectStorageFileJob(key: string) {
-	return objectStorageQueue.add(
-		"deleteFile",
-		{
-			key: key,
-		},
-		{
-			removeOnComplete: true,
-			removeOnFail: true,
-		},
-	);
-}
-
-export function createCleanRemoteFilesJob() {
-	return objectStorageQueue.add(
-		"cleanRemoteFiles",
-		{},
-		{
-			removeOnComplete: true,
-			removeOnFail: true,
-		},
-	);
-}
-
-export function createIndexAllNotesJob(data = {}) {
-	return backgroundQueue.add("indexAllNotes", data, {
-		removeOnComplete: true,
-		removeOnFail: true,
-	});
-}
-
-export function webhookDeliver(
-	webhook: Webhook,
-	type: typeof webhookEventTypes[number],
-	content: unknown,
-) {
-	const data = {
-		type,
-		content,
-		webhookId: webhook.id,
-		userId: webhook.userId,
-		to: webhook.url,
-		secret: webhook.secret,
-		createdAt: Date.now(),
-		eventId: uuid(),
-	};
-
-	return webhookDeliverQueue.add(data, {
-		attempts: 4,
-		timeout: 1 * 60 * 1000, // 1min
-		backoff: {
-			type: "apBackoff",
-		},
-		removeOnComplete: true,
-		removeOnFail: true,
-	});
-}
-
-export default function () {
-	if (envOption.onlyServer) return;
-
-	deliverQueue.process(config.deliverJobConcurrency || 128, processDeliver);
-	inboxQueue.process(config.inboxJobConcurrency || 16, processInbox);
-	endedPollNotificationQueue.process(endedPollNotification);
-	webhookDeliverQueue.process(64, processWebhookDeliver);
-	processDb(dbQueue);
-	processObjectStorage(objectStorageQueue);
-	processBackground(backgroundQueue);
-
-	systemQueue.add(
-		"tickCharts",
-		{},
-		{
-			repeat: { cron: "55 * * * *" },
-			removeOnComplete: true,
-		},
-	);
-
-	systemQueue.add(
-		"resyncCharts",
-		{},
-		{
-			repeat: { cron: "0 0 * * *" },
-			removeOnComplete: true,
-		},
-	);
-
-	systemQueue.add(
-		"cleanCharts",
-		{},
-		{
-			repeat: { cron: "0 0 * * *" },
-			removeOnComplete: true,
-		},
-	);
-
-	systemQueue.add(
-		"clean",
-		{},
-		{
-			repeat: { cron: "0 0 * * *" },
-			removeOnComplete: true,
-		},
-	);
-
-	systemQueue.add(
-		"checkExpiredMutings",
-		{},
-		{
-			repeat: { cron: "*/5 * * * *" },
-			removeOnComplete: true,
-		},
-	);
-
-	processSystemQueue(systemQueue);
-}
-
-export function destroy() {
-	deliverQueue.once("cleaned", (jobs, status) => {
-		deliverLogger.succ(`Cleaned ${jobs.length} ${status} jobs`);
-	});
-	deliverQueue.clean(0, "delayed");
-
-	inboxQueue.once("cleaned", (jobs, status) => {
-		inboxLogger.succ(`Cleaned ${jobs.length} ${status} jobs`);
-	});
-	inboxQueue.clean(0, "delayed");
-}
diff --git a/packages/backend/src/queue/initialize.ts b/packages/backend/src/queue/initialize.ts
deleted file mode 100644
index d7945d5dad..0000000000
--- a/packages/backend/src/queue/initialize.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import Bull from "bull";
-import config from "@/config/index.js";
-
-export function initialize<T>(name: string, limitPerSec = -1) {
-	return new Bull<T>(name, {
-		redis: {
-			port: config.redis.port,
-			host: config.redis.host,
-			family: config.redis.family == null ? 0 : config.redis.family,
-			password: config.redis.pass,
-			db: config.redis.db || 0,
-		},
-		prefix: config.redis.prefix ? `${config.redis.prefix}:queue` : "queue",
-		limiter:
-			limitPerSec > 0
-				? {
-						max: limitPerSec,
-						duration: 1000,
-				  }
-				: undefined,
-		settings: {
-			backoffStrategies: {
-				apBackoff,
-			},
-		},
-	});
-}
-
-// ref. https://github.com/misskey-dev/misskey/pull/7635#issue-971097019
-function apBackoff(attemptsMade: number, err: Error) {
-	const baseDelay = 60 * 1000; // 1min
-	const maxBackoff = 8 * 60 * 60 * 1000; // 8hours
-	let backoff = (Math.pow(2, attemptsMade) - 1) * baseDelay;
-	backoff = Math.min(backoff, maxBackoff);
-	backoff += Math.round(backoff * Math.random() * 0.2);
-	return backoff;
-}
diff --git a/packages/backend/src/queue/logger.ts b/packages/backend/src/queue/logger.ts
deleted file mode 100644
index 929c207e3c..0000000000
--- a/packages/backend/src/queue/logger.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import Logger from "@/services/logger.js";
-
-export const queueLogger = new Logger("queue", "orange");
diff --git a/packages/backend/src/queue/processors/background/index-all-notes.ts b/packages/backend/src/queue/processors/background/index-all-notes.ts
deleted file mode 100644
index 03219199d9..0000000000
--- a/packages/backend/src/queue/processors/background/index-all-notes.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-import type Bull from "bull";
-
-import { queueLogger } from "../../logger.js";
-import { Notes } from "@/models/index.js";
-import { MoreThan } from "typeorm";
-import { index } from "@/services/note/create.js";
-import { Note } from "@/models/entities/note.js";
-
-const logger = queueLogger.createSubLogger("index-all-notes");
-
-export default async function indexAllNotes(
-	job: Bull.Job<Record<string, unknown>>,
-	done: () => void,
-): Promise<void> {
-	logger.info("Indexing all notes...");
-
-	let cursor: string | null = (job.data.cursor as string) ?? null;
-	let indexedCount: number = (job.data.indexedCount as number) ?? 0;
-	let total: number = (job.data.total as number) ?? 0;
-
-	let running = true;
-	const take = 50000;
-	const batch = 100;
-	while (running) {
-		logger.info(
-			`Querying for ${take} notes ${indexedCount}/${
-				total ? total : "?"
-			} at ${cursor}`,
-		);
-
-		let notes: Note[] = [];
-		try {
-			notes = await Notes.find({
-				where: {
-					...(cursor ? { id: MoreThan(cursor) } : {}),
-				},
-				take: take,
-				order: {
-					id: 1,
-				},
-			});
-		} catch (e) {
-			logger.error(`Failed to query notes ${e}`);
-			continue;
-		}
-
-		if (notes.length === 0) {
-			job.progress(100);
-			running = false;
-			break;
-		}
-
-		try {
-			const count = await Notes.count();
-			total = count;
-			job.update({ indexedCount, cursor, total });
-		} catch (e) {}
-
-		for (let i = 0; i < notes.length; i += batch) {
-			const chunk = notes.slice(i, i + batch);
-			await Promise.all(chunk.map((note) => index(note)));
-
-			indexedCount += chunk.length;
-			const pct = (indexedCount / total) * 100;
-			job.update({ indexedCount, cursor, total });
-			job.progress(+pct.toFixed(1));
-			logger.info(`Indexed notes ${indexedCount}/${total ? total : "?"}`);
-		}
-		cursor = notes[notes.length - 1].id;
-		job.update({ indexedCount, cursor, total });
-
-		if (notes.length < take) {
-			running = false;
-		}
-	}
-
-	done();
-	logger.info("All notes have been indexed.");
-}
diff --git a/packages/backend/src/queue/processors/background/index.ts b/packages/backend/src/queue/processors/background/index.ts
deleted file mode 100644
index 6674f954b0..0000000000
--- a/packages/backend/src/queue/processors/background/index.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import type Bull from "bull";
-import indexAllNotes from "./index-all-notes.js";
-
-const jobs = {
-	indexAllNotes,
-} as Record<string, Bull.ProcessCallbackFunction<Record<string, unknown>>>;
-
-export default function (q: Bull.Queue) {
-	for (const [k, v] of Object.entries(jobs)) {
-		q.process(k, 16, v);
-	}
-}
diff --git a/packages/backend/src/queue/processors/db/delete-account.ts b/packages/backend/src/queue/processors/db/delete-account.ts
deleted file mode 100644
index 764b83db2d..0000000000
--- a/packages/backend/src/queue/processors/db/delete-account.ts
+++ /dev/null
@@ -1,102 +0,0 @@
-import type Bull from "bull";
-import { queueLogger } from "../../logger.js";
-import { DriveFiles, Notes, UserProfiles, Users } from "@/models/index.js";
-import type { DbUserDeleteJobData } from "@/queue/types.js";
-import type { Note } from "@/models/entities/note.js";
-import type { DriveFile } from "@/models/entities/drive-file.js";
-import { MoreThan } from "typeorm";
-import { deleteFileSync } from "@/services/drive/delete-file.js";
-import { sendEmail } from "@/services/send-email.js";
-
-const logger = queueLogger.createSubLogger("delete-account");
-
-export async function deleteAccount(
-	job: Bull.Job<DbUserDeleteJobData>,
-): Promise<string | void> {
-	logger.info(`Deleting account of ${job.data.user.id} ...`);
-
-	const user = await Users.findOneBy({ id: job.data.user.id });
-	if (user == null) {
-		return;
-	}
-
-	{
-		// Delete notes
-		let cursor: Note["id"] | null = null;
-
-		while (true) {
-			const notes = (await Notes.find({
-				where: {
-					userId: user.id,
-					...(cursor ? { id: MoreThan(cursor) } : {}),
-				},
-				take: 100,
-				order: {
-					id: 1,
-				},
-			})) as Note[];
-
-			if (notes.length === 0) {
-				break;
-			}
-
-			cursor = notes[notes.length - 1].id;
-
-			await Notes.delete(notes.map((note) => note.id));
-		}
-
-		logger.succ("All of notes deleted");
-	}
-
-	{
-		// Delete files
-		let cursor: DriveFile["id"] | null = null;
-
-		while (true) {
-			const files = (await DriveFiles.find({
-				where: {
-					userId: user.id,
-					...(cursor ? { id: MoreThan(cursor) } : {}),
-				},
-				take: 10,
-				order: {
-					id: 1,
-				},
-			})) as DriveFile[];
-
-			if (files.length === 0) {
-				break;
-			}
-
-			cursor = files[files.length - 1].id;
-
-			for (const file of files) {
-				await deleteFileSync(file);
-			}
-		}
-
-		logger.succ("All of files deleted");
-	}
-
-	{
-		// Send email notification
-		const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
-		if (profile.email && profile.emailVerified) {
-			sendEmail(
-				profile.email,
-				"Account deleted",
-				"Your account has been deleted.",
-				"Your account has been deleted.",
-			);
-		}
-	}
-
-	// soft指定されている場合は物理削除しない
-	if (job.data.soft) {
-		// nop
-	} else {
-		await Users.delete(job.data.user.id);
-	}
-
-	return "Account deleted";
-}
diff --git a/packages/backend/src/queue/processors/db/delete-drive-files.ts b/packages/backend/src/queue/processors/db/delete-drive-files.ts
deleted file mode 100644
index 28e4771329..0000000000
--- a/packages/backend/src/queue/processors/db/delete-drive-files.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-import type Bull from "bull";
-
-import { queueLogger } from "../../logger.js";
-import { deleteFileSync } from "@/services/drive/delete-file.js";
-import { Users, DriveFiles } from "@/models/index.js";
-import { MoreThan } from "typeorm";
-import type { DbUserJobData } from "@/queue/types.js";
-
-const logger = queueLogger.createSubLogger("delete-drive-files");
-
-export async function deleteDriveFiles(
-	job: Bull.Job<DbUserJobData>,
-	done: any,
-): Promise<void> {
-	logger.info(`Deleting drive files of ${job.data.user.id} ...`);
-
-	const user = await Users.findOneBy({ id: job.data.user.id });
-	if (user == null) {
-		done();
-		return;
-	}
-
-	let deletedCount = 0;
-	let cursor: any = null;
-
-	while (true) {
-		const files = await DriveFiles.find({
-			where: {
-				userId: user.id,
-				...(cursor ? { id: MoreThan(cursor) } : {}),
-			},
-			take: 100,
-			order: {
-				id: 1,
-			},
-		});
-
-		if (files.length === 0) {
-			job.progress(100);
-			break;
-		}
-
-		cursor = files[files.length - 1].id;
-
-		for (const file of files) {
-			await deleteFileSync(file);
-			deletedCount++;
-		}
-
-		const total = await DriveFiles.countBy({
-			userId: user.id,
-		});
-
-		job.progress(deletedCount / total);
-	}
-
-	logger.succ(
-		`All drive files (${deletedCount}) of ${user.id} has been deleted.`,
-	);
-	done();
-}
diff --git a/packages/backend/src/queue/processors/db/export-blocking.ts b/packages/backend/src/queue/processors/db/export-blocking.ts
deleted file mode 100644
index 90da76b872..0000000000
--- a/packages/backend/src/queue/processors/db/export-blocking.ts
+++ /dev/null
@@ -1,105 +0,0 @@
-import type Bull from "bull";
-import * as fs from "node:fs";
-
-import { queueLogger } from "../../logger.js";
-import { addFile } from "@/services/drive/add-file.js";
-import { format as dateFormat } from "date-fns";
-import { getFullApAccount } from "@/misc/convert-host.js";
-import { createTemp } from "@/misc/create-temp.js";
-import { Users, Blockings } from "@/models/index.js";
-import { MoreThan } from "typeorm";
-import type { DbUserJobData } from "@/queue/types.js";
-
-const logger = queueLogger.createSubLogger("export-blocking");
-
-export async function exportBlocking(
-	job: Bull.Job<DbUserJobData>,
-	done: any,
-): Promise<void> {
-	logger.info(`Exporting blocking of ${job.data.user.id} ...`);
-
-	const user = await Users.findOneBy({ id: job.data.user.id });
-	if (user == null) {
-		done();
-		return;
-	}
-
-	// Create temp file
-	const [path, cleanup] = await createTemp();
-
-	logger.info(`Temp file is ${path}`);
-
-	try {
-		const stream = fs.createWriteStream(path, { flags: "a" });
-
-		let exportedCount = 0;
-		let cursor: any = null;
-
-		while (true) {
-			const blockings = await Blockings.find({
-				where: {
-					blockerId: user.id,
-					...(cursor ? { id: MoreThan(cursor) } : {}),
-				},
-				take: 100,
-				order: {
-					id: 1,
-				},
-			});
-
-			if (blockings.length === 0) {
-				job.progress(100);
-				break;
-			}
-
-			cursor = blockings[blockings.length - 1].id;
-
-			for (const block of blockings) {
-				const u = await Users.findOneBy({ id: block.blockeeId });
-				if (u == null) {
-					exportedCount++;
-					continue;
-				}
-
-				const content = getFullApAccount(u.username, u.host);
-				await new Promise<void>((res, rej) => {
-					stream.write(content + "\n", (err) => {
-						if (err) {
-							logger.error(err);
-							rej(err);
-						} else {
-							res();
-						}
-					});
-				});
-				exportedCount++;
-			}
-
-			const total = await Blockings.countBy({
-				blockerId: user.id,
-			});
-
-			job.progress(exportedCount / total);
-		}
-
-		stream.end();
-		logger.succ(`Exported to: ${path}`);
-
-		const fileName = `blocking-${dateFormat(
-			new Date(),
-			"yyyy-MM-dd-HH-mm-ss",
-		)}.csv`;
-		const driveFile = await addFile({
-			user,
-			path,
-			name: fileName,
-			force: true,
-		});
-
-		logger.succ(`Exported to: ${driveFile.id}`);
-	} finally {
-		cleanup();
-	}
-
-	done();
-}
diff --git a/packages/backend/src/queue/processors/db/export-custom-emojis.ts b/packages/backend/src/queue/processors/db/export-custom-emojis.ts
deleted file mode 100644
index 7a19d0b60b..0000000000
--- a/packages/backend/src/queue/processors/db/export-custom-emojis.ts
+++ /dev/null
@@ -1,130 +0,0 @@
-import type Bull from "bull";
-import * as fs from "node:fs";
-
-import { ulid } from "ulid";
-import mime from "mime-types";
-import archiver from "archiver";
-import { queueLogger } from "../../logger.js";
-import { addFile } from "@/services/drive/add-file.js";
-import { format as dateFormat } from "date-fns";
-import { Users, Emojis } from "@/models/index.js";
-import {} from "@/queue/types.js";
-import { createTemp, createTempDir } from "@/misc/create-temp.js";
-import { downloadUrl } from "@/misc/download-url.js";
-import config from "@/config/index.js";
-import { IsNull } from "typeorm";
-
-const logger = queueLogger.createSubLogger("export-custom-emojis");
-
-export async function exportCustomEmojis(
-	job: Bull.Job,
-	done: () => void,
-): Promise<void> {
-	logger.info("Exporting custom emojis ...");
-
-	const user = await Users.findOneBy({ id: job.data.user.id });
-	if (user == null) {
-		done();
-		return;
-	}
-
-	const [path, cleanup] = await createTempDir();
-
-	logger.info(`Temp dir is ${path}`);
-
-	const metaPath = `${path}/meta.json`;
-
-	fs.writeFileSync(metaPath, "", "utf-8");
-
-	const metaStream = fs.createWriteStream(metaPath, { flags: "a" });
-
-	const writeMeta = (text: string): Promise<void> => {
-		return new Promise<void>((res, rej) => {
-			metaStream.write(text, (err) => {
-				if (err) {
-					logger.error(err);
-					rej(err);
-				} else {
-					res();
-				}
-			});
-		});
-	};
-
-	await writeMeta(
-		`{"metaVersion":2,"host":"${
-			config.host
-		}","exportedAt":"${new Date().toString()}","emojis":[`,
-	);
-
-	const customEmojis = await Emojis.find({
-		where: {
-			host: IsNull(),
-		},
-		order: {
-			id: "ASC",
-		},
-	});
-
-	for (const emoji of customEmojis) {
-		const ext = mime.extension(emoji.type);
-		const fileName = emoji.name + (ext ? `.${ext}` : "");
-		const emojiPath = `${path}/${fileName}`;
-		fs.writeFileSync(emojiPath, "", "binary");
-		let downloaded = false;
-
-		try {
-			await downloadUrl(emoji.originalUrl, emojiPath);
-			downloaded = true;
-		} catch (e) {
-			// TODO: 何度か再試行
-			logger.error(e instanceof Error ? e : new Error(e as string));
-		}
-
-		if (!downloaded) {
-			fs.unlinkSync(emojiPath);
-		}
-
-		const content = JSON.stringify({
-			fileName: fileName,
-			downloaded: downloaded,
-			emoji: emoji,
-		});
-		const isFirst = customEmojis.indexOf(emoji) === 0;
-
-		await writeMeta(isFirst ? content : ",\n" + content);
-	}
-
-	await writeMeta("]}");
-
-	metaStream.end();
-
-	// Create archive
-	const [archivePath, archiveCleanup] = await createTemp();
-	const archiveStream = fs.createWriteStream(archivePath);
-	const archive = archiver("zip", {
-		zlib: { level: 0 },
-	});
-	archiveStream.on("close", async () => {
-		logger.succ(`Exported to: ${archivePath}`);
-
-		const fileName = `custom-emojis-${dateFormat(
-			new Date(),
-			"yyyy-MM-dd-HH-mm-ss",
-		)}.zip`;
-		const driveFile = await addFile({
-			user,
-			path: archivePath,
-			name: fileName,
-			force: true,
-		});
-
-		logger.succ(`Exported to: ${driveFile.id}`);
-		cleanup();
-		archiveCleanup();
-		done();
-	});
-	archive.pipe(archiveStream);
-	archive.directory(path, false);
-	archive.finalize();
-}
diff --git a/packages/backend/src/queue/processors/db/export-following.ts b/packages/backend/src/queue/processors/db/export-following.ts
deleted file mode 100644
index 80e8e6b925..0000000000
--- a/packages/backend/src/queue/processors/db/export-following.ts
+++ /dev/null
@@ -1,113 +0,0 @@
-import type Bull from "bull";
-import * as fs from "node:fs";
-
-import { queueLogger } from "../../logger.js";
-import { addFile } from "@/services/drive/add-file.js";
-import { format as dateFormat } from "date-fns";
-import { getFullApAccount } from "@/misc/convert-host.js";
-import { createTemp } from "@/misc/create-temp.js";
-import { Users, Followings, Mutings } from "@/models/index.js";
-import { In, MoreThan, Not } from "typeorm";
-import type { DbUserJobData } from "@/queue/types.js";
-import type { Following } from "@/models/entities/following.js";
-
-const logger = queueLogger.createSubLogger("export-following");
-
-export async function exportFollowing(
-	job: Bull.Job<DbUserJobData>,
-	done: () => void,
-): Promise<void> {
-	logger.info(`Exporting following of ${job.data.user.id} ...`);
-
-	const user = await Users.findOneBy({ id: job.data.user.id });
-	if (user == null) {
-		done();
-		return;
-	}
-
-	// Create temp file
-	const [path, cleanup] = await createTemp();
-
-	logger.info(`Temp file is ${path}`);
-
-	try {
-		const stream = fs.createWriteStream(path, { flags: "a" });
-
-		let cursor: Following["id"] | null = null;
-
-		const mutings = job.data.excludeMuting
-			? await Mutings.findBy({
-					muterId: user.id,
-			  })
-			: [];
-
-		while (true) {
-			const followings = (await Followings.find({
-				where: {
-					followerId: user.id,
-					...(mutings.length > 0
-						? { followeeId: Not(In(mutings.map((x) => x.muteeId))) }
-						: {}),
-					...(cursor ? { id: MoreThan(cursor) } : {}),
-				},
-				take: 100,
-				order: {
-					id: 1,
-				},
-			})) as Following[];
-
-			if (followings.length === 0) {
-				break;
-			}
-
-			cursor = followings[followings.length - 1].id;
-
-			for (const following of followings) {
-				const u = await Users.findOneBy({ id: following.followeeId });
-				if (u == null) {
-					continue;
-				}
-
-				if (
-					job.data.excludeInactive &&
-					u.updatedAt &&
-					Date.now() - u.updatedAt.getTime() > 1000 * 60 * 60 * 24 * 90
-				) {
-					continue;
-				}
-
-				const content = getFullApAccount(u.username, u.host);
-				await new Promise<void>((res, rej) => {
-					stream.write(content + "\n", (err) => {
-						if (err) {
-							logger.error(err);
-							rej(err);
-						} else {
-							res();
-						}
-					});
-				});
-			}
-		}
-
-		stream.end();
-		logger.succ(`Exported to: ${path}`);
-
-		const fileName = `following-${dateFormat(
-			new Date(),
-			"yyyy-MM-dd-HH-mm-ss",
-		)}.csv`;
-		const driveFile = await addFile({
-			user,
-			path,
-			name: fileName,
-			force: true,
-		});
-
-		logger.succ(`Exported to: ${driveFile.id}`);
-	} finally {
-		cleanup();
-	}
-
-	done();
-}
diff --git a/packages/backend/src/queue/processors/db/export-mute.ts b/packages/backend/src/queue/processors/db/export-mute.ts
deleted file mode 100644
index 87b140b762..0000000000
--- a/packages/backend/src/queue/processors/db/export-mute.ts
+++ /dev/null
@@ -1,106 +0,0 @@
-import type Bull from "bull";
-import * as fs from "node:fs";
-
-import { queueLogger } from "../../logger.js";
-import { addFile } from "@/services/drive/add-file.js";
-import { format as dateFormat } from "date-fns";
-import { getFullApAccount } from "@/misc/convert-host.js";
-import { createTemp } from "@/misc/create-temp.js";
-import { Users, Mutings } from "@/models/index.js";
-import { IsNull, MoreThan } from "typeorm";
-import type { DbUserJobData } from "@/queue/types.js";
-
-const logger = queueLogger.createSubLogger("export-mute");
-
-export async function exportMute(
-	job: Bull.Job<DbUserJobData>,
-	done: any,
-): Promise<void> {
-	logger.info(`Exporting mute of ${job.data.user.id} ...`);
-
-	const user = await Users.findOneBy({ id: job.data.user.id });
-	if (user == null) {
-		done();
-		return;
-	}
-
-	// Create temp file
-	const [path, cleanup] = await createTemp();
-
-	logger.info(`Temp file is ${path}`);
-
-	try {
-		const stream = fs.createWriteStream(path, { flags: "a" });
-
-		let exportedCount = 0;
-		let cursor: any = null;
-
-		while (true) {
-			const mutes = await Mutings.find({
-				where: {
-					muterId: user.id,
-					expiresAt: IsNull(),
-					...(cursor ? { id: MoreThan(cursor) } : {}),
-				},
-				take: 100,
-				order: {
-					id: 1,
-				},
-			});
-
-			if (mutes.length === 0) {
-				job.progress(100);
-				break;
-			}
-
-			cursor = mutes[mutes.length - 1].id;
-
-			for (const mute of mutes) {
-				const u = await Users.findOneBy({ id: mute.muteeId });
-				if (u == null) {
-					exportedCount++;
-					continue;
-				}
-
-				const content = getFullApAccount(u.username, u.host);
-				await new Promise<void>((res, rej) => {
-					stream.write(content + "\n", (err) => {
-						if (err) {
-							logger.error(err);
-							rej(err);
-						} else {
-							res();
-						}
-					});
-				});
-				exportedCount++;
-			}
-
-			const total = await Mutings.countBy({
-				muterId: user.id,
-			});
-
-			job.progress(exportedCount / total);
-		}
-
-		stream.end();
-		logger.succ(`Exported to: ${path}`);
-
-		const fileName = `mute-${dateFormat(
-			new Date(),
-			"yyyy-MM-dd-HH-mm-ss",
-		)}.csv`;
-		const driveFile = await addFile({
-			user,
-			path,
-			name: fileName,
-			force: true,
-		});
-
-		logger.succ(`Exported to: ${driveFile.id}`);
-	} finally {
-		cleanup();
-	}
-
-	done();
-}
diff --git a/packages/backend/src/queue/processors/db/export-notes.ts b/packages/backend/src/queue/processors/db/export-notes.ts
deleted file mode 100644
index de8fac05b4..0000000000
--- a/packages/backend/src/queue/processors/db/export-notes.ts
+++ /dev/null
@@ -1,132 +0,0 @@
-import type Bull from "bull";
-import * as fs from "node:fs";
-
-import { queueLogger } from "../../logger.js";
-import { addFile } from "@/services/drive/add-file.js";
-import { format as dateFormat } from "date-fns";
-import { Users, Notes, Polls } from "@/models/index.js";
-import { MoreThan } from "typeorm";
-import type { Note } from "@/models/entities/note.js";
-import type { Poll } from "@/models/entities/poll.js";
-import type { DbUserJobData } from "@/queue/types.js";
-import { createTemp } from "@/misc/create-temp.js";
-
-const logger = queueLogger.createSubLogger("export-notes");
-
-export async function exportNotes(
-	job: Bull.Job<DbUserJobData>,
-	done: any,
-): Promise<void> {
-	logger.info(`Exporting notes of ${job.data.user.id} ...`);
-
-	const user = await Users.findOneBy({ id: job.data.user.id });
-	if (user == null) {
-		done();
-		return;
-	}
-
-	// Create temp file
-	const [path, cleanup] = await createTemp();
-
-	logger.info(`Temp file is ${path}`);
-
-	try {
-		const stream = fs.createWriteStream(path, { flags: "a" });
-
-		const write = (text: string): Promise<void> => {
-			return new Promise<void>((res, rej) => {
-				stream.write(text, (err) => {
-					if (err) {
-						logger.error(err);
-						rej(err);
-					} else {
-						res();
-					}
-				});
-			});
-		};
-
-		await write("[");
-
-		let exportedNotesCount = 0;
-		let cursor: Note["id"] | null = null;
-
-		while (true) {
-			const notes = (await Notes.find({
-				where: {
-					userId: user.id,
-					...(cursor ? { id: MoreThan(cursor) } : {}),
-				},
-				take: 100,
-				order: {
-					id: 1,
-				},
-			})) as Note[];
-
-			if (notes.length === 0) {
-				job.progress(100);
-				break;
-			}
-
-			cursor = notes[notes.length - 1].id;
-
-			for (const note of notes) {
-				let poll: Poll | undefined;
-				if (note.hasPoll) {
-					poll = await Polls.findOneByOrFail({ noteId: note.id });
-				}
-				const content = JSON.stringify(serialize(note, poll));
-				const isFirst = exportedNotesCount === 0;
-				await write(isFirst ? content : ",\n" + content);
-				exportedNotesCount++;
-			}
-
-			const total = await Notes.countBy({
-				userId: user.id,
-			});
-
-			job.progress(exportedNotesCount / total);
-		}
-
-		await write("]");
-
-		stream.end();
-		logger.succ(`Exported to: ${path}`);
-
-		const fileName = `notes-${dateFormat(
-			new Date(),
-			"yyyy-MM-dd-HH-mm-ss",
-		)}.json`;
-		const driveFile = await addFile({
-			user,
-			path,
-			name: fileName,
-			force: true,
-		});
-
-		logger.succ(`Exported to: ${driveFile.id}`);
-	} finally {
-		cleanup();
-	}
-
-	done();
-}
-
-function serialize(
-	note: Note,
-	poll: Poll | null = null,
-): Record<string, unknown> {
-	return {
-		id: note.id,
-		text: note.text,
-		createdAt: note.createdAt,
-		fileIds: note.fileIds,
-		replyId: note.replyId,
-		renoteId: note.renoteId,
-		poll: poll,
-		cw: note.cw,
-		visibility: note.visibility,
-		visibleUserIds: note.visibleUserIds,
-		localOnly: note.localOnly,
-	};
-}
diff --git a/packages/backend/src/queue/processors/db/export-user-lists.ts b/packages/backend/src/queue/processors/db/export-user-lists.ts
deleted file mode 100644
index e0c9cd8f3f..0000000000
--- a/packages/backend/src/queue/processors/db/export-user-lists.ts
+++ /dev/null
@@ -1,81 +0,0 @@
-import type Bull from "bull";
-import * as fs from "node:fs";
-
-import { queueLogger } from "../../logger.js";
-import { addFile } from "@/services/drive/add-file.js";
-import { format as dateFormat } from "date-fns";
-import { getFullApAccount } from "@/misc/convert-host.js";
-import { createTemp } from "@/misc/create-temp.js";
-import { Users, UserLists, UserListJoinings } from "@/models/index.js";
-import { In } from "typeorm";
-import type { DbUserJobData } from "@/queue/types.js";
-
-const logger = queueLogger.createSubLogger("export-user-lists");
-
-export async function exportUserLists(
-	job: Bull.Job<DbUserJobData>,
-	done: any,
-): Promise<void> {
-	logger.info(`Exporting user lists of ${job.data.user.id} ...`);
-
-	const user = await Users.findOneBy({ id: job.data.user.id });
-	if (user == null) {
-		done();
-		return;
-	}
-
-	const lists = await UserLists.findBy({
-		userId: user.id,
-	});
-
-	// Create temp file
-	const [path, cleanup] = await createTemp();
-
-	logger.info(`Temp file is ${path}`);
-
-	try {
-		const stream = fs.createWriteStream(path, { flags: "a" });
-
-		for (const list of lists) {
-			const joinings = await UserListJoinings.findBy({ userListId: list.id });
-			const users = await Users.findBy({
-				id: In(joinings.map((j) => j.userId)),
-			});
-
-			for (const u of users) {
-				const acct = getFullApAccount(u.username, u.host);
-				const content = `${list.name},${acct}`;
-				await new Promise<void>((res, rej) => {
-					stream.write(content + "\n", (err) => {
-						if (err) {
-							logger.error(err);
-							rej(err);
-						} else {
-							res();
-						}
-					});
-				});
-			}
-		}
-
-		stream.end();
-		logger.succ(`Exported to: ${path}`);
-
-		const fileName = `user-lists-${dateFormat(
-			new Date(),
-			"yyyy-MM-dd-HH-mm-ss",
-		)}.csv`;
-		const driveFile = await addFile({
-			user,
-			path,
-			name: fileName,
-			force: true,
-		});
-
-		logger.succ(`Exported to: ${driveFile.id}`);
-	} finally {
-		cleanup();
-	}
-
-	done();
-}
diff --git a/packages/backend/src/queue/processors/db/import-blocking.ts b/packages/backend/src/queue/processors/db/import-blocking.ts
deleted file mode 100644
index 2fdf80a6eb..0000000000
--- a/packages/backend/src/queue/processors/db/import-blocking.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-import type Bull from "bull";
-
-import { queueLogger } from "../../logger.js";
-import * as Acct from "@/misc/acct.js";
-import { resolveUser } from "@/remote/resolve-user.js";
-import { downloadTextFile } from "@/misc/download-text-file.js";
-import { isSelfHost, toPuny } from "@/misc/convert-host.js";
-import { Users, DriveFiles, Blockings } from "@/models/index.js";
-import type { DbUserImportJobData } from "@/queue/types.js";
-import block from "@/services/blocking/create.js";
-import { IsNull } from "typeorm";
-
-const logger = queueLogger.createSubLogger("import-blocking");
-
-export async function importBlocking(
-	job: Bull.Job<DbUserImportJobData>,
-	done: any,
-): Promise<void> {
-	logger.info(`Importing blocking of ${job.data.user.id} ...`);
-
-	const user = await Users.findOneBy({ id: job.data.user.id });
-	if (user == null) {
-		done();
-		return;
-	}
-
-	const file = await DriveFiles.findOneBy({
-		id: job.data.fileId,
-	});
-	if (file == null) {
-		done();
-		return;
-	}
-
-	const csv = await downloadTextFile(file.url);
-
-	let linenum = 0;
-
-	for (const line of csv.trim().split("\n")) {
-		linenum++;
-
-		try {
-			const acct = line.split(",")[0].trim();
-			const { username, host } = Acct.parse(acct);
-
-			let target = isSelfHost(host!)
-				? await Users.findOneBy({
-						host: IsNull(),
-						usernameLower: username.toLowerCase(),
-				  })
-				: await Users.findOneBy({
-						host: toPuny(host!),
-						usernameLower: username.toLowerCase(),
-				  });
-
-			if (host == null && target == null) continue;
-
-			if (target == null) {
-				target = await resolveUser(username, host);
-			}
-
-			if (target == null) {
-				throw new Error(`cannot resolve user: @${username}@${host}`);
-			}
-
-			// skip myself
-			if (target.id === job.data.user.id) continue;
-
-			logger.info(`Block[${linenum}] ${target.id} ...`);
-
-			await block(user, target);
-		} catch (e) {
-			logger.warn(`Error in line:${linenum} ${e}`);
-		}
-	}
-
-	logger.succ("Imported");
-	done();
-}
diff --git a/packages/backend/src/queue/processors/db/import-custom-emojis.ts b/packages/backend/src/queue/processors/db/import-custom-emojis.ts
deleted file mode 100644
index 373a3a2daf..0000000000
--- a/packages/backend/src/queue/processors/db/import-custom-emojis.ts
+++ /dev/null
@@ -1,91 +0,0 @@
-import type Bull from "bull";
-import * as fs from "node:fs";
-import unzipper from "unzipper";
-
-import { queueLogger } from "../../logger.js";
-import { createTempDir } from "@/misc/create-temp.js";
-import { downloadUrl } from "@/misc/download-url.js";
-import { DriveFiles, Emojis } from "@/models/index.js";
-import type { DbUserImportJobData } from "@/queue/types.js";
-import { addFile } from "@/services/drive/add-file.js";
-import { genId } from "@/misc/gen-id.js";
-import { db } from "@/db/postgre.js";
-
-const logger = queueLogger.createSubLogger("import-custom-emojis");
-
-// TODO: 名前衝突時の動作を選べるようにする
-export async function importCustomEmojis(
-	job: Bull.Job<DbUserImportJobData>,
-	done: any,
-): Promise<void> {
-	logger.info("Importing custom emojis ...");
-
-	const file = await DriveFiles.findOneBy({
-		id: job.data.fileId,
-	});
-	if (file == null) {
-		done();
-		return;
-	}
-
-	const [path, cleanup] = await createTempDir();
-
-	logger.info(`Temp dir is ${path}`);
-
-	const destPath = `${path}/emojis.zip`;
-
-	try {
-		fs.writeFileSync(destPath, "", "binary");
-		await downloadUrl(file.url, destPath);
-	} catch (e) {
-		// TODO: 何度か再試行
-		if (e instanceof Error || typeof e === "string") {
-			logger.error(e);
-		}
-		throw e;
-	}
-
-	const outputPath = `${path}/emojis`;
-	const unzipStream = fs.createReadStream(destPath);
-	const extractor = unzipper.Extract({ path: outputPath });
-	extractor.on("close", async () => {
-		const metaRaw = fs.readFileSync(`${outputPath}/meta.json`, "utf-8");
-		const meta = JSON.parse(metaRaw);
-
-		for (const record of meta.emojis) {
-			if (!record.downloaded) continue;
-			const emojiInfo = record.emoji;
-			const emojiPath = `${outputPath}/${record.fileName}`;
-			await Emojis.delete({
-				name: emojiInfo.name,
-			});
-			const driveFile = await addFile({
-				user: null,
-				path: emojiPath,
-				name: record.fileName,
-				force: true,
-			});
-			const emoji = await Emojis.insert({
-				id: genId(),
-				updatedAt: new Date(),
-				name: emojiInfo.name,
-				category: emojiInfo.category,
-				host: null,
-				aliases: emojiInfo.aliases,
-				originalUrl: driveFile.url,
-				publicUrl: driveFile.webpublicUrl ?? driveFile.url,
-				type: driveFile.webpublicType ?? driveFile.type,
-				license: emojiInfo.license,
-			}).then((x) => Emojis.findOneByOrFail(x.identifiers[0]));
-		}
-
-		await db.queryResultCache!.remove(["meta_emojis"]);
-
-		cleanup();
-
-		logger.succ("Imported");
-		done();
-	});
-	unzipStream.pipe(extractor);
-	logger.succ(`Unzipping to ${outputPath}`);
-}
diff --git a/packages/backend/src/queue/processors/db/import-following.ts b/packages/backend/src/queue/processors/db/import-following.ts
deleted file mode 100644
index b1a7cd2c9b..0000000000
--- a/packages/backend/src/queue/processors/db/import-following.ts
+++ /dev/null
@@ -1,116 +0,0 @@
-import { IsNull } from "typeorm";
-import follow from "@/services/following/create.js";
-
-import * as Acct from "@/misc/acct.js";
-import { resolveUser } from "@/remote/resolve-user.js";
-import { downloadTextFile } from "@/misc/download-text-file.js";
-import { isSelfHost, toPuny } from "@/misc/convert-host.js";
-import { Users, DriveFiles } from "@/models/index.js";
-import type { DbUserImportJobData } from "@/queue/types.js";
-import { queueLogger } from "../../logger.js";
-import type Bull from "bull";
-
-const logger = queueLogger.createSubLogger("import-following");
-
-export async function importFollowing(
-	job: Bull.Job<DbUserImportJobData>,
-	done: any,
-): Promise<void> {
-	logger.info(`Importing following of ${job.data.user.id} ...`);
-
-	const user = await Users.findOneBy({ id: job.data.user.id });
-	if (user == null) {
-		done();
-		return;
-	}
-
-	const file = await DriveFiles.findOneBy({
-		id: job.data.fileId,
-	});
-	if (file == null) {
-		done();
-		return;
-	}
-
-	const csv = await downloadTextFile(file.url);
-
-	let linenum = 0;
-
-	if (file.type.endsWith("json")) {
-		for (const acct of JSON.parse(csv)) {
-			try {
-				const { username, host } = Acct.parse(acct);
-
-				let target = isSelfHost(host!)
-					? await Users.findOneBy({
-							host: IsNull(),
-							usernameLower: username.toLowerCase(),
-					  })
-					: await Users.findOneBy({
-							host: toPuny(host!),
-							usernameLower: username.toLowerCase(),
-					  });
-
-				if (host == null && target == null) continue;
-
-				if (target == null) {
-					target = await resolveUser(username, host);
-				}
-
-				if (target == null) {
-					throw new Error(`cannot resolve user: @${username}@${host}`);
-				}
-
-				// skip myself
-				if (target.id === job.data.user.id) continue;
-
-				logger.info(`Follow[${linenum}] ${target.id} ...`);
-
-				follow(user, target);
-			} catch (e) {
-				logger.warn(`Error in line:${linenum} ${e}`);
-			}
-		}
-	} else {
-		for (const line of csv.trim().split("\n")) {
-			linenum++;
-
-			try {
-				const acct = line.split(",")[0].trim();
-				const { username, host } = Acct.parse(acct);
-
-				let target = isSelfHost(host!)
-					? await Users.findOneBy({
-							host: IsNull(),
-							usernameLower: username.toLowerCase(),
-					  })
-					: await Users.findOneBy({
-							host: toPuny(host!),
-							usernameLower: username.toLowerCase(),
-					  });
-
-				if (host == null && target == null) continue;
-
-				if (target == null) {
-					target = await resolveUser(username, host);
-				}
-
-				if (target == null) {
-					throw new Error(`cannot resolve user: @${username}@${host}`);
-				}
-
-				// skip myself
-				if (target.id === job.data.user.id) continue;
-
-				logger.info(`Follow[${linenum}] ${target.id} ...`);
-
-				follow(user, target);
-			} catch (e) {
-				logger.warn(`Error in line:${linenum} ${e}`);
-			}
-		}
-	}
-
-	logger.succ("Imported");
-	done();
-}
diff --git a/packages/backend/src/queue/processors/db/import-muting.ts b/packages/backend/src/queue/processors/db/import-muting.ts
deleted file mode 100644
index 80e0567397..0000000000
--- a/packages/backend/src/queue/processors/db/import-muting.ts
+++ /dev/null
@@ -1,89 +0,0 @@
-import type Bull from "bull";
-
-import { queueLogger } from "../../logger.js";
-import * as Acct from "@/misc/acct.js";
-import { resolveUser } from "@/remote/resolve-user.js";
-import { downloadTextFile } from "@/misc/download-text-file.js";
-import { isSelfHost, toPuny } from "@/misc/convert-host.js";
-import { Users, DriveFiles, Mutings } from "@/models/index.js";
-import type { DbUserImportJobData } from "@/queue/types.js";
-import type { User } from "@/models/entities/user.js";
-import { genId } from "@/misc/gen-id.js";
-import { IsNull } from "typeorm";
-
-const logger = queueLogger.createSubLogger("import-muting");
-
-export async function importMuting(
-	job: Bull.Job<DbUserImportJobData>,
-	done: any,
-): Promise<void> {
-	logger.info(`Importing muting of ${job.data.user.id} ...`);
-
-	const user = await Users.findOneBy({ id: job.data.user.id });
-	if (user == null) {
-		done();
-		return;
-	}
-
-	const file = await DriveFiles.findOneBy({
-		id: job.data.fileId,
-	});
-	if (file == null) {
-		done();
-		return;
-	}
-
-	const csv = await downloadTextFile(file.url);
-
-	let linenum = 0;
-
-	for (const line of csv.trim().split("\n")) {
-		linenum++;
-
-		try {
-			const acct = line.split(",")[0].trim();
-			const { username, host } = Acct.parse(acct);
-
-			let target = isSelfHost(host!)
-				? await Users.findOneBy({
-						host: IsNull(),
-						usernameLower: username.toLowerCase(),
-				  })
-				: await Users.findOneBy({
-						host: toPuny(host!),
-						usernameLower: username.toLowerCase(),
-				  });
-
-			if (host == null && target == null) continue;
-
-			if (target == null) {
-				target = await resolveUser(username, host);
-			}
-
-			if (target == null) {
-				throw new Error(`cannot resolve user: @${username}@${host}`);
-			}
-
-			// skip myself
-			if (target.id === job.data.user.id) continue;
-
-			logger.info(`Mute[${linenum}] ${target.id} ...`);
-
-			await mute(user, target);
-		} catch (e) {
-			logger.warn(`Error in line:${linenum} ${e}`);
-		}
-	}
-
-	logger.succ("Imported");
-	done();
-}
-
-async function mute(user: User, target: User) {
-	await Mutings.insert({
-		id: genId(),
-		createdAt: new Date(),
-		muterId: user.id,
-		muteeId: target.id,
-	});
-}
diff --git a/packages/backend/src/queue/processors/db/import-posts.ts b/packages/backend/src/queue/processors/db/import-posts.ts
deleted file mode 100644
index 20ef3a518d..0000000000
--- a/packages/backend/src/queue/processors/db/import-posts.ts
+++ /dev/null
@@ -1,131 +0,0 @@
-import { IsNull } from "typeorm";
-import follow from "@/services/following/create.js";
-
-import * as Post from "@/misc/post.js";
-import create from "@/services/note/create.js";
-import { downloadTextFile } from "@/misc/download-text-file.js";
-import { Users, DriveFiles } from "@/models/index.js";
-import type { DbUserImportPostsJobData } from "@/queue/types.js";
-import { queueLogger } from "../../logger.js";
-import type Bull from "bull";
-import { htmlToMfm } from "@/remote/activitypub/misc/html-to-mfm.js";
-
-const logger = queueLogger.createSubLogger("import-posts");
-
-export async function importPosts(
-	job: Bull.Job<DbUserImportPostsJobData>,
-	done: any,
-): Promise<void> {
-	logger.info(`Importing posts of ${job.data.user.id} ...`);
-
-	const user = await Users.findOneBy({ id: job.data.user.id });
-	if (user == null) {
-		done();
-		return;
-	}
-
-	const file = await DriveFiles.findOneBy({
-		id: job.data.fileId,
-	});
-	if (file == null) {
-		done();
-		return;
-	}
-
-	const json = await downloadTextFile(file.url);
-
-	let linenum = 0;
-
-	try {
-		const parsed = JSON.parse(json);
-		if (parsed instanceof Array) {
-			logger.info("Parsing key style posts");
-			for (const post of JSON.parse(json)) {
-				try {
-					linenum++;
-					if (post.replyId != null) {
-						continue;
-					}
-					if (post.renoteId != null) {
-						continue;
-					}
-					if (post.visibility !== "public") {
-						continue;
-					}
-					const { text, cw, localOnly, createdAt } = Post.parse(post);
-
-					logger.info(`Posting[${linenum}] ...`);
-
-					const note = await create(user, {
-						createdAt: createdAt,
-						files: undefined,
-						poll: undefined,
-						text: text || undefined,
-						reply: null,
-						renote: null,
-						cw: cw,
-						localOnly,
-						visibility: "public",
-						visibleUsers: [],
-						channel: null,
-						apMentions: new Array(0),
-						apHashtags: undefined,
-						apEmojis: undefined,
-					});
-				} catch (e) {
-					logger.warn(`Error in line:${linenum} ${e}`);
-				}
-			}
-		} else if (parsed instanceof Object) {
-			logger.info("Parsing animal style posts");
-			for (const post of parsed.orderedItems) {
-				try {
-					linenum++;
-					if (post.object.inReplyTo != null) {
-						continue;
-					}
-					if (post.directMessage) {
-						continue;
-					}
-					if (job.data.signatureCheck) {
-						if (!post.signature) {
-							continue;
-						}
-					}
-					let text;
-					try {
-						text = htmlToMfm(post.object.content, post.object.tag);
-					} catch (e) {
-						continue;
-					}
-					logger.info(`Posting[${linenum}] ...`);
-
-					const note = await create(user, {
-						createdAt: new Date(post.object.published),
-						files: undefined,
-						poll: undefined,
-						text: text || undefined,
-						reply: null,
-						renote: null,
-						cw: post.sensitive,
-						localOnly: false,
-						visibility: "public",
-						visibleUsers: [],
-						channel: null,
-						apMentions: new Array(0),
-						apHashtags: undefined,
-						apEmojis: undefined,
-					});
-				} catch (e) {
-					logger.warn(`Error in line:${linenum} ${e}`);
-				}
-			}
-		}
-	} catch (e) {
-		// handle error
-		logger.warn(`Error reading: ${e}`);
-	}
-
-	logger.succ("Imported");
-	done();
-}
diff --git a/packages/backend/src/queue/processors/db/import-user-lists.ts b/packages/backend/src/queue/processors/db/import-user-lists.ts
deleted file mode 100644
index 0c23f06991..0000000000
--- a/packages/backend/src/queue/processors/db/import-user-lists.ts
+++ /dev/null
@@ -1,96 +0,0 @@
-import type Bull from "bull";
-
-import { queueLogger } from "../../logger.js";
-import * as Acct from "@/misc/acct.js";
-import { resolveUser } from "@/remote/resolve-user.js";
-import { pushUserToUserList } from "@/services/user-list/push.js";
-import { downloadTextFile } from "@/misc/download-text-file.js";
-import { isSelfHost, toPuny } from "@/misc/convert-host.js";
-import {
-	DriveFiles,
-	Users,
-	UserLists,
-	UserListJoinings,
-} from "@/models/index.js";
-import { genId } from "@/misc/gen-id.js";
-import type { DbUserImportJobData } from "@/queue/types.js";
-import { IsNull } from "typeorm";
-
-const logger = queueLogger.createSubLogger("import-user-lists");
-
-export async function importUserLists(
-	job: Bull.Job<DbUserImportJobData>,
-	done: any,
-): Promise<void> {
-	logger.info(`Importing user lists of ${job.data.user.id} ...`);
-
-	const user = await Users.findOneBy({ id: job.data.user.id });
-	if (user == null) {
-		done();
-		return;
-	}
-
-	const file = await DriveFiles.findOneBy({
-		id: job.data.fileId,
-	});
-	if (file == null) {
-		done();
-		return;
-	}
-
-	const csv = await downloadTextFile(file.url);
-
-	let linenum = 0;
-
-	for (const line of csv.trim().split("\n")) {
-		linenum++;
-
-		try {
-			const listName = line.split(",")[0].trim();
-			const { username, host } = Acct.parse(line.split(",")[1].trim());
-
-			let list = await UserLists.findOneBy({
-				userId: user.id,
-				name: listName,
-			});
-
-			if (list == null) {
-				list = await UserLists.insert({
-					id: genId(),
-					createdAt: new Date(),
-					userId: user.id,
-					name: listName,
-				}).then((x) => UserLists.findOneByOrFail(x.identifiers[0]));
-			}
-
-			let target = isSelfHost(host!)
-				? await Users.findOneBy({
-						host: IsNull(),
-						usernameLower: username.toLowerCase(),
-				  })
-				: await Users.findOneBy({
-						host: toPuny(host!),
-						usernameLower: username.toLowerCase(),
-				  });
-
-			if (target == null) {
-				target = await resolveUser(username, host);
-			}
-
-			if (
-				(await UserListJoinings.findOneBy({
-					userListId: list!.id,
-					userId: target.id,
-				})) != null
-			)
-				continue;
-
-			pushUserToUserList(target, list!);
-		} catch (e) {
-			logger.warn(`Error in line:${linenum} ${e}`);
-		}
-	}
-
-	logger.succ("Imported");
-	done();
-}
diff --git a/packages/backend/src/queue/processors/db/index.ts b/packages/backend/src/queue/processors/db/index.ts
deleted file mode 100644
index 22b55a3683..0000000000
--- a/packages/backend/src/queue/processors/db/index.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import type Bull from "bull";
-import type { DbJobData } from "@/queue/types.js";
-import { deleteDriveFiles } from "./delete-drive-files.js";
-import { exportCustomEmojis } from "./export-custom-emojis.js";
-import { exportNotes } from "./export-notes.js";
-import { exportFollowing } from "./export-following.js";
-import { exportMute } from "./export-mute.js";
-import { exportBlocking } from "./export-blocking.js";
-import { exportUserLists } from "./export-user-lists.js";
-import { importFollowing } from "./import-following.js";
-import { importUserLists } from "./import-user-lists.js";
-import { deleteAccount } from "./delete-account.js";
-import { importMuting } from "./import-muting.js";
-import { importPosts } from "./import-posts.js";
-import { importBlocking } from "./import-blocking.js";
-import { importCustomEmojis } from "./import-custom-emojis.js";
-
-const jobs = {
-	deleteDriveFiles,
-	exportCustomEmojis,
-	exportNotes,
-	exportFollowing,
-	exportMute,
-	exportBlocking,
-	exportUserLists,
-	importFollowing,
-	importMuting,
-	importBlocking,
-	importUserLists,
-	importPosts,
-	importCustomEmojis,
-	deleteAccount,
-} as Record<
-	string,
-	| Bull.ProcessCallbackFunction<DbJobData>
-	| Bull.ProcessPromiseFunction<DbJobData>
->;
-
-export default function (dbQueue: Bull.Queue<DbJobData>) {
-	for (const [k, v] of Object.entries(jobs)) {
-		dbQueue.process(k, v);
-	}
-}
diff --git a/packages/backend/src/queue/processors/deliver.ts b/packages/backend/src/queue/processors/deliver.ts
deleted file mode 100644
index 65471a559f..0000000000
--- a/packages/backend/src/queue/processors/deliver.ts
+++ /dev/null
@@ -1,81 +0,0 @@
-import { URL } from "node:url";
-import request from "@/remote/activitypub/request.js";
-import { registerOrFetchInstanceDoc } from "@/services/register-or-fetch-instance-doc.js";
-import Logger from "@/services/logger.js";
-import { Instances } from "@/models/index.js";
-import {
-	apRequestChart,
-	federationChart,
-	instanceChart,
-} from "@/services/chart/index.js";
-import { fetchInstanceMetadata } from "@/services/fetch-instance-metadata.js";
-import { toPuny } from "@/misc/convert-host.js";
-import { StatusError } from "@/misc/fetch.js";
-import { shouldSkipInstance } from "@/misc/skipped-instances.js";
-import type { DeliverJobData } from "@/queue/types.js";
-import type Bull from "bull";
-
-const logger = new Logger("deliver");
-
-let latest: string | null = null;
-
-export default async (job: Bull.Job<DeliverJobData>) => {
-	const { host } = new URL(job.data.to);
-	const puny = toPuny(host);
-
-	if (await shouldSkipInstance(puny)) return "skip";
-
-	try {
-		if (latest !== (latest = JSON.stringify(job.data.content, null, 2))) {
-			logger.debug(`delivering ${latest}`);
-		}
-
-		await request(job.data.user, job.data.to, job.data.content);
-
-		// Update stats
-		registerOrFetchInstanceDoc(host).then((i) => {
-			Instances.update(i.id, {
-				latestRequestSentAt: new Date(),
-				latestStatus: 200,
-				lastCommunicatedAt: new Date(),
-				isNotResponding: false,
-			});
-
-			fetchInstanceMetadata(i);
-
-			instanceChart.requestSent(i.host, true);
-			apRequestChart.deliverSucc();
-			federationChart.deliverd(i.host, true);
-		});
-
-		return "Success";
-	} catch (res) {
-		// Update stats
-		registerOrFetchInstanceDoc(host).then((i) => {
-			Instances.update(i.id, {
-				latestRequestSentAt: new Date(),
-				latestStatus: res instanceof StatusError ? res.statusCode : null,
-				isNotResponding: true,
-			});
-
-			instanceChart.requestSent(i.host, false);
-			apRequestChart.deliverFail();
-			federationChart.deliverd(i.host, false);
-		});
-
-		if (res instanceof StatusError) {
-			// 4xx
-			if (res.isClientError) {
-				// HTTPステータスコード4xxはクライアントエラーであり、それはつまり
-				// 何回再送しても成功することはないということなのでエラーにはしないでおく
-				return `${res.statusCode} ${res.statusMessage}`;
-			}
-
-			// 5xx etc.
-			throw new Error(`${res.statusCode} ${res.statusMessage}`);
-		} else {
-			// DNS error, socket error, timeout ...
-			throw res;
-		}
-	}
-};
diff --git a/packages/backend/src/queue/processors/ended-poll-notification.ts b/packages/backend/src/queue/processors/ended-poll-notification.ts
deleted file mode 100644
index 9fe57d8da3..0000000000
--- a/packages/backend/src/queue/processors/ended-poll-notification.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import type Bull from "bull";
-import { In } from "typeorm";
-import { Notes, Polls, PollVotes } from "@/models/index.js";
-import { queueLogger } from "../logger.js";
-import type { EndedPollNotificationJobData } from "@/queue/types.js";
-import { createNotification } from "@/services/create-notification.js";
-
-const logger = queueLogger.createSubLogger("ended-poll-notification");
-
-export async function endedPollNotification(
-	job: Bull.Job<EndedPollNotificationJobData>,
-	done: any,
-): Promise<void> {
-	const note = await Notes.findOneBy({ id: job.data.noteId });
-	if (note == null || !note.hasPoll) {
-		done();
-		return;
-	}
-
-	const votes = await PollVotes.createQueryBuilder("vote")
-		.select("vote.userId")
-		.where("vote.noteId = :noteId", { noteId: note.id })
-		.innerJoinAndSelect("vote.user", "user")
-		.andWhere("user.host IS NULL")
-		.getMany();
-
-	const userIds = [...new Set([note.userId, ...votes.map((v) => v.userId)])];
-
-	for (const userId of userIds) {
-		createNotification(userId, "pollEnded", {
-			noteId: note.id,
-		});
-	}
-
-	done();
-}
diff --git a/packages/backend/src/queue/processors/inbox.ts b/packages/backend/src/queue/processors/inbox.ts
deleted file mode 100644
index ca063a6f3f..0000000000
--- a/packages/backend/src/queue/processors/inbox.ts
+++ /dev/null
@@ -1,175 +0,0 @@
-import { URL } from "node:url";
-import type Bull from "bull";
-import httpSignature from "@peertube/http-signature";
-import perform from "@/remote/activitypub/perform.js";
-import Logger from "@/services/logger.js";
-import { registerOrFetchInstanceDoc } from "@/services/register-or-fetch-instance-doc.js";
-import { Instances } from "@/models/index.js";
-import {
-	apRequestChart,
-	federationChart,
-	instanceChart,
-} from "@/services/chart/index.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { toPuny, extractDbHost } from "@/misc/convert-host.js";
-import { getApId } from "@/remote/activitypub/type.js";
-import { fetchInstanceMetadata } from "@/services/fetch-instance-metadata.js";
-import type { InboxJobData } from "../types.js";
-import DbResolver from "@/remote/activitypub/db-resolver.js";
-import { resolvePerson } from "@/remote/activitypub/models/person.js";
-import { LdSignature } from "@/remote/activitypub/misc/ld-signature.js";
-import { StatusError } from "@/misc/fetch.js";
-import type { CacheableRemoteUser } from "@/models/entities/user.js";
-import type { UserPublickey } from "@/models/entities/user-publickey.js";
-import { shouldBlockInstance } from "@/misc/should-block-instance.js";
-
-const logger = new Logger("inbox");
-
-// Processing when an activity arrives in the user's inbox
-export default async (job: Bull.Job<InboxJobData>): Promise<string> => {
-	const signature = job.data.signature; // HTTP-signature
-	const activity = job.data.activity;
-
-	//#region Log
-	const info = Object.assign({}, activity) as any;
-	info["@context"] = undefined;
-	logger.debug(JSON.stringify(info, null, 2));
-	//#endregion
-	const host = toPuny(new URL(signature.keyId).hostname);
-
-	// interrupt if blocked
-	const meta = await fetchMeta();
-	if (await shouldBlockInstance(host, meta)) {
-		return `Blocked request: ${host}`;
-	}
-
-	// only whitelisted instances in private mode
-	if (meta.privateMode && !meta.allowedHosts.includes(host)) {
-		return `Blocked request: ${host}`;
-	}
-
-	const keyIdLower = signature.keyId.toLowerCase();
-	if (keyIdLower.startsWith("acct:")) {
-		return `Old keyId is no longer supported. ${keyIdLower}`;
-	}
-
-	const dbResolver = new DbResolver();
-
-	// HTTP-Signature keyId from DB
-	let authUser: {
-		user: CacheableRemoteUser;
-		key: UserPublickey | null;
-	} | null = await dbResolver.getAuthUserFromKeyId(signature.keyId);
-
-	// keyIdでわからなければ、activity.actorを元にDBから取得 || activity.actorを元にリモートから取得
-	if (authUser == null) {
-		try {
-			authUser = await dbResolver.getAuthUserFromApId(getApId(activity.actor));
-		} catch (e) {
-			// Skip if target is 4xx
-			if (e instanceof StatusError) {
-				if (e.isClientError) {
-					return `skip: Ignored deleted actors on both ends ${activity.actor} - ${e.statusCode}`;
-				}
-				throw new Error(
-					`Error in actor ${activity.actor} - ${e.statusCode || e}`,
-				);
-			}
-		}
-	}
-
-	// それでもわからなければ終了
-	if (authUser == null) {
-		return "skip: failed to resolve user";
-	}
-
-	// publicKey がなくても終了
-	if (authUser.key == null) {
-		return "skip: failed to resolve user publicKey";
-	}
-
-	// HTTP-Signatureの検証
-	const httpSignatureValidated = httpSignature.verifySignature(
-		signature,
-		authUser.key.keyPem,
-	);
-
-	// また、signatureのsignerは、activity.actorと一致する必要がある
-	if (!httpSignatureValidated || authUser.user.uri !== activity.actor) {
-		// 一致しなくても、でもLD-Signatureがありそうならそっちも見る
-		if (activity.signature) {
-			if (activity.signature.type !== "RsaSignature2017") {
-				return `skip: unsupported LD-signature type ${activity.signature.type}`;
-			}
-
-			// activity.signature.creator: https://example.oom/users/user#main-key
-			// みたいになっててUserを引っ張れば公開キーも入ることを期待する
-			if (activity.signature.creator) {
-				const candicate = activity.signature.creator.replace(/#.*/, "");
-				await resolvePerson(candicate).catch(() => null);
-			}
-
-			// keyIdからLD-Signatureのユーザーを取得
-			authUser = await dbResolver.getAuthUserFromKeyId(
-				activity.signature.creator,
-			);
-			if (authUser == null) {
-				return "skip: LD-Signatureのユーザーが取得できませんでした";
-			}
-
-			if (authUser.key == null) {
-				return "skip: LD-SignatureのユーザーはpublicKeyを持っていませんでした";
-			}
-
-			// LD-Signature検証
-			const ldSignature = new LdSignature();
-			const verified = await ldSignature
-				.verifyRsaSignature2017(activity, authUser.key.keyPem)
-				.catch(() => false);
-			if (!verified) {
-				return "skip: LD-Signatureの検証に失敗しました";
-			}
-
-			// もう一度actorチェック
-			if (authUser.user.uri !== activity.actor) {
-				return `skip: LD-Signature user(${authUser.user.uri}) !== activity.actor(${activity.actor})`;
-			}
-
-			// ブロックしてたら中断
-			const ldHost = extractDbHost(authUser.user.uri);
-			if (await shouldBlockInstance(ldHost, meta)) {
-				return `Blocked request: ${ldHost}`;
-			}
-		} else {
-			return `skip: http-signature verification failed and no LD-Signature. keyId=${signature.keyId}`;
-		}
-	}
-
-	// activity.idがあればホストが署名者のホストであることを確認する
-	if (typeof activity.id === "string") {
-		const signerHost = extractDbHost(authUser.user.uri!);
-		const activityIdHost = extractDbHost(activity.id);
-		if (signerHost !== activityIdHost) {
-			return `skip: signerHost(${signerHost}) !== activity.id host(${activityIdHost}`;
-		}
-	}
-
-	// Update stats
-	registerOrFetchInstanceDoc(authUser.user.host).then((i) => {
-		Instances.update(i.id, {
-			latestRequestReceivedAt: new Date(),
-			lastCommunicatedAt: new Date(),
-			isNotResponding: false,
-		});
-
-		fetchInstanceMetadata(i);
-
-		instanceChart.requestReceived(i.host);
-		apRequestChart.inbox();
-		federationChart.inbox(i.host);
-	});
-
-	// アクティビティを処理
-	await perform(authUser.user, activity);
-	return "ok";
-};
diff --git a/packages/backend/src/queue/processors/object-storage/clean-remote-files.ts b/packages/backend/src/queue/processors/object-storage/clean-remote-files.ts
deleted file mode 100644
index fdfe05d1a6..0000000000
--- a/packages/backend/src/queue/processors/object-storage/clean-remote-files.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-import type Bull from "bull";
-
-import { queueLogger } from "../../logger.js";
-import { deleteFileSync } from "@/services/drive/delete-file.js";
-import { DriveFiles } from "@/models/index.js";
-import { MoreThan, Not, IsNull } from "typeorm";
-
-const logger = queueLogger.createSubLogger("clean-remote-files");
-
-export default async function cleanRemoteFiles(
-	job: Bull.Job<Record<string, unknown>>,
-	done: any,
-): Promise<void> {
-	logger.info("Deleting cached remote files...");
-
-	let deletedCount = 0;
-	let cursor: any = null;
-
-	while (true) {
-		const files = await DriveFiles.find({
-			where: {
-				userHost: Not(IsNull()),
-				isLink: false,
-				...(cursor ? { id: MoreThan(cursor) } : {}),
-			},
-			take: 8,
-			order: {
-				id: 1,
-			},
-		});
-
-		if (files.length === 0) {
-			job.progress(100);
-			break;
-		}
-
-		cursor = files[files.length - 1].id;
-
-		await Promise.all(files.map((file) => deleteFileSync(file, true)));
-
-		deletedCount += 8;
-
-		const total = await DriveFiles.countBy({
-			userHost: Not(IsNull()),
-			isLink: false,
-		});
-
-		job.progress(deletedCount / total);
-	}
-
-	logger.succ("All cahced remote files has been deleted.");
-	done();
-}
diff --git a/packages/backend/src/queue/processors/object-storage/delete-file.ts b/packages/backend/src/queue/processors/object-storage/delete-file.ts
deleted file mode 100644
index 174aa1906c..0000000000
--- a/packages/backend/src/queue/processors/object-storage/delete-file.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import type { ObjectStorageFileJobData } from "@/queue/types.js";
-import type Bull from "bull";
-import { deleteObjectStorageFile } from "@/services/drive/delete-file.js";
-
-export default async (job: Bull.Job<ObjectStorageFileJobData>) => {
-	const key: string = job.data.key;
-
-	await deleteObjectStorageFile(key);
-
-	return "Success";
-};
diff --git a/packages/backend/src/queue/processors/object-storage/index.ts b/packages/backend/src/queue/processors/object-storage/index.ts
deleted file mode 100644
index 5f90d4cd09..0000000000
--- a/packages/backend/src/queue/processors/object-storage/index.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import type Bull from "bull";
-import type { ObjectStorageJobData } from "@/queue/types.js";
-import deleteFile from "./delete-file.js";
-import cleanRemoteFiles from "./clean-remote-files.js";
-
-const jobs = {
-	deleteFile,
-	cleanRemoteFiles,
-} as Record<
-	string,
-	| Bull.ProcessCallbackFunction<ObjectStorageJobData>
-	| Bull.ProcessPromiseFunction<ObjectStorageJobData>
->;
-
-export default function (q: Bull.Queue) {
-	for (const [k, v] of Object.entries(jobs)) {
-		q.process(k, 16, v);
-	}
-}
diff --git a/packages/backend/src/queue/processors/system/check-expired-mutings.ts b/packages/backend/src/queue/processors/system/check-expired-mutings.ts
deleted file mode 100644
index a482d0218a..0000000000
--- a/packages/backend/src/queue/processors/system/check-expired-mutings.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import type Bull from "bull";
-import { In } from "typeorm";
-import { Mutings } from "@/models/index.js";
-import { queueLogger } from "../../logger.js";
-import { publishUserEvent } from "@/services/stream.js";
-
-const logger = queueLogger.createSubLogger("check-expired-mutings");
-
-export async function checkExpiredMutings(
-	job: Bull.Job<Record<string, unknown>>,
-	done: any,
-): Promise<void> {
-	logger.info("Checking expired mutings...");
-
-	const expired = await Mutings.createQueryBuilder("muting")
-		.where("muting.expiresAt IS NOT NULL")
-		.andWhere("muting.expiresAt < :now", { now: new Date() })
-		.innerJoinAndSelect("muting.mutee", "mutee")
-		.getMany();
-
-	if (expired.length > 0) {
-		await Mutings.delete({
-			id: In(expired.map((m) => m.id)),
-		});
-
-		for (const m of expired) {
-			publishUserEvent(m.muterId, "unmute", m.mutee!);
-		}
-	}
-
-	logger.succ("All expired mutings checked.");
-	done();
-}
diff --git a/packages/backend/src/queue/processors/system/clean-charts.ts b/packages/backend/src/queue/processors/system/clean-charts.ts
deleted file mode 100644
index dde5d95fe3..0000000000
--- a/packages/backend/src/queue/processors/system/clean-charts.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import type Bull from "bull";
-
-import { queueLogger } from "../../logger.js";
-import {
-	activeUsersChart,
-	driveChart,
-	federationChart,
-	hashtagChart,
-	instanceChart,
-	notesChart,
-	perUserDriveChart,
-	perUserFollowingChart,
-	perUserNotesChart,
-	perUserReactionsChart,
-	usersChart,
-	apRequestChart,
-} from "@/services/chart/index.js";
-
-const logger = queueLogger.createSubLogger("clean-charts");
-
-export async function cleanCharts(
-	job: Bull.Job<Record<string, unknown>>,
-	done: any,
-): Promise<void> {
-	logger.info("Clean charts...");
-
-	await Promise.all([
-		federationChart.clean(),
-		notesChart.clean(),
-		usersChart.clean(),
-		activeUsersChart.clean(),
-		instanceChart.clean(),
-		perUserNotesChart.clean(),
-		driveChart.clean(),
-		perUserReactionsChart.clean(),
-		hashtagChart.clean(),
-		perUserFollowingChart.clean(),
-		perUserDriveChart.clean(),
-		apRequestChart.clean(),
-	]);
-
-	logger.succ("All charts successfully cleaned.");
-	done();
-}
diff --git a/packages/backend/src/queue/processors/system/clean.ts b/packages/backend/src/queue/processors/system/clean.ts
deleted file mode 100644
index fbd45b0bb9..0000000000
--- a/packages/backend/src/queue/processors/system/clean.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import type Bull from "bull";
-import { LessThan } from "typeorm";
-import { UserIps } from "@/models/index.js";
-
-import { queueLogger } from "../../logger.js";
-
-const logger = queueLogger.createSubLogger("clean");
-
-export async function clean(
-	job: Bull.Job<Record<string, unknown>>,
-	done: any,
-): Promise<void> {
-	logger.info("Cleaning...");
-
-	UserIps.delete({
-		createdAt: LessThan(new Date(Date.now() - 1000 * 60 * 60 * 24 * 90)),
-	});
-
-	logger.succ("Cleaned.");
-	done();
-}
diff --git a/packages/backend/src/queue/processors/system/index.ts b/packages/backend/src/queue/processors/system/index.ts
deleted file mode 100644
index 68833d76f4..0000000000
--- a/packages/backend/src/queue/processors/system/index.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import type Bull from "bull";
-import { tickCharts } from "./tick-charts.js";
-import { resyncCharts } from "./resync-charts.js";
-import { cleanCharts } from "./clean-charts.js";
-import { checkExpiredMutings } from "./check-expired-mutings.js";
-import { clean } from "./clean.js";
-
-const jobs = {
-	tickCharts,
-	resyncCharts,
-	cleanCharts,
-	checkExpiredMutings,
-	clean,
-} as Record<
-	string,
-	| Bull.ProcessCallbackFunction<Record<string, unknown>>
-	| Bull.ProcessPromiseFunction<Record<string, unknown>>
->;
-
-export default function (dbQueue: Bull.Queue<Record<string, unknown>>) {
-	for (const [k, v] of Object.entries(jobs)) {
-		dbQueue.process(k, v);
-	}
-}
diff --git a/packages/backend/src/queue/processors/system/resync-charts.ts b/packages/backend/src/queue/processors/system/resync-charts.ts
deleted file mode 100644
index dbea0df733..0000000000
--- a/packages/backend/src/queue/processors/system/resync-charts.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import type Bull from "bull";
-
-import { queueLogger } from "../../logger.js";
-import { driveChart, notesChart, usersChart } from "@/services/chart/index.js";
-
-const logger = queueLogger.createSubLogger("resync-charts");
-
-export async function resyncCharts(
-	job: Bull.Job<Record<string, unknown>>,
-	done: any,
-): Promise<void> {
-	logger.info("Resync charts...");
-
-	// TODO: ユーザーごとのチャートも更新する
-	// TODO: インスタンスごとのチャートも更新する
-	await Promise.all([
-		driveChart.resync(),
-		notesChart.resync(),
-		usersChart.resync(),
-	]);
-
-	logger.succ("All charts successfully resynced.");
-	done();
-}
diff --git a/packages/backend/src/queue/processors/system/tick-charts.ts b/packages/backend/src/queue/processors/system/tick-charts.ts
deleted file mode 100644
index 33eed8a596..0000000000
--- a/packages/backend/src/queue/processors/system/tick-charts.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import type Bull from "bull";
-
-import { queueLogger } from "../../logger.js";
-import {
-	activeUsersChart,
-	driveChart,
-	federationChart,
-	hashtagChart,
-	instanceChart,
-	notesChart,
-	perUserDriveChart,
-	perUserFollowingChart,
-	perUserNotesChart,
-	perUserReactionsChart,
-	usersChart,
-	apRequestChart,
-} from "@/services/chart/index.js";
-
-const logger = queueLogger.createSubLogger("tick-charts");
-
-export async function tickCharts(
-	job: Bull.Job<Record<string, unknown>>,
-	done: any,
-): Promise<void> {
-	logger.info("Tick charts...");
-
-	await Promise.all([
-		federationChart.tick(false),
-		notesChart.tick(false),
-		usersChart.tick(false),
-		activeUsersChart.tick(false),
-		instanceChart.tick(false),
-		perUserNotesChart.tick(false),
-		driveChart.tick(false),
-		perUserReactionsChart.tick(false),
-		hashtagChart.tick(false),
-		perUserFollowingChart.tick(false),
-		perUserDriveChart.tick(false),
-		apRequestChart.tick(false),
-	]);
-
-	logger.succ("All charts successfully ticked.");
-	done();
-}
diff --git a/packages/backend/src/queue/processors/webhook-deliver.ts b/packages/backend/src/queue/processors/webhook-deliver.ts
deleted file mode 100644
index 0a54ae7d89..0000000000
--- a/packages/backend/src/queue/processors/webhook-deliver.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-import { URL } from "node:url";
-import type Bull from "bull";
-import Logger from "@/services/logger.js";
-import type { WebhookDeliverJobData } from "../types.js";
-import { getResponse, StatusError } from "@/misc/fetch.js";
-import { Webhooks } from "@/models/index.js";
-import config from "@/config/index.js";
-
-const logger = new Logger("webhook");
-
-export default async (job: Bull.Job<WebhookDeliverJobData>) => {
-	try {
-		logger.debug(`delivering ${job.data.webhookId}`);
-
-		const res = await getResponse({
-			url: job.data.to,
-			method: "POST",
-			headers: {
-				"User-Agent": "Calckey-Hooks",
-				"X-Calckey-Host": config.host,
-				"X-Calckey-Hook-Id": job.data.webhookId,
-				"X-Calckey-Hook-Secret": job.data.secret,
-				"Content-Type": "application/json",
-			},
-			body: JSON.stringify({
-				hookId: job.data.webhookId,
-				userId: job.data.userId,
-				eventId: job.data.eventId,
-				createdAt: job.data.createdAt,
-				type: job.data.type,
-				body: job.data.content,
-			}),
-		});
-
-		Webhooks.update(
-			{ id: job.data.webhookId },
-			{
-				latestSentAt: new Date(),
-				latestStatus: res.status,
-			},
-		);
-
-		return "Success";
-	} catch (res) {
-		Webhooks.update(
-			{ id: job.data.webhookId },
-			{
-				latestSentAt: new Date(),
-				latestStatus: res instanceof StatusError ? res.statusCode : 1,
-			},
-		);
-
-		if (res instanceof StatusError) {
-			// 4xx
-			if (res.isClientError) {
-				return `${res.statusCode} ${res.statusMessage}`;
-			}
-
-			// 5xx etc.
-			throw new Error(`${res.statusCode} ${res.statusMessage}`);
-		} else {
-			// DNS error, socket error, timeout ...
-			throw res;
-		}
-	}
-};
diff --git a/packages/backend/src/queue/queues.ts b/packages/backend/src/queue/queues.ts
deleted file mode 100644
index 6d7fffcb30..0000000000
--- a/packages/backend/src/queue/queues.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import config from "@/config/index.js";
-import { initialize as initializeQueue } from "./initialize.js";
-import type {
-	DeliverJobData,
-	InboxJobData,
-	DbJobData,
-	ObjectStorageJobData,
-	EndedPollNotificationJobData,
-	WebhookDeliverJobData,
-} from "./types.js";
-
-export const systemQueue = initializeQueue<Record<string, unknown>>("system");
-export const endedPollNotificationQueue =
-	initializeQueue<EndedPollNotificationJobData>("endedPollNotification");
-export const deliverQueue = initializeQueue<DeliverJobData>(
-	"deliver",
-	config.deliverJobPerSec || 128,
-);
-export const inboxQueue = initializeQueue<InboxJobData>(
-	"inbox",
-	config.inboxJobPerSec || 16,
-);
-export const dbQueue = initializeQueue<DbJobData>("db");
-export const objectStorageQueue =
-	initializeQueue<ObjectStorageJobData>("objectStorage");
-export const webhookDeliverQueue = initializeQueue<WebhookDeliverJobData>(
-	"webhookDeliver",
-	64,
-);
-export const backgroundQueue = initializeQueue<Record<string, unknown>>("bg");
-
-export const queues = [
-	systemQueue,
-	endedPollNotificationQueue,
-	deliverQueue,
-	inboxQueue,
-	dbQueue,
-	objectStorageQueue,
-	webhookDeliverQueue,
-	backgroundQueue,
-];
diff --git a/packages/backend/src/queue/types.ts b/packages/backend/src/queue/types.ts
deleted file mode 100644
index e31619ff27..0000000000
--- a/packages/backend/src/queue/types.ts
+++ /dev/null
@@ -1,75 +0,0 @@
-import type { DriveFile } from "@/models/entities/drive-file.js";
-import type { Note } from "@/models/entities/note";
-import type { User } from "@/models/entities/user.js";
-import type { Webhook } from "@/models/entities/webhook";
-import type { IActivity } from "@/remote/activitypub/type.js";
-import type httpSignature from "@peertube/http-signature";
-
-export type DeliverJobData = {
-	/** Actor */
-	user: ThinUser;
-	/** Activity */
-	content: unknown;
-	/** inbox URL to deliver */
-	to: string;
-};
-
-export type InboxJobData = {
-	activity: IActivity;
-	signature: httpSignature.IParsedSignature;
-};
-
-export type DbJobData =
-	| DbUserJobData
-	| DbUserImportPostsJobData
-	| DbUserImportJobData
-	| DbUserDeleteJobData;
-
-export type DbUserJobData = {
-	user: ThinUser;
-	excludeMuting: boolean;
-	excludeInactive: boolean;
-};
-
-export type DbUserDeleteJobData = {
-	user: ThinUser;
-	soft?: boolean;
-};
-
-export type DbUserImportJobData = {
-	user: ThinUser;
-	fileId: DriveFile["id"];
-};
-
-export type DbUserImportPostsJobData = {
-	user: ThinUser;
-	fileId: DriveFile["id"];
-	signatureCheck: boolean;
-};
-
-export type ObjectStorageJobData =
-	| ObjectStorageFileJobData
-	| Record<string, unknown>;
-
-export type ObjectStorageFileJobData = {
-	key: string;
-};
-
-export type EndedPollNotificationJobData = {
-	noteId: Note["id"];
-};
-
-export type WebhookDeliverJobData = {
-	type: string;
-	content: unknown;
-	webhookId: Webhook["id"];
-	userId: User["id"];
-	to: string;
-	secret: string;
-	createdAt: number;
-	eventId: string;
-};
-
-export type ThinUser = {
-	id: User["id"];
-};
diff --git a/packages/backend/src/remote/activitypub/ap-request.ts b/packages/backend/src/remote/activitypub/ap-request.ts
deleted file mode 100644
index d5a9ec0539..0000000000
--- a/packages/backend/src/remote/activitypub/ap-request.ts
+++ /dev/null
@@ -1,152 +0,0 @@
-import * as crypto from "node:crypto";
-import { URL } from "node:url";
-
-type Request = {
-	url: string;
-	method: string;
-	headers: Record<string, string>;
-};
-
-type PrivateKey = {
-	privateKeyPem: string;
-	keyId: string;
-};
-
-export function createSignedPost(args: {
-	key: PrivateKey;
-	url: string;
-	body: string;
-	additionalHeaders: Record<string, string>;
-}) {
-	const u = new URL(args.url);
-	const digestHeader = `SHA-256=${crypto
-		.createHash("sha256")
-		.update(args.body)
-		.digest("base64")}`;
-
-	const request: Request = {
-		url: u.href,
-		method: "POST",
-		headers: objectAssignWithLcKey(
-			{
-				Date: new Date().toUTCString(),
-				Host: u.hostname,
-				"Content-Type": "application/activity+json",
-				Digest: digestHeader,
-			},
-			args.additionalHeaders,
-		),
-	};
-
-	const result = signToRequest(request, args.key, [
-		"(request-target)",
-		"date",
-		"host",
-		"digest",
-	]);
-
-	return {
-		request,
-		signingString: result.signingString,
-		signature: result.signature,
-		signatureHeader: result.signatureHeader,
-	};
-}
-
-export function createSignedGet(args: {
-	key: PrivateKey;
-	url: string;
-	additionalHeaders: Record<string, string>;
-}) {
-	const u = new URL(args.url);
-
-	const request: Request = {
-		url: u.href,
-		method: "GET",
-		headers: objectAssignWithLcKey(
-			{
-				Accept: "application/activity+json, application/ld+json",
-				Date: new Date().toUTCString(),
-				Host: new URL(args.url).hostname,
-			},
-			args.additionalHeaders,
-		),
-	};
-
-	const result = signToRequest(request, args.key, [
-		"(request-target)",
-		"date",
-		"host",
-		"accept",
-	]);
-
-	return {
-		request,
-		signingString: result.signingString,
-		signature: result.signature,
-		signatureHeader: result.signatureHeader,
-	};
-}
-
-function signToRequest(
-	request: Request,
-	key: PrivateKey,
-	includeHeaders: string[],
-) {
-	const signingString = genSigningString(request, includeHeaders);
-	const signature = crypto
-		.sign("sha256", Buffer.from(signingString), key.privateKeyPem)
-		.toString("base64");
-	const signatureHeader = `keyId="${
-		key.keyId
-	}",algorithm="rsa-sha256",headers="${includeHeaders.join(
-		" ",
-	)}",signature="${signature}"`;
-
-	request.headers = objectAssignWithLcKey(request.headers, {
-		Signature: signatureHeader,
-	});
-
-	return {
-		request,
-		signingString,
-		signature,
-		signatureHeader,
-	};
-}
-
-function genSigningString(request: Request, includeHeaders: string[]) {
-	request.headers = lcObjectKey(request.headers);
-
-	const results: string[] = [];
-
-	for (const key of includeHeaders.map((x) => x.toLowerCase())) {
-		if (key === "(request-target)") {
-			results.push(
-				`(request-target): ${request.method.toLowerCase()} ${
-					new URL(request.url).pathname
-				}`,
-			);
-		} else {
-			results.push(`${key}: ${request.headers[key]}`);
-		}
-	}
-
-	return results.join("\n");
-}
-
-function lcObjectKey(src: Record<string, string>) {
-	const dst: Record<string, string> = {};
-	for (const key of Object.keys(src).filter(
-		(x) => x !== "__proto__" && typeof src[x] === "string",
-	))
-		dst[key.toLowerCase()] = src[key];
-	return dst;
-}
-
-function objectAssignWithLcKey(
-	a: Record<string, string>,
-	b: Record<string, string>,
-) {
-	return Object.assign(lcObjectKey(a), lcObjectKey(b));
-}
diff --git a/packages/backend/src/remote/activitypub/audience.ts b/packages/backend/src/remote/activitypub/audience.ts
deleted file mode 100644
index 210d47573c..0000000000
--- a/packages/backend/src/remote/activitypub/audience.ts
+++ /dev/null
@@ -1,104 +0,0 @@
-import type { ApObject } from "./type.js";
-import { getApIds } from "./type.js";
-import type Resolver from "./resolver.js";
-import { resolvePerson } from "./models/person.js";
-import { unique, concat } from "@/prelude/array.js";
-import promiseLimit from "promise-limit";
-import type {
-	CacheableRemoteUser,
-	CacheableUser,
-} from "@/models/entities/user.js";
-import { User } from "@/models/entities/user.js";
-
-type Visibility = "public" | "home" | "followers" | "specified";
-
-type AudienceInfo = {
-	visibility: Visibility;
-	mentionedUsers: CacheableUser[];
-	visibleUsers: CacheableUser[];
-};
-
-export async function parseAudience(
-	actor: CacheableRemoteUser,
-	to?: ApObject,
-	cc?: ApObject,
-	resolver?: Resolver,
-): Promise<AudienceInfo> {
-	const toGroups = groupingAudience(getApIds(to), actor);
-	const ccGroups = groupingAudience(getApIds(cc), actor);
-
-	const others = unique(concat([toGroups.other, ccGroups.other]));
-
-	const limit = promiseLimit<CacheableUser | null>(2);
-	const mentionedUsers = (
-		await Promise.all(
-			others.map((id) =>
-				limit(() => resolvePerson(id, resolver).catch(() => null)),
-			),
-		)
-	).filter((x): x is CacheableUser => x != null);
-
-	if (toGroups.public.length > 0) {
-		return {
-			visibility: "public",
-			mentionedUsers,
-			visibleUsers: [],
-		};
-	}
-
-	if (ccGroups.public.length > 0) {
-		return {
-			visibility: "home",
-			mentionedUsers,
-			visibleUsers: [],
-		};
-	}
-
-	if (toGroups.followers.length > 0) {
-		return {
-			visibility: "followers",
-			mentionedUsers,
-			visibleUsers: [],
-		};
-	}
-
-	return {
-		visibility: "specified",
-		mentionedUsers,
-		visibleUsers: mentionedUsers,
-	};
-}
-
-function groupingAudience(ids: string[], actor: CacheableRemoteUser) {
-	const groups = {
-		public: [] as string[],
-		followers: [] as string[],
-		other: [] as string[],
-	};
-
-	for (const id of ids) {
-		if (isPublic(id)) {
-			groups.public.push(id);
-		} else if (isFollowers(id, actor)) {
-			groups.followers.push(id);
-		} else {
-			groups.other.push(id);
-		}
-	}
-
-	groups.other = unique(groups.other);
-
-	return groups;
-}
-
-function isPublic(id: string) {
-	return [
-		"https://www.w3.org/ns/activitystreams#Public",
-		"as#Public",
-		"Public",
-	].includes(id);
-}
-
-function isFollowers(id: string, actor: CacheableRemoteUser) {
-	return id === (actor.followersUri || `${actor.uri}/followers`);
-}
diff --git a/packages/backend/src/remote/activitypub/check-fetch.ts b/packages/backend/src/remote/activitypub/check-fetch.ts
deleted file mode 100644
index a8bbe61b84..0000000000
--- a/packages/backend/src/remote/activitypub/check-fetch.ts
+++ /dev/null
@@ -1,97 +0,0 @@
-import { URL } from "url";
-import httpSignature from "@peertube/http-signature";
-import config from "@/config/index.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { toPuny } from "@/misc/convert-host.js";
-import DbResolver from "@/remote/activitypub/db-resolver.js";
-import { getApId } from "@/remote/activitypub/type.js";
-import { shouldBlockInstance } from "@/misc/should-block-instance.js";
-import type { IncomingMessage } from "http";
-
-export async function hasSignature(req: IncomingMessage): Promise<string> {
-	const meta = await fetchMeta();
-	const required = meta.secureMode || meta.privateMode;
-
-	try {
-		httpSignature.parseRequest(req, { headers: [] });
-	} catch (e) {
-		if (e instanceof Error && e.name === "MissingHeaderError") {
-			return required ? "missing" : "optional";
-		}
-		return "invalid";
-	}
-	return required ? "supplied" : "unneeded";
-}
-
-export async function checkFetch(req: IncomingMessage): Promise<number> {
-	const meta = await fetchMeta();
-	if (meta.secureMode || meta.privateMode) {
-		let signature;
-
-		try {
-			signature = httpSignature.parseRequest(req, { headers: [] });
-		} catch (e) {
-			return 401;
-		}
-
-		const keyId = new URL(signature.keyId);
-		const host = toPuny(keyId.hostname);
-
-		if (await shouldBlockInstance(host, meta)) {
-			return 403;
-		}
-
-		if (
-			meta.privateMode &&
-			host !== config.host &&
-			!meta.allowedHosts.includes(host)
-		) {
-			return 403;
-		}
-
-		const keyIdLower = signature.keyId.toLowerCase();
-		if (keyIdLower.startsWith("acct:")) {
-			// Old keyId is no longer supported.
-			return 401;
-		}
-
-		const dbResolver = new DbResolver();
-
-		// HTTP-Signature keyIdを元にDBから取得
-		let authUser = await dbResolver.getAuthUserFromKeyId(signature.keyId);
-
-		// keyIdでわからなければ、resolveしてみる
-		if (authUser == null) {
-			try {
-				keyId.hash = "";
-				authUser = await dbResolver.getAuthUserFromApId(
-					getApId(keyId.toString()),
-				);
-			} catch (e) {
-				// できなければ駄目
-				return 403;
-			}
-		}
-
-		// publicKey がなくても終了
-		if (authUser?.key == null) {
-			return 403;
-		}
-
-		// もう一回チェック
-		if (authUser.user.host !== host) {
-			return 403;
-		}
-
-		// HTTP-Signatureの検証
-		const httpSignatureValidated = httpSignature.verifySignature(
-			signature,
-			authUser.key.keyPem,
-		);
-
-		if (!httpSignatureValidated) {
-			return 403;
-		}
-	}
-	return 200;
-}
diff --git a/packages/backend/src/remote/activitypub/db-resolver.ts b/packages/backend/src/remote/activitypub/db-resolver.ts
deleted file mode 100644
index 0a2aec9e85..0000000000
--- a/packages/backend/src/remote/activitypub/db-resolver.ts
+++ /dev/null
@@ -1,189 +0,0 @@
-import escapeRegexp from "escape-regexp";
-import config from "@/config/index.js";
-import type { Note } from "@/models/entities/note.js";
-import type {
-	CacheableRemoteUser,
-	CacheableUser,
-} from "@/models/entities/user.js";
-import { User, IRemoteUser } from "@/models/entities/user.js";
-import type { UserPublickey } from "@/models/entities/user-publickey.js";
-import type { MessagingMessage } from "@/models/entities/messaging-message.js";
-import {
-	Notes,
-	Users,
-	UserPublickeys,
-	MessagingMessages,
-} from "@/models/index.js";
-import { Cache } from "@/misc/cache.js";
-import { uriPersonCache, userByIdCache } from "@/services/user-cache.js";
-import type { IObject } from "./type.js";
-import { getApId } from "./type.js";
-import { resolvePerson } from "./models/person.js";
-
-const publicKeyCache = new Cache<UserPublickey | null>(Infinity);
-const publicKeyByUserIdCache = new Cache<UserPublickey | null>(Infinity);
-
-export type UriParseResult =
-	| {
-			/** wether the URI was generated by us */
-			local: true;
-			/** id in DB */
-			id: string;
-			/** hint of type, e.g. "notes", "users" */
-			type: string;
-			/** any remaining text after type and id, not including the slash after id. undefined if empty */
-			rest?: string;
-	  }
-	| {
-			/** wether the URI was generated by us */
-			local: false;
-			/** uri in DB */
-			uri: string;
-	  };
-
-export function parseUri(value: string | IObject): UriParseResult {
-	const uri = getApId(value);
-
-	// the host part of a URL is case insensitive, so use the 'i' flag.
-	const localRegex = new RegExp(
-		`^${escapeRegexp(config.url)}/(\\w+)/(\\w+)(?:/(.+))?`,
-		"i",
-	);
-	const matchLocal = uri.match(localRegex);
-
-	if (matchLocal) {
-		return {
-			local: true,
-			type: matchLocal[1],
-			id: matchLocal[2],
-			rest: matchLocal[3],
-		};
-	} else {
-		return {
-			local: false,
-			uri,
-		};
-	}
-}
-
-export default class DbResolver {
-	constructor() {}
-
-	/**
-	 * AP Note => Misskey Note in DB
-	 */
-	public async getNoteFromApId(value: string | IObject): Promise<Note | null> {
-		const parsed = parseUri(value);
-
-		if (parsed.local) {
-			if (parsed.type !== "notes") return null;
-
-			return await Notes.findOneBy({
-				id: parsed.id,
-			});
-		} else {
-			return await Notes.findOneBy({
-				uri: parsed.uri,
-			});
-		}
-	}
-
-	public async getMessageFromApId(
-		value: string | IObject,
-	): Promise<MessagingMessage | null> {
-		const parsed = parseUri(value);
-
-		if (parsed.local) {
-			if (parsed.type !== "notes") return null;
-
-			return await MessagingMessages.findOneBy({
-				id: parsed.id,
-			});
-		} else {
-			return await MessagingMessages.findOneBy({
-				uri: parsed.uri,
-			});
-		}
-	}
-
-	/**
-	 * AP Person => Misskey User in DB
-	 */
-	public async getUserFromApId(
-		value: string | IObject,
-	): Promise<CacheableUser | null> {
-		const parsed = parseUri(value);
-
-		if (parsed.local) {
-			if (parsed.type !== "users") return null;
-
-			return (
-				(await userByIdCache.fetchMaybe(parsed.id, () =>
-					Users.findOneBy({
-						id: parsed.id,
-					}).then((x) => x ?? undefined),
-				)) ?? null
-			);
-		} else {
-			return await uriPersonCache.fetch(parsed.uri, () =>
-				Users.findOneBy({
-					uri: parsed.uri,
-				}),
-			);
-		}
-	}
-
-	/**
-	 * AP KeyId => Misskey User and Key
-	 */
-	public async getAuthUserFromKeyId(keyId: string): Promise<{
-		user: CacheableRemoteUser;
-		key: UserPublickey;
-	} | null> {
-		const key = await publicKeyCache.fetch(
-			keyId,
-			async () => {
-				const key = await UserPublickeys.findOneBy({
-					keyId,
-				});
-
-				if (key == null) return null;
-
-				return key;
-			},
-			(key) => key != null,
-		);
-
-		if (key == null) return null;
-
-		return {
-			user: (await userByIdCache.fetch(key.userId, () =>
-				Users.findOneByOrFail({ id: key.userId }),
-			)) as CacheableRemoteUser,
-			key,
-		};
-	}
-
-	/**
-	 * AP Actor id => Misskey User and Key
-	 */
-	public async getAuthUserFromApId(uri: string): Promise<{
-		user: CacheableRemoteUser;
-		key: UserPublickey | null;
-	} | null> {
-		const user = (await resolvePerson(uri)) as CacheableRemoteUser;
-
-		if (user == null) return null;
-
-		const key = await publicKeyByUserIdCache.fetch(
-			user.id,
-			() => UserPublickeys.findOneBy({ userId: user.id }),
-			(v) => v != null,
-		);
-
-		return {
-			user,
-			key,
-		};
-	}
-}
diff --git a/packages/backend/src/remote/activitypub/deliver-manager.ts b/packages/backend/src/remote/activitypub/deliver-manager.ts
deleted file mode 100644
index 400e047774..0000000000
--- a/packages/backend/src/remote/activitypub/deliver-manager.ts
+++ /dev/null
@@ -1,171 +0,0 @@
-import { IsNull, Not } from "typeorm";
-import { Users, Followings } from "@/models/index.js";
-import type { ILocalUser, IRemoteUser, User } from "@/models/entities/user.js";
-import { deliver } from "@/queue/index.js";
-import { skippedInstances } from "@/misc/skipped-instances.js";
-
-//#region types
-interface IRecipe {
-	type: string;
-}
-
-interface IFollowersRecipe extends IRecipe {
-	type: "Followers";
-}
-
-interface IDirectRecipe extends IRecipe {
-	type: "Direct";
-	to: IRemoteUser;
-}
-
-const isFollowers = (recipe: any): recipe is IFollowersRecipe =>
-	recipe.type === "Followers";
-
-const isDirect = (recipe: any): recipe is IDirectRecipe =>
-	recipe.type === "Direct";
-//#endregion
-
-export default class DeliverManager {
-	private actor: { id: User["id"]; host: null };
-	private activity: any;
-	private recipes: IRecipe[] = [];
-
-	/**
-	 * Constructor
-	 * @param actor Actor
-	 * @param activity Activity to deliver
-	 */
-	constructor(actor: { id: User["id"]; host: null }, activity: any) {
-		this.actor = actor;
-		this.activity = activity;
-	}
-
-	/**
-	 * Add recipe for followers deliver
-	 */
-	public addFollowersRecipe() {
-		const deliver = {
-			type: "Followers",
-		} as IFollowersRecipe;
-
-		this.addRecipe(deliver);
-	}
-
-	/**
-	 * Add recipe for direct deliver
-	 * @param to To
-	 */
-	public addDirectRecipe(to: IRemoteUser) {
-		const recipe = {
-			type: "Direct",
-			to,
-		} as IDirectRecipe;
-
-		this.addRecipe(recipe);
-	}
-
-	/**
-	 * Add recipe
-	 * @param recipe Recipe
-	 */
-	public addRecipe(recipe: IRecipe) {
-		this.recipes.push(recipe);
-	}
-
-	/**
-	 * Execute delivers
-	 */
-	public async execute() {
-		if (!Users.isLocalUser(this.actor)) return;
-
-		const inboxes = new Set<string>();
-
-		/*
-		build inbox list
-
-		Process follower recipes first to avoid duplication when processing
-		direct recipes later.
-		*/
-		if (this.recipes.some((r) => isFollowers(r))) {
-			// followers deliver
-			// TODO: SELECT DISTINCT ON ("followerSharedInbox") "followerSharedInbox" みたいな問い合わせにすればよりパフォーマンス向上できそう
-			// ただ、sharedInboxがnullなリモートユーザーも稀におり、その対応ができなさそう?
-			const followers = (await Followings.find({
-				where: {
-					followeeId: this.actor.id,
-					followerHost: Not(IsNull()),
-				},
-				select: {
-					followerSharedInbox: true,
-					followerInbox: true,
-				},
-			})) as {
-				followerSharedInbox: string | null;
-				followerInbox: string;
-			}[];
-
-			for (const following of followers) {
-				const inbox = following.followerSharedInbox || following.followerInbox;
-				inboxes.add(inbox);
-			}
-		}
-
-		this.recipes
-			.filter(
-				(recipe): recipe is IDirectRecipe =>
-					// followers recipes have already been processed
-					isDirect(recipe) &&
-					// check that shared inbox has not been added yet
-					!(recipe.to.sharedInbox && inboxes.has(recipe.to.sharedInbox)) &&
-					// check that they actually have an inbox
-					recipe.to.inbox != null,
-			)
-			.forEach((recipe) => inboxes.add(recipe.to.inbox!));
-
-		const instancesToSkip = await skippedInstances(
-			// get (unique) list of hosts
-			Array.from(
-				new Set(Array.from(inboxes).map((inbox) => new URL(inbox).host)),
-			),
-		);
-
-		// deliver
-		for (const inbox of inboxes) {
-			// skip instances as indicated
-			if (instancesToSkip.includes(new URL(inbox).host)) continue;
-
-			deliver(this.actor, this.activity, inbox);
-		}
-	}
-}
-
-//#region Utilities
-/**
- * Deliver activity to followers
- * @param activity Activity
- * @param from Followee
- */
-export async function deliverToFollowers(
-	actor: { id: ILocalUser["id"]; host: null },
-	activity: any,
-) {
-	const manager = new DeliverManager(actor, activity);
-	manager.addFollowersRecipe();
-	await manager.execute();
-}
-
-/**
- * Deliver activity to user
- * @param activity Activity
- * @param to Target user
- */
-export async function deliverToUser(
-	actor: { id: ILocalUser["id"]; host: null },
-	activity: any,
-	to: IRemoteUser,
-) {
-	const manager = new DeliverManager(actor, activity);
-	manager.addDirectRecipe(to);
-	await manager.execute();
-}
-//#endregion
diff --git a/packages/backend/src/remote/activitypub/kernel/accept/follow.ts b/packages/backend/src/remote/activitypub/kernel/accept/follow.ts
deleted file mode 100644
index e430bbf576..0000000000
--- a/packages/backend/src/remote/activitypub/kernel/accept/follow.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import type { CacheableRemoteUser } from "@/models/entities/user.js";
-import accept from "@/services/following/requests/accept.js";
-import type { IFollow } from "../../type.js";
-import DbResolver from "../../db-resolver.js";
-import { relayAccepted } from "@/services/relay.js";
-
-export default async (
-	actor: CacheableRemoteUser,
-	activity: IFollow,
-): Promise<string> => {
-	// ※ activityはこっちから投げたフォローリクエストなので、activity.actorは存在するローカルユーザーである必要がある
-
-	const dbResolver = new DbResolver();
-	const follower = await dbResolver.getUserFromApId(activity.actor);
-
-	if (follower == null) {
-		return "skip: follower not found";
-	}
-
-	if (follower.host != null) {
-		return "skip: follower is not a local user";
-	}
-
-	// relay
-	const match = activity.id?.match(/follow-relay\/(\w+)/);
-	if (match) {
-		return await relayAccepted(match[1]);
-	}
-
-	await accept(actor, follower);
-	return "ok";
-};
diff --git a/packages/backend/src/remote/activitypub/kernel/accept/index.ts b/packages/backend/src/remote/activitypub/kernel/accept/index.ts
deleted file mode 100644
index 5c73760ff3..0000000000
--- a/packages/backend/src/remote/activitypub/kernel/accept/index.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import Resolver from "../../resolver.js";
-import type { CacheableRemoteUser } from "@/models/entities/user.js";
-import acceptFollow from "./follow.js";
-import type { IAccept } from "../../type.js";
-import { isFollow, getApType } from "../../type.js";
-import { apLogger } from "../../logger.js";
-
-const logger = apLogger;
-
-export default async (
-	actor: CacheableRemoteUser,
-	activity: IAccept,
-): Promise<string> => {
-	const uri = activity.id || activity;
-
-	logger.info(`Accept: ${uri}`);
-
-	const resolver = new Resolver();
-
-	const object = await resolver.resolve(activity.object).catch((e) => {
-		logger.error(`Resolution failed: ${e}`);
-		throw e;
-	});
-
-	if (isFollow(object)) return await acceptFollow(actor, object);
-
-	return `skip: Unknown Accept type: ${getApType(object)}`;
-};
diff --git a/packages/backend/src/remote/activitypub/kernel/add/index.ts b/packages/backend/src/remote/activitypub/kernel/add/index.ts
deleted file mode 100644
index b3606e5d93..0000000000
--- a/packages/backend/src/remote/activitypub/kernel/add/index.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import type { CacheableRemoteUser } from "@/models/entities/user.js";
-import type { IAdd } from "../../type.js";
-import { resolveNote } from "../../models/note.js";
-import { addPinned } from "@/services/i/pin.js";
-
-export default async (
-	actor: CacheableRemoteUser,
-	activity: IAdd,
-): Promise<void> => {
-	if ("actor" in activity && actor.uri !== activity.actor) {
-		throw new Error("invalid actor");
-	}
-
-	if (activity.target == null) {
-		throw new Error("target is null");
-	}
-
-	if (activity.target === actor.featured) {
-		const note = await resolveNote(activity.object);
-		if (note == null) throw new Error("note not found");
-		await addPinned(actor, note.id);
-		return;
-	}
-
-	throw new Error(`unknown target: ${activity.target}`);
-};
diff --git a/packages/backend/src/remote/activitypub/kernel/announce/index.ts b/packages/backend/src/remote/activitypub/kernel/announce/index.ts
deleted file mode 100644
index 975e070f92..0000000000
--- a/packages/backend/src/remote/activitypub/kernel/announce/index.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import Resolver from "../../resolver.js";
-import type { CacheableRemoteUser } from "@/models/entities/user.js";
-import announceNote from "./note.js";
-import type { IAnnounce } from "../../type.js";
-import { getApId } from "../../type.js";
-import { apLogger } from "../../logger.js";
-
-const logger = apLogger;
-
-export default async (
-	actor: CacheableRemoteUser,
-	activity: IAnnounce,
-): Promise<void> => {
-	const uri = getApId(activity);
-
-	logger.info(`Announce: ${uri}`);
-
-	const resolver = new Resolver();
-
-	const targetUri = getApId(activity.object);
-
-	announceNote(resolver, actor, activity, targetUri);
-};
diff --git a/packages/backend/src/remote/activitypub/kernel/announce/note.ts b/packages/backend/src/remote/activitypub/kernel/announce/note.ts
deleted file mode 100644
index 6cdaa61662..0000000000
--- a/packages/backend/src/remote/activitypub/kernel/announce/note.ts
+++ /dev/null
@@ -1,84 +0,0 @@
-import type Resolver from "../../resolver.js";
-import post from "@/services/note/create.js";
-import type { CacheableRemoteUser } from "@/models/entities/user.js";
-import type { IAnnounce } from "../../type.js";
-import { getApId } from "../../type.js";
-import { fetchNote, resolveNote } from "../../models/note.js";
-import { apLogger } from "../../logger.js";
-import { extractDbHost } from "@/misc/convert-host.js";
-import { getApLock } from "@/misc/app-lock.js";
-import { parseAudience } from "../../audience.js";
-import { StatusError } from "@/misc/fetch.js";
-import { Notes } from "@/models/index.js";
-import { shouldBlockInstance } from "@/misc/should-block-instance.js";
-
-const logger = apLogger;
-
-/**
- * Handle announcement activities
- */
-export default async function (
-	resolver: Resolver,
-	actor: CacheableRemoteUser,
-	activity: IAnnounce,
-	targetUri: string,
-): Promise<void> {
-	const uri = getApId(activity);
-
-	if (actor.isSuspended) {
-		return;
-	}
-
-	// Interrupt if you block the announcement destination
-	if (await shouldBlockInstance(extractDbHost(uri))) return;
-
-	const unlock = await getApLock(uri);
-
-	try {
-		// Check if something with the same URI is already registered
-		const exist = await fetchNote(uri);
-		if (exist) {
-			return;
-		}
-
-		// Resolve Announce target
-		let renote;
-		try {
-			renote = await resolveNote(targetUri);
-		} catch (e) {
-			// Skip if target is 4xx
-			if (e instanceof StatusError) {
-				if (e.isClientError) {
-					logger.warn(`Ignored announce target ${targetUri} - ${e.statusCode}`);
-					return;
-				}
-
-				logger.warn(
-					`Error in announce target ${targetUri} - ${e.statusCode || e}`,
-				);
-			}
-			throw e;
-		}
-
-		if (!(await Notes.isVisibleForMe(renote, actor.id)))
-			return "skip: invalid actor for this activity";
-
-		logger.info(`Creating the (Re)Note: ${uri}`);
-
-		const activityAudience = await parseAudience(
-			actor,
-			activity.to,
-			activity.cc,
-		);
-
-		await post(actor, {
-			createdAt: activity.published ? new Date(activity.published) : null,
-			renote,
-			visibility: activityAudience.visibility,
-			visibleUsers: activityAudience.visibleUsers,
-			uri,
-		});
-	} finally {
-		unlock();
-	}
-}
diff --git a/packages/backend/src/remote/activitypub/kernel/block/index.ts b/packages/backend/src/remote/activitypub/kernel/block/index.ts
deleted file mode 100644
index 4dc868ba10..0000000000
--- a/packages/backend/src/remote/activitypub/kernel/block/index.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import type { IBlock } from "../../type.js";
-import block from "@/services/blocking/create.js";
-import type { CacheableRemoteUser } from "@/models/entities/user.js";
-import DbResolver from "../../db-resolver.js";
-import { Users } from "@/models/index.js";
-
-export default async (
-	actor: CacheableRemoteUser,
-	activity: IBlock,
-): Promise<string> => {
-	// ※ There is a block target in activity.object, which should be a local user that exists.
-
-	const dbResolver = new DbResolver();
-	const blockee = await dbResolver.getUserFromApId(activity.object);
-
-	if (blockee == null) {
-		return "skip: blockee not found";
-	}
-
-	if (blockee.host != null) {
-		return "skip: The user you are trying to block is not a local user";
-	}
-
-	await block(
-		await Users.findOneByOrFail({ id: actor.id }),
-		await Users.findOneByOrFail({ id: blockee.id }),
-	);
-	return "ok";
-};
diff --git a/packages/backend/src/remote/activitypub/kernel/create/index.ts b/packages/backend/src/remote/activitypub/kernel/create/index.ts
deleted file mode 100644
index 3dcf648247..0000000000
--- a/packages/backend/src/remote/activitypub/kernel/create/index.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import Resolver from "../../resolver.js";
-import type { CacheableRemoteUser } from "@/models/entities/user.js";
-import createNote from "./note.js";
-import type { ICreate } from "../../type.js";
-import { getApId, isPost, getApType } from "../../type.js";
-import { apLogger } from "../../logger.js";
-import { toArray, concat, unique } from "@/prelude/array.js";
-
-const logger = apLogger;
-
-export default async (
-	actor: CacheableRemoteUser,
-	activity: ICreate,
-): Promise<void> => {
-	const uri = getApId(activity);
-
-	logger.info(`Create: ${uri}`);
-
-	// copy audiences between activity <=> object.
-	if (typeof activity.object === "object") {
-		const to = unique(
-			concat([toArray(activity.to), toArray(activity.object.to)]),
-		);
-		const cc = unique(
-			concat([toArray(activity.cc), toArray(activity.object.cc)]),
-		);
-
-		activity.to = to;
-		activity.cc = cc;
-		activity.object.to = to;
-		activity.object.cc = cc;
-	}
-
-	// If there is no attributedTo, use Activity actor.
-	if (typeof activity.object === "object" && !activity.object.attributedTo) {
-		activity.object.attributedTo = activity.actor;
-	}
-
-	const resolver = new Resolver();
-
-	const object = await resolver.resolve(activity.object).catch((e) => {
-		logger.error(`Resolution failed: ${e}`);
-		throw e;
-	});
-
-	if (isPost(object)) {
-		createNote(resolver, actor, object, false, activity);
-	} else {
-		logger.warn(`Unknown type: ${getApType(object)}`);
-	}
-};
diff --git a/packages/backend/src/remote/activitypub/kernel/create/note.ts b/packages/backend/src/remote/activitypub/kernel/create/note.ts
deleted file mode 100644
index 09c492730c..0000000000
--- a/packages/backend/src/remote/activitypub/kernel/create/note.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import type Resolver from "../../resolver.js";
-import type { CacheableRemoteUser } from "@/models/entities/user.js";
-import { createNote, fetchNote } from "../../models/note.js";
-import type { IObject, ICreate } from "../../type.js";
-import { getApId } from "../../type.js";
-import { getApLock } from "@/misc/app-lock.js";
-import { extractDbHost } from "@/misc/convert-host.js";
-import { StatusError } from "@/misc/fetch.js";
-
-/**
- * Handle post creation activity
- */
-export default async function (
-	resolver: Resolver,
-	actor: CacheableRemoteUser,
-	note: IObject,
-	silent = false,
-	activity?: ICreate,
-): Promise<string> {
-	const uri = getApId(note);
-
-	if (typeof note === "object") {
-		if (actor.uri !== note.attributedTo) {
-			return "skip: actor.uri !== note.attributedTo";
-		}
-
-		if (typeof note.id === "string") {
-			if (extractDbHost(actor.uri) !== extractDbHost(note.id)) {
-				return "skip: host in actor.uri !== note.id";
-			}
-		}
-	}
-
-	const unlock = await getApLock(uri);
-
-	try {
-		const exist = await fetchNote(note);
-		if (exist) return "skip: note exists";
-
-		await createNote(note, resolver, silent);
-		return "ok";
-	} catch (e) {
-		if (e instanceof StatusError && e.isClientError) {
-			return `skip ${e.statusCode}`;
-		} else {
-			throw e;
-		}
-	} finally {
-		unlock();
-	}
-}
diff --git a/packages/backend/src/remote/activitypub/kernel/delete/actor.ts b/packages/backend/src/remote/activitypub/kernel/delete/actor.ts
deleted file mode 100644
index 3571135aa5..0000000000
--- a/packages/backend/src/remote/activitypub/kernel/delete/actor.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import { apLogger } from "../../logger.js";
-import { createDeleteAccountJob } from "@/queue/index.js";
-import type { CacheableRemoteUser } from "@/models/entities/user.js";
-import { Users } from "@/models/index.js";
-
-const logger = apLogger;
-
-export async function deleteActor(
-	actor: CacheableRemoteUser,
-	uri: string,
-): Promise<string> {
-	logger.info(`Deleting the Actor: ${uri}`);
-
-	if (actor.uri !== uri) {
-		return `skip: delete actor ${actor.uri} !== ${uri}`;
-	}
-
-	const user = await Users.findOneByOrFail({ id: actor.id });
-	if (user.isDeleted) {
-		logger.info("skip: already deleted");
-	}
-
-	const job = await createDeleteAccountJob(actor);
-
-	await Users.update(actor.id, {
-		isDeleted: true,
-	});
-
-	return `ok: queued ${job.name} ${job.id}`;
-}
diff --git a/packages/backend/src/remote/activitypub/kernel/delete/index.ts b/packages/backend/src/remote/activitypub/kernel/delete/index.ts
deleted file mode 100644
index f9ad52de54..0000000000
--- a/packages/backend/src/remote/activitypub/kernel/delete/index.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-import type { CacheableRemoteUser } from "@/models/entities/user.js";
-import { toSingle } from "@/prelude/array.js";
-import { getApId, isTombstone, validPost, validActor } from "../../type.js";
-import deleteNote from "./note.js";
-import { deleteActor } from "./actor.js";
-import type { IDelete, IObject } from "../../type.js";
-
-/**
- * Handle delete activity
- */
-export default async (
-	actor: CacheableRemoteUser,
-	activity: IDelete,
-): Promise<string> => {
-	if ("actor" in activity && actor.uri !== activity.actor) {
-		throw new Error("invalid actor");
-	}
-
-	// Type of object to be deleted
-	let formerType: string | undefined;
-
-	if (typeof activity.object === "string") {
-		// The type is unknown, but it has disappeared
-		// anyway, so it does not remote resolve
-		formerType = undefined;
-	} else {
-		const object = activity.object as IObject;
-		if (isTombstone(object)) {
-			formerType = toSingle(object.formerType);
-		} else {
-			formerType = toSingle(object.type);
-		}
-	}
-
-	const uri = getApId(activity.object);
-
-	// Even if type is unknown, if actor and object are the same,
-	// it must be `Person`.
-	if (!formerType && actor.uri === uri) {
-		formerType = "Person";
-	}
-
-	// If not, fallback to `Note`.
-	if (!formerType) {
-		formerType = "Note";
-	}
-
-	if (validPost.includes(formerType)) {
-		return await deleteNote(actor, uri);
-	} else if (validActor.includes(formerType)) {
-		return await deleteActor(actor, uri);
-	} else {
-		return `Unknown type ${formerType}`;
-	}
-};
diff --git a/packages/backend/src/remote/activitypub/kernel/delete/note.ts b/packages/backend/src/remote/activitypub/kernel/delete/note.ts
deleted file mode 100644
index 69298e9175..0000000000
--- a/packages/backend/src/remote/activitypub/kernel/delete/note.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import type { CacheableRemoteUser } from "@/models/entities/user.js";
-import deleteNode from "@/services/note/delete.js";
-import { apLogger } from "../../logger.js";
-import DbResolver from "../../db-resolver.js";
-import { getApLock } from "@/misc/app-lock.js";
-import { deleteMessage } from "@/services/messages/delete.js";
-
-const logger = apLogger;
-
-export default async function (
-	actor: CacheableRemoteUser,
-	uri: string,
-): Promise<string> {
-	logger.info(`Deleting the Note: ${uri}`);
-
-	const unlock = await getApLock(uri);
-
-	try {
-		const dbResolver = new DbResolver();
-		const note = await dbResolver.getNoteFromApId(uri);
-
-		if (note == null) {
-			const message = await dbResolver.getMessageFromApId(uri);
-			if (message == null) return "message not found";
-
-			if (message.userId !== actor.id) {
-				return "The user trying to delete the post is not the post author";
-			}
-
-			await deleteMessage(message);
-
-			return "ok: message deleted";
-		}
-
-		if (note.userId !== actor.id) {
-			return "The user trying to delete the post is not the post author";
-		}
-
-		await deleteNode(actor, note);
-		return "ok: note deleted";
-	} finally {
-		unlock();
-	}
-}
diff --git a/packages/backend/src/remote/activitypub/kernel/flag/index.ts b/packages/backend/src/remote/activitypub/kernel/flag/index.ts
deleted file mode 100644
index 39ba8b3f4f..0000000000
--- a/packages/backend/src/remote/activitypub/kernel/flag/index.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import type { CacheableRemoteUser } from "@/models/entities/user.js";
-import config from "@/config/index.js";
-import type { IFlag } from "../../type.js";
-import { getApIds } from "../../type.js";
-import { AbuseUserReports, Users } from "@/models/index.js";
-import { In } from "typeorm";
-import { genId } from "@/misc/gen-id.js";
-
-export default async (
-	actor: CacheableRemoteUser,
-	activity: IFlag,
-): Promise<string> => {
-	// The object is `(User | Note) | (User | Note) []`, but it cannot be
-	// matched with all patterns of the DB schema, so the target user is the first
-	// user and it is stored as a comment.
-	const uris = getApIds(activity.object);
-
-	const userIds = uris
-		.filter((uri) => uri.startsWith(`${config.url}/users/`))
-		.map((uri) => uri.split("/").pop()!);
-	const users = await Users.findBy({
-		id: In(userIds),
-	});
-	if (users.length < 1) return "skip";
-
-	await AbuseUserReports.insert({
-		id: genId(),
-		createdAt: new Date(),
-		targetUserId: users[0].id,
-		targetUserHost: users[0].host,
-		reporterId: actor.id,
-		reporterHost: actor.host,
-		comment: `${activity.content}\n${JSON.stringify(uris, null, 2)}`,
-	});
-
-	return "ok";
-};
diff --git a/packages/backend/src/remote/activitypub/kernel/follow.ts b/packages/backend/src/remote/activitypub/kernel/follow.ts
deleted file mode 100644
index 1c1ef36cfa..0000000000
--- a/packages/backend/src/remote/activitypub/kernel/follow.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import type { CacheableRemoteUser } from "@/models/entities/user.js";
-import follow from "@/services/following/create.js";
-import type { IFollow } from "../type.js";
-import DbResolver from "../db-resolver.js";
-
-export default async (
-	actor: CacheableRemoteUser,
-	activity: IFollow,
-): Promise<string> => {
-	const dbResolver = new DbResolver();
-	const followee = await dbResolver.getUserFromApId(activity.object);
-
-	if (followee == null) {
-		return "skip: followee not found";
-	}
-
-	if (followee.host != null) {
-		return "skip: user you are trying to follow is not a local user";
-	}
-
-	await follow(actor, followee, activity.id);
-	return "ok";
-};
diff --git a/packages/backend/src/remote/activitypub/kernel/index.ts b/packages/backend/src/remote/activitypub/kernel/index.ts
deleted file mode 100644
index 58e354a512..0000000000
--- a/packages/backend/src/remote/activitypub/kernel/index.ts
+++ /dev/null
@@ -1,111 +0,0 @@
-import type { CacheableRemoteUser } from "@/models/entities/user.js";
-import { toArray } from "@/prelude/array.js";
-import {
-	isCreate,
-	isDelete,
-	isUpdate,
-	isRead,
-	isFollow,
-	isAccept,
-	isReject,
-	isAdd,
-	isRemove,
-	isAnnounce,
-	isLike,
-	isUndo,
-	isBlock,
-	isCollectionOrOrderedCollection,
-	isCollection,
-	isFlag,
-	isMove,
-	getApId,
-} from "../type.js";
-import { apLogger } from "../logger.js";
-import Resolver from "../resolver.js";
-import create from "./create/index.js";
-import performDeleteActivity from "./delete/index.js";
-import performUpdateActivity from "./update/index.js";
-import { performReadActivity } from "./read.js";
-import follow from "./follow.js";
-import undo from "./undo/index.js";
-import like from "./like.js";
-import announce from "./announce/index.js";
-import accept from "./accept/index.js";
-import reject from "./reject/index.js";
-import add from "./add/index.js";
-import remove from "./remove/index.js";
-import block from "./block/index.js";
-import flag from "./flag/index.js";
-import move from "./move/index.js";
-import type { IObject } from "../type.js";
-import { extractDbHost } from "@/misc/convert-host.js";
-import { shouldBlockInstance } from "@/misc/should-block-instance.js";
-
-export async function performActivity(
-	actor: CacheableRemoteUser,
-	activity: IObject,
-) {
-	if (isCollectionOrOrderedCollection(activity)) {
-		const resolver = new Resolver();
-		for (const item of toArray(
-			isCollection(activity) ? activity.items : activity.orderedItems,
-		)) {
-			const act = await resolver.resolve(item);
-			try {
-				await performOneActivity(actor, act);
-			} catch (err) {
-				if (err instanceof Error || typeof err === "string") {
-					apLogger.error(err);
-				}
-			}
-		}
-	} else {
-		await performOneActivity(actor, activity);
-	}
-}
-
-async function performOneActivity(
-	actor: CacheableRemoteUser,
-	activity: IObject,
-): Promise<void> {
-	if (actor.isSuspended) return;
-
-	if (typeof activity.id !== "undefined") {
-		const host = extractDbHost(getApId(activity));
-		if (await shouldBlockInstance(host)) return;
-	}
-
-	if (isCreate(activity)) {
-		await create(actor, activity);
-	} else if (isDelete(activity)) {
-		await performDeleteActivity(actor, activity);
-	} else if (isUpdate(activity)) {
-		await performUpdateActivity(actor, activity);
-	} else if (isRead(activity)) {
-		await performReadActivity(actor, activity);
-	} else if (isFollow(activity)) {
-		await follow(actor, activity);
-	} else if (isAccept(activity)) {
-		await accept(actor, activity);
-	} else if (isReject(activity)) {
-		await reject(actor, activity);
-	} else if (isAdd(activity)) {
-		await add(actor, activity).catch((err) => apLogger.error(err));
-	} else if (isRemove(activity)) {
-		await remove(actor, activity).catch((err) => apLogger.error(err));
-	} else if (isAnnounce(activity)) {
-		await announce(actor, activity);
-	} else if (isLike(activity)) {
-		await like(actor, activity);
-	} else if (isUndo(activity)) {
-		await undo(actor, activity);
-	} else if (isBlock(activity)) {
-		await block(actor, activity);
-	} else if (isFlag(activity)) {
-		await flag(actor, activity);
-	} else if (isMove(activity)) {
-		await move(actor, activity);
-	} else {
-		apLogger.warn(`unrecognized activity type: ${(activity as any).type}`);
-	}
-}
diff --git a/packages/backend/src/remote/activitypub/kernel/like.ts b/packages/backend/src/remote/activitypub/kernel/like.ts
deleted file mode 100644
index 7b30d1cd54..0000000000
--- a/packages/backend/src/remote/activitypub/kernel/like.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import type { CacheableRemoteUser } from "@/models/entities/user.js";
-import type { ILike } from "../type.js";
-import { getApId } from "../type.js";
-import create from "@/services/note/reaction/create.js";
-import { fetchNote, extractEmojis } from "../models/note.js";
-
-export default async (actor: CacheableRemoteUser, activity: ILike) => {
-	const targetUri = getApId(activity.object);
-
-	const note = await fetchNote(targetUri);
-	if (!note) return `skip: target note not found ${targetUri}`;
-
-	await extractEmojis(activity.tag || [], actor.host).catch(() => null);
-
-	return await create(
-		actor,
-		note,
-		activity._misskey_reaction || activity.content || activity.name,
-	)
-		.catch((e) => {
-			if (e.id === "51c42bb4-931a-456b-bff7-e5a8a70dd298") {
-				return "skip: already reacted";
-			} else {
-				throw e;
-			}
-		})
-		.then(() => "ok");
-};
diff --git a/packages/backend/src/remote/activitypub/kernel/move/index.ts b/packages/backend/src/remote/activitypub/kernel/move/index.ts
deleted file mode 100644
index 800fd7bfea..0000000000
--- a/packages/backend/src/remote/activitypub/kernel/move/index.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-import type { CacheableRemoteUser } from "@/models/entities/user.js";
-import { Followings, Users } from "@/models/index.js";
-import {
-	resolvePerson,
-	updatePerson,
-} from "@/remote/activitypub/models/person.js";
-import create from "@/services/following/create.js";
-import deleteFollowing from "@/services/following/delete.js";
-
-import type { IMove } from "../../type.js";
-import { getApHrefNullable } from "../../type.js";
-
-export default async (
-	actor: CacheableRemoteUser,
-	activity: IMove,
-): Promise<string> => {
-	// ※ There is a block target in activity.object, which should be a local user that exists.
-
-	// fetch the new and old accounts
-	const targetUri = getApHrefNullable(activity.target);
-	if (!targetUri) return "move: target uri is null";
-	let new_acc = await resolvePerson(targetUri);
-	if (!actor.uri) return "move: actor uri is null";
-	let old_acc = await resolvePerson(actor.uri);
-
-	// update them if they're remote
-	if (new_acc.uri) await updatePerson(new_acc.uri);
-	if (old_acc.uri) await updatePerson(old_acc.uri);
-
-	// retrieve updated users
-	new_acc = await resolvePerson(targetUri);
-	old_acc = await resolvePerson(actor.uri);
-
-	// check if alsoKnownAs of the new account is valid
-	let isValidMove = true;
-	if (old_acc.uri) {
-		if (!new_acc.alsoKnownAs?.includes(old_acc.uri)) {
-			isValidMove = false;
-		}
-	} else if (!new_acc.alsoKnownAs?.includes(old_acc.id)) {
-		isValidMove = false;
-	}
-	if (!isValidMove) {
-		return "skip: accounts invalid";
-	}
-
-	// add target uri to movedToUri in order to indicate that the user has moved
-	await Users.update(old_acc.id, { movedToUri: targetUri });
-
-	// follow the new account and unfollow the old one
-	const followings = await Followings.findBy({
-		followeeId: old_acc.id,
-	});
-	followings.forEach(async (following) => {
-		// If follower is local
-		if (!following.followerHost) {
-			try {
-				const follower = await Users.findOneBy({ id: following.followerId });
-				if (!follower) return;
-				await create(follower, new_acc);
-				await deleteFollowing(follower, old_acc);
-			} catch {
-				/* empty */
-			}
-		}
-	});
-
-	return "ok";
-};
diff --git a/packages/backend/src/remote/activitypub/kernel/read.ts b/packages/backend/src/remote/activitypub/kernel/read.ts
deleted file mode 100644
index 7cc70976c3..0000000000
--- a/packages/backend/src/remote/activitypub/kernel/read.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import type { CacheableRemoteUser } from "@/models/entities/user.js";
-import type { IRead } from "../type.js";
-import { getApId } from "../type.js";
-import { isSelfHost, extractDbHost } from "@/misc/convert-host.js";
-import { MessagingMessages } from "@/models/index.js";
-import { readUserMessagingMessage } from "../../../server/api/common/read-messaging-message.js";
-
-export const performReadActivity = async (
-	actor: CacheableRemoteUser,
-	activity: IRead,
-): Promise<string> => {
-	const id = await getApId(activity.object);
-
-	if (!isSelfHost(extractDbHost(id))) {
-		return `skip: Read to foreign host (${id})`;
-	}
-
-	const messageId = id.split("/").pop();
-
-	const message = await MessagingMessages.findOneBy({ id: messageId });
-	if (message == null) {
-		return "skip: message not found";
-	}
-
-	if (actor.id !== message.recipientId) {
-		return "skip: actor is not a message recipient";
-	}
-
-	await readUserMessagingMessage(message.recipientId!, message.userId, [
-		message.id,
-	]);
-	return `ok: mark as read (${message.userId} => ${message.recipientId} ${message.id})`;
-};
diff --git a/packages/backend/src/remote/activitypub/kernel/reject/follow.ts b/packages/backend/src/remote/activitypub/kernel/reject/follow.ts
deleted file mode 100644
index 670c1556fd..0000000000
--- a/packages/backend/src/remote/activitypub/kernel/reject/follow.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import type { CacheableRemoteUser } from "@/models/entities/user.js";
-import { remoteReject } from "@/services/following/reject.js";
-import type { IFollow } from "../../type.js";
-import DbResolver from "../../db-resolver.js";
-import { relayRejected } from "@/services/relay.js";
-import { Users } from "@/models/index.js";
-
-export default async (
-	actor: CacheableRemoteUser,
-	activity: IFollow,
-): Promise<string> => {
-	// ※ `activity.actor` must be an existing local user, since `activity` is a follow request thrown from us.
-
-	const dbResolver = new DbResolver();
-	const follower = await dbResolver.getUserFromApId(activity.actor);
-
-	if (follower == null) {
-		return "skip: follower not found";
-	}
-
-	if (!Users.isLocalUser(follower)) {
-		return "skip: follower is not a local user";
-	}
-
-	// relay
-	const match = activity.id?.match(/follow-relay\/(\w+)/);
-	if (match) {
-		return await relayRejected(match[1]);
-	}
-
-	await remoteReject(actor, follower);
-	return "ok";
-};
diff --git a/packages/backend/src/remote/activitypub/kernel/reject/index.ts b/packages/backend/src/remote/activitypub/kernel/reject/index.ts
deleted file mode 100644
index 10edb0f7a2..0000000000
--- a/packages/backend/src/remote/activitypub/kernel/reject/index.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import Resolver from "../../resolver.js";
-import type { CacheableRemoteUser } from "@/models/entities/user.js";
-import rejectFollow from "./follow.js";
-import type { IReject } from "../../type.js";
-import { isFollow, getApType } from "../../type.js";
-import { apLogger } from "../../logger.js";
-
-const logger = apLogger;
-
-export default async (
-	actor: CacheableRemoteUser,
-	activity: IReject,
-): Promise<string> => {
-	const uri = activity.id || activity;
-
-	logger.info(`Reject: ${uri}`);
-
-	const resolver = new Resolver();
-
-	const object = await resolver.resolve(activity.object).catch((e) => {
-		logger.error(`Resolution failed: ${e}`);
-		throw e;
-	});
-
-	if (isFollow(object)) return await rejectFollow(actor, object);
-
-	return `skip: Unknown Reject type: ${getApType(object)}`;
-};
diff --git a/packages/backend/src/remote/activitypub/kernel/remove/index.ts b/packages/backend/src/remote/activitypub/kernel/remove/index.ts
deleted file mode 100644
index 0b4be6b5f2..0000000000
--- a/packages/backend/src/remote/activitypub/kernel/remove/index.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import type { CacheableRemoteUser } from "@/models/entities/user.js";
-import type { IRemove } from "../../type.js";
-import { resolveNote } from "../../models/note.js";
-import { removePinned } from "@/services/i/pin.js";
-
-export default async (
-	actor: CacheableRemoteUser,
-	activity: IRemove,
-): Promise<void> => {
-	if ("actor" in activity && actor.uri !== activity.actor) {
-		throw new Error("invalid actor");
-	}
-
-	if (activity.target == null) {
-		throw new Error("target is null");
-	}
-
-	if (activity.target === actor.featured) {
-		const note = await resolveNote(activity.object);
-		if (note == null) throw new Error("note not found");
-		await removePinned(actor, note.id);
-		return;
-	}
-
-	throw new Error(`unknown target: ${activity.target}`);
-};
diff --git a/packages/backend/src/remote/activitypub/kernel/undo/accept.ts b/packages/backend/src/remote/activitypub/kernel/undo/accept.ts
deleted file mode 100644
index 2cd05a77d2..0000000000
--- a/packages/backend/src/remote/activitypub/kernel/undo/accept.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import unfollow from "@/services/following/delete.js";
-import cancelRequest from "@/services/following/requests/cancel.js";
-import type { IAccept } from "../../type.js";
-import type { CacheableRemoteUser } from "@/models/entities/user.js";
-import { Followings } from "@/models/index.js";
-import DbResolver from "../../db-resolver.js";
-
-export default async (
-	actor: CacheableRemoteUser,
-	activity: IAccept,
-): Promise<string> => {
-	const dbResolver = new DbResolver();
-
-	const follower = await dbResolver.getUserFromApId(activity.object);
-	if (follower == null) {
-		return "skip: follower not found";
-	}
-
-	const following = await Followings.findOneBy({
-		followerId: follower.id,
-		followeeId: actor.id,
-	});
-
-	if (following) {
-		await unfollow(follower, actor);
-		return "ok: unfollowed";
-	}
-
-	return "skip: skip: not followed";
-};
diff --git a/packages/backend/src/remote/activitypub/kernel/undo/announce.ts b/packages/backend/src/remote/activitypub/kernel/undo/announce.ts
deleted file mode 100644
index a6e9c88c61..0000000000
--- a/packages/backend/src/remote/activitypub/kernel/undo/announce.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import { Notes } from "@/models/index.js";
-import type { CacheableRemoteUser } from "@/models/entities/user.js";
-import type { IAnnounce } from "../../type.js";
-import { getApId } from "../../type.js";
-import deleteNote from "@/services/note/delete.js";
-
-export const undoAnnounce = async (
-	actor: CacheableRemoteUser,
-	activity: IAnnounce,
-): Promise<string> => {
-	const uri = getApId(activity);
-
-	const note = await Notes.findOneBy({
-		uri,
-		userId: actor.id,
-	});
-
-	if (!note) return "skip: no such Announce";
-
-	await deleteNote(actor, note);
-	return "ok: deleted";
-};
diff --git a/packages/backend/src/remote/activitypub/kernel/undo/block.ts b/packages/backend/src/remote/activitypub/kernel/undo/block.ts
deleted file mode 100644
index b4e1d8ee43..0000000000
--- a/packages/backend/src/remote/activitypub/kernel/undo/block.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import type { IBlock } from "../../type.js";
-import unblock from "@/services/blocking/delete.js";
-import type { CacheableRemoteUser } from "@/models/entities/user.js";
-import DbResolver from "../../db-resolver.js";
-import { Users } from "@/models/index.js";
-
-export default async (
-	actor: CacheableRemoteUser,
-	activity: IBlock,
-): Promise<string> => {
-	const dbResolver = new DbResolver();
-	const blockee = await dbResolver.getUserFromApId(activity.object);
-
-	if (blockee == null) {
-		return "skip: blockee not found";
-	}
-
-	if (blockee.host != null) {
-		return "skip: The user you are trying to unblock is not a local user";
-	}
-
-	await unblock(await Users.findOneByOrFail({ id: actor.id }), blockee);
-	return "ok";
-};
diff --git a/packages/backend/src/remote/activitypub/kernel/undo/follow.ts b/packages/backend/src/remote/activitypub/kernel/undo/follow.ts
deleted file mode 100644
index 1c4648cf90..0000000000
--- a/packages/backend/src/remote/activitypub/kernel/undo/follow.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import unfollow from "@/services/following/delete.js";
-import cancelRequest from "@/services/following/requests/cancel.js";
-import type { IFollow } from "../../type.js";
-import type { CacheableRemoteUser } from "@/models/entities/user.js";
-import { FollowRequests, Followings } from "@/models/index.js";
-import DbResolver from "../../db-resolver.js";
-
-export default async (
-	actor: CacheableRemoteUser,
-	activity: IFollow,
-): Promise<string> => {
-	const dbResolver = new DbResolver();
-
-	const followee = await dbResolver.getUserFromApId(activity.object);
-	if (followee == null) {
-		return "skip: followee not found";
-	}
-
-	if (followee.host != null) {
-		return "skip: The user you are trying to unfollow is not a local user";
-	}
-
-	const req = await FollowRequests.findOneBy({
-		followerId: actor.id,
-		followeeId: followee.id,
-	});
-
-	const following = await Followings.findOneBy({
-		followerId: actor.id,
-		followeeId: followee.id,
-	});
-
-	if (req) {
-		await cancelRequest(followee, actor);
-		return "ok: follow request canceled";
-	}
-
-	if (following) {
-		await unfollow(actor, followee);
-		return "ok: unfollowed";
-	}
-
-	return "skip: Not requested or followed";
-};
diff --git a/packages/backend/src/remote/activitypub/kernel/undo/index.ts b/packages/backend/src/remote/activitypub/kernel/undo/index.ts
deleted file mode 100644
index f0e2316fab..0000000000
--- a/packages/backend/src/remote/activitypub/kernel/undo/index.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import type { CacheableRemoteUser } from "@/models/entities/user.js";
-import type { IUndo } from "../../type.js";
-import {
-	isFollow,
-	isBlock,
-	isLike,
-	isAnnounce,
-	getApType,
-	isAccept,
-} from "../../type.js";
-import unfollow from "./follow.js";
-import unblock from "./block.js";
-import undoLike from "./like.js";
-import undoAccept from "./accept.js";
-import { undoAnnounce } from "./announce.js";
-import Resolver from "../../resolver.js";
-import { apLogger } from "../../logger.js";
-
-const logger = apLogger;
-
-export default async (
-	actor: CacheableRemoteUser,
-	activity: IUndo,
-): Promise<string> => {
-	if ("actor" in activity && actor.uri !== activity.actor) {
-		throw new Error("invalid actor");
-	}
-
-	const uri = activity.id || activity;
-
-	logger.info(`Undo: ${uri}`);
-
-	const resolver = new Resolver();
-
-	const object = await resolver.resolve(activity.object).catch((e) => {
-		logger.error(`Resolution failed: ${e}`);
-		throw e;
-	});
-
-	if (isFollow(object)) return await unfollow(actor, object);
-	if (isBlock(object)) return await unblock(actor, object);
-	if (isLike(object)) return await undoLike(actor, object);
-	if (isAnnounce(object)) return await undoAnnounce(actor, object);
-	if (isAccept(object)) return await undoAccept(actor, object);
-
-	return `skip: unknown object type ${getApType(object)}`;
-};
diff --git a/packages/backend/src/remote/activitypub/kernel/undo/like.ts b/packages/backend/src/remote/activitypub/kernel/undo/like.ts
deleted file mode 100644
index 90220e203d..0000000000
--- a/packages/backend/src/remote/activitypub/kernel/undo/like.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import type { CacheableRemoteUser } from "@/models/entities/user.js";
-import type { ILike } from "../../type.js";
-import { getApId } from "../../type.js";
-import deleteReaction from "@/services/note/reaction/delete.js";
-import { fetchNote } from "../../models/note.js";
-
-/**
- * Process Undo.Like activity
- */
-export default async (actor: CacheableRemoteUser, activity: ILike) => {
-	const targetUri = getApId(activity.object);
-
-	const note = await fetchNote(targetUri);
-	if (!note) return `skip: target note not found ${targetUri}`;
-
-	await deleteReaction(actor, note).catch((e) => {
-		if (e.id === "60527ec9-b4cb-4a88-a6bd-32d3ad26817d") return;
-		throw e;
-	});
-
-	return "ok";
-};
diff --git a/packages/backend/src/remote/activitypub/kernel/update/index.ts b/packages/backend/src/remote/activitypub/kernel/update/index.ts
deleted file mode 100644
index 4f1514ddd1..0000000000
--- a/packages/backend/src/remote/activitypub/kernel/update/index.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import type { CacheableRemoteUser } from "@/models/entities/user.js";
-import type { IUpdate } from "../../type.js";
-import { getApType, isActor } from "../../type.js";
-import { apLogger } from "../../logger.js";
-import { updateQuestion } from "../../models/question.js";
-import Resolver from "../../resolver.js";
-import { updatePerson } from "../../models/person.js";
-
-/**
- * Handler for the Update activity
- */
-export default async (
-	actor: CacheableRemoteUser,
-	activity: IUpdate,
-): Promise<string> => {
-	if ("actor" in activity && actor.uri !== activity.actor) {
-		return "skip: invalid actor";
-	}
-
-	apLogger.debug("Update");
-
-	const resolver = new Resolver();
-
-	const object = await resolver.resolve(activity.object).catch((e) => {
-		apLogger.error(`Resolution failed: ${e}`);
-		throw e;
-	});
-
-	if (isActor(object)) {
-		await updatePerson(actor.uri!, resolver, object);
-		return "ok: Person updated";
-	} else if (getApType(object) === "Question") {
-		await updateQuestion(object, resolver).catch((e) => console.log(e));
-		return "ok: Question updated";
-	} else {
-		return `skip: Unknown type: ${getApType(object)}`;
-	}
-};
diff --git a/packages/backend/src/remote/activitypub/logger.ts b/packages/backend/src/remote/activitypub/logger.ts
deleted file mode 100644
index 47383cf7fa..0000000000
--- a/packages/backend/src/remote/activitypub/logger.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import { remoteLogger } from "../logger.js";
-
-export const apLogger = remoteLogger.createSubLogger("ap", "magenta");
diff --git a/packages/backend/src/remote/activitypub/misc/contexts.ts b/packages/backend/src/remote/activitypub/misc/contexts.ts
deleted file mode 100644
index 8c97b59729..0000000000
--- a/packages/backend/src/remote/activitypub/misc/contexts.ts
+++ /dev/null
@@ -1,525 +0,0 @@
-const id_v1 = {
-	"@context": {
-		id: "@id",
-		type: "@type",
-
-		cred: "https://w3id.org/credentials#",
-		dc: "http://purl.org/dc/terms/",
-		identity: "https://w3id.org/identity#",
-		perm: "https://w3id.org/permissions#",
-		ps: "https://w3id.org/payswarm#",
-		rdf: "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
-		rdfs: "http://www.w3.org/2000/01/rdf-schema#",
-		sec: "https://w3id.org/security#",
-		schema: "http://schema.org/",
-		xsd: "http://www.w3.org/2001/XMLSchema#",
-
-		Group: "https://www.w3.org/ns/activitystreams#Group",
-
-		claim: { "@id": "cred:claim", "@type": "@id" },
-		credential: { "@id": "cred:credential", "@type": "@id" },
-		issued: { "@id": "cred:issued", "@type": "xsd:dateTime" },
-		issuer: { "@id": "cred:issuer", "@type": "@id" },
-		recipient: { "@id": "cred:recipient", "@type": "@id" },
-		Credential: "cred:Credential",
-		CryptographicKeyCredential: "cred:CryptographicKeyCredential",
-
-		about: { "@id": "schema:about", "@type": "@id" },
-		address: { "@id": "schema:address", "@type": "@id" },
-		addressCountry: "schema:addressCountry",
-		addressLocality: "schema:addressLocality",
-		addressRegion: "schema:addressRegion",
-		comment: "rdfs:comment",
-		created: { "@id": "dc:created", "@type": "xsd:dateTime" },
-		creator: { "@id": "dc:creator", "@type": "@id" },
-		description: "schema:description",
-		email: "schema:email",
-		familyName: "schema:familyName",
-		givenName: "schema:givenName",
-		image: { "@id": "schema:image", "@type": "@id" },
-		label: "rdfs:label",
-		name: "schema:name",
-		postalCode: "schema:postalCode",
-		streetAddress: "schema:streetAddress",
-		title: "dc:title",
-		url: { "@id": "schema:url", "@type": "@id" },
-		Person: "schema:Person",
-		PostalAddress: "schema:PostalAddress",
-		Organization: "schema:Organization",
-
-		identityService: { "@id": "identity:identityService", "@type": "@id" },
-		idp: { "@id": "identity:idp", "@type": "@id" },
-		Identity: "identity:Identity",
-
-		paymentProcessor: "ps:processor",
-		preferences: { "@id": "ps:preferences", "@type": "@vocab" },
-
-		cipherAlgorithm: "sec:cipherAlgorithm",
-		cipherData: "sec:cipherData",
-		cipherKey: "sec:cipherKey",
-		digestAlgorithm: "sec:digestAlgorithm",
-		digestValue: "sec:digestValue",
-		domain: "sec:domain",
-		expires: { "@id": "sec:expiration", "@type": "xsd:dateTime" },
-		initializationVector: "sec:initializationVector",
-		member: { "@id": "schema:member", "@type": "@id" },
-		memberOf: { "@id": "schema:memberOf", "@type": "@id" },
-		nonce: "sec:nonce",
-		normalizationAlgorithm: "sec:normalizationAlgorithm",
-		owner: { "@id": "sec:owner", "@type": "@id" },
-		password: "sec:password",
-		privateKey: { "@id": "sec:privateKey", "@type": "@id" },
-		privateKeyPem: "sec:privateKeyPem",
-		publicKey: { "@id": "sec:publicKey", "@type": "@id" },
-		publicKeyPem: "sec:publicKeyPem",
-		publicKeyService: { "@id": "sec:publicKeyService", "@type": "@id" },
-		revoked: { "@id": "sec:revoked", "@type": "xsd:dateTime" },
-		signature: "sec:signature",
-		signatureAlgorithm: "sec:signatureAlgorithm",
-		signatureValue: "sec:signatureValue",
-		CryptographicKey: "sec:Key",
-		EncryptedMessage: "sec:EncryptedMessage",
-		GraphSignature2012: "sec:GraphSignature2012",
-		LinkedDataSignature2015: "sec:LinkedDataSignature2015",
-
-		accessControl: { "@id": "perm:accessControl", "@type": "@id" },
-		writePermission: { "@id": "perm:writePermission", "@type": "@id" },
-	},
-};
-
-const security_v1 = {
-	"@context": {
-		id: "@id",
-		type: "@type",
-
-		dc: "http://purl.org/dc/terms/",
-		sec: "https://w3id.org/security#",
-		xsd: "http://www.w3.org/2001/XMLSchema#",
-
-		EcdsaKoblitzSignature2016: "sec:EcdsaKoblitzSignature2016",
-		Ed25519Signature2018: "sec:Ed25519Signature2018",
-		EncryptedMessage: "sec:EncryptedMessage",
-		GraphSignature2012: "sec:GraphSignature2012",
-		LinkedDataSignature2015: "sec:LinkedDataSignature2015",
-		LinkedDataSignature2016: "sec:LinkedDataSignature2016",
-		CryptographicKey: "sec:Key",
-
-		authenticationTag: "sec:authenticationTag",
-		canonicalizationAlgorithm: "sec:canonicalizationAlgorithm",
-		cipherAlgorithm: "sec:cipherAlgorithm",
-		cipherData: "sec:cipherData",
-		cipherKey: "sec:cipherKey",
-		created: { "@id": "dc:created", "@type": "xsd:dateTime" },
-		creator: { "@id": "dc:creator", "@type": "@id" },
-		digestAlgorithm: "sec:digestAlgorithm",
-		digestValue: "sec:digestValue",
-		domain: "sec:domain",
-		encryptionKey: "sec:encryptionKey",
-		expiration: { "@id": "sec:expiration", "@type": "xsd:dateTime" },
-		expires: { "@id": "sec:expiration", "@type": "xsd:dateTime" },
-		initializationVector: "sec:initializationVector",
-		iterationCount: "sec:iterationCount",
-		nonce: "sec:nonce",
-		normalizationAlgorithm: "sec:normalizationAlgorithm",
-		owner: { "@id": "sec:owner", "@type": "@id" },
-		password: "sec:password",
-		privateKey: { "@id": "sec:privateKey", "@type": "@id" },
-		privateKeyPem: "sec:privateKeyPem",
-		publicKey: { "@id": "sec:publicKey", "@type": "@id" },
-		publicKeyBase58: "sec:publicKeyBase58",
-		publicKeyPem: "sec:publicKeyPem",
-		publicKeyWif: "sec:publicKeyWif",
-		publicKeyService: { "@id": "sec:publicKeyService", "@type": "@id" },
-		revoked: { "@id": "sec:revoked", "@type": "xsd:dateTime" },
-		salt: "sec:salt",
-		signature: "sec:signature",
-		signatureAlgorithm: "sec:signingAlgorithm",
-		signatureValue: "sec:signatureValue",
-	},
-};
-
-const activitystreams = {
-	"@context": {
-		"@vocab": "_:",
-		xsd: "http://www.w3.org/2001/XMLSchema#",
-		as: "https://www.w3.org/ns/activitystreams#",
-		ldp: "http://www.w3.org/ns/ldp#",
-		vcard: "http://www.w3.org/2006/vcard/ns#",
-		id: "@id",
-		type: "@type",
-		Accept: "as:Accept",
-		Activity: "as:Activity",
-		IntransitiveActivity: "as:IntransitiveActivity",
-		Add: "as:Add",
-		Announce: "as:Announce",
-		Application: "as:Application",
-		Arrive: "as:Arrive",
-		Article: "as:Article",
-		Audio: "as:Audio",
-		Block: "as:Block",
-		Collection: "as:Collection",
-		CollectionPage: "as:CollectionPage",
-		Relationship: "as:Relationship",
-		Create: "as:Create",
-		Delete: "as:Delete",
-		Dislike: "as:Dislike",
-		Document: "as:Document",
-		Event: "as:Event",
-		Follow: "as:Follow",
-		Flag: "as:Flag",
-		Group: "as:Group",
-		Ignore: "as:Ignore",
-		Image: "as:Image",
-		Invite: "as:Invite",
-		Join: "as:Join",
-		Leave: "as:Leave",
-		Like: "as:Like",
-		Link: "as:Link",
-		Mention: "as:Mention",
-		Note: "as:Note",
-		Object: "as:Object",
-		Offer: "as:Offer",
-		OrderedCollection: "as:OrderedCollection",
-		OrderedCollectionPage: "as:OrderedCollectionPage",
-		Organization: "as:Organization",
-		Page: "as:Page",
-		Person: "as:Person",
-		Place: "as:Place",
-		Profile: "as:Profile",
-		Question: "as:Question",
-		Reject: "as:Reject",
-		Remove: "as:Remove",
-		Service: "as:Service",
-		TentativeAccept: "as:TentativeAccept",
-		TentativeReject: "as:TentativeReject",
-		Tombstone: "as:Tombstone",
-		Undo: "as:Undo",
-		Update: "as:Update",
-		Video: "as:Video",
-		View: "as:View",
-		Listen: "as:Listen",
-		Read: "as:Read",
-		Move: "as:Move",
-		Travel: "as:Travel",
-		IsFollowing: "as:IsFollowing",
-		IsFollowedBy: "as:IsFollowedBy",
-		IsContact: "as:IsContact",
-		IsMember: "as:IsMember",
-		subject: {
-			"@id": "as:subject",
-			"@type": "@id",
-		},
-		relationship: {
-			"@id": "as:relationship",
-			"@type": "@id",
-		},
-		actor: {
-			"@id": "as:actor",
-			"@type": "@id",
-		},
-		attributedTo: {
-			"@id": "as:attributedTo",
-			"@type": "@id",
-		},
-		attachment: {
-			"@id": "as:attachment",
-			"@type": "@id",
-		},
-		bcc: {
-			"@id": "as:bcc",
-			"@type": "@id",
-		},
-		bto: {
-			"@id": "as:bto",
-			"@type": "@id",
-		},
-		cc: {
-			"@id": "as:cc",
-			"@type": "@id",
-		},
-		context: {
-			"@id": "as:context",
-			"@type": "@id",
-		},
-		current: {
-			"@id": "as:current",
-			"@type": "@id",
-		},
-		first: {
-			"@id": "as:first",
-			"@type": "@id",
-		},
-		generator: {
-			"@id": "as:generator",
-			"@type": "@id",
-		},
-		icon: {
-			"@id": "as:icon",
-			"@type": "@id",
-		},
-		image: {
-			"@id": "as:image",
-			"@type": "@id",
-		},
-		inReplyTo: {
-			"@id": "as:inReplyTo",
-			"@type": "@id",
-		},
-		items: {
-			"@id": "as:items",
-			"@type": "@id",
-		},
-		instrument: {
-			"@id": "as:instrument",
-			"@type": "@id",
-		},
-		orderedItems: {
-			"@id": "as:items",
-			"@type": "@id",
-			"@container": "@list",
-		},
-		last: {
-			"@id": "as:last",
-			"@type": "@id",
-		},
-		location: {
-			"@id": "as:location",
-			"@type": "@id",
-		},
-		next: {
-			"@id": "as:next",
-			"@type": "@id",
-		},
-		object: {
-			"@id": "as:object",
-			"@type": "@id",
-		},
-		oneOf: {
-			"@id": "as:oneOf",
-			"@type": "@id",
-		},
-		anyOf: {
-			"@id": "as:anyOf",
-			"@type": "@id",
-		},
-		closed: {
-			"@id": "as:closed",
-			"@type": "xsd:dateTime",
-		},
-		origin: {
-			"@id": "as:origin",
-			"@type": "@id",
-		},
-		accuracy: {
-			"@id": "as:accuracy",
-			"@type": "xsd:float",
-		},
-		prev: {
-			"@id": "as:prev",
-			"@type": "@id",
-		},
-		preview: {
-			"@id": "as:preview",
-			"@type": "@id",
-		},
-		replies: {
-			"@id": "as:replies",
-			"@type": "@id",
-		},
-		result: {
-			"@id": "as:result",
-			"@type": "@id",
-		},
-		audience: {
-			"@id": "as:audience",
-			"@type": "@id",
-		},
-		partOf: {
-			"@id": "as:partOf",
-			"@type": "@id",
-		},
-		tag: {
-			"@id": "as:tag",
-			"@type": "@id",
-		},
-		target: {
-			"@id": "as:target",
-			"@type": "@id",
-		},
-		to: {
-			"@id": "as:to",
-			"@type": "@id",
-		},
-		url: {
-			"@id": "as:url",
-			"@type": "@id",
-		},
-		altitude: {
-			"@id": "as:altitude",
-			"@type": "xsd:float",
-		},
-		content: "as:content",
-		contentMap: {
-			"@id": "as:content",
-			"@container": "@language",
-		},
-		name: "as:name",
-		nameMap: {
-			"@id": "as:name",
-			"@container": "@language",
-		},
-		duration: {
-			"@id": "as:duration",
-			"@type": "xsd:duration",
-		},
-		endTime: {
-			"@id": "as:endTime",
-			"@type": "xsd:dateTime",
-		},
-		height: {
-			"@id": "as:height",
-			"@type": "xsd:nonNegativeInteger",
-		},
-		href: {
-			"@id": "as:href",
-			"@type": "@id",
-		},
-		hreflang: "as:hreflang",
-		latitude: {
-			"@id": "as:latitude",
-			"@type": "xsd:float",
-		},
-		longitude: {
-			"@id": "as:longitude",
-			"@type": "xsd:float",
-		},
-		mediaType: "as:mediaType",
-		published: {
-			"@id": "as:published",
-			"@type": "xsd:dateTime",
-		},
-		radius: {
-			"@id": "as:radius",
-			"@type": "xsd:float",
-		},
-		rel: "as:rel",
-		startIndex: {
-			"@id": "as:startIndex",
-			"@type": "xsd:nonNegativeInteger",
-		},
-		startTime: {
-			"@id": "as:startTime",
-			"@type": "xsd:dateTime",
-		},
-		summary: "as:summary",
-		summaryMap: {
-			"@id": "as:summary",
-			"@container": "@language",
-		},
-		totalItems: {
-			"@id": "as:totalItems",
-			"@type": "xsd:nonNegativeInteger",
-		},
-		units: "as:units",
-		updated: {
-			"@id": "as:updated",
-			"@type": "xsd:dateTime",
-		},
-		width: {
-			"@id": "as:width",
-			"@type": "xsd:nonNegativeInteger",
-		},
-		describes: {
-			"@id": "as:describes",
-			"@type": "@id",
-		},
-		formerType: {
-			"@id": "as:formerType",
-			"@type": "@id",
-		},
-		deleted: {
-			"@id": "as:deleted",
-			"@type": "xsd:dateTime",
-		},
-		inbox: {
-			"@id": "ldp:inbox",
-			"@type": "@id",
-		},
-		outbox: {
-			"@id": "as:outbox",
-			"@type": "@id",
-		},
-		following: {
-			"@id": "as:following",
-			"@type": "@id",
-		},
-		followers: {
-			"@id": "as:followers",
-			"@type": "@id",
-		},
-		streams: {
-			"@id": "as:streams",
-			"@type": "@id",
-		},
-		preferredUsername: "as:preferredUsername",
-		endpoints: {
-			"@id": "as:endpoints",
-			"@type": "@id",
-		},
-		uploadMedia: {
-			"@id": "as:uploadMedia",
-			"@type": "@id",
-		},
-		proxyUrl: {
-			"@id": "as:proxyUrl",
-			"@type": "@id",
-		},
-		liked: {
-			"@id": "as:liked",
-			"@type": "@id",
-		},
-		oauthAuthorizationEndpoint: {
-			"@id": "as:oauthAuthorizationEndpoint",
-			"@type": "@id",
-		},
-		oauthTokenEndpoint: {
-			"@id": "as:oauthTokenEndpoint",
-			"@type": "@id",
-		},
-		provideClientKey: {
-			"@id": "as:provideClientKey",
-			"@type": "@id",
-		},
-		signClientKey: {
-			"@id": "as:signClientKey",
-			"@type": "@id",
-		},
-		sharedInbox: {
-			"@id": "as:sharedInbox",
-			"@type": "@id",
-		},
-		Public: {
-			"@id": "as:Public",
-			"@type": "@id",
-		},
-		source: "as:source",
-		likes: {
-			"@id": "as:likes",
-			"@type": "@id",
-		},
-		shares: {
-			"@id": "as:shares",
-			"@type": "@id",
-		},
-		alsoKnownAs: {
-			"@id": "as:alsoKnownAs",
-			"@type": "@id",
-		},
-	},
-};
-
-export const CONTEXTS: Record<string, unknown> = {
-	"https://w3id.org/identity/v1": id_v1,
-	"https://w3id.org/security/v1": security_v1,
-	"https://www.w3.org/ns/activitystreams": activitystreams,
-};
diff --git a/packages/backend/src/remote/activitypub/misc/get-note-html.ts b/packages/backend/src/remote/activitypub/misc/get-note-html.ts
deleted file mode 100644
index cb5294f731..0000000000
--- a/packages/backend/src/remote/activitypub/misc/get-note-html.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import * as mfm from "mfm-js";
-import type { Note } from "@/models/entities/note.js";
-import { toHtml } from "../../../mfm/to-html.js";
-
-export default function (note: Note) {
-	if (!note.text) return "";
-	return toHtml(mfm.parse(note.text), JSON.parse(note.mentionedRemoteUsers));
-}
diff --git a/packages/backend/src/remote/activitypub/misc/html-to-mfm.ts b/packages/backend/src/remote/activitypub/misc/html-to-mfm.ts
deleted file mode 100644
index 9d71a46a36..0000000000
--- a/packages/backend/src/remote/activitypub/misc/html-to-mfm.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import type { IObject } from "../type.js";
-import { extractApHashtagObjects } from "../models/tag.js";
-import { fromHtml } from "../../../mfm/from-html.js";
-
-export function htmlToMfm(html: string, tag?: IObject | IObject[]) {
-	const hashtagNames = extractApHashtagObjects(tag)
-		.map((x) => x.name)
-		.filter((x): x is string => x != null);
-
-	return fromHtml(html, hashtagNames);
-}
diff --git a/packages/backend/src/remote/activitypub/misc/ld-signature.ts b/packages/backend/src/remote/activitypub/misc/ld-signature.ts
deleted file mode 100644
index 1657597ab6..0000000000
--- a/packages/backend/src/remote/activitypub/misc/ld-signature.ts
+++ /dev/null
@@ -1,143 +0,0 @@
-import * as crypto from "node:crypto";
-import jsonld from "jsonld";
-import { CONTEXTS } from "./contexts.js";
-import fetch from "node-fetch";
-import { httpAgent, httpsAgent } from "@/misc/fetch.js";
-
-// RsaSignature2017 based from https://github.com/transmute-industries/RsaSignature2017
-
-export class LdSignature {
-	public debug = false;
-	public preLoad = true;
-	public loderTimeout = 10 * 1000;
-
-	constructor() {}
-
-	public async signRsaSignature2017(
-		data: any,
-		privateKey: string,
-		creator: string,
-		domain?: string,
-		created?: Date,
-	): Promise<any> {
-		const options = {
-			type: "RsaSignature2017",
-			creator,
-			domain,
-			nonce: crypto.randomBytes(16).toString("hex"),
-			created: (created || new Date()).toISOString(),
-		} as {
-			type: string;
-			creator: string;
-			domain?: string;
-			nonce: string;
-			created: string;
-		};
-
-		if (!domain) {
-			options.domain = undefined;
-		}
-
-		const toBeSigned = await this.createVerifyData(data, options);
-
-		const signer = crypto.createSign("sha256");
-		signer.update(toBeSigned);
-		signer.end();
-
-		const signature = signer.sign(privateKey);
-
-		return {
-			...data,
-			signature: {
-				...options,
-				signatureValue: signature.toString("base64"),
-			},
-		};
-	}
-
-	public async verifyRsaSignature2017(
-		data: any,
-		publicKey: string,
-	): Promise<boolean> {
-		const toBeSigned = await this.createVerifyData(data, data.signature);
-		const verifier = crypto.createVerify("sha256");
-		verifier.update(toBeSigned);
-		return verifier.verify(publicKey, data.signature.signatureValue, "base64");
-	}
-
-	public async createVerifyData(data: any, options: any) {
-		const transformedOptions = {
-			...options,
-			"@context": "https://w3id.org/identity/v1",
-		};
-		delete transformedOptions["type"];
-		delete transformedOptions["id"];
-		delete transformedOptions["signatureValue"];
-		const canonizedOptions = await this.normalize(transformedOptions);
-		const optionsHash = this.sha256(canonizedOptions);
-		const transformedData = { ...data };
-		delete transformedData["signature"];
-		const cannonidedData = await this.normalize(transformedData);
-		if (this.debug) console.debug(`cannonidedData: ${cannonidedData}`);
-		const documentHash = this.sha256(cannonidedData);
-		const verifyData = `${optionsHash}${documentHash}`;
-		return verifyData;
-	}
-
-	public async normalize(data: any) {
-		const customLoader = this.getLoader();
-		return await jsonld.normalize(data, {
-			documentLoader: customLoader,
-		});
-	}
-
-	private getLoader() {
-		return async (url: string): Promise<any> => {
-			if (!url.match("^https?://")) throw new Error(`Invalid URL ${url}`);
-
-			if (this.preLoad) {
-				if (url in CONTEXTS) {
-					if (this.debug) console.debug(`HIT: ${url}`);
-					return {
-						contextUrl: null,
-						document: CONTEXTS[url],
-						documentUrl: url,
-					};
-				}
-			}
-
-			if (this.debug) console.debug(`MISS: ${url}`);
-			const document = await this.fetchDocument(url);
-			return {
-				contextUrl: null,
-				document: document,
-				documentUrl: url,
-			};
-		};
-	}
-
-	private async fetchDocument(url: string) {
-		const json = await fetch(url, {
-			headers: {
-				Accept: "application/ld+json, application/json",
-			},
-			// TODO
-			//timeout: this.loderTimeout,
-			agent: (u) => (u.protocol === "http:" ? httpAgent : httpsAgent),
-		}).then((res) => {
-			if (!res.ok) {
-				throw new Error(`${res.status} ${res.statusText}`);
-			} else {
-				return res.json();
-			}
-		});
-
-		return json;
-	}
-
-	public sha256(data: string): string {
-		const hash = crypto.createHash("sha256");
-		hash.update(data);
-		return hash.digest("hex");
-	}
-}
diff --git a/packages/backend/src/remote/activitypub/models/icon.ts b/packages/backend/src/remote/activitypub/models/icon.ts
deleted file mode 100644
index 50794a937d..0000000000
--- a/packages/backend/src/remote/activitypub/models/icon.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-export type IIcon = {
-	type: string;
-	mediaType?: string;
-	url?: string;
-};
diff --git a/packages/backend/src/remote/activitypub/models/identifier.ts b/packages/backend/src/remote/activitypub/models/identifier.ts
deleted file mode 100644
index f6c3bb8c88..0000000000
--- a/packages/backend/src/remote/activitypub/models/identifier.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-export type IIdentifier = {
-	type: string;
-	name: string;
-	value: string;
-};
diff --git a/packages/backend/src/remote/activitypub/models/image.ts b/packages/backend/src/remote/activitypub/models/image.ts
deleted file mode 100644
index 211aa3931e..0000000000
--- a/packages/backend/src/remote/activitypub/models/image.ts
+++ /dev/null
@@ -1,82 +0,0 @@
-import { uploadFromUrl } from "@/services/drive/upload-from-url.js";
-import type { CacheableRemoteUser } from "@/models/entities/user.js";
-import { IRemoteUser } from "@/models/entities/user.js";
-import Resolver from "../resolver.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { apLogger } from "../logger.js";
-import type { DriveFile } from "@/models/entities/drive-file.js";
-import { DriveFiles, Users } from "@/models/index.js";
-import { truncate } from "@/misc/truncate.js";
-import { DB_MAX_IMAGE_COMMENT_LENGTH } from "@/misc/hard-limits.js";
-
-const logger = apLogger;
-
-/**
- * create an Image.
- */
-export async function createImage(
-	actor: CacheableRemoteUser,
-	value: any,
-): Promise<DriveFile> {
-	// Skip if author is frozen.
-	if (actor.isSuspended) {
-		throw new Error("actor has been suspended");
-	}
-
-	const image = (await new Resolver().resolve(value)) as any;
-
-	if (image.url == null) {
-		throw new Error("invalid image: url not privided");
-	}
-
-	if (!image.url.startsWith("https://") && !image.url.startsWith("http://")) {
-		throw new Error("invalid image: unexpected shcema of url: " + image.url);
-	}
-
-	logger.info(`Creating the Image: ${image.url}`);
-
-	const instance = await fetchMeta();
-
-	let file = await uploadFromUrl({
-		url: image.url,
-		user: actor,
-		uri: image.url,
-		sensitive: image.sensitive,
-		isLink: !instance.cacheRemoteFiles,
-		comment: truncate(image.name, DB_MAX_IMAGE_COMMENT_LENGTH),
-	});
-
-	if (file.isLink) {
-		// If the URL is different, it means that the same image was previously
-		// registered with a different URL, so update the URL
-		if (file.url !== image.url) {
-			await DriveFiles.update(
-				{ id: file.id },
-				{
-					url: image.url,
-					uri: image.url,
-				},
-			);
-
-			file = await DriveFiles.findOneByOrFail({ id: file.id });
-		}
-	}
-
-	return file;
-}
-
-/**
- * Resolve Image.
- *
- * If the target Image is registered in Calckey, return it, otherwise
- * Fetch from remote server, register with Calckey and return it.
- */
-export async function resolveImage(
-	actor: CacheableRemoteUser,
-	value: any,
-): Promise<DriveFile> {
-	// TODO
-
-	// Fetch from remote server and register
-	return await createImage(actor, value);
-}
diff --git a/packages/backend/src/remote/activitypub/models/mention.ts b/packages/backend/src/remote/activitypub/models/mention.ts
deleted file mode 100644
index b888fa21a4..0000000000
--- a/packages/backend/src/remote/activitypub/models/mention.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import promiseLimit from "promise-limit";
-import { toArray, unique } from "@/prelude/array.js";
-import type { CacheableUser } from "@/models/entities/user.js";
-import { User } from "@/models/entities/user.js";
-import type { IObject, IApMention } from "../type.js";
-import { isMention } from "../type.js";
-import Resolver from "../resolver.js";
-import { resolvePerson } from "./person.js";
-
-export async function extractApMentions(
-	tags: IObject | IObject[] | null | undefined,
-) {
-	const hrefs = unique(
-		extractApMentionObjects(tags).map((x) => x.href as string),
-	);
-
-	const resolver = new Resolver();
-
-	const limit = promiseLimit<CacheableUser | null>(2);
-	const mentionedUsers = (
-		await Promise.all(
-			hrefs.map((x) =>
-				limit(() => resolvePerson(x, resolver).catch(() => null)),
-			),
-		)
-	).filter((x): x is CacheableUser => x != null);
-
-	return mentionedUsers;
-}
-
-export function extractApMentionObjects(
-	tags: IObject | IObject[] | null | undefined,
-): IApMention[] {
-	if (tags == null) return [];
-	return toArray(tags).filter(isMention);
-}
diff --git a/packages/backend/src/remote/activitypub/models/note.ts b/packages/backend/src/remote/activitypub/models/note.ts
deleted file mode 100644
index 033157b081..0000000000
--- a/packages/backend/src/remote/activitypub/models/note.ts
+++ /dev/null
@@ -1,499 +0,0 @@
-import promiseLimit from "promise-limit";
-
-import config from "@/config/index.js";
-import Resolver from "../resolver.js";
-import post from "@/services/note/create.js";
-import { resolvePerson } from "./person.js";
-import { resolveImage } from "./image.js";
-import type { CacheableRemoteUser } from "@/models/entities/user.js";
-import { htmlToMfm } from "../misc/html-to-mfm.js";
-import { extractApHashtags } from "./tag.js";
-import { unique, toArray, toSingle } from "@/prelude/array.js";
-import { extractPollFromQuestion } from "./question.js";
-import vote from "@/services/note/polls/vote.js";
-import { apLogger } from "../logger.js";
-import type { DriveFile } from "@/models/entities/drive-file.js";
-import { deliverQuestionUpdate } from "@/services/note/polls/update.js";
-import { extractDbHost, toPuny } from "@/misc/convert-host.js";
-import { Emojis, Polls, MessagingMessages } from "@/models/index.js";
-import type { Note } from "@/models/entities/note.js";
-import type { IObject, IPost } from "../type.js";
-import {
-	getOneApId,
-	getApId,
-	getOneApHrefNullable,
-	validPost,
-	isEmoji,
-	getApType,
-} from "../type.js";
-import type { Emoji } from "@/models/entities/emoji.js";
-import { genId } from "@/misc/gen-id.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { getApLock } from "@/misc/app-lock.js";
-import { createMessage } from "@/services/messages/create.js";
-import { parseAudience } from "../audience.js";
-import { extractApMentions } from "./mention.js";
-import DbResolver from "../db-resolver.js";
-import { StatusError } from "@/misc/fetch.js";
-import { shouldBlockInstance } from "@/misc/should-block-instance.js";
-
-const logger = apLogger;
-
-export function validateNote(object: any, uri: string) {
-	const expectHost = extractDbHost(uri);
-
-	if (object == null) {
-		return new Error("invalid Note: object is null");
-	}
-
-	if (!validPost.includes(getApType(object))) {
-		return new Error(`invalid Note: invalid object type ${getApType(object)}`);
-	}
-
-	if (object.id && extractDbHost(object.id) !== expectHost) {
-		return new Error(
-			`invalid Note: id has different host. expected: ${expectHost}, actual: ${extractDbHost(
-				object.id,
-			)}`,
-		);
-	}
-
-	if (
-		object.attributedTo &&
-		extractDbHost(getOneApId(object.attributedTo)) !== expectHost
-	) {
-		return new Error(
-			`invalid Note: attributedTo has different host. expected: ${expectHost}, actual: ${extractDbHost(
-				object.attributedTo,
-			)}`,
-		);
-	}
-
-	return null;
-}
-
-/**
- * Fetch Notes.
- *
- * If the target Note is registered in Calckey, it will be returned.
- */
-export async function fetchNote(
-	object: string | IObject,
-): Promise<Note | null> {
-	const dbResolver = new DbResolver();
-	return await dbResolver.getNoteFromApId(object);
-}
-
-/**
- * Create a Note.
- */
-export async function createNote(
-	value: string | IObject,
-	resolver?: Resolver,
-	silent = false,
-): Promise<Note | null> {
-	if (resolver == null) resolver = new Resolver();
-
-	const object: any = await resolver.resolve(value);
-
-	const entryUri = getApId(value);
-	const err = validateNote(object, entryUri);
-	if (err) {
-		logger.error(`${err.message}`, {
-			resolver: {
-				history: resolver.getHistory(),
-			},
-			value: value,
-			object: object,
-		});
-		throw new Error("invalid note");
-	}
-
-	const note: IPost = object;
-
-	if (note.id && !note.id.startsWith("https://")) {
-		throw new Error(`unexpected schema of note.id: ${note.id}`);
-	}
-
-	const url = getOneApHrefNullable(note.url);
-
-	if (url && !url.startsWith("https://")) {
-		throw new Error(`unexpected schema of note url: ${url}`);
-	}
-
-	logger.debug(`Note fetched: ${JSON.stringify(note, null, 2)}`);
-	logger.info(`Creating the Note: ${note.id}`);
-
-	// Skip if note is made before 2007 (1yr before Fedi was created)
-	// OR skip if note is made 3 days in advance
-	if (note.published) {
-		const DateChecker = new Date(note.published);
-		const FutureCheck = new Date();
-		FutureCheck.setDate(FutureCheck.getDate() + 3); // Allow some wiggle room for misconfigured hosts
-		if (DateChecker.getFullYear() < 2007) {
-			logger.warn(
-				"Note somehow made before Activitypub was created; discarding",
-			);
-			return null;
-		}
-		if (DateChecker > FutureCheck) {
-			logger.warn("Note somehow made after today; discarding");
-			return null;
-		}
-	}
-
-	// Fetch author
-	const actor = (await resolvePerson(
-		getOneApId(note.attributedTo),
-		resolver,
-	)) as CacheableRemoteUser;
-
-	// Skip if author is suspended.
-	if (actor.isSuspended) {
-		logger.debug(
-			`User ${actor.usernameLower}@${actor.host} suspended; discarding.`,
-		);
-		return null;
-	}
-
-	const noteAudience = await parseAudience(actor, note.to, note.cc);
-	let visibility = noteAudience.visibility;
-	const visibleUsers = noteAudience.visibleUsers;
-
-	// If Audience (to, cc) was not specified
-	if (visibility === "specified" && visibleUsers.length === 0) {
-		if (typeof value === "string") {
-			// If the input is a string, GET occurs in resolver
-			// Public if you can GET anonymously from here
-			visibility = "public";
-		}
-	}
-
-	let isTalk = note._misskey_talk && visibility === "specified";
-
-	const apMentions = await extractApMentions(note.tag);
-	const apHashtags = await extractApHashtags(note.tag);
-
-	// Attachments
-	// TODO: attachmentは必ずしもImageではない
-	// TODO: attachmentは必ずしも配列ではない
-	// Noteがsensitiveなら添付もsensitiveにする
-	const limit = promiseLimit(2);
-
-	note.attachment = Array.isArray(note.attachment)
-		? note.attachment
-		: note.attachment
-		? [note.attachment]
-		: [];
-	const files = note.attachment.map(
-		(attach) => (attach.sensitive = note.sensitive),
-	)
-		? (
-				await Promise.all(
-					note.attachment.map(
-						(x) => limit(() => resolveImage(actor, x)) as Promise<DriveFile>,
-					),
-				)
-		  ).filter((image) => image != null)
-		: [];
-
-	// Reply
-	const reply: Note | null = note.inReplyTo
-		? await resolveNote(note.inReplyTo, resolver)
-				.then((x) => {
-					if (x == null) {
-						logger.warn("Specified inReplyTo, but nout found");
-						throw new Error("inReplyTo not found");
-					} else {
-						return x;
-					}
-				})
-				.catch(async (e) => {
-					// トークだったらinReplyToのエラーは無視
-					const uri = getApId(note.inReplyTo);
-					if (uri.startsWith(`${config.url}/`)) {
-						const id = uri.split("/").pop();
-						const talk = await MessagingMessages.findOneBy({ id });
-						if (talk) {
-							isTalk = true;
-							return null;
-						}
-					}
-
-					logger.warn(
-						`Error in inReplyTo ${note.inReplyTo} - ${e.statusCode || e}`,
-					);
-					throw e;
-				})
-		: null;
-
-	// Quote
-	let quote: Note | undefined | null;
-
-	if (note._misskey_quote || note.quoteUrl || note.quoteUri) {
-		const tryResolveNote = async (
-			uri: string,
-		): Promise<
-			| {
-					status: "ok";
-					res: Note | null;
-			  }
-			| {
-					status: "permerror" | "temperror";
-			  }
-		> => {
-			if (typeof uri !== "string" || !uri.match(/^https?:/))
-				return { status: "permerror" };
-			try {
-				const res = await resolveNote(uri);
-				if (res) {
-					return {
-						status: "ok",
-						res,
-					};
-				} else {
-					return {
-						status: "permerror",
-					};
-				}
-			} catch (e) {
-				return {
-					status:
-						e instanceof StatusError && e.isClientError
-							? "permerror"
-							: "temperror",
-				};
-			}
-		};
-
-		const uris = unique(
-			[note._misskey_quote, note.quoteUrl, note.quoteUri].filter(
-				(x): x is string => typeof x === "string",
-			),
-		);
-		const results = await Promise.all(uris.map((uri) => tryResolveNote(uri)));
-
-		quote = results
-			.filter((x): x is { status: "ok"; res: Note | null } => x.status === "ok")
-			.map((x) => x.res)
-			.find((x) => x);
-		if (!quote) {
-			if (results.some((x) => x.status === "temperror")) {
-				throw new Error("quote resolve failed");
-			}
-		}
-	}
-
-	const cw = note.summary === "" ? null : note.summary;
-
-	// Text parsing
-	let text: string | null = null;
-	if (
-		note.source?.mediaType === "text/x.misskeymarkdown" &&
-		typeof note.source?.content === "string"
-	) {
-		text = note.source.content;
-	} else if (typeof note._misskey_content !== "undefined") {
-		text = note._misskey_content;
-	} else if (typeof note.content === "string") {
-		text = htmlToMfm(note.content, note.tag);
-	}
-
-	// vote
-	if (reply?.hasPoll) {
-		const poll = await Polls.findOneByOrFail({ noteId: reply.id });
-
-		const tryCreateVote = async (
-			name: string,
-			index: number,
-		): Promise<null> => {
-			if (poll.expiresAt && Date.now() > new Date(poll.expiresAt).getTime()) {
-				logger.warn(
-					`vote to expired poll from AP: actor=${actor.username}@${actor.host}, note=${note.id}, choice=${name}`,
-				);
-			} else if (index >= 0) {
-				logger.info(
-					`vote from AP: actor=${actor.username}@${actor.host}, note=${note.id}, choice=${name}`,
-				);
-				await vote(actor, reply, index);
-
-				// リモートフォロワーにUpdate配信
-				deliverQuestionUpdate(reply.id);
-			}
-			return null;
-		};
-
-		if (note.name) {
-			return await tryCreateVote(
-				note.name,
-				poll.choices.findIndex((x) => x === note.name),
-			);
-		}
-	}
-
-	const emojis = await extractEmojis(note.tag || [], actor.host).catch((e) => {
-		logger.info(`extractEmojis: ${e}`);
-		return [] as Emoji[];
-	});
-
-	const apEmojis = emojis.map((emoji) => emoji.name);
-
-	const poll = await extractPollFromQuestion(note, resolver).catch(
-		() => undefined,
-	);
-
-	if (isTalk) {
-		for (const recipient of visibleUsers) {
-			await createMessage(
-				actor,
-				recipient,
-				undefined,
-				text || undefined,
-				files && files.length > 0 ? files[0] : null,
-				object.id,
-			);
-			return null;
-		}
-	}
-
-	return await post(
-		actor,
-		{
-			createdAt: note.published ? new Date(note.published) : null,
-			files,
-			reply,
-			renote: quote,
-			name: note.name,
-			cw,
-			text,
-			localOnly: false,
-			visibility,
-			visibleUsers,
-			apMentions,
-			apHashtags,
-			apEmojis,
-			poll,
-			uri: note.id,
-			url: url,
-		},
-		silent,
-	);
-}
-
-/**
- * Resolve Note.
- *
- * If the target Note is registered in Calckey, return it, otherwise
- * Fetch from remote server, register with Calckey and return it.
- */
-export async function resolveNote(
-	value: string | IObject,
-	resolver?: Resolver,
-): Promise<Note | null> {
-	const uri = typeof value === "string" ? value : value.id;
-	if (uri == null) throw new Error("missing uri");
-
-	// Abort if origin host is blocked
-	if (await shouldBlockInstance(extractDbHost(uri)))
-		throw new StatusError(
-			"host blocked",
-			451,
-			`host ${extractDbHost(uri)} is blocked`,
-		);
-
-	const unlock = await getApLock(uri);
-
-	try {
-		//#region Returns if already registered with this server
-		const exist = await fetchNote(uri);
-
-		if (exist) {
-			return exist;
-		}
-		//#endregion
-
-		if (uri.startsWith(config.url)) {
-			throw new StatusError(
-				"cannot resolve local note",
-				400,
-				"cannot resolve local note",
-			);
-		}
-
-		// Fetch from remote server and register
-		// If the attached `Note` Object is specified here instead of the uri, the note will be generated without going through the server fetch.
-		// Since the attached Note Object may be disguised, always specify the uri and fetch it from the server.
-		return await createNote(uri, resolver, true);
-	} finally {
-		unlock();
-	}
-}
-
-export async function extractEmojis(
-	tags: IObject | IObject[],
-	host: string,
-): Promise<Emoji[]> {
-	host = toPuny(host);
-
-	if (!tags) return [];
-
-	const eomjiTags = toArray(tags).filter(isEmoji);
-
-	return await Promise.all(
-		eomjiTags.map(async (tag) => {
-			const name = tag.name!.replace(/^:/, "").replace(/:$/, "");
-			tag.icon = toSingle(tag.icon);
-
-			const exists = await Emojis.findOneBy({
-				host,
-				name,
-			});
-
-			if (exists) {
-				if (
-					(tag.updated != null && exists.updatedAt == null) ||
-					(tag.id != null && exists.uri == null) ||
-					(tag.updated != null &&
-						exists.updatedAt != null &&
-						new Date(tag.updated) > exists.updatedAt) ||
-					tag.icon!.url !== exists.originalUrl
-				) {
-					await Emojis.update(
-						{
-							host,
-							name,
-						},
-						{
-							uri: tag.id,
-							originalUrl: tag.icon!.url,
-							publicUrl: tag.icon!.url,
-							updatedAt: new Date(),
-						},
-					);
-
-					return (await Emojis.findOneBy({
-						host,
-						name,
-					})) as Emoji;
-				}
-
-				return exists;
-			}
-
-			logger.info(`register emoji host=${host}, name=${name}`);
-
-			return await Emojis.insert({
-				id: genId(),
-				host,
-				name,
-				uri: tag.id,
-				originalUrl: tag.icon!.url,
-				publicUrl: tag.icon!.url,
-				updatedAt: new Date(),
-				aliases: [],
-			} as Partial<Emoji>).then((x) =>
-				Emojis.findOneByOrFail(x.identifiers[0]),
-			);
-		}),
-	);
-}
diff --git a/packages/backend/src/remote/activitypub/models/person.ts b/packages/backend/src/remote/activitypub/models/person.ts
deleted file mode 100644
index 877f5f3323..0000000000
--- a/packages/backend/src/remote/activitypub/models/person.ts
+++ /dev/null
@@ -1,698 +0,0 @@
-import { URL } from "node:url";
-import promiseLimit from "promise-limit";
-
-import config from "@/config/index.js";
-import { registerOrFetchInstanceDoc } from "@/services/register-or-fetch-instance-doc.js";
-import type { Note } from "@/models/entities/note.js";
-import { updateUsertags } from "@/services/update-hashtag.js";
-import {
-	Users,
-	Instances,
-	DriveFiles,
-	Followings,
-	UserProfiles,
-	UserPublickeys,
-} from "@/models/index.js";
-import type { IRemoteUser, CacheableUser } from "@/models/entities/user.js";
-import { User } from "@/models/entities/user.js";
-import type { Emoji } from "@/models/entities/emoji.js";
-import { UserNotePining } from "@/models/entities/user-note-pining.js";
-import { genId } from "@/misc/gen-id.js";
-import { instanceChart, usersChart } from "@/services/chart/index.js";
-import { UserPublickey } from "@/models/entities/user-publickey.js";
-import { isDuplicateKeyValueError } from "@/misc/is-duplicate-key-value-error.js";
-import { toPuny } from "@/misc/convert-host.js";
-import { UserProfile } from "@/models/entities/user-profile.js";
-import { toArray } from "@/prelude/array.js";
-import { fetchInstanceMetadata } from "@/services/fetch-instance-metadata.js";
-import { normalizeForSearch } from "@/misc/normalize-for-search.js";
-import { truncate } from "@/misc/truncate.js";
-import { StatusError } from "@/misc/fetch.js";
-import { uriPersonCache } from "@/services/user-cache.js";
-import { publishInternalEvent } from "@/services/stream.js";
-import { db } from "@/db/postgre.js";
-import { apLogger } from "../logger.js";
-import { htmlToMfm } from "../misc/html-to-mfm.js";
-import { fromHtml } from "../../../mfm/from-html.js";
-import type { IActor, IObject, IApPropertyValue } from "../type.js";
-import {
-	isCollectionOrOrderedCollection,
-	isCollection,
-	getApId,
-	getOneApHrefNullable,
-	isPropertyValue,
-	getApType,
-	isActor,
-} from "../type.js";
-import Resolver from "../resolver.js";
-import { extractApHashtags } from "./tag.js";
-import { resolveNote, extractEmojis } from "./note.js";
-import { resolveImage } from "./image.js";
-
-const logger = apLogger;
-
-const nameLength = 128;
-const summaryLength = 2048;
-
-/**
- * Validate and convert to actor object
- * @param x Fetched object
- * @param uri Fetch target URI
- */
-function validateActor(x: IObject, uri: string): IActor {
-	const expectHost = toPuny(new URL(uri).hostname);
-
-	if (x == null) {
-		throw new Error("invalid Actor: object is null");
-	}
-
-	if (!isActor(x)) {
-		throw new Error(`invalid Actor type '${x.type}'`);
-	}
-
-	if (!(typeof x.id === "string" && x.id.length > 0)) {
-		throw new Error("invalid Actor: wrong id");
-	}
-
-	if (!(typeof x.inbox === "string" && x.inbox.length > 0)) {
-		throw new Error("invalid Actor: wrong inbox");
-	}
-
-	if (
-		!(
-			typeof x.preferredUsername === "string" &&
-			x.preferredUsername.length > 0 &&
-			x.preferredUsername.length <= 128 &&
-			/^\w([\w-.]*\w)?$/.test(x.preferredUsername)
-		)
-	) {
-		throw new Error("invalid Actor: wrong username");
-	}
-
-	// These fields are only informational, and some AP software allows these
-	// fields to be very long. If they are too long, we cut them off. This way
-	// we can at least see these users and their activities.
-	if (x.name) {
-		if (!(typeof x.name === "string" && x.name.length > 0)) {
-			throw new Error("invalid Actor: wrong name");
-		}
-		x.name = truncate(x.name, nameLength);
-	}
-	if (x.summary) {
-		if (!(typeof x.summary === "string" && x.summary.length > 0)) {
-			throw new Error("invalid Actor: wrong summary");
-		}
-		x.summary = truncate(x.summary, summaryLength);
-	}
-
-	const idHost = toPuny(new URL(x.id!).hostname);
-	if (idHost !== expectHost) {
-		throw new Error("invalid Actor: id has different host");
-	}
-
-	if (x.publicKey) {
-		if (typeof x.publicKey.id !== "string") {
-			throw new Error("invalid Actor: publicKey.id is not a string");
-		}
-
-		const publicKeyIdHost = toPuny(new URL(x.publicKey.id).hostname);
-		if (publicKeyIdHost !== expectHost) {
-			throw new Error("invalid Actor: publicKey.id has different host");
-		}
-	}
-
-	return x;
-}
-
-/**
- * Fetch a Person.
- *
- * If the target Person is registered in Calckey, it will be returned.
- */
-export async function fetchPerson(
-	uri: string,
-	resolver?: Resolver,
-): Promise<CacheableUser | null> {
-	if (typeof uri !== "string") throw new Error("uri is not string");
-
-	const cached = uriPersonCache.get(uri);
-	if (cached) return cached;
-
-	// Fetch from the database if the URI points to this server
-	if (uri.startsWith(`${config.url}/`)) {
-		const id = uri.split("/").pop();
-		const u = await Users.findOneBy({ id });
-		if (u) uriPersonCache.set(uri, u);
-		return u;
-	}
-
-	//#region Returns if already registered with this server
-	const exist = await Users.findOneBy({ uri });
-
-	if (exist) {
-		uriPersonCache.set(uri, exist);
-		return exist;
-	}
-	//#endregion
-
-	return null;
-}
-
-/**
- * Create Person.
- */
-export async function createPerson(
-	uri: string,
-	resolver?: Resolver,
-): Promise<User> {
-	if (typeof uri !== "string") throw new Error("uri is not string");
-
-	if (uri.startsWith(config.url)) {
-		throw new StatusError(
-			"cannot resolve local user",
-			400,
-			"cannot resolve local user",
-		);
-	}
-
-	if (resolver == null) resolver = new Resolver();
-
-	const object = (await resolver.resolve(uri)) as any;
-
-	const person = validateActor(object, uri);
-
-	logger.info(`Creating the Person: ${person.id}`);
-
-	const host = toPuny(new URL(object.id).hostname);
-
-	const { fields } = analyzeAttachments(person.attachment || []);
-
-	const tags = extractApHashtags(person.tag)
-		.map((tag) => normalizeForSearch(tag))
-		.splice(0, 32);
-
-	const isBot = getApType(object) === "Service";
-
-	const bday = person["vcard:bday"]?.match(/^\d{4}-\d{2}-\d{2}/);
-
-	const url = getOneApHrefNullable(person.url);
-
-	if (url && !url.startsWith("https://")) {
-		throw new Error(`unexpected schema of person url: ${url}`);
-	}
-
-	let followersCount: number | undefined;
-
-	if (typeof person.followers === "string") {
-		try {
-			let data = await fetch(person.followers, {
-				headers: { Accept: "application/json" },
-			});
-			let json_data = JSON.parse(await data.text());
-
-			followersCount = json_data.totalItems;
-		} catch {
-			followersCount = undefined;
-		}
-	}
-
-	let followingCount: number | undefined;
-
-	if (typeof person.following === "string") {
-		try {
-			let data = await fetch(person.following, {
-				headers: { Accept: "application/json" },
-			});
-			let json_data = JSON.parse(await data.text());
-
-			followingCount = json_data.totalItems;
-		} catch (e) {
-			followingCount = undefined;
-		}
-	}
-
-	// Create user
-	let user: IRemoteUser;
-	try {
-		// Start transaction
-		await db.transaction(async (transactionalEntityManager) => {
-			user = (await transactionalEntityManager.save(
-				new User({
-					id: genId(),
-					avatarId: null,
-					bannerId: null,
-					createdAt: new Date(),
-					lastFetchedAt: new Date(),
-					name: truncate(person.name, nameLength),
-					isLocked: !!person.manuallyApprovesFollowers,
-					movedToUri: person.movedTo,
-					alsoKnownAs: person.alsoKnownAs,
-					isExplorable: !!person.discoverable,
-					username: person.preferredUsername,
-					usernameLower: person.preferredUsername!.toLowerCase(),
-					host,
-					inbox: person.inbox,
-					sharedInbox:
-						person.sharedInbox ||
-						(person.endpoints ? person.endpoints.sharedInbox : undefined),
-					followersUri: person.followers
-						? getApId(person.followers)
-						: undefined,
-					followersCount:
-						followersCount !== undefined
-							? followersCount
-							: person.followers &&
-							  typeof person.followers !== "string" &&
-							  isCollectionOrOrderedCollection(person.followers)
-							? person.followers.totalItems
-							: undefined,
-					followingCount:
-						followingCount !== undefined
-							? followingCount
-							: person.following &&
-							  typeof person.following !== "string" &&
-							  isCollectionOrOrderedCollection(person.following)
-							? person.following.totalItems
-							: undefined,
-					featured: person.featured ? getApId(person.featured) : undefined,
-					uri: person.id,
-					tags,
-					isBot,
-					isCat: (person as any).isCat === true,
-					showTimelineReplies: false,
-				}),
-			)) as IRemoteUser;
-
-			await transactionalEntityManager.save(
-				new UserProfile({
-					userId: user.id,
-					description: person.summary
-						? htmlToMfm(truncate(person.summary, summaryLength), person.tag)
-						: null,
-					url: url,
-					fields,
-					birthday: bday ? bday[0] : null,
-					location: person["vcard:Address"] || null,
-					userHost: host,
-				}),
-			);
-
-			if (person.publicKey) {
-				await transactionalEntityManager.save(
-					new UserPublickey({
-						userId: user.id,
-						keyId: person.publicKey.id,
-						keyPem: person.publicKey.publicKeyPem,
-					}),
-				);
-			}
-		});
-	} catch (e) {
-		// duplicate key error
-		if (isDuplicateKeyValueError(e)) {
-			// /users/@a => /users/:id Corresponds to an error that may occur when the input is an alias like
-			const u = await Users.findOneBy({
-				uri: person.id,
-			});
-
-			if (u) {
-				user = u as IRemoteUser;
-			} else {
-				throw new Error("already registered");
-			}
-		} else {
-			logger.error(e instanceof Error ? e : new Error(e as string));
-			throw e;
-		}
-	}
-
-	// Register host
-	registerOrFetchInstanceDoc(host).then((i) => {
-		Instances.increment({ id: i.id }, "usersCount", 1);
-		instanceChart.newUser(i.host);
-		fetchInstanceMetadata(i);
-	});
-
-	usersChart.update(user!, true);
-
-	// Hashtag update
-	updateUsertags(user!, tags);
-
-	//#region Fetch avatar and header image
-	const [avatar, banner] = await Promise.all(
-		[person.icon, person.image].map((img) =>
-			img == null
-				? Promise.resolve(null)
-				: resolveImage(user!, img).catch(() => null),
-		),
-	);
-
-	const avatarId = avatar ? avatar.id : null;
-	const bannerId = banner ? banner.id : null;
-
-	await Users.update(user!.id, {
-		avatarId,
-		bannerId,
-	});
-
-	user!.avatarId = avatarId;
-	user!.bannerId = bannerId;
-	//#endregion
-
-	//#region Get custom emoji
-	const emojis = await extractEmojis(person.tag || [], host).catch((e) => {
-		logger.info(`extractEmojis: ${e}`);
-		return [] as Emoji[];
-	});
-
-	const emojiNames = emojis.map((emoji) => emoji.name);
-
-	await Users.update(user!.id, {
-		emojis: emojiNames,
-	});
-	//#endregion
-
-	await updateFeatured(user!.id, resolver).catch((err) => logger.error(err));
-
-	return user!;
-}
-
-/**
- * Update Person data from remote.
- * If the target Person is not registered in Calckey, it is ignored.
- * @param uri URI of Person
- * @param resolver Resolver
- * @param hint Hint of Person object (If this value is a valid Person, it is used for updating without Remote resolve)
- */
-export async function updatePerson(
-	uri: string,
-	resolver?: Resolver | null,
-	hint?: IObject,
-): Promise<void> {
-	if (typeof uri !== "string") throw new Error("uri is not string");
-
-	// Skip if the URI points to this server
-	if (uri.startsWith(`${config.url}/`)) {
-		return;
-	}
-
-	//#region Already registered on this server?
-	const exist = (await Users.findOneBy({ uri })) as IRemoteUser;
-
-	if (exist == null) {
-		return;
-	}
-	//#endregion
-
-	if (resolver == null) resolver = new Resolver();
-
-	const object = hint || (await resolver.resolve(uri));
-
-	const person = validateActor(object, uri);
-
-	logger.info(`Updating the Person: ${person.id}`);
-
-	// Fetch avatar and header image
-	const [avatar, banner] = await Promise.all(
-		[person.icon, person.image].map((img) =>
-			img == null
-				? Promise.resolve(null)
-				: resolveImage(exist, img).catch(() => null),
-		),
-	);
-
-	// Custom pictogram acquisition
-	const emojis = await extractEmojis(person.tag || [], exist.host).catch(
-		(e) => {
-			logger.info(`extractEmojis: ${e}`);
-			return [] as Emoji[];
-		},
-	);
-
-	const emojiNames = emojis.map((emoji) => emoji.name);
-
-	const { fields } = analyzeAttachments(person.attachment || []);
-
-	const tags = extractApHashtags(person.tag)
-		.map((tag) => normalizeForSearch(tag))
-		.splice(0, 32);
-
-	const bday = person["vcard:bday"]?.match(/^\d{4}-\d{2}-\d{2}/);
-
-	const url = getOneApHrefNullable(person.url);
-
-	if (url && !url.startsWith("https://")) {
-		throw new Error(`unexpected schema of person url: ${url}`);
-	}
-
-	let followersCount: number | undefined;
-
-	if (typeof person.followers === "string") {
-		try {
-			let data = await fetch(person.followers, {
-				headers: { Accept: "application/json" },
-			});
-			let json_data = JSON.parse(await data.text());
-
-			followersCount = json_data.totalItems;
-		} catch {
-			followersCount = undefined;
-		}
-	}
-
-	let followingCount: number | undefined;
-
-	if (typeof person.following === "string") {
-		try {
-			let data = await fetch(person.following, {
-				headers: { Accept: "application/json" },
-			});
-			let json_data = JSON.parse(await data.text());
-
-			followingCount = json_data.totalItems;
-		} catch {
-			followingCount = undefined;
-		}
-	}
-
-	const updates = {
-		lastFetchedAt: new Date(),
-		inbox: person.inbox,
-		sharedInbox:
-			person.sharedInbox ||
-			(person.endpoints ? person.endpoints.sharedInbox : undefined),
-		followersUri: person.followers ? getApId(person.followers) : undefined,
-		followersCount:
-			followersCount !== undefined
-				? followersCount
-				: person.followers &&
-				  typeof person.followers !== "string" &&
-				  isCollectionOrOrderedCollection(person.followers)
-				? person.followers.totalItems
-				: undefined,
-		followingCount:
-			followingCount !== undefined
-				? followingCount
-				: person.following &&
-				  typeof person.following !== "string" &&
-				  isCollectionOrOrderedCollection(person.following)
-				? person.following.totalItems
-				: undefined,
-		featured: person.featured,
-		emojis: emojiNames,
-		name: truncate(person.name, nameLength),
-		tags,
-		isBot: getApType(object) === "Service",
-		isCat: (person as any).isCat === true,
-		isLocked: !!person.manuallyApprovesFollowers,
-		movedToUri: person.movedTo || null,
-		alsoKnownAs: person.alsoKnownAs || null,
-		isExplorable: !!person.discoverable,
-	} as Partial<User>;
-
-	if (avatar) {
-		updates.avatarId = avatar.id;
-	}
-
-	if (banner) {
-		updates.bannerId = banner.id;
-	}
-
-	// Update user
-	await Users.update(exist.id, updates);
-
-	if (person.publicKey) {
-		await UserPublickeys.update(
-			{ userId: exist.id },
-			{
-				keyId: person.publicKey.id,
-				keyPem: person.publicKey.publicKeyPem,
-			},
-		);
-	}
-
-	await UserProfiles.update(
-		{ userId: exist.id },
-		{
-			url: url,
-			fields,
-			description: person.summary
-				? htmlToMfm(truncate(person.summary, summaryLength), person.tag)
-				: null,
-			birthday: bday ? bday[0] : null,
-			location: person["vcard:Address"] || null,
-		},
-	);
-
-	publishInternalEvent("remoteUserUpdated", { id: exist.id });
-
-	// Hashtag Update
-	updateUsertags(exist, tags);
-
-	// If the user in question is a follower, followers will also be updated.
-	await Followings.update(
-		{
-			followerId: exist.id,
-		},
-		{
-			followerSharedInbox:
-				person.sharedInbox ||
-				(person.endpoints ? person.endpoints.sharedInbox : undefined),
-		},
-	);
-
-	await updateFeatured(exist.id, resolver).catch((err) => logger.error(err));
-}
-
-/**
- * Resolve Person.
- *
- * If the target person is registered in Calckey, it returns it;
- * otherwise, it fetches it from the remote server, registers it in Calckey, and returns it.
- */
-export async function resolvePerson(
-	uri: string,
-	resolver?: Resolver,
-): Promise<CacheableUser> {
-	if (typeof uri !== "string") throw new Error("uri is not string");
-
-	//#region If already registered on this server, return it.
-	const exist = await fetchPerson(uri);
-
-	if (exist) {
-		return exist;
-	}
-	//#endregion
-
-	// Fetched from remote server and registered
-	if (resolver == null) resolver = new Resolver();
-	return await createPerson(uri, resolver);
-}
-
-const services: {
-	[x: string]: (id: string, username: string) => any;
-} = {
-	"misskey:authentication:twitter": (userId, screenName) => ({
-		userId,
-		screenName,
-	}),
-	"misskey:authentication:github": (id, login) => ({ id, login }),
-	"misskey:authentication:discord": (id, name) => $discord(id, name),
-};
-
-const $discord = (id: string, name: string) => {
-	if (typeof name !== "string") {
-		name = "unknown#0000";
-	}
-	const [username, discriminator] = name.split("#");
-	return { id, username, discriminator };
-};
-
-function addService(target: { [x: string]: any }, source: IApPropertyValue) {
-	const service = services[source.name];
-
-	if (typeof source.value !== "string") {
-		source.value = "unknown";
-	}
-
-	const [id, username] = source.value.split("@");
-
-	if (service) {
-		target[source.name.split(":")[2]] = service(id, username);
-	}
-}
-
-export function analyzeAttachments(
-	attachments: IObject | IObject[] | undefined,
-) {
-	const fields: {
-		name: string;
-		value: string;
-	}[] = [];
-	const services: { [x: string]: any } = {};
-
-	if (Array.isArray(attachments)) {
-		for (const attachment of attachments.filter(isPropertyValue)) {
-			if (isPropertyValue(attachment.identifier)) {
-				addService(services, attachment.identifier);
-			} else {
-				fields.push({
-					name: attachment.name,
-					value: fromHtml(attachment.value),
-				});
-			}
-		}
-	}
-
-	return { fields, services };
-}
-
-export async function updateFeatured(userId: User["id"], resolver?: Resolver) {
-	const user = await Users.findOneByOrFail({ id: userId });
-	if (!Users.isRemoteUser(user)) return;
-	if (!user.featured) return;
-
-	logger.info(`Updating the featured: ${user.uri}`);
-
-	if (resolver == null) resolver = new Resolver();
-
-	// Resolve to (Ordered)Collection Object
-	const collection = await resolver.resolveCollection(user.featured);
-	if (!isCollectionOrOrderedCollection(collection))
-		throw new Error("Object is not Collection or OrderedCollection");
-
-	// Resolve to Object(may be Note) arrays
-	const unresolvedItems = isCollection(collection)
-		? collection.items
-		: collection.orderedItems;
-	const items = await Promise.all(
-		toArray(unresolvedItems).map((x) => resolver.resolve(x)),
-	);
-
-	// Resolve and regist Notes
-	const limit = promiseLimit<Note | null>(2);
-	const featuredNotes = await Promise.all(
-		items
-			.filter((item) => getApType(item) === "Note") // TODO: Maybe it doesn't have to be a Note.
-			.slice(0, 5)
-			.map((item) => limit(() => resolveNote(item, resolver))),
-	);
-
-	await db.transaction(async (transactionalEntityManager) => {
-		await transactionalEntityManager.delete(UserNotePining, {
-			userId: user.id,
-		});
-
-		// For now, generate the id at a different time and maintain the order.
-		let td = 0;
-		for (const note of featuredNotes.filter((note) => note != null)) {
-			td -= 1000;
-			transactionalEntityManager.insert(UserNotePining, {
-				id: genId(new Date(Date.now() + td)),
-				createdAt: new Date(),
-				userId: user.id,
-				noteId: note!.id,
-			});
-		}
-	});
-}
diff --git a/packages/backend/src/remote/activitypub/models/question.ts b/packages/backend/src/remote/activitypub/models/question.ts
deleted file mode 100644
index 520b9fee94..0000000000
--- a/packages/backend/src/remote/activitypub/models/question.ts
+++ /dev/null
@@ -1,97 +0,0 @@
-import config from "@/config/index.js";
-import Resolver from "../resolver.js";
-import type { IObject, IQuestion } from "../type.js";
-import { isQuestion } from "../type.js";
-import { apLogger } from "../logger.js";
-import { Notes, Polls } from "@/models/index.js";
-import type { IPoll } from "@/models/entities/poll.js";
-
-export async function extractPollFromQuestion(
-	source: string | IObject,
-	resolver?: Resolver,
-): Promise<IPoll> {
-	if (resolver == null) resolver = new Resolver();
-
-	const question = await resolver.resolve(source);
-
-	if (!isQuestion(question)) {
-		throw new Error("invalid type");
-	}
-
-	const multiple = !question.oneOf;
-	const expiresAt = question.endTime
-		? new Date(question.endTime)
-		: question.closed
-		? new Date(question.closed)
-		: null;
-
-	if (multiple && !question.anyOf) {
-		throw new Error("invalid question");
-	}
-
-	const choices = question[multiple ? "anyOf" : "oneOf"]!.map(
-		(x, i) => x.name!,
-	);
-
-	const votes = question[multiple ? "anyOf" : "oneOf"]!.map(
-		(x, i) => x.replies?.totalItems || x._misskey_votes || 0,
-	);
-
-	return {
-		choices,
-		votes,
-		multiple,
-		expiresAt,
-	};
-}
-
-/**
- * Update votes of Question
- * @param uri URI of AP Question object
- * @returns true if updated
- */
-export async function updateQuestion(value: any, resolver?: Resolver) {
-	const uri = typeof value === "string" ? value : value.id;
-
-	// Skip if URI points to this server
-	if (uri.startsWith(`${config.url}/`)) throw new Error("uri points local");
-
-	//#region Already registered with this server?
-	const note = await Notes.findOneBy({ uri });
-	if (note == null) throw new Error("Question is not registed");
-
-	const poll = await Polls.findOneBy({ noteId: note.id });
-	if (poll == null) throw new Error("Question is not registed");
-	//#endregion
-
-	// resolve new Question object
-	if (resolver == null) resolver = new Resolver();
-	const question = (await resolver.resolve(value)) as IQuestion;
-	apLogger.debug(`fetched question: ${JSON.stringify(question, null, 2)}`);
-
-	if (question.type !== "Question") throw new Error("object is not a Question");
-
-	const apChoices = question.oneOf || question.anyOf;
-
-	let changed = false;
-
-	for (const choice of poll.choices) {
-		const oldCount = poll.votes[poll.choices.indexOf(choice)];
-		const newCount = apChoices!.filter((ap) => ap.name === choice)[0].replies!
-			.totalItems;
-
-		if (oldCount !== newCount) {
-			changed = true;
-			poll.votes[poll.choices.indexOf(choice)] = newCount;
-		}
-	}
-
-	await Polls.update(
-		{ noteId: note.id },
-		{
-			votes: poll.votes,
-		},
-	);
-
-	return changed;
-}
diff --git a/packages/backend/src/remote/activitypub/models/tag.ts b/packages/backend/src/remote/activitypub/models/tag.ts
deleted file mode 100644
index 537cdecbd5..0000000000
--- a/packages/backend/src/remote/activitypub/models/tag.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { toArray } from "@/prelude/array.js";
-import type { IObject, IApHashtag } from "../type.js";
-import { isHashtag } from "../type.js";
-
-export function extractApHashtags(
-	tags: IObject | IObject[] | null | undefined,
-) {
-	if (tags == null) return [];
-
-	const hashtags = extractApHashtagObjects(tags);
-
-	return hashtags
-		.map((tag) => {
-			const m = tag.name.match(/^#(.+)/);
-			return m ? m[1] : null;
-		})
-		.filter((x): x is string => x != null);
-}
-
-export function extractApHashtagObjects(
-	tags: IObject | IObject[] | null | undefined,
-): IApHashtag[] {
-	if (tags == null) return [];
-	return toArray(tags).filter(isHashtag);
-}
diff --git a/packages/backend/src/remote/activitypub/perform.ts b/packages/backend/src/remote/activitypub/perform.ts
deleted file mode 100644
index 0d2cdb4a5e..0000000000
--- a/packages/backend/src/remote/activitypub/perform.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import type { IObject } from "./type.js";
-import type { CacheableRemoteUser } from "@/models/entities/user.js";
-import { performActivity } from "./kernel/index.js";
-import { updatePerson } from "./models/person.js";
-
-export default async (
-	actor: CacheableRemoteUser,
-	activity: IObject,
-): Promise<void> => {
-	await performActivity(actor, activity);
-
-	// Update the remote user information if it is out of date
-	if (actor.uri) {
-		if (
-			actor.lastFetchedAt == null ||
-			Date.now() - actor.lastFetchedAt.getTime() > 1000 * 60 * 60 * 24
-		) {
-			setImmediate(() => {
-				updatePerson(actor.uri!);
-			});
-		}
-	}
-};
diff --git a/packages/backend/src/remote/activitypub/renderer/accept.ts b/packages/backend/src/remote/activitypub/renderer/accept.ts
deleted file mode 100644
index fd145dcf97..0000000000
--- a/packages/backend/src/remote/activitypub/renderer/accept.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import config from "@/config/index.js";
-import type { User } from "@/models/entities/user.js";
-
-export default (object: any, user: { id: User["id"]; host: null }) => ({
-	type: "Accept",
-	actor: `${config.url}/users/${user.id}`,
-	object,
-});
diff --git a/packages/backend/src/remote/activitypub/renderer/add.ts b/packages/backend/src/remote/activitypub/renderer/add.ts
deleted file mode 100644
index d8203ac1ea..0000000000
--- a/packages/backend/src/remote/activitypub/renderer/add.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import config from "@/config/index.js";
-import type { ILocalUser } from "@/models/entities/user.js";
-
-export default (user: ILocalUser, target: any, object: any) => ({
-	type: "Add",
-	actor: `${config.url}/users/${user.id}`,
-	target,
-	object,
-});
diff --git a/packages/backend/src/remote/activitypub/renderer/announce.ts b/packages/backend/src/remote/activitypub/renderer/announce.ts
deleted file mode 100644
index 1fd1842acf..0000000000
--- a/packages/backend/src/remote/activitypub/renderer/announce.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import config from "@/config/index.js";
-import type { Note } from "@/models/entities/note.js";
-
-export default (object: any, note: Note) => {
-	const attributedTo = `${config.url}/users/${note.userId}`;
-
-	const mentions = (
-		JSON.parse(note.mentionedRemoteUsers) as IMentionedRemoteUsers
-	).map((x) => x.uri);
-
-	let to: string[] = [];
-	let cc: string[] = [];
-
-	if (note.visibility === "public") {
-		to = ["https://www.w3.org/ns/activitystreams#Public"];
-		cc = [`${attributedTo}/followers`];
-	} else if (note.visibility === "home") {
-		to = [`${attributedTo}/followers`];
-		cc = ["https://www.w3.org/ns/activitystreams#Public"];
-	} else if (note.visibility === "followers") {
-		to = [`${attributedTo}/followers`];
-	} else if (note.visibility === "specified") {
-		to = mentions;
-	} else {
-		return null;
-	}
-
-	return {
-		id: `${config.url}/notes/${note.id}/activity`,
-		actor: `${config.url}/users/${note.userId}`,
-		type: "Announce",
-		published: note.createdAt.toISOString(),
-		to,
-		cc,
-		object,
-	};
-};
diff --git a/packages/backend/src/remote/activitypub/renderer/block.ts b/packages/backend/src/remote/activitypub/renderer/block.ts
deleted file mode 100644
index c2ea267f38..0000000000
--- a/packages/backend/src/remote/activitypub/renderer/block.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import config from "@/config/index.js";
-import type { Blocking } from "@/models/entities/blocking.js";
-
-/**
- * Renders a block into its ActivityPub representation.
- *
- * @param block The block to be rendered. The blockee relation must be loaded.
- */
-export function renderBlock(block: Blocking) {
-	if (block.blockee?.uri == null) {
-		throw new Error("renderBlock: missing blockee uri");
-	}
-
-	return {
-		type: "Block",
-		id: `${config.url}/blocks/${block.id}`,
-		actor: `${config.url}/users/${block.blockerId}`,
-		object: block.blockee.uri,
-	};
-}
diff --git a/packages/backend/src/remote/activitypub/renderer/create.ts b/packages/backend/src/remote/activitypub/renderer/create.ts
deleted file mode 100644
index 857f5722cc..0000000000
--- a/packages/backend/src/remote/activitypub/renderer/create.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import config from "@/config/index.js";
-import type { Note } from "@/models/entities/note.js";
-
-export default (object: any, note: Note) => {
-	const activity = {
-		id: `${config.url}/notes/${note.id}/activity`,
-		actor: `${config.url}/users/${note.userId}`,
-		type: "Create",
-		published: note.createdAt.toISOString(),
-		object,
-	} as any;
-
-	if (object.to) activity.to = object.to;
-	if (object.cc) activity.cc = object.cc;
-
-	return activity;
-};
diff --git a/packages/backend/src/remote/activitypub/renderer/delete.ts b/packages/backend/src/remote/activitypub/renderer/delete.ts
deleted file mode 100644
index 70bdc34922..0000000000
--- a/packages/backend/src/remote/activitypub/renderer/delete.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import config from "@/config/index.js";
-import type { User } from "@/models/entities/user.js";
-
-export default (object: any, user: { id: User["id"]; host: null }) => ({
-	type: "Delete",
-	actor: `${config.url}/users/${user.id}`,
-	object,
-	published: new Date().toISOString(),
-});
diff --git a/packages/backend/src/remote/activitypub/renderer/document.ts b/packages/backend/src/remote/activitypub/renderer/document.ts
deleted file mode 100644
index 1c2ca89d94..0000000000
--- a/packages/backend/src/remote/activitypub/renderer/document.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import type { DriveFile } from "@/models/entities/drive-file.js";
-import { DriveFiles } from "@/models/index.js";
-
-export default (file: DriveFile) => ({
-	type: "Document",
-	mediaType: file.type,
-	url: DriveFiles.getPublicUrl(file),
-	name: file.comment,
-});
diff --git a/packages/backend/src/remote/activitypub/renderer/emoji.ts b/packages/backend/src/remote/activitypub/renderer/emoji.ts
deleted file mode 100644
index 3d9b8cd55b..0000000000
--- a/packages/backend/src/remote/activitypub/renderer/emoji.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import config from "@/config/index.js";
-import type { Emoji } from "@/models/entities/emoji.js";
-
-export default (emoji: Emoji) => ({
-	id: `${config.url}/emojis/${emoji.name}`,
-	type: "Emoji",
-	name: `:${emoji.name}:`,
-	updated:
-		emoji.updatedAt != null
-			? emoji.updatedAt.toISOString()
-			: new Date().toISOString,
-	icon: {
-		type: "Image",
-		mediaType: emoji.type || "image/png",
-		url: emoji.publicUrl || emoji.originalUrl, // || emoji.originalUrl してるのは後方互換性のため
-	},
-});
diff --git a/packages/backend/src/remote/activitypub/renderer/flag.ts b/packages/backend/src/remote/activitypub/renderer/flag.ts
deleted file mode 100644
index f94d508e1d..0000000000
--- a/packages/backend/src/remote/activitypub/renderer/flag.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import config from "@/config/index.js";
-import { IObject, IActivity } from "@/remote/activitypub/type.js";
-import type { ILocalUser } from "@/models/entities/user.js";
-import { IRemoteUser } from "@/models/entities/user.js";
-import { getInstanceActor } from "@/services/instance-actor.js";
-
-// to anonymise reporters, the reporting actor must be a system user
-// object has to be a uri or array of uris
-export const renderFlag = (
-	user: ILocalUser,
-	object: [string],
-	content: string,
-) => {
-	return {
-		type: "Flag",
-		actor: `${config.url}/users/${user.id}`,
-		content,
-		object,
-	};
-};
diff --git a/packages/backend/src/remote/activitypub/renderer/follow-relay.ts b/packages/backend/src/remote/activitypub/renderer/follow-relay.ts
deleted file mode 100644
index ad7f05bf84..0000000000
--- a/packages/backend/src/remote/activitypub/renderer/follow-relay.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import config from "@/config/index.js";
-import type { Relay } from "@/models/entities/relay.js";
-import type { ILocalUser } from "@/models/entities/user.js";
-
-export function renderFollowRelay(relay: Relay, relayActor: ILocalUser) {
-	const follow = {
-		id: `${config.url}/activities/follow-relay/${relay.id}`,
-		type: "Follow",
-		actor: `${config.url}/users/${relayActor.id}`,
-		object: "https://www.w3.org/ns/activitystreams#Public",
-	};
-
-	return follow;
-}
diff --git a/packages/backend/src/remote/activitypub/renderer/follow-user.ts b/packages/backend/src/remote/activitypub/renderer/follow-user.ts
deleted file mode 100644
index 22ee429ff6..0000000000
--- a/packages/backend/src/remote/activitypub/renderer/follow-user.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import config from "@/config/index.js";
-import { Users } from "@/models/index.js";
-import type { User } from "@/models/entities/user.js";
-
-/**
- * Convert (local|remote)(Follower|Followee)ID to URL
- * @param id Follower|Followee ID
- */
-export default async function renderFollowUser(id: User["id"]): Promise<any> {
-	const user = await Users.findOneByOrFail({ id: id });
-	return Users.isLocalUser(user) ? `${config.url}/users/${user.id}` : user.uri;
-}
diff --git a/packages/backend/src/remote/activitypub/renderer/follow.ts b/packages/backend/src/remote/activitypub/renderer/follow.ts
deleted file mode 100644
index 3ff89c12aa..0000000000
--- a/packages/backend/src/remote/activitypub/renderer/follow.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import config from "@/config/index.js";
-import type { User } from "@/models/entities/user.js";
-import { Users } from "@/models/index.js";
-
-export default (
-	follower: { id: User["id"]; host: User["host"]; uri: User["host"] },
-	followee: { id: User["id"]; host: User["host"]; uri: User["host"] },
-	requestId?: string,
-) => {
-	const follow = {
-		id: requestId ?? `${config.url}/follows/${follower.id}/${followee.id}`,
-		type: "Follow",
-		actor: Users.isLocalUser(follower)
-			? `${config.url}/users/${follower.id}`
-			: follower.uri,
-		object: Users.isLocalUser(followee)
-			? `${config.url}/users/${followee.id}`
-			: followee.uri,
-	} as any;
-
-	return follow;
-};
diff --git a/packages/backend/src/remote/activitypub/renderer/hashtag.ts b/packages/backend/src/remote/activitypub/renderer/hashtag.ts
deleted file mode 100644
index a00cd1ff5e..0000000000
--- a/packages/backend/src/remote/activitypub/renderer/hashtag.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import config from "@/config/index.js";
-
-export default (tag: string) => ({
-	type: "Hashtag",
-	href: `${config.url}/tags/${encodeURIComponent(tag)}`,
-	name: `#${tag}`,
-});
diff --git a/packages/backend/src/remote/activitypub/renderer/image.ts b/packages/backend/src/remote/activitypub/renderer/image.ts
deleted file mode 100644
index 96183c7ad0..0000000000
--- a/packages/backend/src/remote/activitypub/renderer/image.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import type { DriveFile } from "@/models/entities/drive-file.js";
-import { DriveFiles } from "@/models/index.js";
-
-export default (file: DriveFile) => ({
-	type: "Image",
-	url: DriveFiles.getPublicUrl(file),
-	sensitive: file.isSensitive,
-	name: file.comment,
-});
diff --git a/packages/backend/src/remote/activitypub/renderer/index.ts b/packages/backend/src/remote/activitypub/renderer/index.ts
deleted file mode 100644
index 7b98cf2d77..0000000000
--- a/packages/backend/src/remote/activitypub/renderer/index.ts
+++ /dev/null
@@ -1,73 +0,0 @@
-import { v4 as uuid } from "uuid";
-import config from "@/config/index.js";
-import { getUserKeypair } from "@/misc/keypair-store.js";
-import type { User } from "@/models/entities/user.js";
-import { LdSignature } from "../misc/ld-signature.js";
-import type { IActivity } from "../type.js";
-
-export const renderActivity = (x: any): IActivity | null => {
-	if (x == null) return null;
-
-	if (typeof x === "object" && x.id == null) {
-		x.id = `${config.url}/${uuid()}`;
-	}
-
-	return Object.assign(
-		{
-			"@context": [
-				"https://www.w3.org/ns/activitystreams",
-				"https://w3id.org/security/v1",
-				{
-					// as non-standards
-					manuallyApprovesFollowers: "as:manuallyApprovesFollowers",
-					movedToUri: "as:movedTo",
-					sensitive: "as:sensitive",
-					Hashtag: "as:Hashtag",
-					quoteUri: "fedibird:quoteUri",
-					quoteUrl: "as:quoteUrl",
-					// Mastodon
-					toot: "http://joinmastodon.org/ns#",
-					Emoji: "toot:Emoji",
-					featured: "toot:featured",
-					discoverable: "toot:discoverable",
-					// schema
-					schema: "http://schema.org#",
-					PropertyValue: "schema:PropertyValue",
-					value: "schema:value",
-					// Misskey
-					misskey: "https://misskey-hub.net/ns#",
-					_misskey_content: "misskey:_misskey_content",
-					_misskey_quote: "misskey:_misskey_quote",
-					_misskey_reaction: "misskey:_misskey_reaction",
-					_misskey_votes: "misskey:_misskey_votes",
-					_misskey_talk: "misskey:_misskey_talk",
-					isCat: "misskey:isCat",
-					// Fedibird
-					fedibird: "http://fedibird.com/ns#",
-					// vcard
-					vcard: "http://www.w3.org/2006/vcard/ns#",
-				},
-			],
-		},
-		x,
-	);
-};
-
-export const attachLdSignature = async (
-	activity: any,
-	user: { id: User["id"]; host: null },
-): Promise<IActivity | null> => {
-	if (activity == null) return null;
-
-	const keypair = await getUserKeypair(user.id);
-
-	const ldSignature = new LdSignature();
-	ldSignature.debug = false;
-	activity = await ldSignature.signRsaSignature2017(
-		activity,
-		keypair.privateKey,
-		`${config.url}/users/${user.id}#main-key`,
-	);
-
-	return activity;
-};
diff --git a/packages/backend/src/remote/activitypub/renderer/key.ts b/packages/backend/src/remote/activitypub/renderer/key.ts
deleted file mode 100644
index 084bb5361a..0000000000
--- a/packages/backend/src/remote/activitypub/renderer/key.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import config from "@/config/index.js";
-import type { ILocalUser } from "@/models/entities/user.js";
-import type { UserKeypair } from "@/models/entities/user-keypair.js";
-import { createPublicKey } from "node:crypto";
-
-export default (user: ILocalUser, key: UserKeypair, postfix?: string) => ({
-	id: `${config.url}/users/${user.id}${postfix || "/publickey"}`,
-	type: "Key",
-	owner: `${config.url}/users/${user.id}`,
-	publicKeyPem: createPublicKey(key.publicKey).export({
-		type: "spki",
-		format: "pem",
-	}),
-});
diff --git a/packages/backend/src/remote/activitypub/renderer/like.ts b/packages/backend/src/remote/activitypub/renderer/like.ts
deleted file mode 100644
index 53c66c5c92..0000000000
--- a/packages/backend/src/remote/activitypub/renderer/like.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import { IsNull } from "typeorm";
-import config from "@/config/index.js";
-import type { NoteReaction } from "@/models/entities/note-reaction.js";
-import type { Note } from "@/models/entities/note.js";
-import { Emojis } from "@/models/index.js";
-import renderEmoji from "./emoji.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-
-export const renderLike = async (noteReaction: NoteReaction, note: Note) => {
-	const reaction = noteReaction.reaction;
-	const meta = await fetchMeta();
-
-	const object = {
-		type: "Like",
-		id: `${config.url}/likes/${noteReaction.id}`,
-		actor: `${config.url}/users/${noteReaction.userId}`,
-		object: note.uri ? note.uri : `${config.url}/notes/${noteReaction.noteId}`,
-		...(!meta.defaultReaction.includes(reaction)
-			? {
-					content: reaction,
-					_misskey_reaction: reaction,
-			  }
-			: {}),
-	} as any;
-
-	if (reaction.startsWith(":")) {
-		const name = reaction.replace(/:/g, "");
-		const emoji = await Emojis.findOneBy({
-			name,
-			host: IsNull(),
-		});
-
-		if (emoji) object.tag = [renderEmoji(emoji)];
-	}
-
-	return object;
-};
diff --git a/packages/backend/src/remote/activitypub/renderer/mention.ts b/packages/backend/src/remote/activitypub/renderer/mention.ts
deleted file mode 100644
index e7f0435c16..0000000000
--- a/packages/backend/src/remote/activitypub/renderer/mention.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import config from "@/config/index.js";
-import type { User, ILocalUser } from "@/models/entities/user.js";
-import { Users } from "@/models/index.js";
-
-export default (mention: User) => ({
-	type: "Mention",
-	href: Users.isRemoteUser(mention)
-		? mention.uri
-		: `${config.url}/users/${(mention as ILocalUser).id}`,
-	name: Users.isRemoteUser(mention)
-		? `@${mention.username}@${mention.host}`
-		: `@${(mention as ILocalUser).username}`,
-});
diff --git a/packages/backend/src/remote/activitypub/renderer/note.ts b/packages/backend/src/remote/activitypub/renderer/note.ts
deleted file mode 100644
index 2ad2fec9fb..0000000000
--- a/packages/backend/src/remote/activitypub/renderer/note.ts
+++ /dev/null
@@ -1,188 +0,0 @@
-import { In, IsNull } from "typeorm";
-import config from "@/config/index.js";
-import type { Note, IMentionedRemoteUsers } from "@/models/entities/note.js";
-import type { DriveFile } from "@/models/entities/drive-file.js";
-import { DriveFiles, Notes, Users, Emojis, Polls } from "@/models/index.js";
-import type { Emoji } from "@/models/entities/emoji.js";
-import type { Poll } from "@/models/entities/poll.js";
-import toHtml from "../misc/get-note-html.js";
-import renderEmoji from "./emoji.js";
-import renderMention from "./mention.js";
-import renderHashtag from "./hashtag.js";
-import renderDocument from "./document.js";
-
-export default async function renderNote(
-	note: Note,
-	dive = true,
-	isTalk = false,
-): Promise<Record<string, unknown>> {
-	const getPromisedFiles = async (ids: string[]) => {
-		if (!ids || ids.length === 0) return [];
-		const items = await DriveFiles.findBy({ id: In(ids) });
-		return ids
-			.map((id) => items.find((item) => item.id === id))
-			.filter((item) => item != null) as DriveFile[];
-	};
-
-	let inReplyTo;
-	let inReplyToNote: Note | null;
-
-	if (note.replyId) {
-		inReplyToNote = await Notes.findOneBy({ id: note.replyId });
-
-		if (inReplyToNote != null) {
-			const inReplyToUser = await Users.findOneBy({ id: inReplyToNote.userId });
-
-			if (inReplyToUser != null) {
-				if (inReplyToNote.uri) {
-					inReplyTo = inReplyToNote.uri;
-				} else {
-					if (dive) {
-						inReplyTo = await renderNote(inReplyToNote, false);
-					} else {
-						inReplyTo = `${config.url}/notes/${inReplyToNote.id}`;
-					}
-				}
-			}
-		}
-	} else {
-		inReplyTo = null;
-	}
-
-	let quote;
-
-	if (note.renoteId) {
-		const renote = await Notes.findOneBy({ id: note.renoteId });
-
-		if (renote) {
-			quote = renote.uri ? renote.uri : `${config.url}/notes/${renote.id}`;
-		}
-	}
-
-	const attributedTo = `${config.url}/users/${note.userId}`;
-
-	const mentions = (
-		JSON.parse(note.mentionedRemoteUsers) as IMentionedRemoteUsers
-	).map((x) => x.uri);
-
-	let to: string[] = [];
-	let cc: string[] = [];
-
-	if (note.visibility === "public") {
-		to = ["https://www.w3.org/ns/activitystreams#Public"];
-		cc = [`${attributedTo}/followers`].concat(mentions);
-	} else if (note.visibility === "home") {
-		to = [`${attributedTo}/followers`];
-		cc = ["https://www.w3.org/ns/activitystreams#Public"].concat(mentions);
-	} else if (note.visibility === "followers") {
-		to = [`${attributedTo}/followers`];
-		cc = mentions;
-	} else {
-		to = mentions;
-	}
-
-	const mentionedUsers =
-		note.mentions.length > 0
-			? await Users.findBy({
-					id: In(note.mentions),
-			  })
-			: [];
-
-	const hashtagTags = (note.tags || []).map((tag) => renderHashtag(tag));
-	const mentionTags = mentionedUsers.map((u) => renderMention(u));
-
-	const files = await getPromisedFiles(note.fileIds);
-
-	const text = note.text ?? "";
-	let poll: Poll | null = null;
-
-	if (note.hasPoll) {
-		poll = await Polls.findOneBy({ noteId: note.id });
-	}
-
-	let apText = text;
-
-	if (quote) {
-		apText += `\n\nRE: ${quote}`;
-	}
-
-	const summary = note.cw === "" ? String.fromCharCode(0x200b) : note.cw;
-
-	const content = toHtml(
-		Object.assign({}, note, {
-			text: apText,
-		}),
-	);
-
-	const emojis = await getEmojis(note.emojis);
-	const apemojis = emojis.map((emoji) => renderEmoji(emoji));
-
-	const tag = [...hashtagTags, ...mentionTags, ...apemojis];
-
-	const asPoll = poll
-		? {
-				type: "Question",
-				content: toHtml(
-					Object.assign({}, note, {
-						text: text,
-					}),
-				),
-				[poll.expiresAt && poll.expiresAt < new Date() ? "closed" : "endTime"]:
-					poll.expiresAt,
-				[poll.multiple ? "anyOf" : "oneOf"]: poll.choices.map((text, i) => ({
-					type: "Note",
-					name: text,
-					replies: {
-						type: "Collection",
-						totalItems: poll!.votes[i],
-					},
-				})),
-		  }
-		: {};
-
-	const asTalk = isTalk
-		? {
-				_misskey_talk: true,
-		  }
-		: {};
-
-	return {
-		id: `${config.url}/notes/${note.id}`,
-		type: "Note",
-		attributedTo,
-		summary,
-		content,
-		_misskey_content: text,
-		source: {
-			content: text,
-			mediaType: "text/x.misskeymarkdown",
-		},
-		_misskey_quote: quote,
-		quoteUri: quote,
-		quoteUrl: quote,
-		published: note.createdAt.toISOString(),
-		to,
-		cc,
-		inReplyTo,
-		attachment: files.map(renderDocument),
-		sensitive: note.cw != null || files.some((file) => file.isSensitive),
-		tag,
-		...asPoll,
-		...asTalk,
-	};
-}
-
-export async function getEmojis(names: string[]): Promise<Emoji[]> {
-	if (names == null || names.length === 0) return [];
-
-	const emojis = await Promise.all(
-		names.map((name) =>
-			Emojis.findOneBy({
-				name,
-				host: IsNull(),
-			}),
-		),
-	);
-
-	return emojis.filter((emoji) => emoji != null) as Emoji[];
-}
diff --git a/packages/backend/src/remote/activitypub/renderer/ordered-collection-page.ts b/packages/backend/src/remote/activitypub/renderer/ordered-collection-page.ts
deleted file mode 100644
index 2275c9c94e..0000000000
--- a/packages/backend/src/remote/activitypub/renderer/ordered-collection-page.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * Render OrderedCollectionPage
- * @param id URL of self
- * @param totalItems Number of total items
- * @param orderedItems Items
- * @param partOf URL of base
- * @param prev URL of prev page (optional)
- * @param next URL of next page (optional)
- */
-export default function (
-	id: string,
-	totalItems: any,
-	orderedItems: any,
-	partOf: string,
-	prev?: string,
-	next?: string,
-) {
-	const page = {
-		id,
-		partOf,
-		type: "OrderedCollectionPage",
-		totalItems,
-		orderedItems,
-	} as any;
-
-	if (prev) page.prev = prev;
-	if (next) page.next = next;
-
-	return page;
-}
diff --git a/packages/backend/src/remote/activitypub/renderer/ordered-collection.ts b/packages/backend/src/remote/activitypub/renderer/ordered-collection.ts
deleted file mode 100644
index b975399b68..0000000000
--- a/packages/backend/src/remote/activitypub/renderer/ordered-collection.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * Render OrderedCollection
- * @param id URL of self
- * @param totalItems Total number of items
- * @param first URL of first page (optional)
- * @param last URL of last page (optional)
- * @param orderedItems attached objects (optional)
- */
-export default function (
-	id: string | null,
-	totalItems: any,
-	first?: string,
-	last?: string,
-	orderedItems?: Record<string, unknown>[],
-): {
-	id: string | null;
-	type: "OrderedCollection";
-	totalItems: any;
-	first?: string;
-	last?: string;
-	orderedItems?: Record<string, unknown>[];
-} {
-	const page: any = {
-		id,
-		type: "OrderedCollection",
-		totalItems,
-	};
-
-	if (first) page.first = first;
-	if (last) page.last = last;
-	if (orderedItems) page.orderedItems = orderedItems;
-
-	return page;
-}
diff --git a/packages/backend/src/remote/activitypub/renderer/person.ts b/packages/backend/src/remote/activitypub/renderer/person.ts
deleted file mode 100644
index 1122a3a279..0000000000
--- a/packages/backend/src/remote/activitypub/renderer/person.ts
+++ /dev/null
@@ -1,104 +0,0 @@
-import { URL } from "node:url";
-import * as mfm from "mfm-js";
-import config from "@/config/index.js";
-import type { ILocalUser } from "@/models/entities/user.js";
-import { DriveFiles, UserProfiles } from "@/models/index.js";
-import { getUserKeypair } from "@/misc/keypair-store.js";
-import { toHtml } from "../../../mfm/to-html.js";
-import renderImage from "./image.js";
-import renderKey from "./key.js";
-import { getEmojis } from "./note.js";
-import renderEmoji from "./emoji.js";
-import renderHashtag from "./hashtag.js";
-import type { IIdentifier } from "../models/identifier.js";
-
-export async function renderPerson(user: ILocalUser) {
-	const id = `${config.url}/users/${user.id}`;
-	const isSystem = !!user.username.match(/\./);
-
-	const [avatar, banner, profile] = await Promise.all([
-		user.avatarId
-			? DriveFiles.findOneBy({ id: user.avatarId })
-			: Promise.resolve(undefined),
-		user.bannerId
-			? DriveFiles.findOneBy({ id: user.bannerId })
-			: Promise.resolve(undefined),
-		UserProfiles.findOneByOrFail({ userId: user.id }),
-	]);
-
-	const attachment: {
-		type: "PropertyValue";
-		name: string;
-		value: string;
-		identifier?: IIdentifier;
-	}[] = [];
-
-	if (profile.fields) {
-		for (const field of profile.fields) {
-			attachment.push({
-				type: "PropertyValue",
-				name: field.name,
-				value: field.value?.match(/^https?:/)
-					? `<a href="${
-							new URL(field.value).href
-					  }" rel="me nofollow noopener" target="_blank">${
-							new URL(field.value).href
-					  }</a>`
-					: field.value,
-			});
-		}
-	}
-
-	const emojis = await getEmojis(user.emojis);
-	const apemojis = emojis.map((emoji) => renderEmoji(emoji));
-
-	const hashtagTags = (user.tags || []).map((tag) => renderHashtag(tag));
-
-	const tag = [...apemojis, ...hashtagTags];
-
-	const keypair = await getUserKeypair(user.id);
-
-	const person = {
-		type: isSystem ? "Application" : user.isBot ? "Service" : "Person",
-		id,
-		inbox: `${id}/inbox`,
-		outbox: `${id}/outbox`,
-		followers: `${id}/followers`,
-		following: `${id}/following`,
-		featured: `${id}/collections/featured`,
-		sharedInbox: `${config.url}/inbox`,
-		endpoints: { sharedInbox: `${config.url}/inbox` },
-		url: `${config.url}/@${user.username}`,
-		preferredUsername: user.username,
-		name: user.name,
-		summary: profile.description
-			? toHtml(mfm.parse(profile.description))
-			: null,
-		icon: avatar ? renderImage(avatar) : null,
-		image: banner ? renderImage(banner) : null,
-		tag,
-		manuallyApprovesFollowers: user.isLocked,
-		discoverable: !!user.isExplorable,
-		publicKey: renderKey(user, keypair, "#main-key"),
-		isCat: user.isCat,
-		attachment: attachment.length ? attachment : undefined,
-	} as any;
-
-	if (user.movedToUri) {
-		person.movedTo = user.movedToUri;
-	}
-
-	if (user.alsoKnownAs) {
-		person.alsoKnownAs = user.alsoKnownAs;
-	}
-
-	if (profile.birthday) {
-		person["vcard:bday"] = profile.birthday;
-	}
-
-	if (profile.location) {
-		person["vcard:Address"] = profile.location;
-	}
-
-	return person;
-}
diff --git a/packages/backend/src/remote/activitypub/renderer/question.ts b/packages/backend/src/remote/activitypub/renderer/question.ts
deleted file mode 100644
index cb89aa7583..0000000000
--- a/packages/backend/src/remote/activitypub/renderer/question.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import config from "@/config/index.js";
-import type { User } from "@/models/entities/user.js";
-import type { Note } from "@/models/entities/note.js";
-import type { Poll } from "@/models/entities/poll.js";
-
-export default async function renderQuestion(
-	user: { id: User["id"] },
-	note: Note,
-	poll: Poll,
-) {
-	const question = {
-		type: "Question",
-		id: `${config.url}/questions/${note.id}`,
-		actor: `${config.url}/users/${user.id}`,
-		content: note.text || "",
-		[poll.multiple ? "anyOf" : "oneOf"]: poll.choices.map((text, i) => ({
-			name: text,
-			_misskey_votes: poll.votes[i],
-			replies: {
-				type: "Collection",
-				totalItems: poll.votes[i],
-			},
-		})),
-	};
-
-	return question;
-}
diff --git a/packages/backend/src/remote/activitypub/renderer/read.ts b/packages/backend/src/remote/activitypub/renderer/read.ts
deleted file mode 100644
index 212e7e8ddf..0000000000
--- a/packages/backend/src/remote/activitypub/renderer/read.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import config from "@/config/index.js";
-import type { User } from "@/models/entities/user.js";
-import type { MessagingMessage } from "@/models/entities/messaging-message.js";
-
-export const renderReadActivity = (
-	user: { id: User["id"] },
-	message: MessagingMessage,
-) => ({
-	type: "Read",
-	actor: `${config.url}/users/${user.id}`,
-	object: message.uri,
-});
diff --git a/packages/backend/src/remote/activitypub/renderer/reject.ts b/packages/backend/src/remote/activitypub/renderer/reject.ts
deleted file mode 100644
index 7ac4452411..0000000000
--- a/packages/backend/src/remote/activitypub/renderer/reject.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import config from "@/config/index.js";
-import type { User } from "@/models/entities/user.js";
-
-export default (object: any, user: { id: User["id"] }) => ({
-	type: "Reject",
-	actor: `${config.url}/users/${user.id}`,
-	object,
-});
diff --git a/packages/backend/src/remote/activitypub/renderer/remove.ts b/packages/backend/src/remote/activitypub/renderer/remove.ts
deleted file mode 100644
index e3b3fef856..0000000000
--- a/packages/backend/src/remote/activitypub/renderer/remove.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import config from "@/config/index.js";
-import type { User } from "@/models/entities/user.js";
-
-export default (user: { id: User["id"] }, target: any, object: any) => ({
-	type: "Remove",
-	actor: `${config.url}/users/${user.id}`,
-	target,
-	object,
-});
diff --git a/packages/backend/src/remote/activitypub/renderer/tombstone.ts b/packages/backend/src/remote/activitypub/renderer/tombstone.ts
deleted file mode 100644
index 5c4003c75a..0000000000
--- a/packages/backend/src/remote/activitypub/renderer/tombstone.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export default (id: string) => ({
-	id,
-	type: "Tombstone",
-});
diff --git a/packages/backend/src/remote/activitypub/renderer/undo.ts b/packages/backend/src/remote/activitypub/renderer/undo.ts
deleted file mode 100644
index 249d643b25..0000000000
--- a/packages/backend/src/remote/activitypub/renderer/undo.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import config from "@/config/index.js";
-import type { User } from "@/models/entities/user.js";
-import { ILocalUser } from "@/models/entities/user.js";
-
-export default (object: any, user: { id: User["id"] }) => {
-	if (object == null) return null;
-	const id =
-		typeof object.id === "string" && object.id.startsWith(config.url)
-			? `${object.id}/undo`
-			: undefined;
-
-	return {
-		type: "Undo",
-		...(id ? { id } : {}),
-		actor: `${config.url}/users/${user.id}`,
-		object,
-		published: new Date().toISOString(),
-	};
-};
diff --git a/packages/backend/src/remote/activitypub/renderer/update.ts b/packages/backend/src/remote/activitypub/renderer/update.ts
deleted file mode 100644
index 765a52f06d..0000000000
--- a/packages/backend/src/remote/activitypub/renderer/update.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import config from "@/config/index.js";
-import type { User } from "@/models/entities/user.js";
-
-export default (object: any, user: { id: User["id"] }) => {
-	const activity = {
-		id: `${config.url}/users/${user.id}#updates/${new Date().getTime()}`,
-		actor: `${config.url}/users/${user.id}`,
-		type: "Update",
-		to: ["https://www.w3.org/ns/activitystreams#Public"],
-		object,
-		published: new Date().toISOString(),
-	} as any;
-
-	return activity;
-};
diff --git a/packages/backend/src/remote/activitypub/renderer/vote.ts b/packages/backend/src/remote/activitypub/renderer/vote.ts
deleted file mode 100644
index 21234a112d..0000000000
--- a/packages/backend/src/remote/activitypub/renderer/vote.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import config from "@/config/index.js";
-import type { Note } from "@/models/entities/note.js";
-import type { IRemoteUser, User } from "@/models/entities/user.js";
-import type { PollVote } from "@/models/entities/poll-vote.js";
-import type { Poll } from "@/models/entities/poll.js";
-
-export default async function renderVote(
-	user: { id: User["id"] },
-	vote: PollVote,
-	note: Note,
-	poll: Poll,
-	pollOwner: IRemoteUser,
-): Promise<any> {
-	return {
-		id: `${config.url}/users/${user.id}#votes/${vote.id}/activity`,
-		actor: `${config.url}/users/${user.id}`,
-		type: "Create",
-		to: [pollOwner.uri],
-		published: new Date().toISOString(),
-		object: {
-			id: `${config.url}/users/${user.id}#votes/${vote.id}`,
-			type: "Note",
-			attributedTo: `${config.url}/users/${user.id}`,
-			to: [pollOwner.uri],
-			inReplyTo: note.uri,
-			name: poll.choices[vote.choice],
-		},
-	};
-}
diff --git a/packages/backend/src/remote/activitypub/request.ts b/packages/backend/src/remote/activitypub/request.ts
deleted file mode 100644
index ffb3e25a33..0000000000
--- a/packages/backend/src/remote/activitypub/request.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-import config from "@/config/index.js";
-import { getUserKeypair } from "@/misc/keypair-store.js";
-import type { User } from "@/models/entities/user.js";
-import { getResponse } from "../../misc/fetch.js";
-import { createSignedPost, createSignedGet } from "./ap-request.js";
-
-export default async (user: { id: User["id"] }, url: string, object: any) => {
-	const body = JSON.stringify(object);
-
-	const keypair = await getUserKeypair(user.id);
-
-	const req = createSignedPost({
-		key: {
-			privateKeyPem: keypair.privateKey,
-			keyId: `${config.url}/users/${user.id}#main-key`,
-		},
-		url,
-		body,
-		additionalHeaders: {
-			"User-Agent": config.userAgent,
-		},
-	});
-
-	await getResponse({
-		url,
-		method: req.request.method,
-		headers: req.request.headers,
-		body,
-	});
-};
-
-/**
- * Get AP object with http-signature
- * @param user http-signature user
- * @param url URL to fetch
- */
-export async function signedGet(url: string, user: { id: User["id"] }) {
-	const keypair = await getUserKeypair(user.id);
-
-	const req = createSignedGet({
-		key: {
-			privateKeyPem: keypair.privateKey,
-			keyId: `${config.url}/users/${user.id}#main-key`,
-		},
-		url,
-		additionalHeaders: {
-			"User-Agent": config.userAgent,
-		},
-	});
-
-	const res = await getResponse({
-		url,
-		method: req.request.method,
-		headers: req.request.headers,
-	});
-
-	return await res.json();
-}
diff --git a/packages/backend/src/remote/activitypub/resolver.ts b/packages/backend/src/remote/activitypub/resolver.ts
deleted file mode 100644
index 0547927609..0000000000
--- a/packages/backend/src/remote/activitypub/resolver.ts
+++ /dev/null
@@ -1,169 +0,0 @@
-import config from "@/config/index.js";
-import { getJson } from "@/misc/fetch.js";
-import type { ILocalUser } from "@/models/entities/user.js";
-import { getInstanceActor } from "@/services/instance-actor.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { extractDbHost, isSelfHost } from "@/misc/convert-host.js";
-import { signedGet } from "./request.js";
-import type { IObject, ICollection, IOrderedCollection } from "./type.js";
-import { isCollectionOrOrderedCollection, getApId } from "./type.js";
-import {
-	FollowRequests,
-	Notes,
-	NoteReactions,
-	Polls,
-	Users,
-} from "@/models/index.js";
-import { parseUri } from "./db-resolver.js";
-import renderNote from "@/remote/activitypub/renderer/note.js";
-import { renderLike } from "@/remote/activitypub/renderer/like.js";
-import { renderPerson } from "@/remote/activitypub/renderer/person.js";
-import renderQuestion from "@/remote/activitypub/renderer/question.js";
-import renderCreate from "@/remote/activitypub/renderer/create.js";
-import { renderActivity } from "@/remote/activitypub/renderer/index.js";
-import renderFollow from "@/remote/activitypub/renderer/follow.js";
-import { shouldBlockInstance } from "@/misc/should-block-instance.js";
-
-export default class Resolver {
-	private history: Set<string>;
-	private user?: ILocalUser;
-	private recursionLimit?: number;
-
-	constructor(recursionLimit = 100) {
-		this.history = new Set();
-		this.recursionLimit = recursionLimit;
-	}
-
-	public getHistory(): string[] {
-		return Array.from(this.history);
-	}
-
-	public async resolveCollection(
-		value: string | IObject,
-	): Promise<ICollection | IOrderedCollection> {
-		const collection = await this.resolve(value);
-
-		if (isCollectionOrOrderedCollection(collection)) {
-			return collection;
-		} else {
-			throw new Error(`unrecognized collection type: ${collection.type}`);
-		}
-	}
-
-	public async resolve(value: string | IObject): Promise<IObject> {
-		if (value == null) {
-			throw new Error("resolvee is null (or undefined)");
-		}
-
-		if (typeof value !== "string") {
-			if (typeof value.id !== "undefined") {
-				const host = extractDbHost(getApId(value));
-				if (await shouldBlockInstance(host)) {
-					throw new Error("instance is blocked");
-				}
-			}
-			return value;
-		}
-
-		if (value.includes("#")) {
-			// URLs with fragment parts cannot be resolved correctly because
-			// the fragment part does not get transmitted over HTTP(S).
-			// Avoid strange behaviour by not trying to resolve these at all.
-			throw new Error(`cannot resolve URL with fragment: ${value}`);
-		}
-
-		if (this.history.has(value)) {
-			throw new Error("cannot resolve already resolved one");
-		}
-		if (this.recursionLimit && this.history.size > this.recursionLimit) {
-			throw new Error("hit recursion limit");
-		}
-		this.history.add(value);
-
-		const host = extractDbHost(value);
-		if (isSelfHost(host)) {
-			return await this.resolveLocal(value);
-		}
-
-		const meta = await fetchMeta();
-		if (await shouldBlockInstance(host, meta)) {
-			throw new Error("Instance is blocked");
-		}
-
-		if (
-			meta.privateMode &&
-			config.host !== host &&
-			!meta.allowedHosts.includes(host)
-		) {
-			throw new Error("Instance is not allowed");
-		}
-
-		if (!this.user) {
-			this.user = await getInstanceActor();
-		}
-
-		const object = (
-			this.user
-				? await signedGet(value, this.user)
-				: await getJson(value, "application/activity+json, application/ld+json")
-		) as IObject;
-
-		if (
-			object == null ||
-			(Array.isArray(object["@context"])
-				? !(object["@context"] as unknown[]).includes(
-						"https://www.w3.org/ns/activitystreams",
-				  )
-				: object["@context"] !== "https://www.w3.org/ns/activitystreams")
-		) {
-			throw new Error("invalid response");
-		}
-
-		return object;
-	}
-
-	private resolveLocal(url: string): Promise<IObject> {
-		const parsed = parseUri(url);
-		if (!parsed.local) throw new Error("resolveLocal: not local");
-
-		switch (parsed.type) {
-			case "notes":
-				return Notes.findOneByOrFail({ id: parsed.id }).then((note) => {
-					if (parsed.rest === "activity") {
-						// this refers to the create activity and not the note itself
-						return renderActivity(renderCreate(renderNote(note)));
-					} else {
-						return renderNote(note);
-					}
-				});
-			case "users":
-				return Users.findOneByOrFail({ id: parsed.id }).then((user) =>
-					renderPerson(user as ILocalUser),
-				);
-			case "questions":
-				// Polls are indexed by the note they are attached to.
-				return Promise.all([
-					Notes.findOneByOrFail({ id: parsed.id }),
-					Polls.findOneByOrFail({ noteId: parsed.id }),
-				]).then(([note, poll]) =>
-					renderQuestion({ id: note.userId }, note, poll),
-				);
-			case "likes":
-				return NoteReactions.findOneByOrFail({ id: parsed.id }).then(
-					(reaction) => renderActivity(renderLike(reaction, { uri: null })),
-				);
-			case "follows":
-				// rest should be <followee id>
-				if (parsed.rest == null || !/^\w+$/.test(parsed.rest))
-					throw new Error("resolveLocal: invalid follow URI");
-
-				return Promise.all(
-					[parsed.id, parsed.rest].map((id) => Users.findOneByOrFail({ id })),
-				).then(([follower, followee]) =>
-					renderActivity(renderFollow(follower, followee, url)),
-				);
-			default:
-				throw new Error(`resolveLocal: type ${type} unhandled`);
-		}
-	}
-}
diff --git a/packages/backend/src/remote/activitypub/type.ts b/packages/backend/src/remote/activitypub/type.ts
deleted file mode 100644
index b0bdb0a8b4..0000000000
--- a/packages/backend/src/remote/activitypub/type.ts
+++ /dev/null
@@ -1,354 +0,0 @@
-export type obj = { [x: string]: any };
-export type ApObject = IObject | string | (IObject | string)[];
-
-export interface IObject {
-	"@context": string | string[] | obj | obj[];
-	type: string | string[];
-	id?: string;
-	summary?: string;
-	published?: string;
-	cc?: ApObject;
-	to?: ApObject;
-	attributedTo: ApObject;
-	attachment?: any[];
-	inReplyTo?: any;
-	replies?: ICollection;
-	content?: string;
-	name?: string;
-	startTime?: Date;
-	endTime?: Date;
-	icon?: any;
-	image?: any;
-	url?: ApObject;
-	href?: string;
-	tag?: IObject | IObject[];
-	sensitive?: boolean;
-}
-
-/**
- * Get array of ActivityStreams Objects id
- */
-export function getApIds(value: ApObject | undefined): string[] {
-	if (value == null) return [];
-	const array = Array.isArray(value) ? value : [value];
-	return array.map((x) => getApId(x));
-}
-
-/**
- * Get first ActivityStreams Object id
- */
-export function getOneApId(value: ApObject): string {
-	const firstOne = Array.isArray(value) ? value[0] : value;
-	return getApId(firstOne);
-}
-
-/**
- * Get ActivityStreams Object id
- */
-export function getApId(value: string | IObject): string {
-	if (typeof value === "string") return value;
-	if (typeof value.id === "string") return value.id;
-	throw new Error("cannot detemine id");
-}
-
-/**
- * Get ActivityStreams Object type
- */
-export function getApType(value: IObject): string {
-	if (typeof value.type === "string") return value.type;
-	if (Array.isArray(value.type) && typeof value.type[0] === "string")
-		return value.type[0];
-	throw new Error("cannot detect type");
-}
-
-export function getOneApHrefNullable(
-	value: ApObject | undefined,
-): string | undefined {
-	const firstOne = Array.isArray(value) ? value[0] : value;
-	return getApHrefNullable(firstOne);
-}
-
-export function getApHrefNullable(
-	value: string | IObject | undefined,
-): string | undefined {
-	if (typeof value === "string") return value;
-	if (typeof value?.href === "string") return value.href;
-	return undefined;
-}
-
-export interface IActivity extends IObject {
-	//type: 'Activity';
-	actor: IObject | string;
-	object: IObject | string;
-	target?: IObject | string;
-	/** LD-Signature */
-	signature?: {
-		type: string;
-		created: Date;
-		creator: string;
-		domain?: string;
-		nonce?: string;
-		signatureValue: string;
-	};
-}
-
-export interface ICollection extends IObject {
-	type: "Collection";
-	totalItems: number;
-	items: ApObject;
-}
-
-export interface IOrderedCollection extends IObject {
-	type: "OrderedCollection";
-	totalItems: number;
-	orderedItems: ApObject;
-}
-
-export const validPost = [
-	"Note",
-	"Question",
-	"Article",
-	"Audio",
-	"Document",
-	"Image",
-	"Page",
-	"Video",
-	"Event",
-];
-
-export const isPost = (object: IObject): object is IPost =>
-	validPost.includes(getApType(object));
-
-export interface IPost extends IObject {
-	type:
-		| "Note"
-		| "Question"
-		| "Article"
-		| "Audio"
-		| "Document"
-		| "Image"
-		| "Page"
-		| "Video"
-		| "Event";
-	source?: {
-		content: string;
-		mediaType: string;
-	};
-	_misskey_quote?: string;
-	quoteUrl?: string;
-	quoteUri?: string;
-	_misskey_talk: boolean;
-}
-
-export interface IQuestion extends IObject {
-	type: "Note" | "Question";
-	source?: {
-		content: string;
-		mediaType: string;
-	};
-	_misskey_quote?: string;
-	quoteUrl?: string;
-	oneOf?: IQuestionChoice[];
-	anyOf?: IQuestionChoice[];
-	endTime?: Date;
-	closed?: Date;
-}
-
-export const isQuestion = (object: IObject): object is IQuestion =>
-	getApType(object) === "Note" || getApType(object) === "Question";
-
-interface IQuestionChoice {
-	name?: string;
-	replies?: ICollection;
-	_misskey_votes?: number;
-}
-export interface ITombstone extends IObject {
-	type: "Tombstone";
-	formerType?: string;
-	deleted?: Date;
-}
-
-export const isTombstone = (object: IObject): object is ITombstone =>
-	getApType(object) === "Tombstone";
-
-export const validActor = [
-	"Person",
-	"Service",
-	"Group",
-	"Organization",
-	"Application",
-];
-
-export const isActor = (object: IObject): object is IActor =>
-	validActor.includes(getApType(object));
-
-export interface IActor extends IObject {
-	type: "Person" | "Service" | "Organization" | "Group" | "Application";
-	name?: string;
-	preferredUsername?: string;
-	manuallyApprovesFollowers?: boolean;
-	movedTo?: string;
-	alsoKnownAs?: string[];
-	discoverable?: boolean;
-	inbox: string;
-	sharedInbox?: string; // backward compatibility.. ig
-	publicKey?: {
-		id: string;
-		publicKeyPem: string;
-	};
-	followers?: string | ICollection | IOrderedCollection;
-	following?: string | ICollection | IOrderedCollection;
-	featured?: string | IOrderedCollection;
-	outbox: string | IOrderedCollection;
-	endpoints?: {
-		sharedInbox?: string;
-	};
-	"vcard:bday"?: string;
-	"vcard:Address"?: string;
-}
-
-export const isCollection = (object: IObject): object is ICollection =>
-	getApType(object) === "Collection";
-
-export const isOrderedCollection = (
-	object: IObject,
-): object is IOrderedCollection => getApType(object) === "OrderedCollection";
-
-export const isCollectionOrOrderedCollection = (
-	object: IObject,
-): object is ICollection | IOrderedCollection =>
-	isCollection(object) || isOrderedCollection(object);
-
-export interface IApPropertyValue extends IObject {
-	type: "PropertyValue";
-	identifier: IApPropertyValue;
-	name: string;
-	value: string;
-}
-
-export const isPropertyValue = (object: IObject): object is IApPropertyValue =>
-	object &&
-	getApType(object) === "PropertyValue" &&
-	typeof object.name === "string" &&
-	typeof (object as any).value === "string";
-
-export interface IApMention extends IObject {
-	type: "Mention";
-	href: string;
-}
-
-export const isMention = (object: IObject): object is IApMention =>
-	getApType(object) === "Mention" && typeof object.href === "string";
-
-export interface IApHashtag extends IObject {
-	type: "Hashtag";
-	name: string;
-}
-
-export const isHashtag = (object: IObject): object is IApHashtag =>
-	getApType(object) === "Hashtag" && typeof object.name === "string";
-
-export interface IApEmoji extends IObject {
-	type: "Emoji";
-	updated: Date;
-}
-
-export const isEmoji = (object: IObject): object is IApEmoji =>
-	getApType(object) === "Emoji" &&
-	!Array.isArray(object.icon) &&
-	object.icon.url != null;
-
-export interface ICreate extends IActivity {
-	type: "Create";
-}
-
-export interface IDelete extends IActivity {
-	type: "Delete";
-}
-
-export interface IUpdate extends IActivity {
-	type: "Update";
-}
-
-export interface IRead extends IActivity {
-	type: "Read";
-}
-
-export interface IUndo extends IActivity {
-	type: "Undo";
-}
-
-export interface IFollow extends IActivity {
-	type: "Follow";
-}
-
-export interface IAccept extends IActivity {
-	type: "Accept";
-}
-
-export interface IReject extends IActivity {
-	type: "Reject";
-}
-
-export interface IAdd extends IActivity {
-	type: "Add";
-}
-
-export interface IRemove extends IActivity {
-	type: "Remove";
-}
-
-export interface ILike extends IActivity {
-	type: "Like" | "EmojiReaction" | "EmojiReact";
-	_misskey_reaction?: string;
-}
-
-export interface IAnnounce extends IActivity {
-	type: "Announce";
-}
-
-export interface IBlock extends IActivity {
-	type: "Block";
-}
-
-export interface IFlag extends IActivity {
-	type: "Flag";
-}
-
-export interface IMove extends IActivity {
-	type: "Move";
-	target: IObject | string;
-}
-
-export const isCreate = (object: IObject): object is ICreate =>
-	getApType(object) === "Create";
-export const isDelete = (object: IObject): object is IDelete =>
-	getApType(object) === "Delete";
-export const isUpdate = (object: IObject): object is IUpdate =>
-	getApType(object) === "Update";
-export const isRead = (object: IObject): object is IRead =>
-	getApType(object) === "Read";
-export const isUndo = (object: IObject): object is IUndo =>
-	getApType(object) === "Undo";
-export const isFollow = (object: IObject): object is IFollow =>
-	getApType(object) === "Follow";
-export const isAccept = (object: IObject): object is IAccept =>
-	getApType(object) === "Accept";
-export const isReject = (object: IObject): object is IReject =>
-	getApType(object) === "Reject";
-export const isAdd = (object: IObject): object is IAdd =>
-	getApType(object) === "Add";
-export const isRemove = (object: IObject): object is IRemove =>
-	getApType(object) === "Remove";
-export const isLike = (object: IObject): object is ILike =>
-	getApType(object) === "Like" ||
-	getApType(object) === "EmojiReaction" ||
-	getApType(object) === "EmojiReact";
-export const isAnnounce = (object: IObject): object is IAnnounce =>
-	getApType(object) === "Announce";
-export const isBlock = (object: IObject): object is IBlock =>
-	getApType(object) === "Block";
-export const isFlag = (object: IObject): object is IFlag =>
-	getApType(object) === "Flag";
-export const isMove = (object: IObject): object is IMove =>
-	getApType(object) === "Move";
diff --git a/packages/backend/src/remote/logger.ts b/packages/backend/src/remote/logger.ts
deleted file mode 100644
index b6bc5bf6dd..0000000000
--- a/packages/backend/src/remote/logger.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import Logger from "@/services/logger.js";
-
-export const remoteLogger = new Logger("remote", "cyan");
diff --git a/packages/backend/src/remote/resolve-user.ts b/packages/backend/src/remote/resolve-user.ts
deleted file mode 100644
index a6c1e399a5..0000000000
--- a/packages/backend/src/remote/resolve-user.ts
+++ /dev/null
@@ -1,139 +0,0 @@
-import { URL } from "node:url";
-import chalk from "chalk";
-import { IsNull } from "typeorm";
-import config from "@/config/index.js";
-import type { User, IRemoteUser } from "@/models/entities/user.js";
-import { Users } from "@/models/index.js";
-import { toPuny } from "@/misc/convert-host.js";
-import webFinger from "./webfinger.js";
-import { createPerson, updatePerson } from "./activitypub/models/person.js";
-import { remoteLogger } from "./logger.js";
-
-const logger = remoteLogger.createSubLogger("resolve-user");
-
-export async function resolveUser(
-	username: string,
-	host: string | null,
-): Promise<User> {
-	const usernameLower = username.toLowerCase();
-
-	if (host == null) {
-		logger.info(`return local user: ${usernameLower}`);
-		return await Users.findOneBy({ usernameLower, host: IsNull() }).then(
-			(u) => {
-				if (u == null) {
-					throw new Error("user not found");
-				} else {
-					return u;
-				}
-			},
-		);
-	}
-
-	host = toPuny(host);
-
-	if (config.host === host) {
-		logger.info(`return local user: ${usernameLower}`);
-		return await Users.findOneBy({ usernameLower, host: IsNull() }).then(
-			(u) => {
-				if (u == null) {
-					throw new Error("user not found");
-				} else {
-					return u;
-				}
-			},
-		);
-	}
-
-	const user = (await Users.findOneBy({
-		usernameLower,
-		host,
-	})) as IRemoteUser | null;
-
-	const acctLower = `${usernameLower}@${host}`;
-
-	if (user == null) {
-		const self = await resolveSelf(acctLower);
-
-		logger.succ(`return new remote user: ${chalk.magenta(acctLower)}`);
-		return await createPerson(self.href);
-	}
-
-	// If user information is out of date, return it by starting over from WebFilger
-	if (
-		user.lastFetchedAt == null ||
-		Date.now() - user.lastFetchedAt.getTime() > 1000 * 60 * 60 * 24
-	) {
-		// Prevent multiple attempts to connect to unconnected instances, update before each attempt to prevent subsequent similar attempts
-		await Users.update(user.id, {
-			lastFetchedAt: new Date(),
-		});
-
-		logger.info(`try resync: ${acctLower}`);
-		const self = await resolveSelf(acctLower);
-
-		if (user.uri !== self.href) {
-			// if uri mismatch, Fix (user@host <=> AP's Person id(IRemoteUser.uri)) mapping.
-			logger.info(`uri missmatch: ${acctLower}`);
-			logger.info(
-				`recovery missmatch uri for (username=${username}, host=${host}) from ${user.uri} to ${self.href}`,
-			);
-
-			// validate uri
-			const uri = new URL(self.href);
-			if (uri.hostname !== host) {
-				throw new Error("Invalid uri");
-			}
-
-			await Users.update(
-				{
-					usernameLower,
-					host: host,
-				},
-				{
-					uri: self.href,
-				},
-			);
-		} else {
-			logger.info(`uri is fine: ${acctLower}`);
-		}
-
-		await updatePerson(self.href);
-
-		logger.info(`return resynced remote user: ${acctLower}`);
-		return await Users.findOneBy({ uri: self.href }).then((u) => {
-			if (u == null) {
-				throw new Error("user not found");
-			} else {
-				return u;
-			}
-		});
-	}
-
-	logger.info(`return existing remote user: ${acctLower}`);
-	return user;
-}
-
-async function resolveSelf(acctLower: string) {
-	logger.info(`WebFinger for ${chalk.yellow(acctLower)}`);
-	const finger = await webFinger(acctLower).catch((e) => {
-		logger.error(
-			`Failed to WebFinger for ${chalk.yellow(acctLower)}: ${
-				e.statusCode || e.message
-			}`,
-		);
-		throw new Error(
-			`Failed to WebFinger for ${acctLower}: ${e.statusCode || e.message}`,
-		);
-	});
-	const self = finger.links.find(
-		(link) => link.rel != null && link.rel.toLowerCase() === "self",
-	);
-	if (!self) {
-		logger.error(
-			`Failed to WebFinger for ${chalk.yellow(acctLower)}: self link not found`,
-		);
-		throw new Error("self link not found");
-	}
-	return self;
-}
diff --git a/packages/backend/src/remote/webfinger.ts b/packages/backend/src/remote/webfinger.ts
deleted file mode 100644
index 1e929c8ff1..0000000000
--- a/packages/backend/src/remote/webfinger.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import { URL } from "node:url";
-import { getJson } from "@/misc/fetch.js";
-import { query as urlQuery } from "@/prelude/url.js";
-
-type ILink = {
-	href: string;
-	rel?: string;
-};
-
-type IWebFinger = {
-	links: ILink[];
-	subject: string;
-};
-
-export default async function (query: string): Promise<IWebFinger> {
-	const url = genUrl(query);
-
-	return (await getJson(
-		url,
-		"application/jrd+json, application/json",
-	)) as IWebFinger;
-}
-
-function genUrl(query: string) {
-	if (query.match(/^https?:\/\//)) {
-		const u = new URL(query);
-		return `${u.protocol}//${u.hostname}/.well-known/webfinger?${urlQuery({
-			resource: query,
-		})}`;
-	}
-
-	const m = query.match(/^([^@]+)@(.*)/);
-	if (m) {
-		const hostname = m[2];
-		return `https://${hostname}/.well-known/webfinger?${urlQuery({
-			resource: `acct:${query}`,
-		})}`;
-	}
-
-	throw new Error(`Invalid query (${query})`);
-}
diff --git a/packages/backend/src/server/activitypub.ts b/packages/backend/src/server/activitypub.ts
deleted file mode 100644
index 29ac726efc..0000000000
--- a/packages/backend/src/server/activitypub.ts
+++ /dev/null
@@ -1,368 +0,0 @@
-import Router from "@koa/router";
-import json from "koa-json-body";
-import httpSignature from "@peertube/http-signature";
-
-import { In, IsNull, Not } from "typeorm";
-import { renderActivity } from "@/remote/activitypub/renderer/index.js";
-import renderNote from "@/remote/activitypub/renderer/note.js";
-import renderKey from "@/remote/activitypub/renderer/key.js";
-import { renderPerson } from "@/remote/activitypub/renderer/person.js";
-import renderEmoji from "@/remote/activitypub/renderer/emoji.js";
-import { inbox as processInbox } from "@/queue/index.js";
-import { isSelfHost, toPuny } from "@/misc/convert-host.js";
-import { Notes, Users, Emojis, NoteReactions } from "@/models/index.js";
-import type { ILocalUser, User } from "@/models/entities/user.js";
-import { renderLike } from "@/remote/activitypub/renderer/like.js";
-import { getUserKeypair } from "@/misc/keypair-store.js";
-import { checkFetch, hasSignature } from "@/remote/activitypub/check-fetch.js";
-import { getInstanceActor } from "@/services/instance-actor.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import renderFollow from "@/remote/activitypub/renderer/follow.js";
-import Featured from "./activitypub/featured.js";
-import Following from "./activitypub/following.js";
-import Followers from "./activitypub/followers.js";
-import Outbox, { packActivity } from "./activitypub/outbox.js";
-
-// Init router
-const router = new Router();
-
-//#region Routing
-
-function inbox(ctx: Router.RouterContext) {
-	let signature;
-
-	try {
-		signature = httpSignature.parseRequest(ctx.req, { headers: [] });
-	} catch (e) {
-		ctx.status = 401;
-		return;
-	}
-
-	processInbox(ctx.request.body, signature);
-
-	ctx.status = 202;
-}
-
-const ACTIVITY_JSON = "application/activity+json; charset=utf-8";
-const LD_JSON =
-	'application/ld+json; profile="https://www.w3.org/ns/activitystreams"; charset=utf-8';
-
-function isActivityPubReq(ctx: Router.RouterContext) {
-	ctx.response.vary("Accept");
-	const accepted = ctx.accepts("html", ACTIVITY_JSON, LD_JSON);
-	return typeof accepted === "string" && !accepted.match(/html/);
-}
-
-export function setResponseType(ctx: Router.RouterContext) {
-	const accept = ctx.accepts(ACTIVITY_JSON, LD_JSON);
-	if (accept === LD_JSON) {
-		ctx.response.type = LD_JSON;
-	} else {
-		ctx.response.type = ACTIVITY_JSON;
-	}
-}
-
-// inbox
-router.post("/inbox", json(), inbox);
-router.post("/users/:user/inbox", json(), inbox);
-
-// note
-router.get("/notes/:note", async (ctx, next) => {
-	if (!isActivityPubReq(ctx)) return await next();
-
-	const verify = await checkFetch(ctx.req);
-	if (verify !== 200) {
-		ctx.status = verify;
-		return;
-	}
-
-	const note = await Notes.findOneBy({
-		id: ctx.params.note,
-		visibility: In(["public" as const, "home" as const]),
-		localOnly: false,
-	});
-
-	if (note == null) {
-		ctx.status = 404;
-		return;
-	}
-
-	// redirect if remote
-	if (note.userHost !== null) {
-		if (note.uri == null || isSelfHost(note.userHost)) {
-			ctx.status = 500;
-			return;
-		}
-		ctx.redirect(note.uri);
-		return;
-	}
-
-	ctx.body = renderActivity(await renderNote(note, false));
-
-	const meta = await fetchMeta();
-	if (meta.secureMode || meta.privateMode) {
-		ctx.set("Cache-Control", "private, max-age=0, must-revalidate");
-	} else {
-		ctx.set("Cache-Control", "public, max-age=180");
-	}
-	setResponseType(ctx);
-});
-
-// note activity
-router.get("/notes/:note/activity", async (ctx) => {
-	const verify = await checkFetch(ctx.req);
-	if (verify !== 200) {
-		ctx.status = verify;
-		return;
-	}
-
-	const note = await Notes.findOneBy({
-		id: ctx.params.note,
-		userHost: IsNull(),
-		visibility: In(["public" as const, "home" as const]),
-		localOnly: false,
-	});
-
-	if (note == null) {
-		ctx.status = 404;
-		return;
-	}
-
-	ctx.body = renderActivity(await packActivity(note));
-	const meta = await fetchMeta();
-	if (meta.secureMode || meta.privateMode) {
-		ctx.set("Cache-Control", "private, max-age=0, must-revalidate");
-	} else {
-		ctx.set("Cache-Control", "public, max-age=180");
-	}
-	setResponseType(ctx);
-});
-
-// outbox
-router.get("/users/:user/outbox", Outbox);
-
-// followers
-router.get("/users/:user/followers", Followers);
-
-// following
-router.get("/users/:user/following", Following);
-
-// featured
-router.get("/users/:user/collections/featured", Featured);
-
-// publickey
-router.get("/users/:user/publickey", async (ctx) => {
-	const instanceActor = await getInstanceActor();
-	if (ctx.params.user === instanceActor.id) {
-		ctx.body = renderActivity(
-			renderKey(instanceActor, await getUserKeypair(instanceActor.id)),
-		);
-		ctx.set("Cache-Control", "public, max-age=180");
-		setResponseType(ctx);
-		return;
-	}
-
-	const verify = await checkFetch(ctx.req);
-	if (verify !== 200) {
-		ctx.status = verify;
-		return;
-	}
-
-	const userId = ctx.params.user;
-
-	const user = await Users.findOneBy({
-		id: userId,
-		host: IsNull(),
-	});
-
-	if (user == null) {
-		ctx.status = 404;
-		return;
-	}
-
-	const keypair = await getUserKeypair(user.id);
-
-	if (Users.isLocalUser(user)) {
-		ctx.body = renderActivity(renderKey(user, keypair));
-		const meta = await fetchMeta();
-		if (meta.secureMode || meta.privateMode) {
-			ctx.set("Cache-Control", "private, max-age=0, must-revalidate");
-		} else {
-			ctx.set("Cache-Control", "public, max-age=180");
-		}
-		setResponseType(ctx);
-	} else {
-		ctx.status = 400;
-	}
-});
-
-// user
-async function userInfo(ctx: Router.RouterContext, user: User | null) {
-	if (user == null) {
-		ctx.status = 404;
-		return;
-	}
-
-	ctx.body = renderActivity(await renderPerson(user as ILocalUser));
-	const meta = await fetchMeta();
-	if (meta.secureMode || meta.privateMode) {
-		ctx.set("Cache-Control", "private, max-age=0, must-revalidate");
-	} else {
-		ctx.set("Cache-Control", "public, max-age=180");
-	}
-	setResponseType(ctx);
-}
-
-router.get("/users/:user", async (ctx, next) => {
-	if (!isActivityPubReq(ctx)) return await next();
-
-	const instanceActor = await getInstanceActor();
-	if (ctx.params.user === instanceActor.id) {
-		await userInfo(ctx, instanceActor);
-		return;
-	}
-
-	const verify = await checkFetch(ctx.req);
-	if (verify !== 200) {
-		ctx.status = verify;
-		return;
-	}
-
-	const userId = ctx.params.user;
-
-	const user = await Users.findOneBy({
-		id: userId,
-		host: IsNull(),
-		isSuspended: false,
-	});
-
-	await userInfo(ctx, user);
-});
-
-router.get("/@:user", async (ctx, next) => {
-	if (!isActivityPubReq(ctx)) return await next();
-
-	if (ctx.params.user === "instance.actor") {
-		const instanceActor = await getInstanceActor();
-		await userInfo(ctx, instanceActor);
-		return;
-	}
-
-	const verify = await checkFetch(ctx.req);
-	if (verify !== 200) {
-		ctx.status = verify;
-		return;
-	}
-
-	const user = await Users.findOneBy({
-		usernameLower: ctx.params.user.toLowerCase(),
-		host: IsNull(),
-		isSuspended: false,
-	});
-
-	await userInfo(ctx, user);
-});
-
-router.get("/actor", async (ctx, next) => {
-	const instanceActor = await getInstanceActor();
-	await userInfo(ctx, instanceActor);
-});
-//#endregion
-
-// emoji
-router.get("/emojis/:emoji", async (ctx) => {
-	const verify = await checkFetch(ctx.req);
-	if (verify !== 200) {
-		ctx.status = verify;
-		return;
-	}
-
-	const emoji = await Emojis.findOneBy({
-		host: IsNull(),
-		name: ctx.params.emoji,
-	});
-
-	if (emoji == null) {
-		ctx.status = 404;
-		return;
-	}
-
-	ctx.body = renderActivity(await renderEmoji(emoji));
-	const meta = await fetchMeta();
-	if (meta.secureMode || meta.privateMode) {
-		ctx.set("Cache-Control", "private, max-age=0, must-revalidate");
-	} else {
-		ctx.set("Cache-Control", "public, max-age=180");
-	}
-	setResponseType(ctx);
-});
-
-// like
-router.get("/likes/:like", async (ctx) => {
-	const verify = await checkFetch(ctx.req);
-	if (verify !== 200) {
-		ctx.status = verify;
-		return;
-	}
-
-	const reaction = await NoteReactions.findOneBy({ id: ctx.params.like });
-
-	if (reaction == null) {
-		ctx.status = 404;
-		return;
-	}
-
-	const note = await Notes.findOneBy({ id: reaction.noteId });
-
-	if (note == null) {
-		ctx.status = 404;
-		return;
-	}
-
-	ctx.body = renderActivity(await renderLike(reaction, note));
-	const meta = await fetchMeta();
-	if (meta.secureMode || meta.privateMode) {
-		ctx.set("Cache-Control", "private, max-age=0, must-revalidate");
-	} else {
-		ctx.set("Cache-Control", "public, max-age=180");
-	}
-	setResponseType(ctx);
-});
-
-// follow
-router.get("/follows/:follower/:followee", async (ctx) => {
-	const verify = await checkFetch(ctx.req);
-	if (verify !== 200) {
-		ctx.status = verify;
-		return;
-	}
-	// This may be used before the follow is completed, so we do not
-	// check if the following exists.
-
-	const [follower, followee] = await Promise.all([
-		Users.findOneBy({
-			id: ctx.params.follower,
-			host: IsNull(),
-		}),
-		Users.findOneBy({
-			id: ctx.params.followee,
-			host: Not(IsNull()),
-		}),
-	]);
-
-	if (follower == null || followee == null) {
-		ctx.status = 404;
-		return;
-	}
-
-	ctx.body = renderActivity(renderFollow(follower, followee));
-	const meta = await fetchMeta();
-	if (meta.secureMode || meta.privateMode) {
-		ctx.set("Cache-Control", "private, max-age=0, must-revalidate");
-	} else {
-		ctx.set("Cache-Control", "public, max-age=180");
-	}
-	setResponseType(ctx);
-});
-
-export default router;
diff --git a/packages/backend/src/server/activitypub/featured.ts b/packages/backend/src/server/activitypub/featured.ts
deleted file mode 100644
index 82bb19fa12..0000000000
--- a/packages/backend/src/server/activitypub/featured.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-import { IsNull } from "typeorm";
-import config from "@/config/index.js";
-import { renderActivity } from "@/remote/activitypub/renderer/index.js";
-import renderOrderedCollection from "@/remote/activitypub/renderer/ordered-collection.js";
-import renderNote from "@/remote/activitypub/renderer/note.js";
-import { Users, Notes, UserNotePinings } from "@/models/index.js";
-import { checkFetch } from "@/remote/activitypub/check-fetch.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { setResponseType } from "../activitypub.js";
-import type Router from "@koa/router";
-
-export default async (ctx: Router.RouterContext) => {
-	const verify = await checkFetch(ctx.req);
-	if (verify !== 200) {
-		ctx.status = verify;
-		return;
-	}
-
-	const userId = ctx.params.user;
-
-	const user = await Users.findOneBy({
-		id: userId,
-		host: IsNull(),
-	});
-
-	if (user == null) {
-		ctx.status = 404;
-		return;
-	}
-
-	const pinings = await UserNotePinings.find({
-		where: { userId: user.id },
-		order: { id: "DESC" },
-	});
-
-	const pinnedNotes = await Promise.all(
-		pinings.map((pining) => Notes.findOneByOrFail({ id: pining.noteId })),
-	);
-
-	const renderedNotes = await Promise.all(
-		pinnedNotes.map((note) => renderNote(note)),
-	);
-
-	const rendered = renderOrderedCollection(
-		`${config.url}/users/${userId}/collections/featured`,
-		renderedNotes.length,
-		undefined,
-		undefined,
-		renderedNotes,
-	);
-
-	ctx.body = renderActivity(rendered);
-
-	const meta = await fetchMeta();
-	if (meta.secureMode || meta.privateMode) {
-		ctx.set("Cache-Control", "private, max-age=0, must-revalidate");
-	} else {
-		ctx.set("Cache-Control", "public, max-age=180");
-	}
-	setResponseType(ctx);
-};
diff --git a/packages/backend/src/server/activitypub/followers.ts b/packages/backend/src/server/activitypub/followers.ts
deleted file mode 100644
index 146ca51928..0000000000
--- a/packages/backend/src/server/activitypub/followers.ts
+++ /dev/null
@@ -1,119 +0,0 @@
-import { IsNull, LessThan } from "typeorm";
-import config from "@/config/index.js";
-import * as url from "@/prelude/url.js";
-import { renderActivity } from "@/remote/activitypub/renderer/index.js";
-import renderOrderedCollection from "@/remote/activitypub/renderer/ordered-collection.js";
-import renderOrderedCollectionPage from "@/remote/activitypub/renderer/ordered-collection-page.js";
-import renderFollowUser from "@/remote/activitypub/renderer/follow-user.js";
-import { Users, Followings, UserProfiles } from "@/models/index.js";
-import type { Following } from "@/models/entities/following.js";
-import { checkFetch } from "@/remote/activitypub/check-fetch.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { setResponseType } from "../activitypub.js";
-import type { FindOptionsWhere } from "typeorm";
-import type Router from "@koa/router";
-
-export default async (ctx: Router.RouterContext) => {
-	const verify = await checkFetch(ctx.req);
-	if (verify !== 200) {
-		ctx.status = verify;
-		return;
-	}
-
-	const userId = ctx.params.user;
-
-	const cursor = ctx.request.query.cursor;
-	if (cursor != null && typeof cursor !== "string") {
-		ctx.status = 400;
-		return;
-	}
-
-	const page = ctx.request.query.page === "true";
-
-	const user = await Users.findOneBy({
-		id: userId,
-		host: IsNull(),
-	});
-
-	if (user == null) {
-		ctx.status = 404;
-		return;
-	}
-
-	//#region Check ff visibility
-	const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
-
-	if (profile.ffVisibility === "private") {
-		ctx.status = 403;
-		ctx.set("Cache-Control", "public, max-age=30");
-		return;
-	} else if (profile.ffVisibility === "followers") {
-		ctx.status = 403;
-		ctx.set("Cache-Control", "public, max-age=30");
-		return;
-	}
-	//#endregion
-
-	const limit = 10;
-	const partOf = `${config.url}/users/${userId}/followers`;
-
-	if (page) {
-		const query = {
-			followeeId: user.id,
-		} as FindOptionsWhere<Following>;
-
-		// カーソルが指定されている場合
-		if (cursor) {
-			query.id = LessThan(cursor);
-		}
-
-		// Get followers
-		const followings = await Followings.find({
-			where: query,
-			take: limit + 1,
-			order: { id: -1 },
-		});
-
-		// 「次のページ」があるかどうか
-		const inStock = followings.length === limit + 1;
-		if (inStock) followings.pop();
-
-		const renderedFollowers = await Promise.all(
-			followings.map((following) => renderFollowUser(following.followerId)),
-		);
-		const rendered = renderOrderedCollectionPage(
-			`${partOf}?${url.query({
-				page: "true",
-				cursor,
-			})}`,
-			user.followersCount,
-			renderedFollowers,
-			partOf,
-			undefined,
-			inStock
-				? `${partOf}?${url.query({
-						page: "true",
-						cursor: followings[followings.length - 1].id,
-				  })}`
-				: undefined,
-		);
-
-		ctx.body = renderActivity(rendered);
-		setResponseType(ctx);
-	} else {
-		// index page
-		const rendered = renderOrderedCollection(
-			partOf,
-			user.followersCount,
-			`${partOf}?page=true`,
-		);
-		ctx.body = renderActivity(rendered);
-		setResponseType(ctx);
-	}
-	const meta = await fetchMeta();
-	if (meta.secureMode || meta.privateMode) {
-		ctx.set("Cache-Control", "private, max-age=0, must-revalidate");
-	} else {
-		ctx.set("Cache-Control", "public, max-age=180");
-	}
-};
diff --git a/packages/backend/src/server/activitypub/following.ts b/packages/backend/src/server/activitypub/following.ts
deleted file mode 100644
index eab513ce64..0000000000
--- a/packages/backend/src/server/activitypub/following.ts
+++ /dev/null
@@ -1,119 +0,0 @@
-import { LessThan, IsNull } from "typeorm";
-import config from "@/config/index.js";
-import * as url from "@/prelude/url.js";
-import { renderActivity } from "@/remote/activitypub/renderer/index.js";
-import renderOrderedCollection from "@/remote/activitypub/renderer/ordered-collection.js";
-import renderOrderedCollectionPage from "@/remote/activitypub/renderer/ordered-collection-page.js";
-import renderFollowUser from "@/remote/activitypub/renderer/follow-user.js";
-import { Users, Followings, UserProfiles } from "@/models/index.js";
-import type { Following } from "@/models/entities/following.js";
-import { checkFetch } from "@/remote/activitypub/check-fetch.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { setResponseType } from "../activitypub.js";
-import type { FindOptionsWhere } from "typeorm";
-import type Router from "@koa/router";
-
-export default async (ctx: Router.RouterContext) => {
-	const verify = await checkFetch(ctx.req);
-	if (verify !== 200) {
-		ctx.status = verify;
-		return;
-	}
-
-	const userId = ctx.params.user;
-
-	const cursor = ctx.request.query.cursor;
-	if (cursor != null && typeof cursor !== "string") {
-		ctx.status = 400;
-		return;
-	}
-
-	const page = ctx.request.query.page === "true";
-
-	const user = await Users.findOneBy({
-		id: userId,
-		host: IsNull(),
-	});
-
-	if (user == null) {
-		ctx.status = 404;
-		return;
-	}
-
-	//#region Check ff visibility
-	const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
-
-	if (profile.ffVisibility === "private") {
-		ctx.status = 403;
-		ctx.set("Cache-Control", "public, max-age=30");
-		return;
-	} else if (profile.ffVisibility === "followers") {
-		ctx.status = 403;
-		ctx.set("Cache-Control", "public, max-age=30");
-		return;
-	}
-	//#endregion
-
-	const limit = 10;
-	const partOf = `${config.url}/users/${userId}/following`;
-
-	if (page) {
-		const query = {
-			followerId: user.id,
-		} as FindOptionsWhere<Following>;
-
-		// If a cursor is specified
-		if (cursor) {
-			query.id = LessThan(cursor);
-		}
-
-		// Get followings
-		const followings = await Followings.find({
-			where: query,
-			take: limit + 1,
-			order: { id: -1 },
-		});
-
-		// Whether there is a "next page" or not
-		const inStock = followings.length === limit + 1;
-		if (inStock) followings.pop();
-
-		const renderedFollowees = await Promise.all(
-			followings.map((following) => renderFollowUser(following.followeeId)),
-		);
-		const rendered = renderOrderedCollectionPage(
-			`${partOf}?${url.query({
-				page: "true",
-				cursor,
-			})}`,
-			user.followingCount,
-			renderedFollowees,
-			partOf,
-			undefined,
-			inStock
-				? `${partOf}?${url.query({
-						page: "true",
-						cursor: followings[followings.length - 1].id,
-				  })}`
-				: undefined,
-		);
-
-		ctx.body = renderActivity(rendered);
-		setResponseType(ctx);
-	} else {
-		// index page
-		const rendered = renderOrderedCollection(
-			partOf,
-			user.followingCount,
-			`${partOf}?page=true`,
-		);
-		ctx.body = renderActivity(rendered);
-		setResponseType(ctx);
-	}
-	const meta = await fetchMeta();
-	if (meta.secureMode || meta.privateMode) {
-		ctx.set("Cache-Control", "private, max-age=0, must-revalidate");
-	} else {
-		ctx.set("Cache-Control", "public, max-age=180");
-	}
-};
diff --git a/packages/backend/src/server/activitypub/outbox.ts b/packages/backend/src/server/activitypub/outbox.ts
deleted file mode 100644
index e0a380ffb6..0000000000
--- a/packages/backend/src/server/activitypub/outbox.ts
+++ /dev/null
@@ -1,147 +0,0 @@
-import { Brackets, IsNull } from "typeorm";
-import config from "@/config/index.js";
-import { renderActivity } from "@/remote/activitypub/renderer/index.js";
-import renderOrderedCollection from "@/remote/activitypub/renderer/ordered-collection.js";
-import renderOrderedCollectionPage from "@/remote/activitypub/renderer/ordered-collection-page.js";
-import renderNote from "@/remote/activitypub/renderer/note.js";
-import renderCreate from "@/remote/activitypub/renderer/create.js";
-import renderAnnounce from "@/remote/activitypub/renderer/announce.js";
-import { countIf } from "@/prelude/array.js";
-import * as url from "@/prelude/url.js";
-import { Users, Notes } from "@/models/index.js";
-import type { Note } from "@/models/entities/note.js";
-import { checkFetch } from "@/remote/activitypub/check-fetch.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { makePaginationQuery } from "../api/common/make-pagination-query.js";
-import { setResponseType } from "../activitypub.js";
-import type Router from "@koa/router";
-
-export default async (ctx: Router.RouterContext) => {
-	const verify = await checkFetch(ctx.req);
-	if (verify !== 200) {
-		ctx.status = verify;
-		return;
-	}
-
-	const userId = ctx.params.user;
-
-	const sinceId = ctx.request.query.since_id;
-	if (sinceId != null && typeof sinceId !== "string") {
-		ctx.status = 400;
-		return;
-	}
-
-	const untilId = ctx.request.query.until_id;
-	if (untilId != null && typeof untilId !== "string") {
-		ctx.status = 400;
-		return;
-	}
-
-	const page = ctx.request.query.page === "true";
-
-	if (countIf((x) => x != null, [sinceId, untilId]) > 1) {
-		ctx.status = 400;
-		return;
-	}
-
-	const user = await Users.findOneBy({
-		id: userId,
-		host: IsNull(),
-	});
-
-	if (user == null) {
-		ctx.status = 404;
-		return;
-	}
-
-	const limit = 20;
-	const partOf = `${config.url}/users/${userId}/outbox`;
-
-	if (page) {
-		const query = makePaginationQuery(
-			Notes.createQueryBuilder("note"),
-			sinceId,
-			untilId,
-		)
-			.andWhere("note.userId = :userId", { userId: user.id })
-			.andWhere(
-				new Brackets((qb) => {
-					qb.where("note.visibility = 'public'").orWhere(
-						"note.visibility = 'home'",
-					);
-				}),
-			)
-			.andWhere("note.localOnly = FALSE");
-
-		const notes = await query.take(limit).getMany();
-
-		if (sinceId) notes.reverse();
-
-		const activities = await Promise.all(
-			notes.map((note) => packActivity(note)),
-		);
-		const rendered = renderOrderedCollectionPage(
-			`${partOf}?${url.query({
-				page: "true",
-				since_id: sinceId,
-				until_id: untilId,
-			})}`,
-			user.notesCount,
-			activities,
-			partOf,
-			notes.length
-				? `${partOf}?${url.query({
-						page: "true",
-						since_id: notes[0].id,
-				  })}`
-				: undefined,
-			notes.length
-				? `${partOf}?${url.query({
-						page: "true",
-						until_id: notes[notes.length - 1].id,
-				  })}`
-				: undefined,
-		);
-
-		ctx.body = renderActivity(rendered);
-		setResponseType(ctx);
-	} else {
-		// index page
-		const rendered = renderOrderedCollection(
-			partOf,
-			user.notesCount,
-			`${partOf}?page=true`,
-			`${partOf}?page=true&since_id=000000000000000000000000`,
-		);
-		ctx.body = renderActivity(rendered);
-
-		setResponseType(ctx);
-	}
-	const meta = await fetchMeta();
-	if (meta.secureMode || meta.privateMode) {
-		ctx.set("Cache-Control", "private, max-age=0, must-revalidate");
-	} else {
-		ctx.set("Cache-Control", "public, max-age=180");
-	}
-};
-
-/**
- * Pack Create<Note> or Announce Activity
- * @param note Note
- */
-export async function packActivity(note: Note): Promise<any> {
-	if (
-		note.renoteId &&
-		note.text == null &&
-		!note.hasPoll &&
-		(note.fileIds == null || note.fileIds.length === 0)
-	) {
-		const renote = await Notes.findOneByOrFail({ id: note.renoteId });
-		return renderAnnounce(
-			renote.uri ? renote.uri : `${config.url}/notes/${renote.id}`,
-			note,
-		);
-	}
-
-	return renderCreate(await renderNote(note, false), note);
-}
diff --git a/packages/backend/src/server/api/2fa.ts b/packages/backend/src/server/api/2fa.ts
deleted file mode 100644
index 7318f0f433..0000000000
--- a/packages/backend/src/server/api/2fa.ts
+++ /dev/null
@@ -1,417 +0,0 @@
-import * as crypto from "node:crypto";
-import * as jsrsasign from "jsrsasign";
-import config from "@/config/index.js";
-
-const ECC_PRELUDE = Buffer.from([0x04]);
-const NULL_BYTE = Buffer.from([0]);
-const PEM_PRELUDE = Buffer.from(
-	"3059301306072a8648ce3d020106082a8648ce3d030107034200",
-	"hex",
-);
-
-// Android Safetynet attestations are signed with this cert:
-const GSR2 = `-----BEGIN CERTIFICATE-----
-MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G
-A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp
-Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1
-MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG
-A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
-hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL
-v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8
-eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq
-tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd
-C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa
-zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB
-mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH
-V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n
-bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG
-3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs
-J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO
-291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS
-ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd
-AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
-TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
------END CERTIFICATE-----\n`;
-
-function base64URLDecode(source: string) {
-	return Buffer.from(source.replace(/\-/g, "+").replace(/_/g, "/"), "base64");
-}
-
-function getCertSubject(certificate: string) {
-	const subjectCert = new jsrsasign.X509();
-	subjectCert.readCertPEM(certificate);
-
-	const subjectString = subjectCert.getSubjectString();
-	const subjectFields = subjectString.slice(1).split("/");
-
-	const fields = {} as Record<string, string>;
-	for (const field of subjectFields) {
-		const eqIndex = field.indexOf("=");
-		fields[field.substring(0, eqIndex)] = field.substring(eqIndex + 1);
-	}
-
-	return fields;
-}
-
-function verifyCertificateChain(certificates: string[]) {
-	let valid = true;
-
-	for (let i = 0; i < certificates.length; i++) {
-		const Cert = certificates[i];
-		const certificate = new jsrsasign.X509();
-		certificate.readCertPEM(Cert);
-
-		const CACert = i + 1 >= certificates.length ? Cert : certificates[i + 1];
-
-		const certStruct = jsrsasign.ASN1HEX.getTLVbyList(certificate.hex!, 0, [0]);
-		const algorithm = certificate.getSignatureAlgorithmField();
-		const signatureHex = certificate.getSignatureValueHex();
-
-		// Verify against CA
-		const Signature = new jsrsasign.KJUR.crypto.Signature({ alg: algorithm });
-		Signature.init(CACert);
-		Signature.updateHex(certStruct);
-		valid = valid && !!Signature.verify(signatureHex); // true if CA signed the certificate
-	}
-
-	return valid;
-}
-
-function PEMString(pemBuffer: Buffer, type = "CERTIFICATE") {
-	if (pemBuffer.length === 65 && pemBuffer[0] === 0x04) {
-		pemBuffer = Buffer.concat([PEM_PRELUDE, pemBuffer], 91);
-		type = "PUBLIC KEY";
-	}
-	const cert = pemBuffer.toString("base64");
-
-	const keyParts = [];
-	const max = Math.ceil(cert.length / 64);
-	let start = 0;
-	for (let i = 0; i < max; i++) {
-		keyParts.push(cert.substring(start, start + 64));
-		start += 64;
-	}
-
-	return `-----BEGIN ${type}-----\n${keyParts.join(
-		"\n",
-	)}\n-----END ${type}-----\n`;
-}
-
-export function hash(data: Buffer) {
-	return crypto.createHash("sha256").update(data).digest();
-}
-
-export function verifyLogin({
-	publicKey,
-	authenticatorData,
-	clientDataJSON,
-	clientData,
-	signature,
-	challenge,
-}: {
-	publicKey: Buffer;
-	authenticatorData: Buffer;
-	clientDataJSON: Buffer;
-	clientData: any;
-	signature: Buffer;
-	challenge: string;
-}) {
-	if (clientData.type !== "webauthn.get") {
-		throw new Error("type is not webauthn.get");
-	}
-
-	if (hash(clientData.challenge).toString("hex") !== challenge) {
-		throw new Error("challenge mismatch");
-	}
-	if (clientData.origin !== `${config.scheme}://${config.host}`) {
-		throw new Error("origin mismatch");
-	}
-
-	const verificationData = Buffer.concat(
-		[authenticatorData, hash(clientDataJSON)],
-		32 + authenticatorData.length,
-	);
-
-	return crypto
-		.createVerify("SHA256")
-		.update(verificationData)
-		.verify(PEMString(publicKey), signature);
-}
-
-export const procedures = {
-	none: {
-		verify({ publicKey }: { publicKey: Map<number, Buffer> }) {
-			const negTwo = publicKey.get(-2);
-
-			if (!negTwo || negTwo.length !== 32) {
-				throw new Error("invalid or no -2 key given");
-			}
-			const negThree = publicKey.get(-3);
-			if (!negThree || negThree.length !== 32) {
-				throw new Error("invalid or no -3 key given");
-			}
-
-			const publicKeyU2F = Buffer.concat(
-				[ECC_PRELUDE, negTwo, negThree],
-				1 + 32 + 32,
-			);
-
-			return {
-				publicKey: publicKeyU2F,
-				valid: true,
-			};
-		},
-	},
-	"android-key": {
-		verify({
-			attStmt,
-			authenticatorData,
-			clientDataHash,
-			publicKey,
-			rpIdHash,
-			credentialId,
-		}: {
-			attStmt: any;
-			authenticatorData: Buffer;
-			clientDataHash: Buffer;
-			publicKey: Map<number, any>;
-			rpIdHash: Buffer;
-			credentialId: Buffer;
-		}) {
-			if (attStmt.alg !== -7) {
-				throw new Error("alg mismatch");
-			}
-
-			const verificationData = Buffer.concat([
-				authenticatorData,
-				clientDataHash,
-			]);
-
-			const attCert: Buffer = attStmt.x5c[0];
-
-			const negTwo = publicKey.get(-2);
-
-			if (!negTwo || negTwo.length !== 32) {
-				throw new Error("invalid or no -2 key given");
-			}
-			const negThree = publicKey.get(-3);
-			if (!negThree || negThree.length !== 32) {
-				throw new Error("invalid or no -3 key given");
-			}
-
-			const publicKeyData = Buffer.concat(
-				[ECC_PRELUDE, negTwo, negThree],
-				1 + 32 + 32,
-			);
-
-			if (!attCert.equals(publicKeyData)) {
-				throw new Error("public key mismatch");
-			}
-
-			const isValid = crypto
-				.createVerify("SHA256")
-				.update(verificationData)
-				.verify(PEMString(attCert), attStmt.sig);
-
-			// TODO: Check 'attestationChallenge' field in extension of cert matches hash(clientDataJSON)
-
-			return {
-				valid: isValid,
-				publicKey: publicKeyData,
-			};
-		},
-	},
-	// what a stupid attestation
-	"android-safetynet": {
-		verify({
-			attStmt,
-			authenticatorData,
-			clientDataHash,
-			publicKey,
-			rpIdHash,
-			credentialId,
-		}: {
-			attStmt: any;
-			authenticatorData: Buffer;
-			clientDataHash: Buffer;
-			publicKey: Map<number, any>;
-			rpIdHash: Buffer;
-			credentialId: Buffer;
-		}) {
-			const verificationData = hash(
-				Buffer.concat([authenticatorData, clientDataHash]),
-			);
-
-			const jwsParts = attStmt.response.toString("utf-8").split(".");
-
-			const header = JSON.parse(base64URLDecode(jwsParts[0]).toString("utf-8"));
-			const response = JSON.parse(
-				base64URLDecode(jwsParts[1]).toString("utf-8"),
-			);
-			const signature = jwsParts[2];
-
-			if (!verificationData.equals(Buffer.from(response.nonce, "base64"))) {
-				throw new Error("invalid nonce");
-			}
-
-			const certificateChain = header.x5c
-				.map((key: any) => PEMString(key))
-				.concat([GSR2]);
-
-			if (getCertSubject(certificateChain[0]).CN !== "attest.android.com") {
-				throw new Error("invalid common name");
-			}
-
-			if (!verifyCertificateChain(certificateChain)) {
-				throw new Error("Invalid certificate chain!");
-			}
-
-			const signatureBase = Buffer.from(
-				`${jwsParts[0]}.${jwsParts[1]}`,
-				"utf-8",
-			);
-
-			const valid = crypto
-				.createVerify("sha256")
-				.update(signatureBase)
-				.verify(certificateChain[0], base64URLDecode(signature));
-
-			const negTwo = publicKey.get(-2);
-
-			if (!negTwo || negTwo.length !== 32) {
-				throw new Error("invalid or no -2 key given");
-			}
-			const negThree = publicKey.get(-3);
-			if (!negThree || negThree.length !== 32) {
-				throw new Error("invalid or no -3 key given");
-			}
-
-			const publicKeyData = Buffer.concat(
-				[ECC_PRELUDE, negTwo, negThree],
-				1 + 32 + 32,
-			);
-			return {
-				valid,
-				publicKey: publicKeyData,
-			};
-		},
-	},
-	packed: {
-		verify({
-			attStmt,
-			authenticatorData,
-			clientDataHash,
-			publicKey,
-			rpIdHash,
-			credentialId,
-		}: {
-			attStmt: any;
-			authenticatorData: Buffer;
-			clientDataHash: Buffer;
-			publicKey: Map<number, any>;
-			rpIdHash: Buffer;
-			credentialId: Buffer;
-		}) {
-			const verificationData = Buffer.concat([
-				authenticatorData,
-				clientDataHash,
-			]);
-
-			if (attStmt.x5c) {
-				const attCert = attStmt.x5c[0];
-
-				const validSignature = crypto
-					.createVerify("SHA256")
-					.update(verificationData)
-					.verify(PEMString(attCert), attStmt.sig);
-
-				const negTwo = publicKey.get(-2);
-
-				if (!negTwo || negTwo.length !== 32) {
-					throw new Error("invalid or no -2 key given");
-				}
-				const negThree = publicKey.get(-3);
-				if (!negThree || negThree.length !== 32) {
-					throw new Error("invalid or no -3 key given");
-				}
-
-				const publicKeyData = Buffer.concat(
-					[ECC_PRELUDE, negTwo, negThree],
-					1 + 32 + 32,
-				);
-
-				return {
-					valid: validSignature,
-					publicKey: publicKeyData,
-				};
-			} else if (attStmt.ecdaaKeyId) {
-				// https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-ecdaa-algorithm-v2.0-id-20180227.html#ecdaa-verify-operation
-				throw new Error("ECDAA-Verify is not supported");
-			} else {
-				if (attStmt.alg !== -7) throw new Error("alg mismatch");
-
-				throw new Error("self attestation is not supported");
-			}
-		},
-	},
-
-	"fido-u2f": {
-		verify({
-			attStmt,
-			authenticatorData,
-			clientDataHash,
-			publicKey,
-			rpIdHash,
-			credentialId,
-		}: {
-			attStmt: any;
-			authenticatorData: Buffer;
-			clientDataHash: Buffer;
-			publicKey: Map<number, any>;
-			rpIdHash: Buffer;
-			credentialId: Buffer;
-		}) {
-			const x5c: Buffer[] = attStmt.x5c;
-			if (x5c.length !== 1) {
-				throw new Error("x5c length does not match expectation");
-			}
-
-			const attCert = x5c[0];
-
-			// TODO: make sure attCert is an Elliptic Curve (EC) public key over the P-256 curve
-
-			const negTwo: Buffer = publicKey.get(-2);
-
-			if (!negTwo || negTwo.length !== 32) {
-				throw new Error("invalid or no -2 key given");
-			}
-			const negThree: Buffer = publicKey.get(-3);
-			if (!negThree || negThree.length !== 32) {
-				throw new Error("invalid or no -3 key given");
-			}
-
-			const publicKeyU2F = Buffer.concat(
-				[ECC_PRELUDE, negTwo, negThree],
-				1 + 32 + 32,
-			);
-
-			const verificationData = Buffer.concat([
-				NULL_BYTE,
-				rpIdHash,
-				clientDataHash,
-				credentialId,
-				publicKeyU2F,
-			]);
-
-			const validSignature = crypto
-				.createVerify("SHA256")
-				.update(verificationData)
-				.verify(PEMString(attCert), attStmt.sig);
-
-			return {
-				valid: validSignature,
-				publicKey: publicKeyU2F,
-			};
-		},
-	},
-};
diff --git a/packages/backend/src/server/api/api-handler.ts b/packages/backend/src/server/api/api-handler.ts
deleted file mode 100644
index 99a12fd110..0000000000
--- a/packages/backend/src/server/api/api-handler.ts
+++ /dev/null
@@ -1,123 +0,0 @@
-import type Koa from "koa";
-
-import type { User } from "@/models/entities/user.js";
-import { UserIps } from "@/models/index.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import type { IEndpoint } from "./endpoints.js";
-import authenticate, { AuthenticationError } from "./authenticate.js";
-import call from "./call.js";
-import { ApiError } from "./error.js";
-
-const userIpHistories = new Map<User["id"], Set<string>>();
-
-setInterval(() => {
-	userIpHistories.clear();
-}, 1000 * 60 * 60);
-
-export default (endpoint: IEndpoint, ctx: Koa.Context) =>
-	new Promise<void>((res) => {
-		const body = ctx.is("multipart/form-data")
-			? (ctx.request as any).body
-			: ctx.method === "GET"
-			? ctx.query
-			: ctx.request.body;
-
-		const reply = (x?: any, y?: ApiError) => {
-			if (x == null) {
-				ctx.status = 204;
-			} else if (typeof x === "number" && y) {
-				ctx.status = x;
-				ctx.body = {
-					error: {
-						message: y!.message,
-						code: y!.code,
-						id: y!.id,
-						kind: y!.kind,
-						...(y!.info ? { info: y!.info } : {}),
-					},
-				};
-			} else {
-				// 文字列を返す場合は、JSON.stringify通さないとJSONと認識されない
-				ctx.body = typeof x === "string" ? JSON.stringify(x) : x;
-			}
-			res();
-		};
-
-		// Authentication
-		// for GET requests, do not even pass on the body parameter as it is considered unsafe
-		authenticate(
-			ctx.headers.authorization,
-			ctx.method === "GET" ? null : body["i"],
-		)
-			.then(([user, app]) => {
-				// API invoking
-				call(endpoint.name, user, app, body, ctx)
-					.then((res: any) => {
-						if (
-							ctx.method === "GET" &&
-							endpoint.meta.cacheSec &&
-							!body["i"] &&
-							!user
-						) {
-							ctx.set(
-								"Cache-Control",
-								`public, max-age=${endpoint.meta.cacheSec}`,
-							);
-						}
-						reply(res);
-					})
-					.catch((e: ApiError) => {
-						reply(
-							e.httpStatusCode
-								? e.httpStatusCode
-								: e.kind === "client"
-								? 400
-								: 500,
-							e,
-						);
-					});
-
-				// Log IP
-				if (user) {
-					fetchMeta().then((meta) => {
-						if (!meta.enableIpLogging) return;
-						const ip = ctx.ip;
-						const ips = userIpHistories.get(user.id);
-						if (ips == null || !ips.has(ip)) {
-							if (ips == null) {
-								userIpHistories.set(user.id, new Set([ip]));
-							} else {
-								ips.add(ip);
-							}
-
-							try {
-								UserIps.createQueryBuilder()
-									.insert()
-									.values({
-										createdAt: new Date(),
-										userId: user.id,
-										ip: ip,
-									})
-									.orIgnore(true)
-									.execute();
-							} catch {}
-						}
-					});
-				}
-			})
-			.catch((e) => {
-				if (e instanceof AuthenticationError) {
-					ctx.response.status = 403;
-					ctx.response.set("WWW-Authenticate", "Bearer");
-					ctx.response.body = {
-						message: `Authentication failed: ${e.message}`,
-						code: "AUTHENTICATION_FAILED",
-						id: "b0a7f5f8-dc2f-4171-b91f-de88ad238e14",
-						kind: "client",
-					};
-					res();
-				} else {
-					reply(500, new ApiError());
-				}
-			});
-	});
diff --git a/packages/backend/src/server/api/authenticate.ts b/packages/backend/src/server/api/authenticate.ts
deleted file mode 100644
index 42274ad2a4..0000000000
--- a/packages/backend/src/server/api/authenticate.ts
+++ /dev/null
@@ -1,103 +0,0 @@
-import isNativeToken from "./common/is-native-token.js";
-import type { CacheableLocalUser, ILocalUser } from "@/models/entities/user.js";
-import { Users, AccessTokens, Apps } from "@/models/index.js";
-import type { AccessToken } from "@/models/entities/access-token.js";
-import { Cache } from "@/misc/cache.js";
-import type { App } from "@/models/entities/app.js";
-import {
-	localUserByIdCache,
-	localUserByNativeTokenCache,
-} from "@/services/user-cache.js";
-
-const appCache = new Cache<App>(Infinity);
-
-export class AuthenticationError extends Error {
-	constructor(message: string) {
-		super(message);
-		this.name = "AuthenticationError";
-	}
-}
-
-export default async (
-	authorization: string | null | undefined,
-	bodyToken: string | null,
-): Promise<
-	[CacheableLocalUser | null | undefined, AccessToken | null | undefined]
-> => {
-	let token: string | null = null;
-
-	// check if there is an authorization header set
-	if (authorization != null) {
-		if (bodyToken != null) {
-			throw new AuthenticationError("using multiple authorization schemes");
-		}
-
-		// check if OAuth 2.0 Bearer tokens are being used
-		// Authorization schemes are case insensitive
-		if (authorization.substring(0, 7).toLowerCase() === "bearer ") {
-			token = authorization.substring(7);
-		} else {
-			throw new AuthenticationError("unsupported authentication scheme");
-		}
-	} else if (bodyToken != null) {
-		token = bodyToken;
-	} else {
-		return [null, null];
-	}
-
-	if (isNativeToken(token)) {
-		const user = await localUserByNativeTokenCache.fetch(
-			token,
-			() => Users.findOneBy({ token }) as Promise<ILocalUser | null>,
-		);
-
-		if (user == null) {
-			throw new AuthenticationError("unknown token");
-		}
-
-		return [user, null];
-	} else {
-		const accessToken = await AccessTokens.findOne({
-			where: [
-				{
-					hash: token.toLowerCase(), // app
-				},
-				{
-					token: token, // miauth
-				},
-			],
-		});
-
-		if (accessToken == null) {
-			throw new AuthenticationError("unknown token");
-		}
-
-		AccessTokens.update(accessToken.id, {
-			lastUsedAt: new Date(),
-		});
-
-		const user = await localUserByIdCache.fetch(
-			accessToken.userId,
-			() =>
-				Users.findOneBy({
-					id: accessToken.userId,
-				}) as Promise<ILocalUser>,
-		);
-
-		if (accessToken.appId) {
-			const app = await appCache.fetch(accessToken.appId, () =>
-				Apps.findOneByOrFail({ id: accessToken.appId! }),
-			);
-
-			return [
-				user,
-				{
-					id: accessToken.id,
-					permission: app.permission,
-				} as AccessToken,
-			];
-		} else {
-			return [user, accessToken];
-		}
-	}
-};
diff --git a/packages/backend/src/server/api/call.ts b/packages/backend/src/server/api/call.ts
deleted file mode 100644
index 45471ed564..0000000000
--- a/packages/backend/src/server/api/call.ts
+++ /dev/null
@@ -1,192 +0,0 @@
-import { performance } from "perf_hooks";
-import type Koa from "koa";
-import type { CacheableLocalUser } from "@/models/entities/user.js";
-import { User } from "@/models/entities/user.js";
-import type { AccessToken } from "@/models/entities/access-token.js";
-import { getIpHash } from "@/misc/get-ip-hash.js";
-import { limiter } from "./limiter.js";
-import type { IEndpointMeta } from "./endpoints.js";
-import endpoints from "./endpoints.js";
-import compatibility from "./compatibility.js";
-import { ApiError } from "./error.js";
-import { apiLogger } from "./logger.js";
-import type { AccessToken } from "@/models/entities/access-token.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-
-const accessDenied = {
-	message: "Access denied.",
-	code: "ACCESS_DENIED",
-	id: "56f35758-7dd5-468b-8439-5d6fb8ec9b8e",
-};
-
-export default async (
-	endpoint: string,
-	user: CacheableLocalUser | null | undefined,
-	token: AccessToken | null | undefined,
-	data: any,
-	ctx?: Koa.Context,
-) => {
-	const isSecure = user != null && token == null;
-	const isModerator = user != null && (user.isModerator || user.isAdmin);
-
-	const ep =
-		endpoints.find((e) => e.name === endpoint) ||
-		compatibility.find((e) => e.name === endpoint);
-
-	if (ep == null) {
-		throw new ApiError({
-			message: "No such endpoint.",
-			code: "NO_SUCH_ENDPOINT",
-			id: "f8080b67-5f9c-4eb7-8c18-7f1eeae8f709",
-			httpStatusCode: 404,
-		});
-	}
-
-	if (ep.meta.secure && !isSecure) {
-		throw new ApiError(accessDenied);
-	}
-
-	if (ep.meta.limit) {
-		// koa will automatically load the `X-Forwarded-For` header if `proxy: true` is configured in the app.
-		let limitActor: string;
-		if (user) {
-			limitActor = user.id;
-		} else {
-			limitActor = getIpHash(ctx!.ip);
-		}
-
-		const limit = Object.assign({}, ep.meta.limit);
-
-		if (!limit.key) {
-			limit.key = ep.name;
-		}
-
-		// Rate limit
-		await limiter(
-			limit as IEndpointMeta["limit"] & { key: NonNullable<string> },
-			limitActor,
-		).catch((e) => {
-			throw new ApiError({
-				message: "Rate limit exceeded. Please try again later.",
-				code: "RATE_LIMIT_EXCEEDED",
-				id: "d5826d14-3982-4d2e-8011-b9e9f02499ef",
-				httpStatusCode: 429,
-			});
-		});
-	}
-
-	if (ep.meta.requireCredential && user == null) {
-		throw new ApiError({
-			message: "Credential required.",
-			code: "CREDENTIAL_REQUIRED",
-			id: "1384574d-a912-4b81-8601-c7b1c4085df1",
-			httpStatusCode: 401,
-		});
-	}
-
-	if (ep.meta.requireCredential && user!.isSuspended) {
-		throw new ApiError({
-			message: "Your account has been suspended.",
-			code: "YOUR_ACCOUNT_SUSPENDED",
-			id: "a8c724b3-6e9c-4b46-b1a8-bc3ed6258370",
-			httpStatusCode: 403,
-		});
-	}
-
-	if (ep.meta.requireAdmin && !user!.isAdmin) {
-		throw new ApiError(accessDenied, { reason: "You are not the admin." });
-	}
-
-	if (ep.meta.requireModerator && !isModerator) {
-		throw new ApiError(accessDenied, { reason: "You are not a moderator." });
-	}
-
-	if (
-		token &&
-		ep.meta.kind &&
-		!token.permission.some((p) => p === ep.meta.kind)
-	) {
-		throw new ApiError({
-			message:
-				"Your app does not have the necessary permissions to use this endpoint.",
-			code: "PERMISSION_DENIED",
-			id: "1370e5b7-d4eb-4566-bb1d-7748ee6a1838",
-		});
-	}
-
-	// private mode
-	const meta = await fetchMeta();
-	if (
-		meta.privateMode &&
-		ep.meta.requireCredentialPrivateMode &&
-		user == null
-	) {
-		throw new ApiError({
-			message: "Credential required.",
-			code: "CREDENTIAL_REQUIRED",
-			id: "1384574d-a912-4b81-8601-c7b1c4085df1",
-			httpStatusCode: 401,
-		});
-	}
-
-	// Cast non JSON input
-	if ((ep.meta.requireFile || ctx?.method === "GET") && ep.params.properties) {
-		for (const k of Object.keys(ep.params.properties)) {
-			const param = ep.params.properties![k];
-			if (
-				["boolean", "number", "integer"].includes(param.type ?? "") &&
-				typeof data[k] === "string"
-			) {
-				try {
-					data[k] = JSON.parse(data[k]);
-				} catch (e) {
-					throw new ApiError(
-						{
-							message: "Invalid param.",
-							code: "INVALID_PARAM",
-							id: "0b5f1631-7c1a-41a6-b399-cce335f34d85",
-						},
-						{
-							param: k,
-							reason: `cannot cast to ${param.type}`,
-						},
-					);
-				}
-			}
-		}
-	}
-
-	// API invoking
-	const before = performance.now();
-	return await ep
-		.exec(data, user, token, ctx?.file, ctx?.ip, ctx?.headers)
-		.catch((e: Error) => {
-			if (e instanceof ApiError) {
-				throw e;
-			} else {
-				apiLogger.error(`Internal error occurred in ${ep.name}: ${e.message}`, {
-					ep: ep.name,
-					ps: data,
-					e: {
-						message: e.message,
-						code: e.name,
-						stack: e.stack,
-					},
-				});
-				throw new ApiError(null, {
-					e: {
-						message: e.message,
-						code: e.name,
-						stack: e.stack,
-					},
-				});
-			}
-		})
-		.finally(() => {
-			const after = performance.now();
-			const time = after - before;
-			if (time > 1000) {
-				apiLogger.warn(`SLOW API CALL DETECTED: ${ep.name} (${time}ms)`);
-			}
-		});
-};
diff --git a/packages/backend/src/server/api/common/generate-block-query.ts b/packages/backend/src/server/api/common/generate-block-query.ts
deleted file mode 100644
index a37b607eb9..0000000000
--- a/packages/backend/src/server/api/common/generate-block-query.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-import type { User } from "@/models/entities/user.js";
-import { Blockings } from "@/models/index.js";
-import type { SelectQueryBuilder } from "typeorm";
-import { Brackets } from "typeorm";
-
-// ここでいうBlockedは被Blockedの意
-export function generateBlockedUserQuery(
-	q: SelectQueryBuilder<any>,
-	me: { id: User["id"] },
-) {
-	const blockingQuery = Blockings.createQueryBuilder("blocking")
-		.select("blocking.blockerId")
-		.where("blocking.blockeeId = :blockeeId", { blockeeId: me.id });
-
-	// 投稿の作者にブロックされていない かつ
-	// 投稿の返信先の作者にブロックされていない かつ
-	// 投稿の引用元の作者にブロックされていない
-	q.andWhere(`note.userId NOT IN (${blockingQuery.getQuery()})`)
-		.andWhere(
-			new Brackets((qb) => {
-				qb.where("note.replyUserId IS NULL").orWhere(
-					`note.replyUserId NOT IN (${blockingQuery.getQuery()})`,
-				);
-			}),
-		)
-		.andWhere(
-			new Brackets((qb) => {
-				qb.where("note.renoteUserId IS NULL").orWhere(
-					`note.renoteUserId NOT IN (${blockingQuery.getQuery()})`,
-				);
-			}),
-		);
-
-	q.setParameters(blockingQuery.getParameters());
-}
-
-export function generateBlockQueryForUsers(
-	q: SelectQueryBuilder<any>,
-	me: { id: User["id"] },
-) {
-	const blockingQuery = Blockings.createQueryBuilder("blocking")
-		.select("blocking.blockeeId")
-		.where("blocking.blockerId = :blockerId", { blockerId: me.id });
-
-	const blockedQuery = Blockings.createQueryBuilder("blocking")
-		.select("blocking.blockerId")
-		.where("blocking.blockeeId = :blockeeId", { blockeeId: me.id });
-
-	q.andWhere(`user.id NOT IN (${blockingQuery.getQuery()})`);
-	q.setParameters(blockingQuery.getParameters());
-
-	q.andWhere(`user.id NOT IN (${blockedQuery.getQuery()})`);
-	q.setParameters(blockedQuery.getParameters());
-}
diff --git a/packages/backend/src/server/api/common/generate-channel-query.ts b/packages/backend/src/server/api/common/generate-channel-query.ts
deleted file mode 100644
index 318062266e..0000000000
--- a/packages/backend/src/server/api/common/generate-channel-query.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import type { User } from "@/models/entities/user.js";
-import { ChannelFollowings } from "@/models/index.js";
-import type { SelectQueryBuilder } from "typeorm";
-import { Brackets } from "typeorm";
-
-export function generateChannelQuery(
-	q: SelectQueryBuilder<any>,
-	me?: { id: User["id"] } | null,
-) {
-	if (me == null) {
-		q.andWhere("note.channelId IS NULL");
-	} else {
-		q.leftJoinAndSelect("note.channel", "channel");
-
-		const channelFollowingQuery = ChannelFollowings.createQueryBuilder(
-			"channelFollowing",
-		)
-			.select("channelFollowing.followeeId")
-			.where("channelFollowing.followerId = :followerId", {
-				followerId: me.id,
-			});
-
-		q.andWhere(
-			new Brackets((qb) => {
-				qb
-					// チャンネルのノートではない
-					.where("note.channelId IS NULL")
-					// または自分がフォローしているチャンネルのノート
-					.orWhere(`note.channelId IN (${channelFollowingQuery.getQuery()})`);
-			}),
-		);
-
-		q.setParameters(channelFollowingQuery.getParameters());
-	}
-}
diff --git a/packages/backend/src/server/api/common/generate-muted-note-query.ts b/packages/backend/src/server/api/common/generate-muted-note-query.ts
deleted file mode 100644
index 86da2ea883..0000000000
--- a/packages/backend/src/server/api/common/generate-muted-note-query.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import type { User } from "@/models/entities/user.js";
-import { MutedNotes } from "@/models/index.js";
-import type { SelectQueryBuilder } from "typeorm";
-
-export function generateMutedNoteQuery(
-	q: SelectQueryBuilder<any>,
-	me: { id: User["id"] },
-) {
-	const mutedQuery = MutedNotes.createQueryBuilder("muted")
-		.select("muted.noteId")
-		.where("muted.userId = :userId", { userId: me.id });
-
-	q.andWhere(`note.id NOT IN (${mutedQuery.getQuery()})`);
-
-	q.setParameters(mutedQuery.getParameters());
-}
diff --git a/packages/backend/src/server/api/common/generate-muted-note-thread-query.ts b/packages/backend/src/server/api/common/generate-muted-note-thread-query.ts
deleted file mode 100644
index 61f44f4a76..0000000000
--- a/packages/backend/src/server/api/common/generate-muted-note-thread-query.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import type { User } from "@/models/entities/user.js";
-import { NoteThreadMutings } from "@/models/index.js";
-import type { SelectQueryBuilder } from "typeorm";
-import { Brackets } from "typeorm";
-
-export function generateMutedNoteThreadQuery(
-	q: SelectQueryBuilder<any>,
-	me: { id: User["id"] },
-) {
-	const mutedQuery = NoteThreadMutings.createQueryBuilder("threadMuted")
-		.select("threadMuted.threadId")
-		.where("threadMuted.userId = :userId", { userId: me.id });
-
-	q.andWhere(`note.id NOT IN (${mutedQuery.getQuery()})`);
-	q.andWhere(
-		new Brackets((qb) => {
-			qb.where("note.threadId IS NULL").orWhere(
-				`note.threadId NOT IN (${mutedQuery.getQuery()})`,
-			);
-		}),
-	);
-
-	q.setParameters(mutedQuery.getParameters());
-}
diff --git a/packages/backend/src/server/api/common/generate-muted-user-query.ts b/packages/backend/src/server/api/common/generate-muted-user-query.ts
deleted file mode 100644
index 3538fbf0af..0000000000
--- a/packages/backend/src/server/api/common/generate-muted-user-query.ts
+++ /dev/null
@@ -1,81 +0,0 @@
-import type { SelectQueryBuilder } from "typeorm";
-import { Brackets } from "typeorm";
-import type { User } from "@/models/entities/user.js";
-import { Mutings, UserProfiles } from "@/models/index.js";
-
-export function generateMutedUserQuery(
-	q: SelectQueryBuilder<any>,
-	me: { id: User["id"] },
-	exclude?: User,
-) {
-	const mutingQuery = Mutings.createQueryBuilder("muting")
-		.select("muting.muteeId")
-		.where("muting.muterId = :muterId", { muterId: me.id });
-
-	if (exclude) {
-		mutingQuery.andWhere("muting.muteeId != :excludeId", {
-			excludeId: exclude.id,
-		});
-	}
-
-	const mutingInstanceQuery = UserProfiles.createQueryBuilder("user_profile")
-		.select("user_profile.mutedInstances")
-		.where("user_profile.userId = :muterId", { muterId: me.id });
-
-	// 投稿の作者をミュートしていない かつ
-	// 投稿の返信先の作者をミュートしていない かつ
-	// 投稿の引用元の作者をミュートしていない
-	q.andWhere(`note.userId NOT IN (${mutingQuery.getQuery()})`)
-		.andWhere(
-			new Brackets((qb) => {
-				qb.where("note.replyUserId IS NULL").orWhere(
-					`note.replyUserId NOT IN (${mutingQuery.getQuery()})`,
-				);
-			}),
-		)
-		.andWhere(
-			new Brackets((qb) => {
-				qb.where("note.renoteUserId IS NULL").orWhere(
-					`note.renoteUserId NOT IN (${mutingQuery.getQuery()})`,
-				);
-			}),
-		)
-		// mute instances
-		.andWhere(
-			new Brackets((qb) => {
-				qb.andWhere("note.userHost IS NULL").orWhere(
-					`NOT ((${mutingInstanceQuery.getQuery()})::jsonb ? note.userHost)`,
-				);
-			}),
-		)
-		.andWhere(
-			new Brackets((qb) => {
-				qb.where("note.replyUserHost IS NULL").orWhere(
-					`NOT ((${mutingInstanceQuery.getQuery()})::jsonb ? note.replyUserHost)`,
-				);
-			}),
-		)
-		.andWhere(
-			new Brackets((qb) => {
-				qb.where("note.renoteUserHost IS NULL").orWhere(
-					`NOT ((${mutingInstanceQuery.getQuery()})::jsonb ? note.renoteUserHost)`,
-				);
-			}),
-		);
-
-	q.setParameters(mutingQuery.getParameters());
-	q.setParameters(mutingInstanceQuery.getParameters());
-}
-
-export function generateMutedUserQueryForUsers(
-	q: SelectQueryBuilder<any>,
-	me: { id: User["id"] },
-) {
-	const mutingQuery = Mutings.createQueryBuilder("muting")
-		.select("muting.muteeId")
-		.where("muting.muterId = :muterId", { muterId: me.id });
-
-	q.andWhere(`user.id NOT IN (${mutingQuery.getQuery()})`);
-
-	q.setParameters(mutingQuery.getParameters());
-}
diff --git a/packages/backend/src/server/api/common/generate-native-user-token.ts b/packages/backend/src/server/api/common/generate-native-user-token.ts
deleted file mode 100644
index 5a8b41b70e..0000000000
--- a/packages/backend/src/server/api/common/generate-native-user-token.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import { secureRndstr } from "@/misc/secure-rndstr.js";
-
-export default () => secureRndstr(16, true);
diff --git a/packages/backend/src/server/api/common/generate-replies-query.ts b/packages/backend/src/server/api/common/generate-replies-query.ts
deleted file mode 100644
index 140c1d74a0..0000000000
--- a/packages/backend/src/server/api/common/generate-replies-query.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import type { User } from "@/models/entities/user.js";
-import type { SelectQueryBuilder } from "typeorm";
-import { Brackets } from "typeorm";
-
-export function generateRepliesQuery(
-	q: SelectQueryBuilder<any>,
-	me?: Pick<User, "id" | "showTimelineReplies"> | null,
-) {
-	if (me == null) {
-		q.andWhere(
-			new Brackets((qb) => {
-				qb.where("note.replyId IS NULL") // 返信ではない
-					.orWhere(
-						new Brackets((qb) => {
-							qb.where(
-								// 返信だけど投稿者自身への返信
-								"note.replyId IS NOT NULL",
-							).andWhere("note.replyUserId = note.userId");
-						}),
-					);
-			}),
-		);
-	} else if (!me.showTimelineReplies) {
-		q.andWhere(
-			new Brackets((qb) => {
-				qb.where("note.replyId IS NULL") // 返信ではない
-					.orWhere("note.replyUserId = :meId", { meId: me.id }) // 返信だけど自分のノートへの返信
-					.orWhere(
-						new Brackets((qb) => {
-							qb.where(
-								// 返信だけど自分の行った返信
-								"note.replyId IS NOT NULL",
-							).andWhere("note.userId = :meId", { meId: me.id });
-						}),
-					)
-					.orWhere(
-						new Brackets((qb) => {
-							qb.where(
-								// 返信だけど投稿者自身への返信
-								"note.replyId IS NOT NULL",
-							).andWhere("note.replyUserId = note.userId");
-						}),
-					);
-			}),
-		);
-	}
-}
diff --git a/packages/backend/src/server/api/common/generate-visibility-query.ts b/packages/backend/src/server/api/common/generate-visibility-query.ts
deleted file mode 100644
index c434df0820..0000000000
--- a/packages/backend/src/server/api/common/generate-visibility-query.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-import type { User } from "@/models/entities/user.js";
-import { Followings } from "@/models/index.js";
-import type { SelectQueryBuilder } from "typeorm";
-import { Brackets } from "typeorm";
-
-export function generateVisibilityQuery(
-	q: SelectQueryBuilder<any>,
-	me?: { id: User["id"] } | null,
-) {
-	// This code must always be synchronized with the checks in Notes.isVisibleForMe.
-	if (me == null) {
-		q.andWhere(
-			new Brackets((qb) => {
-				qb.where(`note.visibility = 'public'`).orWhere(
-					`note.visibility = 'home'`,
-				);
-			}),
-		);
-	} else {
-		const followingQuery = Followings.createQueryBuilder("following")
-			.select("following.followeeId")
-			.where("following.followerId = :meId");
-
-		q.andWhere(
-			new Brackets((qb) => {
-				qb
-					// 公開投稿である
-					.where(
-						new Brackets((qb) => {
-							qb.where(`note.visibility = 'public'`).orWhere(
-								`note.visibility = 'home'`,
-							);
-						}),
-					)
-					// または 自分自身
-					.orWhere("note.userId = :meId")
-					// または 自分宛て
-					.orWhere(":meId = ANY(note.visibleUserIds)")
-					.orWhere(":meId = ANY(note.mentions)")
-					.orWhere(
-						new Brackets((qb) => {
-							qb
-								// または フォロワー宛ての投稿であり、
-								.where(`note.visibility = 'followers'`)
-								.andWhere(
-									new Brackets((qb) => {
-										qb
-											// 自分がフォロワーである
-											.where(`note.userId IN (${followingQuery.getQuery()})`)
-											// または 自分の投稿へのリプライ
-											.orWhere("note.replyUserId = :meId");
-									}),
-								);
-						}),
-					);
-			}),
-		);
-
-		q.setParameters({ meId: me.id });
-	}
-}
diff --git a/packages/backend/src/server/api/common/generated-muted-renote-query.ts b/packages/backend/src/server/api/common/generated-muted-renote-query.ts
deleted file mode 100644
index 3fcd9b28e8..0000000000
--- a/packages/backend/src/server/api/common/generated-muted-renote-query.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import { Brackets, SelectQueryBuilder } from "typeorm";
-import { User } from "@/models/entities/user.js";
-import { RenoteMutings } from "@/models/index.js";
-
-export function generateMutedUserRenotesQueryForNotes(
-	q: SelectQueryBuilder<any>,
-	me: { id: User["id"] },
-): void {
-	const mutingQuery = RenoteMutings.createQueryBuilder("renote_muting")
-		.select("renote_muting.muteeId")
-		.where("renote_muting.muterId = :muterId", { muterId: me.id });
-
-	q.andWhere(
-		new Brackets((qb) => {
-			qb.where(
-				new Brackets((qb) => {
-					qb.where("note.renoteId IS NOT NULL");
-					qb.andWhere("note.text IS NULL");
-					qb.andWhere(`note.userId NOT IN (${mutingQuery.getQuery()})`);
-				}),
-			)
-				.orWhere("note.renoteId IS NULL")
-				.orWhere("note.text IS NOT NULL");
-		}),
-	);
-
-	q.setParameters(mutingQuery.getParameters());
-}
diff --git a/packages/backend/src/server/api/common/getters.ts b/packages/backend/src/server/api/common/getters.ts
deleted file mode 100644
index fd7580775a..0000000000
--- a/packages/backend/src/server/api/common/getters.ts
+++ /dev/null
@@ -1,72 +0,0 @@
-import { IdentifiableError } from "@/misc/identifiable-error.js";
-import type { User } from "@/models/entities/user.js";
-import type { Note } from "@/models/entities/note.js";
-import { Notes, Users } from "@/models/index.js";
-import { generateVisibilityQuery } from "./generate-visibility-query.js";
-
-/**
- * Get note for API processing, taking into account visibility.
- */
-export async function getNote(
-	noteId: Note["id"],
-	me: { id: User["id"] } | null,
-) {
-	const query = Notes.createQueryBuilder("note").where("note.id = :id", {
-		id: noteId,
-	});
-
-	generateVisibilityQuery(query, me);
-
-	const note = await query.getOne();
-
-	if (note == null) {
-		throw new IdentifiableError(
-			"9725d0ce-ba28-4dde-95a7-2cbb2c15de24",
-			"No such note.",
-		);
-	}
-
-	return note;
-}
-
-/**
- * Get user for API processing
- */
-export async function getUser(userId: User["id"]) {
-	const user = await Users.findOneBy({ id: userId });
-
-	if (user == null) {
-		throw new IdentifiableError(
-			"15348ddd-432d-49c2-8a5a-8069753becff",
-			"No such user.",
-		);
-	}
-
-	return user;
-}
-
-/**
- * Get remote user for API processing
- */
-export async function getRemoteUser(userId: User["id"]) {
-	const user = await getUser(userId);
-
-	if (!Users.isRemoteUser(user)) {
-		throw new Error("user is not a remote user");
-	}
-
-	return user;
-}
-
-/**
- * Get local user for API processing
- */
-export async function getLocalUser(userId: User["id"]) {
-	const user = await getUser(userId);
-
-	if (!Users.isLocalUser(user)) {
-		throw new Error("user is not a local user");
-	}
-
-	return user;
-}
diff --git a/packages/backend/src/server/api/common/inject-featured.ts b/packages/backend/src/server/api/common/inject-featured.ts
deleted file mode 100644
index 30ba3eca93..0000000000
--- a/packages/backend/src/server/api/common/inject-featured.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-import rndstr from "rndstr";
-import type { Note } from "@/models/entities/note.js";
-import type { User } from "@/models/entities/user.js";
-import { Notes, UserProfiles, NoteReactions } from "@/models/index.js";
-import { generateMutedUserQuery } from "./generate-muted-user-query.js";
-import { generateBlockedUserQuery } from "./generate-block-query.js";
-
-// TODO: リアクション、Renote、返信などをしたノートは除外する
-
-export async function injectFeatured(timeline: Note[], user?: User | null) {
-	if (timeline.length < 5) return;
-
-	if (user) {
-		const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
-		if (!profile.injectFeaturedNote) return;
-	}
-
-	const max = 30;
-	const day = 1000 * 60 * 60 * 24 * 3; // 3日前まで
-
-	const query = Notes.createQueryBuilder("note")
-		.addSelect("note.score")
-		.where("note.userHost IS NULL")
-		.andWhere("note.score > 0")
-		.andWhere("note.createdAt > :date", { date: new Date(Date.now() - day) })
-		.andWhere(`note.visibility = 'public'`)
-		.innerJoinAndSelect("note.user", "user");
-
-	if (user) {
-		query.andWhere("note.userId != :userId", { userId: user.id });
-
-		generateMutedUserQuery(query, user);
-		generateBlockedUserQuery(query, user);
-
-		const reactionQuery = NoteReactions.createQueryBuilder("reaction")
-			.select("reaction.noteId")
-			.where("reaction.userId = :userId", { userId: user.id });
-
-		query.andWhere(`note.id NOT IN (${reactionQuery.getQuery()})`);
-	}
-
-	const notes = await query.orderBy("note.score", "DESC").take(max).getMany();
-
-	if (notes.length === 0) return;
-
-	// Pick random one
-	const featured = notes[Math.floor(Math.random() * notes.length)];
-
-	(featured as any)._featuredId_ = rndstr("a-z0-9", 8);
-
-	// Inject featured
-	timeline.splice(3, 0, featured);
-}
diff --git a/packages/backend/src/server/api/common/inject-promo.ts b/packages/backend/src/server/api/common/inject-promo.ts
deleted file mode 100644
index dcc4e5f3fa..0000000000
--- a/packages/backend/src/server/api/common/inject-promo.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import rndstr from "rndstr";
-import type { Note } from "@/models/entities/note.js";
-import type { User } from "@/models/entities/user.js";
-import { PromoReads, PromoNotes, Notes, Users } from "@/models/index.js";
-
-export async function injectPromo(timeline: Note[], user?: User | null) {
-	if (timeline.length < 5) return;
-
-	// TODO: readやexpireフィルタはクエリ側でやる
-
-	const reads = user
-		? await PromoReads.findBy({
-				userId: user.id,
-		  })
-		: [];
-
-	let promos = await PromoNotes.find();
-
-	promos = promos.filter((n) => n.expiresAt.getTime() > Date.now());
-	promos = promos.filter((n) => !reads.map((r) => r.noteId).includes(n.noteId));
-
-	if (promos.length === 0) return;
-
-	// Pick random promo
-	const promo = promos[Math.floor(Math.random() * promos.length)];
-
-	const note = await Notes.findOneByOrFail({ id: promo.noteId });
-
-	// Join
-	note.user = await Users.findOneByOrFail({ id: note.userId });
-
-	(note as any)._prId_ = rndstr("a-z0-9", 8);
-
-	// Inject promo
-	timeline.splice(3, 0, note);
-}
diff --git a/packages/backend/src/server/api/common/is-native-token.ts b/packages/backend/src/server/api/common/is-native-token.ts
deleted file mode 100644
index 2833c570c8..0000000000
--- a/packages/backend/src/server/api/common/is-native-token.ts
+++ /dev/null
@@ -1 +0,0 @@
-export default (token: string) => token.length === 16;
diff --git a/packages/backend/src/server/api/common/make-pagination-query.ts b/packages/backend/src/server/api/common/make-pagination-query.ts
deleted file mode 100644
index a2c3275693..0000000000
--- a/packages/backend/src/server/api/common/make-pagination-query.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import type { SelectQueryBuilder } from "typeorm";
-
-export function makePaginationQuery<T>(
-	q: SelectQueryBuilder<T>,
-	sinceId?: string,
-	untilId?: string,
-	sinceDate?: number,
-	untilDate?: number,
-) {
-	if (sinceId && untilId) {
-		q.andWhere(`${q.alias}.id > :sinceId`, { sinceId: sinceId });
-		q.andWhere(`${q.alias}.id < :untilId`, { untilId: untilId });
-		q.orderBy(`${q.alias}.id`, "DESC");
-	} else if (sinceId) {
-		q.andWhere(`${q.alias}.id > :sinceId`, { sinceId: sinceId });
-		q.orderBy(`${q.alias}.id`, "ASC");
-	} else if (untilId) {
-		q.andWhere(`${q.alias}.id < :untilId`, { untilId: untilId });
-		q.orderBy(`${q.alias}.id`, "DESC");
-	} else if (sinceDate && untilDate) {
-		q.andWhere(`${q.alias}.createdAt > :sinceDate`, {
-			sinceDate: new Date(sinceDate),
-		});
-		q.andWhere(`${q.alias}.createdAt < :untilDate`, {
-			untilDate: new Date(untilDate),
-		});
-		q.orderBy(`${q.alias}.createdAt`, "DESC");
-	} else if (sinceDate) {
-		q.andWhere(`${q.alias}.createdAt > :sinceDate`, {
-			sinceDate: new Date(sinceDate),
-		});
-		q.orderBy(`${q.alias}.createdAt`, "ASC");
-	} else if (untilDate) {
-		q.andWhere(`${q.alias}.createdAt < :untilDate`, {
-			untilDate: new Date(untilDate),
-		});
-		q.orderBy(`${q.alias}.createdAt`, "DESC");
-	} else {
-		q.orderBy(`${q.alias}.id`, "DESC");
-	}
-	return q;
-}
diff --git a/packages/backend/src/server/api/common/read-messaging-message.ts b/packages/backend/src/server/api/common/read-messaging-message.ts
deleted file mode 100644
index fc22c843af..0000000000
--- a/packages/backend/src/server/api/common/read-messaging-message.ts
+++ /dev/null
@@ -1,179 +0,0 @@
-import {
-	publishMainStream,
-	publishGroupMessagingStream,
-} from "@/services/stream.js";
-import { publishMessagingStream } from "@/services/stream.js";
-import { publishMessagingIndexStream } from "@/services/stream.js";
-import { pushNotification } from "@/services/push-notification.js";
-import type { User, IRemoteUser } from "@/models/entities/user.js";
-import type { MessagingMessage } from "@/models/entities/messaging-message.js";
-import { MessagingMessages, UserGroupJoinings, Users } from "@/models/index.js";
-import { In } from "typeorm";
-import { IdentifiableError } from "@/misc/identifiable-error.js";
-import type { UserGroup } from "@/models/entities/user-group.js";
-import { toArray } from "@/prelude/array.js";
-import { renderReadActivity } from "@/remote/activitypub/renderer/read.js";
-import { renderActivity } from "@/remote/activitypub/renderer/index.js";
-import { deliver } from "@/queue/index.js";
-import orderedCollection from "@/remote/activitypub/renderer/ordered-collection.js";
-
-/**
- * Mark messages as read
- */
-export async function readUserMessagingMessage(
-	userId: User["id"],
-	otherpartyId: User["id"],
-	messageIds: MessagingMessage["id"][],
-) {
-	if (messageIds.length === 0) return;
-
-	const messages = await MessagingMessages.findBy({
-		id: In(messageIds),
-	});
-
-	for (const message of messages) {
-		if (message.recipientId !== userId) {
-			throw new IdentifiableError(
-				"e140a4bf-49ce-4fb6-b67c-b78dadf6b52f",
-				"Access denied (user).",
-			);
-		}
-	}
-
-	// Update documents
-	await MessagingMessages.update(
-		{
-			id: In(messageIds),
-			userId: otherpartyId,
-			recipientId: userId,
-			isRead: false,
-		},
-		{
-			isRead: true,
-		},
-	);
-
-	// Publish event
-	publishMessagingStream(otherpartyId, userId, "read", messageIds);
-	publishMessagingIndexStream(userId, "read", messageIds);
-
-	if (!(await Users.getHasUnreadMessagingMessage(userId))) {
-		// 全ての(いままで未読だった)自分宛てのメッセージを(これで)読みましたよというイベントを発行
-		publishMainStream(userId, "readAllMessagingMessages");
-		pushNotification(userId, "readAllMessagingMessages", undefined);
-	} else {
-		// そのユーザーとのメッセージで未読がなければイベント発行
-		const count = await MessagingMessages.count({
-			where: {
-				userId: otherpartyId,
-				recipientId: userId,
-				isRead: false,
-			},
-			take: 1,
-		});
-
-		if (!count) {
-			pushNotification(userId, "readAllMessagingMessagesOfARoom", {
-				userId: otherpartyId,
-			});
-		}
-	}
-}
-
-/**
- * Mark messages as read
- */
-export async function readGroupMessagingMessage(
-	userId: User["id"],
-	groupId: UserGroup["id"],
-	messageIds: MessagingMessage["id"][],
-) {
-	if (messageIds.length === 0) return;
-
-	// check joined
-	const joining = await UserGroupJoinings.findOneBy({
-		userId: userId,
-		userGroupId: groupId,
-	});
-
-	if (joining == null) {
-		throw new IdentifiableError(
-			"930a270c-714a-46b2-b776-ad27276dc569",
-			"Access denied (group).",
-		);
-	}
-
-	const messages = await MessagingMessages.findBy({
-		id: In(messageIds),
-	});
-
-	const reads: MessagingMessage["id"][] = [];
-
-	for (const message of messages) {
-		if (message.userId === userId) continue;
-		if (message.reads.includes(userId)) continue;
-
-		// Update document
-		await MessagingMessages.createQueryBuilder()
-			.update()
-			.set({
-				reads: (() => `array_append("reads", '${joining.userId}')`) as any,
-			})
-			.where("id = :id", { id: message.id })
-			.execute();
-
-		reads.push(message.id);
-	}
-
-	// Publish event
-	publishGroupMessagingStream(groupId, "read", {
-		ids: reads,
-		userId: userId,
-	});
-	publishMessagingIndexStream(userId, "read", reads);
-
-	if (!(await Users.getHasUnreadMessagingMessage(userId))) {
-		// 全ての(いままで未読だった)自分宛てのメッセージを(これで)読みましたよというイベントを発行
-		publishMainStream(userId, "readAllMessagingMessages");
-		pushNotification(userId, "readAllMessagingMessages", undefined);
-	} else {
-		// そのグループにおいて未読がなければイベント発行
-		const unreadExist = await MessagingMessages.createQueryBuilder("message")
-			.where("message.groupId = :groupId", { groupId: groupId })
-			.andWhere("message.userId != :userId", { userId: userId })
-			.andWhere("NOT (:userId = ANY(message.reads))", { userId: userId })
-			.andWhere("message.createdAt > :joinedAt", {
-				joinedAt: joining.createdAt,
-			}) // 自分が加入する前の会話については、未読扱いしない
-			.getOne()
-			.then((x) => x != null);
-
-		if (!unreadExist) {
-			pushNotification(userId, "readAllMessagingMessagesOfARoom", { groupId });
-		}
-	}
-}
-
-export async function deliverReadActivity(
-	user: { id: User["id"]; host: null },
-	recipient: IRemoteUser,
-	messages: MessagingMessage | MessagingMessage[],
-) {
-	messages = toArray(messages).filter((x) => x.uri);
-	const contents = messages.map((x) => renderReadActivity(user, x));
-
-	if (contents.length > 1) {
-		const collection = orderedCollection(
-			null,
-			contents.length,
-			undefined,
-			undefined,
-			contents,
-		);
-		deliver(user, renderActivity(collection), recipient.inbox);
-	} else {
-		for (const content of contents) {
-			deliver(user, renderActivity(content), recipient.inbox);
-		}
-	}
-}
diff --git a/packages/backend/src/server/api/common/read-notification.ts b/packages/backend/src/server/api/common/read-notification.ts
deleted file mode 100644
index 1fb1d642fe..0000000000
--- a/packages/backend/src/server/api/common/read-notification.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import { In } from "typeorm";
-import { publishMainStream } from "@/services/stream.js";
-import { pushNotification } from "@/services/push-notification.js";
-import type { User } from "@/models/entities/user.js";
-import type { Notification } from "@/models/entities/notification.js";
-import { Notifications, Users } from "@/models/index.js";
-
-export async function readNotification(
-	userId: User["id"],
-	notificationIds: Notification["id"][],
-) {
-	if (notificationIds.length === 0) return;
-
-	// Update documents
-	const result = await Notifications.update(
-		{
-			notifieeId: userId,
-			id: In(notificationIds),
-			isRead: false,
-		},
-		{
-			isRead: true,
-		},
-	);
-
-	if (result.affected === 0) return;
-
-	if (!(await Users.getHasUnreadNotification(userId)))
-		return postReadAllNotifications(userId);
-	else return postReadNotifications(userId, notificationIds);
-}
-
-export async function readNotificationByQuery(
-	userId: User["id"],
-	query: Record<string, any>,
-) {
-	const notificationIds = await Notifications.findBy({
-		...query,
-		notifieeId: userId,
-		isRead: false,
-	}).then((notifications) =>
-		notifications.map((notification) => notification.id),
-	);
-
-	return readNotification(userId, notificationIds);
-}
-
-function postReadAllNotifications(userId: User["id"]) {
-	publishMainStream(userId, "readAllNotifications");
-	return pushNotification(userId, "readAllNotifications", undefined);
-}
-
-function postReadNotifications(
-	userId: User["id"],
-	notificationIds: Notification["id"][],
-) {
-	publishMainStream(userId, "readNotifications", notificationIds);
-	return pushNotification(userId, "readNotifications", { notificationIds });
-}
diff --git a/packages/backend/src/server/api/common/signin.ts b/packages/backend/src/server/api/common/signin.ts
deleted file mode 100644
index a8a435843f..0000000000
--- a/packages/backend/src/server/api/common/signin.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import type Koa from "koa";
-
-import config from "@/config/index.js";
-import type { ILocalUser } from "@/models/entities/user.js";
-import { Signins } from "@/models/index.js";
-import { genId } from "@/misc/gen-id.js";
-import { publishMainStream } from "@/services/stream.js";
-
-export default function (ctx: Koa.Context, user: ILocalUser, redirect = false) {
-	if (redirect) {
-		//#region Cookie
-		ctx.cookies.set("igi", user.token!, {
-			path: "/",
-			// SEE: https://github.com/koajs/koa/issues/974
-			// When using a SSL proxy it should be configured to add the "X-Forwarded-Proto: https" header
-			secure: config.url.startsWith("https"),
-			httpOnly: false,
-		});
-		//#endregion
-
-		ctx.redirect(config.url);
-	} else {
-		ctx.body = {
-			id: user.id,
-			i: user.token,
-		};
-		ctx.status = 200;
-	}
-
-	(async () => {
-		// Append signin history
-		const record = await Signins.insert({
-			id: genId(),
-			createdAt: new Date(),
-			userId: user.id,
-			ip: ctx.ip,
-			headers: ctx.headers,
-			success: true,
-		}).then((x) => Signins.findOneByOrFail(x.identifiers[0]));
-
-		// Publish signin event
-		publishMainStream(user.id, "signin", await Signins.pack(record));
-	})();
-}
diff --git a/packages/backend/src/server/api/common/signup.ts b/packages/backend/src/server/api/common/signup.ts
deleted file mode 100644
index 6beae2c782..0000000000
--- a/packages/backend/src/server/api/common/signup.ts
+++ /dev/null
@@ -1,141 +0,0 @@
-import { generateKeyPair } from "node:crypto";
-import generateUserToken from "./generate-native-user-token.js";
-import { User } from "@/models/entities/user.js";
-import { Users, UsedUsernames } from "@/models/index.js";
-import { UserProfile } from "@/models/entities/user-profile.js";
-import { IsNull } from "typeorm";
-import { genId } from "@/misc/gen-id.js";
-import { toPunyNullable } from "@/misc/convert-host.js";
-import { UserKeypair } from "@/models/entities/user-keypair.js";
-import { usersChart } from "@/services/chart/index.js";
-import { UsedUsername } from "@/models/entities/used-username.js";
-import { db } from "@/db/postgre.js";
-import config from "@/config/index.js";
-import { hashPassword } from "@/misc/password.js";
-
-export async function signup(opts: {
-	username: User["username"];
-	password?: string | null;
-	passwordHash?: UserProfile["password"] | null;
-	host?: string | null;
-}) {
-	const { username, password, passwordHash, host } = opts;
-	let hash = passwordHash;
-
-	const userCount = await Users.countBy({
-		host: IsNull(),
-	});
-
-	if (config.maxUserSignups != null && userCount > config.maxUserSignups) {
-		throw new Error("MAX_USERS_REACHED");
-	}
-
-	// Validate username
-	if (!Users.validateLocalUsername(username)) {
-		throw new Error("INVALID_USERNAME");
-	}
-
-	if (password != null && passwordHash == null) {
-		// Validate password
-		if (!Users.validatePassword(password)) {
-			throw new Error("INVALID_PASSWORD");
-		}
-
-		// Generate hash of password
-		hash = await hashPassword(password);
-	}
-
-	// Generate secret
-	const secret = generateUserToken();
-
-	// Check username duplication
-	if (
-		await Users.findOneBy({
-			usernameLower: username.toLowerCase(),
-			host: IsNull(),
-		})
-	) {
-		throw new Error("DUPLICATED_USERNAME");
-	}
-
-	// Check deleted username duplication
-	if (await UsedUsernames.findOneBy({ username: username.toLowerCase() })) {
-		throw new Error("USED_USERNAME");
-	}
-
-	const keyPair = await new Promise<string[]>((res, rej) =>
-		generateKeyPair(
-			"rsa",
-			{
-				modulusLength: 4096,
-				publicKeyEncoding: {
-					type: "spki",
-					format: "pem",
-				},
-				privateKeyEncoding: {
-					type: "pkcs8",
-					format: "pem",
-					cipher: undefined,
-					passphrase: undefined,
-				},
-			} as any,
-			(err, publicKey, privateKey) =>
-				err ? rej(err) : res([publicKey, privateKey]),
-		),
-	);
-
-	let account!: User;
-
-	// Start transaction
-	await db.transaction(async (transactionalEntityManager) => {
-		const exist = await transactionalEntityManager.findOneBy(User, {
-			usernameLower: username.toLowerCase(),
-			host: IsNull(),
-		});
-
-		if (exist) throw new Error(" the username is already used");
-
-		account = await transactionalEntityManager.save(
-			new User({
-				id: genId(),
-				createdAt: new Date(),
-				username: username,
-				usernameLower: username.toLowerCase(),
-				host: toPunyNullable(host),
-				token: secret,
-				isAdmin:
-					(await Users.countBy({
-						host: IsNull(),
-						isAdmin: true,
-					})) === 0,
-			}),
-		);
-
-		await transactionalEntityManager.save(
-			new UserKeypair({
-				publicKey: keyPair[0],
-				privateKey: keyPair[1],
-				userId: account.id,
-			}),
-		);
-
-		await transactionalEntityManager.save(
-			new UserProfile({
-				userId: account.id,
-				autoAcceptFollowed: true,
-				password: hash,
-			}),
-		);
-
-		await transactionalEntityManager.save(
-			new UsedUsername({
-				createdAt: new Date(),
-				username: username.toLowerCase(),
-			}),
-		);
-	});
-
-	usersChart.update(account, true);
-
-	return { account, secret };
-}
diff --git a/packages/backend/src/server/api/compatibility.ts b/packages/backend/src/server/api/compatibility.ts
deleted file mode 100644
index 7e44fa8b2e..0000000000
--- a/packages/backend/src/server/api/compatibility.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import type { IEndpoint } from "./endpoints";
-
-import * as cp___instanceInfo from "./endpoints/compatibility/instance-info.js";
-import * as cp___customEmojis from "./endpoints/compatibility/custom-emojis.js";
-
-const cps = [
-	["v1/instance", cp___instanceInfo],
-	["v1/custom_emojis", cp___customEmojis],
-];
-
-const compatibility: IEndpoint[] = cps.map(([name, cp]) => {
-	return {
-		name: name,
-		exec: cp.default,
-		meta: cp.meta || {},
-		params: cp.paramDef,
-	} as IEndpoint;
-});
-
-export default compatibility;
diff --git a/packages/backend/src/server/api/define.ts b/packages/backend/src/server/api/define.ts
deleted file mode 100644
index ee0844185f..0000000000
--- a/packages/backend/src/server/api/define.ts
+++ /dev/null
@@ -1,105 +0,0 @@
-import * as fs from "node:fs";
-import Ajv from "ajv";
-import type { CacheableLocalUser } from "@/models/entities/user.js";
-import { ILocalUser } from "@/models/entities/user.js";
-import type { Schema, SchemaType } from "@/misc/schema.js";
-import type { AccessToken } from "@/models/entities/access-token.js";
-import type { IEndpointMeta } from "./endpoints.js";
-import { ApiError } from "./error.js";
-
-export type Response = Record<string, any> | void;
-
-// TODO: paramsの型をT['params']のスキーマ定義から推論する
-type executor<T extends IEndpointMeta, Ps extends Schema> = (
-	params: SchemaType<Ps>,
-	user: T["requireCredential"] extends true
-		? CacheableLocalUser
-		: CacheableLocalUser | null,
-	token: AccessToken | null,
-	file?: any,
-	cleanup?: () => any,
-	ip?: string | null,
-	headers?: Record<string, string> | null,
-) => Promise<
-	T["res"] extends undefined ? Response : SchemaType<NonNullable<T["res"]>>
->;
-
-const ajv = new Ajv({
-	useDefaults: true,
-});
-
-ajv.addFormat("misskey:id", /^[a-zA-Z0-9]+$/);
-
-export default function <T extends IEndpointMeta, Ps extends Schema>(
-	meta: T,
-	paramDef: Ps,
-	cb: executor<T, Ps>,
-): (
-	params: any,
-	user: T["requireCredential"] extends true
-		? CacheableLocalUser
-		: CacheableLocalUser | null,
-	token: AccessToken | null,
-	file?: any,
-	ip?: string | null,
-	headers?: Record<string, string> | null,
-) => Promise<any> {
-	const validate = ajv.compile(paramDef);
-
-	return (
-		params: any,
-		user: T["requireCredential"] extends true
-			? CacheableLocalUser
-			: CacheableLocalUser | null,
-		token: AccessToken | null,
-		file?: any,
-		ip?: string | null,
-		headers?: Record<string, string> | null,
-	) => {
-		let cleanup: undefined | (() => void) = undefined;
-
-		if (meta.requireFile) {
-			cleanup = () => {
-				fs.unlink(file.path, () => {});
-			};
-
-			if (file == null)
-				return Promise.reject(
-					new ApiError({
-						message: "File required.",
-						code: "FILE_REQUIRED",
-						id: "4267801e-70d1-416a-b011-4ee502885d8b",
-					}),
-				);
-		}
-
-		const valid = validate(params);
-		if (!valid) {
-			if (file) cleanup!();
-
-			const errors = validate.errors!;
-			const err = new ApiError(
-				{
-					message: "Invalid param.",
-					code: "INVALID_PARAM",
-					id: "3d81ceae-475f-4600-b2a8-2bc116157532",
-				},
-				{
-					param: errors[0].schemaPath,
-					reason: errors[0].message,
-				},
-			);
-			return Promise.reject(err);
-		}
-
-		return cb(
-			params as SchemaType<Ps>,
-			user,
-			token,
-			file,
-			cleanup,
-			ip,
-			headers,
-		);
-	};
-}
diff --git a/packages/backend/src/server/api/endpoints.ts b/packages/backend/src/server/api/endpoints.ts
deleted file mode 100644
index 3f82eb7a73..0000000000
--- a/packages/backend/src/server/api/endpoints.ts
+++ /dev/null
@@ -1,805 +0,0 @@
-import type { Schema } from "@/misc/schema.js";
-
-import * as ep___admin_meta from "./endpoints/admin/meta.js";
-import * as ep___admin_abuseUserReports from "./endpoints/admin/abuse-user-reports.js";
-import * as ep___admin_accounts_create from "./endpoints/admin/accounts/create.js";
-import * as ep___admin_accounts_delete from "./endpoints/admin/accounts/delete.js";
-import * as ep___admin_accounts_hosted from "./endpoints/admin/accounts/hosted.js";
-import * as ep___admin_ad_create from "./endpoints/admin/ad/create.js";
-import * as ep___admin_ad_delete from "./endpoints/admin/ad/delete.js";
-import * as ep___admin_ad_list from "./endpoints/admin/ad/list.js";
-import * as ep___admin_ad_update from "./endpoints/admin/ad/update.js";
-import * as ep___admin_announcements_create from "./endpoints/admin/announcements/create.js";
-import * as ep___admin_announcements_delete from "./endpoints/admin/announcements/delete.js";
-import * as ep___admin_announcements_list from "./endpoints/admin/announcements/list.js";
-import * as ep___admin_announcements_update from "./endpoints/admin/announcements/update.js";
-import * as ep___admin_deleteAllFilesOfAUser from "./endpoints/admin/delete-all-files-of-a-user.js";
-import * as ep___admin_drive_cleanRemoteFiles from "./endpoints/admin/drive/clean-remote-files.js";
-import * as ep___admin_drive_cleanup from "./endpoints/admin/drive/cleanup.js";
-import * as ep___admin_drive_files from "./endpoints/admin/drive/files.js";
-import * as ep___admin_drive_showFile from "./endpoints/admin/drive/show-file.js";
-import * as ep___admin_emoji_addAliasesBulk from "./endpoints/admin/emoji/add-aliases-bulk.js";
-import * as ep___admin_emoji_add from "./endpoints/admin/emoji/add.js";
-import * as ep___admin_emoji_copy from "./endpoints/admin/emoji/copy.js";
-import * as ep___admin_emoji_deleteBulk from "./endpoints/admin/emoji/delete-bulk.js";
-import * as ep___admin_emoji_delete from "./endpoints/admin/emoji/delete.js";
-import * as ep___admin_emoji_importZip from "./endpoints/admin/emoji/import-zip.js";
-import * as ep___admin_emoji_listRemote from "./endpoints/admin/emoji/list-remote.js";
-import * as ep___admin_emoji_list from "./endpoints/admin/emoji/list.js";
-import * as ep___admin_emoji_removeAliasesBulk from "./endpoints/admin/emoji/remove-aliases-bulk.js";
-import * as ep___admin_emoji_setAliasesBulk from "./endpoints/admin/emoji/set-aliases-bulk.js";
-import * as ep___admin_emoji_setCategoryBulk from "./endpoints/admin/emoji/set-category-bulk.js";
-import * as ep___admin_emoji_setLicenseBulk from "./endpoints/admin/emoji/set-license-bulk.js";
-import * as ep___admin_emoji_update from "./endpoints/admin/emoji/update.js";
-import * as ep___admin_federation_deleteAllFiles from "./endpoints/admin/federation/delete-all-files.js";
-import * as ep___admin_federation_refreshRemoteInstanceMetadata from "./endpoints/admin/federation/refresh-remote-instance-metadata.js";
-import * as ep___admin_federation_removeAllFollowing from "./endpoints/admin/federation/remove-all-following.js";
-import * as ep___admin_federation_updateInstance from "./endpoints/admin/federation/update-instance.js";
-import * as ep___admin_getIndexStats from "./endpoints/admin/get-index-stats.js";
-import * as ep___admin_getTableStats from "./endpoints/admin/get-table-stats.js";
-import * as ep___admin_getUserIps from "./endpoints/admin/get-user-ips.js";
-import * as ep___admin_invite from "./endpoints/admin/invite.js";
-import * as ep___admin_moderators_add from "./endpoints/admin/moderators/add.js";
-import * as ep___admin_moderators_remove from "./endpoints/admin/moderators/remove.js";
-import * as ep___admin_promo_create from "./endpoints/admin/promo/create.js";
-import * as ep___admin_queue_clear from "./endpoints/admin/queue/clear.js";
-import * as ep___admin_queue_deliverDelayed from "./endpoints/admin/queue/deliver-delayed.js";
-import * as ep___admin_queue_inboxDelayed from "./endpoints/admin/queue/inbox-delayed.js";
-import * as ep___admin_queue_stats from "./endpoints/admin/queue/stats.js";
-import * as ep___admin_relays_add from "./endpoints/admin/relays/add.js";
-import * as ep___admin_relays_list from "./endpoints/admin/relays/list.js";
-import * as ep___admin_relays_remove from "./endpoints/admin/relays/remove.js";
-import * as ep___admin_resetPassword from "./endpoints/admin/reset-password.js";
-import * as ep___admin_resolveAbuseUserReport from "./endpoints/admin/resolve-abuse-user-report.js";
-import * as ep___admin_search_indexAll from "./endpoints/admin/search/index-all.js";
-import * as ep___admin_sendEmail from "./endpoints/admin/send-email.js";
-import * as ep___admin_serverInfo from "./endpoints/admin/server-info.js";
-import * as ep___admin_showModerationLogs from "./endpoints/admin/show-moderation-logs.js";
-import * as ep___admin_showUser from "./endpoints/admin/show-user.js";
-import * as ep___admin_showUsers from "./endpoints/admin/show-users.js";
-import * as ep___admin_silenceUser from "./endpoints/admin/silence-user.js";
-import * as ep___admin_suspendUser from "./endpoints/admin/suspend-user.js";
-import * as ep___admin_unsilenceUser from "./endpoints/admin/unsilence-user.js";
-import * as ep___admin_unsuspendUser from "./endpoints/admin/unsuspend-user.js";
-import * as ep___admin_updateMeta from "./endpoints/admin/update-meta.js";
-import * as ep___admin_vacuum from "./endpoints/admin/vacuum.js";
-import * as ep___admin_deleteAccount from "./endpoints/admin/delete-account.js";
-import * as ep___admin_updateUserNote from "./endpoints/admin/update-user-note.js";
-import * as ep___announcements from "./endpoints/announcements.js";
-import * as ep___antennas_create from "./endpoints/antennas/create.js";
-import * as ep___antennas_delete from "./endpoints/antennas/delete.js";
-import * as ep___antennas_list from "./endpoints/antennas/list.js";
-import * as ep___antennas_markRead from "./endpoints/antennas/markread.js";
-import * as ep___antennas_notes from "./endpoints/antennas/notes.js";
-import * as ep___antennas_show from "./endpoints/antennas/show.js";
-import * as ep___antennas_update from "./endpoints/antennas/update.js";
-import * as ep___ap_get from "./endpoints/ap/get.js";
-import * as ep___ap_show from "./endpoints/ap/show.js";
-import * as ep___app_create from "./endpoints/app/create.js";
-import * as ep___app_show from "./endpoints/app/show.js";
-import * as ep___auth_accept from "./endpoints/auth/accept.js";
-import * as ep___auth_session_generate from "./endpoints/auth/session/generate.js";
-import * as ep___auth_session_show from "./endpoints/auth/session/show.js";
-import * as ep___auth_session_userkey from "./endpoints/auth/session/userkey.js";
-import * as ep___blocking_create from "./endpoints/blocking/create.js";
-import * as ep___blocking_delete from "./endpoints/blocking/delete.js";
-import * as ep___blocking_list from "./endpoints/blocking/list.js";
-import * as ep___channels_create from "./endpoints/channels/create.js";
-import * as ep___channels_featured from "./endpoints/channels/featured.js";
-import * as ep___channels_follow from "./endpoints/channels/follow.js";
-import * as ep___channels_followed from "./endpoints/channels/followed.js";
-import * as ep___channels_owned from "./endpoints/channels/owned.js";
-import * as ep___channels_show from "./endpoints/channels/show.js";
-import * as ep___channels_timeline from "./endpoints/channels/timeline.js";
-import * as ep___channels_unfollow from "./endpoints/channels/unfollow.js";
-import * as ep___channels_update from "./endpoints/channels/update.js";
-import * as ep___charts_activeUsers from "./endpoints/charts/active-users.js";
-import * as ep___charts_apRequest from "./endpoints/charts/ap-request.js";
-import * as ep___charts_drive from "./endpoints/charts/drive.js";
-import * as ep___charts_federation from "./endpoints/charts/federation.js";
-import * as ep___charts_hashtag from "./endpoints/charts/hashtag.js";
-import * as ep___charts_instance from "./endpoints/charts/instance.js";
-import * as ep___charts_notes from "./endpoints/charts/notes.js";
-import * as ep___charts_user_drive from "./endpoints/charts/user/drive.js";
-import * as ep___charts_user_following from "./endpoints/charts/user/following.js";
-import * as ep___charts_user_notes from "./endpoints/charts/user/notes.js";
-import * as ep___charts_user_reactions from "./endpoints/charts/user/reactions.js";
-import * as ep___charts_users from "./endpoints/charts/users.js";
-import * as ep___clips_addNote from "./endpoints/clips/add-note.js";
-import * as ep___clips_removeNote from "./endpoints/clips/remove-note.js";
-import * as ep___clips_create from "./endpoints/clips/create.js";
-import * as ep___clips_delete from "./endpoints/clips/delete.js";
-import * as ep___clips_list from "./endpoints/clips/list.js";
-import * as ep___clips_notes from "./endpoints/clips/notes.js";
-import * as ep___clips_show from "./endpoints/clips/show.js";
-import * as ep___clips_update from "./endpoints/clips/update.js";
-import * as ep___drive from "./endpoints/drive.js";
-import * as ep___drive_files from "./endpoints/drive/files.js";
-import * as ep___drive_files_attachedNotes from "./endpoints/drive/files/attached-notes.js";
-import * as ep___drive_files_checkExistence from "./endpoints/drive/files/check-existence.js";
-import * as ep___drive_files_captionImage from "./endpoints/drive/files/caption-image.js";
-import * as ep___drive_files_create from "./endpoints/drive/files/create.js";
-import * as ep___drive_files_delete from "./endpoints/drive/files/delete.js";
-import * as ep___drive_files_findByHash from "./endpoints/drive/files/find-by-hash.js";
-import * as ep___drive_files_find from "./endpoints/drive/files/find.js";
-import * as ep___drive_files_show from "./endpoints/drive/files/show.js";
-import * as ep___drive_files_update from "./endpoints/drive/files/update.js";
-import * as ep___drive_files_uploadFromUrl from "./endpoints/drive/files/upload-from-url.js";
-import * as ep___drive_folders from "./endpoints/drive/folders.js";
-import * as ep___drive_folders_create from "./endpoints/drive/folders/create.js";
-import * as ep___drive_folders_delete from "./endpoints/drive/folders/delete.js";
-import * as ep___drive_folders_find from "./endpoints/drive/folders/find.js";
-import * as ep___drive_folders_show from "./endpoints/drive/folders/show.js";
-import * as ep___drive_folders_update from "./endpoints/drive/folders/update.js";
-import * as ep___drive_stream from "./endpoints/drive/stream.js";
-import * as ep___emailAddress_available from "./endpoints/email-address/available.js";
-import * as ep___emoji from "./endpoints/emoji.js";
-import * as ep___endpoint from "./endpoints/endpoint.js";
-import * as ep___endpoints from "./endpoints/endpoints.js";
-import * as ep___exportCustomEmojis from "./endpoints/export-custom-emojis.js";
-import * as ep___federation_followers from "./endpoints/federation/followers.js";
-import * as ep___federation_following from "./endpoints/federation/following.js";
-import * as ep___federation_instances from "./endpoints/federation/instances.js";
-import * as ep___federation_showInstance from "./endpoints/federation/show-instance.js";
-import * as ep___federation_updateRemoteUser from "./endpoints/federation/update-remote-user.js";
-import * as ep___federation_users from "./endpoints/federation/users.js";
-import * as ep___federation_stats from "./endpoints/federation/stats.js";
-import * as ep___following_create from "./endpoints/following/create.js";
-import * as ep___following_delete from "./endpoints/following/delete.js";
-import * as ep___following_invalidate from "./endpoints/following/invalidate.js";
-import * as ep___following_requests_accept from "./endpoints/following/requests/accept.js";
-import * as ep___following_requests_cancel from "./endpoints/following/requests/cancel.js";
-import * as ep___following_requests_list from "./endpoints/following/requests/list.js";
-import * as ep___following_requests_reject from "./endpoints/following/requests/reject.js";
-import * as ep___gallery_featured from "./endpoints/gallery/featured.js";
-import * as ep___gallery_popular from "./endpoints/gallery/popular.js";
-import * as ep___gallery_posts from "./endpoints/gallery/posts.js";
-import * as ep___gallery_posts_create from "./endpoints/gallery/posts/create.js";
-import * as ep___gallery_posts_delete from "./endpoints/gallery/posts/delete.js";
-import * as ep___gallery_posts_like from "./endpoints/gallery/posts/like.js";
-import * as ep___gallery_posts_show from "./endpoints/gallery/posts/show.js";
-import * as ep___gallery_posts_unlike from "./endpoints/gallery/posts/unlike.js";
-import * as ep___gallery_posts_update from "./endpoints/gallery/posts/update.js";
-import * as ep___getOnlineUsersCount from "./endpoints/get-online-users-count.js";
-import * as ep___hashtags_list from "./endpoints/hashtags/list.js";
-import * as ep___hashtags_search from "./endpoints/hashtags/search.js";
-import * as ep___hashtags_show from "./endpoints/hashtags/show.js";
-import * as ep___hashtags_trend from "./endpoints/hashtags/trend.js";
-import * as ep___hashtags_users from "./endpoints/hashtags/users.js";
-import * as ep___i from "./endpoints/i.js";
-import * as ep___i_2fa_done from "./endpoints/i/2fa/done.js";
-import * as ep___i_2fa_keyDone from "./endpoints/i/2fa/key-done.js";
-import * as ep___i_2fa_passwordLess from "./endpoints/i/2fa/password-less.js";
-import * as ep___i_2fa_registerKey from "./endpoints/i/2fa/register-key.js";
-import * as ep___i_2fa_register from "./endpoints/i/2fa/register.js";
-import * as ep___i_2fa_removeKey from "./endpoints/i/2fa/remove-key.js";
-import * as ep___i_2fa_unregister from "./endpoints/i/2fa/unregister.js";
-import * as ep___i_apps from "./endpoints/i/apps.js";
-import * as ep___i_authorizedApps from "./endpoints/i/authorized-apps.js";
-import * as ep___i_changePassword from "./endpoints/i/change-password.js";
-import * as ep___i_deleteAccount from "./endpoints/i/delete-account.js";
-import * as ep___i_exportBlocking from "./endpoints/i/export-blocking.js";
-import * as ep___i_exportFollowing from "./endpoints/i/export-following.js";
-import * as ep___i_exportMute from "./endpoints/i/export-mute.js";
-import * as ep___i_exportNotes from "./endpoints/i/export-notes.js";
-import * as ep___i_importPosts from "./endpoints/i/import-posts.js";
-import * as ep___i_exportUserLists from "./endpoints/i/export-user-lists.js";
-import * as ep___i_favorites from "./endpoints/i/favorites.js";
-import * as ep___i_gallery_likes from "./endpoints/i/gallery/likes.js";
-import * as ep___i_gallery_posts from "./endpoints/i/gallery/posts.js";
-import * as ep___i_getWordMutedNotesCount from "./endpoints/i/get-word-muted-notes-count.js";
-import * as ep___i_importBlocking from "./endpoints/i/import-blocking.js";
-import * as ep___i_importFollowing from "./endpoints/i/import-following.js";
-import * as ep___i_importMuting from "./endpoints/i/import-muting.js";
-import * as ep___i_importUserLists from "./endpoints/i/import-user-lists.js";
-import * as ep___i_notifications from "./endpoints/i/notifications.js";
-import * as ep___i_pageLikes from "./endpoints/i/page-likes.js";
-import * as ep___i_pages from "./endpoints/i/pages.js";
-import * as ep___i_pin from "./endpoints/i/pin.js";
-import * as ep___i_readAllMessagingMessages from "./endpoints/i/read-all-messaging-messages.js";
-import * as ep___i_readAllUnreadNotes from "./endpoints/i/read-all-unread-notes.js";
-import * as ep___i_readAnnouncement from "./endpoints/i/read-announcement.js";
-import * as ep___i_regenerateToken from "./endpoints/i/regenerate-token.js";
-import * as ep___i_registry_getAll from "./endpoints/i/registry/get-all.js";
-import * as ep___i_registry_getDetail from "./endpoints/i/registry/get-detail.js";
-import * as ep___i_registry_getUnsecure from "./endpoints/i/registry/get-unsecure.js";
-import * as ep___i_registry_get from "./endpoints/i/registry/get.js";
-import * as ep___i_registry_keysWithType from "./endpoints/i/registry/keys-with-type.js";
-import * as ep___i_registry_keys from "./endpoints/i/registry/keys.js";
-import * as ep___i_registry_remove from "./endpoints/i/registry/remove.js";
-import * as ep___i_registry_scopes from "./endpoints/i/registry/scopes.js";
-import * as ep___i_registry_set from "./endpoints/i/registry/set.js";
-import * as ep___i_revokeToken from "./endpoints/i/revoke-token.js";
-import * as ep___i_signinHistory from "./endpoints/i/signin-history.js";
-import * as ep___i_unpin from "./endpoints/i/unpin.js";
-import * as ep___i_updateEmail from "./endpoints/i/update-email.js";
-import * as ep___i_update from "./endpoints/i/update.js";
-import * as ep___i_userGroupInvites from "./endpoints/i/user-group-invites.js";
-import * as ep___i_webhooks_create from "./endpoints/i/webhooks/create.js";
-import * as ep___i_webhooks_show from "./endpoints/i/webhooks/show.js";
-import * as ep___i_webhooks_list from "./endpoints/i/webhooks/list.js";
-import * as ep___i_webhooks_update from "./endpoints/i/webhooks/update.js";
-import * as ep___i_webhooks_delete from "./endpoints/i/webhooks/delete.js";
-import * as ep___messaging_history from "./endpoints/messaging/history.js";
-import * as ep___messaging_messages from "./endpoints/messaging/messages.js";
-import * as ep___messaging_messages_create from "./endpoints/messaging/messages/create.js";
-import * as ep___messaging_messages_delete from "./endpoints/messaging/messages/delete.js";
-import * as ep___messaging_messages_read from "./endpoints/messaging/messages/read.js";
-import * as ep___meta from "./endpoints/meta.js";
-import * as ep___sounds from "./endpoints/get-sounds.js";
-import * as ep___miauth_genToken from "./endpoints/miauth/gen-token.js";
-import * as ep___mute_create from "./endpoints/mute/create.js";
-import * as ep___mute_delete from "./endpoints/mute/delete.js";
-import * as ep___mute_list from "./endpoints/mute/list.js";
-import * as ep___renote_mute_create from "./endpoints/renote-mute/create.js";
-import * as ep___renote_mute_delete from "./endpoints/renote-mute/delete.js";
-import * as ep___renote_mute_list from "./endpoints/renote-mute/list.js";
-import * as ep___my_apps from "./endpoints/my/apps.js";
-import * as ep___notes from "./endpoints/notes.js";
-import * as ep___notes_children from "./endpoints/notes/children.js";
-import * as ep___notes_clips from "./endpoints/notes/clips.js";
-import * as ep___notes_conversation from "./endpoints/notes/conversation.js";
-import * as ep___notes_create from "./endpoints/notes/create.js";
-import * as ep___notes_delete from "./endpoints/notes/delete.js";
-import * as ep___notes_favorites_create from "./endpoints/notes/favorites/create.js";
-import * as ep___notes_favorites_delete from "./endpoints/notes/favorites/delete.js";
-import * as ep___notes_featured from "./endpoints/notes/featured.js";
-import * as ep___notes_globalTimeline from "./endpoints/notes/global-timeline.js";
-import * as ep___notes_hybridTimeline from "./endpoints/notes/hybrid-timeline.js";
-import * as ep___notes_localTimeline from "./endpoints/notes/local-timeline.js";
-import * as ep___notes_recommendedTimeline from "./endpoints/notes/recommended-timeline.js";
-import * as ep___notes_mentions from "./endpoints/notes/mentions.js";
-import * as ep___notes_polls_recommendation from "./endpoints/notes/polls/recommendation.js";
-import * as ep___notes_polls_vote from "./endpoints/notes/polls/vote.js";
-import * as ep___notes_reactions from "./endpoints/notes/reactions.js";
-import * as ep___notes_reactions_create from "./endpoints/notes/reactions/create.js";
-import * as ep___notes_reactions_delete from "./endpoints/notes/reactions/delete.js";
-import * as ep___notes_renotes from "./endpoints/notes/renotes.js";
-import * as ep___notes_replies from "./endpoints/notes/replies.js";
-import * as ep___notes_searchByTag from "./endpoints/notes/search-by-tag.js";
-import * as ep___notes_search from "./endpoints/notes/search.js";
-import * as ep___notes_show from "./endpoints/notes/show.js";
-import * as ep___notes_state from "./endpoints/notes/state.js";
-import * as ep___notes_threadMuting_create from "./endpoints/notes/thread-muting/create.js";
-import * as ep___notes_threadMuting_delete from "./endpoints/notes/thread-muting/delete.js";
-import * as ep___notes_timeline from "./endpoints/notes/timeline.js";
-import * as ep___notes_translate from "./endpoints/notes/translate.js";
-import * as ep___notes_unrenote from "./endpoints/notes/unrenote.js";
-import * as ep___notes_userListTimeline from "./endpoints/notes/user-list-timeline.js";
-import * as ep___notes_watching_create from "./endpoints/notes/watching/create.js";
-import * as ep___notes_watching_delete from "./endpoints/notes/watching/delete.js";
-import * as ep___notifications_create from "./endpoints/notifications/create.js";
-import * as ep___notifications_markAllAsRead from "./endpoints/notifications/mark-all-as-read.js";
-import * as ep___notifications_read from "./endpoints/notifications/read.js";
-import * as ep___pagePush from "./endpoints/page-push.js";
-import * as ep___pages_create from "./endpoints/pages/create.js";
-import * as ep___pages_delete from "./endpoints/pages/delete.js";
-import * as ep___pages_featured from "./endpoints/pages/featured.js";
-import * as ep___pages_like from "./endpoints/pages/like.js";
-import * as ep___pages_show from "./endpoints/pages/show.js";
-import * as ep___pages_unlike from "./endpoints/pages/unlike.js";
-import * as ep___pages_update from "./endpoints/pages/update.js";
-import * as ep___ping from "./endpoints/ping.js";
-import * as ep___recommendedInstances from "./endpoints/recommended-instances.js";
-import * as ep___pinnedUsers from "./endpoints/pinned-users.js";
-import * as ep___customMOTD from "./endpoints/custom-motd.js";
-import * as ep___customSplashIcons from "./endpoints/custom-splash-icons.js";
-import * as ep___latestVersion from "./endpoints/latest-version.js";
-import * as ep___patrons from "./endpoints/patrons.js";
-import * as ep___release from "./endpoints/release.js";
-import * as ep___promo_read from "./endpoints/promo/read.js";
-import * as ep___requestResetPassword from "./endpoints/request-reset-password.js";
-import * as ep___resetDb from "./endpoints/reset-db.js";
-import * as ep___resetPassword from "./endpoints/reset-password.js";
-import * as ep___serverInfo from "./endpoints/server-info.js";
-import * as ep___stats from "./endpoints/stats.js";
-import * as ep___sw_show_registration from "./endpoints/sw/show-registration.js";
-import * as ep___sw_update_registration from "./endpoints/sw/update-registration.js";
-import * as ep___sw_register from "./endpoints/sw/register.js";
-import * as ep___sw_unregister from "./endpoints/sw/unregister.js";
-import * as ep___test from "./endpoints/test.js";
-import * as ep___username_available from "./endpoints/username/available.js";
-import * as ep___users from "./endpoints/users.js";
-import * as ep___users_clips from "./endpoints/users/clips.js";
-import * as ep___users_followers from "./endpoints/users/followers.js";
-import * as ep___users_following from "./endpoints/users/following.js";
-import * as ep___users_gallery_posts from "./endpoints/users/gallery/posts.js";
-import * as ep___users_getFrequentlyRepliedUsers from "./endpoints/users/get-frequently-replied-users.js";
-import * as ep___users_groups_create from "./endpoints/users/groups/create.js";
-import * as ep___users_groups_delete from "./endpoints/users/groups/delete.js";
-import * as ep___users_groups_invitations_accept from "./endpoints/users/groups/invitations/accept.js";
-import * as ep___users_groups_invitations_reject from "./endpoints/users/groups/invitations/reject.js";
-import * as ep___users_groups_invite from "./endpoints/users/groups/invite.js";
-import * as ep___users_groups_joined from "./endpoints/users/groups/joined.js";
-import * as ep___users_groups_leave from "./endpoints/users/groups/leave.js";
-import * as ep___users_groups_owned from "./endpoints/users/groups/owned.js";
-import * as ep___users_groups_pull from "./endpoints/users/groups/pull.js";
-import * as ep___users_groups_show from "./endpoints/users/groups/show.js";
-import * as ep___users_groups_transfer from "./endpoints/users/groups/transfer.js";
-import * as ep___users_groups_update from "./endpoints/users/groups/update.js";
-import * as ep___users_lists_create from "./endpoints/users/lists/create.js";
-import * as ep___users_lists_delete from "./endpoints/users/lists/delete.js";
-import * as ep___users_lists_delete_all from "./endpoints/users/lists/delete-all.js";
-import * as ep___users_lists_list from "./endpoints/users/lists/list.js";
-import * as ep___users_lists_pull from "./endpoints/users/lists/pull.js";
-import * as ep___users_lists_push from "./endpoints/users/lists/push.js";
-import * as ep___users_lists_show from "./endpoints/users/lists/show.js";
-import * as ep___users_lists_update from "./endpoints/users/lists/update.js";
-import * as ep___users_notes from "./endpoints/users/notes.js";
-import * as ep___users_pages from "./endpoints/users/pages.js";
-import * as ep___users_reactions from "./endpoints/users/reactions.js";
-import * as ep___users_recommendation from "./endpoints/users/recommendation.js";
-import * as ep___users_relation from "./endpoints/users/relation.js";
-import * as ep___users_reportAbuse from "./endpoints/users/report-abuse.js";
-import * as ep___users_searchByUsernameAndHost from "./endpoints/users/search-by-username-and-host.js";
-import * as ep___users_search from "./endpoints/users/search.js";
-import * as ep___users_show from "./endpoints/users/show.js";
-import * as ep___users_stats from "./endpoints/users/stats.js";
-import * as ep___fetchRss from "./endpoints/fetch-rss.js";
-import * as ep___admin_driveCapOverride from "./endpoints/admin/drive-capacity-override.js";
-
-//Calckey Move
-import * as ep___i_move from "./endpoints/i/move.js";
-import * as ep___i_known_as from "./endpoints/i/known-as.js";
-
-const eps = [
-	["admin/meta", ep___admin_meta],
-	["admin/abuse-user-reports", ep___admin_abuseUserReports],
-	["admin/accounts/create", ep___admin_accounts_create],
-	["admin/accounts/delete", ep___admin_accounts_delete],
-	["admin/accounts/hosted", ep___admin_accounts_hosted],
-	["admin/ad/create", ep___admin_ad_create],
-	["admin/ad/delete", ep___admin_ad_delete],
-	["admin/ad/list", ep___admin_ad_list],
-	["admin/ad/update", ep___admin_ad_update],
-	["admin/announcements/create", ep___admin_announcements_create],
-	["admin/announcements/delete", ep___admin_announcements_delete],
-	["admin/announcements/list", ep___admin_announcements_list],
-	["admin/announcements/update", ep___admin_announcements_update],
-	["admin/delete-all-files-of-a-user", ep___admin_deleteAllFilesOfAUser],
-	["admin/drive/clean-remote-files", ep___admin_drive_cleanRemoteFiles],
-	["admin/drive/cleanup", ep___admin_drive_cleanup],
-	["admin/drive/files", ep___admin_drive_files],
-	["admin/drive/show-file", ep___admin_drive_showFile],
-	["admin/emoji/add-aliases-bulk", ep___admin_emoji_addAliasesBulk],
-	["admin/emoji/add", ep___admin_emoji_add],
-	["admin/emoji/copy", ep___admin_emoji_copy],
-	["admin/emoji/delete-bulk", ep___admin_emoji_deleteBulk],
-	["admin/emoji/delete", ep___admin_emoji_delete],
-	["admin/emoji/import-zip", ep___admin_emoji_importZip],
-	["admin/emoji/list-remote", ep___admin_emoji_listRemote],
-	["admin/emoji/list", ep___admin_emoji_list],
-	["admin/emoji/remove-aliases-bulk", ep___admin_emoji_removeAliasesBulk],
-	["admin/emoji/set-aliases-bulk", ep___admin_emoji_setAliasesBulk],
-	["admin/emoji/set-category-bulk", ep___admin_emoji_setCategoryBulk],
-	["admin/emoji/set-license-bulk", ep___admin_emoji_setLicenseBulk],
-	["admin/emoji/update", ep___admin_emoji_update],
-	["admin/federation/delete-all-files", ep___admin_federation_deleteAllFiles],
-	[
-		"admin/federation/refresh-remote-instance-metadata",
-		ep___admin_federation_refreshRemoteInstanceMetadata,
-	],
-	[
-		"admin/federation/remove-all-following",
-		ep___admin_federation_removeAllFollowing,
-	],
-	["admin/federation/update-instance", ep___admin_federation_updateInstance],
-	["admin/get-index-stats", ep___admin_getIndexStats],
-	["admin/get-table-stats", ep___admin_getTableStats],
-	["admin/get-user-ips", ep___admin_getUserIps],
-	["admin/invite", ep___admin_invite],
-	["admin/moderators/add", ep___admin_moderators_add],
-	["admin/moderators/remove", ep___admin_moderators_remove],
-	["admin/promo/create", ep___admin_promo_create],
-	["admin/queue/clear", ep___admin_queue_clear],
-	["admin/queue/deliver-delayed", ep___admin_queue_deliverDelayed],
-	["admin/queue/inbox-delayed", ep___admin_queue_inboxDelayed],
-	["admin/queue/stats", ep___admin_queue_stats],
-	["admin/relays/add", ep___admin_relays_add],
-	["admin/relays/list", ep___admin_relays_list],
-	["admin/relays/remove", ep___admin_relays_remove],
-	["admin/reset-password", ep___admin_resetPassword],
-	["admin/resolve-abuse-user-report", ep___admin_resolveAbuseUserReport],
-	["admin/search/index-all", ep___admin_search_indexAll],
-	["admin/send-email", ep___admin_sendEmail],
-	["admin/server-info", ep___admin_serverInfo],
-	["admin/show-moderation-logs", ep___admin_showModerationLogs],
-	["admin/show-user", ep___admin_showUser],
-	["admin/show-users", ep___admin_showUsers],
-	["admin/silence-user", ep___admin_silenceUser],
-	["admin/suspend-user", ep___admin_suspendUser],
-	["admin/unsilence-user", ep___admin_unsilenceUser],
-	["admin/unsuspend-user", ep___admin_unsuspendUser],
-	["admin/update-meta", ep___admin_updateMeta],
-	["admin/vacuum", ep___admin_vacuum],
-	["admin/delete-account", ep___admin_deleteAccount],
-	["admin/update-user-note", ep___admin_updateUserNote],
-	["announcements", ep___announcements],
-	["antennas/create", ep___antennas_create],
-	["antennas/delete", ep___antennas_delete],
-	["antennas/list", ep___antennas_list],
-	["antennas/mark-read", ep___antennas_markRead],
-	["antennas/notes", ep___antennas_notes],
-	["antennas/show", ep___antennas_show],
-	["antennas/update", ep___antennas_update],
-	["ap/get", ep___ap_get],
-	["ap/show", ep___ap_show],
-	["app/create", ep___app_create],
-	["app/show", ep___app_show],
-	["auth/accept", ep___auth_accept],
-	["auth/session/generate", ep___auth_session_generate],
-	["auth/session/show", ep___auth_session_show],
-	["auth/session/userkey", ep___auth_session_userkey],
-	["blocking/create", ep___blocking_create],
-	["blocking/delete", ep___blocking_delete],
-	["blocking/list", ep___blocking_list],
-	["channels/create", ep___channels_create],
-	["channels/featured", ep___channels_featured],
-	["channels/follow", ep___channels_follow],
-	["channels/followed", ep___channels_followed],
-	["channels/owned", ep___channels_owned],
-	["channels/show", ep___channels_show],
-	["channels/timeline", ep___channels_timeline],
-	["channels/unfollow", ep___channels_unfollow],
-	["channels/update", ep___channels_update],
-	["charts/active-users", ep___charts_activeUsers],
-	["charts/ap-request", ep___charts_apRequest],
-	["charts/drive", ep___charts_drive],
-	["charts/federation", ep___charts_federation],
-	["charts/hashtag", ep___charts_hashtag],
-	["charts/instance", ep___charts_instance],
-	["charts/notes", ep___charts_notes],
-	["charts/user/drive", ep___charts_user_drive],
-	["charts/user/following", ep___charts_user_following],
-	["charts/user/notes", ep___charts_user_notes],
-	["charts/user/reactions", ep___charts_user_reactions],
-	["charts/users", ep___charts_users],
-	["clips/add-note", ep___clips_addNote],
-	["clips/remove-note", ep___clips_removeNote],
-	["clips/create", ep___clips_create],
-	["clips/delete", ep___clips_delete],
-	["clips/list", ep___clips_list],
-	["clips/notes", ep___clips_notes],
-	["clips/show", ep___clips_show],
-	["clips/update", ep___clips_update],
-	["drive", ep___drive],
-	["drive/files", ep___drive_files],
-	["drive/files/attached-notes", ep___drive_files_attachedNotes],
-	["drive/files/caption-image", ep___drive_files_captionImage],
-	["drive/files/check-existence", ep___drive_files_checkExistence],
-	["drive/files/create", ep___drive_files_create],
-	["drive/files/delete", ep___drive_files_delete],
-	["drive/files/find-by-hash", ep___drive_files_findByHash],
-	["drive/files/find", ep___drive_files_find],
-	["drive/files/show", ep___drive_files_show],
-	["drive/files/update", ep___drive_files_update],
-	["drive/files/upload-from-url", ep___drive_files_uploadFromUrl],
-	["drive/folders", ep___drive_folders],
-	["drive/folders/create", ep___drive_folders_create],
-	["drive/folders/delete", ep___drive_folders_delete],
-	["drive/folders/find", ep___drive_folders_find],
-	["drive/folders/show", ep___drive_folders_show],
-	["drive/folders/update", ep___drive_folders_update],
-	["drive/stream", ep___drive_stream],
-	["email-address/available", ep___emailAddress_available],
-	["emoji", ep___emoji],
-	["endpoint", ep___endpoint],
-	["endpoints", ep___endpoints],
-	["export-custom-emojis", ep___exportCustomEmojis],
-	["federation/followers", ep___federation_followers],
-	["federation/following", ep___federation_following],
-	["federation/instances", ep___federation_instances],
-	["federation/show-instance", ep___federation_showInstance],
-	["federation/update-remote-user", ep___federation_updateRemoteUser],
-	["federation/users", ep___federation_users],
-	["federation/stats", ep___federation_stats],
-	["following/create", ep___following_create],
-	["following/delete", ep___following_delete],
-	["following/invalidate", ep___following_invalidate],
-	["following/requests/accept", ep___following_requests_accept],
-	["following/requests/cancel", ep___following_requests_cancel],
-	["following/requests/list", ep___following_requests_list],
-	["following/requests/reject", ep___following_requests_reject],
-	["gallery/featured", ep___gallery_featured],
-	["gallery/popular", ep___gallery_popular],
-	["gallery/posts", ep___gallery_posts],
-	["gallery/posts/create", ep___gallery_posts_create],
-	["gallery/posts/delete", ep___gallery_posts_delete],
-	["gallery/posts/like", ep___gallery_posts_like],
-	["gallery/posts/show", ep___gallery_posts_show],
-	["gallery/posts/unlike", ep___gallery_posts_unlike],
-	["gallery/posts/update", ep___gallery_posts_update],
-	["get-online-users-count", ep___getOnlineUsersCount],
-	["hashtags/list", ep___hashtags_list],
-	["hashtags/search", ep___hashtags_search],
-	["hashtags/show", ep___hashtags_show],
-	["hashtags/trend", ep___hashtags_trend],
-	["hashtags/users", ep___hashtags_users],
-	["i", ep___i],
-	["i/known-as", ep___i_known_as],
-	["i/move", ep___i_move],
-	["i/2fa/done", ep___i_2fa_done],
-	["i/2fa/key-done", ep___i_2fa_keyDone],
-	["i/2fa/password-less", ep___i_2fa_passwordLess],
-	["i/2fa/register-key", ep___i_2fa_registerKey],
-	["i/2fa/register", ep___i_2fa_register],
-	["i/2fa/remove-key", ep___i_2fa_removeKey],
-	["i/2fa/unregister", ep___i_2fa_unregister],
-	["i/apps", ep___i_apps],
-	["i/authorized-apps", ep___i_authorizedApps],
-	["i/change-password", ep___i_changePassword],
-	["i/delete-account", ep___i_deleteAccount],
-	["i/export-blocking", ep___i_exportBlocking],
-	["i/export-following", ep___i_exportFollowing],
-	["i/export-mute", ep___i_exportMute],
-	["i/export-notes", ep___i_exportNotes],
-	["i/import-posts", ep___i_importPosts],
-	["i/export-user-lists", ep___i_exportUserLists],
-	["i/favorites", ep___i_favorites],
-	["i/gallery/likes", ep___i_gallery_likes],
-	["i/gallery/posts", ep___i_gallery_posts],
-	["i/get-word-muted-notes-count", ep___i_getWordMutedNotesCount],
-	["i/import-blocking", ep___i_importBlocking],
-	["i/import-following", ep___i_importFollowing],
-	["i/import-muting", ep___i_importMuting],
-	["i/import-user-lists", ep___i_importUserLists],
-	["i/notifications", ep___i_notifications],
-	["i/page-likes", ep___i_pageLikes],
-	["i/pages", ep___i_pages],
-	["i/pin", ep___i_pin],
-	["i/read-all-messaging-messages", ep___i_readAllMessagingMessages],
-	["i/read-all-unread-notes", ep___i_readAllUnreadNotes],
-	["i/read-announcement", ep___i_readAnnouncement],
-	["i/regenerate-token", ep___i_regenerateToken],
-	["i/registry/get-all", ep___i_registry_getAll],
-	["i/registry/get-detail", ep___i_registry_getDetail],
-	["i/registry/get-unsecure", ep___i_registry_getUnsecure],
-	["i/registry/get", ep___i_registry_get],
-	["i/registry/keys-with-type", ep___i_registry_keysWithType],
-	["i/registry/keys", ep___i_registry_keys],
-	["i/registry/remove", ep___i_registry_remove],
-	["i/registry/scopes", ep___i_registry_scopes],
-	["i/registry/set", ep___i_registry_set],
-	["i/revoke-token", ep___i_revokeToken],
-	["i/signin-history", ep___i_signinHistory],
-	["i/unpin", ep___i_unpin],
-	["i/update-email", ep___i_updateEmail],
-	["i/update", ep___i_update],
-	["i/user-group-invites", ep___i_userGroupInvites],
-	["i/webhooks/create", ep___i_webhooks_create],
-	["i/webhooks/list", ep___i_webhooks_list],
-	["i/webhooks/show", ep___i_webhooks_show],
-	["i/webhooks/update", ep___i_webhooks_update],
-	["i/webhooks/delete", ep___i_webhooks_delete],
-	["messaging/history", ep___messaging_history],
-	["messaging/messages", ep___messaging_messages],
-	["messaging/messages/create", ep___messaging_messages_create],
-	["messaging/messages/delete", ep___messaging_messages_delete],
-	["messaging/messages/read", ep___messaging_messages_read],
-	["meta", ep___meta],
-	["miauth/gen-token", ep___miauth_genToken],
-	["mute/create", ep___mute_create],
-	["mute/delete", ep___mute_delete],
-	["mute/list", ep___mute_list],
-	["my/apps", ep___my_apps],
-	["notes", ep___notes],
-	["notes/children", ep___notes_children],
-	["notes/clips", ep___notes_clips],
-	["notes/conversation", ep___notes_conversation],
-	["notes/create", ep___notes_create],
-	["notes/delete", ep___notes_delete],
-	["notes/favorites/create", ep___notes_favorites_create],
-	["notes/favorites/delete", ep___notes_favorites_delete],
-	["notes/featured", ep___notes_featured],
-	["notes/global-timeline", ep___notes_globalTimeline],
-	["notes/hybrid-timeline", ep___notes_hybridTimeline],
-	["notes/local-timeline", ep___notes_localTimeline],
-	["notes/recommended-timeline", ep___notes_recommendedTimeline],
-	["notes/mentions", ep___notes_mentions],
-	["notes/polls/recommendation", ep___notes_polls_recommendation],
-	["notes/polls/vote", ep___notes_polls_vote],
-	["notes/reactions", ep___notes_reactions],
-	["notes/reactions/create", ep___notes_reactions_create],
-	["notes/reactions/delete", ep___notes_reactions_delete],
-	["notes/renotes", ep___notes_renotes],
-	["notes/replies", ep___notes_replies],
-	["notes/search-by-tag", ep___notes_searchByTag],
-	["notes/search", ep___notes_search],
-	["notes/show", ep___notes_show],
-	["notes/state", ep___notes_state],
-	["notes/thread-muting/create", ep___notes_threadMuting_create],
-	["notes/thread-muting/delete", ep___notes_threadMuting_delete],
-	["notes/timeline", ep___notes_timeline],
-	["notes/translate", ep___notes_translate],
-	["notes/unrenote", ep___notes_unrenote],
-	["notes/user-list-timeline", ep___notes_userListTimeline],
-	["notes/watching/create", ep___notes_watching_create],
-	["notes/watching/delete", ep___notes_watching_delete],
-	["notifications/create", ep___notifications_create],
-	["notifications/mark-all-as-read", ep___notifications_markAllAsRead],
-	["notifications/read", ep___notifications_read],
-	["page-push", ep___pagePush],
-	["pages/create", ep___pages_create],
-	["pages/delete", ep___pages_delete],
-	["pages/featured", ep___pages_featured],
-	["pages/like", ep___pages_like],
-	["pages/show", ep___pages_show],
-	["pages/unlike", ep___pages_unlike],
-	["pages/update", ep___pages_update],
-	["ping", ep___ping],
-	["pinned-users", ep___pinnedUsers],
-	["recommended-instances", ep___recommendedInstances],
-	["renote-mute/create", ep___renote_mute_create],
-	["renote-mute/delete", ep___renote_mute_delete],
-	["renote-mute/list", ep___renote_mute_list],
-	["custom-motd", ep___customMOTD],
-	["custom-splash-icons", ep___customSplashIcons],
-	["latest-version", ep___latestVersion],
-	["patrons", ep___patrons],
-	["release", ep___release],
-	["promo/read", ep___promo_read],
-	["request-reset-password", ep___requestResetPassword],
-	["reset-db", ep___resetDb],
-	["reset-password", ep___resetPassword],
-	["server-info", ep___serverInfo],
-	["stats", ep___stats],
-	["sw/register", ep___sw_register],
-	["sw/unregister", ep___sw_unregister],
-	["sw/show-registration", ep___sw_show_registration],
-	["sw/update-registration", ep___sw_update_registration],
-	["test", ep___test],
-	["username/available", ep___username_available],
-	["users", ep___users],
-	["users/clips", ep___users_clips],
-	["users/followers", ep___users_followers],
-	["users/following", ep___users_following],
-	["users/gallery/posts", ep___users_gallery_posts],
-	["users/get-frequently-replied-users", ep___users_getFrequentlyRepliedUsers],
-	["users/groups/create", ep___users_groups_create],
-	["users/groups/delete", ep___users_groups_delete],
-	["users/groups/invitations/accept", ep___users_groups_invitations_accept],
-	["users/groups/invitations/reject", ep___users_groups_invitations_reject],
-	["users/groups/invite", ep___users_groups_invite],
-	["users/groups/joined", ep___users_groups_joined],
-	["users/groups/leave", ep___users_groups_leave],
-	["users/groups/owned", ep___users_groups_owned],
-	["users/groups/pull", ep___users_groups_pull],
-	["users/groups/show", ep___users_groups_show],
-	["users/groups/transfer", ep___users_groups_transfer],
-	["users/groups/update", ep___users_groups_update],
-	["users/lists/create", ep___users_lists_create],
-	["users/lists/delete", ep___users_lists_delete],
-	["users/lists/delete-all", ep___users_lists_delete_all],
-	["users/lists/list", ep___users_lists_list],
-	["users/lists/pull", ep___users_lists_pull],
-	["users/lists/push", ep___users_lists_push],
-	["users/lists/show", ep___users_lists_show],
-	["users/lists/update", ep___users_lists_update],
-	["users/notes", ep___users_notes],
-	["users/pages", ep___users_pages],
-	["users/reactions", ep___users_reactions],
-	["users/recommendation", ep___users_recommendation],
-	["users/relation", ep___users_relation],
-	["users/report-abuse", ep___users_reportAbuse],
-	["users/search-by-username-and-host", ep___users_searchByUsernameAndHost],
-	["users/search", ep___users_search],
-	["users/show", ep___users_show],
-	["users/stats", ep___users_stats],
-	["admin/drive-capacity-override", ep___admin_driveCapOverride],
-	["fetch-rss", ep___fetchRss],
-	["get-sounds", ep___sounds],
-];
-
-export interface IEndpointMeta {
-	readonly stability?: "deprecated" | "experimental" | "stable";
-
-	readonly tags?: ReadonlyArray<string>;
-
-	readonly errors?: {
-		readonly [key: string]: {
-			readonly message: string;
-			readonly code: string;
-			readonly id: string;
-		};
-	};
-
-	readonly res?: Schema;
-
-	/**
-	 * このエンドポイントにリクエストするのにユーザー情報が必須か否か
-	 * 省略した場合は false として解釈されます。
-	 */
-	readonly requireCredential?: boolean;
-
-	/**
-	 * 管理者のみ使えるエンドポイントか否か
-	 */
-	readonly requireAdmin?: boolean;
-
-	/**
-	 * 管理者またはモデレーターのみ使えるエンドポイントか否か
-	 */
-	readonly requireModerator?: boolean;
-
-	/**
-	 * エンドポイントのリミテーションに関するやつ
-	 * 省略した場合はリミテーションは無いものとして解釈されます。
-	 */
-	readonly limit?: {
-		/**
-		 * 複数のエンドポイントでリミットを共有したい場合に指定するキー
-		 */
-		readonly key?: string;
-
-		/**
-		 * リミットを適用する期間(ms)
-		 * このプロパティを設定する場合、max プロパティも設定する必要があります。
-		 */
-		readonly duration?: number;
-
-		/**
-		 * durationで指定した期間内にいくつまでリクエストできるのか
-		 * このプロパティを設定する場合、duration プロパティも設定する必要があります。
-		 */
-		readonly max?: number;
-
-		/**
-		 * 最低でもどれくらいの間隔を開けてリクエストしなければならないか(ms)
-		 */
-		readonly minInterval?: number;
-	};
-
-	/**
-	 * ファイルの添付を必要とするか否か
-	 * 省略した場合は false として解釈されます。
-	 */
-	readonly requireFile?: boolean;
-
-	/**
-	 * サードパーティアプリからはリクエストすることができないか否か
-	 * 省略した場合は false として解釈されます。
-	 */
-	readonly secure?: boolean;
-
-	/**
-	 * プライベートモードでなら、このエンドポイントにリクエストするときにユーザー情報が必要か否か
-	 * 省略した場合は false として解釈されます
-	 */
-	readonly requireCredentialPrivateMode?: boolean;
-
-	/**
-	 * エンドポイントの種類
-	 * パーミッションの実現に利用されます。
-	 */
-	readonly kind?: string;
-
-	readonly description?: string;
-
-	/**
-	 * GETでのリクエストを許容するか否か
-	 */
-	readonly allowGet?: boolean;
-
-	/**
-	 * 正常応答をキャッシュ (Cache-Control: public) する秒数
-	 */
-	readonly cacheSec?: number;
-}
-
-export interface IEndpoint {
-	name: string;
-	exec: any; // TODO: may be obosolete @ThatOneCalculator
-	meta: IEndpointMeta;
-	params: Schema;
-}
-
-const endpoints: IEndpoint[] = (eps as [string, any]).map(([name, ep]) => {
-	return {
-		name: name,
-		exec: ep.default,
-		meta: ep.meta ?? {},
-		params: ep.paramDef,
-	};
-});
-
-export default endpoints;
diff --git a/packages/backend/src/server/api/endpoints/admin/abuse-user-reports.ts b/packages/backend/src/server/api/endpoints/admin/abuse-user-reports.ts
deleted file mode 100644
index 4861431403..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/abuse-user-reports.ts
+++ /dev/null
@@ -1,144 +0,0 @@
-import define from "../../define.js";
-import { AbuseUserReports } from "@/models/index.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			properties: {
-				id: {
-					type: "string",
-					nullable: false,
-					optional: false,
-					format: "id",
-					example: "xxxxxxxxxx",
-				},
-				createdAt: {
-					type: "string",
-					nullable: false,
-					optional: false,
-					format: "date-time",
-				},
-				comment: {
-					type: "string",
-					nullable: false,
-					optional: false,
-				},
-				resolved: {
-					type: "boolean",
-					nullable: false,
-					optional: false,
-					example: false,
-				},
-				reporterId: {
-					type: "string",
-					nullable: false,
-					optional: false,
-					format: "id",
-				},
-				targetUserId: {
-					type: "string",
-					nullable: false,
-					optional: false,
-					format: "id",
-				},
-				assigneeId: {
-					type: "string",
-					nullable: true,
-					optional: false,
-					format: "id",
-				},
-				reporter: {
-					type: "object",
-					nullable: false,
-					optional: false,
-					ref: "User",
-				},
-				targetUser: {
-					type: "object",
-					nullable: false,
-					optional: false,
-					ref: "User",
-				},
-				assignee: {
-					type: "object",
-					nullable: true,
-					optional: true,
-					ref: "User",
-				},
-			},
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-		state: { type: "string", nullable: true, default: null },
-		reporterOrigin: {
-			type: "string",
-			enum: ["combined", "local", "remote"],
-			default: "combined",
-		},
-		targetUserOrigin: {
-			type: "string",
-			enum: ["combined", "local", "remote"],
-			default: "combined",
-		},
-		forwarded: { type: "boolean", default: false },
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	const query = makePaginationQuery(
-		AbuseUserReports.createQueryBuilder("report"),
-		ps.sinceId,
-		ps.untilId,
-	);
-
-	switch (ps.state) {
-		case "resolved":
-			query.andWhere("report.resolved = TRUE");
-			break;
-		case "unresolved":
-			query.andWhere("report.resolved = FALSE");
-			break;
-	}
-
-	switch (ps.reporterOrigin) {
-		case "local":
-			query.andWhere("report.reporterHost IS NULL");
-			break;
-		case "remote":
-			query.andWhere("report.reporterHost IS NOT NULL");
-			break;
-	}
-
-	switch (ps.targetUserOrigin) {
-		case "local":
-			query.andWhere("report.targetUserHost IS NULL");
-			break;
-		case "remote":
-			query.andWhere("report.targetUserHost IS NOT NULL");
-			break;
-	}
-
-	const reports = await query.take(ps.limit).getMany();
-
-	return await AbuseUserReports.packMany(reports);
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/accounts/create.ts b/packages/backend/src/server/api/endpoints/admin/accounts/create.ts
deleted file mode 100644
index 2e035d1695..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/accounts/create.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-import define from "../../../define.js";
-import { Users } from "@/models/index.js";
-import { signup } from "../../../common/signup.js";
-import { IsNull } from "typeorm";
-
-export const meta = {
-	tags: ["admin"],
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "User",
-		properties: {
-			token: {
-				type: "string",
-				optional: false,
-				nullable: false,
-			},
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		username: Users.localUsernameSchema,
-		password: Users.passwordSchema,
-	},
-	required: ["username", "password"],
-} as const;
-
-export default define(meta, paramDef, async (ps, _me) => {
-	const me = _me ? await Users.findOneByOrFail({ id: _me.id }) : null;
-	const noUsers =
-		(await Users.countBy({
-			host: IsNull(),
-			isAdmin: true,
-		})) === 0;
-	if (!(noUsers || me?.isAdmin)) throw new Error("access denied");
-
-	const { account, secret } = await signup({
-		username: ps.username,
-		password: ps.password,
-	});
-
-	const res = await Users.pack(account, account, {
-		detail: true,
-		includeSecrets: true,
-	});
-
-	(res as any).token = secret;
-
-	return res;
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/accounts/delete.ts b/packages/backend/src/server/api/endpoints/admin/accounts/delete.ts
deleted file mode 100644
index 3f7243ab50..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/accounts/delete.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-import define from "../../../define.js";
-import { Users } from "@/models/index.js";
-import { doPostSuspend } from "@/services/suspend-user.js";
-import { publishUserEvent } from "@/services/stream.js";
-import { createDeleteAccountJob } from "@/queue/index.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		userId: { type: "string", format: "misskey:id" },
-	},
-	required: ["userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const user = await Users.findOneBy({ id: ps.userId });
-
-	if (user == null) {
-		throw new Error("user not found");
-	}
-
-	if (user.isAdmin) {
-		throw new Error("cannot suspend admin");
-	}
-
-	if (user.isModerator) {
-		throw new Error("cannot suspend moderator");
-	}
-
-	if (Users.isLocalUser(user)) {
-		// 物理削除する前にDelete activityを送信する
-		await doPostSuspend(user).catch((e) => {});
-
-		createDeleteAccountJob(user, {
-			soft: false,
-		});
-	} else {
-		createDeleteAccountJob(user, {
-			soft: true, // リモートユーザーの削除は、完全にDBから物理削除してしまうと再度連合してきてアカウントが復活する可能性があるため、soft指定する
-		});
-	}
-
-	await Users.update(user.id, {
-		isDeleted: true,
-	});
-
-	if (Users.isLocalUser(user)) {
-		// Terminate streaming
-		publishUserEvent(user.id, "terminate", {});
-	}
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/accounts/hosted.ts b/packages/backend/src/server/api/endpoints/admin/accounts/hosted.ts
deleted file mode 100644
index 15ad1f9a17..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/accounts/hosted.ts
+++ /dev/null
@@ -1,116 +0,0 @@
-import config from "@/config/index.js";
-import { Meta } from "@/models/entities/meta.js";
-import { insertModerationLog } from "@/services/insert-moderation-log.js";
-import { db } from "@/db/postgre.js";
-import define from "../../../define.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireAdmin: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const hostedConfig = config.isManagedHosting;
-	const hosted = hostedConfig != null && hostedConfig === true;
-	if (hosted) {
-		const set = {} as Partial<Meta>;
-		if (config.deepl.managed != null && config.deepl.managed === true) {
-			if (typeof config.deepl.authKey === "boolean") {
-				set.deeplAuthKey = config.deepl.authKey;
-			}
-			if (typeof config.deepl.isPro === "boolean") {
-				set.deeplIsPro = config.deepl.isPro;
-			}
-		}
-		if (config.email.managed != null && config.email.managed === true) {
-			set.enableEmail = true;
-			if (typeof config.email.address === "string") {
-				set.email = config.email.address;
-			}
-			if (typeof config.email.host === "string") {
-				set.smtpHost = config.email.host;
-			}
-			if (typeof config.email.port === "number") {
-				set.smtpPort = config.email.port;
-			}
-			if (typeof config.email.user === "string") {
-				set.smtpUser = config.email.user;
-			}
-			if (typeof config.email.pass === "string") {
-				set.smtpPass = config.email.pass;
-			}
-			if (typeof config.email.useImplicitSslTls === "boolean") {
-				set.smtpSecure = config.email.useImplicitSslTls;
-			}
-		}
-		if (
-			config.objectStorage.managed != null &&
-			config.objectStorage.managed === true
-		) {
-			set.useObjectStorage = true;
-			if (typeof config.objectStorage.baseUrl === "string") {
-				set.objectStorageBaseUrl = config.objectStorage.baseUrl;
-			}
-			if (typeof config.objectStorage.bucket === "string") {
-				set.objectStorageBucket = config.objectStorage.bucket;
-			}
-			if (typeof config.objectStorage.prefix === "string") {
-				set.objectStoragePrefix = config.objectStorage.prefix;
-			}
-			if (typeof config.objectStorage.endpoint === "string") {
-				set.objectStorageEndpoint = config.objectStorage.endpoint;
-			}
-			if (typeof config.objectStorage.region === "string") {
-				set.objectStorageRegion = config.objectStorage.region;
-			}
-			if (typeof config.objectStorage.accessKey === "string") {
-				set.objectStorageAccessKey = config.objectStorage.accessKey;
-			}
-			if (typeof config.objectStorage.secretKey === "string") {
-				set.objectStorageSecretKey = config.objectStorage.secretKey;
-			}
-			if (typeof config.objectStorage.useSsl === "boolean") {
-				set.objectStorageUseSSL = config.objectStorage.useSsl;
-			}
-			if (typeof config.objectStorage.connnectOverProxy === "boolean") {
-				set.objectStorageUseProxy = config.objectStorage.connnectOverProxy;
-			}
-			if (typeof config.objectStorage.setPublicReadOnUpload === "boolean") {
-				set.objectStorageSetPublicRead =
-					config.objectStorage.setPublicReadOnUpload;
-			}
-			if (typeof config.objectStorage.s3ForcePathStyle === "boolean") {
-				set.objectStorageS3ForcePathStyle =
-					config.objectStorage.s3ForcePathStyle;
-			}
-		}
-		if (config.summalyProxyUrl !== undefined) {
-			set.summalyProxy = config.summalyProxyUrl;
-		}
-		await db.transaction(async (transactionalEntityManager) => {
-			const metas = await transactionalEntityManager.find(Meta, {
-				order: {
-					id: "DESC",
-				},
-			});
-
-			const meta = metas[0];
-
-			if (meta) {
-				await transactionalEntityManager.update(Meta, meta.id, set);
-			} else {
-				await transactionalEntityManager.save(Meta, set);
-			}
-		});
-		insertModerationLog(me, "updateMeta");
-	}
-	return hosted;
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/ad/create.ts b/packages/backend/src/server/api/endpoints/admin/ad/create.ts
deleted file mode 100644
index db39f3eb27..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/ad/create.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import define from "../../../define.js";
-import { Ads } from "@/models/index.js";
-import { genId } from "@/misc/gen-id.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		url: { type: "string", minLength: 1 },
-		memo: { type: "string" },
-		place: { type: "string" },
-		priority: { type: "string" },
-		ratio: { type: "integer" },
-		expiresAt: { type: "integer" },
-		imageUrl: { type: "string", minLength: 1 },
-	},
-	required: [
-		"url",
-		"memo",
-		"place",
-		"priority",
-		"ratio",
-		"expiresAt",
-		"imageUrl",
-	],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	await Ads.insert({
-		id: genId(),
-		createdAt: new Date(),
-		expiresAt: new Date(ps.expiresAt),
-		url: ps.url,
-		imageUrl: ps.imageUrl,
-		priority: ps.priority,
-		ratio: ps.ratio,
-		place: ps.place,
-		memo: ps.memo,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/ad/delete.ts b/packages/backend/src/server/api/endpoints/admin/ad/delete.ts
deleted file mode 100644
index ee6d314de7..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/ad/delete.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import define from "../../../define.js";
-import { Ads } from "@/models/index.js";
-import { ApiError } from "../../../error.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-
-	errors: {
-		noSuchAd: {
-			message: "No such ad.",
-			code: "NO_SUCH_AD",
-			id: "ccac9863-3a03-416e-b899-8a64041118b1",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		id: { type: "string", format: "misskey:id" },
-	},
-	required: ["id"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const ad = await Ads.findOneBy({ id: ps.id });
-
-	if (ad == null) throw new ApiError(meta.errors.noSuchAd);
-
-	await Ads.delete(ad.id);
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/ad/list.ts b/packages/backend/src/server/api/endpoints/admin/ad/list.ts
deleted file mode 100644
index 65944d31e9..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/ad/list.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import define from "../../../define.js";
-import { Ads } from "@/models/index.js";
-import { makePaginationQuery } from "../../../common/make-pagination-query.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	const query = makePaginationQuery(
-		Ads.createQueryBuilder("ad"),
-		ps.sinceId,
-		ps.untilId,
-	).andWhere("ad.expiresAt > :now", { now: new Date() });
-
-	const ads = await query.take(ps.limit).getMany();
-
-	return ads;
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/ad/update.ts b/packages/backend/src/server/api/endpoints/admin/ad/update.ts
deleted file mode 100644
index 2c70387310..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/ad/update.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-import define from "../../../define.js";
-import { Ads } from "@/models/index.js";
-import { ApiError } from "../../../error.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-
-	errors: {
-		noSuchAd: {
-			message: "No such ad.",
-			code: "NO_SUCH_AD",
-			id: "b7aa1727-1354-47bc-a182-3a9c3973d300",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		id: { type: "string", format: "misskey:id" },
-		memo: { type: "string" },
-		url: { type: "string", minLength: 1 },
-		imageUrl: { type: "string", minLength: 1 },
-		place: { type: "string" },
-		priority: { type: "string" },
-		ratio: { type: "integer" },
-		expiresAt: { type: "integer" },
-	},
-	required: [
-		"id",
-		"memo",
-		"url",
-		"imageUrl",
-		"place",
-		"priority",
-		"ratio",
-		"expiresAt",
-	],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const ad = await Ads.findOneBy({ id: ps.id });
-
-	if (ad == null) throw new ApiError(meta.errors.noSuchAd);
-
-	await Ads.update(ad.id, {
-		url: ps.url,
-		place: ps.place,
-		priority: ps.priority,
-		ratio: ps.ratio,
-		memo: ps.memo,
-		imageUrl: ps.imageUrl,
-		expiresAt: new Date(ps.expiresAt),
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/announcements/create.ts b/packages/backend/src/server/api/endpoints/admin/announcements/create.ts
deleted file mode 100644
index a532b6677f..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/announcements/create.ts
+++ /dev/null
@@ -1,78 +0,0 @@
-import define from "../../../define.js";
-import { Announcements } from "@/models/index.js";
-import { genId } from "@/misc/gen-id.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		properties: {
-			id: {
-				type: "string",
-				optional: false,
-				nullable: false,
-				format: "id",
-				example: "xxxxxxxxxx",
-			},
-			createdAt: {
-				type: "string",
-				optional: false,
-				nullable: false,
-				format: "date-time",
-			},
-			updatedAt: {
-				type: "string",
-				optional: false,
-				nullable: true,
-				format: "date-time",
-			},
-			title: {
-				type: "string",
-				optional: false,
-				nullable: false,
-			},
-			text: {
-				type: "string",
-				optional: false,
-				nullable: false,
-			},
-			imageUrl: {
-				type: "string",
-				optional: false,
-				nullable: true,
-			},
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		title: { type: "string", minLength: 1 },
-		text: { type: "string", minLength: 1 },
-		imageUrl: { type: "string", nullable: true, minLength: 1 },
-	},
-	required: ["title", "text", "imageUrl"],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	const announcement = await Announcements.insert({
-		id: genId(),
-		createdAt: new Date(),
-		updatedAt: null,
-		title: ps.title,
-		text: ps.text,
-		imageUrl: ps.imageUrl,
-	}).then((x) => Announcements.findOneByOrFail(x.identifiers[0]));
-
-	return Object.assign({}, announcement, {
-		createdAt: announcement.createdAt.toISOString(),
-		updatedAt: null,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/announcements/delete.ts b/packages/backend/src/server/api/endpoints/admin/announcements/delete.ts
deleted file mode 100644
index 5665b94a7b..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/announcements/delete.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import define from "../../../define.js";
-import { Announcements } from "@/models/index.js";
-import { ApiError } from "../../../error.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-
-	errors: {
-		noSuchAnnouncement: {
-			message: "No such announcement.",
-			code: "NO_SUCH_ANNOUNCEMENT",
-			id: "ecad8040-a276-4e85-bda9-015a708d291e",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		id: { type: "string", format: "misskey:id" },
-	},
-	required: ["id"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const announcement = await Announcements.findOneBy({ id: ps.id });
-
-	if (announcement == null) throw new ApiError(meta.errors.noSuchAnnouncement);
-
-	await Announcements.delete(announcement.id);
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/announcements/list.ts b/packages/backend/src/server/api/endpoints/admin/announcements/list.ts
deleted file mode 100644
index fc5b020706..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/announcements/list.ts
+++ /dev/null
@@ -1,104 +0,0 @@
-import { Announcements, AnnouncementReads } from "@/models/index.js";
-import type { Announcement } from "@/models/entities/announcement.js";
-import define from "../../../define.js";
-import { makePaginationQuery } from "../../../common/make-pagination-query.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			properties: {
-				id: {
-					type: "string",
-					optional: false,
-					nullable: false,
-					format: "id",
-					example: "xxxxxxxxxx",
-				},
-				createdAt: {
-					type: "string",
-					optional: false,
-					nullable: false,
-					format: "date-time",
-				},
-				updatedAt: {
-					type: "string",
-					optional: false,
-					nullable: true,
-					format: "date-time",
-				},
-				text: {
-					type: "string",
-					optional: false,
-					nullable: false,
-				},
-				title: {
-					type: "string",
-					optional: false,
-					nullable: false,
-				},
-				imageUrl: {
-					type: "string",
-					optional: false,
-					nullable: true,
-				},
-				reads: {
-					type: "number",
-					optional: false,
-					nullable: false,
-				},
-			},
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	const query = makePaginationQuery(
-		Announcements.createQueryBuilder("announcement"),
-		ps.sinceId,
-		ps.untilId,
-	);
-
-	const announcements = await query.take(ps.limit).getMany();
-
-	const reads = new Map<Announcement, number>();
-
-	for (const announcement of announcements) {
-		reads.set(
-			announcement,
-			await AnnouncementReads.countBy({
-				announcementId: announcement.id,
-			}),
-		);
-	}
-
-	return announcements.map((announcement) => ({
-		id: announcement.id,
-		createdAt: announcement.createdAt.toISOString(),
-		updatedAt: announcement.updatedAt?.toISOString() ?? null,
-		title: announcement.title,
-		text: announcement.text,
-		imageUrl: announcement.imageUrl,
-		reads: reads.get(announcement)!,
-	}));
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/announcements/update.ts b/packages/backend/src/server/api/endpoints/admin/announcements/update.ts
deleted file mode 100644
index 35e64f2819..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/announcements/update.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import define from "../../../define.js";
-import { Announcements } from "@/models/index.js";
-import { ApiError } from "../../../error.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-
-	errors: {
-		noSuchAnnouncement: {
-			message: "No such announcement.",
-			code: "NO_SUCH_ANNOUNCEMENT",
-			id: "d3aae5a7-6372-4cb4-b61c-f511ffc2d7cc",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		id: { type: "string", format: "misskey:id" },
-		title: { type: "string", minLength: 1 },
-		text: { type: "string", minLength: 1 },
-		imageUrl: { type: "string", nullable: true, minLength: 1 },
-	},
-	required: ["id", "title", "text", "imageUrl"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const announcement = await Announcements.findOneBy({ id: ps.id });
-
-	if (announcement == null) throw new ApiError(meta.errors.noSuchAnnouncement);
-
-	await Announcements.update(announcement.id, {
-		updatedAt: new Date(),
-		title: ps.title,
-		text: ps.text,
-		imageUrl: ps.imageUrl,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/delete-account.ts b/packages/backend/src/server/api/endpoints/admin/delete-account.ts
deleted file mode 100644
index 9fd196888d..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/delete-account.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import { Users } from "@/models/index.js";
-import { deleteAccount } from "@/services/delete-account.js";
-import define from "../../define.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireAdmin: true,
-
-	res: {},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		userId: { type: "string", format: "misskey:id" },
-	},
-	required: ["userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	const user = await Users.findOneByOrFail({ id: ps.userId });
-	if (user.isDeleted) {
-		return;
-	}
-
-	await deleteAccount(user);
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/delete-all-files-of-a-user.ts b/packages/backend/src/server/api/endpoints/admin/delete-all-files-of-a-user.ts
deleted file mode 100644
index 7969008113..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/delete-all-files-of-a-user.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import define from "../../define.js";
-import { deleteFile } from "@/services/drive/delete-file.js";
-import { DriveFiles } from "@/models/index.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		userId: { type: "string", format: "misskey:id" },
-	},
-	required: ["userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const files = await DriveFiles.findBy({
-		userId: ps.userId,
-	});
-
-	for (const file of files) {
-		deleteFile(file);
-	}
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/drive-capacity-override.ts b/packages/backend/src/server/api/endpoints/admin/drive-capacity-override.ts
deleted file mode 100644
index c8be344696..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/drive-capacity-override.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import define from "../../define.js";
-import { Users } from "@/models/index.js";
-import { insertModerationLog } from "@/services/insert-moderation-log.js";
-import { publishInternalEvent } from "@/services/stream.js";
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		userId: { type: "string", format: "misskey:id" },
-		overrideMb: { type: "number", nullable: true },
-	},
-	required: ["userId", "overrideMb"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const user = await Users.findOneBy({ id: ps.userId });
-
-	if (user == null) {
-		throw new Error("user not found");
-	}
-
-	if (!Users.isLocalUser(user)) {
-		throw new Error("user is not local user");
-	}
-
-	await Users.update(user.id, {
-		driveCapacityOverrideMb: ps.overrideMb,
-	});
-
-	publishInternalEvent("localUserUpdated", {
-		id: user.id,
-	});
-
-	insertModerationLog(me, "change-drive-capacity-override", {
-		targetId: user.id,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/drive/clean-remote-files.ts b/packages/backend/src/server/api/endpoints/admin/drive/clean-remote-files.ts
deleted file mode 100644
index 1b0c1260bd..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/drive/clean-remote-files.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import define from "../../../define.js";
-import { createCleanRemoteFilesJob } from "@/queue/index.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	createCleanRemoteFilesJob();
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/drive/cleanup.ts b/packages/backend/src/server/api/endpoints/admin/drive/cleanup.ts
deleted file mode 100644
index 04208f6004..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/drive/cleanup.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import { IsNull } from "typeorm";
-import define from "../../../define.js";
-import { deleteFile } from "@/services/drive/delete-file.js";
-import { DriveFiles } from "@/models/index.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const files = await DriveFiles.findBy({
-		userId: IsNull(),
-	});
-
-	for (const file of files) {
-		deleteFile(file);
-	}
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/drive/files.ts b/packages/backend/src/server/api/endpoints/admin/drive/files.ts
deleted file mode 100644
index 5cb0aecd81..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/drive/files.ts
+++ /dev/null
@@ -1,89 +0,0 @@
-import { DriveFiles } from "@/models/index.js";
-import define from "../../../define.js";
-import { makePaginationQuery } from "../../../common/make-pagination-query.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: false,
-	requireModerator: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "DriveFile",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-		userId: { type: "string", format: "misskey:id", nullable: true },
-		type: {
-			type: "string",
-			nullable: true,
-			pattern: /^[a-zA-Z0-9\/\-*]+$/.toString().slice(1, -1),
-		},
-		origin: {
-			type: "string",
-			enum: ["combined", "local", "remote"],
-			default: "local",
-		},
-		hostname: {
-			type: "string",
-			nullable: true,
-			default: null,
-			description: "The local host is represented with `null`.",
-		},
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const query = makePaginationQuery(
-		DriveFiles.createQueryBuilder("file"),
-		ps.sinceId,
-		ps.untilId,
-	);
-
-	if (ps.userId) {
-		query.andWhere("file.userId = :userId", { userId: ps.userId });
-	} else {
-		if (ps.origin === "local") {
-			query.andWhere("file.userHost IS NULL");
-		} else if (ps.origin === "remote") {
-			query.andWhere("file.userHost IS NOT NULL");
-		}
-
-		if (ps.hostname) {
-			query.andWhere("file.userHost = :hostname", { hostname: ps.hostname });
-		}
-	}
-
-	if (ps.type) {
-		if (ps.type.endsWith("/*")) {
-			query.andWhere("file.type like :type", {
-				type: `${ps.type.replace("/*", "/")}%`,
-			});
-		} else {
-			query.andWhere("file.type = :type", { type: ps.type });
-		}
-	}
-
-	const files = await query.take(ps.limit).getMany();
-
-	return await DriveFiles.packMany(files, {
-		detail: true,
-		withUser: true,
-		self: true,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/drive/show-file.ts b/packages/backend/src/server/api/endpoints/admin/drive/show-file.ts
deleted file mode 100644
index d65ec09fc2..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/drive/show-file.ts
+++ /dev/null
@@ -1,225 +0,0 @@
-import { DriveFiles } from "@/models/index.js";
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-
-	errors: {
-		noSuchFile: {
-			message: "No such file.",
-			code: "NO_SUCH_FILE",
-			id: "caf3ca38-c6e5-472e-a30c-b05377dcc240",
-		},
-	},
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		properties: {
-			id: {
-				type: "string",
-				optional: false,
-				nullable: false,
-				format: "id",
-				example: "xxxxxxxxxx",
-			},
-			createdAt: {
-				type: "string",
-				optional: false,
-				nullable: false,
-				format: "date-time",
-			},
-			userId: {
-				type: "string",
-				optional: false,
-				nullable: true,
-				format: "id",
-				example: "xxxxxxxxxx",
-			},
-			userHost: {
-				type: "string",
-				optional: false,
-				nullable: true,
-				description: "The local host is represented with `null`.",
-			},
-			md5: {
-				type: "string",
-				optional: false,
-				nullable: false,
-				format: "md5",
-				example: "15eca7fba0480996e2245f5185bf39f2",
-			},
-			name: {
-				type: "string",
-				optional: false,
-				nullable: false,
-				example: "lenna.jpg",
-			},
-			type: {
-				type: "string",
-				optional: false,
-				nullable: false,
-				example: "image/jpeg",
-			},
-			size: {
-				type: "number",
-				optional: false,
-				nullable: false,
-				example: 51469,
-			},
-			comment: {
-				type: "string",
-				optional: false,
-				nullable: true,
-			},
-			blurhash: {
-				type: "string",
-				optional: false,
-				nullable: true,
-			},
-			properties: {
-				type: "object",
-				optional: false,
-				nullable: false,
-				properties: {
-					width: {
-						type: "number",
-						optional: false,
-						nullable: false,
-						example: 1280,
-					},
-					height: {
-						type: "number",
-						optional: false,
-						nullable: false,
-						example: 720,
-					},
-					avgColor: {
-						type: "string",
-						optional: true,
-						nullable: false,
-						example: "rgb(40,65,87)",
-					},
-				},
-			},
-			storedInternal: {
-				type: "boolean",
-				optional: false,
-				nullable: true,
-				example: true,
-			},
-			url: {
-				type: "string",
-				optional: false,
-				nullable: true,
-				format: "url",
-			},
-			thumbnailUrl: {
-				type: "string",
-				optional: false,
-				nullable: true,
-				format: "url",
-			},
-			webpublicUrl: {
-				type: "string",
-				optional: false,
-				nullable: true,
-				format: "url",
-			},
-			accessKey: {
-				type: "string",
-				optional: false,
-				nullable: false,
-			},
-			thumbnailAccessKey: {
-				type: "string",
-				optional: false,
-				nullable: false,
-			},
-			webpublicAccessKey: {
-				type: "string",
-				optional: false,
-				nullable: false,
-			},
-			uri: {
-				type: "string",
-				optional: false,
-				nullable: true,
-			},
-			src: {
-				type: "string",
-				optional: false,
-				nullable: true,
-			},
-			folderId: {
-				type: "string",
-				optional: false,
-				nullable: true,
-				format: "id",
-				example: "xxxxxxxxxx",
-			},
-			isSensitive: {
-				type: "boolean",
-				optional: false,
-				nullable: false,
-			},
-			isLink: {
-				type: "boolean",
-				optional: false,
-				nullable: false,
-			},
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	anyOf: [
-		{
-			properties: {
-				fileId: { type: "string", format: "misskey:id" },
-			},
-			required: ["fileId"],
-		},
-		{
-			properties: {
-				url: { type: "string" },
-			},
-			required: ["url"],
-		},
-	],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const file = ps.fileId
-		? await DriveFiles.findOneBy({ id: ps.fileId })
-		: await DriveFiles.findOne({
-				where: [
-					{
-						url: ps.url,
-					},
-					{
-						thumbnailUrl: ps.url,
-					},
-					{
-						webpublicUrl: ps.url,
-					},
-				],
-		  });
-
-	if (file == null) {
-		throw new ApiError(meta.errors.noSuchFile);
-	}
-
-	if (!me.isAdmin) {
-		file.requestIp = undefined;
-		file.requestHeaders = undefined;
-	}
-
-	return file;
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/add-aliases-bulk.ts b/packages/backend/src/server/api/endpoints/admin/emoji/add-aliases-bulk.ts
deleted file mode 100644
index 1ea457adf2..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/emoji/add-aliases-bulk.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import define from "../../../define.js";
-import { Emojis } from "@/models/index.js";
-import { In } from "typeorm";
-import { ApiError } from "../../../error.js";
-import { db } from "@/db/postgre.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		ids: {
-			type: "array",
-			items: {
-				type: "string",
-				format: "misskey:id",
-			},
-		},
-		aliases: {
-			type: "array",
-			items: {
-				type: "string",
-			},
-		},
-	},
-	required: ["ids", "aliases"],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	const emojis = await Emojis.findBy({
-		id: In(ps.ids),
-	});
-
-	for (const emoji of emojis) {
-		await Emojis.update(emoji.id, {
-			updatedAt: new Date(),
-			aliases: [...new Set(emoji.aliases.concat(ps.aliases))],
-		});
-	}
-
-	await db.queryResultCache!.remove(["meta_emojis"]);
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/add.ts b/packages/backend/src/server/api/endpoints/admin/emoji/add.ts
deleted file mode 100644
index bfc025834f..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/emoji/add.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-import define from "../../../define.js";
-import { Emojis, DriveFiles } from "@/models/index.js";
-import { genId } from "@/misc/gen-id.js";
-import { insertModerationLog } from "@/services/insert-moderation-log.js";
-import { ApiError } from "../../../error.js";
-import rndstr from "rndstr";
-import { publishBroadcastStream } from "@/services/stream.js";
-import { db } from "@/db/postgre.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-
-	errors: {
-		noSuchFile: {
-			message: "No such file.",
-			code: "MO_SUCH_FILE",
-			id: "fc46b5a4-6b92-4c33-ac66-b806659bb5cf",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		fileId: { type: "string", format: "misskey:id" },
-	},
-	required: ["fileId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const file = await DriveFiles.findOneBy({ id: ps.fileId });
-
-	if (file == null) throw new ApiError(meta.errors.noSuchFile);
-
-	const name = file.name.split(".")[0].match(/^[a-z0-9_]+$/)
-		? file.name.split(".")[0]
-		: `_${rndstr("a-z0-9", 8)}_`;
-
-	const emoji = await Emojis.insert({
-		id: genId(),
-		updatedAt: new Date(),
-		name: name,
-		category: null,
-		host: null,
-		aliases: [],
-		originalUrl: file.url,
-		publicUrl: file.webpublicUrl ?? file.url,
-		type: file.webpublicType ?? file.type,
-		license: null,
-	}).then((x) => Emojis.findOneByOrFail(x.identifiers[0]));
-
-	await db.queryResultCache!.remove(["meta_emojis"]);
-
-	publishBroadcastStream("emojiAdded", {
-		emoji: await Emojis.pack(emoji.id),
-	});
-
-	insertModerationLog(me, "addEmoji", {
-		emojiId: emoji.id,
-	});
-
-	return {
-		id: emoji.id,
-	};
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/copy.ts b/packages/backend/src/server/api/endpoints/admin/emoji/copy.ts
deleted file mode 100644
index 951158f7d4..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/emoji/copy.ts
+++ /dev/null
@@ -1,88 +0,0 @@
-import define from "../../../define.js";
-import { Emojis } from "@/models/index.js";
-import { genId } from "@/misc/gen-id.js";
-import { ApiError } from "../../../error.js";
-import type { DriveFile } from "@/models/entities/drive-file.js";
-import { uploadFromUrl } from "@/services/drive/upload-from-url.js";
-import { publishBroadcastStream } from "@/services/stream.js";
-import { db } from "@/db/postgre.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-
-	errors: {
-		noSuchEmoji: {
-			message: "No such emoji.",
-			code: "NO_SUCH_EMOJI",
-			id: "e2785b66-dca3-4087-9cac-b93c541cc425",
-		},
-	},
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		properties: {
-			id: {
-				type: "string",
-				optional: false,
-				nullable: false,
-				format: "id",
-			},
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		emojiId: { type: "string", format: "misskey:id" },
-	},
-	required: ["emojiId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const emoji = await Emojis.findOneBy({ id: ps.emojiId });
-
-	if (emoji == null) {
-		throw new ApiError(meta.errors.noSuchEmoji);
-	}
-
-	let driveFile: DriveFile;
-
-	try {
-		// Create file
-		driveFile = await uploadFromUrl({
-			url: emoji.originalUrl,
-			user: null,
-			force: true,
-		});
-	} catch (e) {
-		throw new ApiError();
-	}
-
-	const copied = await Emojis.insert({
-		id: genId(),
-		updatedAt: new Date(),
-		name: emoji.name,
-		host: null,
-		aliases: [],
-		originalUrl: driveFile.url,
-		publicUrl: driveFile.webpublicUrl ?? driveFile.url,
-		type: driveFile.webpublicType ?? driveFile.type,
-		license: emoji.license,
-	}).then((x) => Emojis.findOneByOrFail(x.identifiers[0]));
-
-	await db.queryResultCache!.remove(["meta_emojis"]);
-
-	publishBroadcastStream("emojiAdded", {
-		emoji: await Emojis.pack(copied.id),
-	});
-
-	return {
-		id: copied.id,
-	};
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/delete-bulk.ts b/packages/backend/src/server/api/endpoints/admin/emoji/delete-bulk.ts
deleted file mode 100644
index 585af231f6..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/emoji/delete-bulk.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import define from "../../../define.js";
-import { Emojis } from "@/models/index.js";
-import { In } from "typeorm";
-import { insertModerationLog } from "@/services/insert-moderation-log.js";
-import { ApiError } from "../../../error.js";
-import { db } from "@/db/postgre.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		ids: {
-			type: "array",
-			items: {
-				type: "string",
-				format: "misskey:id",
-			},
-		},
-	},
-	required: ["ids"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const emojis = await Emojis.findBy({
-		id: In(ps.ids),
-	});
-
-	for (const emoji of emojis) {
-		await Emojis.delete(emoji.id);
-
-		await db.queryResultCache!.remove(["meta_emojis"]);
-
-		insertModerationLog(me, "deleteEmoji", {
-			emoji: emoji,
-		});
-	}
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/delete.ts b/packages/backend/src/server/api/endpoints/admin/emoji/delete.ts
deleted file mode 100644
index 761c7c3776..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/emoji/delete.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import define from "../../../define.js";
-import { Emojis } from "@/models/index.js";
-import { insertModerationLog } from "@/services/insert-moderation-log.js";
-import { ApiError } from "../../../error.js";
-import { db } from "@/db/postgre.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-
-	errors: {
-		noSuchEmoji: {
-			message: "No such emoji.",
-			code: "NO_SUCH_EMOJI",
-			id: "be83669b-773a-44b7-b1f8-e5e5170ac3c2",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		id: { type: "string", format: "misskey:id" },
-	},
-	required: ["id"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const emoji = await Emojis.findOneBy({ id: ps.id });
-
-	if (emoji == null) throw new ApiError(meta.errors.noSuchEmoji);
-
-	await Emojis.delete(emoji.id);
-
-	await db.queryResultCache!.remove(["meta_emojis"]);
-
-	insertModerationLog(me, "deleteEmoji", {
-		emoji: emoji,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/import-zip.ts b/packages/backend/src/server/api/endpoints/admin/emoji/import-zip.ts
deleted file mode 100644
index 6f49d6d18d..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/emoji/import-zip.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import define from "../../../define.js";
-import { createImportCustomEmojisJob } from "@/queue/index.js";
-import ms from "ms";
-
-export const meta = {
-	secure: true,
-	requireCredential: true,
-	requireModerator: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		fileId: { type: "string", format: "misskey:id" },
-	},
-	required: ["fileId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	createImportCustomEmojisJob(user, ps.fileId);
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/list-remote.ts b/packages/backend/src/server/api/endpoints/admin/emoji/list-remote.ts
deleted file mode 100644
index fae986dd96..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/emoji/list-remote.ts
+++ /dev/null
@@ -1,105 +0,0 @@
-import define from "../../../define.js";
-import { Emojis } from "@/models/index.js";
-import { toPuny } from "@/misc/convert-host.js";
-import { makePaginationQuery } from "../../../common/make-pagination-query.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			properties: {
-				id: {
-					type: "string",
-					optional: false,
-					nullable: false,
-					format: "id",
-				},
-				aliases: {
-					type: "array",
-					optional: false,
-					nullable: false,
-					items: {
-						type: "string",
-						optional: false,
-						nullable: false,
-					},
-				},
-				name: {
-					type: "string",
-					optional: false,
-					nullable: false,
-				},
-				category: {
-					type: "string",
-					optional: false,
-					nullable: true,
-				},
-				host: {
-					type: "string",
-					optional: false,
-					nullable: true,
-					description: "The local host is represented with `null`.",
-				},
-				url: {
-					type: "string",
-					optional: false,
-					nullable: false,
-				},
-				license: {
-					type: "string",
-					optional: false,
-					nullable: true,
-				},
-			},
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		query: { type: "string", nullable: true, default: null },
-		host: {
-			type: "string",
-			nullable: true,
-			default: null,
-			description: "Use `null` to represent the local host.",
-		},
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	const q = makePaginationQuery(
-		Emojis.createQueryBuilder("emoji"),
-		ps.sinceId,
-		ps.untilId,
-	);
-
-	if (ps.host == null) {
-		q.andWhere("emoji.host IS NOT NULL");
-	} else {
-		q.andWhere("emoji.host = :host", { host: toPuny(ps.host) });
-	}
-
-	if (ps.query) {
-		q.andWhere("emoji.name like :query", { query: `%${ps.query}%` });
-	}
-
-	const emojis = await q.orderBy("emoji.id", "DESC").take(ps.limit).getMany();
-
-	return Emojis.packMany(emojis);
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/list.ts b/packages/backend/src/server/api/endpoints/admin/emoji/list.ts
deleted file mode 100644
index aa49f14803..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/emoji/list.ts
+++ /dev/null
@@ -1,107 +0,0 @@
-import define from "../../../define.js";
-import { Emojis } from "@/models/index.js";
-import { makePaginationQuery } from "../../../common/make-pagination-query.js";
-import type { Emoji } from "@/models/entities/emoji.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			properties: {
-				id: {
-					type: "string",
-					optional: false,
-					nullable: false,
-					format: "id",
-				},
-				aliases: {
-					type: "array",
-					optional: false,
-					nullable: false,
-					items: {
-						type: "string",
-						optional: false,
-						nullable: false,
-					},
-				},
-				name: {
-					type: "string",
-					optional: false,
-					nullable: false,
-				},
-				category: {
-					type: "string",
-					optional: false,
-					nullable: true,
-				},
-				host: {
-					type: "null",
-					optional: false,
-					description:
-						"The local host is represented with `null`. The field exists for compatibility with other API endpoints that return files.",
-				},
-				url: {
-					type: "string",
-					optional: false,
-					nullable: false,
-				},
-				license: {
-					type: "string",
-					optional: false,
-					nullable: true,
-				},
-			},
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		query: { type: "string", nullable: true, default: null },
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	const q = makePaginationQuery(
-		Emojis.createQueryBuilder("emoji"),
-		ps.sinceId,
-		ps.untilId,
-	).andWhere("emoji.host IS NULL");
-
-	let emojis: Emoji[];
-
-	if (ps.query) {
-		//q.andWhere('emoji.name ILIKE :q', { q: `%${ps.query}%` });
-		//const emojis = await q.take(ps.limit).getMany();
-
-		emojis = await q.getMany();
-
-		emojis = emojis.filter(
-			(emoji) =>
-				emoji.name.includes(ps.query!) ||
-				emoji.aliases.some((a) => a.includes(ps.query!)) ||
-				emoji.category?.includes(ps.query!),
-		);
-
-		emojis.splice(ps.limit + 1);
-	} else {
-		emojis = await q.take(ps.limit).getMany();
-	}
-
-	return Emojis.packMany(emojis);
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/remove-aliases-bulk.ts b/packages/backend/src/server/api/endpoints/admin/emoji/remove-aliases-bulk.ts
deleted file mode 100644
index 4e57fa3dda..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/emoji/remove-aliases-bulk.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import define from "../../../define.js";
-import { Emojis } from "@/models/index.js";
-import { In } from "typeorm";
-import { ApiError } from "../../../error.js";
-import { db } from "@/db/postgre.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		ids: {
-			type: "array",
-			items: {
-				type: "string",
-				format: "misskey:id",
-			},
-		},
-		aliases: {
-			type: "array",
-			items: {
-				type: "string",
-			},
-		},
-	},
-	required: ["ids", "aliases"],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	const emojis = await Emojis.findBy({
-		id: In(ps.ids),
-	});
-
-	for (const emoji of emojis) {
-		await Emojis.update(emoji.id, {
-			updatedAt: new Date(),
-			aliases: emoji.aliases.filter((x) => !ps.aliases.includes(x)),
-		});
-	}
-
-	await db.queryResultCache!.remove(["meta_emojis"]);
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/set-aliases-bulk.ts b/packages/backend/src/server/api/endpoints/admin/emoji/set-aliases-bulk.ts
deleted file mode 100644
index 1197f60779..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/emoji/set-aliases-bulk.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import define from "../../../define.js";
-import { Emojis } from "@/models/index.js";
-import { In } from "typeorm";
-import { ApiError } from "../../../error.js";
-import { db } from "@/db/postgre.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		ids: {
-			type: "array",
-			items: {
-				type: "string",
-				format: "misskey:id",
-			},
-		},
-		aliases: {
-			type: "array",
-			items: {
-				type: "string",
-			},
-		},
-	},
-	required: ["ids", "aliases"],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	await Emojis.update(
-		{
-			id: In(ps.ids),
-		},
-		{
-			updatedAt: new Date(),
-			aliases: ps.aliases,
-		},
-	);
-
-	await db.queryResultCache!.remove(["meta_emojis"]);
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/set-category-bulk.ts b/packages/backend/src/server/api/endpoints/admin/emoji/set-category-bulk.ts
deleted file mode 100644
index 17881a4454..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/emoji/set-category-bulk.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import define from "../../../define.js";
-import { Emojis } from "@/models/index.js";
-import { In } from "typeorm";
-import { ApiError } from "../../../error.js";
-import { db } from "@/db/postgre.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		ids: {
-			type: "array",
-			items: {
-				type: "string",
-				format: "misskey:id",
-			},
-		},
-		category: {
-			type: "string",
-			nullable: true,
-			description: "Use `null` to reset the category.",
-		},
-	},
-	required: ["ids"],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	await Emojis.update(
-		{
-			id: In(ps.ids),
-		},
-		{
-			updatedAt: new Date(),
-			category: ps.category,
-		},
-	);
-
-	await db.queryResultCache!.remove(["meta_emojis"]);
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/set-license-bulk.ts b/packages/backend/src/server/api/endpoints/admin/emoji/set-license-bulk.ts
deleted file mode 100644
index c98ca03fae..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/emoji/set-license-bulk.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import define from "../../../define.js";
-import { Emojis } from "@/models/index.js";
-import { In } from "typeorm";
-import { ApiError } from "../../../error.js";
-import { db } from "@/db/postgre.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		ids: {
-			type: "array",
-			items: {
-				type: "string",
-				format: "misskey:id",
-			},
-		},
-		license: {
-			type: "string",
-			nullable: true,
-			description: "Use `null` to reset the license.",
-		},
-	},
-	required: ["ids"],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	await Emojis.update(
-		{
-			id: In(ps.ids),
-		},
-		{
-			updatedAt: new Date(),
-			license: ps.license,
-		},
-	);
-
-	await db.queryResultCache!.remove(["meta_emojis"]);
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/emoji/update.ts b/packages/backend/src/server/api/endpoints/admin/emoji/update.ts
deleted file mode 100644
index 9e2e854760..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/emoji/update.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import define from "../../../define.js";
-import { Emojis } from "@/models/index.js";
-import { ApiError } from "../../../error.js";
-import { db } from "@/db/postgre.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-
-	errors: {
-		noSuchEmoji: {
-			message: "No such emoji.",
-			code: "NO_SUCH_EMOJI",
-			id: "684dec9d-a8c2-4364-9aa8-456c49cb1dc8",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		id: { type: "string", format: "misskey:id" },
-		name: { type: "string" },
-		category: {
-			type: "string",
-			nullable: true,
-			description: "Use `null` to reset the category.",
-		},
-		aliases: {
-			type: "array",
-			items: {
-				type: "string",
-			},
-		},
-		license: {
-			type: "string",
-			nullable: true,
-		},
-	},
-	required: ["id", "name", "aliases"],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	const emoji = await Emojis.findOneBy({ id: ps.id });
-
-	if (emoji == null) throw new ApiError(meta.errors.noSuchEmoji);
-
-	await Emojis.update(emoji.id, {
-		updatedAt: new Date(),
-		name: ps.name,
-		category: ps.category,
-		aliases: ps.aliases,
-		license: ps.license,
-	});
-
-	await db.queryResultCache!.remove(["meta_emojis"]);
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/federation/delete-all-files.ts b/packages/backend/src/server/api/endpoints/admin/federation/delete-all-files.ts
deleted file mode 100644
index 534f226c28..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/federation/delete-all-files.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import define from "../../../define.js";
-import { deleteFile } from "@/services/drive/delete-file.js";
-import { DriveFiles } from "@/models/index.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		host: { type: "string" },
-	},
-	required: ["host"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const files = await DriveFiles.findBy({
-		userHost: ps.host,
-	});
-
-	for (const file of files) {
-		deleteFile(file);
-	}
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/federation/refresh-remote-instance-metadata.ts b/packages/backend/src/server/api/endpoints/admin/federation/refresh-remote-instance-metadata.ts
deleted file mode 100644
index 9c7165593c..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/federation/refresh-remote-instance-metadata.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import define from "../../../define.js";
-import { Instances } from "@/models/index.js";
-import { toPuny } from "@/misc/convert-host.js";
-import { fetchInstanceMetadata } from "@/services/fetch-instance-metadata.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		host: { type: "string" },
-	},
-	required: ["host"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const instance = await Instances.findOneBy({ host: toPuny(ps.host) });
-
-	if (instance == null) {
-		throw new Error("instance not found");
-	}
-
-	fetchInstanceMetadata(instance, true);
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/federation/remove-all-following.ts b/packages/backend/src/server/api/endpoints/admin/federation/remove-all-following.ts
deleted file mode 100644
index a1ccf11af0..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/federation/remove-all-following.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import define from "../../../define.js";
-import deleteFollowing from "@/services/following/delete.js";
-import { Followings, Users } from "@/models/index.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		host: { type: "string" },
-	},
-	required: ["host"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const followings = await Followings.findBy({
-		followerHost: ps.host,
-	});
-
-	const pairs = await Promise.all(
-		followings.map((f) =>
-			Promise.all([
-				Users.findOneByOrFail({ id: f.followerId }),
-				Users.findOneByOrFail({ id: f.followeeId }),
-			]),
-		),
-	);
-
-	for (const pair of pairs) {
-		deleteFollowing(pair[0], pair[1]);
-	}
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/federation/update-instance.ts b/packages/backend/src/server/api/endpoints/admin/federation/update-instance.ts
deleted file mode 100644
index 016989b541..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/federation/update-instance.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import define from "../../../define.js";
-import { Instances } from "@/models/index.js";
-import { toPuny } from "@/misc/convert-host.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		host: { type: "string" },
-		isSuspended: { type: "boolean" },
-	},
-	required: ["host", "isSuspended"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const instance = await Instances.findOneBy({ host: toPuny(ps.host) });
-
-	if (instance == null) {
-		throw new Error("instance not found");
-	}
-
-	Instances.update(
-		{ host: toPuny(ps.host) },
-		{
-			isSuspended: ps.isSuspended,
-		},
-	);
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/get-index-stats.ts b/packages/backend/src/server/api/endpoints/admin/get-index-stats.ts
deleted file mode 100644
index f39a369ecb..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/get-index-stats.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import define from "../../define.js";
-import { db } from "@/db/postgre.js";
-
-export const meta = {
-	requireCredential: true,
-	requireModerator: true,
-
-	tags: ["admin"],
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async () => {
-	const stats = await db.query("SELECT * FROM pg_indexes;").then((recs) => {
-		const res = [] as { tablename: string; indexname: string }[];
-		for (const rec of recs) {
-			res.push(rec);
-		}
-		return res;
-	});
-
-	return stats;
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/get-table-stats.ts b/packages/backend/src/server/api/endpoints/admin/get-table-stats.ts
deleted file mode 100644
index 25d07f327a..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/get-table-stats.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import { db } from "@/db/postgre.js";
-import define from "../../define.js";
-
-export const meta = {
-	requireCredential: true,
-	requireModerator: true,
-
-	tags: ["admin"],
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		example: {
-			migrations: {
-				count: 66,
-				size: 32768,
-			},
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async () => {
-	const sizes = await db
-		.query(`
-			SELECT relname AS "table", reltuples as "count", pg_total_relation_size(C.oid) AS "size"
-			FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
-			WHERE nspname NOT IN ('pg_catalog', 'information_schema')
-				AND C.relkind <> 'i'
-				AND nspname !~ '^pg_toast';`)
-		.then((recs) => {
-			const res = {} as Record<string, { count: number; size: number }>;
-			for (const rec of recs) {
-				res[rec.table] = {
-					count: parseInt(rec.count, 10),
-					size: parseInt(rec.size, 10),
-				};
-			}
-			return res;
-		});
-
-	return sizes;
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/get-user-ips.ts b/packages/backend/src/server/api/endpoints/admin/get-user-ips.ts
deleted file mode 100644
index da76ae624e..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/get-user-ips.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import { UserIps } from "@/models/index.js";
-import define from "../../define.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireAdmin: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		userId: { type: "string", format: "misskey:id" },
-	},
-	required: ["userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const ips = await UserIps.find({
-		where: { userId: ps.userId },
-		order: { createdAt: "DESC" },
-		take: 30,
-	});
-
-	return ips.map((x) => ({
-		ip: x.ip,
-		createdAt: x.createdAt.toISOString(),
-	}));
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/invite.ts b/packages/backend/src/server/api/endpoints/admin/invite.ts
deleted file mode 100644
index b8bdb38b46..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/invite.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import rndstr from "rndstr";
-import define from "../../define.js";
-import { RegistrationTickets } from "@/models/index.js";
-import { genId } from "@/misc/gen-id.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		properties: {
-			code: {
-				type: "string",
-				optional: false,
-				nullable: false,
-				example: "2ERUA5VR",
-				maxLength: 8,
-				minLength: 8,
-			},
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async () => {
-	const code = rndstr({
-		length: 8,
-		chars: "2-9A-HJ-NP-Z", // [0-9A-Z] w/o [01IO] (32 patterns)
-	});
-
-	await RegistrationTickets.insert({
-		id: genId(),
-		createdAt: new Date(),
-		code,
-	});
-
-	return {
-		code,
-	};
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/meta.ts b/packages/backend/src/server/api/endpoints/admin/meta.ts
deleted file mode 100644
index c8c639f504..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/meta.ts
+++ /dev/null
@@ -1,570 +0,0 @@
-import config from "@/config/index.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { MAX_NOTE_TEXT_LENGTH, MAX_CAPTION_TEXT_LENGTH } from "@/const.js";
-import define from "../../define.js";
-
-export const meta = {
-	tags: ["meta"],
-
-	requireCredential: true,
-	requireAdmin: true,
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		properties: {
-			driveCapacityPerLocalUserMb: {
-				type: "number",
-				optional: false,
-				nullable: false,
-			},
-			driveCapacityPerRemoteUserMb: {
-				type: "number",
-				optional: false,
-				nullable: false,
-			},
-			cacheRemoteFiles: {
-				type: "boolean",
-				optional: false,
-				nullable: false,
-			},
-			emailRequiredForSignup: {
-				type: "boolean",
-				optional: false,
-				nullable: false,
-			},
-			enableHcaptcha: {
-				type: "boolean",
-				optional: false,
-				nullable: false,
-			},
-			hcaptchaSiteKey: {
-				type: "string",
-				optional: false,
-				nullable: true,
-			},
-			enableRecaptcha: {
-				type: "boolean",
-				optional: false,
-				nullable: false,
-			},
-			recaptchaSiteKey: {
-				type: "string",
-				optional: false,
-				nullable: true,
-			},
-			swPublickey: {
-				type: "string",
-				optional: false,
-				nullable: true,
-			},
-			mascotImageUrl: {
-				type: "string",
-				optional: false,
-				nullable: false,
-				default: "/assets/ai.png",
-			},
-			bannerUrl: {
-				type: "string",
-				optional: false,
-				nullable: false,
-			},
-			errorImageUrl: {
-				type: "string",
-				optional: false,
-				nullable: false,
-				default: "https://xn--931a.moe/aiart/yubitun.png",
-			},
-			iconUrl: {
-				type: "string",
-				optional: false,
-				nullable: true,
-			},
-			maxNoteTextLength: {
-				type: "number",
-				optional: false,
-				nullable: false,
-			},
-			maxCaptionTextLength: {
-				type: "number",
-				optional: false,
-				nullable: false,
-			},
-			emojis: {
-				type: "array",
-				optional: false,
-				nullable: false,
-				items: {
-					type: "object",
-					optional: false,
-					nullable: false,
-					properties: {
-						id: {
-							type: "string",
-							optional: false,
-							nullable: false,
-							format: "id",
-						},
-						aliases: {
-							type: "array",
-							optional: false,
-							nullable: false,
-							items: {
-								type: "string",
-								optional: false,
-								nullable: false,
-							},
-						},
-						category: {
-							type: "string",
-							optional: false,
-							nullable: true,
-						},
-						host: {
-							type: "string",
-							optional: false,
-							nullable: true,
-						},
-						url: {
-							type: "string",
-							optional: false,
-							nullable: false,
-							format: "url",
-						},
-					},
-				},
-			},
-			ads: {
-				type: "array",
-				optional: false,
-				nullable: false,
-				items: {
-					type: "object",
-					optional: false,
-					nullable: false,
-					properties: {
-						place: {
-							type: "string",
-							optional: false,
-							nullable: false,
-						},
-						url: {
-							type: "string",
-							optional: false,
-							nullable: false,
-							format: "url",
-						},
-						imageUrl: {
-							type: "string",
-							optional: false,
-							nullable: false,
-							format: "url",
-						},
-					},
-				},
-			},
-			enableEmail: {
-				type: "boolean",
-				optional: false,
-				nullable: false,
-			},
-			enableTwitterIntegration: {
-				type: "boolean",
-				optional: false,
-				nullable: false,
-			},
-			enableGithubIntegration: {
-				type: "boolean",
-				optional: false,
-				nullable: false,
-			},
-			enableDiscordIntegration: {
-				type: "boolean",
-				optional: false,
-				nullable: false,
-			},
-			enableServiceWorker: {
-				type: "boolean",
-				optional: false,
-				nullable: false,
-			},
-			translatorAvailable: {
-				type: "boolean",
-				optional: false,
-				nullable: false,
-			},
-			proxyAccountName: {
-				type: "string",
-				optional: false,
-				nullable: true,
-			},
-			recommendedInstances: {
-				type: "array",
-				optional: true,
-				nullable: false,
-				items: {
-					type: "string",
-					optional: false,
-					nullable: false,
-				},
-			},
-			pinnedUsers: {
-				type: "array",
-				optional: true,
-				nullable: false,
-				items: {
-					type: "string",
-					optional: false,
-					nullable: false,
-				},
-			},
-			customMOTD: {
-				type: "array",
-				optional: true,
-				nullable: false,
-				items: {
-					type: "string",
-					optional: false,
-					nullable: false,
-				},
-			},
-			customSplashIcons: {
-				type: "array",
-				optional: true,
-				nullable: false,
-				items: {
-					type: "string",
-					optional: false,
-					nullable: false,
-				},
-			},
-			hiddenTags: {
-				type: "array",
-				optional: true,
-				nullable: false,
-				items: {
-					type: "string",
-					optional: false,
-					nullable: false,
-				},
-			},
-			blockedHosts: {
-				type: "array",
-				optional: true,
-				nullable: false,
-				items: {
-					type: "string",
-					optional: false,
-					nullable: false,
-				},
-			},
-			allowedHosts: {
-				type: "array",
-				optional: true,
-				nullable: false,
-				items: {
-					type: "string",
-					optional: false,
-					nullable: false,
-				},
-			},
-			privateMode: {
-				type: "boolean",
-				optional: false,
-				nullable: false,
-			},
-			secureMode: {
-				type: "boolean",
-				optional: false,
-				nullable: false,
-			},
-			hcaptchaSecretKey: {
-				type: "string",
-				optional: true,
-				nullable: true,
-			},
-			recaptchaSecretKey: {
-				type: "string",
-				optional: true,
-				nullable: true,
-			},
-			sensitiveMediaDetection: {
-				type: "string",
-				optional: true,
-				nullable: false,
-			},
-			sensitiveMediaDetectionSensitivity: {
-				type: "string",
-				optional: true,
-				nullable: false,
-			},
-			setSensitiveFlagAutomatically: {
-				type: "boolean",
-				optional: true,
-				nullable: false,
-			},
-			enableSensitiveMediaDetectionForVideos: {
-				type: "boolean",
-				optional: true,
-				nullable: false,
-			},
-			proxyAccountId: {
-				type: "string",
-				optional: true,
-				nullable: true,
-				format: "id",
-			},
-			twitterConsumerKey: {
-				type: "string",
-				optional: true,
-				nullable: true,
-			},
-			twitterConsumerSecret: {
-				type: "string",
-				optional: true,
-				nullable: true,
-			},
-			githubClientId: {
-				type: "string",
-				optional: true,
-				nullable: true,
-			},
-			githubClientSecret: {
-				type: "string",
-				optional: true,
-				nullable: true,
-			},
-			discordClientId: {
-				type: "string",
-				optional: true,
-				nullable: true,
-			},
-			discordClientSecret: {
-				type: "string",
-				optional: true,
-				nullable: true,
-			},
-			summaryProxy: {
-				type: "string",
-				optional: true,
-				nullable: true,
-			},
-			email: {
-				type: "string",
-				optional: true,
-				nullable: true,
-			},
-			smtpSecure: {
-				type: "boolean",
-				optional: true,
-				nullable: false,
-			},
-			smtpHost: {
-				type: "string",
-				optional: true,
-				nullable: true,
-			},
-			smtpPort: {
-				type: "string",
-				optional: true,
-				nullable: true,
-			},
-			smtpUser: {
-				type: "string",
-				optional: true,
-				nullable: true,
-			},
-			smtpPass: {
-				type: "string",
-				optional: true,
-				nullable: true,
-			},
-			swPrivateKey: {
-				type: "string",
-				optional: true,
-				nullable: true,
-			},
-			useObjectStorage: {
-				type: "boolean",
-				optional: true,
-				nullable: false,
-			},
-			objectStorageBaseUrl: {
-				type: "string",
-				optional: true,
-				nullable: true,
-			},
-			objectStorageBucket: {
-				type: "string",
-				optional: true,
-				nullable: true,
-			},
-			objectStoragePrefix: {
-				type: "string",
-				optional: true,
-				nullable: true,
-			},
-			objectStorageEndpoint: {
-				type: "string",
-				optional: true,
-				nullable: true,
-			},
-			objectStorageRegion: {
-				type: "string",
-				optional: true,
-				nullable: true,
-			},
-			objectStoragePort: {
-				type: "number",
-				optional: true,
-				nullable: true,
-			},
-			objectStorageAccessKey: {
-				type: "string",
-				optional: true,
-				nullable: true,
-			},
-			objectStorageSecretKey: {
-				type: "string",
-				optional: true,
-				nullable: true,
-			},
-			objectStorageUseSSL: {
-				type: "boolean",
-				optional: true,
-				nullable: false,
-			},
-			objectStorageUseProxy: {
-				type: "boolean",
-				optional: true,
-				nullable: false,
-			},
-			objectStorageSetPublicRead: {
-				type: "boolean",
-				optional: true,
-				nullable: false,
-			},
-			enableIpLogging: {
-				type: "boolean",
-				optional: true,
-				nullable: false,
-			},
-			enableActiveEmailValidation: {
-				type: "boolean",
-				optional: true,
-				nullable: false,
-			},
-			defaultReaction: {
-				type: "string",
-				optional: false,
-				nullable: false,
-			},
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const instance = await fetchMeta(true);
-
-	return {
-		maintainerName: instance.maintainerName,
-		maintainerEmail: instance.maintainerEmail,
-		version: config.version,
-		name: instance.name,
-		uri: config.url,
-		description: instance.description,
-		langs: instance.langs,
-		tosUrl: instance.ToSUrl,
-		repositoryUrl: instance.repositoryUrl,
-		feedbackUrl: instance.feedbackUrl,
-		disableRegistration: instance.disableRegistration,
-		disableLocalTimeline: instance.disableLocalTimeline,
-		disableRecommendedTimeline: instance.disableRecommendedTimeline,
-		disableGlobalTimeline: instance.disableGlobalTimeline,
-		driveCapacityPerLocalUserMb: instance.localDriveCapacityMb,
-		driveCapacityPerRemoteUserMb: instance.remoteDriveCapacityMb,
-		emailRequiredForSignup: instance.emailRequiredForSignup,
-		enableHcaptcha: instance.enableHcaptcha,
-		hcaptchaSiteKey: instance.hcaptchaSiteKey,
-		enableRecaptcha: instance.enableRecaptcha,
-		recaptchaSiteKey: instance.recaptchaSiteKey,
-		swPublickey: instance.swPublicKey,
-		themeColor: instance.themeColor,
-		mascotImageUrl: instance.mascotImageUrl,
-		bannerUrl: instance.bannerUrl,
-		errorImageUrl: instance.errorImageUrl,
-		iconUrl: instance.iconUrl,
-		backgroundImageUrl: instance.backgroundImageUrl,
-		logoImageUrl: instance.logoImageUrl,
-		maxNoteTextLength: MAX_NOTE_TEXT_LENGTH, // 後方互換性のため
-		maxCaptionTextLength: MAX_CAPTION_TEXT_LENGTH,
-		defaultLightTheme: instance.defaultLightTheme,
-		defaultDarkTheme: instance.defaultDarkTheme,
-		enableEmail: instance.enableEmail,
-		enableTwitterIntegration: instance.enableTwitterIntegration,
-		enableGithubIntegration: instance.enableGithubIntegration,
-		enableDiscordIntegration: instance.enableDiscordIntegration,
-		enableServiceWorker: instance.enableServiceWorker,
-		translatorAvailable: instance.deeplAuthKey != null,
-		pinnedPages: instance.pinnedPages,
-		pinnedClipId: instance.pinnedClipId,
-		cacheRemoteFiles: instance.cacheRemoteFiles,
-		defaultReaction: instance.defaultReaction,
-		recommendedInstances: instance.recommendedInstances,
-		pinnedUsers: instance.pinnedUsers,
-		customMOTD: instance.customMOTD,
-		customSplashIcons: instance.customSplashIcons,
-		hiddenTags: instance.hiddenTags,
-		blockedHosts: instance.blockedHosts,
-		allowedHosts: instance.allowedHosts,
-		privateMode: instance.privateMode,
-		secureMode: instance.secureMode,
-		hcaptchaSecretKey: instance.hcaptchaSecretKey,
-		recaptchaSecretKey: instance.recaptchaSecretKey,
-		sensitiveMediaDetection: instance.sensitiveMediaDetection,
-		sensitiveMediaDetectionSensitivity:
-			instance.sensitiveMediaDetectionSensitivity,
-		setSensitiveFlagAutomatically: instance.setSensitiveFlagAutomatically,
-		enableSensitiveMediaDetectionForVideos:
-			instance.enableSensitiveMediaDetectionForVideos,
-		proxyAccountId: instance.proxyAccountId,
-		twitterConsumerKey: instance.twitterConsumerKey,
-		twitterConsumerSecret: instance.twitterConsumerSecret,
-		githubClientId: instance.githubClientId,
-		githubClientSecret: instance.githubClientSecret,
-		discordClientId: instance.discordClientId,
-		discordClientSecret: instance.discordClientSecret,
-		summalyProxy: instance.summalyProxy,
-		email: instance.email,
-		smtpSecure: instance.smtpSecure,
-		smtpHost: instance.smtpHost,
-		smtpPort: instance.smtpPort,
-		smtpUser: instance.smtpUser,
-		smtpPass: instance.smtpPass,
-		swPrivateKey: instance.swPrivateKey,
-		useObjectStorage: instance.useObjectStorage,
-		objectStorageBaseUrl: instance.objectStorageBaseUrl,
-		objectStorageBucket: instance.objectStorageBucket,
-		objectStoragePrefix: instance.objectStoragePrefix,
-		objectStorageEndpoint: instance.objectStorageEndpoint,
-		objectStorageRegion: instance.objectStorageRegion,
-		objectStoragePort: instance.objectStoragePort,
-		objectStorageAccessKey: instance.objectStorageAccessKey,
-		objectStorageSecretKey: instance.objectStorageSecretKey,
-		objectStorageUseSSL: instance.objectStorageUseSSL,
-		objectStorageUseProxy: instance.objectStorageUseProxy,
-		objectStorageSetPublicRead: instance.objectStorageSetPublicRead,
-		objectStorageS3ForcePathStyle: instance.objectStorageS3ForcePathStyle,
-		deeplAuthKey: instance.deeplAuthKey,
-		deeplIsPro: instance.deeplIsPro,
-		enableIpLogging: instance.enableIpLogging,
-		enableActiveEmailValidation: instance.enableActiveEmailValidation,
-	};
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/moderators/add.ts b/packages/backend/src/server/api/endpoints/admin/moderators/add.ts
deleted file mode 100644
index 478f2661b6..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/moderators/add.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-import define from "../../../define.js";
-import { Users } from "@/models/index.js";
-import { publishInternalEvent } from "@/services/stream.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireAdmin: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		userId: { type: "string", format: "misskey:id" },
-	},
-	required: ["userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	const user = await Users.findOneBy({ id: ps.userId });
-
-	if (user == null) {
-		throw new Error("user not found");
-	}
-
-	if (user.isAdmin) {
-		throw new Error("cannot mark as moderator if admin user");
-	}
-
-	await Users.update(user.id, {
-		isModerator: true,
-	});
-
-	publishInternalEvent("userChangeModeratorState", {
-		id: user.id,
-		isModerator: true,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/moderators/remove.ts b/packages/backend/src/server/api/endpoints/admin/moderators/remove.ts
deleted file mode 100644
index a43cc0cbe1..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/moderators/remove.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import define from "../../../define.js";
-import { Users } from "@/models/index.js";
-import { publishInternalEvent } from "@/services/stream.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireAdmin: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		userId: { type: "string", format: "misskey:id" },
-	},
-	required: ["userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	const user = await Users.findOneBy({ id: ps.userId });
-
-	if (user == null) {
-		throw new Error("user not found");
-	}
-
-	await Users.update(user.id, {
-		isModerator: false,
-	});
-
-	publishInternalEvent("userChangeModeratorState", {
-		id: user.id,
-		isModerator: false,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/promo/create.ts b/packages/backend/src/server/api/endpoints/admin/promo/create.ts
deleted file mode 100644
index a6d1f35191..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/promo/create.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-import { getNote } from "../../../common/getters.js";
-import { PromoNotes } from "@/models/index.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-
-	errors: {
-		noSuchNote: {
-			message: "No such note.",
-			code: "NO_SUCH_NOTE",
-			id: "ee449fbe-af2a-453b-9cae-cf2fe7c895fc",
-		},
-
-		alreadyPromoted: {
-			message: "The note has already promoted.",
-			code: "ALREADY_PROMOTED",
-			id: "ae427aa2-7a41-484f-a18c-2c1104051604",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		noteId: { type: "string", format: "misskey:id" },
-		expiresAt: { type: "integer" },
-	},
-	required: ["noteId", "expiresAt"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const note = await getNote(ps.noteId, user).catch((err) => {
-		if (err.id === "9725d0ce-ba28-4dde-95a7-2cbb2c15de24")
-			throw new ApiError(meta.errors.noSuchNote);
-		throw err;
-	});
-
-	const exist = await PromoNotes.findOneBy({ noteId: note.id });
-
-	if (exist != null) {
-		throw new ApiError(meta.errors.alreadyPromoted);
-	}
-
-	await PromoNotes.insert({
-		noteId: note.id,
-		expiresAt: new Date(ps.expiresAt),
-		userId: note.userId,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/queue/clear.ts b/packages/backend/src/server/api/endpoints/admin/queue/clear.ts
deleted file mode 100644
index 9b828bb241..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/queue/clear.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import define from "../../../define.js";
-import { destroy } from "@/queue/index.js";
-import { insertModerationLog } from "@/services/insert-moderation-log.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	destroy();
-
-	insertModerationLog(me, "clearQueue");
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/queue/deliver-delayed.ts b/packages/backend/src/server/api/endpoints/admin/queue/deliver-delayed.ts
deleted file mode 100644
index 15fdfb0250..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/queue/deliver-delayed.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-import { deliverQueue } from "@/queue/queues.js";
-import { URL } from "node:url";
-import define from "../../../define.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "array",
-			optional: false,
-			nullable: false,
-			items: {
-				anyOf: [
-					{
-						type: "string",
-					},
-					{
-						type: "number",
-					},
-				],
-			},
-		},
-		example: [["example.com", 12]],
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	const jobs = await deliverQueue.getJobs(["delayed"]);
-
-	const res = [] as [string, number][];
-
-	for (const job of jobs) {
-		const host = new URL(job.data.to).host;
-		if (res.find((x) => x[0] === host)) {
-			res.find((x) => x[0] === host)![1]++;
-		} else {
-			res.push([host, 1]);
-		}
-	}
-
-	res.sort((a, b) => b[1] - a[1]);
-
-	return res;
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/queue/inbox-delayed.ts b/packages/backend/src/server/api/endpoints/admin/queue/inbox-delayed.ts
deleted file mode 100644
index 1890bd4345..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/queue/inbox-delayed.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-import { URL } from "node:url";
-import define from "../../../define.js";
-import { inboxQueue } from "@/queue/queues.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "array",
-			optional: false,
-			nullable: false,
-			items: {
-				anyOf: [
-					{
-						type: "string",
-					},
-					{
-						type: "number",
-					},
-				],
-			},
-		},
-		example: [["example.com", 12]],
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	const jobs = await inboxQueue.getJobs(["delayed"]);
-
-	const res = [] as [string, number][];
-
-	for (const job of jobs) {
-		const host = new URL(job.data.signature.keyId).host;
-		if (res.find((x) => x[0] === host)) {
-			res.find((x) => x[0] === host)![1]++;
-		} else {
-			res.push([host, 1]);
-		}
-	}
-
-	res.sort((a, b) => b[1] - a[1]);
-
-	return res;
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/queue/stats.ts b/packages/backend/src/server/api/endpoints/admin/queue/stats.ts
deleted file mode 100644
index 4a437c3d12..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/queue/stats.ts
+++ /dev/null
@@ -1,70 +0,0 @@
-import {
-	deliverQueue,
-	inboxQueue,
-	dbQueue,
-	objectStorageQueue,
-	backgroundQueue,
-} from "@/queue/queues.js";
-import define from "../../../define.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		properties: {
-			deliver: {
-				optional: false,
-				nullable: false,
-				ref: "QueueCount",
-			},
-			inbox: {
-				optional: false,
-				nullable: false,
-				ref: "QueueCount",
-			},
-			db: {
-				optional: false,
-				nullable: false,
-				ref: "QueueCount",
-			},
-			objectStorage: {
-				optional: false,
-				nullable: false,
-				ref: "QueueCount",
-			},
-			backgroundQueue: {
-				optional: false,
-				nullable: false,
-				ref: "QueueCount",
-			},
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	const deliverJobCounts = await deliverQueue.getJobCounts();
-	const inboxJobCounts = await inboxQueue.getJobCounts();
-	const dbJobCounts = await dbQueue.getJobCounts();
-	const objectStorageJobCounts = await objectStorageQueue.getJobCounts();
-	const backgroundJobCounts = await backgroundQueue.getJobCounts();
-
-	return {
-		deliver: deliverJobCounts,
-		inbox: inboxJobCounts,
-		db: dbJobCounts,
-		objectStorage: objectStorageJobCounts,
-		backgroundQueue: backgroundJobCounts,
-	};
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/relays/add.ts b/packages/backend/src/server/api/endpoints/admin/relays/add.ts
deleted file mode 100644
index bb56216a74..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/relays/add.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-import { URL } from "node:url";
-import define from "../../../define.js";
-import { addRelay } from "@/services/relay.js";
-import { ApiError } from "../../../error.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-
-	errors: {
-		invalidUrl: {
-			message: "Invalid URL",
-			code: "INVALID_URL",
-			id: "fb8c92d3-d4e5-44e7-b3d4-800d5cef8b2c",
-		},
-	},
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		properties: {
-			id: {
-				type: "string",
-				optional: false,
-				nullable: false,
-				format: "id",
-			},
-			inbox: {
-				description: "URL of the inbox, must be a https scheme URL",
-				type: "string",
-				optional: false,
-				nullable: false,
-				format: "url",
-			},
-			status: {
-				type: "string",
-				optional: false,
-				nullable: false,
-				default: "requesting",
-				enum: ["requesting", "accepted", "rejected"],
-			},
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		inbox: { type: "string" },
-	},
-	required: ["inbox"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	try {
-		if (new URL(ps.inbox).protocol !== "https:") throw new Error("https only");
-	} catch {
-		throw new ApiError(meta.errors.invalidUrl);
-	}
-
-	return await addRelay(ps.inbox);
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/relays/list.ts b/packages/backend/src/server/api/endpoints/admin/relays/list.ts
deleted file mode 100644
index 4c294ba9b2..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/relays/list.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import define from "../../../define.js";
-import { listRelay } from "@/services/relay.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			properties: {
-				id: {
-					type: "string",
-					optional: false,
-					nullable: false,
-					format: "id",
-				},
-				inbox: {
-					type: "string",
-					optional: false,
-					nullable: false,
-					format: "url",
-				},
-				status: {
-					type: "string",
-					optional: false,
-					nullable: false,
-					default: "requesting",
-					enum: ["requesting", "accepted", "rejected"],
-				},
-			},
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	return await listRelay();
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/relays/remove.ts b/packages/backend/src/server/api/endpoints/admin/relays/remove.ts
deleted file mode 100644
index 1b3d90628b..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/relays/remove.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import define from "../../../define.js";
-import { removeRelay } from "@/services/relay.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		inbox: { type: "string" },
-	},
-	required: ["inbox"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	return await removeRelay(ps.inbox);
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/reset-password.ts b/packages/backend/src/server/api/endpoints/admin/reset-password.ts
deleted file mode 100644
index cbe6735ce5..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/reset-password.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-import define from "../../define.js";
-// import bcrypt from "bcryptjs";
-import rndstr from "rndstr";
-import { Users, UserProfiles } from "@/models/index.js";
-import { hashPassword } from "@/misc/password.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		properties: {
-			password: {
-				type: "string",
-				optional: false,
-				nullable: false,
-				minLength: 8,
-				maxLength: 8,
-			},
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		userId: { type: "string", format: "misskey:id" },
-	},
-	required: ["userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	const user = await Users.findOneBy({ id: ps.userId });
-
-	if (user == null) {
-		throw new Error("user not found");
-	}
-
-	if (user.isAdmin) {
-		throw new Error("cannot reset password of admin");
-	}
-
-	const passwd = rndstr("a-zA-Z0-9", 8);
-
-	// Generate hash of password
-	// const hash = bcrypt.hashSync(passwd);
-	const hash = await hashPassword(passwd);
-
-	await UserProfiles.update(
-		{
-			userId: user.id,
-		},
-		{
-			password: hash,
-		},
-	);
-
-	return {
-		password: passwd,
-	};
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/resolve-abuse-user-report.ts b/packages/backend/src/server/api/endpoints/admin/resolve-abuse-user-report.ts
deleted file mode 100644
index c876a21984..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/resolve-abuse-user-report.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import define from "../../define.js";
-import { AbuseUserReports, Users } from "@/models/index.js";
-import { getInstanceActor } from "@/services/instance-actor.js";
-import { deliver } from "@/queue/index.js";
-import { renderActivity } from "@/remote/activitypub/renderer/index.js";
-import { renderFlag } from "@/remote/activitypub/renderer/flag.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		reportId: { type: "string", format: "misskey:id" },
-		forward: { type: "boolean", default: false },
-	},
-	required: ["reportId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const report = await AbuseUserReports.findOneByOrFail({ id: ps.reportId });
-
-	if (report == null) {
-		throw new Error("report not found");
-	}
-
-	if (ps.forward && report.targetUserHost != null) {
-		const actor = await getInstanceActor();
-		const targetUser = await Users.findOneByOrFail({ id: report.targetUserId });
-
-		deliver(
-			actor,
-			renderActivity(renderFlag(actor, [targetUser.uri!], report.comment)),
-			targetUser.inbox,
-		);
-	}
-
-	await AbuseUserReports.update(report.id, {
-		resolved: true,
-		assigneeId: me.id,
-		forwarded: ps.forward && report.targetUserHost != null,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/search/index-all.ts b/packages/backend/src/server/api/endpoints/admin/search/index-all.ts
deleted file mode 100644
index 135b48eccd..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/search/index-all.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import define from "../../../define.js";
-import { createIndexAllNotesJob } from "@/queue/index.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		cursor: {
-			type: "string",
-			format: "misskey:id",
-			nullable: true,
-			default: null,
-		},
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, _me) => {
-	createIndexAllNotesJob({
-		cursor: ps.cursor ?? undefined,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/send-email.ts b/packages/backend/src/server/api/endpoints/admin/send-email.ts
deleted file mode 100644
index 1676f68907..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/send-email.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import define from "../../define.js";
-import { sendEmail } from "@/services/send-email.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		to: { type: "string" },
-		subject: { type: "string" },
-		text: { type: "string" },
-	},
-	required: ["to", "subject", "text"],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	await sendEmail(ps.to, ps.subject, ps.text, ps.text);
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/server-info.ts b/packages/backend/src/server/api/endpoints/admin/server-info.ts
deleted file mode 100644
index 8998032cc9..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/server-info.ts
+++ /dev/null
@@ -1,143 +0,0 @@
-import * as os from "node:os";
-import si from "systeminformation";
-import define from "../../define.js";
-import { redisClient } from "../../../../db/redis.js";
-import { db } from "@/db/postgre.js";
-
-export const meta = {
-	requireCredential: true,
-	requireModerator: true,
-
-	tags: ["admin", "meta"],
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		properties: {
-			machine: {
-				type: "string",
-				optional: false,
-				nullable: false,
-			},
-			os: {
-				type: "string",
-				optional: false,
-				nullable: false,
-				example: "linux",
-			},
-			node: {
-				type: "string",
-				optional: false,
-				nullable: false,
-			},
-			psql: {
-				type: "string",
-				optional: false,
-				nullable: false,
-			},
-			cpu: {
-				type: "object",
-				optional: false,
-				nullable: false,
-				properties: {
-					model: {
-						type: "string",
-						optional: false,
-						nullable: false,
-					},
-					cores: {
-						type: "number",
-						optional: false,
-						nullable: false,
-					},
-				},
-			},
-			mem: {
-				type: "object",
-				optional: false,
-				nullable: false,
-				properties: {
-					total: {
-						type: "number",
-						optional: false,
-						nullable: false,
-						format: "bytes",
-					},
-				},
-			},
-			fs: {
-				type: "object",
-				optional: false,
-				nullable: false,
-				properties: {
-					total: {
-						type: "number",
-						optional: false,
-						nullable: false,
-						format: "bytes",
-					},
-					used: {
-						type: "number",
-						optional: false,
-						nullable: false,
-						format: "bytes",
-					},
-				},
-			},
-			net: {
-				type: "object",
-				optional: false,
-				nullable: false,
-				properties: {
-					interface: {
-						type: "string",
-						optional: false,
-						nullable: false,
-						example: "eth0",
-					},
-				},
-			},
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async () => {
-	const memStats = await si.mem();
-	const fsStats = await si.fsSize();
-	const netInterface = await si.networkInterfaceDefault();
-
-	const redisServerInfo = await redisClient.info("Server");
-	const m = redisServerInfo.match(new RegExp("^redis_version:(.*)", "m"));
-	const redis_version = m?.[1];
-
-	return {
-		machine: os.hostname(),
-		os: os.platform(),
-		node: process.version,
-		psql: await db
-			.query("SHOW server_version")
-			.then((x) => x[0].server_version),
-		redis: redis_version,
-		cpu: {
-			model: os.cpus()[0].model,
-			cores: os.cpus().length,
-		},
-		mem: {
-			total: memStats.total,
-		},
-		fs: {
-			total: fsStats[0].size,
-			used: fsStats[0].used,
-		},
-		net: {
-			interface: netInterface,
-		},
-	};
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/show-moderation-logs.ts b/packages/backend/src/server/api/endpoints/admin/show-moderation-logs.ts
deleted file mode 100644
index df7e8979ca..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/show-moderation-logs.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-import define from "../../define.js";
-import { ModerationLogs } from "@/models/index.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			properties: {
-				id: {
-					type: "string",
-					optional: false,
-					nullable: false,
-					format: "id",
-				},
-				createdAt: {
-					type: "string",
-					optional: false,
-					nullable: false,
-					format: "date-time",
-				},
-				type: {
-					type: "string",
-					optional: false,
-					nullable: false,
-				},
-				info: {
-					type: "object",
-					optional: false,
-					nullable: false,
-				},
-				userId: {
-					type: "string",
-					optional: false,
-					nullable: false,
-					format: "id",
-				},
-				user: {
-					type: "object",
-					optional: false,
-					nullable: false,
-					ref: "UserDetailed",
-				},
-			},
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	const query = makePaginationQuery(
-		ModerationLogs.createQueryBuilder("report"),
-		ps.sinceId,
-		ps.untilId,
-	);
-
-	const reports = await query.take(ps.limit).getMany();
-
-	return await ModerationLogs.packMany(reports);
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/show-user.ts b/packages/backend/src/server/api/endpoints/admin/show-user.ts
deleted file mode 100644
index e91f07f838..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/show-user.ts
+++ /dev/null
@@ -1,78 +0,0 @@
-import { Signins, UserProfiles, Users } from "@/models/index.js";
-import define from "../../define.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-
-	res: {
-		type: "object",
-		nullable: false,
-		optional: false,
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		userId: { type: "string", format: "misskey:id" },
-	},
-	required: ["userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const [user, profile] = await Promise.all([
-		Users.findOneBy({ id: ps.userId }),
-		UserProfiles.findOneBy({ userId: ps.userId }),
-	]);
-
-	if (user == null || profile == null) {
-		throw new Error("user not found");
-	}
-
-	const _me = await Users.findOneByOrFail({ id: me.id });
-	if (_me.isModerator && !_me.isAdmin && user.isAdmin) {
-		throw new Error("cannot show info of admin");
-	}
-
-	if (!_me.isAdmin) {
-		return {
-			isModerator: user.isModerator,
-			isSilenced: user.isSilenced,
-			isSuspended: user.isSuspended,
-		};
-	}
-
-	const maskedKeys = ["accessToken", "accessTokenSecret", "refreshToken"];
-	Object.keys(profile.integrations).forEach((integration) => {
-		maskedKeys.forEach(
-			(key) => (profile.integrations[integration][key] = "<MASKED>"),
-		);
-	});
-
-	const signins = await Signins.findBy({ userId: user.id });
-
-	return {
-		email: profile.email,
-		emailVerified: profile.emailVerified,
-		autoAcceptFollowed: profile.autoAcceptFollowed,
-		noCrawle: profile.noCrawle,
-		alwaysMarkNsfw: profile.alwaysMarkNsfw,
-		autoSensitive: profile.autoSensitive,
-		carefulBot: profile.carefulBot,
-		injectFeaturedNote: profile.injectFeaturedNote,
-		receiveAnnouncementEmail: profile.receiveAnnouncementEmail,
-		integrations: profile.integrations,
-		mutedWords: profile.mutedWords,
-		mutedInstances: profile.mutedInstances,
-		mutingNotificationTypes: profile.mutingNotificationTypes,
-		isModerator: user.isModerator,
-		isSilenced: user.isSilenced,
-		isSuspended: user.isSuspended,
-		lastActiveDate: user.lastActiveDate,
-		moderationNote: profile.moderationNote,
-		signins,
-	};
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/show-users.ts b/packages/backend/src/server/api/endpoints/admin/show-users.ts
deleted file mode 100644
index 868df9dc9b..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/show-users.ts
+++ /dev/null
@@ -1,149 +0,0 @@
-import { Users } from "@/models/index.js";
-import define from "../../define.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-
-	res: {
-		type: "array",
-		nullable: false,
-		optional: false,
-		items: {
-			type: "object",
-			nullable: false,
-			optional: false,
-			ref: "UserDetailed",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		offset: { type: "integer", default: 0 },
-		sort: {
-			type: "string",
-			enum: [
-				"+follower",
-				"-follower",
-				"+createdAt",
-				"-createdAt",
-				"+updatedAt",
-				"-updatedAt",
-			],
-		},
-		state: {
-			type: "string",
-			enum: [
-				"all",
-				"alive",
-				"available",
-				"admin",
-				"moderator",
-				"adminOrModerator",
-				"silenced",
-				"suspended",
-			],
-			default: "all",
-		},
-		origin: {
-			type: "string",
-			enum: ["combined", "local", "remote"],
-			default: "combined",
-		},
-		username: { type: "string", nullable: true, default: null },
-		hostname: {
-			type: "string",
-			nullable: true,
-			default: null,
-			description: "The local host is represented with `null`.",
-		},
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const query = Users.createQueryBuilder("user");
-
-	switch (ps.state) {
-		case "available":
-			query.where("user.isSuspended = FALSE");
-			break;
-		case "admin":
-			query.where("user.isAdmin = TRUE");
-			break;
-		case "moderator":
-			query.where("user.isModerator = TRUE");
-			break;
-		case "adminOrModerator":
-			query.where("user.isAdmin = TRUE OR user.isModerator = TRUE");
-			break;
-		case "alive":
-			query.where("user.updatedAt > :date", {
-				date: new Date(Date.now() - 1000 * 60 * 60 * 24 * 5),
-			});
-			break;
-		case "silenced":
-			query.where("user.isSilenced = TRUE");
-			break;
-		case "suspended":
-			query.where("user.isSuspended = TRUE");
-			break;
-	}
-
-	switch (ps.origin) {
-		case "local":
-			query.andWhere("user.host IS NULL");
-			break;
-		case "remote":
-			query.andWhere("user.host IS NOT NULL");
-			break;
-	}
-
-	if (ps.username) {
-		query.andWhere("user.usernameLower like :username", {
-			username: `${ps.username.toLowerCase()}%`,
-		});
-	}
-
-	if (ps.hostname) {
-		query.andWhere("user.host = :hostname", {
-			hostname: ps.hostname.toLowerCase(),
-		});
-	}
-
-	switch (ps.sort) {
-		case "+follower":
-			query.orderBy("user.followersCount", "DESC");
-			break;
-		case "-follower":
-			query.orderBy("user.followersCount", "ASC");
-			break;
-		case "+createdAt":
-			query.orderBy("user.createdAt", "DESC");
-			break;
-		case "-createdAt":
-			query.orderBy("user.createdAt", "ASC");
-			break;
-		case "+updatedAt":
-			query.orderBy("user.updatedAt", "DESC", "NULLS LAST");
-			break;
-		case "-updatedAt":
-			query.orderBy("user.updatedAt", "ASC", "NULLS FIRST");
-			break;
-		default:
-			query.orderBy("user.id", "ASC");
-			break;
-	}
-
-	query.take(ps.limit);
-	query.skip(ps.offset);
-
-	const users = await query.getMany();
-
-	return await Users.packMany(users, me, { detail: true });
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/silence-user.ts b/packages/backend/src/server/api/endpoints/admin/silence-user.ts
deleted file mode 100644
index a61823297b..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/silence-user.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import define from "../../define.js";
-import { Users } from "@/models/index.js";
-import { insertModerationLog } from "@/services/insert-moderation-log.js";
-import { publishInternalEvent } from "@/services/stream.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		userId: { type: "string", format: "misskey:id" },
-	},
-	required: ["userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const user = await Users.findOneBy({ id: ps.userId });
-
-	if (user == null) {
-		throw new Error("user not found");
-	}
-
-	if (user.isAdmin) {
-		throw new Error("cannot silence admin");
-	}
-
-	await Users.update(user.id, {
-		isSilenced: true,
-	});
-
-	publishInternalEvent("userChangeSilencedState", {
-		id: user.id,
-		isSilenced: true,
-	});
-
-	insertModerationLog(me, "silence", {
-		targetId: user.id,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/suspend-user.ts b/packages/backend/src/server/api/endpoints/admin/suspend-user.ts
deleted file mode 100644
index 984bc0789e..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/suspend-user.ts
+++ /dev/null
@@ -1,87 +0,0 @@
-import define from "../../define.js";
-import deleteFollowing from "@/services/following/delete.js";
-import { Users, Followings, Notifications } from "@/models/index.js";
-import type { User } from "@/models/entities/user.js";
-import { insertModerationLog } from "@/services/insert-moderation-log.js";
-import { doPostSuspend } from "@/services/suspend-user.js";
-import { publishUserEvent } from "@/services/stream.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		userId: { type: "string", format: "misskey:id" },
-	},
-	required: ["userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const user = await Users.findOneBy({ id: ps.userId });
-
-	if (user == null) {
-		throw new Error("user not found");
-	}
-
-	if (user.isAdmin) {
-		throw new Error("cannot suspend admin");
-	}
-
-	if (user.isModerator) {
-		throw new Error("cannot suspend moderator");
-	}
-
-	await Users.update(user.id, {
-		isSuspended: true,
-	});
-
-	insertModerationLog(me, "suspend", {
-		targetId: user.id,
-	});
-
-	// Terminate streaming
-	if (Users.isLocalUser(user)) {
-		publishUserEvent(user.id, "terminate", {});
-	}
-
-	(async () => {
-		await doPostSuspend(user).catch((e) => {});
-		await unFollowAll(user).catch((e) => {});
-		await readAllNotify(user).catch((e) => {});
-	})();
-});
-
-async function unFollowAll(follower: User) {
-	const followings = await Followings.findBy({
-		followerId: follower.id,
-	});
-
-	for (const following of followings) {
-		const followee = await Users.findOneBy({
-			id: following.followeeId,
-		});
-
-		if (followee == null) {
-			throw new Error(`Cant find followee ${following.followeeId}`);
-		}
-
-		await deleteFollowing(follower, followee, true);
-	}
-}
-
-async function readAllNotify(notifier: User) {
-	await Notifications.update(
-		{
-			notifierId: notifier.id,
-			isRead: false,
-		},
-		{
-			isRead: true,
-		},
-	);
-}
diff --git a/packages/backend/src/server/api/endpoints/admin/unsilence-user.ts b/packages/backend/src/server/api/endpoints/admin/unsilence-user.ts
deleted file mode 100644
index 6a01b8e8d3..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/unsilence-user.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import define from "../../define.js";
-import { Users } from "@/models/index.js";
-import { insertModerationLog } from "@/services/insert-moderation-log.js";
-import { publishInternalEvent } from "@/services/stream.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		userId: { type: "string", format: "misskey:id" },
-	},
-	required: ["userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const user = await Users.findOneBy({ id: ps.userId });
-
-	if (user == null) {
-		throw new Error("user not found");
-	}
-
-	await Users.update(user.id, {
-		isSilenced: false,
-	});
-
-	publishInternalEvent("userChangeSilencedState", {
-		id: user.id,
-		isSilenced: false,
-	});
-
-	insertModerationLog(me, "unsilence", {
-		targetId: user.id,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/unsuspend-user.ts b/packages/backend/src/server/api/endpoints/admin/unsuspend-user.ts
deleted file mode 100644
index e51d5851c2..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/unsuspend-user.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import define from "../../define.js";
-import { Users } from "@/models/index.js";
-import { insertModerationLog } from "@/services/insert-moderation-log.js";
-import { doPostUnsuspend } from "@/services/unsuspend-user.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		userId: { type: "string", format: "misskey:id" },
-	},
-	required: ["userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const user = await Users.findOneBy({ id: ps.userId });
-
-	if (user == null) {
-		throw new Error("user not found");
-	}
-
-	await Users.update(user.id, {
-		isSuspended: false,
-	});
-
-	insertModerationLog(me, "unsuspend", {
-		targetId: user.id,
-	});
-
-	doPostUnsuspend(user);
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/update-meta.ts b/packages/backend/src/server/api/endpoints/admin/update-meta.ts
deleted file mode 100644
index f7e79b64b5..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/update-meta.ts
+++ /dev/null
@@ -1,543 +0,0 @@
-import { Meta } from "@/models/entities/meta.js";
-import { insertModerationLog } from "@/services/insert-moderation-log.js";
-import { DB_MAX_NOTE_TEXT_LENGTH } from "@/misc/hard-limits.js";
-import { db } from "@/db/postgre.js";
-import define from "../../define.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireAdmin: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		disableRegistration: { type: "boolean", nullable: true },
-		disableLocalTimeline: { type: "boolean", nullable: true },
-		disableRecommendedTimeline: { type: "boolean", nullable: true },
-		disableGlobalTimeline: { type: "boolean", nullable: true },
-		defaultReaction: { type: "string", nullable: true },
-		recommendedInstances: {
-			type: "array",
-			nullable: true,
-			items: {
-				type: "string",
-			},
-		},
-		pinnedUsers: {
-			type: "array",
-			nullable: true,
-			items: {
-				type: "string",
-			},
-		},
-		customMOTD: {
-			type: "array",
-			nullable: true,
-			items: {
-				type: "string",
-			},
-		},
-		customSplashIcons: {
-			type: "array",
-			nullable: true,
-			items: {
-				type: "string",
-			},
-		},
-		hiddenTags: {
-			type: "array",
-			nullable: true,
-			items: {
-				type: "string",
-			},
-		},
-		blockedHosts: {
-			type: "array",
-			nullable: true,
-			items: {
-				type: "string",
-			},
-		},
-		allowedHosts: {
-			type: "array",
-			nullable: true,
-			items: {
-				type: "string",
-			},
-		},
-		secureMode: { type: "boolean", nullable: true },
-		privateMode: { type: "boolean", nullable: true },
-		themeColor: {
-			type: "string",
-			nullable: true,
-			pattern: "^#[0-9a-fA-F]{6}$",
-		},
-		mascotImageUrl: { type: "string", nullable: true },
-		bannerUrl: { type: "string", nullable: true },
-		logoImageUrl: { type: "string", nullable: true },
-		errorImageUrl: { type: "string", nullable: true },
-		iconUrl: { type: "string", nullable: true },
-		backgroundImageUrl: { type: "string", nullable: true },
-		name: { type: "string", nullable: true },
-		description: { type: "string", nullable: true },
-		defaultLightTheme: { type: "string", nullable: true },
-		defaultDarkTheme: { type: "string", nullable: true },
-		localDriveCapacityMb: { type: "integer" },
-		remoteDriveCapacityMb: { type: "integer" },
-		cacheRemoteFiles: { type: "boolean" },
-		emailRequiredForSignup: { type: "boolean" },
-		enableHcaptcha: { type: "boolean" },
-		hcaptchaSiteKey: { type: "string", nullable: true },
-		hcaptchaSecretKey: { type: "string", nullable: true },
-		enableRecaptcha: { type: "boolean" },
-		recaptchaSiteKey: { type: "string", nullable: true },
-		recaptchaSecretKey: { type: "string", nullable: true },
-		sensitiveMediaDetection: {
-			type: "string",
-			enum: ["none", "all", "local", "remote"],
-		},
-		sensitiveMediaDetectionSensitivity: {
-			type: "string",
-			enum: ["medium", "low", "high", "veryLow", "veryHigh"],
-		},
-		setSensitiveFlagAutomatically: { type: "boolean" },
-		enableSensitiveMediaDetectionForVideos: { type: "boolean" },
-		proxyAccountId: { type: "string", format: "misskey:id", nullable: true },
-		maintainerName: { type: "string", nullable: true },
-		maintainerEmail: { type: "string", nullable: true },
-		pinnedPages: {
-			type: "array",
-			items: {
-				type: "string",
-			},
-		},
-		pinnedClipId: { type: "string", format: "misskey:id", nullable: true },
-		langs: {
-			type: "array",
-			items: {
-				type: "string",
-			},
-		},
-		summalyProxy: { type: "string", nullable: true },
-		deeplAuthKey: { type: "string", nullable: true },
-		deeplIsPro: { type: "boolean" },
-		enableTwitterIntegration: { type: "boolean" },
-		twitterConsumerKey: { type: "string", nullable: true },
-		twitterConsumerSecret: { type: "string", nullable: true },
-		enableGithubIntegration: { type: "boolean" },
-		githubClientId: { type: "string", nullable: true },
-		githubClientSecret: { type: "string", nullable: true },
-		enableDiscordIntegration: { type: "boolean" },
-		discordClientId: { type: "string", nullable: true },
-		discordClientSecret: { type: "string", nullable: true },
-		enableEmail: { type: "boolean" },
-		email: { type: "string", nullable: true },
-		smtpSecure: { type: "boolean" },
-		smtpHost: { type: "string", nullable: true },
-		smtpPort: { type: "integer", nullable: true },
-		smtpUser: { type: "string", nullable: true },
-		smtpPass: { type: "string", nullable: true },
-		enableServiceWorker: { type: "boolean" },
-		swPublicKey: { type: "string", nullable: true },
-		swPrivateKey: { type: "string", nullable: true },
-		tosUrl: { type: "string", nullable: true },
-		repositoryUrl: { type: "string" },
-		feedbackUrl: { type: "string" },
-		useObjectStorage: { type: "boolean" },
-		objectStorageBaseUrl: { type: "string", nullable: true },
-		objectStorageBucket: { type: "string", nullable: true },
-		objectStoragePrefix: { type: "string", nullable: true },
-		objectStorageEndpoint: { type: "string", nullable: true },
-		objectStorageRegion: { type: "string", nullable: true },
-		objectStoragePort: { type: "integer", nullable: true },
-		objectStorageAccessKey: { type: "string", nullable: true },
-		objectStorageSecretKey: { type: "string", nullable: true },
-		objectStorageUseSSL: { type: "boolean" },
-		objectStorageUseProxy: { type: "boolean" },
-		objectStorageSetPublicRead: { type: "boolean" },
-		objectStorageS3ForcePathStyle: { type: "boolean" },
-		enableIpLogging: { type: "boolean" },
-		enableActiveEmailValidation: { type: "boolean" },
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const set = {} as Partial<Meta>;
-
-	if (typeof ps.disableRegistration === "boolean") {
-		set.disableRegistration = ps.disableRegistration;
-	}
-
-	if (typeof ps.disableLocalTimeline === "boolean") {
-		set.disableLocalTimeline = ps.disableLocalTimeline;
-	}
-
-	if (typeof ps.disableRecommendedTimeline === "boolean") {
-		set.disableRecommendedTimeline = ps.disableRecommendedTimeline;
-	}
-
-	if (typeof ps.disableGlobalTimeline === "boolean") {
-		set.disableGlobalTimeline = ps.disableGlobalTimeline;
-	}
-
-	if (typeof ps.defaultReaction === "string") {
-		set.defaultReaction = ps.defaultReaction;
-	}
-
-	if (Array.isArray(ps.pinnedUsers)) {
-		set.pinnedUsers = ps.pinnedUsers.filter(Boolean);
-	}
-
-	if (Array.isArray(ps.customMOTD)) {
-		set.customMOTD = ps.customMOTD.filter(Boolean);
-	}
-
-	if (Array.isArray(ps.customSplashIcons)) {
-		set.customSplashIcons = ps.customSplashIcons.filter(Boolean);
-	}
-
-	if (Array.isArray(ps.recommendedInstances)) {
-		set.recommendedInstances = ps.recommendedInstances.filter(Boolean);
-	}
-
-	if (Array.isArray(ps.hiddenTags)) {
-		set.hiddenTags = ps.hiddenTags.filter(Boolean);
-	}
-
-	if (Array.isArray(ps.blockedHosts)) {
-		let lastValue = "";
-		set.blockedHosts = ps.blockedHosts.sort().filter((h) => {
-			const lv = lastValue;
-			lastValue = h;
-			return h !== "" && h !== lv;
-		});
-	}
-
-	if (ps.themeColor !== undefined) {
-		set.themeColor = ps.themeColor;
-	}
-
-	if (Array.isArray(ps.allowedHosts)) {
-		set.allowedHosts = ps.allowedHosts.filter(Boolean);
-	}
-
-	if (typeof ps.privateMode === "boolean") {
-		set.privateMode = ps.privateMode;
-	}
-
-	if (typeof ps.secureMode === "boolean") {
-		set.secureMode = ps.secureMode;
-	}
-
-	if (ps.mascotImageUrl !== undefined) {
-		set.mascotImageUrl = ps.mascotImageUrl;
-	}
-
-	if (ps.bannerUrl !== undefined) {
-		set.bannerUrl = ps.bannerUrl;
-	}
-
-	if (ps.logoImageUrl !== undefined) {
-		set.logoImageUrl = ps.logoImageUrl;
-	}
-
-	if (ps.iconUrl !== undefined) {
-		set.iconUrl = ps.iconUrl;
-	}
-
-	if (ps.backgroundImageUrl !== undefined) {
-		set.backgroundImageUrl = ps.backgroundImageUrl;
-	}
-
-	if (ps.logoImageUrl !== undefined) {
-		set.logoImageUrl = ps.logoImageUrl;
-	}
-
-	if (ps.name !== undefined) {
-		set.name = ps.name;
-	}
-
-	if (ps.description !== undefined) {
-		set.description = ps.description;
-	}
-
-	if (ps.defaultLightTheme !== undefined) {
-		set.defaultLightTheme = ps.defaultLightTheme;
-	}
-
-	if (ps.defaultDarkTheme !== undefined) {
-		set.defaultDarkTheme = ps.defaultDarkTheme;
-	}
-
-	if (ps.localDriveCapacityMb !== undefined) {
-		set.localDriveCapacityMb = ps.localDriveCapacityMb;
-	}
-
-	if (ps.remoteDriveCapacityMb !== undefined) {
-		set.remoteDriveCapacityMb = ps.remoteDriveCapacityMb;
-	}
-
-	if (ps.cacheRemoteFiles !== undefined) {
-		set.cacheRemoteFiles = ps.cacheRemoteFiles;
-	}
-
-	if (ps.emailRequiredForSignup !== undefined) {
-		set.emailRequiredForSignup = ps.emailRequiredForSignup;
-	}
-
-	if (ps.enableHcaptcha !== undefined) {
-		set.enableHcaptcha = ps.enableHcaptcha;
-	}
-
-	if (ps.hcaptchaSiteKey !== undefined) {
-		set.hcaptchaSiteKey = ps.hcaptchaSiteKey;
-	}
-
-	if (ps.hcaptchaSecretKey !== undefined) {
-		set.hcaptchaSecretKey = ps.hcaptchaSecretKey;
-	}
-
-	if (ps.enableRecaptcha !== undefined) {
-		set.enableRecaptcha = ps.enableRecaptcha;
-	}
-
-	if (ps.recaptchaSiteKey !== undefined) {
-		set.recaptchaSiteKey = ps.recaptchaSiteKey;
-	}
-
-	if (ps.recaptchaSecretKey !== undefined) {
-		set.recaptchaSecretKey = ps.recaptchaSecretKey;
-	}
-
-	if (ps.sensitiveMediaDetection !== undefined) {
-		set.sensitiveMediaDetection = ps.sensitiveMediaDetection;
-	}
-
-	if (ps.sensitiveMediaDetectionSensitivity !== undefined) {
-		set.sensitiveMediaDetectionSensitivity =
-			ps.sensitiveMediaDetectionSensitivity;
-	}
-
-	if (ps.setSensitiveFlagAutomatically !== undefined) {
-		set.setSensitiveFlagAutomatically = ps.setSensitiveFlagAutomatically;
-	}
-
-	if (ps.enableSensitiveMediaDetectionForVideos !== undefined) {
-		set.enableSensitiveMediaDetectionForVideos =
-			ps.enableSensitiveMediaDetectionForVideos;
-	}
-
-	if (ps.proxyAccountId !== undefined) {
-		set.proxyAccountId = ps.proxyAccountId;
-	}
-
-	if (ps.maintainerName !== undefined) {
-		set.maintainerName = ps.maintainerName;
-	}
-
-	if (ps.maintainerEmail !== undefined) {
-		set.maintainerEmail = ps.maintainerEmail;
-	}
-
-	if (Array.isArray(ps.langs)) {
-		set.langs = ps.langs.filter(Boolean);
-	}
-
-	if (Array.isArray(ps.pinnedPages)) {
-		set.pinnedPages = ps.pinnedPages.filter(Boolean);
-	}
-
-	if (ps.pinnedClipId !== undefined) {
-		set.pinnedClipId = ps.pinnedClipId;
-	}
-
-	if (ps.summalyProxy !== undefined) {
-		set.summalyProxy = ps.summalyProxy;
-	}
-
-	if (ps.enableTwitterIntegration !== undefined) {
-		set.enableTwitterIntegration = ps.enableTwitterIntegration;
-	}
-
-	if (ps.twitterConsumerKey !== undefined) {
-		set.twitterConsumerKey = ps.twitterConsumerKey;
-	}
-
-	if (ps.twitterConsumerSecret !== undefined) {
-		set.twitterConsumerSecret = ps.twitterConsumerSecret;
-	}
-
-	if (ps.enableGithubIntegration !== undefined) {
-		set.enableGithubIntegration = ps.enableGithubIntegration;
-	}
-
-	if (ps.githubClientId !== undefined) {
-		set.githubClientId = ps.githubClientId;
-	}
-
-	if (ps.githubClientSecret !== undefined) {
-		set.githubClientSecret = ps.githubClientSecret;
-	}
-
-	if (ps.enableDiscordIntegration !== undefined) {
-		set.enableDiscordIntegration = ps.enableDiscordIntegration;
-	}
-
-	if (ps.discordClientId !== undefined) {
-		set.discordClientId = ps.discordClientId;
-	}
-
-	if (ps.discordClientSecret !== undefined) {
-		set.discordClientSecret = ps.discordClientSecret;
-	}
-
-	if (ps.enableEmail !== undefined) {
-		set.enableEmail = ps.enableEmail;
-	}
-
-	if (ps.email !== undefined) {
-		set.email = ps.email;
-	}
-
-	if (ps.smtpSecure !== undefined) {
-		set.smtpSecure = ps.smtpSecure;
-	}
-
-	if (ps.smtpHost !== undefined) {
-		set.smtpHost = ps.smtpHost;
-	}
-
-	if (ps.smtpPort !== undefined) {
-		set.smtpPort = ps.smtpPort;
-	}
-
-	if (ps.smtpUser !== undefined) {
-		set.smtpUser = ps.smtpUser;
-	}
-
-	if (ps.smtpPass !== undefined) {
-		set.smtpPass = ps.smtpPass;
-	}
-
-	if (ps.errorImageUrl !== undefined) {
-		set.errorImageUrl = ps.errorImageUrl;
-	}
-
-	if (ps.enableServiceWorker !== undefined) {
-		set.enableServiceWorker = ps.enableServiceWorker;
-	}
-
-	if (ps.swPublicKey !== undefined) {
-		set.swPublicKey = ps.swPublicKey;
-	}
-
-	if (ps.swPrivateKey !== undefined) {
-		set.swPrivateKey = ps.swPrivateKey;
-	}
-
-	if (ps.tosUrl !== undefined) {
-		set.ToSUrl = ps.tosUrl;
-	}
-
-	if (ps.repositoryUrl !== undefined) {
-		set.repositoryUrl = ps.repositoryUrl;
-	}
-
-	if (ps.feedbackUrl !== undefined) {
-		set.feedbackUrl = ps.feedbackUrl;
-	}
-
-	if (ps.useObjectStorage !== undefined) {
-		set.useObjectStorage = ps.useObjectStorage;
-	}
-
-	if (ps.objectStorageBaseUrl !== undefined) {
-		set.objectStorageBaseUrl = ps.objectStorageBaseUrl;
-	}
-
-	if (ps.objectStorageBucket !== undefined) {
-		set.objectStorageBucket = ps.objectStorageBucket;
-	}
-
-	if (ps.objectStoragePrefix !== undefined) {
-		set.objectStoragePrefix = ps.objectStoragePrefix;
-	}
-
-	if (ps.objectStorageEndpoint !== undefined) {
-		set.objectStorageEndpoint = ps.objectStorageEndpoint;
-	}
-
-	if (ps.objectStorageRegion !== undefined) {
-		set.objectStorageRegion = ps.objectStorageRegion;
-	}
-
-	if (ps.objectStoragePort !== undefined) {
-		set.objectStoragePort = ps.objectStoragePort;
-	}
-
-	if (ps.objectStorageAccessKey !== undefined) {
-		set.objectStorageAccessKey = ps.objectStorageAccessKey;
-	}
-
-	if (ps.objectStorageSecretKey !== undefined) {
-		set.objectStorageSecretKey = ps.objectStorageSecretKey;
-	}
-
-	if (ps.objectStorageUseSSL !== undefined) {
-		set.objectStorageUseSSL = ps.objectStorageUseSSL;
-	}
-
-	if (ps.objectStorageUseProxy !== undefined) {
-		set.objectStorageUseProxy = ps.objectStorageUseProxy;
-	}
-
-	if (ps.objectStorageSetPublicRead !== undefined) {
-		set.objectStorageSetPublicRead = ps.objectStorageSetPublicRead;
-	}
-
-	if (ps.objectStorageS3ForcePathStyle !== undefined) {
-		set.objectStorageS3ForcePathStyle = ps.objectStorageS3ForcePathStyle;
-	}
-
-	if (ps.deeplAuthKey !== undefined) {
-		if (ps.deeplAuthKey === "") {
-			set.deeplAuthKey = null;
-		} else {
-			set.deeplAuthKey = ps.deeplAuthKey;
-		}
-	}
-
-	if (ps.deeplIsPro !== undefined) {
-		set.deeplIsPro = ps.deeplIsPro;
-	}
-
-	if (ps.enableIpLogging !== undefined) {
-		set.enableIpLogging = ps.enableIpLogging;
-	}
-
-	if (ps.enableActiveEmailValidation !== undefined) {
-		set.enableActiveEmailValidation = ps.enableActiveEmailValidation;
-	}
-
-	await db.transaction(async (transactionalEntityManager) => {
-		const metas = await transactionalEntityManager.find(Meta, {
-			order: {
-				id: "DESC",
-			},
-		});
-
-		const meta = metas[0];
-
-		if (meta) {
-			await transactionalEntityManager.update(Meta, meta.id, set);
-		} else {
-			await transactionalEntityManager.save(Meta, set);
-		}
-	});
-
-	insertModerationLog(me, "updateMeta");
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/update-user-note.ts b/packages/backend/src/server/api/endpoints/admin/update-user-note.ts
deleted file mode 100644
index 04870d1c1c..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/update-user-note.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import { UserProfiles, Users } from "@/models/index.js";
-import define from "../../define.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		userId: { type: "string", format: "misskey:id" },
-		text: { type: "string" },
-	},
-	required: ["userId", "text"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const user = await Users.findOneBy({ id: ps.userId });
-
-	if (user == null) {
-		throw new Error("user not found");
-	}
-
-	await UserProfiles.update(
-		{ userId: user.id },
-		{
-			moderationNote: ps.text,
-		},
-	);
-});
diff --git a/packages/backend/src/server/api/endpoints/admin/vacuum.ts b/packages/backend/src/server/api/endpoints/admin/vacuum.ts
deleted file mode 100644
index 559b310e46..0000000000
--- a/packages/backend/src/server/api/endpoints/admin/vacuum.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import define from "../../define.js";
-import { insertModerationLog } from "@/services/insert-moderation-log.js";
-import { db } from "@/db/postgre.js";
-
-export const meta = {
-	tags: ["admin"],
-
-	requireCredential: true,
-	requireModerator: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		full: { type: "boolean" },
-		analyze: { type: "boolean" },
-	},
-	required: ["full", "analyze"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const params: string[] = [];
-
-	if (ps.full) {
-		params.push("FULL");
-	}
-
-	if (ps.analyze) {
-		params.push("ANALYZE");
-	}
-
-	db.query(`VACUUM ${params.join(" ")}`);
-
-	insertModerationLog(me, "vacuum", ps);
-});
diff --git a/packages/backend/src/server/api/endpoints/announcements.ts b/packages/backend/src/server/api/endpoints/announcements.ts
deleted file mode 100644
index 00634cc421..0000000000
--- a/packages/backend/src/server/api/endpoints/announcements.ts
+++ /dev/null
@@ -1,103 +0,0 @@
-import { Announcements, AnnouncementReads } from "@/models/index.js";
-import define from "../define.js";
-import { makePaginationQuery } from "../common/make-pagination-query.js";
-
-export const meta = {
-	tags: ["meta"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			properties: {
-				id: {
-					type: "string",
-					optional: false,
-					nullable: false,
-					format: "id",
-					example: "xxxxxxxxxx",
-				},
-				createdAt: {
-					type: "string",
-					optional: false,
-					nullable: false,
-					format: "date-time",
-				},
-				updatedAt: {
-					type: "string",
-					optional: false,
-					nullable: true,
-					format: "date-time",
-				},
-				text: {
-					type: "string",
-					optional: false,
-					nullable: false,
-				},
-				title: {
-					type: "string",
-					optional: false,
-					nullable: false,
-				},
-				imageUrl: {
-					type: "string",
-					optional: false,
-					nullable: true,
-				},
-				isRead: {
-					type: "boolean",
-					optional: true,
-					nullable: false,
-				},
-			},
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		withUnreads: { type: "boolean", default: false },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const query = makePaginationQuery(
-		Announcements.createQueryBuilder("announcement"),
-		ps.sinceId,
-		ps.untilId,
-	);
-
-	const announcements = await query.take(ps.limit).getMany();
-
-	if (user) {
-		const reads = (
-			await AnnouncementReads.findBy({
-				userId: user.id,
-			})
-		).map((x) => x.announcementId);
-
-		for (const announcement of announcements) {
-			(announcement as any).isRead = reads.includes(announcement.id);
-		}
-	}
-
-	return (
-		ps.withUnreads ? announcements.filter((a: any) => !a.isRead) : announcements
-	).map((a) => ({
-		...a,
-		createdAt: a.createdAt.toISOString(),
-		updatedAt: a.updatedAt?.toISOString() ?? null,
-	}));
-});
diff --git a/packages/backend/src/server/api/endpoints/antennas/create.ts b/packages/backend/src/server/api/endpoints/antennas/create.ts
deleted file mode 100644
index c1ba7bcdfd..0000000000
--- a/packages/backend/src/server/api/endpoints/antennas/create.ts
+++ /dev/null
@@ -1,141 +0,0 @@
-import define from "../../define.js";
-import { genId } from "@/misc/gen-id.js";
-import { Antennas, UserLists, UserGroupJoinings } from "@/models/index.js";
-import { ApiError } from "../../error.js";
-import { publishInternalEvent } from "@/services/stream.js";
-
-export const meta = {
-	tags: ["antennas"],
-
-	requireCredential: true,
-
-	kind: "write:account",
-
-	errors: {
-		noSuchUserList: {
-			message: "No such user list.",
-			code: "NO_SUCH_USER_LIST",
-			id: "95063e93-a283-4b8b-9aa5-bcdb8df69a7f",
-		},
-
-		noSuchUserGroup: {
-			message: "No such user group.",
-			code: "NO_SUCH_USER_GROUP",
-			id: "aa3c0b9a-8cae-47c0-92ac-202ce5906682",
-		},
-	},
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "Antenna",
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		name: { type: "string", minLength: 1, maxLength: 100 },
-		src: {
-			type: "string",
-			enum: ["home", "all", "users", "list", "group", "instances"],
-		},
-		userListId: { type: "string", format: "misskey:id", nullable: true },
-		userGroupId: { type: "string", format: "misskey:id", nullable: true },
-		keywords: {
-			type: "array",
-			items: {
-				type: "array",
-				items: {
-					type: "string",
-				},
-			},
-		},
-		excludeKeywords: {
-			type: "array",
-			items: {
-				type: "array",
-				items: {
-					type: "string",
-				},
-			},
-		},
-		users: {
-			type: "array",
-			items: {
-				type: "string",
-			},
-		},
-		instances: {
-			type: "array",
-			items: {
-				type: "string",
-			},
-		},
-		caseSensitive: { type: "boolean" },
-		withReplies: { type: "boolean" },
-		withFile: { type: "boolean" },
-		notify: { type: "boolean" },
-	},
-	required: [
-		"name",
-		"src",
-		"keywords",
-		"excludeKeywords",
-		"users",
-		"instances",
-		"caseSensitive",
-		"withReplies",
-		"withFile",
-		"notify",
-	],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	if (user.movedToUri != null) throw new ApiError(meta.errors.noSuchUserGroup);
-	let userList;
-	let userGroupJoining;
-
-	if (ps.src === "list" && ps.userListId) {
-		userList = await UserLists.findOneBy({
-			id: ps.userListId,
-			userId: user.id,
-		});
-
-		if (userList == null) {
-			throw new ApiError(meta.errors.noSuchUserList);
-		}
-	} else if (ps.src === "group" && ps.userGroupId) {
-		userGroupJoining = await UserGroupJoinings.findOneBy({
-			userGroupId: ps.userGroupId,
-			userId: user.id,
-		});
-
-		if (userGroupJoining == null) {
-			throw new ApiError(meta.errors.noSuchUserGroup);
-		}
-	}
-
-	const antenna = await Antennas.insert({
-		id: genId(),
-		createdAt: new Date(),
-		userId: user.id,
-		name: ps.name,
-		src: ps.src,
-		userListId: userList ? userList.id : null,
-		userGroupJoiningId: userGroupJoining ? userGroupJoining.id : null,
-		keywords: ps.keywords,
-		excludeKeywords: ps.excludeKeywords,
-		users: ps.users,
-		instances: ps.instances,
-		caseSensitive: ps.caseSensitive,
-		withReplies: ps.withReplies,
-		withFile: ps.withFile,
-		notify: ps.notify,
-	}).then((x) => Antennas.findOneByOrFail(x.identifiers[0]));
-
-	publishInternalEvent("antennaCreated", antenna);
-
-	return await Antennas.pack(antenna);
-});
diff --git a/packages/backend/src/server/api/endpoints/antennas/delete.ts b/packages/backend/src/server/api/endpoints/antennas/delete.ts
deleted file mode 100644
index a6cf79011a..0000000000
--- a/packages/backend/src/server/api/endpoints/antennas/delete.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { Antennas } from "@/models/index.js";
-import { publishInternalEvent } from "@/services/stream.js";
-
-export const meta = {
-	tags: ["antennas"],
-
-	requireCredential: true,
-
-	kind: "write:account",
-
-	errors: {
-		noSuchAntenna: {
-			message: "No such antenna.",
-			code: "NO_SUCH_ANTENNA",
-			id: "b34dcf9d-348f-44bb-99d0-6c9314cfe2df",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		antennaId: { type: "string", format: "misskey:id" },
-	},
-	required: ["antennaId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const antenna = await Antennas.findOneBy({
-		id: ps.antennaId,
-		userId: user.id,
-	});
-
-	if (antenna == null) {
-		throw new ApiError(meta.errors.noSuchAntenna);
-	}
-
-	await Antennas.delete(antenna.id);
-
-	publishInternalEvent("antennaDeleted", antenna);
-});
diff --git a/packages/backend/src/server/api/endpoints/antennas/list.ts b/packages/backend/src/server/api/endpoints/antennas/list.ts
deleted file mode 100644
index 929b761d4f..0000000000
--- a/packages/backend/src/server/api/endpoints/antennas/list.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import define from "../../define.js";
-import { Antennas } from "@/models/index.js";
-
-export const meta = {
-	tags: ["antennas", "account"],
-
-	requireCredential: true,
-
-	kind: "read:account",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Antenna",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const antennas = await Antennas.findBy({
-		userId: me.id,
-	});
-
-	return await Promise.all(antennas.map((x) => Antennas.pack(x)));
-});
diff --git a/packages/backend/src/server/api/endpoints/antennas/markread.ts b/packages/backend/src/server/api/endpoints/antennas/markread.ts
deleted file mode 100644
index e29e13bbbb..0000000000
--- a/packages/backend/src/server/api/endpoints/antennas/markread.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import define from "../../define.js";
-import { Antennas, AntennaNotes } from "@/models/index.js";
-import { FindOptionsWhere } from "typeorm";
-import { AntennaNote } from "@/models/entities/antenna-note.js";
-
-export const meta = {
-	tags: ["antennas", "account"],
-
-	requireCredential: true,
-
-	kind: "write:account",
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		antennaId: { type: "string", format: "misskey:id" },
-	},
-	required: ["antennaId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const antenna = await Antennas.findOneBy({
-		userId: me.id,
-		id: ps.antennaId,
-	});
-
-	if (!antenna) {
-		return null;
-	}
-
-	await AntennaNotes.update(
-		{
-			antennaId: antenna.id,
-			read: false,
-		},
-		{
-			read: true,
-		},
-	);
-
-	return true;
-});
diff --git a/packages/backend/src/server/api/endpoints/antennas/notes.ts b/packages/backend/src/server/api/endpoints/antennas/notes.ts
deleted file mode 100644
index d011c5fb80..0000000000
--- a/packages/backend/src/server/api/endpoints/antennas/notes.ts
+++ /dev/null
@@ -1,97 +0,0 @@
-import define from "../../define.js";
-import readNote from "@/services/note/read.js";
-import { Antennas, Notes, AntennaNotes } from "@/models/index.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-import { generateVisibilityQuery } from "../../common/generate-visibility-query.js";
-import { generateMutedUserQuery } from "../../common/generate-muted-user-query.js";
-import { ApiError } from "../../error.js";
-import { generateBlockedUserQuery } from "../../common/generate-block-query.js";
-
-export const meta = {
-	tags: ["antennas", "account", "notes"],
-
-	requireCredential: true,
-
-	kind: "read:account",
-
-	errors: {
-		noSuchAntenna: {
-			message: "No such antenna.",
-			code: "NO_SUCH_ANTENNA",
-			id: "850926e0-fd3b-49b6-b69a-b28a5dbd82fe",
-		},
-	},
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Note",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		antennaId: { type: "string", format: "misskey:id" },
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-		sinceDate: { type: "integer" },
-		untilDate: { type: "integer" },
-	},
-	required: ["antennaId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const antenna = await Antennas.findOneBy({
-		id: ps.antennaId,
-		userId: user.id,
-	});
-
-	if (antenna == null) {
-		throw new ApiError(meta.errors.noSuchAntenna);
-	}
-
-	const query = makePaginationQuery(
-		Notes.createQueryBuilder("note"),
-		ps.sinceId,
-		ps.untilId,
-		ps.sinceDate,
-		ps.untilDate,
-	)
-		.innerJoin(
-			AntennaNotes.metadata.targetName,
-			"antennaNote",
-			"antennaNote.noteId = note.id",
-		)
-		.innerJoinAndSelect("note.user", "user")
-		.leftJoinAndSelect("user.avatar", "avatar")
-		.leftJoinAndSelect("user.banner", "banner")
-		.leftJoinAndSelect("note.reply", "reply")
-		.leftJoinAndSelect("note.renote", "renote")
-		.leftJoinAndSelect("reply.user", "replyUser")
-		.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
-		.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
-		.leftJoinAndSelect("renote.user", "renoteUser")
-		.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
-		.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner")
-		.andWhere("antennaNote.antennaId = :antennaId", { antennaId: antenna.id });
-
-	generateVisibilityQuery(query, user);
-	generateMutedUserQuery(query, user);
-	generateBlockedUserQuery(query, user);
-
-	const notes = await query.take(ps.limit).getMany();
-
-	if (notes.length > 0) {
-		readNote(user.id, notes);
-	}
-
-	return await Notes.packMany(notes, user);
-});
diff --git a/packages/backend/src/server/api/endpoints/antennas/show.ts b/packages/backend/src/server/api/endpoints/antennas/show.ts
deleted file mode 100644
index 350d739216..0000000000
--- a/packages/backend/src/server/api/endpoints/antennas/show.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { Antennas } from "@/models/index.js";
-
-export const meta = {
-	tags: ["antennas", "account"],
-
-	requireCredential: true,
-
-	kind: "read:account",
-
-	errors: {
-		noSuchAntenna: {
-			message: "No such antenna.",
-			code: "NO_SUCH_ANTENNA",
-			id: "c06569fb-b025-4f23-b22d-1fcd20d2816b",
-		},
-	},
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "Antenna",
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		antennaId: { type: "string", format: "misskey:id" },
-	},
-	required: ["antennaId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	// Fetch the antenna
-	const antenna = await Antennas.findOneBy({
-		id: ps.antennaId,
-		userId: me.id,
-	});
-
-	if (antenna == null) {
-		throw new ApiError(meta.errors.noSuchAntenna);
-	}
-
-	return await Antennas.pack(antenna);
-});
diff --git a/packages/backend/src/server/api/endpoints/antennas/update.ts b/packages/backend/src/server/api/endpoints/antennas/update.ts
deleted file mode 100644
index f491c0b638..0000000000
--- a/packages/backend/src/server/api/endpoints/antennas/update.ts
+++ /dev/null
@@ -1,157 +0,0 @@
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { Antennas, UserLists, UserGroupJoinings } from "@/models/index.js";
-import { publishInternalEvent } from "@/services/stream.js";
-
-export const meta = {
-	tags: ["antennas"],
-
-	requireCredential: true,
-
-	kind: "write:account",
-
-	errors: {
-		noSuchAntenna: {
-			message: "No such antenna.",
-			code: "NO_SUCH_ANTENNA",
-			id: "10c673ac-8852-48eb-aa1f-f5b67f069290",
-		},
-
-		noSuchUserList: {
-			message: "No such user list.",
-			code: "NO_SUCH_USER_LIST",
-			id: "1c6b35c9-943e-48c2-81e4-2844989407f7",
-		},
-
-		noSuchUserGroup: {
-			message: "No such user group.",
-			code: "NO_SUCH_USER_GROUP",
-			id: "109ed789-b6eb-456e-b8a9-6059d567d385",
-		},
-	},
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "Antenna",
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		antennaId: { type: "string", format: "misskey:id" },
-		name: { type: "string", minLength: 1, maxLength: 100 },
-		src: {
-			type: "string",
-			enum: ["home", "all", "users", "list", "group", "instances"],
-		},
-		userListId: { type: "string", format: "misskey:id", nullable: true },
-		userGroupId: { type: "string", format: "misskey:id", nullable: true },
-		keywords: {
-			type: "array",
-			items: {
-				type: "array",
-				items: {
-					type: "string",
-				},
-			},
-		},
-		excludeKeywords: {
-			type: "array",
-			items: {
-				type: "array",
-				items: {
-					type: "string",
-				},
-			},
-		},
-		users: {
-			type: "array",
-			items: {
-				type: "string",
-			},
-		},
-		instances: {
-			type: "array",
-			items: {
-				type: "string",
-			},
-		},
-		caseSensitive: { type: "boolean" },
-		withReplies: { type: "boolean" },
-		withFile: { type: "boolean" },
-		notify: { type: "boolean" },
-	},
-	required: [
-		"antennaId",
-		"name",
-		"src",
-		"keywords",
-		"excludeKeywords",
-		"users",
-		"instances",
-		"caseSensitive",
-		"withReplies",
-		"withFile",
-		"notify",
-	],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	// Fetch the antenna
-	const antenna = await Antennas.findOneBy({
-		id: ps.antennaId,
-		userId: user.id,
-	});
-
-	if (antenna == null) {
-		throw new ApiError(meta.errors.noSuchAntenna);
-	}
-
-	let userList;
-	let userGroupJoining;
-
-	if (ps.src === "list" && ps.userListId) {
-		userList = await UserLists.findOneBy({
-			id: ps.userListId,
-			userId: user.id,
-		});
-
-		if (userList == null) {
-			throw new ApiError(meta.errors.noSuchUserList);
-		}
-	} else if (ps.src === "group" && ps.userGroupId) {
-		userGroupJoining = await UserGroupJoinings.findOneBy({
-			userGroupId: ps.userGroupId,
-			userId: user.id,
-		});
-
-		if (userGroupJoining == null) {
-			throw new ApiError(meta.errors.noSuchUserGroup);
-		}
-	}
-
-	await Antennas.update(antenna.id, {
-		name: ps.name,
-		src: ps.src,
-		userListId: userList ? userList.id : null,
-		userGroupJoiningId: userGroupJoining ? userGroupJoining.id : null,
-		keywords: ps.keywords,
-		excludeKeywords: ps.excludeKeywords,
-		users: ps.users,
-		instances: ps.instances,
-		caseSensitive: ps.caseSensitive,
-		withReplies: ps.withReplies,
-		withFile: ps.withFile,
-		notify: ps.notify,
-	});
-
-	publishInternalEvent(
-		"antennaUpdated",
-		await Antennas.findOneByOrFail({ id: antenna.id }),
-	);
-
-	return await Antennas.pack(antenna.id);
-});
diff --git a/packages/backend/src/server/api/endpoints/ap/get.ts b/packages/backend/src/server/api/endpoints/ap/get.ts
deleted file mode 100644
index f0db67a343..0000000000
--- a/packages/backend/src/server/api/endpoints/ap/get.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import define from "../../define.js";
-import Resolver from "@/remote/activitypub/resolver.js";
-import { HOUR } from "@/const.js";
-
-export const meta = {
-	tags: ["federation"],
-
-	requireCredential: true,
-
-	limit: {
-		duration: HOUR,
-		max: 30,
-	},
-
-	errors: {},
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		uri: { type: "string" },
-	},
-	required: ["uri"],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	const resolver = new Resolver();
-	const object = await resolver.resolve(ps.uri);
-	return object;
-});
diff --git a/packages/backend/src/server/api/endpoints/ap/show.ts b/packages/backend/src/server/api/endpoints/ap/show.ts
deleted file mode 100644
index fa804802eb..0000000000
--- a/packages/backend/src/server/api/endpoints/ap/show.ts
+++ /dev/null
@@ -1,164 +0,0 @@
-import define from "../../define.js";
-import config from "@/config/index.js";
-import { createPerson } from "@/remote/activitypub/models/person.js";
-import { createNote } from "@/remote/activitypub/models/note.js";
-import DbResolver from "@/remote/activitypub/db-resolver.js";
-import Resolver from "@/remote/activitypub/resolver.js";
-import { ApiError } from "../../error.js";
-import { extractDbHost } from "@/misc/convert-host.js";
-import { Users, Notes } from "@/models/index.js";
-import type { Note } from "@/models/entities/note.js";
-import type { CacheableLocalUser, User } from "@/models/entities/user.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { isActor, isPost, getApId } from "@/remote/activitypub/type.js";
-import type { SchemaType } from "@/misc/schema.js";
-import { HOUR } from "@/const.js";
-import { shouldBlockInstance } from "@/misc/should-block-instance.js";
-
-export const meta = {
-	tags: ["federation"],
-
-	requireCredential: true,
-
-	limit: {
-		duration: HOUR,
-		max: 30,
-	},
-
-	errors: {
-		noSuchObject: {
-			message: "No such object.",
-			code: "NO_SUCH_OBJECT",
-			id: "dc94d745-1262-4e63-a17d-fecaa57efc82",
-		},
-	},
-
-	res: {
-		optional: false,
-		nullable: false,
-		oneOf: [
-			{
-				type: "object",
-				properties: {
-					type: {
-						type: "string",
-						optional: false,
-						nullable: false,
-						enum: ["User"],
-					},
-					object: {
-						type: "object",
-						optional: false,
-						nullable: false,
-						ref: "UserDetailedNotMe",
-					},
-				},
-			},
-			{
-				type: "object",
-				properties: {
-					type: {
-						type: "string",
-						optional: false,
-						nullable: false,
-						enum: ["Note"],
-					},
-					object: {
-						type: "object",
-						optional: false,
-						nullable: false,
-						ref: "Note",
-					},
-				},
-			},
-		],
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		uri: { type: "string" },
-	},
-	required: ["uri"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const object = await fetchAny(ps.uri, me);
-	if (object) {
-		return object;
-	} else {
-		throw new ApiError(meta.errors.noSuchObject);
-	}
-});
-
-/***
- * Resolve User or Note from URI
- */
-async function fetchAny(
-	uri: string,
-	me: CacheableLocalUser | null | undefined,
-): Promise<SchemaType<typeof meta["res"]> | null> {
-	// Wait if blocked.
-	if (await shouldBlockInstance(extractDbHost(uri))) return null;
-
-	const dbResolver = new DbResolver();
-
-	let local = await mergePack(
-		me,
-		...(await Promise.all([
-			dbResolver.getUserFromApId(uri),
-			dbResolver.getNoteFromApId(uri),
-		])),
-	);
-	if (local != null) return local;
-
-	// fetching Object once from remote
-	const resolver = new Resolver();
-	const object = (await resolver.resolve(uri)) as any;
-
-	// /@user If a URI other than the id is specified,
-	// the URI is determined here
-	if (uri !== object.id) {
-		local = await mergePack(
-			me,
-			...(await Promise.all([
-				dbResolver.getUserFromApId(object.id),
-				dbResolver.getNoteFromApId(object.id),
-			])),
-		);
-		if (local != null) return local;
-	}
-
-	return await mergePack(
-		me,
-		isActor(object) ? await createPerson(getApId(object)) : null,
-		isPost(object) ? await createNote(getApId(object), undefined, true) : null,
-	);
-}
-
-async function mergePack(
-	me: CacheableLocalUser | null | undefined,
-	user: User | null | undefined,
-	note: Note | null | undefined,
-): Promise<SchemaType<typeof meta.res> | null> {
-	if (user != null) {
-		return {
-			type: "User",
-			object: await Users.pack(user, me, { detail: true }),
-		};
-	} else if (note != null) {
-		try {
-			const object = await Notes.pack(note, me, { detail: true });
-
-			return {
-				type: "Note",
-				object,
-			};
-		} catch (e) {
-			return null;
-		}
-	}
-
-	return null;
-}
diff --git a/packages/backend/src/server/api/endpoints/app/create.ts b/packages/backend/src/server/api/endpoints/app/create.ts
deleted file mode 100644
index 013c5a10b9..0000000000
--- a/packages/backend/src/server/api/endpoints/app/create.ts
+++ /dev/null
@@ -1,67 +0,0 @@
-import define from "../../define.js";
-import { Apps } from "@/models/index.js";
-import { genId } from "@/misc/gen-id.js";
-import { unique } from "@/prelude/array.js";
-import { secureRndstr } from "@/misc/secure-rndstr.js";
-
-export const meta = {
-	tags: ["app"],
-
-	requireCredential: false,
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "App",
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		name: { type: "string" },
-		description: { type: "string" },
-		permission: {
-			type: "array",
-			uniqueItems: true,
-			items: {
-				type: "string",
-			},
-		},
-		callbackUrl: { type: "string", nullable: true },
-	},
-	required: ["name", "description", "permission"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	if (user?.movedToUri != null)
-		return await Apps.pack("", null, {
-			detail: true,
-			includeSecret: true,
-		});
-	// Generate secret
-	const secret = secureRndstr(32, true);
-
-	// for backward compatibility
-	const permission = unique(
-		ps.permission.map((v) => v.replace(/^(.+)(\/|-)(read|write)$/, "$3:$1")),
-	);
-
-	// Create account
-	const app = await Apps.insert({
-		id: genId(),
-		createdAt: new Date(),
-		userId: user ? user.id : null,
-		name: ps.name,
-		description: ps.description,
-		permission,
-		callbackUrl: ps.callbackUrl,
-		secret: secret,
-	}).then((x) => Apps.findOneByOrFail(x.identifiers[0]));
-
-	return await Apps.pack(app, null, {
-		detail: true,
-		includeSecret: true,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/app/show.ts b/packages/backend/src/server/api/endpoints/app/show.ts
deleted file mode 100644
index 60949512e0..0000000000
--- a/packages/backend/src/server/api/endpoints/app/show.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { Apps } from "@/models/index.js";
-
-export const meta = {
-	tags: ["app"],
-
-	errors: {
-		noSuchApp: {
-			message: "No such app.",
-			code: "NO_SUCH_APP",
-			id: "dce83913-2dc6-4093-8a7b-71dbb11718a3",
-		},
-	},
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "App",
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		appId: { type: "string", format: "misskey:id" },
-	},
-	required: ["appId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user, token) => {
-	const isSecure = user != null && token == null;
-
-	// Lookup app
-	const ap = await Apps.findOneBy({ id: ps.appId });
-
-	if (ap == null) {
-		throw new ApiError(meta.errors.noSuchApp);
-	}
-
-	return await Apps.pack(ap, user, {
-		detail: true,
-		includeSecret: isSecure && ap.userId === user!.id,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/auth/accept.ts b/packages/backend/src/server/api/endpoints/auth/accept.ts
deleted file mode 100644
index 35565e2560..0000000000
--- a/packages/backend/src/server/api/endpoints/auth/accept.ts
+++ /dev/null
@@ -1,76 +0,0 @@
-import * as crypto from "node:crypto";
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { AuthSessions, AccessTokens, Apps } from "@/models/index.js";
-import { genId } from "@/misc/gen-id.js";
-import { secureRndstr } from "@/misc/secure-rndstr.js";
-
-export const meta = {
-	tags: ["auth"],
-
-	requireCredential: true,
-
-	secure: true,
-
-	errors: {
-		noSuchSession: {
-			message: "No such session.",
-			code: "NO_SUCH_SESSION",
-			id: "9c72d8de-391a-43c1-9d06-08d29efde8df",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		token: { type: "string" },
-	},
-	required: ["token"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	// Fetch token
-	const session = await AuthSessions.findOneBy({ token: ps.token });
-
-	if (session == null) {
-		throw new ApiError(meta.errors.noSuchSession);
-	}
-
-	// Generate access token
-	const accessToken = secureRndstr(32, true);
-
-	// Fetch exist access token
-	const exist = await AccessTokens.findOneBy({
-		appId: session.appId,
-		userId: user.id,
-	});
-
-	if (exist == null) {
-		// Lookup app
-		const app = await Apps.findOneByOrFail({ id: session.appId });
-
-		// Generate Hash
-		const sha256 = crypto.createHash("sha256");
-		sha256.update(accessToken + app.secret);
-		const hash = sha256.digest("hex");
-
-		const now = new Date();
-
-		// Insert access token doc
-		await AccessTokens.insert({
-			id: genId(),
-			createdAt: now,
-			lastUsedAt: now,
-			appId: session.appId,
-			userId: user.id,
-			token: accessToken,
-			hash: hash,
-		});
-	}
-
-	// Update session
-	await AuthSessions.update(session.id, {
-		userId: user.id,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/auth/session/generate.ts b/packages/backend/src/server/api/endpoints/auth/session/generate.ts
deleted file mode 100644
index 1defb94006..0000000000
--- a/packages/backend/src/server/api/endpoints/auth/session/generate.ts
+++ /dev/null
@@ -1,74 +0,0 @@
-import { v4 as uuid } from "uuid";
-import config from "@/config/index.js";
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-import { Apps, AuthSessions } from "@/models/index.js";
-import { genId } from "@/misc/gen-id.js";
-
-export const meta = {
-	tags: ["auth"],
-
-	requireCredential: false,
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		properties: {
-			token: {
-				type: "string",
-				optional: false,
-				nullable: false,
-			},
-			url: {
-				type: "string",
-				optional: false,
-				nullable: false,
-				format: "url",
-			},
-		},
-	},
-
-	errors: {
-		noSuchApp: {
-			message: "No such app.",
-			code: "NO_SUCH_APP",
-			id: "92f93e63-428e-4f2f-a5a4-39e1407fe998",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		appSecret: { type: "string" },
-	},
-	required: ["appSecret"],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	// Lookup app
-	const app = await Apps.findOneBy({
-		secret: ps.appSecret,
-	});
-
-	if (app == null) {
-		throw new ApiError(meta.errors.noSuchApp);
-	}
-
-	// Generate token
-	const token = uuid();
-
-	// Create session token document
-	const doc = await AuthSessions.insert({
-		id: genId(),
-		createdAt: new Date(),
-		appId: app.id,
-		token: token,
-	}).then((x) => AuthSessions.findOneByOrFail(x.identifiers[0]));
-
-	return {
-		token: doc.token,
-		url: `${config.authUrl}/${doc.token}`,
-	};
-});
diff --git a/packages/backend/src/server/api/endpoints/auth/session/show.ts b/packages/backend/src/server/api/endpoints/auth/session/show.ts
deleted file mode 100644
index 01a5fe5dc7..0000000000
--- a/packages/backend/src/server/api/endpoints/auth/session/show.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-import { AuthSessions } from "@/models/index.js";
-
-export const meta = {
-	tags: ["auth"],
-
-	requireCredential: false,
-
-	errors: {
-		noSuchSession: {
-			message: "No such session.",
-			code: "NO_SUCH_SESSION",
-			id: "bd72c97d-eba7-4adb-a467-f171b8847250",
-		},
-	},
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		properties: {
-			id: {
-				type: "string",
-				optional: false,
-				nullable: false,
-				format: "id",
-			},
-			app: {
-				type: "object",
-				optional: false,
-				nullable: false,
-				ref: "App",
-			},
-			token: {
-				type: "string",
-				optional: false,
-				nullable: false,
-			},
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		token: { type: "string" },
-	},
-	required: ["token"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	// Lookup session
-	const session = await AuthSessions.findOneBy({
-		token: ps.token,
-	});
-
-	if (session == null) {
-		throw new ApiError(meta.errors.noSuchSession);
-	}
-
-	return await AuthSessions.pack(session, user);
-});
diff --git a/packages/backend/src/server/api/endpoints/auth/session/userkey.ts b/packages/backend/src/server/api/endpoints/auth/session/userkey.ts
deleted file mode 100644
index 0e97bf414e..0000000000
--- a/packages/backend/src/server/api/endpoints/auth/session/userkey.ts
+++ /dev/null
@@ -1,99 +0,0 @@
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-import { Apps, AuthSessions, AccessTokens, Users } from "@/models/index.js";
-
-export const meta = {
-	tags: ["auth"],
-
-	requireCredential: false,
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		properties: {
-			accessToken: {
-				type: "string",
-				optional: false,
-				nullable: false,
-			},
-
-			user: {
-				type: "object",
-				optional: false,
-				nullable: false,
-				ref: "UserDetailedNotMe",
-			},
-		},
-	},
-
-	errors: {
-		noSuchApp: {
-			message: "No such app.",
-			code: "NO_SUCH_APP",
-			id: "fcab192a-2c5a-43b7-8ad8-9b7054d8d40d",
-		},
-
-		noSuchSession: {
-			message: "No such session.",
-			code: "NO_SUCH_SESSION",
-			id: "5b5a1503-8bc8-4bd0-8054-dc189e8cdcb3",
-		},
-
-		pendingSession: {
-			message: "This session is not completed yet.",
-			code: "PENDING_SESSION",
-			id: "8c8a4145-02cc-4cca-8e66-29ba60445a8e",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		appSecret: { type: "string" },
-		token: { type: "string" },
-	},
-	required: ["appSecret", "token"],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	// Lookup app
-	const app = await Apps.findOneBy({
-		secret: ps.appSecret,
-	});
-
-	if (app == null) {
-		throw new ApiError(meta.errors.noSuchApp);
-	}
-
-	// Fetch token
-	const session = await AuthSessions.findOneBy({
-		token: ps.token,
-		appId: app.id,
-	});
-
-	if (session == null) {
-		throw new ApiError(meta.errors.noSuchSession);
-	}
-
-	if (session.userId == null) {
-		throw new ApiError(meta.errors.pendingSession);
-	}
-
-	// Lookup access token
-	const accessToken = await AccessTokens.findOneByOrFail({
-		appId: app.id,
-		userId: session.userId,
-	});
-
-	// Delete session
-	AuthSessions.delete(session.id);
-
-	return {
-		accessToken: accessToken.token,
-		user: await Users.pack(session.userId, null, {
-			detail: true,
-		}),
-	};
-});
diff --git a/packages/backend/src/server/api/endpoints/blocking/create.ts b/packages/backend/src/server/api/endpoints/blocking/create.ts
deleted file mode 100644
index 4bd58d5ef5..0000000000
--- a/packages/backend/src/server/api/endpoints/blocking/create.ts
+++ /dev/null
@@ -1,91 +0,0 @@
-import create from "@/services/blocking/create.js";
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { getUser } from "../../common/getters.js";
-import { Blockings, NoteWatchings, Users } from "@/models/index.js";
-import { HOUR } from "@/const.js";
-
-export const meta = {
-	tags: ["account"],
-
-	limit: {
-		duration: HOUR,
-		max: 100,
-	},
-
-	requireCredential: true,
-
-	kind: "write:blocks",
-
-	errors: {
-		noSuchUser: {
-			message: "No such user.",
-			code: "NO_SUCH_USER",
-			id: "7cc4f851-e2f1-4621-9633-ec9e1d00c01e",
-		},
-
-		blockeeIsYourself: {
-			message: "Blockee is yourself.",
-			code: "BLOCKEE_IS_YOURSELF",
-			id: "88b19138-f28d-42c0-8499-6a31bbd0fdc6",
-		},
-
-		alreadyBlocking: {
-			message: "You are already blocking that user.",
-			code: "ALREADY_BLOCKING",
-			id: "787fed64-acb9-464a-82eb-afbd745b9614",
-		},
-	},
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "UserDetailedNotMe",
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		userId: { type: "string", format: "misskey:id" },
-	},
-	required: ["userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const blocker = await Users.findOneByOrFail({ id: user.id });
-
-	// 自分自身
-	if (user.id === ps.userId) {
-		throw new ApiError(meta.errors.blockeeIsYourself);
-	}
-
-	// Get blockee
-	const blockee = await getUser(ps.userId).catch((e) => {
-		if (e.id === "15348ddd-432d-49c2-8a5a-8069753becff")
-			throw new ApiError(meta.errors.noSuchUser);
-		throw e;
-	});
-
-	// Check if already blocking
-	const exist = await Blockings.findOneBy({
-		blockerId: blocker.id,
-		blockeeId: blockee.id,
-	});
-
-	if (exist != null) {
-		throw new ApiError(meta.errors.alreadyBlocking);
-	}
-
-	await create(blocker, blockee);
-
-	NoteWatchings.delete({
-		userId: blocker.id,
-		noteUserId: blockee.id,
-	});
-
-	return await Users.pack(blockee.id, blocker, {
-		detail: true,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/blocking/delete.ts b/packages/backend/src/server/api/endpoints/blocking/delete.ts
deleted file mode 100644
index 6c4ca27755..0000000000
--- a/packages/backend/src/server/api/endpoints/blocking/delete.ts
+++ /dev/null
@@ -1,87 +0,0 @@
-import deleteBlocking from "@/services/blocking/delete.js";
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { getUser } from "../../common/getters.js";
-import { Blockings, Users } from "@/models/index.js";
-import { HOUR } from "@/const.js";
-
-export const meta = {
-	tags: ["account"],
-
-	limit: {
-		duration: HOUR,
-		max: 100,
-	},
-
-	requireCredential: true,
-
-	kind: "write:blocks",
-
-	errors: {
-		noSuchUser: {
-			message: "No such user.",
-			code: "NO_SUCH_USER",
-			id: "8621d8bf-c358-4303-a066-5ea78610eb3f",
-		},
-
-		blockeeIsYourself: {
-			message: "Blockee is yourself.",
-			code: "BLOCKEE_IS_YOURSELF",
-			id: "06f6fac6-524b-473c-a354-e97a40ae6eac",
-		},
-
-		notBlocking: {
-			message: "You are not blocking that user.",
-			code: "NOT_BLOCKING",
-			id: "291b2efa-60c6-45c0-9f6a-045c8f9b02cd",
-		},
-	},
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "UserDetailedNotMe",
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		userId: { type: "string", format: "misskey:id" },
-	},
-	required: ["userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const blocker = await Users.findOneByOrFail({ id: user.id });
-
-	// Check if the blockee is yourself
-	if (user.id === ps.userId) {
-		throw new ApiError(meta.errors.blockeeIsYourself);
-	}
-
-	// Get blockee
-	const blockee = await getUser(ps.userId).catch((e) => {
-		if (e.id === "15348ddd-432d-49c2-8a5a-8069753becff")
-			throw new ApiError(meta.errors.noSuchUser);
-		throw e;
-	});
-
-	// Check not blocking
-	const exist = await Blockings.findOneBy({
-		blockerId: blocker.id,
-		blockeeId: blockee.id,
-	});
-
-	if (exist == null) {
-		throw new ApiError(meta.errors.notBlocking);
-	}
-
-	// Delete blocking
-	await deleteBlocking(blocker, blockee);
-
-	return await Users.pack(blockee.id, blocker, {
-		detail: true,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/blocking/list.ts b/packages/backend/src/server/api/endpoints/blocking/list.ts
deleted file mode 100644
index 83fca7b42c..0000000000
--- a/packages/backend/src/server/api/endpoints/blocking/list.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import define from "../../define.js";
-import { Blockings } from "@/models/index.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-
-export const meta = {
-	tags: ["account"],
-
-	requireCredential: true,
-
-	kind: "read:blocks",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Blocking",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 30 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const query = makePaginationQuery(
-		Blockings.createQueryBuilder("blocking"),
-		ps.sinceId,
-		ps.untilId,
-	).andWhere("blocking.blockerId = :meId", { meId: me.id });
-
-	const blockings = await query.take(ps.limit).getMany();
-
-	return await Blockings.packMany(blockings, me);
-});
diff --git a/packages/backend/src/server/api/endpoints/channels/create.ts b/packages/backend/src/server/api/endpoints/channels/create.ts
deleted file mode 100644
index 26a3448b2b..0000000000
--- a/packages/backend/src/server/api/endpoints/channels/create.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { Channels, DriveFiles } from "@/models/index.js";
-import type { Channel } from "@/models/entities/channel.js";
-import { genId } from "@/misc/gen-id.js";
-
-export const meta = {
-	tags: ["channels"],
-
-	requireCredential: true,
-
-	kind: "write:channels",
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "Channel",
-	},
-
-	errors: {
-		noSuchFile: {
-			message: "No such file.",
-			code: "NO_SUCH_FILE",
-			id: "cd1e9f3e-5a12-4ab4-96f6-5d0a2cc32050",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		name: { type: "string", minLength: 1, maxLength: 128 },
-		description: {
-			type: "string",
-			nullable: true,
-			minLength: 1,
-			maxLength: 2048,
-		},
-		bannerId: { type: "string", format: "misskey:id", nullable: true },
-	},
-	required: ["name"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	let banner = null;
-	if (ps.bannerId != null) {
-		banner = await DriveFiles.findOneBy({
-			id: ps.bannerId,
-			userId: user.id,
-		});
-
-		if (banner == null) {
-			throw new ApiError(meta.errors.noSuchFile);
-		}
-	}
-
-	const channel = await Channels.insert({
-		id: genId(),
-		createdAt: new Date(),
-		userId: user.id,
-		name: ps.name,
-		description: ps.description || null,
-		bannerId: banner ? banner.id : null,
-	} as Channel).then((x) => Channels.findOneByOrFail(x.identifiers[0]));
-
-	return await Channels.pack(channel, user);
-});
diff --git a/packages/backend/src/server/api/endpoints/channels/featured.ts b/packages/backend/src/server/api/endpoints/channels/featured.ts
deleted file mode 100644
index 06e0e850fd..0000000000
--- a/packages/backend/src/server/api/endpoints/channels/featured.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import define from "../../define.js";
-import { Channels } from "@/models/index.js";
-
-export const meta = {
-	tags: ["channels"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Channel",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const query = Channels.createQueryBuilder("channel")
-		.where("channel.lastNotedAt IS NOT NULL")
-		.orderBy("channel.lastNotedAt", "DESC");
-
-	const channels = await query.take(10).getMany();
-
-	return await Promise.all(channels.map((x) => Channels.pack(x, me)));
-});
diff --git a/packages/backend/src/server/api/endpoints/channels/follow.ts b/packages/backend/src/server/api/endpoints/channels/follow.ts
deleted file mode 100644
index de0554383e..0000000000
--- a/packages/backend/src/server/api/endpoints/channels/follow.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { Channels, ChannelFollowings } from "@/models/index.js";
-import { genId } from "@/misc/gen-id.js";
-import { publishUserEvent } from "@/services/stream.js";
-
-export const meta = {
-	tags: ["channels"],
-
-	requireCredential: true,
-
-	kind: "write:channels",
-
-	errors: {
-		noSuchChannel: {
-			message: "No such channel.",
-			code: "NO_SUCH_CHANNEL",
-			id: "c0031718-d573-4e85-928e-10039f1fbb68",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		channelId: { type: "string", format: "misskey:id" },
-	},
-	required: ["channelId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const channel = await Channels.findOneBy({
-		id: ps.channelId,
-	});
-
-	if (channel == null) {
-		throw new ApiError(meta.errors.noSuchChannel);
-	}
-
-	await ChannelFollowings.insert({
-		id: genId(),
-		createdAt: new Date(),
-		followerId: user.id,
-		followeeId: channel.id,
-	});
-
-	publishUserEvent(user.id, "followChannel", channel);
-});
diff --git a/packages/backend/src/server/api/endpoints/channels/followed.ts b/packages/backend/src/server/api/endpoints/channels/followed.ts
deleted file mode 100644
index 993a211f7e..0000000000
--- a/packages/backend/src/server/api/endpoints/channels/followed.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import define from "../../define.js";
-import { Channels, ChannelFollowings } from "@/models/index.js";
-
-export const meta = {
-	tags: ["channels", "account"],
-
-	requireCredential: true,
-
-	kind: "read:channels",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Channel",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 5 },
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const query = ChannelFollowings.createQueryBuilder("following").andWhere({
-		followerId: me.id,
-	});
-	if (ps.sinceId) {
-		query.andWhere('following."followeeId" > :sinceId', {
-			sinceId: ps.sinceId,
-		});
-	}
-	if (ps.untilId) {
-		query.andWhere('following."followeeId" < :untilId', {
-			untilId: ps.untilId,
-		});
-	}
-	if (ps.sinceId && !ps.untilId) {
-		query.orderBy('following."followeeId"', "ASC");
-	} else {
-		query.orderBy('following."followeeId"', "DESC");
-	}
-
-	const followings = await query.take(ps.limit).getMany();
-
-	return await Promise.all(
-		followings.map((x) => Channels.pack(x.followeeId, me)),
-	);
-});
diff --git a/packages/backend/src/server/api/endpoints/channels/owned.ts b/packages/backend/src/server/api/endpoints/channels/owned.ts
deleted file mode 100644
index 78d9e80ccf..0000000000
--- a/packages/backend/src/server/api/endpoints/channels/owned.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import define from "../../define.js";
-import { Channels } from "@/models/index.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-
-export const meta = {
-	tags: ["channels", "account"],
-
-	requireCredential: true,
-
-	kind: "read:channels",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Channel",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 5 },
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const query = makePaginationQuery(
-		Channels.createQueryBuilder(),
-		ps.sinceId,
-		ps.untilId,
-	).andWhere({ userId: me.id });
-
-	const channels = await query.take(ps.limit).getMany();
-
-	return await Promise.all(channels.map((x) => Channels.pack(x, me)));
-});
diff --git a/packages/backend/src/server/api/endpoints/channels/show.ts b/packages/backend/src/server/api/endpoints/channels/show.ts
deleted file mode 100644
index e4ca756634..0000000000
--- a/packages/backend/src/server/api/endpoints/channels/show.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { Channels } from "@/models/index.js";
-
-export const meta = {
-	tags: ["channels"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "Channel",
-	},
-
-	errors: {
-		noSuchChannel: {
-			message: "No such channel.",
-			code: "NO_SUCH_CHANNEL",
-			id: "6f6c314b-7486-4897-8966-c04a66a02923",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		channelId: { type: "string", format: "misskey:id" },
-	},
-	required: ["channelId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const channel = await Channels.findOneBy({
-		id: ps.channelId,
-	});
-
-	if (channel == null) {
-		throw new ApiError(meta.errors.noSuchChannel);
-	}
-
-	return await Channels.pack(channel, me);
-});
diff --git a/packages/backend/src/server/api/endpoints/channels/timeline.ts b/packages/backend/src/server/api/endpoints/channels/timeline.ts
deleted file mode 100644
index b5d5325234..0000000000
--- a/packages/backend/src/server/api/endpoints/channels/timeline.ts
+++ /dev/null
@@ -1,84 +0,0 @@
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { Notes, Channels } from "@/models/index.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-import { activeUsersChart } from "@/services/chart/index.js";
-
-export const meta = {
-	tags: ["notes", "channels"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Note",
-		},
-	},
-
-	errors: {
-		noSuchChannel: {
-			message: "No such channel.",
-			code: "NO_SUCH_CHANNEL",
-			id: "4d0eeeba-a02c-4c3c-9966-ef60d38d2e7f",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		channelId: { type: "string", format: "misskey:id" },
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-		sinceDate: { type: "integer" },
-		untilDate: { type: "integer" },
-	},
-	required: ["channelId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const channel = await Channels.findOneBy({
-		id: ps.channelId,
-	});
-
-	if (channel == null) {
-		throw new ApiError(meta.errors.noSuchChannel);
-	}
-
-	//#region Construct query
-	const query = makePaginationQuery(
-		Notes.createQueryBuilder("note"),
-		ps.sinceId,
-		ps.untilId,
-		ps.sinceDate,
-		ps.untilDate,
-	)
-		.andWhere("note.channelId = :channelId", { channelId: channel.id })
-		.innerJoinAndSelect("note.user", "user")
-		.leftJoinAndSelect("user.avatar", "avatar")
-		.leftJoinAndSelect("user.banner", "banner")
-		.leftJoinAndSelect("note.reply", "reply")
-		.leftJoinAndSelect("note.renote", "renote")
-		.leftJoinAndSelect("reply.user", "replyUser")
-		.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
-		.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
-		.leftJoinAndSelect("renote.user", "renoteUser")
-		.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
-		.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner")
-		.leftJoinAndSelect("note.channel", "channel");
-	//#endregion
-
-	const timeline = await query.take(ps.limit).getMany();
-
-	if (user) activeUsersChart.read(user);
-
-	return await Notes.packMany(timeline, user);
-});
diff --git a/packages/backend/src/server/api/endpoints/channels/unfollow.ts b/packages/backend/src/server/api/endpoints/channels/unfollow.ts
deleted file mode 100644
index 654a4fbba5..0000000000
--- a/packages/backend/src/server/api/endpoints/channels/unfollow.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { Channels, ChannelFollowings } from "@/models/index.js";
-import { publishUserEvent } from "@/services/stream.js";
-
-export const meta = {
-	tags: ["channels"],
-
-	requireCredential: true,
-
-	kind: "write:channels",
-
-	errors: {
-		noSuchChannel: {
-			message: "No such channel.",
-			code: "NO_SUCH_CHANNEL",
-			id: "19959ee9-0153-4c51-bbd9-a98c49dc59d6",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		channelId: { type: "string", format: "misskey:id" },
-	},
-	required: ["channelId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const channel = await Channels.findOneBy({
-		id: ps.channelId,
-	});
-
-	if (channel == null) {
-		throw new ApiError(meta.errors.noSuchChannel);
-	}
-
-	await ChannelFollowings.delete({
-		followerId: user.id,
-		followeeId: channel.id,
-	});
-
-	publishUserEvent(user.id, "unfollowChannel", channel);
-});
diff --git a/packages/backend/src/server/api/endpoints/channels/update.ts b/packages/backend/src/server/api/endpoints/channels/update.ts
deleted file mode 100644
index d9f6f7644c..0000000000
--- a/packages/backend/src/server/api/endpoints/channels/update.ts
+++ /dev/null
@@ -1,90 +0,0 @@
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { Channels, DriveFiles } from "@/models/index.js";
-
-export const meta = {
-	tags: ["channels"],
-
-	requireCredential: true,
-
-	kind: "write:channels",
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "Channel",
-	},
-
-	errors: {
-		noSuchChannel: {
-			message: "No such channel.",
-			code: "NO_SUCH_CHANNEL",
-			id: "f9c5467f-d492-4c3c-9a8d-a70dacc86512",
-		},
-
-		accessDenied: {
-			message: "You do not have edit privilege of the channel.",
-			code: "ACCESS_DENIED",
-			id: "1fb7cb09-d46a-4fdf-b8df-057788cce513",
-		},
-
-		noSuchFile: {
-			message: "No such file.",
-			code: "NO_SUCH_FILE",
-			id: "e86c14a4-0da2-4032-8df3-e737a04c7f3b",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		channelId: { type: "string", format: "misskey:id" },
-		name: { type: "string", minLength: 1, maxLength: 128 },
-		description: {
-			type: "string",
-			nullable: true,
-			minLength: 1,
-			maxLength: 2048,
-		},
-		bannerId: { type: "string", format: "misskey:id", nullable: true },
-	},
-	required: ["channelId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const channel = await Channels.findOneBy({
-		id: ps.channelId,
-	});
-
-	if (channel == null) {
-		throw new ApiError(meta.errors.noSuchChannel);
-	}
-
-	if (channel.userId !== me.id) {
-		throw new ApiError(meta.errors.accessDenied);
-	}
-
-	let banner = undefined;
-	if (ps.bannerId != null) {
-		banner = await DriveFiles.findOneBy({
-			id: ps.bannerId,
-			userId: me.id,
-		});
-
-		if (banner == null) {
-			throw new ApiError(meta.errors.noSuchFile);
-		}
-	} else if (ps.bannerId === null) {
-		banner = null;
-	}
-
-	await Channels.update(channel.id, {
-		...(ps.name !== undefined ? { name: ps.name } : {}),
-		...(ps.description !== undefined ? { description: ps.description } : {}),
-		...(banner ? { bannerId: banner.id } : {}),
-	});
-
-	return await Channels.pack(channel.id, me);
-});
diff --git a/packages/backend/src/server/api/endpoints/charts/active-users.ts b/packages/backend/src/server/api/endpoints/charts/active-users.ts
deleted file mode 100644
index 3817a32ca9..0000000000
--- a/packages/backend/src/server/api/endpoints/charts/active-users.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { getJsonSchema } from "@/services/chart/core.js";
-import { activeUsersChart } from "@/services/chart/index.js";
-import define from "../../define.js";
-
-export const meta = {
-	tags: ["charts", "users"],
-	requireCredentialPrivateMode: true,
-
-	res: getJsonSchema(activeUsersChart.schema),
-
-	allowGet: true,
-	cacheSec: 60 * 60,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		span: { type: "string", enum: ["day", "hour"] },
-		limit: { type: "integer", minimum: 1, maximum: 500, default: 30 },
-		offset: { type: "integer", nullable: true, default: null },
-	},
-	required: ["span"],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	return await activeUsersChart.getChart(
-		ps.span,
-		ps.limit,
-		ps.offset ? new Date(ps.offset) : null,
-	);
-});
diff --git a/packages/backend/src/server/api/endpoints/charts/ap-request.ts b/packages/backend/src/server/api/endpoints/charts/ap-request.ts
deleted file mode 100644
index 9e9013ce53..0000000000
--- a/packages/backend/src/server/api/endpoints/charts/ap-request.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { getJsonSchema } from "@/services/chart/core.js";
-import { apRequestChart } from "@/services/chart/index.js";
-import define from "../../define.js";
-
-export const meta = {
-	tags: ["charts"],
-	requireCredentialPrivateMode: true,
-
-	res: getJsonSchema(apRequestChart.schema),
-
-	allowGet: true,
-	cacheSec: 60 * 60,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		span: { type: "string", enum: ["day", "hour"] },
-		limit: { type: "integer", minimum: 1, maximum: 500, default: 30 },
-		offset: { type: "integer", nullable: true, default: null },
-	},
-	required: ["span"],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	return await apRequestChart.getChart(
-		ps.span,
-		ps.limit,
-		ps.offset ? new Date(ps.offset) : null,
-	);
-});
diff --git a/packages/backend/src/server/api/endpoints/charts/drive.ts b/packages/backend/src/server/api/endpoints/charts/drive.ts
deleted file mode 100644
index 03ac4c0473..0000000000
--- a/packages/backend/src/server/api/endpoints/charts/drive.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { getJsonSchema } from "@/services/chart/core.js";
-import { driveChart } from "@/services/chart/index.js";
-import define from "../../define.js";
-
-export const meta = {
-	tags: ["charts", "drive"],
-	requireCredentialPrivateMode: true,
-
-	res: getJsonSchema(driveChart.schema),
-
-	allowGet: true,
-	cacheSec: 60 * 60,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		span: { type: "string", enum: ["day", "hour"] },
-		limit: { type: "integer", minimum: 1, maximum: 500, default: 30 },
-		offset: { type: "integer", nullable: true, default: null },
-	},
-	required: ["span"],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	return await driveChart.getChart(
-		ps.span,
-		ps.limit,
-		ps.offset ? new Date(ps.offset) : null,
-	);
-});
diff --git a/packages/backend/src/server/api/endpoints/charts/federation.ts b/packages/backend/src/server/api/endpoints/charts/federation.ts
deleted file mode 100644
index 5862aad56e..0000000000
--- a/packages/backend/src/server/api/endpoints/charts/federation.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { getJsonSchema } from "@/services/chart/core.js";
-import { federationChart } from "@/services/chart/index.js";
-import define from "../../define.js";
-
-export const meta = {
-	tags: ["charts"],
-	requireCredentialPrivateMode: true,
-
-	res: getJsonSchema(federationChart.schema),
-
-	allowGet: true,
-	cacheSec: 60 * 60,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		span: { type: "string", enum: ["day", "hour"] },
-		limit: { type: "integer", minimum: 1, maximum: 500, default: 30 },
-		offset: { type: "integer", nullable: true, default: null },
-	},
-	required: ["span"],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	return await federationChart.getChart(
-		ps.span,
-		ps.limit,
-		ps.offset ? new Date(ps.offset) : null,
-	);
-});
diff --git a/packages/backend/src/server/api/endpoints/charts/hashtag.ts b/packages/backend/src/server/api/endpoints/charts/hashtag.ts
deleted file mode 100644
index 0af1e35ea9..0000000000
--- a/packages/backend/src/server/api/endpoints/charts/hashtag.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import { getJsonSchema } from "@/services/chart/core.js";
-import { hashtagChart } from "@/services/chart/index.js";
-import define from "../../define.js";
-
-export const meta = {
-	tags: ["charts", "hashtags"],
-	requireCredentialPrivateMode: true,
-
-	res: getJsonSchema(hashtagChart.schema),
-
-	allowGet: true,
-	cacheSec: 60 * 60,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		span: { type: "string", enum: ["day", "hour"] },
-		limit: { type: "integer", minimum: 1, maximum: 500, default: 30 },
-		offset: { type: "integer", nullable: true, default: null },
-		tag: { type: "string" },
-	},
-	required: ["span", "tag"],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	return await hashtagChart.getChart(
-		ps.span,
-		ps.limit,
-		ps.offset ? new Date(ps.offset) : null,
-		ps.tag,
-	);
-});
diff --git a/packages/backend/src/server/api/endpoints/charts/instance.ts b/packages/backend/src/server/api/endpoints/charts/instance.ts
deleted file mode 100644
index 11a1dbce1b..0000000000
--- a/packages/backend/src/server/api/endpoints/charts/instance.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import { getJsonSchema } from "@/services/chart/core.js";
-import { instanceChart } from "@/services/chart/index.js";
-import define from "../../define.js";
-
-export const meta = {
-	tags: ["charts"],
-	requireCredentialPrivateMode: true,
-
-	res: getJsonSchema(instanceChart.schema),
-
-	allowGet: true,
-	cacheSec: 60 * 60,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		span: { type: "string", enum: ["day", "hour"] },
-		limit: { type: "integer", minimum: 1, maximum: 500, default: 30 },
-		offset: { type: "integer", nullable: true, default: null },
-		host: { type: "string" },
-	},
-	required: ["span", "host"],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	return await instanceChart.getChart(
-		ps.span,
-		ps.limit,
-		ps.offset ? new Date(ps.offset) : null,
-		ps.host,
-	);
-});
diff --git a/packages/backend/src/server/api/endpoints/charts/notes.ts b/packages/backend/src/server/api/endpoints/charts/notes.ts
deleted file mode 100644
index 27e69a4c9b..0000000000
--- a/packages/backend/src/server/api/endpoints/charts/notes.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { getJsonSchema } from "@/services/chart/core.js";
-import { notesChart } from "@/services/chart/index.js";
-import define from "../../define.js";
-
-export const meta = {
-	tags: ["charts", "notes"],
-	requireCredentialPrivateMode: true,
-
-	res: getJsonSchema(notesChart.schema),
-
-	allowGet: true,
-	cacheSec: 60 * 60,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		span: { type: "string", enum: ["day", "hour"] },
-		limit: { type: "integer", minimum: 1, maximum: 500, default: 30 },
-		offset: { type: "integer", nullable: true, default: null },
-	},
-	required: ["span"],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	return await notesChart.getChart(
-		ps.span,
-		ps.limit,
-		ps.offset ? new Date(ps.offset) : null,
-	);
-});
diff --git a/packages/backend/src/server/api/endpoints/charts/user/drive.ts b/packages/backend/src/server/api/endpoints/charts/user/drive.ts
deleted file mode 100644
index 178ba453c6..0000000000
--- a/packages/backend/src/server/api/endpoints/charts/user/drive.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import { getJsonSchema } from "@/services/chart/core.js";
-import { perUserDriveChart } from "@/services/chart/index.js";
-import define from "../../../define.js";
-
-export const meta = {
-	tags: ["charts", "drive", "users"],
-	requireCredentialPrivateMode: true,
-
-	res: getJsonSchema(perUserDriveChart.schema),
-
-	allowGet: true,
-	cacheSec: 60 * 60,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		span: { type: "string", enum: ["day", "hour"] },
-		limit: { type: "integer", minimum: 1, maximum: 500, default: 30 },
-		offset: { type: "integer", nullable: true, default: null },
-		userId: { type: "string", format: "misskey:id" },
-	},
-	required: ["span", "userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	return await perUserDriveChart.getChart(
-		ps.span,
-		ps.limit,
-		ps.offset ? new Date(ps.offset) : null,
-		ps.userId,
-	);
-});
diff --git a/packages/backend/src/server/api/endpoints/charts/user/following.ts b/packages/backend/src/server/api/endpoints/charts/user/following.ts
deleted file mode 100644
index 6a0c22df11..0000000000
--- a/packages/backend/src/server/api/endpoints/charts/user/following.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import define from "../../../define.js";
-import { getJsonSchema } from "@/services/chart/core.js";
-import { perUserFollowingChart } from "@/services/chart/index.js";
-
-export const meta = {
-	tags: ["charts", "users", "following"],
-	requireCredentialPrivateMode: true,
-
-	res: getJsonSchema(perUserFollowingChart.schema),
-
-	allowGet: true,
-	cacheSec: 60 * 60,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		span: { type: "string", enum: ["day", "hour"] },
-		limit: { type: "integer", minimum: 1, maximum: 500, default: 30 },
-		offset: { type: "integer", nullable: true, default: null },
-		userId: { type: "string", format: "misskey:id" },
-	},
-	required: ["span", "userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	return await perUserFollowingChart.getChart(
-		ps.span,
-		ps.limit,
-		ps.offset ? new Date(ps.offset) : null,
-		ps.userId,
-	);
-});
diff --git a/packages/backend/src/server/api/endpoints/charts/user/notes.ts b/packages/backend/src/server/api/endpoints/charts/user/notes.ts
deleted file mode 100644
index d788076962..0000000000
--- a/packages/backend/src/server/api/endpoints/charts/user/notes.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import { getJsonSchema } from "@/services/chart/core.js";
-import { perUserNotesChart } from "@/services/chart/index.js";
-import define from "../../../define.js";
-
-export const meta = {
-	tags: ["charts", "users", "notes"],
-	requireCredentialPrivateMode: true,
-
-	res: getJsonSchema(perUserNotesChart.schema),
-
-	allowGet: true,
-	cacheSec: 60 * 60,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		span: { type: "string", enum: ["day", "hour"] },
-		limit: { type: "integer", minimum: 1, maximum: 500, default: 30 },
-		offset: { type: "integer", nullable: true, default: null },
-		userId: { type: "string", format: "misskey:id" },
-	},
-	required: ["span", "userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	return await perUserNotesChart.getChart(
-		ps.span,
-		ps.limit,
-		ps.offset ? new Date(ps.offset) : null,
-		ps.userId,
-	);
-});
diff --git a/packages/backend/src/server/api/endpoints/charts/user/reactions.ts b/packages/backend/src/server/api/endpoints/charts/user/reactions.ts
deleted file mode 100644
index 5b0048c50e..0000000000
--- a/packages/backend/src/server/api/endpoints/charts/user/reactions.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import { getJsonSchema } from "@/services/chart/core.js";
-import { perUserReactionsChart } from "@/services/chart/index.js";
-import define from "../../../define.js";
-
-export const meta = {
-	tags: ["charts", "users", "reactions"],
-	requireCredentialPrivateMode: true,
-
-	res: getJsonSchema(perUserReactionsChart.schema),
-
-	allowGet: true,
-	cacheSec: 60 * 60,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		span: { type: "string", enum: ["day", "hour"] },
-		limit: { type: "integer", minimum: 1, maximum: 500, default: 30 },
-		offset: { type: "integer", nullable: true, default: null },
-		userId: { type: "string", format: "misskey:id" },
-	},
-	required: ["span", "userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	return await perUserReactionsChart.getChart(
-		ps.span,
-		ps.limit,
-		ps.offset ? new Date(ps.offset) : null,
-		ps.userId,
-	);
-});
diff --git a/packages/backend/src/server/api/endpoints/charts/users.ts b/packages/backend/src/server/api/endpoints/charts/users.ts
deleted file mode 100644
index 8973f013b7..0000000000
--- a/packages/backend/src/server/api/endpoints/charts/users.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { getJsonSchema } from "@/services/chart/core.js";
-import { usersChart } from "@/services/chart/index.js";
-import define from "../../define.js";
-
-export const meta = {
-	tags: ["charts", "users"],
-	requireCredentialPrivateMode: true,
-
-	res: getJsonSchema(usersChart.schema),
-
-	allowGet: true,
-	cacheSec: 60 * 60,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		span: { type: "string", enum: ["day", "hour"] },
-		limit: { type: "integer", minimum: 1, maximum: 500, default: 30 },
-		offset: { type: "integer", nullable: true, default: null },
-	},
-	required: ["span"],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	return await usersChart.getChart(
-		ps.span,
-		ps.limit,
-		ps.offset ? new Date(ps.offset) : null,
-	);
-});
diff --git a/packages/backend/src/server/api/endpoints/clips/add-note.ts b/packages/backend/src/server/api/endpoints/clips/add-note.ts
deleted file mode 100644
index b9d6b54c95..0000000000
--- a/packages/backend/src/server/api/endpoints/clips/add-note.ts
+++ /dev/null
@@ -1,74 +0,0 @@
-import define from "../../define.js";
-import { ClipNotes, Clips } from "@/models/index.js";
-import { ApiError } from "../../error.js";
-import { genId } from "@/misc/gen-id.js";
-import { getNote } from "../../common/getters.js";
-
-export const meta = {
-	tags: ["account", "notes", "clips"],
-
-	requireCredential: true,
-
-	kind: "write:account",
-
-	errors: {
-		noSuchClip: {
-			message: "No such clip.",
-			code: "NO_SUCH_CLIP",
-			id: "d6e76cc0-a1b5-4c7c-a287-73fa9c716dcf",
-		},
-
-		noSuchNote: {
-			message: "No such note.",
-			code: "NO_SUCH_NOTE",
-			id: "fc8c0b49-c7a3-4664-a0a6-b418d386bb8b",
-		},
-
-		alreadyClipped: {
-			message: "The note has already been clipped.",
-			code: "ALREADY_CLIPPED",
-			id: "734806c4-542c-463a-9311-15c512803965",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		clipId: { type: "string", format: "misskey:id" },
-		noteId: { type: "string", format: "misskey:id" },
-	},
-	required: ["clipId", "noteId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const clip = await Clips.findOneBy({
-		id: ps.clipId,
-		userId: user.id,
-	});
-
-	if (clip == null) {
-		throw new ApiError(meta.errors.noSuchClip);
-	}
-
-	const note = await getNote(ps.noteId, user).catch((err) => {
-		if (err.id === "9725d0ce-ba28-4dde-95a7-2cbb2c15de24")
-			throw new ApiError(meta.errors.noSuchNote);
-		throw err;
-	});
-
-	const exist = await ClipNotes.findOneBy({
-		noteId: note.id,
-		clipId: clip.id,
-	});
-
-	if (exist != null) {
-		throw new ApiError(meta.errors.alreadyClipped);
-	}
-
-	await ClipNotes.insert({
-		id: genId(),
-		noteId: note.id,
-		clipId: clip.id,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/clips/create.ts b/packages/backend/src/server/api/endpoints/clips/create.ts
deleted file mode 100644
index 918e9462a4..0000000000
--- a/packages/backend/src/server/api/endpoints/clips/create.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import define from "../../define.js";
-import { genId } from "@/misc/gen-id.js";
-import { Clips } from "@/models/index.js";
-
-export const meta = {
-	tags: ["clips"],
-
-	requireCredential: true,
-
-	kind: "write:account",
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "Clip",
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		name: { type: "string", minLength: 1, maxLength: 100 },
-		isPublic: { type: "boolean", default: false },
-		description: {
-			type: "string",
-			nullable: true,
-			minLength: 1,
-			maxLength: 2048,
-		},
-	},
-	required: ["name"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const clip = await Clips.insert({
-		id: genId(),
-		createdAt: new Date(),
-		userId: user.id,
-		name: ps.name,
-		isPublic: ps.isPublic,
-		description: ps.description,
-	}).then((x) => Clips.findOneByOrFail(x.identifiers[0]));
-
-	return await Clips.pack(clip);
-});
diff --git a/packages/backend/src/server/api/endpoints/clips/delete.ts b/packages/backend/src/server/api/endpoints/clips/delete.ts
deleted file mode 100644
index 8f2489dddd..0000000000
--- a/packages/backend/src/server/api/endpoints/clips/delete.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { Clips } from "@/models/index.js";
-
-export const meta = {
-	tags: ["clips"],
-
-	requireCredential: true,
-
-	kind: "write:account",
-
-	errors: {
-		noSuchClip: {
-			message: "No such clip.",
-			code: "NO_SUCH_CLIP",
-			id: "70ca08ba-6865-4630-b6fb-8494759aa754",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		clipId: { type: "string", format: "misskey:id" },
-	},
-	required: ["clipId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const clip = await Clips.findOneBy({
-		id: ps.clipId,
-		userId: user.id,
-	});
-
-	if (clip == null) {
-		throw new ApiError(meta.errors.noSuchClip);
-	}
-
-	await Clips.delete(clip.id);
-});
diff --git a/packages/backend/src/server/api/endpoints/clips/list.ts b/packages/backend/src/server/api/endpoints/clips/list.ts
deleted file mode 100644
index d1625ee036..0000000000
--- a/packages/backend/src/server/api/endpoints/clips/list.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import define from "../../define.js";
-import { Clips } from "@/models/index.js";
-
-export const meta = {
-	tags: ["clips", "account"],
-
-	requireCredential: true,
-
-	kind: "read:account",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Clip",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const clips = await Clips.findBy({
-		userId: me.id,
-	});
-
-	return await Promise.all(clips.map((x) => Clips.pack(x)));
-});
diff --git a/packages/backend/src/server/api/endpoints/clips/notes.ts b/packages/backend/src/server/api/endpoints/clips/notes.ts
deleted file mode 100644
index c641d9ba9f..0000000000
--- a/packages/backend/src/server/api/endpoints/clips/notes.ts
+++ /dev/null
@@ -1,94 +0,0 @@
-import define from "../../define.js";
-import { ClipNotes, Clips, Notes } from "@/models/index.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-import { generateVisibilityQuery } from "../../common/generate-visibility-query.js";
-import { generateMutedUserQuery } from "../../common/generate-muted-user-query.js";
-import { ApiError } from "../../error.js";
-import { generateBlockedUserQuery } from "../../common/generate-block-query.js";
-
-export const meta = {
-	tags: ["account", "notes", "clips"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	kind: "read:account",
-
-	errors: {
-		noSuchClip: {
-			message: "No such clip.",
-			code: "NO_SUCH_CLIP",
-			id: "1d7645e6-2b6d-4635-b0fe-fe22b0e72e00",
-		},
-	},
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Note",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		clipId: { type: "string", format: "misskey:id" },
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-	},
-	required: ["clipId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const clip = await Clips.findOneBy({
-		id: ps.clipId,
-	});
-
-	if (clip == null) {
-		throw new ApiError(meta.errors.noSuchClip);
-	}
-
-	if (!clip.isPublic && (user == null || clip.userId !== user.id)) {
-		throw new ApiError(meta.errors.noSuchClip);
-	}
-
-	const query = makePaginationQuery(
-		Notes.createQueryBuilder("note"),
-		ps.sinceId,
-		ps.untilId,
-	)
-		.innerJoin(
-			ClipNotes.metadata.targetName,
-			"clipNote",
-			"clipNote.noteId = note.id",
-		)
-		.innerJoinAndSelect("note.user", "user")
-		.leftJoinAndSelect("user.avatar", "avatar")
-		.leftJoinAndSelect("user.banner", "banner")
-		.leftJoinAndSelect("note.reply", "reply")
-		.leftJoinAndSelect("note.renote", "renote")
-		.leftJoinAndSelect("reply.user", "replyUser")
-		.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
-		.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
-		.leftJoinAndSelect("renote.user", "renoteUser")
-		.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
-		.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner")
-		.andWhere("clipNote.clipId = :clipId", { clipId: clip.id });
-
-	if (user) {
-		generateVisibilityQuery(query, user);
-		generateMutedUserQuery(query, user);
-		generateBlockedUserQuery(query, user);
-	}
-
-	const notes = await query.take(ps.limit).getMany();
-
-	return await Notes.packMany(notes, user);
-});
diff --git a/packages/backend/src/server/api/endpoints/clips/remove-note.ts b/packages/backend/src/server/api/endpoints/clips/remove-note.ts
deleted file mode 100644
index 2cc19aca94..0000000000
--- a/packages/backend/src/server/api/endpoints/clips/remove-note.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-import define from "../../define.js";
-import { ClipNotes, Clips } from "@/models/index.js";
-import { ApiError } from "../../error.js";
-import { getNote } from "../../common/getters.js";
-
-export const meta = {
-	tags: ["account", "notes", "clips"],
-
-	requireCredential: true,
-
-	kind: "write:account",
-
-	errors: {
-		noSuchClip: {
-			message: "No such clip.",
-			code: "NO_SUCH_CLIP",
-			id: "b80525c6-97f7-49d7-a42d-ebccd49cfd52",
-		},
-
-		noSuchNote: {
-			message: "No such note.",
-			code: "NO_SUCH_NOTE",
-			id: "aff017de-190e-434b-893e-33a9ff5049d8",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		clipId: { type: "string", format: "misskey:id" },
-		noteId: { type: "string", format: "misskey:id" },
-	},
-	required: ["clipId", "noteId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const clip = await Clips.findOneBy({
-		id: ps.clipId,
-		userId: user.id,
-	});
-
-	if (clip == null) {
-		throw new ApiError(meta.errors.noSuchClip);
-	}
-
-	const note = await getNote(ps.noteId).catch((e) => {
-		if (e.id === "9725d0ce-ba28-4dde-95a7-2cbb2c15de24")
-			throw new ApiError(meta.errors.noSuchNote);
-		throw e;
-	});
-
-	await ClipNotes.delete({
-		noteId: note.id,
-		clipId: clip.id,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/clips/show.ts b/packages/backend/src/server/api/endpoints/clips/show.ts
deleted file mode 100644
index 14709b5040..0000000000
--- a/packages/backend/src/server/api/endpoints/clips/show.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { Clips } from "@/models/index.js";
-
-export const meta = {
-	tags: ["clips", "account"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	kind: "read:account",
-
-	errors: {
-		noSuchClip: {
-			message: "No such clip.",
-			code: "NO_SUCH_CLIP",
-			id: "c3c5fe33-d62c-44d2-9ea5-d997703f5c20",
-		},
-	},
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "Clip",
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		clipId: { type: "string", format: "misskey:id" },
-	},
-	required: ["clipId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	// Fetch the clip
-	const clip = await Clips.findOneBy({
-		id: ps.clipId,
-	});
-
-	if (clip == null) {
-		throw new ApiError(meta.errors.noSuchClip);
-	}
-
-	if (!clip.isPublic && (me == null || clip.userId !== me.id)) {
-		throw new ApiError(meta.errors.noSuchClip);
-	}
-
-	return await Clips.pack(clip);
-});
diff --git a/packages/backend/src/server/api/endpoints/clips/update.ts b/packages/backend/src/server/api/endpoints/clips/update.ts
deleted file mode 100644
index e78f36e455..0000000000
--- a/packages/backend/src/server/api/endpoints/clips/update.ts
+++ /dev/null
@@ -1,62 +0,0 @@
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { Clips } from "@/models/index.js";
-
-export const meta = {
-	tags: ["clips"],
-
-	requireCredential: true,
-
-	kind: "write:account",
-
-	errors: {
-		noSuchClip: {
-			message: "No such clip.",
-			code: "NO_SUCH_CLIP",
-			id: "b4d92d70-b216-46fa-9a3f-a8c811699257",
-		},
-	},
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "Clip",
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		clipId: { type: "string", format: "misskey:id" },
-		name: { type: "string", minLength: 1, maxLength: 100 },
-		isPublic: { type: "boolean" },
-		description: {
-			type: "string",
-			nullable: true,
-			minLength: 1,
-			maxLength: 2048,
-		},
-	},
-	required: ["clipId", "name"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	// Fetch the clip
-	const clip = await Clips.findOneBy({
-		id: ps.clipId,
-		userId: user.id,
-	});
-
-	if (clip == null) {
-		throw new ApiError(meta.errors.noSuchClip);
-	}
-
-	await Clips.update(clip.id, {
-		name: ps.name,
-		description: ps.description,
-		isPublic: ps.isPublic,
-	});
-
-	return await Clips.pack(clip.id);
-});
diff --git a/packages/backend/src/server/api/endpoints/compatibility/custom-emojis.ts b/packages/backend/src/server/api/endpoints/compatibility/custom-emojis.ts
deleted file mode 100644
index 62e0836e85..0000000000
--- a/packages/backend/src/server/api/endpoints/compatibility/custom-emojis.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import { Emojis } from "@/models/index.js";
-import type { Emoji } from "@/models/entities/emoji.js";
-import { IsNull, In } from "typeorm";
-import { FILE_TYPE_BROWSERSAFE } from "@/const.js";
-import define from "../../define.js";
-
-export const meta = {
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-	allowGet: true,
-
-	tags: ["meta"],
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async () => {
-	const now = Date.now();
-	const emojis: Emoji[] = await Emojis.find({
-		where: { host: IsNull(), type: In(FILE_TYPE_BROWSERSAFE) },
-		select: ["name", "originalUrl", "publicUrl", "category"],
-	});
-
-	const emojiList = emojis.map((emoji) => ({
-		shortcode: emoji.name,
-		url: emoji.originalUrl,
-		static_url: emoji.publicUrl,
-		visible_in_picker: true,
-		category: emoji.category,
-	}));
-
-	return emojiList;
-});
diff --git a/packages/backend/src/server/api/endpoints/compatibility/instance-info.ts b/packages/backend/src/server/api/endpoints/compatibility/instance-info.ts
deleted file mode 100644
index 4e692568c5..0000000000
--- a/packages/backend/src/server/api/endpoints/compatibility/instance-info.ts
+++ /dev/null
@@ -1,232 +0,0 @@
-import * as mfm from "mfm-js";
-import { toHtml } from "@/mfm/to-html.js";
-import config from "@/config/index.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import {
-	Users,
-	Notes,
-	Instances,
-	UserProfiles,
-	Emojis,
-	DriveFiles,
-} from "@/models/index.js";
-import type { Emoji } from "@/models/entities/emoji.js";
-import type { User } from "@/models/entities/user.js";
-import { IsNull, In } from "typeorm";
-import { MAX_NOTE_TEXT_LENGTH, FILE_TYPE_BROWSERSAFE } from "@/const.js";
-import define from "../../define.js";
-
-export const meta = {
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-	allowGet: true,
-
-	tags: ["meta"],
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async () => {
-	const now = Date.now();
-	const [meta, total, localPosts, instanceCount, firstAdmin, emojis] =
-		await Promise.all([
-			fetchMeta(true),
-			Users.count({ where: { host: IsNull() } }),
-			Notes.count({ where: { userHost: IsNull(), replyId: IsNull() } }),
-			Instances.count(),
-			Users.findOne({
-				where: {
-					host: IsNull(),
-					isAdmin: true,
-					isDeleted: false,
-					isBot: false,
-				},
-				order: { id: "ASC" },
-			}),
-			Emojis.find({
-				where: { host: IsNull(), type: In(FILE_TYPE_BROWSERSAFE) },
-				select: ["id", "name", "originalUrl", "publicUrl"],
-			}).then((l) =>
-				l.reduce((a, e) => {
-					a[e.name] = e;
-					return a;
-				}, {} as Record<string, Emoji>),
-			),
-		]);
-
-	const descSplit = splitN(meta.description, "\n", 2);
-	const shortDesc = markup(descSplit.length > 0 ? descSplit[0] : "");
-	const longDesc = markup(meta.description ?? "");
-
-	return {
-		uri: config.hostname,
-		title: meta.name,
-		short_description: shortDesc,
-		description: longDesc,
-		email: meta.maintainerEmail,
-		version: config.version,
-		urls: {
-			streaming_api: `wss://${config.host}`,
-		},
-		stats: {
-			user_count: total,
-			status_count: localPosts,
-			domain_count: instanceCount,
-		},
-		thumbnail: meta.logoImageUrl,
-		languages: meta.langs,
-		registrations: !meta.disableRegistration,
-		approval_required: false,
-		invites_enabled: false,
-		configuration: {
-			accounts: {
-				max_featured_tags: 16,
-			},
-			statuses: {
-				max_characters: MAX_NOTE_TEXT_LENGTH,
-				max_media_attachments: 16,
-				characters_reserved_per_url: 0,
-			},
-			media_attachments: {
-				supported_mime_types: FILE_TYPE_BROWSERSAFE,
-				image_size_limit: 10485760,
-				image_matrix_limit: 16777216,
-				video_size_limit: 41943040,
-				video_frame_rate_limit: 60,
-				video_matrix_limit: 2304000,
-			},
-			polls: {
-				max_options: 10,
-				max_characters_per_option: 50,
-				min_expiration: 15,
-				max_expiration: -1,
-			},
-		},
-		contact_account: await getContact(firstAdmin, emojis),
-		rules: [],
-	};
-});
-
-const splitN = (s: string | null, split: string, n: number): string[] => {
-	const ret: string[] = [];
-	if (s == null) return ret;
-	if (s === "") {
-		ret.push(s);
-		return ret;
-	}
-
-	let start = 0;
-	let pos = s.indexOf(split);
-	if (pos === -1) {
-		ret.push(s);
-		return ret;
-	}
-
-	for (let i = 0; i < n - 1; i++) {
-		ret.push(s.substring(start, pos));
-		start = pos + split.length;
-		pos = s.indexOf(split, start);
-		if (pos === -1) break;
-	}
-	ret.push(s.substring(start));
-
-	return ret;
-};
-
-type ContactType = {
-	id: string;
-	username: string;
-	acct: string;
-	display_name: string;
-	note?: string;
-	noindex?: boolean;
-	fields?: {
-		name: string;
-		value: string;
-		verified_at: string | null;
-	}[];
-	locked: boolean;
-	bot: boolean;
-	created_at: string;
-	url: string;
-	followers_count: number;
-	following_count: number;
-	statuses_count: number;
-	last_status_at?: string;
-	emojis: any;
-} | null;
-
-const getContact = async (
-	user: User | null,
-	emojis: Record<string, Emoji>,
-): Promise<ContactType> => {
-	if (!user) return null;
-
-	let contact: ContactType = {
-		id: user.id,
-		username: user.username,
-		acct: user.username,
-		display_name: user.name ?? user.username,
-		locked: user.isLocked,
-		bot: user.isBot,
-		created_at: user.createdAt.toISOString(),
-		url: `${config.url}/@${user.username}`,
-		followers_count: user.followersCount,
-		following_count: user.followingCount,
-		statuses_count: user.notesCount,
-		last_status_at: user.lastActiveDate?.toISOString(),
-		emojis: emojis
-			? user.emojis
-					.filter((e, i, a) => e in emojis && a.indexOf(e) === i)
-					.map((e) => ({
-						shortcode: e,
-						static_url: emojis[e].publicUrl,
-						url: emojis[e].originalUrl,
-						visible_in_picker: true,
-					}))
-			: [],
-	};
-
-	const [profile] = await Promise.all([
-		UserProfiles.findOne({ where: { userId: user.id } }),
-		loadDriveFiles(contact, "avatar", user.avatarId),
-		loadDriveFiles(contact, "header", user.bannerId),
-	]);
-
-	if (!profile) {
-		return contact;
-	}
-
-	contact = {
-		...contact,
-		note: markup(profile.description ?? ""),
-		noindex: profile.noCrawle,
-		fields: profile.fields.map((f) => ({
-			name: f.name,
-			value: f.value,
-			verified_at: null,
-		})),
-	};
-
-	return contact;
-};
-
-const loadDriveFiles = async (
-	contact: any,
-	key: string,
-	fileId: string | null,
-) => {
-	if (fileId) {
-		const file = await DriveFiles.findOneBy({ id: fileId });
-		if (file) {
-			contact[key] = file.webpublicUrl ?? file.url;
-			contact[`${key}_static`] = contact[key];
-		}
-	}
-};
-
-const markup = (text: string): string => toHtml(mfm.parse(text)) ?? "";
diff --git a/packages/backend/src/server/api/endpoints/custom-motd.ts b/packages/backend/src/server/api/endpoints/custom-motd.ts
deleted file mode 100644
index 098a676a57..0000000000
--- a/packages/backend/src/server/api/endpoints/custom-motd.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-// import { IsNull } from 'typeorm';
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import define from "../define.js";
-
-export const meta = {
-	tags: ["meta"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "string",
-			optional: false,
-			nullable: false,
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async () => {
-	const meta = await fetchMeta();
-	const motd = await Promise.all(meta.customMOTD.map((x) => x));
-	return motd;
-});
diff --git a/packages/backend/src/server/api/endpoints/custom-splash-icons.ts b/packages/backend/src/server/api/endpoints/custom-splash-icons.ts
deleted file mode 100644
index c4833a4eef..0000000000
--- a/packages/backend/src/server/api/endpoints/custom-splash-icons.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-// import { IsNull } from 'typeorm';
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import define from "../define.js";
-
-export const meta = {
-	tags: ["meta"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "string",
-			optional: false,
-			nullable: false,
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async () => {
-	const meta = await fetchMeta();
-	const icons = await Promise.all(meta.customSplashIcons.map((x) => x));
-	return icons;
-});
diff --git a/packages/backend/src/server/api/endpoints/drive.ts b/packages/backend/src/server/api/endpoints/drive.ts
deleted file mode 100644
index ce98b53a6b..0000000000
--- a/packages/backend/src/server/api/endpoints/drive.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { DriveFiles } from "@/models/index.js";
-import define from "../define.js";
-
-export const meta = {
-	tags: ["drive", "account"],
-
-	requireCredential: true,
-
-	kind: "read:drive",
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		properties: {
-			capacity: {
-				type: "number",
-				optional: false,
-				nullable: false,
-			},
-			usage: {
-				type: "number",
-				optional: false,
-				nullable: false,
-			},
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const instance = await fetchMeta(true);
-
-	// Calculate drive usage
-	const usage = await DriveFiles.calcDriveUsageOf(user.id);
-
-	return {
-		capacity:
-			1024 *
-			1024 *
-			(user.driveCapacityOverrideMb || instance.localDriveCapacityMb),
-		usage: usage,
-	};
-});
diff --git a/packages/backend/src/server/api/endpoints/drive/files.ts b/packages/backend/src/server/api/endpoints/drive/files.ts
deleted file mode 100644
index c749e49038..0000000000
--- a/packages/backend/src/server/api/endpoints/drive/files.ts
+++ /dev/null
@@ -1,72 +0,0 @@
-import define from "../../define.js";
-import { DriveFiles } from "@/models/index.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-
-export const meta = {
-	tags: ["drive"],
-
-	requireCredential: true,
-
-	kind: "read:drive",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "DriveFile",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-		folderId: {
-			type: "string",
-			format: "misskey:id",
-			nullable: true,
-			default: null,
-		},
-		type: {
-			type: "string",
-			nullable: true,
-			pattern: /^[a-zA-Z\/\-*]+$/.toString().slice(1, -1),
-		},
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const query = makePaginationQuery(
-		DriveFiles.createQueryBuilder("file"),
-		ps.sinceId,
-		ps.untilId,
-	).andWhere("file.userId = :userId", { userId: user.id });
-
-	if (ps.folderId) {
-		query.andWhere("file.folderId = :folderId", { folderId: ps.folderId });
-	} else {
-		query.andWhere("file.folderId IS NULL");
-	}
-
-	if (ps.type) {
-		if (ps.type.endsWith("/*")) {
-			query.andWhere("file.type like :type", {
-				type: `${ps.type.replace("/*", "/")}%`,
-			});
-		} else {
-			query.andWhere("file.type = :type", { type: ps.type });
-		}
-	}
-
-	const files = await query.take(ps.limit).getMany();
-
-	return await DriveFiles.packMany(files, { detail: false, self: true });
-});
diff --git a/packages/backend/src/server/api/endpoints/drive/files/attached-notes.ts b/packages/backend/src/server/api/endpoints/drive/files/attached-notes.ts
deleted file mode 100644
index 9267da5856..0000000000
--- a/packages/backend/src/server/api/endpoints/drive/files/attached-notes.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-import { DriveFiles, Notes } from "@/models/index.js";
-
-export const meta = {
-	tags: ["drive", "notes"],
-
-	requireCredential: true,
-
-	kind: "read:drive",
-
-	description: "Find the notes to which the given file is attached.",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Note",
-		},
-	},
-
-	errors: {
-		noSuchFile: {
-			message: "No such file.",
-			code: "NO_SUCH_FILE",
-			id: "c118ece3-2e4b-4296-99d1-51756e32d232",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		fileId: { type: "string", format: "misskey:id" },
-	},
-	required: ["fileId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	// Fetch file
-	const file = await DriveFiles.findOneBy({
-		id: ps.fileId,
-		userId: user.id,
-	});
-
-	if (file == null) {
-		throw new ApiError(meta.errors.noSuchFile);
-	}
-
-	const notes = await Notes.createQueryBuilder("note")
-		.where(":file = ANY(note.fileIds)", { file: file.id })
-		.getMany();
-
-	return await Notes.packMany(notes, user, {
-		detail: true,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/drive/files/caption-image.ts b/packages/backend/src/server/api/endpoints/drive/files/caption-image.ts
deleted file mode 100644
index 1ab817bd0c..0000000000
--- a/packages/backend/src/server/api/endpoints/drive/files/caption-image.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import define from "../../../define.js";
-import { createWorker } from "tesseract.js";
-
-export const meta = {
-	tags: ["drive"],
-
-	requireCredential: true,
-
-	kind: "read:drive",
-
-	description: "Return caption of image",
-
-	res: {
-		type: "string",
-		optional: false,
-		nullable: false,
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		url: { type: "string" },
-	},
-	required: ["url"],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	const worker = createWorker({
-		logger: (m) => console.log(m),
-	});
-
-	await worker.load();
-	await worker.loadLanguage("eng");
-	await worker.initialize("eng");
-	const {
-		data: { text },
-	} = await worker.recognize(ps.url);
-	await worker.terminate();
-
-	return text;
-});
diff --git a/packages/backend/src/server/api/endpoints/drive/files/check-existence.ts b/packages/backend/src/server/api/endpoints/drive/files/check-existence.ts
deleted file mode 100644
index df89685201..0000000000
--- a/packages/backend/src/server/api/endpoints/drive/files/check-existence.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import define from "../../../define.js";
-import { DriveFiles } from "@/models/index.js";
-
-export const meta = {
-	tags: ["drive"],
-
-	requireCredential: true,
-
-	kind: "read:drive",
-
-	description: "Check if a given file exists.",
-
-	res: {
-		type: "boolean",
-		optional: false,
-		nullable: false,
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		md5: { type: "string" },
-	},
-	required: ["md5"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const file = await DriveFiles.findOneBy({
-		md5: ps.md5,
-		userId: user.id,
-	});
-
-	return file != null;
-});
diff --git a/packages/backend/src/server/api/endpoints/drive/files/create.ts b/packages/backend/src/server/api/endpoints/drive/files/create.ts
deleted file mode 100644
index 0a167178b2..0000000000
--- a/packages/backend/src/server/api/endpoints/drive/files/create.ts
+++ /dev/null
@@ -1,129 +0,0 @@
-import { addFile } from "@/services/drive/add-file.js";
-import { DriveFiles } from "@/models/index.js";
-import { DB_MAX_IMAGE_COMMENT_LENGTH } from "@/misc/hard-limits.js";
-import { IdentifiableError } from "@/misc/identifiable-error.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { HOUR } from "@/const.js";
-import define from "../../../define.js";
-import { apiLogger } from "../../../logger.js";
-import { ApiError } from "../../../error.js";
-
-export const meta = {
-	tags: ["drive"],
-
-	requireCredential: true,
-
-	limit: {
-		duration: HOUR,
-		max: 120,
-	},
-
-	requireFile: true,
-
-	kind: "write:drive",
-
-	description: "Upload a new drive file.",
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "DriveFile",
-	},
-
-	errors: {
-		invalidFileName: {
-			message: "Invalid file name.",
-			code: "INVALID_FILE_NAME",
-			id: "f449b209-0c60-4e51-84d5-29486263bfd4",
-		},
-
-		inappropriate: {
-			message:
-				"Cannot upload the file because it has been determined that it possibly contains inappropriate content.",
-			code: "INAPPROPRIATE",
-			id: "bec5bd69-fba3-43c9-b4fb-2894b66ad5d2",
-		},
-
-		noFreeSpace: {
-			message:
-				"Cannot upload the file because you have no free space of drive.",
-			code: "NO_FREE_SPACE",
-			id: "d08dbc37-a6a9-463a-8c47-96c32ab5f064",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		folderId: {
-			type: "string",
-			format: "misskey:id",
-			nullable: true,
-			default: null,
-		},
-		name: { type: "string", nullable: true, default: null },
-		comment: {
-			type: "string",
-			nullable: true,
-			maxLength: DB_MAX_IMAGE_COMMENT_LENGTH,
-			default: null,
-		},
-		isSensitive: { type: "boolean", default: false },
-		force: { type: "boolean", default: false },
-	},
-	required: [],
-} as const;
-
-export default define(
-	meta,
-	paramDef,
-	async (ps, user, _, file, cleanup, ip, headers) => {
-		// Get 'name' parameter
-		let name = ps.name || file.originalname;
-		if (name !== undefined && name !== null) {
-			name = name.trim();
-			if (name.length === 0) {
-				name = null;
-			} else if (name === "blob") {
-				name = null;
-			} else if (!DriveFiles.validateFileName(name)) {
-				throw new ApiError(meta.errors.invalidFileName);
-			}
-		} else {
-			name = null;
-		}
-
-		const meta = await fetchMeta();
-
-		try {
-			// Create file
-			const driveFile = await addFile({
-				user,
-				path: file.path,
-				name,
-				comment: ps.comment,
-				folderId: ps.folderId,
-				force: ps.force,
-				sensitive: ps.isSensitive,
-				requestIp: meta.enableIpLogging ? ip : null,
-				requestHeaders: meta.enableIpLogging ? headers : null,
-			});
-			return await DriveFiles.pack(driveFile, { self: true });
-		} catch (e) {
-			if (e instanceof Error || typeof e === "string") {
-				apiLogger.error(e);
-			}
-			if (e instanceof IdentifiableError) {
-				if (e.id === "282f77bf-5816-4f72-9264-aa14d8261a21")
-					throw new ApiError(meta.errors.inappropriate);
-				if (e.id === "c6244ed2-a39a-4e1c-bf93-f0fbd7764fa6")
-					throw new ApiError(meta.errors.noFreeSpace);
-			}
-			throw new ApiError();
-		} finally {
-			cleanup!();
-		}
-	},
-);
diff --git a/packages/backend/src/server/api/endpoints/drive/files/delete.ts b/packages/backend/src/server/api/endpoints/drive/files/delete.ts
deleted file mode 100644
index 4e8b4156f3..0000000000
--- a/packages/backend/src/server/api/endpoints/drive/files/delete.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-import { deleteFile } from "@/services/drive/delete-file.js";
-import { publishDriveStream } from "@/services/stream.js";
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-import { DriveFiles, Users } from "@/models/index.js";
-
-export const meta = {
-	tags: ["drive"],
-
-	requireCredential: true,
-
-	kind: "write:drive",
-
-	description: "Delete an existing drive file.",
-
-	errors: {
-		noSuchFile: {
-			message: "No such file.",
-			code: "NO_SUCH_FILE",
-			id: "908939ec-e52b-4458-b395-1025195cea58",
-		},
-
-		accessDenied: {
-			message: "Access denied.",
-			code: "ACCESS_DENIED",
-			id: "5eb8d909-2540-4970-90b8-dd6f86088121",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		fileId: { type: "string", format: "misskey:id" },
-	},
-	required: ["fileId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const file = await DriveFiles.findOneBy({ id: ps.fileId });
-
-	if (file == null) {
-		throw new ApiError(meta.errors.noSuchFile);
-	}
-
-	if (!(user.isAdmin || user.isModerator) && file.userId !== user.id) {
-		throw new ApiError(meta.errors.accessDenied);
-	}
-
-	// Delete
-	await deleteFile(file);
-
-	// Publish fileDeleted event
-	publishDriveStream(user.id, "fileDeleted", file.id);
-});
diff --git a/packages/backend/src/server/api/endpoints/drive/files/find-by-hash.ts b/packages/backend/src/server/api/endpoints/drive/files/find-by-hash.ts
deleted file mode 100644
index ce14f4e09e..0000000000
--- a/packages/backend/src/server/api/endpoints/drive/files/find-by-hash.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import { DriveFiles } from "@/models/index.js";
-import define from "../../../define.js";
-
-export const meta = {
-	tags: ["drive"],
-
-	requireCredential: true,
-
-	kind: "read:drive",
-
-	description: "Search for a drive file by a hash of the contents.",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "DriveFile",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		md5: { type: "string" },
-	},
-	required: ["md5"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const files = await DriveFiles.findBy({
-		md5: ps.md5,
-		userId: user.id,
-	});
-
-	return await DriveFiles.packMany(files, { self: true });
-});
diff --git a/packages/backend/src/server/api/endpoints/drive/files/find.ts b/packages/backend/src/server/api/endpoints/drive/files/find.ts
deleted file mode 100644
index c2ad95126f..0000000000
--- a/packages/backend/src/server/api/endpoints/drive/files/find.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import define from "../../../define.js";
-import { DriveFiles } from "@/models/index.js";
-import { IsNull } from "typeorm";
-
-export const meta = {
-	requireCredential: true,
-
-	tags: ["drive"],
-
-	kind: "read:drive",
-
-	description: "Search for a drive file by the given parameters.",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "DriveFile",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		name: { type: "string" },
-		folderId: {
-			type: "string",
-			format: "misskey:id",
-			nullable: true,
-			default: null,
-		},
-	},
-	required: ["name"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const files = await DriveFiles.findBy({
-		name: ps.name,
-		userId: user.id,
-		folderId: ps.folderId ?? IsNull(),
-	});
-
-	return await Promise.all(
-		files.map((file) => DriveFiles.pack(file, { self: true })),
-	);
-});
diff --git a/packages/backend/src/server/api/endpoints/drive/files/show.ts b/packages/backend/src/server/api/endpoints/drive/files/show.ts
deleted file mode 100644
index 291e3f56bb..0000000000
--- a/packages/backend/src/server/api/endpoints/drive/files/show.ts
+++ /dev/null
@@ -1,89 +0,0 @@
-import type { DriveFile } from "@/models/entities/drive-file.js";
-import { DriveFiles, Users } from "@/models/index.js";
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-
-export const meta = {
-	tags: ["drive"],
-
-	requireCredential: true,
-
-	kind: "read:drive",
-
-	description: "Show the properties of a drive file.",
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "DriveFile",
-	},
-
-	errors: {
-		noSuchFile: {
-			message: "No such file.",
-			code: "NO_SUCH_FILE",
-			id: "067bc436-2718-4795-b0fb-ecbe43949e31",
-		},
-
-		accessDenied: {
-			message: "Access denied.",
-			code: "ACCESS_DENIED",
-			id: "25b73c73-68b1-41d0-bad1-381cfdf6579f",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	anyOf: [
-		{
-			properties: {
-				fileId: { type: "string", format: "misskey:id" },
-			},
-			required: ["fileId"],
-		},
-		{
-			properties: {
-				url: { type: "string" },
-			},
-			required: ["url"],
-		},
-	],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	let file: DriveFile | null = null;
-
-	if (ps.fileId) {
-		file = await DriveFiles.findOneBy({ id: ps.fileId });
-	} else if (ps.url) {
-		file = await DriveFiles.findOne({
-			where: [
-				{
-					url: ps.url,
-				},
-				{
-					webpublicUrl: ps.url,
-				},
-				{
-					thumbnailUrl: ps.url,
-				},
-			],
-		});
-	}
-
-	if (file == null) {
-		throw new ApiError(meta.errors.noSuchFile);
-	}
-
-	if (!(user.isAdmin || user.isModerator) && file.userId !== user.id) {
-		throw new ApiError(meta.errors.accessDenied);
-	}
-
-	return await DriveFiles.pack(file, {
-		detail: true,
-		withUser: true,
-		self: true,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/drive/files/update.ts b/packages/backend/src/server/api/endpoints/drive/files/update.ts
deleted file mode 100644
index e833fddb58..0000000000
--- a/packages/backend/src/server/api/endpoints/drive/files/update.ts
+++ /dev/null
@@ -1,116 +0,0 @@
-import { publishDriveStream } from "@/services/stream.js";
-import { DriveFiles, DriveFolders, Users } from "@/models/index.js";
-import { DB_MAX_IMAGE_COMMENT_LENGTH } from "@/misc/hard-limits.js";
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-
-export const meta = {
-	tags: ["drive"],
-
-	requireCredential: true,
-
-	kind: "write:drive",
-
-	description: "Update the properties of a drive file.",
-
-	errors: {
-		invalidFileName: {
-			message: "Invalid file name.",
-			code: "INVALID_FILE_NAME",
-			id: "395e7156-f9f0-475e-af89-53c3c23080c2",
-		},
-
-		noSuchFile: {
-			message: "No such file.",
-			code: "NO_SUCH_FILE",
-			id: "e7778c7e-3af9-49cd-9690-6dbc3e6c972d",
-		},
-
-		accessDenied: {
-			message: "Access denied.",
-			code: "ACCESS_DENIED",
-			id: "01a53b27-82fc-445b-a0c1-b558465a8ed2",
-		},
-
-		noSuchFolder: {
-			message: "No such folder.",
-			code: "NO_SUCH_FOLDER",
-			id: "ea8fb7a5-af77-4a08-b608-c0218176cd73",
-		},
-	},
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "DriveFile",
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		fileId: { type: "string", format: "misskey:id" },
-		folderId: { type: "string", format: "misskey:id", nullable: true },
-		name: { type: "string" },
-		isSensitive: { type: "boolean" },
-		comment: {
-			type: "string",
-			nullable: true,
-			maxLength: DB_MAX_IMAGE_COMMENT_LENGTH,
-		},
-	},
-	required: ["fileId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const file = await DriveFiles.findOneBy({ id: ps.fileId });
-
-	if (file == null) {
-		throw new ApiError(meta.errors.noSuchFile);
-	}
-
-	if (!(user.isAdmin || user.isModerator) && file.userId !== user.id) {
-		throw new ApiError(meta.errors.accessDenied);
-	}
-
-	if (ps.name) file.name = ps.name;
-	if (!DriveFiles.validateFileName(file.name)) {
-		throw new ApiError(meta.errors.invalidFileName);
-	}
-
-	if (ps.comment !== undefined) file.comment = ps.comment;
-
-	if (ps.isSensitive !== undefined) file.isSensitive = ps.isSensitive;
-
-	if (ps.folderId !== undefined) {
-		if (ps.folderId === null) {
-			file.folderId = null;
-		} else {
-			const folder = await DriveFolders.findOneBy({
-				id: ps.folderId,
-				userId: user.id,
-			});
-
-			if (folder == null) {
-				throw new ApiError(meta.errors.noSuchFolder);
-			}
-
-			file.folderId = folder.id;
-		}
-	}
-
-	await DriveFiles.update(file.id, {
-		name: file.name,
-		comment: file.comment,
-		folderId: file.folderId,
-		isSensitive: file.isSensitive,
-	});
-
-	const fileObj = await DriveFiles.pack(file, { self: true });
-
-	// Publish fileUpdated event
-	publishDriveStream(user.id, "fileUpdated", fileObj);
-
-	return fileObj;
-});
diff --git a/packages/backend/src/server/api/endpoints/drive/files/upload-from-url.ts b/packages/backend/src/server/api/endpoints/drive/files/upload-from-url.ts
deleted file mode 100644
index 7bb47dbef5..0000000000
--- a/packages/backend/src/server/api/endpoints/drive/files/upload-from-url.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-import { uploadFromUrl } from "@/services/drive/upload-from-url.js";
-import define from "../../../define.js";
-import { DriveFiles } from "@/models/index.js";
-import { publishMainStream } from "@/services/stream.js";
-import { HOUR } from "@/const.js";
-
-export const meta = {
-	tags: ["drive"],
-
-	limit: {
-		duration: HOUR,
-		max: 60,
-	},
-
-	description:
-		"Request the server to download a new drive file from the specified URL.",
-
-	requireCredential: true,
-
-	kind: "write:drive",
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		url: { type: "string" },
-		folderId: {
-			type: "string",
-			format: "misskey:id",
-			nullable: true,
-			default: null,
-		},
-		isSensitive: { type: "boolean", default: false },
-		comment: { type: "string", nullable: true, maxLength: 512, default: null },
-		marker: { type: "string", nullable: true, default: null },
-		force: { type: "boolean", default: false },
-	},
-	required: ["url"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	uploadFromUrl({
-		url: ps.url,
-		user,
-		folderId: ps.folderId,
-		sensitive: ps.isSensitive,
-		force: ps.force,
-		comment: ps.comment,
-	}).then((file) => {
-		DriveFiles.pack(file, { self: true }).then((packedFile) => {
-			publishMainStream(user.id, "urlUploadFinished", {
-				marker: ps.marker,
-				file: packedFile,
-			});
-		});
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/drive/folders.ts b/packages/backend/src/server/api/endpoints/drive/folders.ts
deleted file mode 100644
index ed0d38844b..0000000000
--- a/packages/backend/src/server/api/endpoints/drive/folders.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-import define from "../../define.js";
-import { DriveFolders } from "@/models/index.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-
-export const meta = {
-	tags: ["drive"],
-
-	requireCredential: true,
-
-	kind: "read:drive",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "DriveFolder",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-		folderId: {
-			type: "string",
-			format: "misskey:id",
-			nullable: true,
-			default: null,
-		},
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const query = makePaginationQuery(
-		DriveFolders.createQueryBuilder("folder"),
-		ps.sinceId,
-		ps.untilId,
-	).andWhere("folder.userId = :userId", { userId: user.id });
-
-	if (ps.folderId) {
-		query.andWhere("folder.parentId = :parentId", { parentId: ps.folderId });
-	} else {
-		query.andWhere("folder.parentId IS NULL");
-	}
-
-	const folders = await query.take(ps.limit).getMany();
-
-	return await Promise.all(folders.map((folder) => DriveFolders.pack(folder)));
-});
diff --git a/packages/backend/src/server/api/endpoints/drive/folders/create.ts b/packages/backend/src/server/api/endpoints/drive/folders/create.ts
deleted file mode 100644
index d50f5f2815..0000000000
--- a/packages/backend/src/server/api/endpoints/drive/folders/create.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-import { publishDriveStream } from "@/services/stream.js";
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-import { DriveFolders } from "@/models/index.js";
-import { genId } from "@/misc/gen-id.js";
-
-export const meta = {
-	tags: ["drive"],
-
-	requireCredential: true,
-
-	kind: "write:drive",
-
-	errors: {
-		noSuchFolder: {
-			message: "No such folder.",
-			code: "NO_SUCH_FOLDER",
-			id: "53326628-a00d-40a6-a3cd-8975105c0f95",
-		},
-	},
-
-	res: {
-		type: "object" as const,
-		optional: false as const,
-		nullable: false as const,
-		ref: "DriveFolder",
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		name: { type: "string", default: "Untitled", maxLength: 200 },
-		parentId: { type: "string", format: "misskey:id", nullable: true },
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	// If the parent folder is specified
-	let parent = null;
-	if (ps.parentId) {
-		// Fetch parent folder
-		parent = await DriveFolders.findOneBy({
-			id: ps.parentId,
-			userId: user.id,
-		});
-
-		if (parent == null) {
-			throw new ApiError(meta.errors.noSuchFolder);
-		}
-	}
-
-	// Create folder
-	const folder = await DriveFolders.insert({
-		id: genId(),
-		createdAt: new Date(),
-		name: ps.name,
-		parentId: parent !== null ? parent.id : null,
-		userId: user.id,
-	}).then((x) => DriveFolders.findOneByOrFail(x.identifiers[0]));
-
-	const folderObj = await DriveFolders.pack(folder);
-
-	// Publish folderCreated event
-	publishDriveStream(user.id, "folderCreated", folderObj);
-
-	return folderObj;
-});
diff --git a/packages/backend/src/server/api/endpoints/drive/folders/delete.ts b/packages/backend/src/server/api/endpoints/drive/folders/delete.ts
deleted file mode 100644
index 98895a7320..0000000000
--- a/packages/backend/src/server/api/endpoints/drive/folders/delete.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-import define from "../../../define.js";
-import { publishDriveStream } from "@/services/stream.js";
-import { ApiError } from "../../../error.js";
-import { DriveFolders, DriveFiles } from "@/models/index.js";
-
-export const meta = {
-	tags: ["drive"],
-
-	requireCredential: true,
-
-	kind: "write:drive",
-
-	errors: {
-		noSuchFolder: {
-			message: "No such folder.",
-			code: "NO_SUCH_FOLDER",
-			id: "1069098f-c281-440f-b085-f9932edbe091",
-		},
-
-		hasChildFilesOrFolders: {
-			message: "This folder has child files or folders.",
-			code: "HAS_CHILD_FILES_OR_FOLDERS",
-			id: "b0fc8a17-963c-405d-bfbc-859a487295e1",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		folderId: { type: "string", format: "misskey:id" },
-	},
-	required: ["folderId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	// Get folder
-	const folder = await DriveFolders.findOneBy({
-		id: ps.folderId,
-		userId: user.id,
-	});
-
-	if (folder == null) {
-		throw new ApiError(meta.errors.noSuchFolder);
-	}
-
-	const [childFoldersCount, childFilesCount] = await Promise.all([
-		DriveFolders.countBy({ parentId: folder.id }),
-		DriveFiles.countBy({ folderId: folder.id }),
-	]);
-
-	if (childFoldersCount !== 0 || childFilesCount !== 0) {
-		throw new ApiError(meta.errors.hasChildFilesOrFolders);
-	}
-
-	await DriveFolders.delete(folder.id);
-
-	// Publish folderCreated event
-	publishDriveStream(user.id, "folderDeleted", folder.id);
-});
diff --git a/packages/backend/src/server/api/endpoints/drive/folders/find.ts b/packages/backend/src/server/api/endpoints/drive/folders/find.ts
deleted file mode 100644
index 45451fb90b..0000000000
--- a/packages/backend/src/server/api/endpoints/drive/folders/find.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import define from "../../../define.js";
-import { DriveFolders } from "@/models/index.js";
-import { IsNull } from "typeorm";
-
-export const meta = {
-	tags: ["drive"],
-
-	requireCredential: true,
-
-	kind: "read:drive",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "DriveFolder",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		name: { type: "string" },
-		parentId: {
-			type: "string",
-			format: "misskey:id",
-			nullable: true,
-			default: null,
-		},
-	},
-	required: ["name"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const folders = await DriveFolders.findBy({
-		name: ps.name,
-		userId: user.id,
-		parentId: ps.parentId ?? IsNull(),
-	});
-
-	return await Promise.all(folders.map((folder) => DriveFolders.pack(folder)));
-});
diff --git a/packages/backend/src/server/api/endpoints/drive/folders/show.ts b/packages/backend/src/server/api/endpoints/drive/folders/show.ts
deleted file mode 100644
index 6a72a22777..0000000000
--- a/packages/backend/src/server/api/endpoints/drive/folders/show.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-import { DriveFolders } from "@/models/index.js";
-
-export const meta = {
-	tags: ["drive"],
-
-	requireCredential: true,
-
-	kind: "read:drive",
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "DriveFolder",
-	},
-
-	errors: {
-		noSuchFolder: {
-			message: "No such folder.",
-			code: "NO_SUCH_FOLDER",
-			id: "d74ab9eb-bb09-4bba-bf24-fb58f761e1e9",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		folderId: { type: "string", format: "misskey:id" },
-	},
-	required: ["folderId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	// Get folder
-	const folder = await DriveFolders.findOneBy({
-		id: ps.folderId,
-		userId: user.id,
-	});
-
-	if (folder == null) {
-		throw new ApiError(meta.errors.noSuchFolder);
-	}
-
-	return await DriveFolders.pack(folder, {
-		detail: true,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/drive/folders/update.ts b/packages/backend/src/server/api/endpoints/drive/folders/update.ts
deleted file mode 100644
index 929a69bdec..0000000000
--- a/packages/backend/src/server/api/endpoints/drive/folders/update.ts
+++ /dev/null
@@ -1,118 +0,0 @@
-import { publishDriveStream } from "@/services/stream.js";
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-import { DriveFolders } from "@/models/index.js";
-
-export const meta = {
-	tags: ["drive"],
-
-	requireCredential: true,
-
-	kind: "write:drive",
-
-	errors: {
-		noSuchFolder: {
-			message: "No such folder.",
-			code: "NO_SUCH_FOLDER",
-			id: "f7974dac-2c0d-4a27-926e-23583b28e98e",
-		},
-
-		noSuchParentFolder: {
-			message: "No such parent folder.",
-			code: "NO_SUCH_PARENT_FOLDER",
-			id: "ce104e3a-faaf-49d5-b459-10ff0cbbcaa1",
-		},
-
-		recursiveNesting: {
-			message: "It can not be structured like nesting folders recursively.",
-			code: "NO_SUCH_PARENT_FOLDER",
-			id: "ce104e3a-faaf-49d5-b459-10ff0cbbcaa1",
-		},
-	},
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "DriveFolder",
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		folderId: { type: "string", format: "misskey:id" },
-		name: { type: "string", maxLength: 200 },
-		parentId: { type: "string", format: "misskey:id", nullable: true },
-	},
-	required: ["folderId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	// Fetch folder
-	const folder = await DriveFolders.findOneBy({
-		id: ps.folderId,
-		userId: user.id,
-	});
-
-	if (folder == null) {
-		throw new ApiError(meta.errors.noSuchFolder);
-	}
-
-	if (ps.name) folder.name = ps.name;
-
-	if (ps.parentId !== undefined) {
-		if (ps.parentId === folder.id) {
-			throw new ApiError(meta.errors.recursiveNesting);
-		} else if (ps.parentId === null) {
-			folder.parentId = null;
-		} else {
-			// Get parent folder
-			const parent = await DriveFolders.findOneBy({
-				id: ps.parentId,
-				userId: user.id,
-			});
-
-			if (parent == null) {
-				throw new ApiError(meta.errors.noSuchParentFolder);
-			}
-
-			// Check if the circular reference will occur
-			async function checkCircle(folderId: string): Promise<boolean> {
-				// Fetch folder
-				const folder2 = await DriveFolders.findOneBy({
-					id: folderId,
-				});
-
-				if (folder2!.id === folder!.id) {
-					return true;
-				} else if (folder2!.parentId) {
-					return await checkCircle(folder2!.parentId);
-				} else {
-					return false;
-				}
-			}
-
-			if (parent.parentId !== null) {
-				if (await checkCircle(parent.parentId)) {
-					throw new ApiError(meta.errors.recursiveNesting);
-				}
-			}
-
-			folder.parentId = parent.id;
-		}
-	}
-
-	// Update
-	DriveFolders.update(folder.id, {
-		name: folder.name,
-		parentId: folder.parentId,
-	});
-
-	const folderObj = await DriveFolders.pack(folder);
-
-	// Publish folderUpdated event
-	publishDriveStream(user.id, "folderUpdated", folderObj);
-
-	return folderObj;
-});
diff --git a/packages/backend/src/server/api/endpoints/drive/stream.ts b/packages/backend/src/server/api/endpoints/drive/stream.ts
deleted file mode 100644
index 0c9654ca23..0000000000
--- a/packages/backend/src/server/api/endpoints/drive/stream.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import define from "../../define.js";
-import { DriveFiles } from "@/models/index.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-
-export const meta = {
-	tags: ["drive"],
-
-	requireCredential: true,
-
-	kind: "read:drive",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "DriveFile",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-		type: {
-			type: "string",
-			pattern: /^[a-zA-Z\/\-*]+$/.toString().slice(1, -1),
-		},
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const query = makePaginationQuery(
-		DriveFiles.createQueryBuilder("file"),
-		ps.sinceId,
-		ps.untilId,
-	).andWhere("file.userId = :userId", { userId: user.id });
-
-	if (ps.type) {
-		if (ps.type.endsWith("/*")) {
-			query.andWhere("file.type like :type", {
-				type: `${ps.type.replace("/*", "/")}%`,
-			});
-		} else {
-			query.andWhere("file.type = :type", { type: ps.type });
-		}
-	}
-
-	const files = await query.take(ps.limit).getMany();
-
-	return await DriveFiles.packMany(files, { detail: false, self: true });
-});
diff --git a/packages/backend/src/server/api/endpoints/email-address/available.ts b/packages/backend/src/server/api/endpoints/email-address/available.ts
deleted file mode 100644
index dc3c5e4b8e..0000000000
--- a/packages/backend/src/server/api/endpoints/email-address/available.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import define from "../../define.js";
-import { validateEmailForAccount } from "@/services/validate-email-for-account.js";
-
-export const meta = {
-	tags: ["users"],
-
-	requireCredential: false,
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		properties: {
-			available: {
-				type: "boolean",
-				optional: false,
-				nullable: false,
-			},
-			reason: {
-				type: "string",
-				optional: false,
-				nullable: true,
-			},
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		emailAddress: { type: "string" },
-	},
-	required: ["emailAddress"],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	return await validateEmailForAccount(ps.emailAddress);
-});
diff --git a/packages/backend/src/server/api/endpoints/emoji.ts b/packages/backend/src/server/api/endpoints/emoji.ts
deleted file mode 100644
index ddfad77374..0000000000
--- a/packages/backend/src/server/api/endpoints/emoji.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-import { IsNull } from "typeorm";
-import { Emojis } from "@/models/index.js";
-import define from "../define.js";
-
-export const meta = {
-	tags: ["meta"],
-
-	requireCredential: false,
-	allowGet: true,
-	cacheSec: 3600,
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "Emoji",
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		name: {
-			type: "string",
-		},
-	},
-	required: ["name"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const emoji = await Emojis.findOneOrFail({
-		where: {
-			name: ps.name,
-			host: IsNull(),
-		},
-	});
-
-	return Emojis.pack(emoji);
-});
diff --git a/packages/backend/src/server/api/endpoints/endpoint.ts b/packages/backend/src/server/api/endpoints/endpoint.ts
deleted file mode 100644
index ad0ce45623..0000000000
--- a/packages/backend/src/server/api/endpoints/endpoint.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import define from "../define.js";
-import endpoints from "../endpoints.js";
-
-export const meta = {
-	requireCredential: false,
-
-	tags: ["meta"],
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		endpoint: { type: "string" },
-	},
-	required: ["endpoint"],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	const ep = endpoints.find((x) => x.name === ps.endpoint);
-	if (ep == null) return null;
-	return {
-		params: Object.entries(ep.params.properties || {}).map(([k, v]) => ({
-			name: k,
-			type: v.type.charAt(0).toUpperCase() + v.type.slice(1),
-		})),
-	};
-});
diff --git a/packages/backend/src/server/api/endpoints/endpoints.ts b/packages/backend/src/server/api/endpoints/endpoints.ts
deleted file mode 100644
index c5844f8437..0000000000
--- a/packages/backend/src/server/api/endpoints/endpoints.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import define from "../define.js";
-import endpoints from "../endpoints.js";
-
-export const meta = {
-	requireCredential: false,
-
-	tags: ["meta"],
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "string",
-			optional: false,
-			nullable: false,
-		},
-		example: [
-			"admin/abuse-user-reports",
-			"admin/accounts/create",
-			"admin/announcements/create",
-			"...",
-		],
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async () => {
-	return endpoints.map((x) => x.name);
-});
diff --git a/packages/backend/src/server/api/endpoints/export-custom-emojis.ts b/packages/backend/src/server/api/endpoints/export-custom-emojis.ts
deleted file mode 100644
index f4fc43c173..0000000000
--- a/packages/backend/src/server/api/endpoints/export-custom-emojis.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import { createExportCustomEmojisJob } from "@/queue/index.js";
-import define from "../define.js";
-import { HOUR } from "@/const.js";
-
-export const meta = {
-	secure: true,
-	requireCredential: true,
-	limit: {
-		duration: HOUR,
-		max: 1,
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	createExportCustomEmojisJob(user);
-});
diff --git a/packages/backend/src/server/api/endpoints/federation/followers.ts b/packages/backend/src/server/api/endpoints/federation/followers.ts
deleted file mode 100644
index 4c6d83abdb..0000000000
--- a/packages/backend/src/server/api/endpoints/federation/followers.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import define from "../../define.js";
-import { Followings } from "@/models/index.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-
-export const meta = {
-	tags: ["federation"],
-
-	requireCredential: true,
-	requireAdmin: true,
-	requireCredentialPrivateMode: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Following",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		host: { type: "string" },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-	},
-	required: ["host"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const query = makePaginationQuery(
-		Followings.createQueryBuilder("following"),
-		ps.sinceId,
-		ps.untilId,
-	).andWhere("following.followeeHost = :host", { host: ps.host });
-
-	const followings = await query.take(ps.limit).getMany();
-
-	return await Followings.packMany(followings, me, { populateFollowee: true });
-});
diff --git a/packages/backend/src/server/api/endpoints/federation/following.ts b/packages/backend/src/server/api/endpoints/federation/following.ts
deleted file mode 100644
index 88b168600b..0000000000
--- a/packages/backend/src/server/api/endpoints/federation/following.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import define from "../../define.js";
-import { Followings } from "@/models/index.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-
-export const meta = {
-	tags: ["federation"],
-
-	requireCredential: true,
-	requireAdmin: true,
-	requireCredentialPrivateMode: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Following",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		host: { type: "string" },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-	},
-	required: ["host"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const query = makePaginationQuery(
-		Followings.createQueryBuilder("following"),
-		ps.sinceId,
-		ps.untilId,
-	).andWhere("following.followerHost = :host", { host: ps.host });
-
-	const followings = await query.take(ps.limit).getMany();
-
-	return await Followings.packMany(followings, me, { populateFollowee: true });
-});
diff --git a/packages/backend/src/server/api/endpoints/federation/instances.ts b/packages/backend/src/server/api/endpoints/federation/instances.ts
deleted file mode 100644
index 8f6184b196..0000000000
--- a/packages/backend/src/server/api/endpoints/federation/instances.ts
+++ /dev/null
@@ -1,171 +0,0 @@
-import config from "@/config/index.js";
-import define from "../../define.js";
-import { Instances } from "@/models/index.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-
-export const meta = {
-	tags: ["federation"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "FederationInstance",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		host: {
-			type: "string",
-			nullable: true,
-			description: "Omit or use `null` to not filter by host.",
-		},
-		blocked: { type: "boolean", nullable: true },
-		notResponding: { type: "boolean", nullable: true },
-		suspended: { type: "boolean", nullable: true },
-		federating: { type: "boolean", nullable: true },
-		subscribing: { type: "boolean", nullable: true },
-		publishing: { type: "boolean", nullable: true },
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 30 },
-		offset: { type: "integer", default: 0 },
-		sort: { type: "string" },
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const query = Instances.createQueryBuilder("instance");
-
-	switch (ps.sort) {
-		case "+pubSub":
-			query
-				.orderBy("instance.followingCount", "DESC")
-				.orderBy("instance.followersCount", "DESC");
-			break;
-		case "-pubSub":
-			query
-				.orderBy("instance.followingCount", "ASC")
-				.orderBy("instance.followersCount", "ASC");
-			break;
-		case "+notes":
-			query.orderBy("instance.notesCount", "DESC");
-			break;
-		case "-notes":
-			query.orderBy("instance.notesCount", "ASC");
-			break;
-		case "+users":
-			query.orderBy("instance.usersCount", "DESC");
-			break;
-		case "-users":
-			query.orderBy("instance.usersCount", "ASC");
-			break;
-		case "+following":
-			query.orderBy("instance.followingCount", "DESC");
-			break;
-		case "-following":
-			query.orderBy("instance.followingCount", "ASC");
-			break;
-		case "+followers":
-			query.orderBy("instance.followersCount", "DESC");
-			break;
-		case "-followers":
-			query.orderBy("instance.followersCount", "ASC");
-			break;
-		case "+caughtAt":
-			query.orderBy("instance.caughtAt", "DESC");
-			break;
-		case "-caughtAt":
-			query.orderBy("instance.caughtAt", "ASC");
-			break;
-		case "+lastCommunicatedAt":
-			query.orderBy("instance.lastCommunicatedAt", "DESC");
-			break;
-		case "-lastCommunicatedAt":
-			query.orderBy("instance.lastCommunicatedAt", "ASC");
-			break;
-
-		default:
-			query.orderBy("instance.id", "DESC");
-			break;
-	}
-
-	if (typeof ps.blocked === "boolean") {
-		const meta = await fetchMeta(true);
-		if (ps.blocked) {
-			if (meta.blockedHosts.length === 0) {
-				return [];
-			}
-			query.andWhere("instance.host IN (:...blocks)", {
-				blocks: meta.blockedHosts,
-			});
-		} else if (meta.blockedHosts.length > 0) {
-			query.andWhere("instance.host NOT IN (:...blocks)", {
-				blocks: meta.blockedHosts,
-			});
-		}
-	}
-
-	if (typeof ps.notResponding === "boolean") {
-		if (ps.notResponding) {
-			query.andWhere("instance.isNotResponding = TRUE");
-		} else {
-			query.andWhere("instance.isNotResponding = FALSE");
-		}
-	}
-
-	if (typeof ps.suspended === "boolean") {
-		if (ps.suspended) {
-			query.andWhere("instance.isSuspended = TRUE");
-		} else {
-			query.andWhere("instance.isSuspended = FALSE");
-		}
-	}
-
-	if (typeof ps.federating === "boolean") {
-		if (ps.federating) {
-			query.andWhere(
-				"((instance.followingCount > 0) OR (instance.followersCount > 0))",
-			);
-		} else {
-			query.andWhere(
-				"((instance.followingCount = 0) AND (instance.followersCount = 0))",
-			);
-		}
-	}
-
-	if (typeof ps.subscribing === "boolean") {
-		if (ps.subscribing) {
-			query.andWhere("instance.followersCount > 0");
-		} else {
-			query.andWhere("instance.followersCount = 0");
-		}
-	}
-
-	if (typeof ps.publishing === "boolean") {
-		if (ps.publishing) {
-			query.andWhere("instance.followingCount > 0");
-		} else {
-			query.andWhere("instance.followingCount = 0");
-		}
-	}
-
-	if (ps.host) {
-		query.andWhere("instance.host like :host", {
-			host: `%${ps.host.toLowerCase()}%`,
-		});
-	}
-
-	const instances = await query.take(ps.limit).skip(ps.offset).getMany();
-
-	return await Instances.packMany(instances);
-});
diff --git a/packages/backend/src/server/api/endpoints/federation/show-instance.ts b/packages/backend/src/server/api/endpoints/federation/show-instance.ts
deleted file mode 100644
index 633bb57073..0000000000
--- a/packages/backend/src/server/api/endpoints/federation/show-instance.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import define from "../../define.js";
-import { Instances } from "@/models/index.js";
-import { toPuny } from "@/misc/convert-host.js";
-
-export const meta = {
-	tags: ["federation"],
-
-	requireCredential: true,
-	requireCredentialPrivateMode: true,
-
-	res: {
-		oneOf: [
-			{
-				type: "object",
-				ref: "FederationInstance",
-			},
-			{
-				type: "null",
-			},
-		],
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		host: { type: "string" },
-	},
-	required: ["host"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const instance = await Instances.findOneBy({ host: toPuny(ps.host) });
-
-	return instance ? await Instances.pack(instance) : null;
-});
diff --git a/packages/backend/src/server/api/endpoints/federation/stats.ts b/packages/backend/src/server/api/endpoints/federation/stats.ts
deleted file mode 100644
index ede7a56c27..0000000000
--- a/packages/backend/src/server/api/endpoints/federation/stats.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-import { IsNull, MoreThan, Not } from "typeorm";
-import { Followings, Instances } from "@/models/index.js";
-import { awaitAll } from "@/prelude/await-all.js";
-import define from "../../define.js";
-
-export const meta = {
-	tags: ["federation"],
-
-	requireCredential: false,
-
-	allowGet: true,
-	cacheSec: 60 * 60,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	const [topSubInstances, topPubInstances, allSubCount, allPubCount] =
-		await Promise.all([
-			Instances.find({
-				where: {
-					followersCount: MoreThan(0),
-				},
-				order: {
-					followersCount: "DESC",
-				},
-				take: ps.limit,
-			}),
-			Instances.find({
-				where: {
-					followingCount: MoreThan(0),
-				},
-				order: {
-					followingCount: "DESC",
-				},
-				take: ps.limit,
-			}),
-			Followings.count({
-				where: {
-					followeeHost: Not(IsNull()),
-				},
-			}),
-			Followings.count({
-				where: {
-					followerHost: Not(IsNull()),
-				},
-			}),
-		]);
-
-	const gotSubCount = topSubInstances
-		.map((x) => x.followersCount)
-		.reduce((a, b) => a + b, 0);
-	const gotPubCount = topPubInstances
-		.map((x) => x.followingCount)
-		.reduce((a, b) => a + b, 0);
-
-	return await awaitAll({
-		topSubInstances: Instances.packMany(topSubInstances),
-		otherFollowersCount: Math.max(0, allSubCount - gotSubCount),
-		topPubInstances: Instances.packMany(topPubInstances),
-		otherFollowingCount: Math.max(0, allPubCount - gotPubCount),
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/federation/update-remote-user.ts b/packages/backend/src/server/api/endpoints/federation/update-remote-user.ts
deleted file mode 100644
index f4c3f6d18c..0000000000
--- a/packages/backend/src/server/api/endpoints/federation/update-remote-user.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import define from "../../define.js";
-import { getRemoteUser } from "../../common/getters.js";
-import { updatePerson } from "@/remote/activitypub/models/person.js";
-
-export const meta = {
-	tags: ["federation"],
-
-	requireCredential: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		userId: { type: "string", format: "misskey:id" },
-	},
-	required: ["userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	const user = await getRemoteUser(ps.userId);
-	await updatePerson(user.uri!);
-});
diff --git a/packages/backend/src/server/api/endpoints/federation/users.ts b/packages/backend/src/server/api/endpoints/federation/users.ts
deleted file mode 100644
index ded0a26c5f..0000000000
--- a/packages/backend/src/server/api/endpoints/federation/users.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import define from "../../define.js";
-import { Users } from "@/models/index.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-
-export const meta = {
-	tags: ["federation"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "UserDetailedNotMe",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		host: { type: "string" },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-	},
-	required: ["host"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const query = makePaginationQuery(
-		Users.createQueryBuilder("user"),
-		ps.sinceId,
-		ps.untilId,
-	).andWhere("user.host = :host", { host: ps.host });
-
-	const users = await query.take(ps.limit).getMany();
-
-	return await Users.packMany(users, me, { detail: true });
-});
diff --git a/packages/backend/src/server/api/endpoints/fetch-rss.ts b/packages/backend/src/server/api/endpoints/fetch-rss.ts
deleted file mode 100644
index b73d7262c9..0000000000
--- a/packages/backend/src/server/api/endpoints/fetch-rss.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import Parser from "rss-parser";
-import { getResponse } from "@/misc/fetch.js";
-import config from "@/config/index.js";
-import define from "../define.js";
-
-const rssParser = new Parser();
-
-export const meta = {
-	tags: ["meta"],
-
-	requireCredential: false,
-	allowGet: true,
-	cacheSec: 60 * 3,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		url: { type: "string" },
-	},
-	required: ["url"],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	const res = await getResponse({
-		url: ps.url,
-		method: "GET",
-		headers: Object.assign({
-			"User-Agent": config.userAgent,
-			Accept: "application/rss+xml, */*",
-		}),
-		timeout: 5000,
-	});
-
-	const text = await res.text();
-
-	return rssParser.parseString(text);
-});
diff --git a/packages/backend/src/server/api/endpoints/following/create.ts b/packages/backend/src/server/api/endpoints/following/create.ts
deleted file mode 100644
index e617c1ffb3..0000000000
--- a/packages/backend/src/server/api/endpoints/following/create.ts
+++ /dev/null
@@ -1,107 +0,0 @@
-import create from "@/services/following/create.js";
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { getUser } from "../../common/getters.js";
-import { Followings, Users } from "@/models/index.js";
-import { IdentifiableError } from "@/misc/identifiable-error.js";
-import { HOUR } from "@/const.js";
-
-export const meta = {
-	tags: ["following", "users"],
-
-	limit: {
-		duration: HOUR,
-		max: 100,
-	},
-
-	requireCredential: true,
-
-	kind: "write:following",
-
-	errors: {
-		noSuchUser: {
-			message: "No such user.",
-			code: "NO_SUCH_USER",
-			id: "fcd2eef9-a9b2-4c4f-8624-038099e90aa5",
-		},
-
-		followeeIsYourself: {
-			message: "Followee is yourself.",
-			code: "FOLLOWEE_IS_YOURSELF",
-			id: "26fbe7bb-a331-4857-af17-205b426669a9",
-		},
-
-		alreadyFollowing: {
-			message: "You are already following that user.",
-			code: "ALREADY_FOLLOWING",
-			id: "35387507-38c7-4cb9-9197-300b93783fa0",
-		},
-
-		blocking: {
-			message: "You are blocking that user.",
-			code: "BLOCKING",
-			id: "4e2206ec-aa4f-4960-b865-6c23ac38e2d9",
-		},
-
-		blocked: {
-			message: "You are blocked by that user.",
-			code: "BLOCKED",
-			id: "c4ab57cc-4e41-45e9-bfd9-584f61e35ce0",
-		},
-	},
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "UserLite",
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		userId: { type: "string", format: "misskey:id" },
-	},
-	required: ["userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const follower = user;
-
-	// 自分自身
-	if (user.id === ps.userId) {
-		throw new ApiError(meta.errors.followeeIsYourself);
-	}
-
-	// Get followee
-	const followee = await getUser(ps.userId).catch((e) => {
-		if (e.id === "15348ddd-432d-49c2-8a5a-8069753becff")
-			throw new ApiError(meta.errors.noSuchUser);
-		throw e;
-	});
-
-	// Check if already following
-	const exist = await Followings.findOneBy({
-		followerId: follower.id,
-		followeeId: followee.id,
-	});
-
-	if (exist != null) {
-		throw new ApiError(meta.errors.alreadyFollowing);
-	}
-
-	try {
-		await create(follower, followee);
-	} catch (e) {
-		if (e instanceof IdentifiableError) {
-			if (e.id === "710e8fb0-b8c3-4922-be49-d5d93d8e6a6e")
-				throw new ApiError(meta.errors.blocking);
-			if (e.id === "3338392a-f764-498d-8855-db939dcf8c48")
-				throw new ApiError(meta.errors.blocked);
-		}
-		throw e;
-	}
-
-	return await Users.pack(followee.id, user);
-});
diff --git a/packages/backend/src/server/api/endpoints/following/delete.ts b/packages/backend/src/server/api/endpoints/following/delete.ts
deleted file mode 100644
index 2eebe8a903..0000000000
--- a/packages/backend/src/server/api/endpoints/following/delete.ts
+++ /dev/null
@@ -1,84 +0,0 @@
-import deleteFollowing from "@/services/following/delete.js";
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { getUser } from "../../common/getters.js";
-import { Followings, Users } from "@/models/index.js";
-import { HOUR } from "@/const.js";
-
-export const meta = {
-	tags: ["following", "users"],
-
-	limit: {
-		duration: HOUR,
-		max: 100,
-	},
-
-	requireCredential: true,
-
-	kind: "write:following",
-
-	errors: {
-		noSuchUser: {
-			message: "No such user.",
-			code: "NO_SUCH_USER",
-			id: "5b12c78d-2b28-4dca-99d2-f56139b42ff8",
-		},
-
-		followeeIsYourself: {
-			message: "Followee is yourself.",
-			code: "FOLLOWEE_IS_YOURSELF",
-			id: "d9e400b9-36b0-4808-b1d8-79e707f1296c",
-		},
-
-		notFollowing: {
-			message: "You are not following that user.",
-			code: "NOT_FOLLOWING",
-			id: "5dbf82f5-c92b-40b1-87d1-6c8c0741fd09",
-		},
-	},
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "UserLite",
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		userId: { type: "string", format: "misskey:id" },
-	},
-	required: ["userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const follower = user;
-
-	// Check if the followee is yourself
-	if (user.id === ps.userId) {
-		throw new ApiError(meta.errors.followeeIsYourself);
-	}
-
-	// Get followee
-	const followee = await getUser(ps.userId).catch((e) => {
-		if (e.id === "15348ddd-432d-49c2-8a5a-8069753becff")
-			throw new ApiError(meta.errors.noSuchUser);
-		throw e;
-	});
-
-	// Check not following
-	const exist = await Followings.findOneBy({
-		followerId: follower.id,
-		followeeId: followee.id,
-	});
-
-	if (exist == null) {
-		throw new ApiError(meta.errors.notFollowing);
-	}
-
-	await deleteFollowing(follower, followee);
-
-	return await Users.pack(followee.id, user);
-});
diff --git a/packages/backend/src/server/api/endpoints/following/invalidate.ts b/packages/backend/src/server/api/endpoints/following/invalidate.ts
deleted file mode 100644
index 979d298f7d..0000000000
--- a/packages/backend/src/server/api/endpoints/following/invalidate.ts
+++ /dev/null
@@ -1,84 +0,0 @@
-import deleteFollowing from "@/services/following/delete.js";
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { getUser } from "../../common/getters.js";
-import { Followings, Users } from "@/models/index.js";
-import { HOUR } from "@/const.js";
-
-export const meta = {
-	tags: ["following", "users"],
-
-	limit: {
-		duration: HOUR,
-		max: 100,
-	},
-
-	requireCredential: true,
-
-	kind: "write:following",
-
-	errors: {
-		noSuchUser: {
-			message: "No such user.",
-			code: "NO_SUCH_USER",
-			id: "5b12c78d-2b28-4dca-99d2-f56139b42ff8",
-		},
-
-		followerIsYourself: {
-			message: "Follower is yourself.",
-			code: "FOLLOWER_IS_YOURSELF",
-			id: "07dc03b9-03da-422d-885b-438313707662",
-		},
-
-		notFollowing: {
-			message: "The other use is not following you.",
-			code: "NOT_FOLLOWING",
-			id: "5dbf82f5-c92b-40b1-87d1-6c8c0741fd09",
-		},
-	},
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "UserLite",
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		userId: { type: "string", format: "misskey:id" },
-	},
-	required: ["userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const followee = user;
-
-	// Check if the follower is yourself
-	if (user.id === ps.userId) {
-		throw new ApiError(meta.errors.followerIsYourself);
-	}
-
-	// Get follower
-	const follower = await getUser(ps.userId).catch((e) => {
-		if (e.id === "15348ddd-432d-49c2-8a5a-8069753becff")
-			throw new ApiError(meta.errors.noSuchUser);
-		throw e;
-	});
-
-	// Check not following
-	const exist = await Followings.findOneBy({
-		followerId: follower.id,
-		followeeId: followee.id,
-	});
-
-	if (exist == null) {
-		throw new ApiError(meta.errors.notFollowing);
-	}
-
-	await deleteFollowing(follower, followee);
-
-	return await Users.pack(followee.id, user);
-});
diff --git a/packages/backend/src/server/api/endpoints/following/requests/accept.ts b/packages/backend/src/server/api/endpoints/following/requests/accept.ts
deleted file mode 100644
index a4fc052367..0000000000
--- a/packages/backend/src/server/api/endpoints/following/requests/accept.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import acceptFollowRequest from "@/services/following/requests/accept.js";
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-import { getUser } from "../../../common/getters.js";
-
-export const meta = {
-	tags: ["following", "account"],
-
-	requireCredential: true,
-
-	kind: "write:following",
-
-	errors: {
-		noSuchUser: {
-			message: "No such user.",
-			code: "NO_SUCH_USER",
-			id: "66ce1645-d66c-46bb-8b79-96739af885bd",
-		},
-		noFollowRequest: {
-			message: "No follow request.",
-			code: "NO_FOLLOW_REQUEST",
-			id: "bcde4f8b-0913-4614-8881-614e522fb041",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		userId: { type: "string", format: "misskey:id" },
-	},
-	required: ["userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	// Fetch follower
-	const follower = await getUser(ps.userId).catch((e) => {
-		if (e.id === "15348ddd-432d-49c2-8a5a-8069753becff")
-			throw new ApiError(meta.errors.noSuchUser);
-		throw e;
-	});
-
-	await acceptFollowRequest(user, follower).catch((e) => {
-		if (e.id === "8884c2dd-5795-4ac9-b27e-6a01d38190f9")
-			throw new ApiError(meta.errors.noFollowRequest);
-		throw e;
-	});
-
-	return;
-});
diff --git a/packages/backend/src/server/api/endpoints/following/requests/cancel.ts b/packages/backend/src/server/api/endpoints/following/requests/cancel.ts
deleted file mode 100644
index f309e32999..0000000000
--- a/packages/backend/src/server/api/endpoints/following/requests/cancel.ts
+++ /dev/null
@@ -1,64 +0,0 @@
-import cancelFollowRequest from "@/services/following/requests/cancel.js";
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-import { getUser } from "../../../common/getters.js";
-import { Users } from "@/models/index.js";
-import { IdentifiableError } from "@/misc/identifiable-error.js";
-
-export const meta = {
-	tags: ["following", "account"],
-
-	requireCredential: true,
-
-	kind: "write:following",
-
-	errors: {
-		noSuchUser: {
-			message: "No such user.",
-			code: "NO_SUCH_USER",
-			id: "4e68c551-fc4c-4e46-bb41-7d4a37bf9dab",
-		},
-
-		followRequestNotFound: {
-			message: "Follow request not found.",
-			code: "FOLLOW_REQUEST_NOT_FOUND",
-			id: "089b125b-d338-482a-9a09-e2622ac9f8d4",
-		},
-	},
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "UserLite",
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		userId: { type: "string", format: "misskey:id" },
-	},
-	required: ["userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	// Fetch followee
-	const followee = await getUser(ps.userId).catch((e) => {
-		if (e.id === "15348ddd-432d-49c2-8a5a-8069753becff")
-			throw new ApiError(meta.errors.noSuchUser);
-		throw e;
-	});
-
-	try {
-		await cancelFollowRequest(followee, user);
-	} catch (e) {
-		if (e instanceof IdentifiableError) {
-			if (e.id === "17447091-ce07-46dd-b331-c1fd4f15b1e7")
-				throw new ApiError(meta.errors.followRequestNotFound);
-		}
-		throw e;
-	}
-
-	return await Users.pack(followee.id, user);
-});
diff --git a/packages/backend/src/server/api/endpoints/following/requests/list.ts b/packages/backend/src/server/api/endpoints/following/requests/list.ts
deleted file mode 100644
index 6ba23de585..0000000000
--- a/packages/backend/src/server/api/endpoints/following/requests/list.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-import define from "../../../define.js";
-import { FollowRequests } from "@/models/index.js";
-
-export const meta = {
-	tags: ["following", "account"],
-
-	requireCredential: true,
-
-	kind: "read:following",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			properties: {
-				id: {
-					type: "string",
-					optional: false,
-					nullable: false,
-					format: "id",
-				},
-				follower: {
-					type: "object",
-					optional: false,
-					nullable: false,
-					ref: "UserLite",
-				},
-				followee: {
-					type: "object",
-					optional: false,
-					nullable: false,
-					ref: "UserLite",
-				},
-			},
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const reqs = await FollowRequests.findBy({
-		followeeId: user.id,
-	});
-
-	return await Promise.all(reqs.map((req) => FollowRequests.pack(req)));
-});
diff --git a/packages/backend/src/server/api/endpoints/following/requests/reject.ts b/packages/backend/src/server/api/endpoints/following/requests/reject.ts
deleted file mode 100644
index fedc0db487..0000000000
--- a/packages/backend/src/server/api/endpoints/following/requests/reject.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import { rejectFollowRequest } from "@/services/following/reject.js";
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-import { getUser } from "../../../common/getters.js";
-
-export const meta = {
-	tags: ["following", "account"],
-
-	requireCredential: true,
-
-	kind: "write:following",
-
-	errors: {
-		noSuchUser: {
-			message: "No such user.",
-			code: "NO_SUCH_USER",
-			id: "abc2ffa6-25b2-4380-ba99-321ff3a94555",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		userId: { type: "string", format: "misskey:id" },
-	},
-	required: ["userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	// Fetch follower
-	const follower = await getUser(ps.userId).catch((e) => {
-		if (e.id === "15348ddd-432d-49c2-8a5a-8069753becff")
-			throw new ApiError(meta.errors.noSuchUser);
-		throw e;
-	});
-
-	await rejectFollowRequest(user, follower);
-
-	return;
-});
diff --git a/packages/backend/src/server/api/endpoints/gallery/featured.ts b/packages/backend/src/server/api/endpoints/gallery/featured.ts
deleted file mode 100644
index d478e8e3bf..0000000000
--- a/packages/backend/src/server/api/endpoints/gallery/featured.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import define from "../../define.js";
-import { GalleryPosts } from "@/models/index.js";
-
-export const meta = {
-	tags: ["gallery"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "GalleryPost",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const query = GalleryPosts.createQueryBuilder("post")
-		.andWhere("post.createdAt > :date", {
-			date: new Date(Date.now() - 1000 * 60 * 60 * 24 * 3),
-		})
-		.andWhere("post.likedCount > 0")
-		.orderBy("post.likedCount", "DESC");
-
-	const posts = await query.take(10).getMany();
-
-	return await GalleryPosts.packMany(posts, me);
-});
diff --git a/packages/backend/src/server/api/endpoints/gallery/popular.ts b/packages/backend/src/server/api/endpoints/gallery/popular.ts
deleted file mode 100644
index 5eef68d971..0000000000
--- a/packages/backend/src/server/api/endpoints/gallery/popular.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import define from "../../define.js";
-import { GalleryPosts } from "@/models/index.js";
-
-export const meta = {
-	tags: ["gallery"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "GalleryPost",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const query = GalleryPosts.createQueryBuilder("post")
-		.andWhere("post.likedCount > 0")
-		.orderBy("post.likedCount", "DESC");
-
-	const posts = await query.take(10).getMany();
-
-	return await GalleryPosts.packMany(posts, me);
-});
diff --git a/packages/backend/src/server/api/endpoints/gallery/posts.ts b/packages/backend/src/server/api/endpoints/gallery/posts.ts
deleted file mode 100644
index f97c161aff..0000000000
--- a/packages/backend/src/server/api/endpoints/gallery/posts.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import define from "../../define.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-import { GalleryPosts } from "@/models/index.js";
-
-export const meta = {
-	tags: ["gallery"],
-	requireCredentialPrivateMode: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "GalleryPost",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const query = makePaginationQuery(
-		GalleryPosts.createQueryBuilder("post"),
-		ps.sinceId,
-		ps.untilId,
-	).innerJoinAndSelect("post.user", "user");
-
-	const posts = await query.take(ps.limit).getMany();
-
-	return await GalleryPosts.packMany(posts, me);
-});
diff --git a/packages/backend/src/server/api/endpoints/gallery/posts/create.ts b/packages/backend/src/server/api/endpoints/gallery/posts/create.ts
deleted file mode 100644
index f3b3768e28..0000000000
--- a/packages/backend/src/server/api/endpoints/gallery/posts/create.ts
+++ /dev/null
@@ -1,81 +0,0 @@
-import define from "../../../define.js";
-import { DriveFiles, GalleryPosts } from "@/models/index.js";
-import { genId } from "../../../../../misc/gen-id.js";
-import { GalleryPost } from "@/models/entities/gallery-post.js";
-import { ApiError } from "../../../error.js";
-import type { DriveFile } from "@/models/entities/drive-file.js";
-import { HOUR } from "@/const.js";
-
-export const meta = {
-	tags: ["gallery"],
-
-	requireCredential: true,
-
-	kind: "write:gallery",
-
-	limit: {
-		duration: HOUR,
-		max: 300,
-	},
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "GalleryPost",
-	},
-
-	errors: {},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		title: { type: "string", minLength: 1 },
-		description: { type: "string", nullable: true },
-		fileIds: {
-			type: "array",
-			uniqueItems: true,
-			minItems: 1,
-			maxItems: 32,
-			items: {
-				type: "string",
-				format: "misskey:id",
-			},
-		},
-		isSensitive: { type: "boolean", default: false },
-	},
-	required: ["title", "fileIds"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const files = (
-		await Promise.all(
-			ps.fileIds.map((fileId) =>
-				DriveFiles.findOneBy({
-					id: fileId,
-					userId: user.id,
-				}),
-			),
-		)
-	).filter((file): file is DriveFile => file != null);
-
-	if (files.length === 0) {
-		throw new Error();
-	}
-
-	const post = await GalleryPosts.insert(
-		new GalleryPost({
-			id: genId(),
-			createdAt: new Date(),
-			updatedAt: new Date(),
-			title: ps.title,
-			description: ps.description,
-			userId: user.id,
-			isSensitive: ps.isSensitive,
-			fileIds: files.map((file) => file.id),
-		}),
-	).then((x) => GalleryPosts.findOneByOrFail(x.identifiers[0]));
-
-	return await GalleryPosts.pack(post, user);
-});
diff --git a/packages/backend/src/server/api/endpoints/gallery/posts/delete.ts b/packages/backend/src/server/api/endpoints/gallery/posts/delete.ts
deleted file mode 100644
index 9fd9a50099..0000000000
--- a/packages/backend/src/server/api/endpoints/gallery/posts/delete.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-import { GalleryPosts } from "@/models/index.js";
-
-export const meta = {
-	tags: ["gallery"],
-
-	requireCredential: true,
-
-	kind: "write:gallery",
-
-	errors: {
-		noSuchPost: {
-			message: "No such post.",
-			code: "NO_SUCH_POST",
-			id: "ae52f367-4bd7-4ecd-afc6-5672fff427f5",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		postId: { type: "string", format: "misskey:id" },
-	},
-	required: ["postId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const post = await GalleryPosts.findOneBy({
-		id: ps.postId,
-		userId: user.id,
-	});
-
-	if (post == null) {
-		throw new ApiError(meta.errors.noSuchPost);
-	}
-
-	await GalleryPosts.delete(post.id);
-});
diff --git a/packages/backend/src/server/api/endpoints/gallery/posts/like.ts b/packages/backend/src/server/api/endpoints/gallery/posts/like.ts
deleted file mode 100644
index fd46406bdf..0000000000
--- a/packages/backend/src/server/api/endpoints/gallery/posts/like.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-import { GalleryPosts, GalleryLikes } from "@/models/index.js";
-import { genId } from "@/misc/gen-id.js";
-
-export const meta = {
-	tags: ["gallery"],
-
-	requireCredential: true,
-
-	kind: "write:gallery-likes",
-
-	errors: {
-		noSuchPost: {
-			message: "No such post.",
-			code: "NO_SUCH_POST",
-			id: "56c06af3-1287-442f-9701-c93f7c4a62ff",
-		},
-
-		alreadyLiked: {
-			message: "The post has already been liked.",
-			code: "ALREADY_LIKED",
-			id: "40e9ed56-a59c-473a-bf3f-f289c54fb5a7",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		postId: { type: "string", format: "misskey:id" },
-	},
-	required: ["postId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const post = await GalleryPosts.findOneBy({ id: ps.postId });
-	if (post == null) {
-		throw new ApiError(meta.errors.noSuchPost);
-	}
-
-	// if already liked
-	const exist = await GalleryLikes.findOneBy({
-		postId: post.id,
-		userId: user.id,
-	});
-
-	if (exist != null) {
-		throw new ApiError(meta.errors.alreadyLiked);
-	}
-
-	// Create like
-	await GalleryLikes.insert({
-		id: genId(),
-		createdAt: new Date(),
-		postId: post.id,
-		userId: user.id,
-	});
-
-	GalleryPosts.increment({ id: post.id }, "likedCount", 1);
-});
diff --git a/packages/backend/src/server/api/endpoints/gallery/posts/show.ts b/packages/backend/src/server/api/endpoints/gallery/posts/show.ts
deleted file mode 100644
index 87e272f018..0000000000
--- a/packages/backend/src/server/api/endpoints/gallery/posts/show.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-import { GalleryPosts } from "@/models/index.js";
-
-export const meta = {
-	tags: ["gallery"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	errors: {
-		noSuchPost: {
-			message: "No such post.",
-			code: "NO_SUCH_POST",
-			id: "1137bf14-c5b0-4604-85bb-5b5371b1cd45",
-		},
-	},
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "GalleryPost",
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		postId: { type: "string", format: "misskey:id" },
-	},
-	required: ["postId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const post = await GalleryPosts.findOneBy({
-		id: ps.postId,
-	});
-
-	if (post == null) {
-		throw new ApiError(meta.errors.noSuchPost);
-	}
-
-	return await GalleryPosts.pack(post, me);
-});
diff --git a/packages/backend/src/server/api/endpoints/gallery/posts/unlike.ts b/packages/backend/src/server/api/endpoints/gallery/posts/unlike.ts
deleted file mode 100644
index 772dc92028..0000000000
--- a/packages/backend/src/server/api/endpoints/gallery/posts/unlike.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-import { GalleryPosts, GalleryLikes } from "@/models/index.js";
-
-export const meta = {
-	tags: ["gallery"],
-
-	requireCredential: true,
-
-	kind: "write:gallery-likes",
-
-	errors: {
-		noSuchPost: {
-			message: "No such post.",
-			code: "NO_SUCH_POST",
-			id: "c32e6dd0-b555-4413-925e-b3757d19ed84",
-		},
-
-		notLiked: {
-			message: "You have not liked that post.",
-			code: "NOT_LIKED",
-			id: "e3e8e06e-be37-41f7-a5b4-87a8250288f0",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		postId: { type: "string", format: "misskey:id" },
-	},
-	required: ["postId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const post = await GalleryPosts.findOneBy({ id: ps.postId });
-	if (post == null) {
-		throw new ApiError(meta.errors.noSuchPost);
-	}
-
-	const exist = await GalleryLikes.findOneBy({
-		postId: post.id,
-		userId: user.id,
-	});
-
-	if (exist == null) {
-		throw new ApiError(meta.errors.notLiked);
-	}
-
-	// Delete like
-	await GalleryLikes.delete(exist.id);
-
-	GalleryPosts.decrement({ id: post.id }, "likedCount", 1);
-});
diff --git a/packages/backend/src/server/api/endpoints/gallery/posts/update.ts b/packages/backend/src/server/api/endpoints/gallery/posts/update.ts
deleted file mode 100644
index 64e204172e..0000000000
--- a/packages/backend/src/server/api/endpoints/gallery/posts/update.ts
+++ /dev/null
@@ -1,84 +0,0 @@
-import define from "../../../define.js";
-import { DriveFiles, GalleryPosts } from "@/models/index.js";
-import { GalleryPost } from "@/models/entities/gallery-post.js";
-import { ApiError } from "../../../error.js";
-import type { DriveFile } from "@/models/entities/drive-file.js";
-import { HOUR } from "@/const.js";
-
-export const meta = {
-	tags: ["gallery"],
-
-	requireCredential: true,
-
-	kind: "write:gallery",
-
-	limit: {
-		duration: HOUR,
-		max: 300,
-	},
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "GalleryPost",
-	},
-
-	errors: {},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		postId: { type: "string", format: "misskey:id" },
-		title: { type: "string", minLength: 1 },
-		description: { type: "string", nullable: true },
-		fileIds: {
-			type: "array",
-			uniqueItems: true,
-			minItems: 1,
-			maxItems: 32,
-			items: {
-				type: "string",
-				format: "misskey:id",
-			},
-		},
-		isSensitive: { type: "boolean", default: false },
-	},
-	required: ["postId", "title", "fileIds"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const files = (
-		await Promise.all(
-			ps.fileIds.map((fileId) =>
-				DriveFiles.findOneBy({
-					id: fileId,
-					userId: user.id,
-				}),
-			),
-		)
-	).filter((file): file is DriveFile => file != null);
-
-	if (files.length === 0) {
-		throw new Error();
-	}
-
-	await GalleryPosts.update(
-		{
-			id: ps.postId,
-			userId: user.id,
-		},
-		{
-			updatedAt: new Date(),
-			title: ps.title,
-			description: ps.description,
-			isSensitive: ps.isSensitive,
-			fileIds: files.map((file) => file.id),
-		},
-	);
-
-	const post = await GalleryPosts.findOneByOrFail({ id: ps.postId });
-
-	return await GalleryPosts.pack(post, user);
-});
diff --git a/packages/backend/src/server/api/endpoints/get-online-users-count.ts b/packages/backend/src/server/api/endpoints/get-online-users-count.ts
deleted file mode 100644
index 805674a5b7..0000000000
--- a/packages/backend/src/server/api/endpoints/get-online-users-count.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import { MoreThan } from "typeorm";
-import { USER_ONLINE_THRESHOLD } from "@/const.js";
-import { Users } from "@/models/index.js";
-import define from "../define.js";
-
-export const meta = {
-	tags: ["meta"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async () => {
-	const count = await Users.countBy({
-		lastActiveDate: MoreThan(new Date(Date.now() - USER_ONLINE_THRESHOLD)),
-	});
-
-	return {
-		count,
-	};
-});
diff --git a/packages/backend/src/server/api/endpoints/get-sounds.ts b/packages/backend/src/server/api/endpoints/get-sounds.ts
deleted file mode 100644
index f7edd38609..0000000000
--- a/packages/backend/src/server/api/endpoints/get-sounds.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import { readdir } from "fs/promises";
-import define from "../define.js";
-
-export const meta = {
-	tags: ["meta"],
-	requireCredential: false,
-	requireCredentialPrivateMode: false,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async () => {
-	const music_files: (string | null)[] = [null];
-	const directory = (
-		await readdir("./assets/sounds", { withFileTypes: true })
-	).filter((potentialFolder) => potentialFolder.isDirectory());
-	for await (const folder of directory) {
-		const files = (await readdir(`./assets/sounds/${folder.name}`)).filter(
-			(potentialSong) => potentialSong.endsWith(".mp3"),
-		);
-		for await (const file of files) {
-			music_files.push(`${folder.name}/${file.replace(".mp3", "")}`);
-		}
-	}
-	return music_files;
-});
diff --git a/packages/backend/src/server/api/endpoints/hashtags/list.ts b/packages/backend/src/server/api/endpoints/hashtags/list.ts
deleted file mode 100644
index df99a1e5a6..0000000000
--- a/packages/backend/src/server/api/endpoints/hashtags/list.ts
+++ /dev/null
@@ -1,112 +0,0 @@
-import define from "../../define.js";
-import { Hashtags } from "@/models/index.js";
-
-export const meta = {
-	tags: ["hashtags"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Hashtag",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		attachedToUserOnly: { type: "boolean", default: false },
-		attachedToLocalUserOnly: { type: "boolean", default: false },
-		attachedToRemoteUserOnly: { type: "boolean", default: false },
-		sort: {
-			type: "string",
-			enum: [
-				"+mentionedUsers",
-				"-mentionedUsers",
-				"+mentionedLocalUsers",
-				"-mentionedLocalUsers",
-				"+mentionedRemoteUsers",
-				"-mentionedRemoteUsers",
-				"+attachedUsers",
-				"-attachedUsers",
-				"+attachedLocalUsers",
-				"-attachedLocalUsers",
-				"+attachedRemoteUsers",
-				"-attachedRemoteUsers",
-			],
-		},
-	},
-	required: ["sort"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const query = Hashtags.createQueryBuilder("tag");
-
-	if (ps.attachedToUserOnly) query.andWhere("tag.attachedUsersCount != 0");
-	if (ps.attachedToLocalUserOnly)
-		query.andWhere("tag.attachedLocalUsersCount != 0");
-	if (ps.attachedToRemoteUserOnly)
-		query.andWhere("tag.attachedRemoteUsersCount != 0");
-
-	switch (ps.sort) {
-		case "+mentionedUsers":
-			query.orderBy("tag.mentionedUsersCount", "DESC");
-			break;
-		case "-mentionedUsers":
-			query.orderBy("tag.mentionedUsersCount", "ASC");
-			break;
-		case "+mentionedLocalUsers":
-			query.orderBy("tag.mentionedLocalUsersCount", "DESC");
-			break;
-		case "-mentionedLocalUsers":
-			query.orderBy("tag.mentionedLocalUsersCount", "ASC");
-			break;
-		case "+mentionedRemoteUsers":
-			query.orderBy("tag.mentionedRemoteUsersCount", "DESC");
-			break;
-		case "-mentionedRemoteUsers":
-			query.orderBy("tag.mentionedRemoteUsersCount", "ASC");
-			break;
-		case "+attachedUsers":
-			query.orderBy("tag.attachedUsersCount", "DESC");
-			break;
-		case "-attachedUsers":
-			query.orderBy("tag.attachedUsersCount", "ASC");
-			break;
-		case "+attachedLocalUsers":
-			query.orderBy("tag.attachedLocalUsersCount", "DESC");
-			break;
-		case "-attachedLocalUsers":
-			query.orderBy("tag.attachedLocalUsersCount", "ASC");
-			break;
-		case "+attachedRemoteUsers":
-			query.orderBy("tag.attachedRemoteUsersCount", "DESC");
-			break;
-		case "-attachedRemoteUsers":
-			query.orderBy("tag.attachedRemoteUsersCount", "ASC");
-			break;
-	}
-
-	query.select([
-		"tag.name",
-		"tag.mentionedUsersCount",
-		"tag.mentionedLocalUsersCount",
-		"tag.mentionedRemoteUsersCount",
-		"tag.attachedUsersCount",
-		"tag.attachedLocalUsersCount",
-		"tag.attachedRemoteUsersCount",
-	]);
-
-	const tags = await query.take(ps.limit).getMany();
-
-	return Hashtags.packMany(tags);
-});
diff --git a/packages/backend/src/server/api/endpoints/hashtags/search.ts b/packages/backend/src/server/api/endpoints/hashtags/search.ts
deleted file mode 100644
index 95bc608ece..0000000000
--- a/packages/backend/src/server/api/endpoints/hashtags/search.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import define from "../../define.js";
-import { Hashtags } from "@/models/index.js";
-
-export const meta = {
-	tags: ["hashtags"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "string",
-			optional: false,
-			nullable: false,
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		query: { type: "string" },
-		offset: { type: "integer", default: 0 },
-	},
-	required: ["query"],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	const hashtags = await Hashtags.createQueryBuilder("tag")
-		.where("tag.name like :q", { q: `${ps.query.toLowerCase()}%` })
-		.orderBy("tag.count", "DESC")
-		.groupBy("tag.id")
-		.take(ps.limit)
-		.skip(ps.offset)
-		.getMany();
-
-	return hashtags.map((tag) => tag.name);
-});
diff --git a/packages/backend/src/server/api/endpoints/hashtags/show.ts b/packages/backend/src/server/api/endpoints/hashtags/show.ts
deleted file mode 100644
index 8cf90e4505..0000000000
--- a/packages/backend/src/server/api/endpoints/hashtags/show.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { Hashtags } from "@/models/index.js";
-import { normalizeForSearch } from "@/misc/normalize-for-search.js";
-
-export const meta = {
-	tags: ["hashtags"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "Hashtag",
-	},
-
-	errors: {
-		noSuchHashtag: {
-			message: "No such hashtag.",
-			code: "NO_SUCH_HASHTAG",
-			id: "110ee688-193e-4a3a-9ecf-c167b2e6981e",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		tag: { type: "string" },
-	},
-	required: ["tag"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const hashtag = await Hashtags.findOneBy({
-		name: normalizeForSearch(ps.tag),
-	});
-	if (hashtag == null) {
-		throw new ApiError(meta.errors.noSuchHashtag);
-	}
-
-	return await Hashtags.pack(hashtag);
-});
diff --git a/packages/backend/src/server/api/endpoints/hashtags/trend.ts b/packages/backend/src/server/api/endpoints/hashtags/trend.ts
deleted file mode 100644
index e2a8345112..0000000000
--- a/packages/backend/src/server/api/endpoints/hashtags/trend.ts
+++ /dev/null
@@ -1,178 +0,0 @@
-import { Brackets } from "typeorm";
-import define from "../../define.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { Notes } from "@/models/index.js";
-import type { Note } from "@/models/entities/note.js";
-import { safeForSql } from "@/misc/safe-for-sql.js";
-import { normalizeForSearch } from "@/misc/normalize-for-search.js";
-
-/*
-トレンドに載るためには「『直近a分間のユニーク投稿数が今からa分前~今からb分前の間のユニーク投稿数のn倍以上』のハッシュタグの上位5位以内に入る」ことが必要
-ユニーク投稿数とはそのハッシュタグと投稿ユーザーのペアのカウントで、例えば同じユーザーが複数回同じハッシュタグを投稿してもそのハッシュタグのユニーク投稿数は1とカウントされる
-
-..が理想だけどPostgreSQLでどうするのか分からないので単に「直近Aの内に投稿されたユニーク投稿数が多いハッシュタグ」で妥協する
-*/
-
-const rangeA = 1000 * 60 * 60; // 60分
-//const rangeB = 1000 * 60 * 120; // 2時間
-//const coefficient = 1.25; // 「n倍」の部分
-//const requiredUsers = 3; // 最低何人がそのタグを投稿している必要があるか
-
-const max = 5;
-
-export const meta = {
-	tags: ["hashtags"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			properties: {
-				tag: {
-					type: "string",
-					optional: false,
-					nullable: false,
-				},
-				chart: {
-					type: "array",
-					optional: false,
-					nullable: false,
-					items: {
-						type: "number",
-						optional: false,
-						nullable: false,
-					},
-				},
-				usersCount: {
-					type: "number",
-					optional: false,
-					nullable: false,
-				},
-			},
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async () => {
-	const instance = await fetchMeta(true);
-	const hiddenTags = instance.hiddenTags.map((t) => normalizeForSearch(t));
-
-	const now = new Date(); // 5分単位で丸めた現在日時
-	now.setMinutes(Math.round(now.getMinutes() / 5) * 5, 0, 0);
-
-	const tagNotes = await Notes.createQueryBuilder("note")
-		.where("note.createdAt > :date", { date: new Date(now.getTime() - rangeA) })
-		.andWhere(
-			new Brackets((qb) => {
-				qb.where(`note.visibility = 'public'`).orWhere(
-					`note.visibility = 'home'`,
-				);
-			}),
-		)
-		.andWhere(`note.tags != '{}'`)
-		.select(["note.tags", "note.userId"])
-		.cache(60000) // 1 min
-		.getMany();
-
-	if (tagNotes.length === 0) {
-		return [];
-	}
-
-	const tags: {
-		name: string;
-		users: Note["userId"][];
-	}[] = [];
-
-	for (const note of tagNotes) {
-		for (const tag of note.tags) {
-			if (hiddenTags.includes(tag)) continue;
-
-			const x = tags.find((x) => x.name === tag);
-			if (x) {
-				if (!x.users.includes(note.userId)) {
-					x.users.push(note.userId);
-				}
-			} else {
-				tags.push({
-					name: tag,
-					users: [note.userId],
-				});
-			}
-		}
-	}
-
-	// タグを人気順に並べ替え
-	const hots = tags
-		.sort((a, b) => b.users.length - a.users.length)
-		.map((tag) => tag.name)
-		.slice(0, max);
-
-	//#region 2(または3)で話題と判定されたタグそれぞれについて過去の投稿数グラフを取得する
-	const countPromises: Promise<number[]>[] = [];
-
-	const range = 20;
-
-	// 10分
-	const interval = 1000 * 60 * 10;
-
-	for (let i = 0; i < range; i++) {
-		countPromises.push(
-			Promise.all(
-				hots.map((tag) =>
-					Notes.createQueryBuilder("note")
-						.select("count(distinct note.userId)")
-						.where(
-							`'{"${safeForSql(tag) ? tag : "aichan_kawaii"}"}' <@ note.tags`,
-						)
-						.andWhere("note.createdAt < :lt", {
-							lt: new Date(now.getTime() - interval * i),
-						})
-						.andWhere("note.createdAt > :gt", {
-							gt: new Date(now.getTime() - interval * (i + 1)),
-						})
-						.cache(60000) // 1 min
-						.getRawOne()
-						.then((x) => parseInt(x.count, 10)),
-				),
-			),
-		);
-	}
-
-	const countsLog = await Promise.all(countPromises);
-	//#endregion
-
-	const totalCounts = await Promise.all(
-		hots.map((tag) =>
-			Notes.createQueryBuilder("note")
-				.select("count(distinct note.userId)")
-				.where(`'{"${safeForSql(tag) ? tag : "aichan_kawaii"}"}' <@ note.tags`)
-				.andWhere("note.createdAt > :gt", {
-					gt: new Date(now.getTime() - rangeA),
-				})
-				.cache(60000 * 60) // 60 min
-				.getRawOne()
-				.then((x) => parseInt(x.count, 10)),
-		),
-	);
-
-	const stats = hots.map((tag, i) => ({
-		tag,
-		chart: countsLog.map((counts) => counts[i]),
-		usersCount: totalCounts[i],
-	}));
-
-	return stats;
-});
diff --git a/packages/backend/src/server/api/endpoints/hashtags/users.ts b/packages/backend/src/server/api/endpoints/hashtags/users.ts
deleted file mode 100644
index 532c663070..0000000000
--- a/packages/backend/src/server/api/endpoints/hashtags/users.ts
+++ /dev/null
@@ -1,92 +0,0 @@
-import define from "../../define.js";
-import { Users } from "@/models/index.js";
-import { normalizeForSearch } from "@/misc/normalize-for-search.js";
-
-export const meta = {
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	tags: ["hashtags", "users"],
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "UserDetailed",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		tag: { type: "string" },
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sort: {
-			type: "string",
-			enum: [
-				"+follower",
-				"-follower",
-				"+createdAt",
-				"-createdAt",
-				"+updatedAt",
-				"-updatedAt",
-			],
-		},
-		state: { type: "string", enum: ["all", "alive"], default: "all" },
-		origin: {
-			type: "string",
-			enum: ["combined", "local", "remote"],
-			default: "local",
-		},
-	},
-	required: ["tag", "sort"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const query = Users.createQueryBuilder("user").where(
-		":tag = ANY(user.tags)",
-		{ tag: normalizeForSearch(ps.tag) },
-	);
-
-	const recent = new Date(Date.now() - 1000 * 60 * 60 * 24 * 5);
-
-	if (ps.state === "alive") {
-		query.andWhere("user.updatedAt > :date", { date: recent });
-	}
-
-	if (ps.origin === "local") {
-		query.andWhere("user.host IS NULL");
-	} else if (ps.origin === "remote") {
-		query.andWhere("user.host IS NOT NULL");
-	}
-
-	switch (ps.sort) {
-		case "+follower":
-			query.orderBy("user.followersCount", "DESC");
-			break;
-		case "-follower":
-			query.orderBy("user.followersCount", "ASC");
-			break;
-		case "+createdAt":
-			query.orderBy("user.createdAt", "DESC");
-			break;
-		case "-createdAt":
-			query.orderBy("user.createdAt", "ASC");
-			break;
-		case "+updatedAt":
-			query.orderBy("user.updatedAt", "DESC");
-			break;
-		case "-updatedAt":
-			query.orderBy("user.updatedAt", "ASC");
-			break;
-	}
-
-	const users = await query.take(ps.limit).getMany();
-
-	return await Users.packMany(users, me, { detail: true });
-});
diff --git a/packages/backend/src/server/api/endpoints/i.ts b/packages/backend/src/server/api/endpoints/i.ts
deleted file mode 100644
index 39543442c5..0000000000
--- a/packages/backend/src/server/api/endpoints/i.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { Users } from "@/models/index.js";
-import define from "../define.js";
-
-export const meta = {
-	tags: ["account"],
-
-	requireCredential: true,
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "MeDetailed",
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user, token) => {
-	const isSecure = token == null;
-
-	// ここで渡ってきている user はキャッシュされていて古い可能性もあるので id だけ渡す
-	return await Users.pack<true, true>(user.id, user, {
-		detail: true,
-		includeSecrets: isSecure,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/i/2fa/done.ts b/packages/backend/src/server/api/endpoints/i/2fa/done.ts
deleted file mode 100644
index 1e9892f03b..0000000000
--- a/packages/backend/src/server/api/endpoints/i/2fa/done.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import * as speakeasy from "speakeasy";
-import define from "../../../define.js";
-import { UserProfiles } from "@/models/index.js";
-
-export const meta = {
-	requireCredential: true,
-
-	secure: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		token: { type: "string" },
-	},
-	required: ["token"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const token = ps.token.replace(/\s/g, "");
-
-	const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
-
-	if (profile.twoFactorTempSecret == null) {
-		throw new Error("二段階認証の設定が開始されていません");
-	}
-
-	const verified = (speakeasy as any).totp.verify({
-		secret: profile.twoFactorTempSecret,
-		encoding: "base32",
-		token: token,
-	});
-
-	if (!verified) {
-		throw new Error("not verified");
-	}
-
-	await UserProfiles.update(user.id, {
-		twoFactorSecret: profile.twoFactorTempSecret,
-		twoFactorEnabled: true,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/i/2fa/key-done.ts b/packages/backend/src/server/api/endpoints/i/2fa/key-done.ts
deleted file mode 100644
index f0581de4b4..0000000000
--- a/packages/backend/src/server/api/endpoints/i/2fa/key-done.ts
+++ /dev/null
@@ -1,151 +0,0 @@
-import { promisify } from "node:util";
-import * as cbor from "cbor";
-import define from "../../../define.js";
-import {
-	UserProfiles,
-	UserSecurityKeys,
-	AttestationChallenges,
-	Users,
-} from "@/models/index.js";
-import config from "@/config/index.js";
-import { procedures, hash } from "../../../2fa.js";
-import { publishMainStream } from "@/services/stream.js";
-import { comparePassword } from "@/misc/password.js";
-
-const cborDecodeFirst = promisify(cbor.decodeFirst) as any;
-const rpIdHashReal = hash(Buffer.from(config.hostname, "utf-8"));
-
-export const meta = {
-	requireCredential: true,
-
-	secure: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		clientDataJSON: { type: "string" },
-		attestationObject: { type: "string" },
-		password: { type: "string" },
-		challengeId: { type: "string" },
-		name: { type: "string" },
-	},
-	required: [
-		"clientDataJSON",
-		"attestationObject",
-		"password",
-		"challengeId",
-		"name",
-	],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
-
-	// Compare password
-	const same = await comparePassword(ps.password, profile.password!);
-
-	if (!same) {
-		throw new Error("incorrect password");
-	}
-
-	if (!profile.twoFactorEnabled) {
-		throw new Error("2fa not enabled");
-	}
-
-	const clientData = JSON.parse(ps.clientDataJSON);
-
-	if (clientData.type !== "webauthn.create") {
-		throw new Error("not a creation attestation");
-	}
-	if (clientData.origin !== `${config.scheme}://${config.host}`) {
-		throw new Error("origin mismatch");
-	}
-
-	const clientDataJSONHash = hash(Buffer.from(ps.clientDataJSON, "utf-8"));
-
-	const attestation = await cborDecodeFirst(ps.attestationObject);
-
-	const rpIdHash = attestation.authData.slice(0, 32);
-	if (!rpIdHashReal.equals(rpIdHash)) {
-		throw new Error("rpIdHash mismatch");
-	}
-
-	const flags = attestation.authData[32];
-
-	if (!(flags & 1)) {
-		throw new Error("user not present");
-	}
-
-	const authData = Buffer.from(attestation.authData);
-	const credentialIdLength = authData.readUInt16BE(53);
-	const credentialId = authData.slice(55, 55 + credentialIdLength);
-	const publicKeyData = authData.slice(55 + credentialIdLength);
-	const publicKey: Map<number, any> = await cborDecodeFirst(publicKeyData);
-	if (publicKey.get(3) !== -7) {
-		throw new Error("alg mismatch");
-	}
-
-	if (!(procedures as any)[attestation.fmt]) {
-		throw new Error("unsupported fmt");
-	}
-
-	const verificationData = (procedures as any)[attestation.fmt].verify({
-		attStmt: attestation.attStmt,
-		authenticatorData: authData,
-		clientDataHash: clientDataJSONHash,
-		credentialId,
-		publicKey,
-		rpIdHash,
-	});
-	if (!verificationData.valid) throw new Error("signature invalid");
-
-	const attestationChallenge = await AttestationChallenges.findOneBy({
-		userId: user.id,
-		id: ps.challengeId,
-		registrationChallenge: true,
-		challenge: hash(clientData.challenge).toString("hex"),
-	});
-
-	if (!attestationChallenge) {
-		throw new Error("non-existent challenge");
-	}
-
-	await AttestationChallenges.delete({
-		userId: user.id,
-		id: ps.challengeId,
-	});
-
-	// Expired challenge (> 5min old)
-	if (
-		new Date().getTime() - attestationChallenge.createdAt.getTime() >=
-		5 * 60 * 1000
-	) {
-		throw new Error("expired challenge");
-	}
-
-	const credentialIdString = credentialId.toString("hex");
-
-	await UserSecurityKeys.insert({
-		userId: user.id,
-		id: credentialIdString,
-		lastUsed: new Date(),
-		name: ps.name,
-		publicKey: verificationData.publicKey.toString("hex"),
-	});
-
-	// Publish meUpdated event
-	publishMainStream(
-		user.id,
-		"meUpdated",
-		await Users.pack(user.id, user, {
-			detail: true,
-			includeSecrets: true,
-		}),
-	);
-
-	return {
-		id: credentialIdString,
-		name: ps.name,
-	};
-});
diff --git a/packages/backend/src/server/api/endpoints/i/2fa/password-less.ts b/packages/backend/src/server/api/endpoints/i/2fa/password-less.ts
deleted file mode 100644
index 11b2e9a2e3..0000000000
--- a/packages/backend/src/server/api/endpoints/i/2fa/password-less.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import define from "../../../define.js";
-import { UserProfiles } from "@/models/index.js";
-
-export const meta = {
-	requireCredential: true,
-
-	secure: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		value: { type: "boolean" },
-	},
-	required: ["value"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	await UserProfiles.update(user.id, {
-		usePasswordLessLogin: ps.value,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/i/2fa/register-key.ts b/packages/backend/src/server/api/endpoints/i/2fa/register-key.ts
deleted file mode 100644
index a10dc9b256..0000000000
--- a/packages/backend/src/server/api/endpoints/i/2fa/register-key.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-import define from "../../../define.js";
-import { UserProfiles, AttestationChallenges } from "@/models/index.js";
-import { promisify } from "node:util";
-import * as crypto from "node:crypto";
-import { genId } from "@/misc/gen-id.js";
-import { hash } from "../../../2fa.js";
-import { comparePassword } from "@/misc/password.js";
-
-const randomBytes = promisify(crypto.randomBytes);
-
-export const meta = {
-	requireCredential: true,
-
-	secure: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		password: { type: "string" },
-	},
-	required: ["password"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
-
-	// Compare password
-	const same = await comparePassword(ps.password, profile.password!);
-
-	if (!same) {
-		throw new Error("incorrect password");
-	}
-
-	// if (!profile.twoFactorEnabled) {
-	// 	throw new Error("2fa not enabled");
-	// }
-
-	// 32 byte challenge
-	const entropy = await randomBytes(32);
-	const challenge = entropy
-		.toString("base64")
-		.replace(/=/g, "")
-		.replace(/\+/g, "-")
-		.replace(/\//g, "_");
-
-	const challengeId = genId();
-
-	await AttestationChallenges.insert({
-		userId: user.id,
-		id: challengeId,
-		challenge: hash(Buffer.from(challenge, "utf-8")).toString("hex"),
-		createdAt: new Date(),
-		registrationChallenge: true,
-	});
-
-	return {
-		challengeId,
-		challenge,
-	};
-});
diff --git a/packages/backend/src/server/api/endpoints/i/2fa/register.ts b/packages/backend/src/server/api/endpoints/i/2fa/register.ts
deleted file mode 100644
index 533035bc91..0000000000
--- a/packages/backend/src/server/api/endpoints/i/2fa/register.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-import * as speakeasy from "speakeasy";
-import * as QRCode from "qrcode";
-import config from "@/config/index.js";
-import { UserProfiles } from "@/models/index.js";
-import define from "../../../define.js";
-import { comparePassword } from "@/misc/password.js";
-
-export const meta = {
-	requireCredential: true,
-
-	secure: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		password: { type: "string" },
-	},
-	required: ["password"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
-
-	// Compare password
-	const same = await comparePassword(ps.password, profile.password!);
-
-	if (!same) {
-		throw new Error("incorrect password");
-	}
-
-	// Generate user's secret key
-	const secret = speakeasy.generateSecret({
-		length: 32,
-	});
-
-	await UserProfiles.update(user.id, {
-		twoFactorTempSecret: secret.base32,
-	});
-
-	// Get the data URL of the authenticator URL
-	const url = speakeasy.otpauthURL({
-		secret: secret.base32,
-		encoding: "base32",
-		label: user.username,
-		issuer: config.host,
-	});
-	const dataUrl = await QRCode.toDataURL(url);
-
-	return {
-		qr: dataUrl,
-		url,
-		secret: secret.base32,
-		label: user.username,
-		issuer: config.host,
-	};
-});
diff --git a/packages/backend/src/server/api/endpoints/i/2fa/remove-key.ts b/packages/backend/src/server/api/endpoints/i/2fa/remove-key.ts
deleted file mode 100644
index 862c971e75..0000000000
--- a/packages/backend/src/server/api/endpoints/i/2fa/remove-key.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-import { comparePassword } from "@/misc/password.js";
-import define from "../../../define.js";
-import { UserProfiles, UserSecurityKeys, Users } from "@/models/index.js";
-import { publishMainStream } from "@/services/stream.js";
-
-export const meta = {
-	requireCredential: true,
-
-	secure: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		password: { type: "string" },
-		credentialId: { type: "string" },
-	},
-	required: ["password", "credentialId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
-
-	// Compare password
-	const same = await comparePassword(ps.password, profile.password!);
-
-	if (!same) {
-		throw new Error("incorrect password");
-	}
-
-	// Make sure we only delete the user's own creds
-	await UserSecurityKeys.delete({
-		userId: user.id,
-		id: ps.credentialId,
-	});
-
-	// Publish meUpdated event
-	publishMainStream(
-		user.id,
-		"meUpdated",
-		await Users.pack(user.id, user, {
-			detail: true,
-			includeSecrets: true,
-		}),
-	);
-
-	return {};
-});
diff --git a/packages/backend/src/server/api/endpoints/i/2fa/unregister.ts b/packages/backend/src/server/api/endpoints/i/2fa/unregister.ts
deleted file mode 100644
index 57d57ff65a..0000000000
--- a/packages/backend/src/server/api/endpoints/i/2fa/unregister.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import define from "../../../define.js";
-import { UserProfiles } from "@/models/index.js";
-import { comparePassword } from "@/misc/password.js";
-
-export const meta = {
-	requireCredential: true,
-
-	secure: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		password: { type: "string" },
-	},
-	required: ["password"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
-
-	// Compare password
-	const same = await comparePassword(ps.password, profile.password!);
-
-	if (!same) {
-		throw new Error("incorrect password");
-	}
-
-	await UserProfiles.update(user.id, {
-		twoFactorSecret: null,
-		twoFactorEnabled: false,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/i/apps.ts b/packages/backend/src/server/api/endpoints/i/apps.ts
deleted file mode 100644
index b951601949..0000000000
--- a/packages/backend/src/server/api/endpoints/i/apps.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-import define from "../../define.js";
-import { AccessTokens } from "@/models/index.js";
-
-export const meta = {
-	requireCredential: true,
-
-	secure: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		sort: {
-			type: "string",
-			enum: ["+createdAt", "-createdAt", "+lastUsedAt", "-lastUsedAt"],
-		},
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const query = AccessTokens.createQueryBuilder("token").where(
-		"token.userId = :userId",
-		{ userId: user.id },
-	);
-
-	switch (ps.sort) {
-		case "+createdAt":
-			query.orderBy("token.createdAt", "DESC");
-			break;
-		case "-createdAt":
-			query.orderBy("token.createdAt", "ASC");
-			break;
-		case "+lastUsedAt":
-			query.orderBy("token.lastUsedAt", "DESC");
-			break;
-		case "-lastUsedAt":
-			query.orderBy("token.lastUsedAt", "ASC");
-			break;
-		default:
-			query.orderBy("token.id", "ASC");
-			break;
-	}
-
-	const tokens = await query.getMany();
-
-	return await Promise.all(
-		tokens.map((token) => ({
-			id: token.id,
-			name: token.name,
-			createdAt: token.createdAt,
-			lastUsedAt: token.lastUsedAt,
-			permission: token.permission,
-		})),
-	);
-});
diff --git a/packages/backend/src/server/api/endpoints/i/authorized-apps.ts b/packages/backend/src/server/api/endpoints/i/authorized-apps.ts
deleted file mode 100644
index f759b23037..0000000000
--- a/packages/backend/src/server/api/endpoints/i/authorized-apps.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import define from "../../define.js";
-import { AccessTokens, Apps } from "@/models/index.js";
-
-export const meta = {
-	requireCredential: true,
-
-	secure: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		offset: { type: "integer", default: 0 },
-		sort: { type: "string", enum: ["desc", "asc"], default: "desc" },
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	// Get tokens
-	const tokens = await AccessTokens.find({
-		where: {
-			userId: user.id,
-		},
-		take: ps.limit,
-		skip: ps.offset,
-		order: {
-			id: ps.sort === "asc" ? 1 : -1,
-		},
-	});
-
-	return await Promise.all(
-		tokens.map((token) =>
-			Apps.pack(token.appId, user, {
-				detail: true,
-			}),
-		),
-	);
-});
diff --git a/packages/backend/src/server/api/endpoints/i/change-password.ts b/packages/backend/src/server/api/endpoints/i/change-password.ts
deleted file mode 100644
index 8bbb3ad93a..0000000000
--- a/packages/backend/src/server/api/endpoints/i/change-password.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import define from "../../define.js";
-import { UserProfiles } from "@/models/index.js";
-import { hashPassword, comparePassword } from "@/misc/password.js";
-
-export const meta = {
-	requireCredential: true,
-
-	secure: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		currentPassword: { type: "string" },
-		newPassword: { type: "string", minLength: 1 },
-	},
-	required: ["currentPassword", "newPassword"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
-
-	// Compare password
-	const same = await comparePassword(ps.currentPassword, profile.password!);
-
-	if (!same) {
-		throw new Error("incorrect password");
-	}
-
-	// Generate hash of password
-	const hash = await hashPassword(ps.newPassword);
-
-	await UserProfiles.update(user.id, {
-		password: hash,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/i/delete-account.ts b/packages/backend/src/server/api/endpoints/i/delete-account.ts
deleted file mode 100644
index 781abe0b38..0000000000
--- a/packages/backend/src/server/api/endpoints/i/delete-account.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import { UserProfiles, Users } from "@/models/index.js";
-import { deleteAccount } from "@/services/delete-account.js";
-import define from "../../define.js";
-import { comparePassword } from "@/misc/password.js";
-
-export const meta = {
-	requireCredential: true,
-
-	secure: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		password: { type: "string" },
-	},
-	required: ["password"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
-	const userDetailed = await Users.findOneByOrFail({ id: user.id });
-	if (userDetailed.isDeleted) {
-		return;
-	}
-
-	// Compare password
-	const same = await comparePassword(ps.password, profile.password!);
-
-	if (!same) {
-		throw new Error("incorrect password");
-	}
-
-	await deleteAccount(user);
-});
diff --git a/packages/backend/src/server/api/endpoints/i/export-blocking.ts b/packages/backend/src/server/api/endpoints/i/export-blocking.ts
deleted file mode 100644
index 4517ad5fab..0000000000
--- a/packages/backend/src/server/api/endpoints/i/export-blocking.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import define from "../../define.js";
-import { createExportBlockingJob } from "@/queue/index.js";
-import { HOUR } from "@/const.js";
-
-export const meta = {
-	secure: true,
-	requireCredential: true,
-	limit: {
-		duration: HOUR,
-		max: 1,
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	createExportBlockingJob(user);
-});
diff --git a/packages/backend/src/server/api/endpoints/i/export-following.ts b/packages/backend/src/server/api/endpoints/i/export-following.ts
deleted file mode 100644
index a228de8f17..0000000000
--- a/packages/backend/src/server/api/endpoints/i/export-following.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import define from "../../define.js";
-import { createExportFollowingJob } from "@/queue/index.js";
-import { HOUR } from "@/const.js";
-
-export const meta = {
-	secure: true,
-	requireCredential: true,
-	limit: {
-		duration: HOUR,
-		max: 1,
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		excludeMuting: { type: "boolean", default: false },
-		excludeInactive: { type: "boolean", default: false },
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	createExportFollowingJob(user, ps.excludeMuting, ps.excludeInactive);
-});
diff --git a/packages/backend/src/server/api/endpoints/i/export-mute.ts b/packages/backend/src/server/api/endpoints/i/export-mute.ts
deleted file mode 100644
index 7bddc434d4..0000000000
--- a/packages/backend/src/server/api/endpoints/i/export-mute.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import define from "../../define.js";
-import { createExportMuteJob } from "@/queue/index.js";
-import { HOUR } from "@/const.js";
-
-export const meta = {
-	secure: true,
-	requireCredential: true,
-	limit: {
-		duration: HOUR,
-		max: 1,
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	createExportMuteJob(user);
-});
diff --git a/packages/backend/src/server/api/endpoints/i/export-notes.ts b/packages/backend/src/server/api/endpoints/i/export-notes.ts
deleted file mode 100644
index 48506ed6d9..0000000000
--- a/packages/backend/src/server/api/endpoints/i/export-notes.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import define from "../../define.js";
-import { createExportNotesJob } from "@/queue/index.js";
-import { DAY } from "@/const.js";
-
-export const meta = {
-	secure: true,
-	requireCredential: true,
-	limit: {
-		duration: DAY,
-		max: 1,
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	createExportNotesJob(user);
-});
diff --git a/packages/backend/src/server/api/endpoints/i/export-user-lists.ts b/packages/backend/src/server/api/endpoints/i/export-user-lists.ts
deleted file mode 100644
index a71b1730b4..0000000000
--- a/packages/backend/src/server/api/endpoints/i/export-user-lists.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import define from "../../define.js";
-import { createExportUserListsJob } from "@/queue/index.js";
-import { MINUTE } from "@/const.js";
-
-export const meta = {
-	secure: true,
-	requireCredential: true,
-	limit: {
-		duration: MINUTE,
-		max: 1,
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	createExportUserListsJob(user);
-});
diff --git a/packages/backend/src/server/api/endpoints/i/favorites.ts b/packages/backend/src/server/api/endpoints/i/favorites.ts
deleted file mode 100644
index f0dbd2de6b..0000000000
--- a/packages/backend/src/server/api/endpoints/i/favorites.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import define from "../../define.js";
-import { NoteFavorites } from "@/models/index.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-
-export const meta = {
-	tags: ["account", "notes", "favorites"],
-
-	requireCredential: true,
-
-	kind: "read:favorites",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "NoteFavorite",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const query = makePaginationQuery(
-		NoteFavorites.createQueryBuilder("favorite"),
-		ps.sinceId,
-		ps.untilId,
-	)
-		.andWhere("favorite.userId = :meId", { meId: user.id })
-		.leftJoinAndSelect("favorite.note", "note");
-
-	const favorites = await query.take(ps.limit).getMany();
-
-	return await NoteFavorites.packMany(favorites, user);
-});
diff --git a/packages/backend/src/server/api/endpoints/i/gallery/likes.ts b/packages/backend/src/server/api/endpoints/i/gallery/likes.ts
deleted file mode 100644
index d71ee3e5a1..0000000000
--- a/packages/backend/src/server/api/endpoints/i/gallery/likes.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-import define from "../../../define.js";
-import { GalleryLikes } from "@/models/index.js";
-import { makePaginationQuery } from "../../../common/make-pagination-query.js";
-
-export const meta = {
-	tags: ["account", "gallery"],
-
-	requireCredential: true,
-
-	kind: "read:gallery-likes",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			properties: {
-				id: {
-					type: "string",
-					optional: false,
-					nullable: false,
-					format: "id",
-				},
-				post: {
-					type: "object",
-					optional: false,
-					nullable: false,
-					ref: "GalleryPost",
-				},
-			},
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const query = makePaginationQuery(
-		GalleryLikes.createQueryBuilder("like"),
-		ps.sinceId,
-		ps.untilId,
-	)
-		.andWhere("like.userId = :meId", { meId: user.id })
-		.leftJoinAndSelect("like.post", "post");
-
-	const likes = await query.take(ps.limit).getMany();
-
-	return await GalleryLikes.packMany(likes, user);
-});
diff --git a/packages/backend/src/server/api/endpoints/i/gallery/posts.ts b/packages/backend/src/server/api/endpoints/i/gallery/posts.ts
deleted file mode 100644
index e471731ae7..0000000000
--- a/packages/backend/src/server/api/endpoints/i/gallery/posts.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import { GalleryPosts } from "@/models/index.js";
-import define from "../../../define.js";
-import { makePaginationQuery } from "../../../common/make-pagination-query.js";
-
-export const meta = {
-	tags: ["account", "gallery"],
-
-	requireCredential: true,
-
-	kind: "read:gallery",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "GalleryPost",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const query = makePaginationQuery(
-		GalleryPosts.createQueryBuilder("post"),
-		ps.sinceId,
-		ps.untilId,
-	).andWhere("post.userId = :meId", { meId: user.id });
-
-	const posts = await query.take(ps.limit).getMany();
-
-	return await GalleryPosts.packMany(posts, user);
-});
diff --git a/packages/backend/src/server/api/endpoints/i/get-word-muted-notes-count.ts b/packages/backend/src/server/api/endpoints/i/get-word-muted-notes-count.ts
deleted file mode 100644
index bd58f9257a..0000000000
--- a/packages/backend/src/server/api/endpoints/i/get-word-muted-notes-count.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import define from "../../define.js";
-import { MutedNotes } from "@/models/index.js";
-
-export const meta = {
-	tags: ["account"],
-
-	requireCredential: true,
-
-	kind: "read:account",
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		properties: {
-			count: {
-				type: "number",
-				optional: false,
-				nullable: false,
-			},
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	return {
-		count: await MutedNotes.countBy({
-			userId: user.id,
-			reason: "word",
-		}),
-	};
-});
diff --git a/packages/backend/src/server/api/endpoints/i/import-blocking.ts b/packages/backend/src/server/api/endpoints/i/import-blocking.ts
deleted file mode 100644
index e4f1da60cc..0000000000
--- a/packages/backend/src/server/api/endpoints/i/import-blocking.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-import define from "../../define.js";
-import { createImportBlockingJob } from "@/queue/index.js";
-import { ApiError } from "../../error.js";
-import { DriveFiles } from "@/models/index.js";
-import { HOUR } from "@/const.js";
-
-export const meta = {
-	secure: true,
-	requireCredential: true,
-
-	limit: {
-		duration: HOUR,
-		max: 1,
-	},
-
-	errors: {
-		noSuchFile: {
-			message: "No such file.",
-			code: "NO_SUCH_FILE",
-			id: "ebb53e5f-6574-9c0c-0b92-7ca6def56d7e",
-		},
-
-		unexpectedFileType: {
-			message: "We need csv file.",
-			code: "UNEXPECTED_FILE_TYPE",
-			id: "b6fab7d6-d945-d67c-dfdb-32da1cd12cfe",
-		},
-
-		tooBigFile: {
-			message: "That file is too big.",
-			code: "TOO_BIG_FILE",
-			id: "b7fbf0b1-aeef-3b21-29ef-fadd4cb72ccf",
-		},
-
-		emptyFile: {
-			message: "That file is empty.",
-			code: "EMPTY_FILE",
-			id: "6f3a4dcc-f060-a707-4950-806fbdbe60d6",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		fileId: { type: "string", format: "misskey:id" },
-	},
-	required: ["fileId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const file = await DriveFiles.findOneBy({ id: ps.fileId });
-
-	if (file == null) throw new ApiError(meta.errors.noSuchFile);
-	//if (!file.type.endsWith('/csv')) throw new ApiError(meta.errors.unexpectedFileType);
-	if (file.size > 50000) throw new ApiError(meta.errors.tooBigFile);
-	if (file.size === 0) throw new ApiError(meta.errors.emptyFile);
-
-	createImportBlockingJob(user, file.id);
-});
diff --git a/packages/backend/src/server/api/endpoints/i/import-following.ts b/packages/backend/src/server/api/endpoints/i/import-following.ts
deleted file mode 100644
index 1a6c9b565d..0000000000
--- a/packages/backend/src/server/api/endpoints/i/import-following.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import define from "../../define.js";
-import { createImportFollowingJob } from "@/queue/index.js";
-import { ApiError } from "../../error.js";
-import { DriveFiles } from "@/models/index.js";
-import { HOUR } from "@/const.js";
-
-export const meta = {
-	secure: true,
-	requireCredential: true,
-	limit: {
-		duratition: HOUR,
-		max: 1,
-	},
-
-	errors: {
-		noSuchFile: {
-			message: "No such file.",
-			code: "NO_SUCH_FILE",
-			id: "b98644cf-a5ac-4277-a502-0b8054a709a3",
-		},
-
-		unexpectedFileType: {
-			message: "Must be a CSV or JSON file.",
-			code: "UNEXPECTED_FILE_TYPE",
-			id: "660f3599-bce0-4f95-9dde-311fd841c183",
-		},
-
-		tooBigFile: {
-			message: "That file is too big.",
-			code: "TOO_BIG_FILE",
-			id: "dee9d4ed-ad07-43ed-8b34-b2856398bc60",
-		},
-
-		emptyFile: {
-			message: "That file is empty.",
-			code: "EMPTY_FILE",
-			id: "31a1b42c-06f7-42ae-8a38-a661c5c9f691",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		fileId: { type: "string", format: "misskey:id" },
-	},
-	required: ["fileId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const file = await DriveFiles.findOneBy({ id: ps.fileId });
-
-	if (file == null) throw new ApiError(meta.errors.noSuchFile);
-	//if (!file.type.endsWith('/csv')) throw new ApiError(meta.errors.unexpectedFileType);
-	if (file.size > 2_000_000) throw new ApiError(meta.errors.tooBigFile);
-	if (file.size === 0) throw new ApiError(meta.errors.emptyFile);
-
-	createImportFollowingJob(user, file.id);
-});
diff --git a/packages/backend/src/server/api/endpoints/i/import-muting.ts b/packages/backend/src/server/api/endpoints/i/import-muting.ts
deleted file mode 100644
index 20d240e739..0000000000
--- a/packages/backend/src/server/api/endpoints/i/import-muting.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-import define from "../../define.js";
-import { createImportMutingJob } from "@/queue/index.js";
-import { ApiError } from "../../error.js";
-import { DriveFiles } from "@/models/index.js";
-import { HOUR } from "@/const.js";
-
-export const meta = {
-	secure: true,
-	requireCredential: true,
-
-	limit: {
-		duration: HOUR,
-		max: 1,
-	},
-
-	errors: {
-		noSuchFile: {
-			message: "No such file.",
-			code: "NO_SUCH_FILE",
-			id: "e674141e-bd2a-ba85-e616-aefb187c9c2a",
-		},
-
-		unexpectedFileType: {
-			message: "We need csv file.",
-			code: "UNEXPECTED_FILE_TYPE",
-			id: "568c6e42-c86c-ba09-c004-517f83f9f1a8",
-		},
-
-		tooBigFile: {
-			message: "That file is too big.",
-			code: "TOO_BIG_FILE",
-			id: "9b4ada6d-d7f7-0472-0713-4f558bd1ec9c",
-		},
-
-		emptyFile: {
-			message: "That file is empty.",
-			code: "EMPTY_FILE",
-			id: "d2f12af1-e7b4-feac-86a3-519548f2728e",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		fileId: { type: "string", format: "misskey:id" },
-	},
-	required: ["fileId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const file = await DriveFiles.findOneBy({ id: ps.fileId });
-
-	if (file == null) throw new ApiError(meta.errors.noSuchFile);
-	//if (!file.type.endsWith('/csv')) throw new ApiError(meta.errors.unexpectedFileType);
-	if (file.size > 50000) throw new ApiError(meta.errors.tooBigFile);
-	if (file.size === 0) throw new ApiError(meta.errors.emptyFile);
-
-	createImportMutingJob(user, file.id);
-});
diff --git a/packages/backend/src/server/api/endpoints/i/import-posts.ts b/packages/backend/src/server/api/endpoints/i/import-posts.ts
deleted file mode 100644
index 6fdf562fdb..0000000000
--- a/packages/backend/src/server/api/endpoints/i/import-posts.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import define from "../../define.js";
-import { createImportPostsJob } from "@/queue/index.js";
-import { ApiError } from "../../error.js";
-import { DriveFiles } from "@/models/index.js";
-import { DAY } from "@/const.js";
-
-export const meta = {
-	secure: true,
-	requireCredential: true,
-	limit: {
-		duration: DAY,
-		max: 1,
-	},
-	errors: {
-		noSuchFile: {
-			message: "No such file.",
-			code: "NO_SUCH_FILE",
-			id: "e674141e-bd2a-ba85-e616-aefb187c9c2a",
-		},
-
-		emptyFile: {
-			message: "That file is empty.",
-			code: "EMPTY_FILE",
-			id: "d2f12af1-e7b4-feac-86a3-519548f2728e",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		fileId: { type: "string", format: "misskey:id" },
-		signatureCheck: { type: "boolean" },
-	},
-	required: ["fileId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const file = await DriveFiles.findOneBy({ id: ps.fileId });
-
-	if (file == null) throw new ApiError(meta.errors.noSuchFile);
-	if (file.size === 0) throw new ApiError(meta.errors.emptyFile);
-	createImportPostsJob(user, file.id, ps.signatureCheck);
-});
diff --git a/packages/backend/src/server/api/endpoints/i/import-user-lists.ts b/packages/backend/src/server/api/endpoints/i/import-user-lists.ts
deleted file mode 100644
index 03b1dffbbb..0000000000
--- a/packages/backend/src/server/api/endpoints/i/import-user-lists.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import define from "../../define.js";
-import { createImportUserListsJob } from "@/queue/index.js";
-import { ApiError } from "../../error.js";
-import { DriveFiles } from "@/models/index.js";
-import { HOUR } from "@/const.js";
-
-export const meta = {
-	secure: true,
-	requireCredential: true,
-	limit: {
-		duration: HOUR,
-		max: 1,
-	},
-
-	errors: {
-		noSuchFile: {
-			message: "No such file.",
-			code: "NO_SUCH_FILE",
-			id: "ea9cc34f-c415-4bc6-a6fe-28ac40357049",
-		},
-
-		unexpectedFileType: {
-			message: "We need csv file.",
-			code: "UNEXPECTED_FILE_TYPE",
-			id: "a3c9edda-dd9b-4596-be6a-150ef813745c",
-		},
-
-		tooBigFile: {
-			message: "That file is too big.",
-			code: "TOO_BIG_FILE",
-			id: "ae6e7a22-971b-4b52-b2be-fc0b9b121fe9",
-		},
-
-		emptyFile: {
-			message: "That file is empty.",
-			code: "EMPTY_FILE",
-			id: "99efe367-ce6e-4d44-93f8-5fae7b040356",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		fileId: { type: "string", format: "misskey:id" },
-	},
-	required: ["fileId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const file = await DriveFiles.findOneBy({ id: ps.fileId });
-
-	if (file == null) throw new ApiError(meta.errors.noSuchFile);
-	//if (!file.type.endsWith('/csv')) throw new ApiError(meta.errors.unexpectedFileType);
-	if (file.size > 30000) throw new ApiError(meta.errors.tooBigFile);
-	if (file.size === 0) throw new ApiError(meta.errors.emptyFile);
-
-	createImportUserListsJob(user, file.id);
-});
diff --git a/packages/backend/src/server/api/endpoints/i/known-as.ts b/packages/backend/src/server/api/endpoints/i/known-as.ts
deleted file mode 100644
index 5e86e8b955..0000000000
--- a/packages/backend/src/server/api/endpoints/i/known-as.ts
+++ /dev/null
@@ -1,101 +0,0 @@
-import type { User, UserDetailedNotMeOnly } from "@/models/entities/user.js";
-import { Users } from "@/models/index.js";
-import { resolveUser } from "@/remote/resolve-user.js";
-import acceptAllFollowRequests from "@/services/following/requests/accept-all.js";
-import { publishToFollowers } from "@/services/i/update.js";
-import { publishMainStream } from "@/services/stream.js";
-import { DAY } from "@/const.js";
-import { apiLogger } from "../../logger.js";
-import { UserProfiles } from "@/models/index.js";
-import config from "@/config/index.js";
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-
-export const meta = {
-	tags: ["users"],
-
-	secure: true,
-	requireCredential: true,
-
-	limit: {
-		duration: DAY,
-		max: 30,
-	},
-
-	errors: {
-		noSuchUser: {
-			message: "No such user.",
-			code: "NO_SUCH_USER",
-			id: "fcd2eef9-a9b2-4c4f-8624-038099e90aa5",
-		},
-		notRemote: {
-			message: "User is not remote. You can only migrate to other instances.",
-			code: "NOT_REMOTE",
-			id: "4362f8dc-731f-4ad8-a694-be2a88922a24",
-		},
-		uriNull: {
-			message: "User ActivityPup URI is null.",
-			code: "URI_NULL",
-			id: "bf326f31-d430-4f97-9933-5d61e4d48a23",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		alsoKnownAs: { type: "string" },
-	},
-	required: ["alsoKnownAs"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	if (!ps.alsoKnownAs) throw new ApiError(meta.errors.noSuchUser);
-
-	let unfiltered: string = ps.alsoKnownAs;
-	const updates = {} as Partial<User>;
-
-	if (!unfiltered) {
-		updates.alsoKnownAs = null;
-	} else {
-		if (unfiltered.startsWith("acct:")) unfiltered = unfiltered.substring(5);
-		if (unfiltered.startsWith("@")) unfiltered = unfiltered.substring(1);
-		if (!unfiltered.includes("@")) throw new ApiError(meta.errors.notRemote);
-
-		const userAddress: string[] = unfiltered.split("@");
-		const knownAs = await resolveUser(userAddress[0], userAddress[1]).catch(
-			(e) => {
-				apiLogger.warn(`failed to resolve remote user: ${e}`);
-				throw new ApiError(meta.errors.noSuchUser);
-			},
-		);
-
-		const toUrl: string | null = knownAs.uri;
-		if (!toUrl) {
-			throw new ApiError(meta.errors.uriNull);
-		}
-		if (updates.alsoKnownAs == null || updates.alsoKnownAs.length === 0) {
-			updates.alsoKnownAs = [toUrl];
-		} else {
-			updates.alsoKnownAs.push(toUrl);
-		}
-	}
-
-	await Users.update(user.id, updates);
-
-	const iObj = await Users.pack<true, true>(user.id, user, {
-		detail: true,
-		includeSecrets: true,
-	});
-
-	// Publish meUpdated event
-	publishMainStream(user.id, "meUpdated", iObj);
-
-	if (user.isLocked === false) {
-		acceptAllFollowRequests(user);
-	}
-
-	publishToFollowers(user.id);
-
-	return iObj;
-});
diff --git a/packages/backend/src/server/api/endpoints/i/move.ts b/packages/backend/src/server/api/endpoints/i/move.ts
deleted file mode 100644
index 3d947063ff..0000000000
--- a/packages/backend/src/server/api/endpoints/i/move.ts
+++ /dev/null
@@ -1,174 +0,0 @@
-import type { User } from "@/models/entities/user.js";
-import { resolveUser } from "@/remote/resolve-user.js";
-import { DAY } from "@/const.js";
-import DeliverManager from "@/remote/activitypub/deliver-manager.js";
-import { renderActivity } from "@/remote/activitypub/renderer/index.js";
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { apiLogger } from "../../logger.js";
-import deleteFollowing from "@/services/following/delete.js";
-import create from "@/services/following/create.js";
-import { getUser } from "@/server/api/common/getters.js";
-import { Followings, Users } from "@/models/index.js";
-import { UserProfiles } from "@/models/index.js";
-import config from "@/config/index.js";
-import { publishMainStream } from "@/services/stream.js";
-
-export const meta = {
-	tags: ["users"],
-
-	secure: true,
-	requireCredential: true,
-
-	limit: {
-		duration: DAY,
-		max: 5,
-	},
-
-	errors: {
-		noSuchMoveTarget: {
-			message: "No such move target.",
-			code: "NO_SUCH_MOVE_TARGET",
-			id: "b5c90186-4ab0-49c8-9bba-a1f76c202ba4",
-		},
-		remoteAccountForbids: {
-			message:
-				"Remote account doesn't have proper 'Known As' alias. Did you remember to set it?",
-			code: "REMOTE_ACCOUNT_FORBIDS",
-			id: "b5c90186-4ab0-49c8-9bba-a1f766282ba4",
-		},
-		notRemote: {
-			message: "User is not remote. You can only migrate to other instances.",
-			code: "NOT_REMOTE",
-			id: "4362f8dc-731f-4ad8-a694-be2a88922a24",
-		},
-		adminForbidden: {
-			message: "Admins cant migrate.",
-			code: "NOT_ADMIN_FORBIDDEN",
-			id: "4362e8dc-731f-4ad8-a694-be2a88922a24",
-		},
-		noSuchUser: {
-			message: "No such user.",
-			code: "NO_SUCH_USER",
-			id: "fcd2eef9-a9b2-4c4f-8624-038099e90aa5",
-		},
-		uriNull: {
-			message: "User ActivityPup URI is null.",
-			code: "URI_NULL",
-			id: "bf326f31-d430-4f97-9933-5d61e4d48a23",
-		},
-		localUriNull: {
-			message: "Local User ActivityPup URI is null.",
-			code: "URI_NULL",
-			id: "95ba11b9-90e8-43a5-ba16-7acc1ab32e71",
-		},
-		alreadyMoved: {
-			message: "Account was already moved to another account.",
-			code: "ALREADY_MOVED",
-			id: "b234a14e-9ebe-4581-8000-074b3c215962",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		moveToAccount: { type: "string" },
-	},
-	required: ["moveToAccount"],
-} as const;
-
-function moveActivity(toUrl: string, fromUrl: string) {
-	const activity = {
-		id: null,
-		actor: fromUrl,
-		type: "Move",
-		object: fromUrl,
-		target: toUrl,
-	} as any;
-
-	return renderActivity(activity);
-}
-
-export default define(meta, paramDef, async (ps, user) => {
-	if (!ps.moveToAccount) throw new ApiError(meta.errors.noSuchMoveTarget);
-	if (user.isAdmin) throw new ApiError(meta.errors.adminForbidden);
-	if (user.movedToUri) throw new ApiError(meta.errors.alreadyMoved);
-
-	let unfiltered: string = ps.moveToAccount;
-	if (!unfiltered) {
-		throw new ApiError(meta.errors.noSuchMoveTarget);
-	}
-
-	if (unfiltered.startsWith("acct:")) unfiltered = unfiltered.substring(5);
-	if (unfiltered.startsWith("@")) unfiltered = unfiltered.substring(1);
-	if (!unfiltered.includes("@")) throw new ApiError(meta.errors.notRemote);
-
-	const userAddress: string[] = unfiltered.split("@");
-	const moveTo: User = await resolveUser(userAddress[0], userAddress[1]).catch(
-		(e) => {
-			apiLogger.warn(`failed to resolve remote user: ${e}`);
-			throw new ApiError(meta.errors.noSuchMoveTarget);
-		},
-	);
-	let fromUrl: string | null = user.uri;
-	if (!fromUrl) {
-		fromUrl = `${config.url}/users/${user.id}`;
-	}
-
-	let toUrl: string | null = moveTo.uri;
-	if (!toUrl) {
-		throw new ApiError(meta.errors.uriNull);
-	}
-
-	let allowed = false;
-
-	moveTo.alsoKnownAs?.forEach((element) => {
-		if (fromUrl!.includes(element)) allowed = true;
-	});
-
-	if (!(allowed && toUrl && fromUrl))
-		throw new ApiError(meta.errors.remoteAccountForbids);
-
-	const updates = {} as Partial<User>;
-
-	if (!toUrl) toUrl = "";
-	updates.movedToUri = toUrl;
-
-	await Users.update(user.id, updates);
-	const iObj = await Users.pack<true, true>(user.id, user, {
-		detail: true,
-		includeSecrets: true,
-	});
-
-	const moveAct = moveActivity(toUrl, fromUrl);
-	const dm = new DeliverManager(user, moveAct);
-	dm.addFollowersRecipe();
-	dm.execute();
-
-	// Publish meUpdated event
-	publishMainStream(user.id, "meUpdated", iObj);
-
-	const followings = await Followings.findBy({
-		followeeId: user.id,
-	});
-
-	followings.forEach(async (following) => {
-		//if follower is local
-		if (!following.followerHost) {
-			const follower = await getUser(following.followerId).catch((e) => {
-				if (e.id === "15348ddd-432d-49c2-8a5a-8069753becff")
-					throw new ApiError(meta.errors.noSuchUser);
-				throw e;
-			});
-			await deleteFollowing(follower!, user);
-			try {
-				await create(follower!, moveTo);
-			} catch (e) {
-				/* empty */
-			}
-		}
-	});
-
-	return iObj;
-});
diff --git a/packages/backend/src/server/api/endpoints/i/notifications.ts b/packages/backend/src/server/api/endpoints/i/notifications.ts
deleted file mode 100644
index 6e1aabef7d..0000000000
--- a/packages/backend/src/server/api/endpoints/i/notifications.ts
+++ /dev/null
@@ -1,186 +0,0 @@
-import { Brackets } from "typeorm";
-import {
-	Notifications,
-	Followings,
-	Mutings,
-	Users,
-	UserProfiles,
-} from "@/models/index.js";
-import { notificationTypes } from "@/types.js";
-import read from "@/services/note/read.js";
-import { readNotification } from "../../common/read-notification.js";
-import define from "../../define.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-
-export const meta = {
-	tags: ["account", "notifications"],
-
-	requireCredential: true,
-
-	limit: {
-		duration: 60000,
-		max: 15,
-	},
-
-	kind: "read:notifications",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Notification",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-		following: { type: "boolean", default: false },
-		unreadOnly: { type: "boolean", default: false },
-		markAsRead: { type: "boolean", default: true },
-		includeTypes: {
-			type: "array",
-			items: {
-				type: "string",
-				enum: notificationTypes,
-			},
-		},
-		excludeTypes: {
-			type: "array",
-			items: {
-				type: "string",
-				enum: notificationTypes,
-			},
-		},
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	// includeTypes が空の場合はクエリしない
-	if (ps.includeTypes && ps.includeTypes.length === 0) {
-		return [];
-	}
-	// excludeTypes に全指定されている場合はクエリしない
-	if (notificationTypes.every((type) => ps.excludeTypes?.includes(type))) {
-		return [];
-	}
-	const followingQuery = Followings.createQueryBuilder("following")
-		.select("following.followeeId")
-		.where("following.followerId = :followerId", { followerId: user.id });
-
-	const mutingQuery = Mutings.createQueryBuilder("muting")
-		.select("muting.muteeId")
-		.where("muting.muterId = :muterId", { muterId: user.id });
-
-	const mutingInstanceQuery = UserProfiles.createQueryBuilder("user_profile")
-		.select("user_profile.mutedInstances")
-		.where("user_profile.userId = :muterId", { muterId: user.id });
-
-	const suspendedQuery = Users.createQueryBuilder("users")
-		.select("users.id")
-		.where("users.isSuspended = TRUE");
-
-	const query = makePaginationQuery(
-		Notifications.createQueryBuilder("notification"),
-		ps.sinceId,
-		ps.untilId,
-	)
-		.andWhere("notification.notifieeId = :meId", { meId: user.id })
-		.leftJoinAndSelect("notification.notifier", "notifier")
-		.leftJoinAndSelect("notification.note", "note")
-		.leftJoinAndSelect("notifier.avatar", "notifierAvatar")
-		.leftJoinAndSelect("notifier.banner", "notifierBanner")
-		.leftJoinAndSelect("note.user", "user")
-		.leftJoinAndSelect("user.avatar", "avatar")
-		.leftJoinAndSelect("user.banner", "banner")
-		.leftJoinAndSelect("note.reply", "reply")
-		.leftJoinAndSelect("note.renote", "renote")
-		.leftJoinAndSelect("reply.user", "replyUser")
-		.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
-		.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
-		.leftJoinAndSelect("renote.user", "renoteUser")
-		.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
-		.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner");
-
-	// muted users
-	query.andWhere(
-		new Brackets((qb) => {
-			qb.where(
-				`notification.notifierId NOT IN (${mutingQuery.getQuery()})`,
-			).orWhere("notification.notifierId IS NULL");
-		}),
-	);
-	query.setParameters(mutingQuery.getParameters());
-
-	// muted instances
-	query.andWhere(
-		new Brackets((qb) => {
-			qb.andWhere("notifier.host IS NULL").orWhere(
-				`NOT (( ${mutingInstanceQuery.getQuery()} )::jsonb ? notifier.host)`,
-			);
-		}),
-	);
-	query.setParameters(mutingInstanceQuery.getParameters());
-
-	// suspended users
-	query.andWhere(
-		new Brackets((qb) => {
-			qb.where(
-				`notification.notifierId NOT IN (${suspendedQuery.getQuery()})`,
-			).orWhere("notification.notifierId IS NULL");
-		}),
-	);
-
-	if (ps.following) {
-		query.andWhere(
-			`((notification.notifierId IN (${followingQuery.getQuery()})) OR (notification.notifierId = :meId))`,
-			{ meId: user.id },
-		);
-		query.setParameters(followingQuery.getParameters());
-	}
-
-	if (ps.includeTypes && ps.includeTypes.length > 0) {
-		query.andWhere("notification.type IN (:...includeTypes)", {
-			includeTypes: ps.includeTypes,
-		});
-	} else if (ps.excludeTypes && ps.excludeTypes.length > 0) {
-		query.andWhere("notification.type NOT IN (:...excludeTypes)", {
-			excludeTypes: ps.excludeTypes,
-		});
-	}
-
-	if (ps.unreadOnly) {
-		query.andWhere("notification.isRead = false");
-	}
-
-	const notifications = await query.take(ps.limit).getMany();
-
-	// Mark all as read
-	if (notifications.length > 0 && ps.markAsRead) {
-		readNotification(
-			user.id,
-			notifications.map((x) => x.id),
-		);
-	}
-
-	const notes = notifications
-		.filter((notification) =>
-			["mention", "reply", "quote"].includes(notification.type),
-		)
-		.map((notification) => notification.note!);
-
-	if (notes.length > 0) {
-		read(user.id, notes);
-	}
-
-	return await Notifications.packMany(notifications, user.id);
-});
diff --git a/packages/backend/src/server/api/endpoints/i/page-likes.ts b/packages/backend/src/server/api/endpoints/i/page-likes.ts
deleted file mode 100644
index 1be783a061..0000000000
--- a/packages/backend/src/server/api/endpoints/i/page-likes.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-import { PageLikes } from "@/models/index.js";
-import define from "../../define.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-
-export const meta = {
-	tags: ["account", "pages"],
-
-	requireCredential: true,
-
-	kind: "read:page-likes",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			properties: {
-				id: {
-					type: "string",
-					optional: false,
-					nullable: false,
-					format: "id",
-				},
-				page: {
-					type: "object",
-					optional: false,
-					nullable: false,
-					ref: "Page",
-				},
-			},
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const query = makePaginationQuery(
-		PageLikes.createQueryBuilder("like"),
-		ps.sinceId,
-		ps.untilId,
-	)
-		.andWhere("like.userId = :meId", { meId: user.id })
-		.leftJoinAndSelect("like.page", "page");
-
-	const likes = await query.take(ps.limit).getMany();
-
-	return PageLikes.packMany(likes, user);
-});
diff --git a/packages/backend/src/server/api/endpoints/i/pages.ts b/packages/backend/src/server/api/endpoints/i/pages.ts
deleted file mode 100644
index 78b72e3bce..0000000000
--- a/packages/backend/src/server/api/endpoints/i/pages.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import { Pages } from "@/models/index.js";
-import define from "../../define.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-
-export const meta = {
-	tags: ["account", "pages"],
-
-	requireCredential: true,
-
-	kind: "read:pages",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Page",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const query = makePaginationQuery(
-		Pages.createQueryBuilder("page"),
-		ps.sinceId,
-		ps.untilId,
-	).andWhere("page.userId = :meId", { meId: user.id });
-
-	const pages = await query.take(ps.limit).getMany();
-
-	return await Pages.packMany(pages);
-});
diff --git a/packages/backend/src/server/api/endpoints/i/pin.ts b/packages/backend/src/server/api/endpoints/i/pin.ts
deleted file mode 100644
index 40aa579184..0000000000
--- a/packages/backend/src/server/api/endpoints/i/pin.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-import { addPinned } from "@/services/i/pin.js";
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { Users } from "@/models/index.js";
-
-export const meta = {
-	tags: ["account", "notes"],
-
-	requireCredential: true,
-
-	kind: "write:account",
-
-	errors: {
-		noSuchNote: {
-			message: "No such note.",
-			code: "NO_SUCH_NOTE",
-			id: "56734f8b-3928-431e-bf80-6ff87df40cb3",
-		},
-
-		pinLimitExceeded: {
-			message: "You can not pin notes any more.",
-			code: "PIN_LIMIT_EXCEEDED",
-			id: "72dab508-c64d-498f-8740-a8eec1ba385a",
-		},
-
-		alreadyPinned: {
-			message: "That note has already been pinned.",
-			code: "ALREADY_PINNED",
-			id: "8b18c2b7-68fe-4edb-9892-c0cbaeb6c913",
-		},
-	},
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "MeDetailed",
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		noteId: { type: "string", format: "misskey:id" },
-	},
-	required: ["noteId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	await addPinned(user, ps.noteId).catch((e) => {
-		if (e.id === "70c4e51f-5bea-449c-a030-53bee3cce202")
-			throw new ApiError(meta.errors.noSuchNote);
-		if (e.id === "15a018eb-58e5-4da1-93be-330fcc5e4e1a")
-			throw new ApiError(meta.errors.pinLimitExceeded);
-		if (e.id === "23f0cf4e-59a3-4276-a91d-61a5891c1514")
-			throw new ApiError(meta.errors.alreadyPinned);
-		throw e;
-	});
-
-	return await Users.pack<true, true>(user.id, user, {
-		detail: true,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/i/read-all-messaging-messages.ts b/packages/backend/src/server/api/endpoints/i/read-all-messaging-messages.ts
deleted file mode 100644
index 0333677275..0000000000
--- a/packages/backend/src/server/api/endpoints/i/read-all-messaging-messages.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-import { publishMainStream } from "@/services/stream.js";
-import define from "../../define.js";
-import { MessagingMessages, UserGroupJoinings } from "@/models/index.js";
-
-export const meta = {
-	tags: ["account", "messaging"],
-
-	requireCredential: true,
-
-	kind: "write:account",
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	// Update documents
-	await MessagingMessages.update(
-		{
-			recipientId: user.id,
-			isRead: false,
-		},
-		{
-			isRead: true,
-		},
-	);
-
-	const joinings = await UserGroupJoinings.findBy({ userId: user.id });
-
-	await Promise.all(
-		joinings.map((j) =>
-			MessagingMessages.createQueryBuilder()
-				.update()
-				.set({
-					reads: (() => `array_append("reads", '${user.id}')`) as any,
-				})
-				.where("groupId = :groupId", { groupId: j.userGroupId })
-				.andWhere("userId != :userId", { userId: user.id })
-				.andWhere("NOT (:userId = ANY(reads))", { userId: user.id })
-				.execute(),
-		),
-	);
-
-	publishMainStream(user.id, "readAllMessagingMessages");
-});
diff --git a/packages/backend/src/server/api/endpoints/i/read-all-unread-notes.ts b/packages/backend/src/server/api/endpoints/i/read-all-unread-notes.ts
deleted file mode 100644
index 8a8857c83c..0000000000
--- a/packages/backend/src/server/api/endpoints/i/read-all-unread-notes.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import { publishMainStream } from "@/services/stream.js";
-import define from "../../define.js";
-import { NoteUnreads } from "@/models/index.js";
-
-export const meta = {
-	tags: ["account"],
-
-	requireCredential: true,
-
-	kind: "write:account",
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	// Remove documents
-	await NoteUnreads.delete({
-		userId: user.id,
-	});
-
-	// 全て既読になったイベントを発行
-	publishMainStream(user.id, "readAllUnreadMentions");
-	publishMainStream(user.id, "readAllUnreadSpecifiedNotes");
-});
diff --git a/packages/backend/src/server/api/endpoints/i/read-announcement.ts b/packages/backend/src/server/api/endpoints/i/read-announcement.ts
deleted file mode 100644
index 5218dba871..0000000000
--- a/packages/backend/src/server/api/endpoints/i/read-announcement.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { genId } from "@/misc/gen-id.js";
-import { AnnouncementReads, Announcements, Users } from "@/models/index.js";
-import { publishMainStream } from "@/services/stream.js";
-
-export const meta = {
-	tags: ["account"],
-
-	requireCredential: true,
-
-	kind: "write:account",
-
-	errors: {
-		noSuchAnnouncement: {
-			message: "No such announcement.",
-			code: "NO_SUCH_ANNOUNCEMENT",
-			id: "184663db-df88-4bc2-8b52-fb85f0681939",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		announcementId: { type: "string", format: "misskey:id" },
-	},
-	required: ["announcementId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	// Check if announcement exists
-	const announcement = await Announcements.findOneBy({ id: ps.announcementId });
-
-	if (announcement == null) {
-		throw new ApiError(meta.errors.noSuchAnnouncement);
-	}
-
-	// Check if already read
-	const read = await AnnouncementReads.findOneBy({
-		announcementId: ps.announcementId,
-		userId: user.id,
-	});
-
-	if (read != null) {
-		return;
-	}
-
-	// Create read
-	await AnnouncementReads.insert({
-		id: genId(),
-		createdAt: new Date(),
-		announcementId: ps.announcementId,
-		userId: user.id,
-	});
-
-	if (!(await Users.getHasUnreadAnnouncement(user.id))) {
-		publishMainStream(user.id, "readAllAnnouncements");
-	}
-});
diff --git a/packages/backend/src/server/api/endpoints/i/regenerate-token.ts b/packages/backend/src/server/api/endpoints/i/regenerate-token.ts
deleted file mode 100644
index b5b34c0902..0000000000
--- a/packages/backend/src/server/api/endpoints/i/regenerate-token.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-import {
-	publishInternalEvent,
-	publishMainStream,
-	publishUserEvent,
-} from "@/services/stream.js";
-import generateUserToken from "../../common/generate-native-user-token.js";
-import define from "../../define.js";
-import { Users, UserProfiles } from "@/models/index.js";
-import { comparePassword } from "@/misc/password.js";
-
-export const meta = {
-	requireCredential: true,
-
-	secure: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		password: { type: "string" },
-	},
-	required: ["password"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const freshUser = await Users.findOneByOrFail({ id: user.id });
-	const oldToken = freshUser.token;
-
-	const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
-
-	// Compare password
-	const same = await comparePassword(ps.password, profile.password!);
-
-	if (!same) {
-		throw new Error("incorrect password");
-	}
-
-	const newToken = generateUserToken();
-
-	await Users.update(user.id, {
-		token: newToken,
-	});
-
-	// Publish event
-	publishInternalEvent("userTokenRegenerated", {
-		id: user.id,
-		oldToken,
-		newToken,
-	});
-	publishMainStream(user.id, "myTokenRegenerated");
-
-	// Terminate streaming
-	setTimeout(() => {
-		publishUserEvent(user.id, "terminate", {});
-	}, 5000);
-});
diff --git a/packages/backend/src/server/api/endpoints/i/registry/get-all.ts b/packages/backend/src/server/api/endpoints/i/registry/get-all.ts
deleted file mode 100644
index ee9fe7e9d5..0000000000
--- a/packages/backend/src/server/api/endpoints/i/registry/get-all.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import define from "../../../define.js";
-import { RegistryItems } from "@/models/index.js";
-
-export const meta = {
-	requireCredential: true,
-
-	secure: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		scope: {
-			type: "array",
-			default: [],
-			items: {
-				type: "string",
-				pattern: /^[a-zA-Z0-9_]+$/.toString().slice(1, -1),
-			},
-		},
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const query = RegistryItems.createQueryBuilder("item")
-		.where("item.domain IS NULL")
-		.andWhere("item.userId = :userId", { userId: user.id })
-		.andWhere("item.scope = :scope", { scope: ps.scope });
-
-	const items = await query.getMany();
-
-	const res = {} as Record<string, any>;
-
-	for (const item of items) {
-		res[item.key] = item.value;
-	}
-
-	return res;
-});
diff --git a/packages/backend/src/server/api/endpoints/i/registry/get-detail.ts b/packages/backend/src/server/api/endpoints/i/registry/get-detail.ts
deleted file mode 100644
index 85900bd74d..0000000000
--- a/packages/backend/src/server/api/endpoints/i/registry/get-detail.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-import define from "../../../define.js";
-import { RegistryItems } from "@/models/index.js";
-import { ApiError } from "../../../error.js";
-
-export const meta = {
-	requireCredential: true,
-
-	secure: true,
-
-	errors: {
-		noSuchKey: {
-			message: "No such key.",
-			code: "NO_SUCH_KEY",
-			id: "97a1e8e7-c0f7-47d2-957a-92e61256e01a",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		key: { type: "string" },
-		scope: {
-			type: "array",
-			default: [],
-			items: {
-				type: "string",
-				pattern: /^[a-zA-Z0-9_]+$/.toString().slice(1, -1),
-			},
-		},
-	},
-	required: ["key"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const query = RegistryItems.createQueryBuilder("item")
-		.where("item.domain IS NULL")
-		.andWhere("item.userId = :userId", { userId: user.id })
-		.andWhere("item.key = :key", { key: ps.key })
-		.andWhere("item.scope = :scope", { scope: ps.scope });
-
-	const item = await query.getOne();
-
-	if (item == null) {
-		throw new ApiError(meta.errors.noSuchKey);
-	}
-
-	return {
-		updatedAt: item.updatedAt,
-		value: item.value,
-	};
-});
diff --git a/packages/backend/src/server/api/endpoints/i/registry/get-unsecure.ts b/packages/backend/src/server/api/endpoints/i/registry/get-unsecure.ts
deleted file mode 100644
index f98c6c929f..0000000000
--- a/packages/backend/src/server/api/endpoints/i/registry/get-unsecure.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import { ApiError } from "../../../error.js";
-import define from "../../../define.js";
-import { RegistryItems } from "@/models/index.js";
-
-export const meta = {
-	requireCredential: true,
-
-	secure: false,
-
-	errors: {
-		noSuchKey: {
-			message: "No such key.",
-			code: "NO_SUCH_KEY",
-			id: "ac3ed68a-62f0-422b-a7bc-d5e09e8f6a6a",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		key: { type: "string" },
-		scope: {
-			type: "array",
-			default: [],
-			items: {
-				type: "string",
-				pattern: /^[a-zA-Z0-9_]+$/.toString().slice(1, -1),
-			},
-		},
-	},
-	required: ["key"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	if (ps.key !== "reactions") return;
-	const query = RegistryItems.createQueryBuilder("item")
-		.where("item.domain IS NULL")
-		.andWhere("item.userId = :userId", { userId: user.id })
-		.andWhere("item.key = :key", { key: ps.key })
-		.andWhere("item.scope = :scope", { scope: ps.scope });
-
-	const item = await query.getOne();
-
-	if (item == null) {
-		throw new ApiError(meta.errors.noSuchKey);
-	}
-
-	return item.value;
-});
diff --git a/packages/backend/src/server/api/endpoints/i/registry/get.ts b/packages/backend/src/server/api/endpoints/i/registry/get.ts
deleted file mode 100644
index b143b7228a..0000000000
--- a/packages/backend/src/server/api/endpoints/i/registry/get.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import define from "../../../define.js";
-import { RegistryItems } from "@/models/index.js";
-import { ApiError } from "../../../error.js";
-
-export const meta = {
-	requireCredential: true,
-
-	secure: true,
-
-	errors: {
-		noSuchKey: {
-			message: "No such key.",
-			code: "NO_SUCH_KEY",
-			id: "ac3ed68a-62f0-422b-a7bc-d5e09e8f6a6a",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		key: { type: "string" },
-		scope: {
-			type: "array",
-			default: [],
-			items: {
-				type: "string",
-				pattern: /^[a-zA-Z0-9_]+$/.toString().slice(1, -1),
-			},
-		},
-	},
-	required: ["key"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const query = RegistryItems.createQueryBuilder("item")
-		.where("item.domain IS NULL")
-		.andWhere("item.userId = :userId", { userId: user.id })
-		.andWhere("item.key = :key", { key: ps.key })
-		.andWhere("item.scope = :scope", { scope: ps.scope });
-
-	const item = await query.getOne();
-
-	if (item == null) {
-		throw new ApiError(meta.errors.noSuchKey);
-	}
-
-	return item.value;
-});
diff --git a/packages/backend/src/server/api/endpoints/i/registry/keys-with-type.ts b/packages/backend/src/server/api/endpoints/i/registry/keys-with-type.ts
deleted file mode 100644
index 23698dc53a..0000000000
--- a/packages/backend/src/server/api/endpoints/i/registry/keys-with-type.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-import define from "../../../define.js";
-import { RegistryItems } from "@/models/index.js";
-
-export const meta = {
-	requireCredential: true,
-
-	secure: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		scope: {
-			type: "array",
-			default: [],
-			items: {
-				type: "string",
-				pattern: /^[a-zA-Z0-9_]+$/.toString().slice(1, -1),
-			},
-		},
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const query = RegistryItems.createQueryBuilder("item")
-		.where("item.domain IS NULL")
-		.andWhere("item.userId = :userId", { userId: user.id })
-		.andWhere("item.scope = :scope", { scope: ps.scope });
-
-	const items = await query.getMany();
-
-	const res = {} as Record<string, string>;
-
-	for (const item of items) {
-		const type = typeof item.value;
-		res[item.key] =
-			item.value === null
-				? "null"
-				: Array.isArray(item.value)
-				? "array"
-				: type === "number"
-				? "number"
-				: type === "string"
-				? "string"
-				: type === "boolean"
-				? "boolean"
-				: type === "object"
-				? "object"
-				: (null as never);
-	}
-
-	return res;
-});
diff --git a/packages/backend/src/server/api/endpoints/i/registry/keys.ts b/packages/backend/src/server/api/endpoints/i/registry/keys.ts
deleted file mode 100644
index ad7d08c5af..0000000000
--- a/packages/backend/src/server/api/endpoints/i/registry/keys.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import define from "../../../define.js";
-import { RegistryItems } from "@/models/index.js";
-
-export const meta = {
-	requireCredential: true,
-
-	secure: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		scope: {
-			type: "array",
-			default: [],
-			items: {
-				type: "string",
-				pattern: /^[a-zA-Z0-9_]+$/.toString().slice(1, -1),
-			},
-		},
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const query = RegistryItems.createQueryBuilder("item")
-		.select("item.key")
-		.where("item.domain IS NULL")
-		.andWhere("item.userId = :userId", { userId: user.id })
-		.andWhere("item.scope = :scope", { scope: ps.scope });
-
-	const items = await query.getMany();
-
-	return items.map((x) => x.key);
-});
diff --git a/packages/backend/src/server/api/endpoints/i/registry/remove.ts b/packages/backend/src/server/api/endpoints/i/registry/remove.ts
deleted file mode 100644
index d3793b0e20..0000000000
--- a/packages/backend/src/server/api/endpoints/i/registry/remove.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import define from "../../../define.js";
-import { RegistryItems } from "@/models/index.js";
-import { ApiError } from "../../../error.js";
-
-export const meta = {
-	requireCredential: true,
-
-	secure: true,
-
-	errors: {
-		noSuchKey: {
-			message: "No such key.",
-			code: "NO_SUCH_KEY",
-			id: "1fac4e8a-a6cd-4e39-a4a5-3a7e11f1b019",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		key: { type: "string" },
-		scope: {
-			type: "array",
-			default: [],
-			items: {
-				type: "string",
-				pattern: /^[a-zA-Z0-9_]+$/.toString().slice(1, -1),
-			},
-		},
-	},
-	required: ["key"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const query = RegistryItems.createQueryBuilder("item")
-		.where("item.domain IS NULL")
-		.andWhere("item.userId = :userId", { userId: user.id })
-		.andWhere("item.key = :key", { key: ps.key })
-		.andWhere("item.scope = :scope", { scope: ps.scope });
-
-	const item = await query.getOne();
-
-	if (item == null) {
-		throw new ApiError(meta.errors.noSuchKey);
-	}
-
-	await RegistryItems.remove(item);
-});
diff --git a/packages/backend/src/server/api/endpoints/i/registry/scopes.ts b/packages/backend/src/server/api/endpoints/i/registry/scopes.ts
deleted file mode 100644
index 3d66359c1d..0000000000
--- a/packages/backend/src/server/api/endpoints/i/registry/scopes.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import define from "../../../define.js";
-import { RegistryItems } from "@/models/index.js";
-
-export const meta = {
-	requireCredential: true,
-
-	secure: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const query = RegistryItems.createQueryBuilder("item")
-		.select("item.scope")
-		.where("item.domain IS NULL")
-		.andWhere("item.userId = :userId", { userId: user.id });
-
-	const items = await query.getMany();
-
-	const res = [] as string[][];
-
-	for (const item of items) {
-		if (res.some((scope) => scope.join(".") === item.scope.join("."))) continue;
-		res.push(item.scope);
-	}
-
-	return res;
-});
diff --git a/packages/backend/src/server/api/endpoints/i/registry/set.ts b/packages/backend/src/server/api/endpoints/i/registry/set.ts
deleted file mode 100644
index 7f9eebd5e0..0000000000
--- a/packages/backend/src/server/api/endpoints/i/registry/set.ts
+++ /dev/null
@@ -1,62 +0,0 @@
-import { publishMainStream } from "@/services/stream.js";
-import define from "../../../define.js";
-import { RegistryItems } from "@/models/index.js";
-import { genId } from "@/misc/gen-id.js";
-
-export const meta = {
-	requireCredential: true,
-
-	secure: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		key: { type: "string", minLength: 1 },
-		value: {},
-		scope: {
-			type: "array",
-			default: [],
-			items: {
-				type: "string",
-				pattern: /^[a-zA-Z0-9_]+$/.toString().slice(1, -1),
-			},
-		},
-	},
-	required: ["key", "value"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const query = RegistryItems.createQueryBuilder("item")
-		.where("item.domain IS NULL")
-		.andWhere("item.userId = :userId", { userId: user.id })
-		.andWhere("item.key = :key", { key: ps.key })
-		.andWhere("item.scope = :scope", { scope: ps.scope });
-
-	const existingItem = await query.getOne();
-
-	if (existingItem) {
-		await RegistryItems.update(existingItem.id, {
-			updatedAt: new Date(),
-			value: ps.value,
-		});
-	} else {
-		await RegistryItems.insert({
-			id: genId(),
-			createdAt: new Date(),
-			updatedAt: new Date(),
-			userId: user.id,
-			domain: null,
-			scope: ps.scope,
-			key: ps.key,
-			value: ps.value,
-		});
-	}
-
-	// TODO: サードパーティアプリが傍受出来てしまうのでどうにかする
-	publishMainStream(user.id, "registryUpdated", {
-		scope: ps.scope,
-		key: ps.key,
-		value: ps.value,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/i/revoke-token.ts b/packages/backend/src/server/api/endpoints/i/revoke-token.ts
deleted file mode 100644
index 308442bf7b..0000000000
--- a/packages/backend/src/server/api/endpoints/i/revoke-token.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import define from "../../define.js";
-import { AccessTokens } from "@/models/index.js";
-import { publishUserEvent } from "@/services/stream.js";
-
-export const meta = {
-	requireCredential: true,
-
-	secure: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		tokenId: { type: "string", format: "misskey:id" },
-	},
-	required: ["tokenId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const token = await AccessTokens.findOneBy({ id: ps.tokenId });
-
-	if (token) {
-		await AccessTokens.delete({
-			id: ps.tokenId,
-			userId: user.id,
-		});
-
-		// Terminate streaming
-		publishUserEvent(user.id, "terminate");
-	}
-});
diff --git a/packages/backend/src/server/api/endpoints/i/signin-history.ts b/packages/backend/src/server/api/endpoints/i/signin-history.ts
deleted file mode 100644
index 288b750b7b..0000000000
--- a/packages/backend/src/server/api/endpoints/i/signin-history.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import define from "../../define.js";
-import { Signins } from "@/models/index.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-
-export const meta = {
-	requireCredential: true,
-
-	secure: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const query = makePaginationQuery(
-		Signins.createQueryBuilder("signin"),
-		ps.sinceId,
-		ps.untilId,
-	).andWhere("signin.userId = :meId", { meId: user.id });
-
-	const history = await query.take(ps.limit).getMany();
-
-	return await Promise.all(history.map((record) => Signins.pack(record)));
-});
diff --git a/packages/backend/src/server/api/endpoints/i/unpin.ts b/packages/backend/src/server/api/endpoints/i/unpin.ts
deleted file mode 100644
index c248eb34e5..0000000000
--- a/packages/backend/src/server/api/endpoints/i/unpin.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import { removePinned } from "@/services/i/pin.js";
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { Users } from "@/models/index.js";
-
-export const meta = {
-	tags: ["account", "notes"],
-
-	requireCredential: true,
-
-	kind: "write:account",
-
-	errors: {
-		noSuchNote: {
-			message: "No such note.",
-			code: "NO_SUCH_NOTE",
-			id: "454170ce-9d63-4a43-9da1-ea10afe81e21",
-		},
-	},
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "MeDetailed",
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		noteId: { type: "string", format: "misskey:id" },
-	},
-	required: ["noteId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	await removePinned(user, ps.noteId).catch((e) => {
-		if (e.id === "b302d4cf-c050-400a-bbb3-be208681f40c")
-			throw new ApiError(meta.errors.noSuchNote);
-		throw e;
-	});
-
-	return await Users.pack<true, true>(user.id, user, {
-		detail: true,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/i/update-email.ts b/packages/backend/src/server/api/endpoints/i/update-email.ts
deleted file mode 100644
index 94ad6b3c72..0000000000
--- a/packages/backend/src/server/api/endpoints/i/update-email.ts
+++ /dev/null
@@ -1,95 +0,0 @@
-import { publishMainStream } from "@/services/stream.js";
-import define from "../../define.js";
-import rndstr from "rndstr";
-import config from "@/config/index.js";
-import { Users, UserProfiles } from "@/models/index.js";
-import { sendEmail } from "@/services/send-email.js";
-import { ApiError } from "../../error.js";
-import { validateEmailForAccount } from "@/services/validate-email-for-account.js";
-import { HOUR } from "@/const.js";
-import { comparePassword } from "@/misc/password.js";
-
-export const meta = {
-	requireCredential: true,
-
-	secure: true,
-
-	limit: {
-		duration: HOUR,
-		max: 3,
-	},
-
-	errors: {
-		incorrectPassword: {
-			message: "Incorrect password.",
-			code: "INCORRECT_PASSWORD",
-			id: "e54c1d7e-e7d6-4103-86b6-0a95069b4ad3",
-		},
-
-		unavailable: {
-			message: "Unavailable email address.",
-			code: "UNAVAILABLE",
-			id: "a2defefb-f220-8849-0af6-17f816099323",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		password: { type: "string" },
-		email: { type: "string", nullable: true },
-	},
-	required: ["password"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
-
-	// Compare password
-	const same = await comparePassword(ps.password, profile.password!);
-
-	if (!same) {
-		throw new ApiError(meta.errors.incorrectPassword);
-	}
-
-	if (ps.email != null) {
-		const available = await validateEmailForAccount(ps.email);
-		if (!available) {
-			throw new ApiError(meta.errors.unavailable);
-		}
-	}
-
-	await UserProfiles.update(user.id, {
-		email: ps.email,
-		emailVerified: false,
-		emailVerifyCode: null,
-	});
-
-	const iObj = await Users.pack(user.id, user, {
-		detail: true,
-		includeSecrets: true,
-	});
-
-	// Publish meUpdated event
-	publishMainStream(user.id, "meUpdated", iObj);
-
-	if (ps.email != null) {
-		const code = rndstr("a-z0-9", 16);
-
-		await UserProfiles.update(user.id, {
-			emailVerifyCode: code,
-		});
-
-		const link = `${config.url}/verify-email/${code}`;
-
-		sendEmail(
-			ps.email,
-			"Email verification",
-			`To verify email, please click this link:<br><a href="${link}">${link}</a>`,
-			`To verify email, please click this link: ${link}`,
-		);
-	}
-
-	return iObj;
-});
diff --git a/packages/backend/src/server/api/endpoints/i/update.ts b/packages/backend/src/server/api/endpoints/i/update.ts
deleted file mode 100644
index 56ed64296b..0000000000
--- a/packages/backend/src/server/api/endpoints/i/update.ts
+++ /dev/null
@@ -1,307 +0,0 @@
-import RE2 from "re2";
-import * as mfm from "mfm-js";
-import { publishMainStream, publishUserEvent } from "@/services/stream.js";
-import acceptAllFollowRequests from "@/services/following/requests/accept-all.js";
-import { publishToFollowers } from "@/services/i/update.js";
-import { extractCustomEmojisFromMfm } from "@/misc/extract-custom-emojis-from-mfm.js";
-import { extractHashtags } from "@/misc/extract-hashtags.js";
-import { updateUsertags } from "@/services/update-hashtag.js";
-import { Users, DriveFiles, UserProfiles, Pages } from "@/models/index.js";
-import type { User } from "@/models/entities/user.js";
-import type { UserProfile } from "@/models/entities/user-profile.js";
-import { notificationTypes } from "@/types.js";
-import { normalizeForSearch } from "@/misc/normalize-for-search.js";
-import { langmap } from "@/misc/langmap.js";
-import { ApiError } from "../../error.js";
-import define from "../../define.js";
-
-export const meta = {
-	tags: ["account"],
-
-	requireCredential: true,
-
-	kind: "write:account",
-
-	errors: {
-		noSuchAvatar: {
-			message: "No such avatar file.",
-			code: "NO_SUCH_AVATAR",
-			id: "539f3a45-f215-4f81-a9a8-31293640207f",
-		},
-
-		noSuchBanner: {
-			message: "No such banner file.",
-			code: "NO_SUCH_BANNER",
-			id: "0d8f5629-f210-41c2-9433-735831a58595",
-		},
-
-		avatarNotAnImage: {
-			message: "The file specified as an avatar is not an image.",
-			code: "AVATAR_NOT_AN_IMAGE",
-			id: "f419f9f8-2f4d-46b1-9fb4-49d3a2fd7191",
-		},
-
-		bannerNotAnImage: {
-			message: "The file specified as a banner is not an image.",
-			code: "BANNER_NOT_AN_IMAGE",
-			id: "75aedb19-2afd-4e6d-87fc-67941256fa60",
-		},
-
-		noSuchPage: {
-			message: "No such page.",
-			code: "NO_SUCH_PAGE",
-			id: "8e01b590-7eb9-431b-a239-860e086c408e",
-		},
-
-		invalidRegexp: {
-			message: "Invalid Regular Expression.",
-			code: "INVALID_REGEXP",
-			id: "0d786918-10df-41cd-8f33-8dec7d9a89a5",
-		},
-	},
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "MeDetailed",
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		name: { ...Users.nameSchema, nullable: true },
-		description: { ...Users.descriptionSchema, nullable: true },
-		location: { ...Users.locationSchema, nullable: true },
-		birthday: { ...Users.birthdaySchema, nullable: true },
-		lang: {
-			type: "string",
-			enum: [null, ...Object.keys(langmap)],
-			nullable: true,
-		},
-		avatarId: { type: "string", format: "misskey:id", nullable: true },
-		bannerId: { type: "string", format: "misskey:id", nullable: true },
-		fields: {
-			type: "array",
-			minItems: 0,
-			maxItems: 16,
-			items: {
-				type: "object",
-				properties: {
-					name: { type: "string" },
-					value: { type: "string" },
-				},
-				required: ["name", "value"],
-			},
-		},
-		isLocked: { type: "boolean" },
-		isExplorable: { type: "boolean" },
-		hideOnlineStatus: { type: "boolean" },
-		publicReactions: { type: "boolean" },
-		carefulBot: { type: "boolean" },
-		autoAcceptFollowed: { type: "boolean" },
-		noCrawle: { type: "boolean" },
-		isBot: { type: "boolean" },
-		isCat: { type: "boolean" },
-		speakAsCat: { type: "boolean" },
-		showTimelineReplies: { type: "boolean" },
-		injectFeaturedNote: { type: "boolean" },
-		receiveAnnouncementEmail: { type: "boolean" },
-		alwaysMarkNsfw: { type: "boolean" },
-		autoSensitive: { type: "boolean" },
-		ffVisibility: { type: "string", enum: ["public", "followers", "private"] },
-		pinnedPageId: { type: "string", format: "misskey:id", nullable: true },
-		mutedWords: { type: "array" },
-		mutedInstances: {
-			type: "array",
-			items: {
-				type: "string",
-			},
-		},
-		mutingNotificationTypes: {
-			type: "array",
-			items: {
-				type: "string",
-				enum: notificationTypes,
-			},
-		},
-		emailNotificationTypes: {
-			type: "array",
-			items: {
-				type: "string",
-			},
-		},
-	},
-} as const;
-
-export default define(meta, paramDef, async (ps, _user, token) => {
-	const user = await Users.findOneByOrFail({ id: _user.id });
-	const isSecure = token == null;
-
-	const updates = {} as Partial<User>;
-	const profileUpdates = {} as Partial<UserProfile>;
-
-	const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
-
-	if (ps.name !== undefined) updates.name = ps.name;
-	if (ps.description !== undefined) profileUpdates.description = ps.description;
-	if (ps.lang !== undefined) profileUpdates.lang = ps.lang;
-	if (ps.location !== undefined) profileUpdates.location = ps.location;
-	if (ps.birthday !== undefined) profileUpdates.birthday = ps.birthday;
-	if (ps.ffVisibility !== undefined)
-		profileUpdates.ffVisibility = ps.ffVisibility;
-	if (ps.avatarId !== undefined) updates.avatarId = ps.avatarId;
-	if (ps.bannerId !== undefined) updates.bannerId = ps.bannerId;
-	if (ps.mutedWords !== undefined) {
-		// validate regular expression syntax
-		ps.mutedWords
-			.filter((x) => !Array.isArray(x))
-			.forEach((x) => {
-				const regexp = x.match(/^\/(.+)\/(.*)$/);
-				if (!regexp) throw new ApiError(meta.errors.invalidRegexp);
-
-				try {
-					new RE2(regexp[1], regexp[2]);
-				} catch (err) {
-					throw new ApiError(meta.errors.invalidRegexp);
-				}
-			});
-
-		profileUpdates.mutedWords = ps.mutedWords;
-		profileUpdates.enableWordMute = ps.mutedWords.length > 0;
-	}
-	if (ps.mutedInstances !== undefined)
-		profileUpdates.mutedInstances = ps.mutedInstances;
-	if (ps.mutingNotificationTypes !== undefined)
-		profileUpdates.mutingNotificationTypes =
-			ps.mutingNotificationTypes as typeof notificationTypes[number][];
-	if (typeof ps.isLocked === "boolean") updates.isLocked = ps.isLocked;
-	if (typeof ps.isExplorable === "boolean")
-		updates.isExplorable = ps.isExplorable;
-	if (typeof ps.hideOnlineStatus === "boolean")
-		updates.hideOnlineStatus = ps.hideOnlineStatus;
-	if (typeof ps.publicReactions === "boolean")
-		profileUpdates.publicReactions = ps.publicReactions;
-	if (typeof ps.isBot === "boolean") updates.isBot = ps.isBot;
-	if (typeof ps.showTimelineReplies === "boolean")
-		updates.showTimelineReplies = ps.showTimelineReplies;
-	if (typeof ps.carefulBot === "boolean")
-		profileUpdates.carefulBot = ps.carefulBot;
-	if (typeof ps.autoAcceptFollowed === "boolean")
-		profileUpdates.autoAcceptFollowed = ps.autoAcceptFollowed;
-	if (typeof ps.noCrawle === "boolean") profileUpdates.noCrawle = ps.noCrawle;
-	if (typeof ps.isCat === "boolean") updates.isCat = ps.isCat;
-	if (typeof ps.speakAsCat === "boolean") updates.speakAsCat = ps.speakAsCat;
-	if (typeof ps.injectFeaturedNote === "boolean")
-		profileUpdates.injectFeaturedNote = ps.injectFeaturedNote;
-	if (typeof ps.receiveAnnouncementEmail === "boolean")
-		profileUpdates.receiveAnnouncementEmail = ps.receiveAnnouncementEmail;
-	if (typeof ps.alwaysMarkNsfw === "boolean")
-		profileUpdates.alwaysMarkNsfw = ps.alwaysMarkNsfw;
-	if (typeof ps.autoSensitive === "boolean")
-		profileUpdates.autoSensitive = ps.autoSensitive;
-	if (ps.emailNotificationTypes !== undefined)
-		profileUpdates.emailNotificationTypes = ps.emailNotificationTypes;
-
-	if (ps.avatarId) {
-		const avatar = await DriveFiles.findOneBy({ id: ps.avatarId });
-
-		if (avatar == null || avatar.userId !== user.id)
-			throw new ApiError(meta.errors.noSuchAvatar);
-		if (!avatar.type.startsWith("image/"))
-			throw new ApiError(meta.errors.avatarNotAnImage);
-	}
-
-	if (ps.bannerId) {
-		const banner = await DriveFiles.findOneBy({ id: ps.bannerId });
-
-		if (banner == null || banner.userId !== user.id)
-			throw new ApiError(meta.errors.noSuchBanner);
-		if (!banner.type.startsWith("image/"))
-			throw new ApiError(meta.errors.bannerNotAnImage);
-	}
-
-	if (ps.pinnedPageId) {
-		const page = await Pages.findOneBy({ id: ps.pinnedPageId });
-
-		if (page == null || page.userId !== user.id)
-			throw new ApiError(meta.errors.noSuchPage);
-
-		profileUpdates.pinnedPageId = page.id;
-	} else if (ps.pinnedPageId === null) {
-		profileUpdates.pinnedPageId = null;
-	}
-
-	if (ps.fields) {
-		profileUpdates.fields = ps.fields
-			.filter(
-				(x) =>
-					typeof x.name === "string" &&
-					x.name !== "" &&
-					typeof x.value === "string" &&
-					x.value !== "",
-			)
-			.map((x) => {
-				return { name: x.name, value: x.value };
-			});
-	}
-
-	//#region emojis/tags
-
-	let emojis = [] as string[];
-	let tags = [] as string[];
-
-	const newName = updates.name === undefined ? user.name : updates.name;
-	const newDescription =
-		profileUpdates.description === undefined
-			? profile.description
-			: profileUpdates.description;
-
-	if (newName != null) {
-		const tokens = mfm.parseSimple(newName);
-		emojis = emojis.concat(extractCustomEmojisFromMfm(tokens!));
-	}
-
-	if (newDescription != null) {
-		const tokens = mfm.parse(newDescription);
-		emojis = emojis.concat(extractCustomEmojisFromMfm(tokens!));
-		tags = extractHashtags(tokens!)
-			.map((tag) => normalizeForSearch(tag))
-			.splice(0, 32);
-	}
-
-	updates.emojis = emojis;
-	updates.tags = tags;
-
-	// ハッシュタグ更新
-	updateUsertags(user, tags);
-	//#endregion
-
-	if (Object.keys(updates).length > 0) await Users.update(user.id, updates);
-	if (Object.keys(profileUpdates).length > 0)
-		await UserProfiles.update(user.id, profileUpdates);
-
-	const iObj = await Users.pack<true, true>(user.id, user, {
-		detail: true,
-		includeSecrets: isSecure,
-	});
-
-	// Publish meUpdated event
-	publishMainStream(user.id, "meUpdated", iObj);
-	publishUserEvent(
-		user.id,
-		"updateUserProfile",
-		await UserProfiles.findOneBy({ userId: user.id }),
-	);
-
-	// 鍵垢を解除したとき、溜まっていたフォローリクエストがあるならすべて承認
-	if (user.isLocked && ps.isLocked === false) {
-		acceptAllFollowRequests(user);
-	}
-
-	// フォロワーにUpdateを配信
-	publishToFollowers(user.id);
-
-	return iObj;
-});
diff --git a/packages/backend/src/server/api/endpoints/i/user-group-invites.ts b/packages/backend/src/server/api/endpoints/i/user-group-invites.ts
deleted file mode 100644
index d0c6caf0e2..0000000000
--- a/packages/backend/src/server/api/endpoints/i/user-group-invites.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-import define from "../../define.js";
-import { UserGroupInvitations } from "@/models/index.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-
-export const meta = {
-	tags: ["account", "groups"],
-
-	requireCredential: true,
-
-	kind: "read:user-groups",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			properties: {
-				id: {
-					type: "string",
-					optional: false,
-					nullable: false,
-					format: "id",
-				},
-				group: {
-					type: "object",
-					optional: false,
-					nullable: false,
-					ref: "UserGroup",
-				},
-			},
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const query = makePaginationQuery(
-		UserGroupInvitations.createQueryBuilder("invitation"),
-		ps.sinceId,
-		ps.untilId,
-	)
-		.andWhere("invitation.userId = :meId", { meId: user.id })
-		.leftJoinAndSelect("invitation.userGroup", "user_group");
-
-	const invitations = await query.take(ps.limit).getMany();
-
-	return await UserGroupInvitations.packMany(invitations);
-});
diff --git a/packages/backend/src/server/api/endpoints/i/webhooks/create.ts b/packages/backend/src/server/api/endpoints/i/webhooks/create.ts
deleted file mode 100644
index 2b0f1781ea..0000000000
--- a/packages/backend/src/server/api/endpoints/i/webhooks/create.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import define from "../../../define.js";
-import { genId } from "@/misc/gen-id.js";
-import { Webhooks } from "@/models/index.js";
-import { publishInternalEvent } from "@/services/stream.js";
-import { webhookEventTypes } from "@/models/entities/webhook.js";
-
-export const meta = {
-	tags: ["webhooks"],
-
-	requireCredential: true,
-
-	kind: "write:account",
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		name: { type: "string", minLength: 1, maxLength: 100 },
-		url: { type: "string", minLength: 1, maxLength: 1024 },
-		secret: { type: "string", minLength: 1, maxLength: 1024 },
-		on: {
-			type: "array",
-			items: {
-				type: "string",
-				enum: webhookEventTypes,
-			},
-		},
-	},
-	required: ["name", "url", "secret", "on"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const webhook = await Webhooks.insert({
-		id: genId(),
-		createdAt: new Date(),
-		userId: user.id,
-		name: ps.name,
-		url: ps.url,
-		secret: ps.secret,
-		on: ps.on,
-	}).then((x) => Webhooks.findOneByOrFail(x.identifiers[0]));
-
-	publishInternalEvent("webhookCreated", webhook);
-
-	return webhook;
-});
diff --git a/packages/backend/src/server/api/endpoints/i/webhooks/delete.ts b/packages/backend/src/server/api/endpoints/i/webhooks/delete.ts
deleted file mode 100644
index 4a2c3d83be..0000000000
--- a/packages/backend/src/server/api/endpoints/i/webhooks/delete.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-import { Webhooks } from "@/models/index.js";
-import { publishInternalEvent } from "@/services/stream.js";
-
-export const meta = {
-	tags: ["webhooks"],
-
-	requireCredential: true,
-
-	kind: "write:account",
-
-	errors: {
-		noSuchWebhook: {
-			message: "No such webhook.",
-			code: "NO_SUCH_WEBHOOK",
-			id: "bae73e5a-5522-4965-ae19-3a8688e71d82",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		webhookId: { type: "string", format: "misskey:id" },
-	},
-	required: ["webhookId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const webhook = await Webhooks.findOneBy({
-		id: ps.webhookId,
-		userId: user.id,
-	});
-
-	if (webhook == null) {
-		throw new ApiError(meta.errors.noSuchWebhook);
-	}
-
-	await Webhooks.delete(webhook.id);
-
-	publishInternalEvent("webhookDeleted", webhook);
-});
diff --git a/packages/backend/src/server/api/endpoints/i/webhooks/list.ts b/packages/backend/src/server/api/endpoints/i/webhooks/list.ts
deleted file mode 100644
index 3afead5996..0000000000
--- a/packages/backend/src/server/api/endpoints/i/webhooks/list.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import define from "../../../define.js";
-import { Webhooks } from "@/models/index.js";
-
-export const meta = {
-	tags: ["webhooks", "account"],
-
-	requireCredential: true,
-
-	kind: "read:account",
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const webhooks = await Webhooks.findBy({
-		userId: me.id,
-	});
-
-	return webhooks;
-});
diff --git a/packages/backend/src/server/api/endpoints/i/webhooks/show.ts b/packages/backend/src/server/api/endpoints/i/webhooks/show.ts
deleted file mode 100644
index 96c0457475..0000000000
--- a/packages/backend/src/server/api/endpoints/i/webhooks/show.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-import { Webhooks } from "@/models/index.js";
-
-export const meta = {
-	tags: ["webhooks"],
-
-	requireCredential: true,
-
-	kind: "read:account",
-
-	errors: {
-		noSuchWebhook: {
-			message: "No such webhook.",
-			code: "NO_SUCH_WEBHOOK",
-			id: "50f614d9-3047-4f7e-90d8-ad6b2d5fb098",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		webhookId: { type: "string", format: "misskey:id" },
-	},
-	required: ["webhookId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const webhook = await Webhooks.findOneBy({
-		id: ps.webhookId,
-		userId: user.id,
-	});
-
-	if (webhook == null) {
-		throw new ApiError(meta.errors.noSuchWebhook);
-	}
-
-	return webhook;
-});
diff --git a/packages/backend/src/server/api/endpoints/i/webhooks/update.ts b/packages/backend/src/server/api/endpoints/i/webhooks/update.ts
deleted file mode 100644
index 161d705e12..0000000000
--- a/packages/backend/src/server/api/endpoints/i/webhooks/update.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-import { Webhooks } from "@/models/index.js";
-import { publishInternalEvent } from "@/services/stream.js";
-import { webhookEventTypes } from "@/models/entities/webhook.js";
-
-export const meta = {
-	tags: ["webhooks"],
-
-	requireCredential: true,
-
-	kind: "write:account",
-
-	errors: {
-		noSuchWebhook: {
-			message: "No such webhook.",
-			code: "NO_SUCH_WEBHOOK",
-			id: "fb0fea69-da18-45b1-828d-bd4fd1612518",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		webhookId: { type: "string", format: "misskey:id" },
-		name: { type: "string", minLength: 1, maxLength: 100 },
-		url: { type: "string", minLength: 1, maxLength: 1024 },
-		secret: { type: "string", minLength: 1, maxLength: 1024 },
-		on: {
-			type: "array",
-			items: {
-				type: "string",
-				enum: webhookEventTypes,
-			},
-		},
-		active: { type: "boolean" },
-	},
-	required: ["webhookId", "name", "url", "secret", "on", "active"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const webhook = await Webhooks.findOneBy({
-		id: ps.webhookId,
-		userId: user.id,
-	});
-
-	if (webhook == null) {
-		throw new ApiError(meta.errors.noSuchWebhook);
-	}
-
-	await Webhooks.update(webhook.id, {
-		name: ps.name,
-		url: ps.url,
-		secret: ps.secret,
-		on: ps.on,
-		active: ps.active,
-	});
-
-	publishInternalEvent("webhookUpdated", webhook);
-});
diff --git a/packages/backend/src/server/api/endpoints/latest-version.ts b/packages/backend/src/server/api/endpoints/latest-version.ts
deleted file mode 100644
index 72e84ae044..0000000000
--- a/packages/backend/src/server/api/endpoints/latest-version.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import define from "../define.js";
-
-export const meta = {
-	tags: ["meta"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async () => {
-	let tag_name;
-	await fetch(
-		"https://codeberg.org/api/v1/repos/calckey/calckey/releases?draft=false&pre-release=false&page=1&limit=1",
-	)
-		.then((response) => response.json())
-		.then((data) => {
-			tag_name = data[0].tag_name;
-		});
-
-	return {
-		tag_name,
-	};
-});
diff --git a/packages/backend/src/server/api/endpoints/messaging/history.ts b/packages/backend/src/server/api/endpoints/messaging/history.ts
deleted file mode 100644
index 7d1df69850..0000000000
--- a/packages/backend/src/server/api/endpoints/messaging/history.ts
+++ /dev/null
@@ -1,112 +0,0 @@
-import { Brackets } from "typeorm";
-import type { MessagingMessage } from "@/models/entities/messaging-message.js";
-import {
-	MessagingMessages,
-	Mutings,
-	UserGroupJoinings,
-} from "@/models/index.js";
-import define from "../../define.js";
-
-export const meta = {
-	tags: ["messaging"],
-
-	requireCredential: true,
-
-	kind: "read:messaging",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "MessagingMessage",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		group: { type: "boolean", default: false },
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const mute = await Mutings.findBy({
-		muterId: user.id,
-	});
-
-	const groups = ps.group
-		? await UserGroupJoinings.findBy({
-				userId: user.id,
-		  }).then((xs) => xs.map((x) => x.userGroupId))
-		: [];
-
-	if (ps.group && groups.length === 0) {
-		return [];
-	}
-
-	const history: MessagingMessage[] = [];
-
-	for (let i = 0; i < ps.limit; i++) {
-		const found = ps.group
-			? history.map((m) => m.groupId!)
-			: history.map((m) => (m.userId === user.id ? m.recipientId! : m.userId!));
-
-		const query = MessagingMessages.createQueryBuilder("message").orderBy(
-			"message.createdAt",
-			"DESC",
-		);
-
-		if (ps.group) {
-			query.where("message.groupId IN (:...groups)", { groups: groups });
-
-			if (found.length > 0) {
-				query.andWhere("message.groupId NOT IN (:...found)", { found: found });
-			}
-		} else {
-			query.where(
-				new Brackets((qb) => {
-					qb.where("message.userId = :userId", { userId: user.id }).orWhere(
-						"message.recipientId = :userId",
-						{ userId: user.id },
-					);
-				}),
-			);
-			query.andWhere("message.groupId IS NULL");
-
-			if (found.length > 0) {
-				query.andWhere("message.userId NOT IN (:...found)", { found: found });
-				query.andWhere("message.recipientId NOT IN (:...found)", {
-					found: found,
-				});
-			}
-
-			if (mute.length > 0) {
-				query.andWhere("message.userId NOT IN (:...mute)", {
-					mute: mute.map((m) => m.muteeId),
-				});
-				query.andWhere("message.recipientId NOT IN (:...mute)", {
-					mute: mute.map((m) => m.muteeId),
-				});
-			}
-		}
-
-		const message = await query.getOne();
-
-		if (message) {
-			history.push(message);
-		} else {
-			break;
-		}
-	}
-
-	return await Promise.all(
-		history.map((h) => MessagingMessages.pack(h.id, user)),
-	);
-});
diff --git a/packages/backend/src/server/api/endpoints/messaging/messages.ts b/packages/backend/src/server/api/endpoints/messaging/messages.ts
deleted file mode 100644
index 4b5440383c..0000000000
--- a/packages/backend/src/server/api/endpoints/messaging/messages.ts
+++ /dev/null
@@ -1,182 +0,0 @@
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { getUser } from "../../common/getters.js";
-import {
-	MessagingMessages,
-	UserGroups,
-	UserGroupJoinings,
-	Users,
-} from "@/models/index.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-import { Brackets } from "typeorm";
-import {
-	readUserMessagingMessage,
-	readGroupMessagingMessage,
-	deliverReadActivity,
-} from "../../common/read-messaging-message.js";
-
-export const meta = {
-	tags: ["messaging"],
-
-	requireCredential: true,
-
-	kind: "read:messaging",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "MessagingMessage",
-		},
-	},
-
-	errors: {
-		noSuchUser: {
-			message: "No such user.",
-			code: "NO_SUCH_USER",
-			id: "11795c64-40ea-4198-b06e-3c873ed9039d",
-		},
-
-		noSuchGroup: {
-			message: "No such group.",
-			code: "NO_SUCH_GROUP",
-			id: "c4d9f88c-9270-4632-b032-6ed8cee36f7f",
-		},
-
-		groupAccessDenied: {
-			message: "You can not read messages of groups that you have not joined.",
-			code: "GROUP_ACCESS_DENIED",
-			id: "a053a8dd-a491-4718-8f87-50775aad9284",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-		markAsRead: { type: "boolean", default: true },
-	},
-	anyOf: [
-		{
-			properties: {
-				userId: { type: "string", format: "misskey:id" },
-			},
-			required: ["userId"],
-		},
-		{
-			properties: {
-				groupId: { type: "string", format: "misskey:id" },
-			},
-			required: ["groupId"],
-		},
-	],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	if (ps.userId != null) {
-		// Fetch recipient (user)
-		const recipient = await getUser(ps.userId).catch((e) => {
-			if (e.id === "15348ddd-432d-49c2-8a5a-8069753becff")
-				throw new ApiError(meta.errors.noSuchUser);
-			throw e;
-		});
-
-		const query = makePaginationQuery(
-			MessagingMessages.createQueryBuilder("message"),
-			ps.sinceId,
-			ps.untilId,
-		)
-			.andWhere(
-				new Brackets((qb) => {
-					qb.where(
-						new Brackets((qb) => {
-							qb.where("message.userId = :meId").andWhere(
-								"message.recipientId = :recipientId",
-							);
-						}),
-					).orWhere(
-						new Brackets((qb) => {
-							qb.where("message.userId = :recipientId").andWhere(
-								"message.recipientId = :meId",
-							);
-						}),
-					);
-				}),
-			)
-			.setParameter("meId", user.id)
-			.setParameter("recipientId", recipient.id);
-
-		const messages = await query.take(ps.limit).getMany();
-
-		// Mark all as read
-		if (ps.markAsRead) {
-			readUserMessagingMessage(
-				user.id,
-				recipient.id,
-				messages.filter((m) => m.recipientId === user.id).map((x) => x.id),
-			);
-
-			// リモートユーザーとのメッセージだったら既読配信
-			if (Users.isLocalUser(user) && Users.isRemoteUser(recipient)) {
-				deliverReadActivity(user, recipient, messages);
-			}
-		}
-
-		return await Promise.all(
-			messages.map((message) =>
-				MessagingMessages.pack(message, user, {
-					populateRecipient: false,
-				}),
-			),
-		);
-	} else if (ps.groupId != null) {
-		// Fetch recipient (group)
-		const recipientGroup = await UserGroups.findOneBy({ id: ps.groupId });
-
-		if (recipientGroup == null) {
-			throw new ApiError(meta.errors.noSuchGroup);
-		}
-
-		// check joined
-		const joining = await UserGroupJoinings.findOneBy({
-			userId: user.id,
-			userGroupId: recipientGroup.id,
-		});
-
-		if (joining == null) {
-			throw new ApiError(meta.errors.groupAccessDenied);
-		}
-
-		const query = makePaginationQuery(
-			MessagingMessages.createQueryBuilder("message"),
-			ps.sinceId,
-			ps.untilId,
-		).andWhere("message.groupId = :groupId", { groupId: recipientGroup.id });
-
-		const messages = await query.take(ps.limit).getMany();
-
-		// Mark all as read
-		if (ps.markAsRead) {
-			readGroupMessagingMessage(
-				user.id,
-				recipientGroup.id,
-				messages.map((x) => x.id),
-			);
-		}
-
-		return await Promise.all(
-			messages.map((message) =>
-				MessagingMessages.pack(message, user, {
-					populateGroup: false,
-				}),
-			),
-		);
-	}
-});
diff --git a/packages/backend/src/server/api/endpoints/messaging/messages/create.ts b/packages/backend/src/server/api/endpoints/messaging/messages/create.ts
deleted file mode 100644
index ed9ae16df0..0000000000
--- a/packages/backend/src/server/api/endpoints/messaging/messages/create.ts
+++ /dev/null
@@ -1,165 +0,0 @@
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-import { getUser } from "../../../common/getters.js";
-import {
-	MessagingMessages,
-	DriveFiles,
-	UserGroups,
-	UserGroupJoinings,
-	Blockings,
-} from "@/models/index.js";
-import type { User } from "@/models/entities/user.js";
-import type { UserGroup } from "@/models/entities/user-group.js";
-import { createMessage } from "@/services/messages/create.js";
-
-export const meta = {
-	tags: ["messaging"],
-
-	requireCredential: true,
-
-	kind: "write:messaging",
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "MessagingMessage",
-	},
-
-	errors: {
-		recipientIsYourself: {
-			message: "You can not send a message to yourself.",
-			code: "RECIPIENT_IS_YOURSELF",
-			id: "17e2ba79-e22a-4cbc-bf91-d327643f4a7e",
-		},
-
-		noSuchUser: {
-			message: "No such user.",
-			code: "NO_SUCH_USER",
-			id: "11795c64-40ea-4198-b06e-3c873ed9039d",
-		},
-
-		noSuchGroup: {
-			message: "No such group.",
-			code: "NO_SUCH_GROUP",
-			id: "c94e2a5d-06aa-4914-8fa6-6a42e73d6537",
-		},
-
-		groupAccessDenied: {
-			message: "You can not send messages to groups that you have not joined.",
-			code: "GROUP_ACCESS_DENIED",
-			id: "d96b3cca-5ad1-438b-ad8b-02f931308fbd",
-		},
-
-		noSuchFile: {
-			message: "No such file.",
-			code: "NO_SUCH_FILE",
-			id: "4372b8e2-185d-4146-8749-2f68864a3e5f",
-		},
-
-		contentRequired: {
-			message: "Content required. You need to set text or fileId.",
-			code: "CONTENT_REQUIRED",
-			id: "25587321-b0e6-449c-9239-f8925092942c",
-		},
-
-		youHaveBeenBlocked: {
-			message:
-				"You cannot send a message because you have been blocked by this user.",
-			code: "YOU_HAVE_BEEN_BLOCKED",
-			id: "c15a5199-7422-4968-941a-2a462c478f7d",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		text: { type: "string", nullable: true, maxLength: 3000 },
-		fileId: { type: "string", format: "misskey:id" },
-	},
-	anyOf: [
-		{
-			properties: {
-				userId: { type: "string", format: "misskey:id" },
-			},
-			required: ["userId"],
-		},
-		{
-			properties: {
-				groupId: { type: "string", format: "misskey:id" },
-			},
-			required: ["groupId"],
-		},
-	],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	let recipientUser: User | null;
-	let recipientGroup: UserGroup | null;
-
-	if (ps.userId != null) {
-		// Myself
-		if (ps.userId === user.id) {
-			throw new ApiError(meta.errors.recipientIsYourself);
-		}
-
-		// Fetch recipient (user)
-		recipientUser = await getUser(ps.userId).catch((e) => {
-			if (e.id === "15348ddd-432d-49c2-8a5a-8069753becff")
-				throw new ApiError(meta.errors.noSuchUser);
-			throw e;
-		});
-
-		// Check blocking
-		const block = await Blockings.findOneBy({
-			blockerId: recipientUser.id,
-			blockeeId: user.id,
-		});
-		if (block) {
-			throw new ApiError(meta.errors.youHaveBeenBlocked);
-		}
-	} else if (ps.groupId != null) {
-		// Fetch recipient (group)
-		recipientGroup = await UserGroups.findOneBy({ id: ps.groupId! });
-
-		if (recipientGroup == null) {
-			throw new ApiError(meta.errors.noSuchGroup);
-		}
-
-		// check joined
-		const joining = await UserGroupJoinings.findOneBy({
-			userId: user.id,
-			userGroupId: recipientGroup.id,
-		});
-
-		if (joining == null) {
-			throw new ApiError(meta.errors.groupAccessDenied);
-		}
-	}
-
-	let file = null;
-	if (ps.fileId != null) {
-		file = await DriveFiles.findOneBy({
-			id: ps.fileId,
-			userId: user.id,
-		});
-
-		if (file == null) {
-			throw new ApiError(meta.errors.noSuchFile);
-		}
-	}
-
-	// テキストが無いかつ添付ファイルも無かったらエラー
-	if ((ps.text == null || ps.text.trim() === "") && file == null) {
-		throw new ApiError(meta.errors.contentRequired);
-	}
-
-	return await createMessage(
-		user,
-		recipientUser,
-		recipientGroup,
-		ps.text,
-		file,
-	);
-});
diff --git a/packages/backend/src/server/api/endpoints/messaging/messages/delete.ts b/packages/backend/src/server/api/endpoints/messaging/messages/delete.ts
deleted file mode 100644
index 42ff050d16..0000000000
--- a/packages/backend/src/server/api/endpoints/messaging/messages/delete.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-import { MessagingMessages } from "@/models/index.js";
-import { deleteMessage } from "@/services/messages/delete.js";
-import { SECOND, HOUR } from "@/const.js";
-
-export const meta = {
-	tags: ["messaging"],
-
-	requireCredential: true,
-
-	kind: "write:messaging",
-
-	limit: {
-		duration: HOUR,
-		max: 300,
-		minInterval: SECOND,
-	},
-
-	errors: {
-		noSuchMessage: {
-			message: "No such message.",
-			code: "NO_SUCH_MESSAGE",
-			id: "54b5b326-7925-42cf-8019-130fda8b56af",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		messageId: { type: "string", format: "misskey:id" },
-	},
-	required: ["messageId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const message = await MessagingMessages.findOneBy({
-		id: ps.messageId,
-		userId: user.id,
-	});
-
-	if (message == null) {
-		throw new ApiError(meta.errors.noSuchMessage);
-	}
-
-	await deleteMessage(message);
-});
diff --git a/packages/backend/src/server/api/endpoints/messaging/messages/read.ts b/packages/backend/src/server/api/endpoints/messaging/messages/read.ts
deleted file mode 100644
index 0ef013b799..0000000000
--- a/packages/backend/src/server/api/endpoints/messaging/messages/read.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-import { MessagingMessages } from "@/models/index.js";
-import {
-	readUserMessagingMessage,
-	readGroupMessagingMessage,
-} from "../../../common/read-messaging-message.js";
-
-export const meta = {
-	tags: ["messaging"],
-
-	requireCredential: true,
-
-	kind: "write:messaging",
-
-	errors: {
-		noSuchMessage: {
-			message: "No such message.",
-			code: "NO_SUCH_MESSAGE",
-			id: "86d56a2f-a9c3-4afb-b13c-3e9bfef9aa14",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		messageId: { type: "string", format: "misskey:id" },
-	},
-	required: ["messageId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const message = await MessagingMessages.findOneBy({ id: ps.messageId });
-
-	if (message == null) {
-		throw new ApiError(meta.errors.noSuchMessage);
-	}
-
-	if (message.recipientId) {
-		await readUserMessagingMessage(user.id, message.userId, [message.id]).catch(
-			(e) => {
-				if (e.id === "e140a4bf-49ce-4fb6-b67c-b78dadf6b52f")
-					throw new ApiError(meta.errors.noSuchMessage);
-				throw e;
-			},
-		);
-	} else if (message.groupId) {
-		await readGroupMessagingMessage(user.id, message.groupId, [
-			message.id,
-		]).catch((e) => {
-			if (e.id === "930a270c-714a-46b2-b776-ad27276dc569")
-				throw new ApiError(meta.errors.noSuchMessage);
-			throw e;
-		});
-	}
-});
diff --git a/packages/backend/src/server/api/endpoints/meta.ts b/packages/backend/src/server/api/endpoints/meta.ts
deleted file mode 100644
index 4dc1c941e3..0000000000
--- a/packages/backend/src/server/api/endpoints/meta.ts
+++ /dev/null
@@ -1,530 +0,0 @@
-import { IsNull, MoreThan } from "typeorm";
-import config from "@/config/index.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { Ads, Emojis, Users } from "@/models/index.js";
-import { MAX_NOTE_TEXT_LENGTH, MAX_CAPTION_TEXT_LENGTH } from "@/const.js";
-import define from "../define.js";
-
-export const meta = {
-	tags: ["meta"],
-
-	requireCredential: false,
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		properties: {
-			maintainerName: {
-				type: "string",
-				optional: false,
-				nullable: true,
-			},
-			maintainerEmail: {
-				type: "string",
-				optional: false,
-				nullable: true,
-			},
-			version: {
-				type: "string",
-				optional: false,
-				nullable: false,
-				example: config.version,
-			},
-			name: {
-				type: "string",
-				optional: false,
-				nullable: false,
-			},
-			uri: {
-				type: "string",
-				optional: false,
-				nullable: false,
-				format: "url",
-				example: "https://calckey.example.com",
-			},
-			description: {
-				type: "string",
-				optional: false,
-				nullable: true,
-			},
-			langs: {
-				type: "array",
-				optional: false,
-				nullable: false,
-				items: {
-					type: "string",
-					optional: false,
-					nullable: false,
-				},
-			},
-			tosUrl: {
-				type: "string",
-				optional: false,
-				nullable: true,
-			},
-			repositoryUrl: {
-				type: "string",
-				optional: false,
-				nullable: false,
-				default: "https://codeberg.org/calckey/calckey",
-			},
-			feedbackUrl: {
-				type: "string",
-				optional: false,
-				nullable: false,
-				default: "https://codeberg.org/calckey/calckey/issues",
-			},
-			defaultDarkTheme: {
-				type: "string",
-				optional: false,
-				nullable: true,
-			},
-			defaultLightTheme: {
-				type: "string",
-				optional: false,
-				nullable: true,
-			},
-			disableRegistration: {
-				type: "boolean",
-				optional: false,
-				nullable: false,
-			},
-			disableLocalTimeline: {
-				type: "boolean",
-				optional: false,
-				nullable: false,
-			},
-			disableRecommendedTimeline: {
-				type: "boolean",
-				optional: false,
-				nullable: false,
-			},
-			disableGlobalTimeline: {
-				type: "boolean",
-				optional: false,
-				nullable: false,
-			},
-			driveCapacityPerLocalUserMb: {
-				type: "number",
-				optional: false,
-				nullable: false,
-			},
-			driveCapacityPerRemoteUserMb: {
-				type: "number",
-				optional: false,
-				nullable: false,
-			},
-			cacheRemoteFiles: {
-				type: "boolean",
-				optional: false,
-				nullable: false,
-			},
-			emailRequiredForSignup: {
-				type: "boolean",
-				optional: false,
-				nullable: false,
-			},
-			enableHcaptcha: {
-				type: "boolean",
-				optional: false,
-				nullable: false,
-			},
-			hcaptchaSiteKey: {
-				type: "string",
-				optional: false,
-				nullable: true,
-			},
-			enableRecaptcha: {
-				type: "boolean",
-				optional: false,
-				nullable: false,
-			},
-			recaptchaSiteKey: {
-				type: "string",
-				optional: false,
-				nullable: true,
-			},
-			swPublickey: {
-				type: "string",
-				optional: false,
-				nullable: true,
-			},
-			mascotImageUrl: {
-				type: "string",
-				optional: false,
-				nullable: false,
-				default: "/assets/ai.png",
-			},
-			bannerUrl: {
-				type: "string",
-				optional: false,
-				nullable: false,
-			},
-			errorImageUrl: {
-				type: "string",
-				optional: false,
-				nullable: false,
-				default: "https://xn--931a.moe/aiart/yubitun.png",
-			},
-			iconUrl: {
-				type: "string",
-				optional: false,
-				nullable: true,
-			},
-			maxNoteTextLength: {
-				type: "number",
-				optional: false,
-				nullable: false,
-			},
-			maxCaptionTextLength: {
-				type: "number",
-				optional: false,
-				nullable: false,
-			},
-			emojis: {
-				type: "array",
-				optional: false,
-				nullable: false,
-				items: {
-					type: "object",
-					optional: false,
-					nullable: false,
-					properties: {
-						id: {
-							type: "string",
-							optional: false,
-							nullable: false,
-							format: "id",
-						},
-						aliases: {
-							type: "array",
-							optional: false,
-							nullable: false,
-							items: {
-								type: "string",
-								optional: false,
-								nullable: false,
-							},
-						},
-						category: {
-							type: "string",
-							optional: false,
-							nullable: true,
-						},
-						host: {
-							type: "string",
-							optional: false,
-							nullable: true,
-							description: "The local host is represented with `null`.",
-						},
-						url: {
-							type: "string",
-							optional: false,
-							nullable: false,
-							format: "url",
-						},
-					},
-				},
-			},
-			ads: {
-				type: "array",
-				optional: false,
-				nullable: false,
-				items: {
-					type: "object",
-					optional: false,
-					nullable: false,
-					properties: {
-						place: {
-							type: "string",
-							optional: false,
-							nullable: false,
-						},
-						url: {
-							type: "string",
-							optional: false,
-							nullable: false,
-							format: "url",
-						},
-						imageUrl: {
-							type: "string",
-							optional: false,
-							nullable: false,
-							format: "url",
-						},
-					},
-				},
-			},
-			requireSetup: {
-				type: "boolean",
-				optional: false,
-				nullable: false,
-				example: false,
-			},
-			enableEmail: {
-				type: "boolean",
-				optional: false,
-				nullable: false,
-			},
-			enableTwitterIntegration: {
-				type: "boolean",
-				optional: false,
-				nullable: false,
-			},
-			enableGithubIntegration: {
-				type: "boolean",
-				optional: false,
-				nullable: false,
-			},
-			enableDiscordIntegration: {
-				type: "boolean",
-				optional: false,
-				nullable: false,
-			},
-			enableServiceWorker: {
-				type: "boolean",
-				optional: false,
-				nullable: false,
-			},
-			translatorAvailable: {
-				type: "boolean",
-				optional: false,
-				nullable: false,
-			},
-			proxyAccountName: {
-				type: "string",
-				optional: false,
-				nullable: true,
-			},
-			features: {
-				type: "object",
-				optional: true,
-				nullable: false,
-				properties: {
-					registration: {
-						type: "boolean",
-						optional: false,
-						nullable: false,
-					},
-					localTimeLine: {
-						type: "boolean",
-						optional: false,
-						nullable: false,
-					},
-					recommendedTimeLine: {
-						type: "boolean",
-						optional: false,
-						nullable: false,
-					},
-					globalTimeLine: {
-						type: "boolean",
-						optional: false,
-						nullable: false,
-					},
-					elasticsearch: {
-						type: "boolean",
-						optional: false,
-						nullable: false,
-					},
-					hcaptcha: {
-						type: "boolean",
-						optional: false,
-						nullable: false,
-					},
-					recaptcha: {
-						type: "boolean",
-						optional: false,
-						nullable: false,
-					},
-					objectStorage: {
-						type: "boolean",
-						optional: false,
-						nullable: false,
-					},
-					twitter: {
-						type: "boolean",
-						optional: false,
-						nullable: false,
-					},
-					github: {
-						type: "boolean",
-						optional: false,
-						nullable: false,
-					},
-					discord: {
-						type: "boolean",
-						optional: false,
-						nullable: false,
-					},
-					serviceWorker: {
-						type: "boolean",
-						optional: false,
-						nullable: false,
-					},
-					miauth: {
-						type: "boolean",
-						optional: true,
-						nullable: false,
-						default: true,
-					},
-				},
-			},
-			secureMode: {
-				type: "boolean",
-				optional: true,
-				nullable: false,
-				default: false,
-			},
-			privateMode: {
-				type: "boolean",
-				optional: true,
-				nullable: false,
-				default: false,
-			},
-			defaultReaction: {
-				type: "string",
-				optional: "false",
-				nullable: false,
-				default: "⭐",
-			},
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		detail: { type: "boolean", default: true },
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const instance = await fetchMeta(true);
-
-	const emojis = await Emojis.find({
-		where: {
-			host: IsNull(),
-		},
-		order: {
-			category: "ASC",
-			name: "ASC",
-		},
-		cache: {
-			id: "meta_emojis",
-			milliseconds: 3600000, // 1 hour
-		},
-	});
-
-	const ads = await Ads.find({
-		where: {
-			expiresAt: MoreThan(new Date()),
-		},
-	});
-
-	const response: any = {
-		maintainerName: instance.maintainerName,
-		maintainerEmail: instance.maintainerEmail,
-
-		version: config.version,
-
-		name: instance.name,
-		uri: config.url,
-		description: instance.description,
-		langs: instance.langs,
-		tosUrl: instance.ToSUrl,
-		repositoryUrl: instance.repositoryUrl,
-		feedbackUrl: instance.feedbackUrl,
-
-		secureMode: instance.secureMode,
-		privateMode: instance.privateMode,
-
-		disableRegistration: instance.disableRegistration,
-		disableLocalTimeline: instance.disableLocalTimeline,
-		disableRecommendedTimeline: instance.disableRecommendedTimeline,
-		disableGlobalTimeline: instance.disableGlobalTimeline,
-		driveCapacityPerLocalUserMb: instance.localDriveCapacityMb,
-		driveCapacityPerRemoteUserMb: instance.remoteDriveCapacityMb,
-		emailRequiredForSignup: instance.emailRequiredForSignup,
-		enableHcaptcha: instance.enableHcaptcha,
-		hcaptchaSiteKey: instance.hcaptchaSiteKey,
-		enableRecaptcha: instance.enableRecaptcha,
-		recaptchaSiteKey: instance.recaptchaSiteKey,
-		swPublickey: instance.swPublicKey,
-		themeColor: instance.themeColor,
-		mascotImageUrl: instance.mascotImageUrl,
-		bannerUrl: instance.bannerUrl,
-		errorImageUrl: instance.errorImageUrl,
-		iconUrl: instance.iconUrl,
-		backgroundImageUrl: instance.backgroundImageUrl,
-		logoImageUrl: instance.logoImageUrl,
-		maxNoteTextLength: MAX_NOTE_TEXT_LENGTH, // 後方互換性のため
-		maxCaptionTextLength: MAX_CAPTION_TEXT_LENGTH,
-		emojis: instance.privateMode && !me ? [] : await Emojis.packMany(emojis),
-		defaultLightTheme: instance.defaultLightTheme,
-		defaultDarkTheme: instance.defaultDarkTheme,
-		ads:
-			instance.privateMode && !me
-				? []
-				: ads.map((ad) => ({
-						id: ad.id,
-						url: ad.url,
-						place: ad.place,
-						ratio: ad.ratio,
-						imageUrl: ad.imageUrl,
-				  })),
-		enableEmail: instance.enableEmail,
-
-		enableTwitterIntegration: instance.enableTwitterIntegration,
-		enableGithubIntegration: instance.enableGithubIntegration,
-		enableDiscordIntegration: instance.enableDiscordIntegration,
-
-		enableServiceWorker: instance.enableServiceWorker,
-
-		translatorAvailable: instance.deeplAuthKey != null,
-		defaultReaction: instance.defaultReaction,
-
-		...(ps.detail
-			? {
-					pinnedPages: instance.privateMode && !me ? [] : instance.pinnedPages,
-					pinnedClipId:
-						instance.privateMode && !me ? [] : instance.pinnedClipId,
-					cacheRemoteFiles: instance.cacheRemoteFiles,
-					requireSetup:
-						(await Users.countBy({
-							host: IsNull(),
-							isAdmin: true,
-						})) === 0,
-			  }
-			: {}),
-	};
-
-	if (ps.detail) {
-		if (!instance.privateMode || me) {
-			const proxyAccount = instance.proxyAccountId
-				? await Users.pack(instance.proxyAccountId).catch(() => null)
-				: null;
-			response.proxyAccountName = proxyAccount ? proxyAccount.username : null;
-		}
-
-		response.features = {
-			registration: !instance.disableRegistration,
-			localTimeLine: !instance.disableLocalTimeline,
-			recommendedTimeline: !instance.disableRecommendedTimeline,
-			globalTimeLine: !instance.disableGlobalTimeline,
-			emailRequiredForSignup: instance.emailRequiredForSignup,
-			elasticsearch: config.elasticsearch ? true : false,
-			hcaptcha: instance.enableHcaptcha,
-			recaptcha: instance.enableRecaptcha,
-			objectStorage: instance.useObjectStorage,
-			twitter: instance.enableTwitterIntegration,
-			github: instance.enableGithubIntegration,
-			discord: instance.enableDiscordIntegration,
-			serviceWorker: instance.enableServiceWorker,
-			miauth: true,
-		};
-	}
-
-	return response;
-});
diff --git a/packages/backend/src/server/api/endpoints/miauth/gen-token.ts b/packages/backend/src/server/api/endpoints/miauth/gen-token.ts
deleted file mode 100644
index 0525d79a7e..0000000000
--- a/packages/backend/src/server/api/endpoints/miauth/gen-token.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-import define from "../../define.js";
-import { AccessTokens } from "@/models/index.js";
-import { genId } from "@/misc/gen-id.js";
-import { secureRndstr } from "@/misc/secure-rndstr.js";
-
-export const meta = {
-	tags: ["auth"],
-
-	requireCredential: true,
-
-	secure: true,
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		properties: {
-			token: {
-				type: "string",
-				optional: false,
-				nullable: false,
-			},
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		session: { type: "string", nullable: true },
-		name: { type: "string", nullable: true },
-		description: { type: "string", nullable: true },
-		iconUrl: { type: "string", nullable: true },
-		permission: {
-			type: "array",
-			uniqueItems: true,
-			items: {
-				type: "string",
-			},
-		},
-	},
-	required: ["session", "permission"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	// Generate access token
-	const accessToken = secureRndstr(32, true);
-
-	const now = new Date();
-
-	// Insert access token doc
-	await AccessTokens.insert({
-		id: genId(),
-		createdAt: now,
-		lastUsedAt: now,
-		session: ps.session,
-		userId: user.id,
-		token: accessToken,
-		hash: accessToken,
-		name: ps.name,
-		description: ps.description,
-		iconUrl: ps.iconUrl,
-		permission: ps.permission,
-	});
-
-	return {
-		token: accessToken,
-	};
-});
diff --git a/packages/backend/src/server/api/endpoints/mute/create.ts b/packages/backend/src/server/api/endpoints/mute/create.ts
deleted file mode 100644
index bacab9b458..0000000000
--- a/packages/backend/src/server/api/endpoints/mute/create.ts
+++ /dev/null
@@ -1,95 +0,0 @@
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { getUser } from "../../common/getters.js";
-import { genId } from "@/misc/gen-id.js";
-import { Mutings, NoteWatchings } from "@/models/index.js";
-import type { Muting } from "@/models/entities/muting.js";
-import { publishUserEvent } from "@/services/stream.js";
-
-export const meta = {
-	tags: ["account"],
-
-	requireCredential: true,
-
-	kind: "write:mutes",
-
-	errors: {
-		noSuchUser: {
-			message: "No such user.",
-			code: "NO_SUCH_USER",
-			id: "6fef56f3-e765-4957-88e5-c6f65329b8a5",
-		},
-
-		muteeIsYourself: {
-			message: "Mutee is yourself.",
-			code: "MUTEE_IS_YOURSELF",
-			id: "a4619cb2-5f23-484b-9301-94c903074e10",
-		},
-
-		alreadyMuting: {
-			message: "You are already muting that user.",
-			code: "ALREADY_MUTING",
-			id: "7e7359cb-160c-4956-b08f-4d1c653cd007",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		userId: { type: "string", format: "misskey:id" },
-		expiresAt: {
-			type: "integer",
-			nullable: true,
-			description:
-				"A Unix Epoch timestamp that must lie in the future. `null` means an indefinite mute.",
-		},
-	},
-	required: ["userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const muter = user;
-
-	// 自分自身
-	if (user.id === ps.userId) {
-		throw new ApiError(meta.errors.muteeIsYourself);
-	}
-
-	// Get mutee
-	const mutee = await getUser(ps.userId).catch((e) => {
-		if (e.id === "15348ddd-432d-49c2-8a5a-8069753becff")
-			throw new ApiError(meta.errors.noSuchUser);
-		throw e;
-	});
-
-	// Check if already muting
-	const exist = await Mutings.findOneBy({
-		muterId: muter.id,
-		muteeId: mutee.id,
-	});
-
-	if (exist != null) {
-		throw new ApiError(meta.errors.alreadyMuting);
-	}
-
-	if (ps.expiresAt && ps.expiresAt <= Date.now()) {
-		return;
-	}
-
-	// Create mute
-	await Mutings.insert({
-		id: genId(),
-		createdAt: new Date(),
-		expiresAt: ps.expiresAt ? new Date(ps.expiresAt) : null,
-		muterId: muter.id,
-		muteeId: mutee.id,
-	} as Muting);
-
-	publishUserEvent(user.id, "mute", mutee);
-
-	NoteWatchings.delete({
-		userId: muter.id,
-		noteUserId: mutee.id,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/mute/delete.ts b/packages/backend/src/server/api/endpoints/mute/delete.ts
deleted file mode 100644
index cc67a44c26..0000000000
--- a/packages/backend/src/server/api/endpoints/mute/delete.ts
+++ /dev/null
@@ -1,74 +0,0 @@
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { getUser } from "../../common/getters.js";
-import { Mutings } from "@/models/index.js";
-import { publishUserEvent } from "@/services/stream.js";
-
-export const meta = {
-	tags: ["account"],
-
-	requireCredential: true,
-
-	kind: "write:mutes",
-
-	errors: {
-		noSuchUser: {
-			message: "No such user.",
-			code: "NO_SUCH_USER",
-			id: "b851d00b-8ab1-4a56-8b1b-e24187cb48ef",
-		},
-
-		muteeIsYourself: {
-			message: "Mutee is yourself.",
-			code: "MUTEE_IS_YOURSELF",
-			id: "f428b029-6b39-4d48-a1d2-cc1ae6dd5cf9",
-		},
-
-		notMuting: {
-			message: "You are not muting that user.",
-			code: "NOT_MUTING",
-			id: "5467d020-daa9-4553-81e1-135c0c35a96d",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		userId: { type: "string", format: "misskey:id" },
-	},
-	required: ["userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const muter = user;
-
-	// Check if the mutee is yourself
-	if (user.id === ps.userId) {
-		throw new ApiError(meta.errors.muteeIsYourself);
-	}
-
-	// Get mutee
-	const mutee = await getUser(ps.userId).catch((e) => {
-		if (e.id === "15348ddd-432d-49c2-8a5a-8069753becff")
-			throw new ApiError(meta.errors.noSuchUser);
-		throw e;
-	});
-
-	// Check not muting
-	const exist = await Mutings.findOneBy({
-		muterId: muter.id,
-		muteeId: mutee.id,
-	});
-
-	if (exist == null) {
-		throw new ApiError(meta.errors.notMuting);
-	}
-
-	// Delete mute
-	await Mutings.delete({
-		id: exist.id,
-	});
-
-	publishUserEvent(user.id, "unmute", mutee);
-});
diff --git a/packages/backend/src/server/api/endpoints/mute/list.ts b/packages/backend/src/server/api/endpoints/mute/list.ts
deleted file mode 100644
index 7bbe29a4c8..0000000000
--- a/packages/backend/src/server/api/endpoints/mute/list.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import define from "../../define.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-import { Mutings } from "@/models/index.js";
-
-export const meta = {
-	tags: ["account"],
-
-	requireCredential: true,
-
-	kind: "read:mutes",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Muting",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 30 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const query = makePaginationQuery(
-		Mutings.createQueryBuilder("muting"),
-		ps.sinceId,
-		ps.untilId,
-	).andWhere("muting.muterId = :meId", { meId: me.id });
-
-	const mutings = await query.take(ps.limit).getMany();
-
-	return await Mutings.packMany(mutings, me);
-});
diff --git a/packages/backend/src/server/api/endpoints/my/apps.ts b/packages/backend/src/server/api/endpoints/my/apps.ts
deleted file mode 100644
index 8a097c8a04..0000000000
--- a/packages/backend/src/server/api/endpoints/my/apps.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import define from "../../define.js";
-import { Apps } from "@/models/index.js";
-
-export const meta = {
-	tags: ["account", "app"],
-
-	requireCredential: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "App",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		offset: { type: "integer", default: 0 },
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const query = {
-		userId: user.id,
-	};
-
-	const apps = await Apps.find({
-		where: query,
-		take: ps.limit,
-		skip: ps.offset,
-	});
-
-	return await Promise.all(
-		apps.map((app) =>
-			Apps.pack(app, user, {
-				detail: true,
-			}),
-		),
-	);
-});
diff --git a/packages/backend/src/server/api/endpoints/notes.ts b/packages/backend/src/server/api/endpoints/notes.ts
deleted file mode 100644
index 9787740ab0..0000000000
--- a/packages/backend/src/server/api/endpoints/notes.ts
+++ /dev/null
@@ -1,91 +0,0 @@
-import { Notes } from "@/models/index.js";
-import define from "../define.js";
-import { makePaginationQuery } from "../common/make-pagination-query.js";
-
-export const meta = {
-	tags: ["notes"],
-
-	requireCredentialPrivateMode: true,
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Note",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		local: { type: "boolean", default: false },
-		reply: { type: "boolean" },
-		renote: { type: "boolean" },
-		withFiles: { type: "boolean" },
-		poll: { type: "boolean" },
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	const query = makePaginationQuery(
-		Notes.createQueryBuilder("note"),
-		ps.sinceId,
-		ps.untilId,
-	)
-		.andWhere("note.visibility = 'public'")
-		.andWhere("note.localOnly = FALSE")
-		.innerJoinAndSelect("note.user", "user")
-		.leftJoinAndSelect("user.avatar", "avatar")
-		.leftJoinAndSelect("user.banner", "banner")
-		.leftJoinAndSelect("note.reply", "reply")
-		.leftJoinAndSelect("note.renote", "renote")
-		.leftJoinAndSelect("reply.user", "replyUser")
-		.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
-		.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
-		.leftJoinAndSelect("renote.user", "renoteUser")
-		.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
-		.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner");
-
-	if (ps.local) {
-		query.andWhere("note.userHost IS NULL");
-	}
-
-	if (ps.reply !== undefined) {
-		query.andWhere(
-			ps.reply ? "note.replyId IS NOT NULL" : "note.replyId IS NULL",
-		);
-	}
-
-	if (ps.renote !== undefined) {
-		query.andWhere(
-			ps.renote ? "note.renoteId IS NOT NULL" : "note.renoteId IS NULL",
-		);
-	}
-
-	if (ps.withFiles !== undefined) {
-		query.andWhere(
-			ps.withFiles ? "note.fileIds != '{}'" : "note.fileIds = '{}'",
-		);
-	}
-
-	if (ps.poll !== undefined) {
-		query.andWhere(ps.poll ? "note.hasPoll = TRUE" : "note.hasPoll = FALSE");
-	}
-
-	// TODO
-	//if (bot != undefined) {
-	//	query.isBot = bot;
-	//}
-
-	const notes = await query.take(ps.limit).getMany();
-
-	return await Notes.packMany(notes);
-});
diff --git a/packages/backend/src/server/api/endpoints/notes/children.ts b/packages/backend/src/server/api/endpoints/notes/children.ts
deleted file mode 100644
index 9047fcce1d..0000000000
--- a/packages/backend/src/server/api/endpoints/notes/children.ts
+++ /dev/null
@@ -1,62 +0,0 @@
-import { Brackets } from "typeorm";
-import { Notes } from "@/models/index.js";
-import define from "../../define.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-import { generateVisibilityQuery } from "../../common/generate-visibility-query.js";
-import { generateMutedUserQuery } from "../../common/generate-muted-user-query.js";
-import { generateBlockedUserQuery } from "../../common/generate-block-query.js";
-
-export const meta = {
-	tags: ["notes"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Note",
-		},
-	},
-};
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		noteId: { type: "string", format: "misskey:id" },
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-	},
-	required: ["noteId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const query = makePaginationQuery(
-		Notes.createQueryBuilder("note"),
-		ps.sinceId,
-		ps.untilId,
-	)
-		.andWhere(
-			"note.id IN (SELECT id FROM note_replies(:noteId, :depth, :limit))",
-			{ noteId: ps.noteId, depth: ps.depth, limit: ps.limit },
-		)
-		.innerJoinAndSelect("note.user", "user")
-		.leftJoinAndSelect("user.avatar", "avatar")
-		.leftJoinAndSelect("user.banner", "banner");
-
-	generateVisibilityQuery(query, user);
-	if (user) {
-		generateMutedUserQuery(query, user);
-		generateBlockedUserQuery(query, user);
-	}
-
-	const notes = await query.getMany();
-
-	return await Notes.packMany(notes, user, { detail: false });
-});
diff --git a/packages/backend/src/server/api/endpoints/notes/clips.ts b/packages/backend/src/server/api/endpoints/notes/clips.ts
deleted file mode 100644
index 34b035add2..0000000000
--- a/packages/backend/src/server/api/endpoints/notes/clips.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import { In } from "typeorm";
-import { ClipNotes, Clips } from "@/models/index.js";
-import define from "../../define.js";
-import { getNote } from "../../common/getters.js";
-import { ApiError } from "../../error.js";
-
-export const meta = {
-	tags: ["clips", "notes"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Clip",
-		},
-	},
-
-	errors: {
-		noSuchNote: {
-			message: "No such note.",
-			code: "NO_SUCH_NOTE",
-			id: "47db1a1c-b0af-458d-8fb4-986e4efafe1e",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		noteId: { type: "string", format: "misskey:id" },
-	},
-	required: ["noteId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const note = await getNote(ps.noteId, me).catch((err) => {
-		if (err.id === "9725d0ce-ba28-4dde-95a7-2cbb2c15de24")
-			throw new ApiError(meta.errors.noSuchNote);
-		throw err;
-	});
-
-	const clipNotes = await ClipNotes.findBy({
-		noteId: note.id,
-	});
-
-	const clips = await Clips.findBy({
-		id: In(clipNotes.map((x) => x.clipId)),
-		isPublic: true,
-	});
-
-	return await Promise.all(clips.map((x) => Clips.pack(x)));
-});
diff --git a/packages/backend/src/server/api/endpoints/notes/conversation.ts b/packages/backend/src/server/api/endpoints/notes/conversation.ts
deleted file mode 100644
index 2e8f5ef73b..0000000000
--- a/packages/backend/src/server/api/endpoints/notes/conversation.ts
+++ /dev/null
@@ -1,81 +0,0 @@
-import type { Note } from "@/models/entities/note.js";
-import { Notes } from "@/models/index.js";
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { getNote } from "../../common/getters.js";
-
-export const meta = {
-	tags: ["notes"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Note",
-		},
-	},
-
-	errors: {
-		noSuchNote: {
-			message: "No such note.",
-			code: "NO_SUCH_NOTE",
-			id: "e1035875-9551-45ec-afa8-1ded1fcb53c8",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		noteId: { type: "string", format: "misskey:id" },
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		offset: { type: "integer", default: 0 },
-	},
-	required: ["noteId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const note = await getNote(ps.noteId, user).catch((err) => {
-		if (err.id === "9725d0ce-ba28-4dde-95a7-2cbb2c15de24")
-			throw new ApiError(meta.errors.noSuchNote);
-		throw err;
-	});
-
-	const conversation: Note[] = [];
-	let i = 0;
-
-	async function get(id: any) {
-		i++;
-		const p = await getNote(id, user).catch((e) => {
-			if (e.id === "9725d0ce-ba28-4dde-95a7-2cbb2c15de24") return null;
-			throw e;
-		});
-
-		if (p == null) return;
-
-		if (i > ps.offset!) {
-			conversation.push(p);
-		}
-
-		if (conversation.length === ps.limit) {
-			return;
-		}
-
-		if (p.replyId) {
-			await get(p.replyId);
-		}
-	}
-
-	if (note.replyId) {
-		await get(note.replyId);
-	}
-
-	return await Notes.packMany(conversation, user);
-});
diff --git a/packages/backend/src/server/api/endpoints/notes/create.ts b/packages/backend/src/server/api/endpoints/notes/create.ts
deleted file mode 100644
index 41b8ab9796..0000000000
--- a/packages/backend/src/server/api/endpoints/notes/create.ts
+++ /dev/null
@@ -1,308 +0,0 @@
-import { In } from "typeorm";
-import create from "@/services/note/create.js";
-import type { User } from "@/models/entities/user.js";
-import {
-	Users,
-	DriveFiles,
-	Notes,
-	Channels,
-	Blockings,
-} from "@/models/index.js";
-import type { DriveFile } from "@/models/entities/drive-file.js";
-import type { Note } from "@/models/entities/note.js";
-import type { Channel } from "@/models/entities/channel.js";
-import { MAX_NOTE_TEXT_LENGTH } from "@/const.js";
-import { noteVisibilities } from "../../../../types.js";
-import { ApiError } from "../../error.js";
-import define from "../../define.js";
-import { HOUR } from "@/const.js";
-import { getNote } from "../../common/getters.js";
-
-export const meta = {
-	tags: ["notes"],
-
-	requireCredential: true,
-
-	limit: {
-		duration: HOUR,
-		max: 300,
-	},
-
-	kind: "write:notes",
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		properties: {
-			createdNote: {
-				type: "object",
-				optional: false,
-				nullable: false,
-				ref: "Note",
-			},
-		},
-	},
-
-	errors: {
-		noSuchRenoteTarget: {
-			message: "No such renote target.",
-			code: "NO_SUCH_RENOTE_TARGET",
-			id: "b5c90186-4ab0-49c8-9bba-a1f76c282ba4",
-		},
-
-		cannotReRenote: {
-			message: "You can not Renote a pure Renote.",
-			code: "CANNOT_RENOTE_TO_A_PURE_RENOTE",
-			id: "fd4cc33e-2a37-48dd-99cc-9b806eb2031a",
-		},
-
-		noSuchReplyTarget: {
-			message: "No such reply target.",
-			code: "NO_SUCH_REPLY_TARGET",
-			id: "749ee0f6-d3da-459a-bf02-282e2da4292c",
-		},
-
-		cannotReplyToPureRenote: {
-			message: "You can not reply to a pure Renote.",
-			code: "CANNOT_REPLY_TO_A_PURE_RENOTE",
-			id: "3ac74a84-8fd5-4bb0-870f-01804f82ce15",
-		},
-
-		cannotCreateAlreadyExpiredPoll: {
-			message: "Poll is already expired.",
-			code: "CANNOT_CREATE_ALREADY_EXPIRED_POLL",
-			id: "04da457d-b083-4055-9082-955525eda5a5",
-		},
-
-		noSuchChannel: {
-			message: "No such channel.",
-			code: "NO_SUCH_CHANNEL",
-			id: "b1653923-5453-4edc-b786-7c4f39bb0bbb",
-		},
-
-		youHaveBeenBlocked: {
-			message: "You have been blocked by this user.",
-			code: "YOU_HAVE_BEEN_BLOCKED",
-			id: "b390d7e1-8a5e-46ed-b625-06271cafd3d3",
-		},
-
-		accountLocked: {
-			message: "You migrated. Your account is now locked.",
-			code: "ACCOUNT_LOCKED",
-			id: "d390d7e1-8a5e-46ed-b625-06271cafd3d3",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		visibility: { type: "string", enum: noteVisibilities, default: "public" },
-		visibleUserIds: {
-			type: "array",
-			uniqueItems: true,
-			items: {
-				type: "string",
-				format: "misskey:id",
-			},
-		},
-		text: { type: "string", maxLength: MAX_NOTE_TEXT_LENGTH, nullable: true },
-		cw: { type: "string", nullable: true, maxLength: 100 },
-		localOnly: { type: "boolean", default: false },
-		noExtractMentions: { type: "boolean", default: false },
-		noExtractHashtags: { type: "boolean", default: false },
-		noExtractEmojis: { type: "boolean", default: false },
-		fileIds: {
-			type: "array",
-			uniqueItems: true,
-			minItems: 1,
-			maxItems: 16,
-			items: { type: "string", format: "misskey:id" },
-		},
-		mediaIds: {
-			deprecated: true,
-			description:
-				"Use `fileIds` instead. If both are specified, this property is discarded.",
-			type: "array",
-			uniqueItems: true,
-			minItems: 1,
-			maxItems: 16,
-			items: { type: "string", format: "misskey:id" },
-		},
-		replyId: { type: "string", format: "misskey:id", nullable: true },
-		renoteId: { type: "string", format: "misskey:id", nullable: true },
-		channelId: { type: "string", format: "misskey:id", nullable: true },
-		poll: {
-			type: "object",
-			nullable: true,
-			properties: {
-				choices: {
-					type: "array",
-					uniqueItems: true,
-					minItems: 2,
-					maxItems: 10,
-					items: { type: "string", minLength: 1, maxLength: 50 },
-				},
-				multiple: { type: "boolean", default: false },
-				expiresAt: { type: "integer", nullable: true },
-				expiredAfter: { type: "integer", nullable: true, minimum: 1 },
-			},
-			required: ["choices"],
-		},
-	},
-	anyOf: [
-		{
-			// (re)note with text, files and poll are optional
-			properties: {
-				text: {
-					type: "string",
-					minLength: 1,
-					maxLength: MAX_NOTE_TEXT_LENGTH,
-					nullable: false,
-				},
-			},
-			required: ["text"],
-		},
-		{
-			// (re)note with files, text and poll are optional
-			required: ["fileIds"],
-		},
-		{
-			// (re)note with files, text and poll are optional
-			required: ["mediaIds"],
-		},
-		{
-			// (re)note with poll, text and files are optional
-			properties: {
-				poll: { type: "object", nullable: false },
-			},
-			required: ["poll"],
-		},
-		{
-			// pure renote
-			required: ["renoteId"],
-		},
-	],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	if (user.movedToUri != null) throw new ApiError(meta.errors.accountLocked);
-	let visibleUsers: User[] = [];
-	if (ps.visibleUserIds) {
-		visibleUsers = await Users.findBy({
-			id: In(ps.visibleUserIds),
-		});
-	}
-
-	let files: DriveFile[] = [];
-	const fileIds =
-		ps.fileIds != null ? ps.fileIds : ps.mediaIds != null ? ps.mediaIds : null;
-	if (fileIds != null) {
-		files = await DriveFiles.createQueryBuilder("file")
-			.where("file.userId = :userId AND file.id IN (:...fileIds)", {
-				userId: user.id,
-				fileIds,
-			})
-			.orderBy('array_position(ARRAY[:...fileIds], "id"::text)')
-			.setParameters({ fileIds })
-			.getMany();
-	}
-
-	let renote: Note | null = null;
-	if (ps.renoteId != null) {
-		// Fetch renote to note
-		renote = await getNote(ps.renoteId, user).catch((e) => {
-			if (e.id === "9725d0ce-ba28-4dde-95a7-2cbb2c15de24")
-				throw new ApiError(meta.errors.noSuchRenoteTarget);
-			throw e;
-		});
-
-		if (renote.renoteId && !renote.text && !renote.fileIds && !renote.hasPoll) {
-			throw new ApiError(meta.errors.cannotReRenote);
-		}
-
-		// Check blocking
-		if (renote.userId !== user.id) {
-			const block = await Blockings.findOneBy({
-				blockerId: renote.userId,
-				blockeeId: user.id,
-			});
-			if (block) {
-				throw new ApiError(meta.errors.youHaveBeenBlocked);
-			}
-		}
-	}
-
-	let reply: Note | null = null;
-	if (ps.replyId != null) {
-		// Fetch reply
-		reply = await getNote(ps.replyId, user).catch((e) => {
-			if (e.id === "9725d0ce-ba28-4dde-95a7-2cbb2c15de24")
-				throw new ApiError(meta.errors.noSuchReplyTarget);
-			throw e;
-		});
-
-		if (reply.renoteId && !reply.text && !reply.fileIds && !reply.hasPoll) {
-			throw new ApiError(meta.errors.cannotReplyToPureRenote);
-		}
-
-		// Check blocking
-		if (reply.userId !== user.id) {
-			const block = await Blockings.findOneBy({
-				blockerId: reply.userId,
-				blockeeId: user.id,
-			});
-			if (block) {
-				throw new ApiError(meta.errors.youHaveBeenBlocked);
-			}
-		}
-	}
-
-	if (ps.poll) {
-		if (typeof ps.poll.expiresAt === "number") {
-			if (ps.poll.expiresAt < Date.now()) {
-				throw new ApiError(meta.errors.cannotCreateAlreadyExpiredPoll);
-			}
-		} else if (typeof ps.poll.expiredAfter === "number") {
-			ps.poll.expiresAt = Date.now() + ps.poll.expiredAfter;
-		}
-	}
-
-	let channel: Channel | null = null;
-	if (ps.channelId != null) {
-		channel = await Channels.findOneBy({ id: ps.channelId });
-
-		if (channel == null) {
-			throw new ApiError(meta.errors.noSuchChannel);
-		}
-	}
-
-	// Create a post
-	const note = await create(user, {
-		createdAt: new Date(),
-		files: files,
-		poll: ps.poll
-			? {
-					choices: ps.poll.choices,
-					multiple: ps.poll.multiple,
-					expiresAt: ps.poll.expiresAt ? new Date(ps.poll.expiresAt) : null,
-			  }
-			: undefined,
-		text: ps.text || undefined,
-		reply,
-		renote,
-		cw: ps.cw,
-		localOnly: ps.localOnly,
-		visibility: ps.visibility,
-		visibleUsers,
-		channel,
-		apMentions: ps.noExtractMentions ? [] : undefined,
-		apHashtags: ps.noExtractHashtags ? [] : undefined,
-		apEmojis: ps.noExtractEmojis ? [] : undefined,
-	});
-
-	return {
-		createdNote: await Notes.pack(note, user),
-	};
-});
diff --git a/packages/backend/src/server/api/endpoints/notes/delete.ts b/packages/backend/src/server/api/endpoints/notes/delete.ts
deleted file mode 100644
index 5fc79db7d1..0000000000
--- a/packages/backend/src/server/api/endpoints/notes/delete.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-import deleteNote from "@/services/note/delete.js";
-import { Users } from "@/models/index.js";
-import define from "../../define.js";
-import { getNote } from "../../common/getters.js";
-import { ApiError } from "../../error.js";
-import { SECOND, HOUR } from "@/const.js";
-
-export const meta = {
-	tags: ["notes"],
-
-	requireCredential: true,
-
-	kind: "write:notes",
-
-	limit: {
-		duration: HOUR,
-		max: 300,
-		minInterval: SECOND,
-	},
-
-	errors: {
-		noSuchNote: {
-			message: "No such note.",
-			code: "NO_SUCH_NOTE",
-			id: "490be23f-8c1f-4796-819f-94cb4f9d1630",
-		},
-
-		accessDenied: {
-			message: "Access denied.",
-			code: "ACCESS_DENIED",
-			id: "fe8d7103-0ea8-4ec3-814d-f8b401dc69e9",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		noteId: { type: "string", format: "misskey:id" },
-	},
-	required: ["noteId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const note = await getNote(ps.noteId, user).catch((err) => {
-		if (err.id === "9725d0ce-ba28-4dde-95a7-2cbb2c15de24")
-			throw new ApiError(meta.errors.noSuchNote);
-		throw err;
-	});
-
-	if (!(user.isAdmin || user.isModerator) && note.userId !== user.id) {
-		throw new ApiError(meta.errors.accessDenied);
-	}
-
-	// この操作を行うのが投稿者とは限らない(例えばモデレーター)ため
-	await deleteNote(await Users.findOneByOrFail({ id: note.userId }), note);
-});
diff --git a/packages/backend/src/server/api/endpoints/notes/favorites/create.ts b/packages/backend/src/server/api/endpoints/notes/favorites/create.ts
deleted file mode 100644
index 835594f03a..0000000000
--- a/packages/backend/src/server/api/endpoints/notes/favorites/create.ts
+++ /dev/null
@@ -1,62 +0,0 @@
-import { NoteFavorites } from "@/models/index.js";
-import { genId } from "@/misc/gen-id.js";
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-import { getNote } from "../../../common/getters.js";
-
-export const meta = {
-	tags: ["notes", "favorites"],
-
-	requireCredential: true,
-
-	kind: "write:favorites",
-
-	errors: {
-		noSuchNote: {
-			message: "No such note.",
-			code: "NO_SUCH_NOTE",
-			id: "6dd26674-e060-4816-909a-45ba3f4da458",
-		},
-
-		alreadyFavorited: {
-			message: "The note has already been marked as a favorite.",
-			code: "ALREADY_FAVORITED",
-			id: "a402c12b-34dd-41d2-97d8-4d2ffd96a1a6",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		noteId: { type: "string", format: "misskey:id" },
-	},
-	required: ["noteId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	// Get favoritee
-	const note = await getNote(ps.noteId, user).catch((err) => {
-		if (err.id === "9725d0ce-ba28-4dde-95a7-2cbb2c15de24")
-			throw new ApiError(meta.errors.noSuchNote);
-		throw err;
-	});
-
-	// if already favorited
-	const exist = await NoteFavorites.findOneBy({
-		noteId: note.id,
-		userId: user.id,
-	});
-
-	if (exist != null) {
-		throw new ApiError(meta.errors.alreadyFavorited);
-	}
-
-	// Create favorite
-	await NoteFavorites.insert({
-		id: genId(),
-		createdAt: new Date(),
-		noteId: note.id,
-		userId: user.id,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/notes/favorites/delete.ts b/packages/backend/src/server/api/endpoints/notes/favorites/delete.ts
deleted file mode 100644
index 9a09767482..0000000000
--- a/packages/backend/src/server/api/endpoints/notes/favorites/delete.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-import { NoteFavorites } from "@/models/index.js";
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-import { getNote } from "../../../common/getters.js";
-
-export const meta = {
-	tags: ["notes", "favorites"],
-
-	requireCredential: true,
-
-	kind: "write:favorites",
-
-	errors: {
-		noSuchNote: {
-			message: "No such note.",
-			code: "NO_SUCH_NOTE",
-			id: "80848a2c-398f-4343-baa9-df1d57696c56",
-		},
-
-		notFavorited: {
-			message: "You have not marked that note a favorite.",
-			code: "NOT_FAVORITED",
-			id: "b625fc69-635e-45e9-86f4-dbefbef35af5",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		noteId: { type: "string", format: "misskey:id" },
-	},
-	required: ["noteId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	// Get favoritee
-	const note = await getNote(ps.noteId, user).catch((err) => {
-		if (err.id === "9725d0ce-ba28-4dde-95a7-2cbb2c15de24")
-			throw new ApiError(meta.errors.noSuchNote);
-		throw err;
-	});
-
-	// if already favorited
-	const exist = await NoteFavorites.findOneBy({
-		noteId: note.id,
-		userId: user.id,
-	});
-
-	if (exist == null) {
-		throw new ApiError(meta.errors.notFavorited);
-	}
-
-	// Delete favorite
-	await NoteFavorites.delete(exist.id);
-});
diff --git a/packages/backend/src/server/api/endpoints/notes/featured.ts b/packages/backend/src/server/api/endpoints/notes/featured.ts
deleted file mode 100644
index 47c1e13812..0000000000
--- a/packages/backend/src/server/api/endpoints/notes/featured.ts
+++ /dev/null
@@ -1,82 +0,0 @@
-import { Notes } from "@/models/index.js";
-import define from "../../define.js";
-import { generateMutedUserQuery } from "../../common/generate-muted-user-query.js";
-import { generateBlockedUserQuery } from "../../common/generate-block-query.js";
-
-export const meta = {
-	tags: ["notes"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Note",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		offset: { type: "integer", default: 0 },
-		origin: {
-			type: "string",
-			enum: ["combined", "local", "remote"],
-			default: "local",
-		},
-		days: { type: "integer", minimum: 1, maximum: 365, default: 3 },
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const max = 30;
-	const day = 1000 * 60 * 60 * 24 * ps.days;
-
-	const query = Notes.createQueryBuilder("note")
-		.addSelect("note.score")
-		.andWhere("note.score > 0")
-		.andWhere("note.createdAt > :date", { date: new Date(Date.now() - day) })
-		.andWhere("note.visibility = 'public'")
-		.innerJoinAndSelect("note.user", "user")
-		.leftJoinAndSelect("user.avatar", "avatar")
-		.leftJoinAndSelect("user.banner", "banner")
-		.leftJoinAndSelect("note.reply", "reply")
-		.leftJoinAndSelect("note.renote", "renote")
-		.leftJoinAndSelect("reply.user", "replyUser")
-		.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
-		.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
-		.leftJoinAndSelect("renote.user", "renoteUser")
-		.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
-		.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner");
-
-	switch (ps.origin) {
-		case "local":
-			query.andWhere("note.userHost IS NULL");
-			break;
-		case "remote":
-			query.andWhere("note.userHost IS NOT NULL");
-			break;
-	}
-
-	if (user) generateMutedUserQuery(query, user);
-	if (user) generateBlockedUserQuery(query, user);
-
-	let notes = await query.orderBy("note.score", "DESC").take(max).getMany();
-
-	notes.sort(
-		(a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime(),
-	);
-
-	notes = notes.slice(ps.offset, ps.offset + ps.limit);
-
-	return await Notes.packMany(notes, user);
-});
diff --git a/packages/backend/src/server/api/endpoints/notes/global-timeline.ts b/packages/backend/src/server/api/endpoints/notes/global-timeline.ts
deleted file mode 100644
index 077a1ad5e1..0000000000
--- a/packages/backend/src/server/api/endpoints/notes/global-timeline.ts
+++ /dev/null
@@ -1,121 +0,0 @@
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { Notes } from "@/models/index.js";
-import { activeUsersChart } from "@/services/chart/index.js";
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-import { generateMutedUserQuery } from "../../common/generate-muted-user-query.js";
-import { generateRepliesQuery } from "../../common/generate-replies-query.js";
-import { generateMutedNoteQuery } from "../../common/generate-muted-note-query.js";
-import { generateBlockedUserQuery } from "../../common/generate-block-query.js";
-import { generateMutedUserRenotesQueryForNotes } from "../../common/generated-muted-renote-query.js";
-
-export const meta = {
-	tags: ["notes"],
-
-	requireCredentialPrivateMode: true,
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Note",
-		},
-	},
-
-	errors: {
-		gtlDisabled: {
-			message: "Global timeline has been disabled.",
-			code: "GTL_DISABLED",
-			id: "0332fc13-6ab2-4427-ae80-a9fadffd1a6b",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		withFiles: {
-			type: "boolean",
-			default: false,
-			description: "Only show notes that have attached files.",
-		},
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-		sinceDate: { type: "integer" },
-		untilDate: { type: "integer" },
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const m = await fetchMeta();
-	if (m.disableGlobalTimeline) {
-		if (user == null || !(user.isAdmin || user.isModerator)) {
-			throw new ApiError(meta.errors.gtlDisabled);
-		}
-	}
-
-	//#region Construct query
-	const query = makePaginationQuery(
-		Notes.createQueryBuilder("note"),
-		ps.sinceId,
-		ps.untilId,
-		ps.sinceDate,
-		ps.untilDate,
-	)
-		.andWhere("note.visibility = 'public'")
-		.andWhere("note.channelId IS NULL")
-		.innerJoinAndSelect("note.user", "user")
-		.leftJoinAndSelect("user.avatar", "avatar")
-		.leftJoinAndSelect("user.banner", "banner")
-		.leftJoinAndSelect("note.reply", "reply")
-		.leftJoinAndSelect("note.renote", "renote")
-		.leftJoinAndSelect("reply.user", "replyUser")
-		.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
-		.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
-		.leftJoinAndSelect("renote.user", "renoteUser")
-		.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
-		.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner");
-
-	generateRepliesQuery(query, user);
-	if (user) {
-		generateMutedUserQuery(query, user);
-		generateMutedNoteQuery(query, user);
-		generateBlockedUserQuery(query, user);
-		generateMutedUserRenotesQueryForNotes(query, user);
-	}
-
-	if (ps.withFiles) {
-		query.andWhere("note.fileIds != '{}'");
-	}
-	//#endregion
-
-	process.nextTick(() => {
-		if (user) {
-			activeUsersChart.read(user);
-		}
-	});
-
-	// We fetch more than requested because some may be filtered out, and if there's less than
-	// requested, the pagination stops.
-	const found = [];
-	const take = Math.floor(ps.limit * 1.5);
-	let skip = 0;
-	while (found.length < ps.limit) {
-		const notes = await query.take(take).skip(skip).getMany();
-		found.push(...(await Notes.packMany(notes, user)));
-		skip += take;
-		if (notes.length < take) break;
-	}
-
-	if (found.length > ps.limit) {
-		found.length = ps.limit;
-	}
-
-	return found;
-});
diff --git a/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts b/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts
deleted file mode 100644
index 3c171278b4..0000000000
--- a/packages/backend/src/server/api/endpoints/notes/hybrid-timeline.ts
+++ /dev/null
@@ -1,177 +0,0 @@
-import { Brackets } from "typeorm";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { Followings, Notes } from "@/models/index.js";
-import { activeUsersChart } from "@/services/chart/index.js";
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-import { generateVisibilityQuery } from "../../common/generate-visibility-query.js";
-import { generateMutedUserQuery } from "../../common/generate-muted-user-query.js";
-import { generateRepliesQuery } from "../../common/generate-replies-query.js";
-import { generateMutedNoteQuery } from "../../common/generate-muted-note-query.js";
-import { generateChannelQuery } from "../../common/generate-channel-query.js";
-import { generateBlockedUserQuery } from "../../common/generate-block-query.js";
-import { generateMutedUserRenotesQueryForNotes } from "../../common/generated-muted-renote-query.js";
-
-export const meta = {
-	tags: ["notes"],
-
-	requireCredential: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Note",
-		},
-	},
-
-	errors: {
-		stlDisabled: {
-			message: "Hybrid timeline has been disabled.",
-			code: "STL_DISABLED",
-			id: "620763f4-f621-4533-ab33-0577a1a3c342",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-		sinceDate: { type: "integer" },
-		untilDate: { type: "integer" },
-		includeMyRenotes: { type: "boolean", default: true },
-		includeRenotedMyNotes: { type: "boolean", default: true },
-		includeLocalRenotes: { type: "boolean", default: true },
-		withFiles: {
-			type: "boolean",
-			default: false,
-			description: "Only show notes that have attached files.",
-		},
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const m = await fetchMeta();
-	if (m.disableLocalTimeline && !user.isAdmin && !user.isModerator) {
-		throw new ApiError(meta.errors.stlDisabled);
-	}
-
-	//#region Construct query
-	const followingQuery = Followings.createQueryBuilder("following")
-		.select("following.followeeId")
-		.where("following.followerId = :followerId", { followerId: user.id });
-
-	const query = makePaginationQuery(
-		Notes.createQueryBuilder("note"),
-		ps.sinceId,
-		ps.untilId,
-		ps.sinceDate,
-		ps.untilDate,
-	)
-		.andWhere(
-			new Brackets((qb) => {
-				qb.where(
-					`((note.userId IN (${followingQuery.getQuery()})) OR (note.userId = :meId))`,
-					{ meId: user.id },
-				).orWhere("(note.visibility = 'public') AND (note.userHost IS NULL)");
-			}),
-		)
-		.innerJoinAndSelect("note.user", "user")
-		.leftJoinAndSelect("user.avatar", "avatar")
-		.leftJoinAndSelect("user.banner", "banner")
-		.leftJoinAndSelect("note.reply", "reply")
-		.leftJoinAndSelect("note.renote", "renote")
-		.leftJoinAndSelect("reply.user", "replyUser")
-		.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
-		.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
-		.leftJoinAndSelect("renote.user", "renoteUser")
-		.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
-		.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner")
-		.setParameters(followingQuery.getParameters());
-
-	generateChannelQuery(query, user);
-	generateRepliesQuery(query, user);
-	generateVisibilityQuery(query, user);
-	generateMutedUserQuery(query, user);
-	generateMutedNoteQuery(query, user);
-	generateBlockedUserQuery(query, user);
-	generateMutedUserRenotesQueryForNotes(query, user);
-
-	if (ps.includeMyRenotes === false) {
-		query.andWhere(
-			new Brackets((qb) => {
-				qb.orWhere("note.userId != :meId", { meId: user.id });
-				qb.orWhere("note.renoteId IS NULL");
-				qb.orWhere("note.text IS NOT NULL");
-				qb.orWhere("note.fileIds != '{}'");
-				qb.orWhere(
-					'0 < (SELECT COUNT(*) FROM poll WHERE poll."noteId" = note.id)',
-				);
-			}),
-		);
-	}
-
-	if (ps.includeRenotedMyNotes === false) {
-		query.andWhere(
-			new Brackets((qb) => {
-				qb.orWhere("note.renoteUserId != :meId", { meId: user.id });
-				qb.orWhere("note.renoteId IS NULL");
-				qb.orWhere("note.text IS NOT NULL");
-				qb.orWhere("note.fileIds != '{}'");
-				qb.orWhere(
-					'0 < (SELECT COUNT(*) FROM poll WHERE poll."noteId" = note.id)',
-				);
-			}),
-		);
-	}
-
-	if (ps.includeLocalRenotes === false) {
-		query.andWhere(
-			new Brackets((qb) => {
-				qb.orWhere("note.renoteUserHost IS NOT NULL");
-				qb.orWhere("note.renoteId IS NULL");
-				qb.orWhere("note.text IS NOT NULL");
-				qb.orWhere("note.fileIds != '{}'");
-				qb.orWhere(
-					'0 < (SELECT COUNT(*) FROM poll WHERE poll."noteId" = note.id)',
-				);
-			}),
-		);
-	}
-
-	if (ps.withFiles) {
-		query.andWhere("note.fileIds != '{}'");
-	}
-	//#endregion
-
-	process.nextTick(() => {
-		activeUsersChart.read(user);
-	});
-
-	// We fetch more than requested because some may be filtered out, and if there's less than
-	// requested, the pagination stops.
-	const found = [];
-	const take = Math.floor(ps.limit * 1.5);
-	let skip = 0;
-	while (found.length < ps.limit) {
-		const notes = await query.take(take).skip(skip).getMany();
-		found.push(...(await Notes.packMany(notes, user)));
-		skip += take;
-		if (notes.length < take) break;
-	}
-
-	if (found.length > ps.limit) {
-		found.length = ps.limit;
-	}
-
-	return found;
-});
diff --git a/packages/backend/src/server/api/endpoints/notes/local-timeline.ts b/packages/backend/src/server/api/endpoints/notes/local-timeline.ts
deleted file mode 100644
index cec371c8dc..0000000000
--- a/packages/backend/src/server/api/endpoints/notes/local-timeline.ts
+++ /dev/null
@@ -1,151 +0,0 @@
-import { Brackets } from "typeorm";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { Notes, Users } from "@/models/index.js";
-import { activeUsersChart } from "@/services/chart/index.js";
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { generateMutedUserQuery } from "../../common/generate-muted-user-query.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-import { generateVisibilityQuery } from "../../common/generate-visibility-query.js";
-import { generateRepliesQuery } from "../../common/generate-replies-query.js";
-import { generateMutedNoteQuery } from "../../common/generate-muted-note-query.js";
-import { generateChannelQuery } from "../../common/generate-channel-query.js";
-import { generateBlockedUserQuery } from "../../common/generate-block-query.js";
-import { generateMutedUserRenotesQueryForNotes } from "../../common/generated-muted-renote-query.js";
-
-export const meta = {
-	tags: ["notes"],
-	requireCredentialPrivateMode: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Note",
-		},
-	},
-
-	errors: {
-		ltlDisabled: {
-			message: "Local timeline has been disabled.",
-			code: "LTL_DISABLED",
-			id: "45a6eb02-7695-4393-b023-dd3be9aaaefd",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		withFiles: {
-			type: "boolean",
-			default: false,
-			description: "Only show notes that have attached files.",
-		},
-		fileType: {
-			type: "array",
-			items: {
-				type: "string",
-			},
-		},
-		excludeNsfw: { type: "boolean", default: false },
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-		sinceDate: { type: "integer" },
-		untilDate: { type: "integer" },
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const m = await fetchMeta();
-	if (m.disableLocalTimeline) {
-		if (user == null || !(user.isAdmin || user.isModerator)) {
-			throw new ApiError(meta.errors.ltlDisabled);
-		}
-	}
-
-	//#region Construct query
-	const query = makePaginationQuery(
-		Notes.createQueryBuilder("note"),
-		ps.sinceId,
-		ps.untilId,
-		ps.sinceDate,
-		ps.untilDate,
-	)
-		.andWhere("(note.visibility = 'public') AND (note.userHost IS NULL)")
-		.innerJoinAndSelect("note.user", "user")
-		.leftJoinAndSelect("user.avatar", "avatar")
-		.leftJoinAndSelect("user.banner", "banner")
-		.leftJoinAndSelect("note.reply", "reply")
-		.leftJoinAndSelect("note.renote", "renote")
-		.leftJoinAndSelect("reply.user", "replyUser")
-		.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
-		.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
-		.leftJoinAndSelect("renote.user", "renoteUser")
-		.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
-		.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner");
-
-	generateChannelQuery(query, user);
-	generateRepliesQuery(query, user);
-	generateVisibilityQuery(query, user);
-	if (user) generateMutedUserQuery(query, user);
-	if (user) generateMutedNoteQuery(query, user);
-	if (user) generateBlockedUserQuery(query, user);
-	if (user) generateMutedUserRenotesQueryForNotes(query, user);
-
-	if (ps.withFiles) {
-		query.andWhere("note.fileIds != '{}'");
-	}
-
-	if (ps.fileType != null) {
-		query.andWhere("note.fileIds != '{}'");
-		query.andWhere(
-			new Brackets((qb) => {
-				for (const type of ps.fileType!) {
-					const i = ps.fileType!.indexOf(type);
-					qb.orWhere(`:type${i} = ANY(note.attachedFileTypes)`, {
-						[`type${i}`]: type,
-					});
-				}
-			}),
-		);
-
-		if (ps.excludeNsfw) {
-			query.andWhere("note.cw IS NULL");
-			query.andWhere(
-				'0 = (SELECT COUNT(*) FROM drive_file df WHERE df.id = ANY(note."fileIds") AND df."isSensitive" = TRUE)',
-			);
-		}
-	}
-	//#endregion
-
-	process.nextTick(() => {
-		if (user) {
-			activeUsersChart.read(user);
-		}
-	});
-
-	// We fetch more than requested because some may be filtered out, and if there's less than
-	// requested, the pagination stops.
-	const found = [];
-	const take = Math.floor(ps.limit * 1.5);
-	let skip = 0;
-	while (found.length < ps.limit) {
-		const notes = await query.take(take).skip(skip).getMany();
-		found.push(...(await Notes.packMany(notes, user)));
-		skip += take;
-		if (notes.length < take) break;
-	}
-
-	if (found.length > ps.limit) {
-		found.length = ps.limit;
-	}
-
-	return found;
-});
diff --git a/packages/backend/src/server/api/endpoints/notes/mentions.ts b/packages/backend/src/server/api/endpoints/notes/mentions.ts
deleted file mode 100644
index 68688b504c..0000000000
--- a/packages/backend/src/server/api/endpoints/notes/mentions.ts
+++ /dev/null
@@ -1,108 +0,0 @@
-import { Brackets } from "typeorm";
-import read from "@/services/note/read.js";
-import { Notes, Followings } from "@/models/index.js";
-import define from "../../define.js";
-import { generateVisibilityQuery } from "../../common/generate-visibility-query.js";
-import { generateMutedUserQuery } from "../../common/generate-muted-user-query.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-import { generateBlockedUserQuery } from "../../common/generate-block-query.js";
-import { generateMutedNoteThreadQuery } from "../../common/generate-muted-note-thread-query.js";
-
-export const meta = {
-	tags: ["notes"],
-
-	requireCredential: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Note",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		following: { type: "boolean", default: false },
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-		visibility: { type: "string" },
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const followingQuery = Followings.createQueryBuilder("following")
-		.select("following.followeeId")
-		.where("following.followerId = :followerId", { followerId: user.id });
-
-	const query = makePaginationQuery(
-		Notes.createQueryBuilder("note"),
-		ps.sinceId,
-		ps.untilId,
-	)
-		.andWhere(
-			new Brackets((qb) => {
-				qb.where(`'{"${user.id}"}' <@ note.mentions`).orWhere(
-					`'{"${user.id}"}' <@ note.visibleUserIds`,
-				);
-			}),
-		)
-		.innerJoinAndSelect("note.user", "user")
-		.leftJoinAndSelect("user.avatar", "avatar")
-		.leftJoinAndSelect("user.banner", "banner")
-		.leftJoinAndSelect("note.reply", "reply")
-		.leftJoinAndSelect("note.renote", "renote")
-		.leftJoinAndSelect("reply.user", "replyUser")
-		.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
-		.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
-		.leftJoinAndSelect("renote.user", "renoteUser")
-		.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
-		.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner");
-
-	generateVisibilityQuery(query, user);
-	generateMutedUserQuery(query, user);
-	generateMutedNoteThreadQuery(query, user);
-	generateBlockedUserQuery(query, user);
-
-	if (ps.visibility) {
-		query.andWhere("note.visibility = :visibility", {
-			visibility: ps.visibility,
-		});
-	}
-
-	if (ps.following) {
-		query.andWhere(
-			`((note.userId IN (${followingQuery.getQuery()})) OR (note.userId = :meId))`,
-			{ meId: user.id },
-		);
-		query.setParameters(followingQuery.getParameters());
-	}
-
-	// We fetch more than requested because some may be filtered out, and if there's less than
-	// requested, the pagination stops.
-	const found = [];
-	const take = Math.floor(ps.limit * 1.5);
-	let skip = 0;
-	while (found.length < ps.limit) {
-		const notes = await query.take(take).skip(skip).getMany();
-		found.push(...(await Notes.packMany(notes, user)));
-		skip += take;
-		if (notes.length < take) break;
-	}
-
-	if (found.length > ps.limit) {
-		found.length = ps.limit;
-	}
-
-	read(user.id, found);
-
-	return found;
-});
diff --git a/packages/backend/src/server/api/endpoints/notes/polls/recommendation.ts b/packages/backend/src/server/api/endpoints/notes/polls/recommendation.ts
deleted file mode 100644
index fcd24db992..0000000000
--- a/packages/backend/src/server/api/endpoints/notes/polls/recommendation.ts
+++ /dev/null
@@ -1,85 +0,0 @@
-import { Brackets, In } from "typeorm";
-import { Polls, Mutings, Notes, PollVotes } from "@/models/index.js";
-import define from "../../../define.js";
-
-export const meta = {
-	tags: ["notes"],
-
-	requireCredential: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Note",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		offset: { type: "integer", default: 0 },
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const query = Polls.createQueryBuilder("poll")
-		.where("poll.userHost IS NULL")
-		.andWhere("poll.userId != :meId", { meId: user.id })
-		.andWhere("poll.noteVisibility = 'public'")
-		.andWhere(
-			new Brackets((qb) => {
-				qb.where("poll.expiresAt IS NULL").orWhere("poll.expiresAt > :now", {
-					now: new Date(),
-				});
-			}),
-		);
-
-	//#region exclude arleady voted polls
-	const votedQuery = PollVotes.createQueryBuilder("vote")
-		.select("vote.noteId")
-		.where("vote.userId = :meId", { meId: user.id });
-
-	query.andWhere(`poll.noteId NOT IN (${votedQuery.getQuery()})`);
-
-	query.setParameters(votedQuery.getParameters());
-	//#endregion
-
-	//#region mute
-	const mutingQuery = Mutings.createQueryBuilder("muting")
-		.select("muting.muteeId")
-		.where("muting.muterId = :muterId", { muterId: user.id });
-
-	query.andWhere(`poll.userId NOT IN (${mutingQuery.getQuery()})`);
-
-	query.setParameters(mutingQuery.getParameters());
-	//#endregion
-
-	const polls = await query
-		.orderBy("poll.noteId", "DESC")
-		.take(ps.limit)
-		.skip(ps.offset)
-		.getMany();
-
-	if (polls.length === 0) return [];
-
-	const notes = await Notes.find({
-		where: {
-			id: In(polls.map((poll) => poll.noteId)),
-		},
-		order: {
-			createdAt: "DESC",
-		},
-	});
-
-	return await Notes.packMany(notes, user, {
-		detail: true,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/notes/polls/vote.ts b/packages/backend/src/server/api/endpoints/notes/polls/vote.ts
deleted file mode 100644
index 0558aa1b8f..0000000000
--- a/packages/backend/src/server/api/endpoints/notes/polls/vote.ts
+++ /dev/null
@@ -1,184 +0,0 @@
-import { Not } from "typeorm";
-import { publishNoteStream } from "@/services/stream.js";
-import { createNotification } from "@/services/create-notification.js";
-import { deliver } from "@/queue/index.js";
-import { renderActivity } from "@/remote/activitypub/renderer/index.js";
-import renderVote from "@/remote/activitypub/renderer/vote.js";
-import { deliverQuestionUpdate } from "@/services/note/polls/update.js";
-import {
-	PollVotes,
-	NoteWatchings,
-	Users,
-	Polls,
-	Blockings,
-} from "@/models/index.js";
-import type { IRemoteUser } from "@/models/entities/user.js";
-import { genId } from "@/misc/gen-id.js";
-import { getNote } from "../../../common/getters.js";
-import { ApiError } from "../../../error.js";
-import define from "../../../define.js";
-
-export const meta = {
-	tags: ["notes"],
-
-	requireCredential: true,
-
-	kind: "write:votes",
-
-	errors: {
-		noSuchNote: {
-			message: "No such note.",
-			code: "NO_SUCH_NOTE",
-			id: "ecafbd2e-c283-4d6d-aecb-1a0a33b75396",
-		},
-
-		noPoll: {
-			message: "The note does not attach a poll.",
-			code: "NO_POLL",
-			id: "5f979967-52d9-4314-a911-1c673727f92f",
-		},
-
-		invalidChoice: {
-			message: "Choice ID is invalid.",
-			code: "INVALID_CHOICE",
-			id: "e0cc9a04-f2e8-41e4-a5f1-4127293260cc",
-		},
-
-		alreadyVoted: {
-			message: "You have already voted.",
-			code: "ALREADY_VOTED",
-			id: "0963fc77-efac-419b-9424-b391608dc6d8",
-		},
-
-		alreadyExpired: {
-			message: "The poll is already expired.",
-			code: "ALREADY_EXPIRED",
-			id: "1022a357-b085-4054-9083-8f8de358337e",
-		},
-
-		youHaveBeenBlocked: {
-			message:
-				"You cannot vote this poll because you have been blocked by this user.",
-			code: "YOU_HAVE_BEEN_BLOCKED",
-			id: "85a5377e-b1e9-4617-b0b9-5bea73331e49",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		noteId: { type: "string", format: "misskey:id" },
-		choice: { type: "integer" },
-	},
-	required: ["noteId", "choice"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const createdAt = new Date();
-
-	// Get votee
-	const note = await getNote(ps.noteId, user).catch((err) => {
-		if (err.id === "9725d0ce-ba28-4dde-95a7-2cbb2c15de24")
-			throw new ApiError(meta.errors.noSuchNote);
-		throw err;
-	});
-
-	if (!note.hasPoll) {
-		throw new ApiError(meta.errors.noPoll);
-	}
-
-	// Check blocking
-	if (note.userId !== user.id) {
-		const block = await Blockings.findOneBy({
-			blockerId: note.userId,
-			blockeeId: user.id,
-		});
-		if (block) {
-			throw new ApiError(meta.errors.youHaveBeenBlocked);
-		}
-	}
-
-	const poll = await Polls.findOneByOrFail({ noteId: note.id });
-
-	if (poll.expiresAt && poll.expiresAt < createdAt) {
-		throw new ApiError(meta.errors.alreadyExpired);
-	}
-
-	if (poll.choices[ps.choice] == null) {
-		throw new ApiError(meta.errors.invalidChoice);
-	}
-
-	// if already voted
-	const exist = await PollVotes.findBy({
-		noteId: note.id,
-		userId: user.id,
-	});
-
-	if (exist.length) {
-		if (poll.multiple) {
-			if (exist.some((x) => x.choice === ps.choice)) {
-				throw new ApiError(meta.errors.alreadyVoted);
-			}
-		} else {
-			throw new ApiError(meta.errors.alreadyVoted);
-		}
-	}
-
-	// Create vote
-	const vote = await PollVotes.insert({
-		id: genId(),
-		createdAt,
-		noteId: note.id,
-		userId: user.id,
-		choice: ps.choice,
-	}).then((x) => PollVotes.findOneByOrFail(x.identifiers[0]));
-
-	// Increment votes count
-	const index = ps.choice + 1; // In SQL, array index is 1 based
-	await Polls.query(
-		`UPDATE poll SET votes[${index}] = votes[${index}] + 1 WHERE "noteId" = '${poll.noteId}'`,
-	);
-
-	publishNoteStream(note.id, "pollVoted", {
-		choice: ps.choice,
-		userId: user.id,
-	});
-
-	// Notify
-	createNotification(note.userId, "pollVote", {
-		notifierId: user.id,
-		noteId: note.id,
-		choice: ps.choice,
-	});
-
-	// Fetch watchers
-	NoteWatchings.findBy({
-		noteId: note.id,
-		userId: Not(user.id),
-	}).then((watchers) => {
-		for (const watcher of watchers) {
-			createNotification(watcher.userId, "pollVote", {
-				notifierId: user.id,
-				noteId: note.id,
-				choice: ps.choice,
-			});
-		}
-	});
-
-	// リモート投票の場合リプライ送信
-	if (note.userHost != null) {
-		const pollOwner = (await Users.findOneByOrFail({
-			id: note.userId,
-		})) as IRemoteUser;
-
-		deliver(
-			user,
-			renderActivity(await renderVote(user, vote, note, poll, pollOwner)),
-			pollOwner.inbox,
-		);
-	}
-
-	// リモートフォロワーにUpdate配信
-	deliverQuestionUpdate(note.id);
-});
diff --git a/packages/backend/src/server/api/endpoints/notes/reactions.ts b/packages/backend/src/server/api/endpoints/notes/reactions.ts
deleted file mode 100644
index 3c8af119ab..0000000000
--- a/packages/backend/src/server/api/endpoints/notes/reactions.ts
+++ /dev/null
@@ -1,85 +0,0 @@
-import type { FindOptionsWhere } from "typeorm";
-import { DeepPartial } from "typeorm";
-import { NoteReactions } from "@/models/index.js";
-import type { NoteReaction } from "@/models/entities/note-reaction.js";
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { getNote } from "../../common/getters.js";
-
-export const meta = {
-	tags: ["notes", "reactions"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	allowGet: true,
-	cacheSec: 60,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "NoteReaction",
-		},
-	},
-
-	errors: {
-		noSuchNote: {
-			message: "No such note.",
-			code: "NO_SUCH_NOTE",
-			id: "263fff3d-d0e1-4af4-bea7-8408059b451a",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		noteId: { type: "string", format: "misskey:id" },
-		type: { type: "string", nullable: true },
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		offset: { type: "integer", default: 0 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-	},
-	required: ["noteId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	// check note visibility
-	const note = await getNote(ps.noteId, user).catch((err) => {
-		if (err.id === "9725d0ce-ba28-4dde-95a7-2cbb2c15de24")
-			throw new ApiError(meta.errors.noSuchNote);
-		throw err;
-	});
-
-	const query = {
-		noteId: ps.noteId,
-	} as FindOptionsWhere<NoteReaction>;
-
-	if (ps.type) {
-		// ローカルリアクションはホスト名が . とされているが
-		// DB 上ではそうではないので、必要に応じて変換
-		const suffix = "@.:";
-		const type = ps.type.endsWith(suffix)
-			? `${ps.type.slice(0, ps.type.length - suffix.length)}:`
-			: ps.type;
-		query.reaction = type;
-	}
-
-	const reactions = await NoteReactions.find({
-		where: query,
-		take: ps.limit,
-		skip: ps.offset,
-		order: {
-			id: -1,
-		},
-		relations: ["user", "user.avatar", "user.banner", "note"],
-	});
-
-	return await NoteReactions.packMany(reactions, user);
-});
diff --git a/packages/backend/src/server/api/endpoints/notes/reactions/create.ts b/packages/backend/src/server/api/endpoints/notes/reactions/create.ts
deleted file mode 100644
index 2c8671070f..0000000000
--- a/packages/backend/src/server/api/endpoints/notes/reactions/create.ts
+++ /dev/null
@@ -1,64 +0,0 @@
-import createReaction from "@/services/note/reaction/create.js";
-import define from "../../../define.js";
-import { getNote } from "../../../common/getters.js";
-import { ApiError } from "../../../error.js";
-
-export const meta = {
-	tags: ["reactions", "notes"],
-
-	requireCredential: true,
-
-	kind: "write:reactions",
-
-	errors: {
-		noSuchNote: {
-			message: "No such note.",
-			code: "NO_SUCH_NOTE",
-			id: "033d0620-5bfe-4027-965d-980b0c85a3ea",
-		},
-
-		alreadyReacted: {
-			message: "You are already reacting to that note.",
-			code: "ALREADY_REACTED",
-			id: "71efcf98-86d6-4e2b-b2ad-9d032369366b",
-		},
-
-		youHaveBeenBlocked: {
-			message:
-				"You cannot react this note because you have been blocked by this user.",
-			code: "YOU_HAVE_BEEN_BLOCKED",
-			id: "20ef5475-9f38-4e4c-bd33-de6d979498ec",
-		},
-		accountLocked: {
-			message: "You migrated. Your account is now locked.",
-			code: "ACCOUNT_LOCKED",
-			id: "d390d7e1-8a5e-46ed-b625-06271cafd3d3",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		noteId: { type: "string", format: "misskey:id" },
-		reaction: { type: "string" },
-	},
-	required: ["noteId", "reaction"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	if (user.movedToUri != null) throw new ApiError(meta.errors.accountLocked);
-	const note = await getNote(ps.noteId, user).catch((err) => {
-		if (err.id === "9725d0ce-ba28-4dde-95a7-2cbb2c15de24")
-			throw new ApiError(meta.errors.noSuchNote);
-		throw err;
-	});
-	await createReaction(user, note, ps.reaction).catch((e) => {
-		if (e.id === "51c42bb4-931a-456b-bff7-e5a8a70dd298")
-			throw new ApiError(meta.errors.alreadyReacted);
-		if (e.id === "e70412a4-7197-4726-8e74-f3e0deb92aa7")
-			throw new ApiError(meta.errors.youHaveBeenBlocked);
-		throw e;
-	});
-	return;
-});
diff --git a/packages/backend/src/server/api/endpoints/notes/reactions/delete.ts b/packages/backend/src/server/api/endpoints/notes/reactions/delete.ts
deleted file mode 100644
index 59096c4c88..0000000000
--- a/packages/backend/src/server/api/endpoints/notes/reactions/delete.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-import deleteReaction from "@/services/note/reaction/delete.js";
-import define from "../../../define.js";
-import { getNote } from "../../../common/getters.js";
-import { ApiError } from "../../../error.js";
-import { SECOND, HOUR } from "@/const.js";
-
-export const meta = {
-	tags: ["reactions", "notes"],
-
-	requireCredential: true,
-
-	kind: "write:reactions",
-
-	limit: {
-		duration: HOUR,
-		max: 60,
-		minInterval: 3 * SECOND,
-	},
-
-	errors: {
-		noSuchNote: {
-			message: "No such note.",
-			code: "NO_SUCH_NOTE",
-			id: "764d9fce-f9f2-4a0e-92b1-6ceac9a7ad37",
-		},
-
-		notReacted: {
-			message: "You are not reacting to that note.",
-			code: "NOT_REACTED",
-			id: "92f4426d-4196-4125-aa5b-02943e2ec8fc",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		noteId: { type: "string", format: "misskey:id" },
-	},
-	required: ["noteId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const note = await getNote(ps.noteId, user).catch((err) => {
-		if (err.id === "9725d0ce-ba28-4dde-95a7-2cbb2c15de24")
-			throw new ApiError(meta.errors.noSuchNote);
-		throw err;
-	});
-	await deleteReaction(user, note).catch((e) => {
-		if (e.id === "60527ec9-b4cb-4a88-a6bd-32d3ad26817d")
-			throw new ApiError(meta.errors.notReacted);
-		throw e;
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/notes/recommended-timeline.ts b/packages/backend/src/server/api/endpoints/notes/recommended-timeline.ts
deleted file mode 100644
index 56847b1dd2..0000000000
--- a/packages/backend/src/server/api/endpoints/notes/recommended-timeline.ts
+++ /dev/null
@@ -1,154 +0,0 @@
-import { Brackets } from "typeorm";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { Notes } from "@/models/index.js";
-import { activeUsersChart } from "@/services/chart/index.js";
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { generateMutedUserQuery } from "../../common/generate-muted-user-query.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-import { generateVisibilityQuery } from "../../common/generate-visibility-query.js";
-import { generateRepliesQuery } from "../../common/generate-replies-query.js";
-import { generateMutedNoteQuery } from "../../common/generate-muted-note-query.js";
-import { generateChannelQuery } from "../../common/generate-channel-query.js";
-import { generateBlockedUserQuery } from "../../common/generate-block-query.js";
-import { generateMutedUserRenotesQueryForNotes } from "../../common/generated-muted-renote-query.js";
-
-export const meta = {
-	tags: ["notes"],
-	requireCredentialPrivateMode: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Note",
-		},
-	},
-
-	errors: {
-		rtlDisabled: {
-			message: "Recommended timeline has been disabled.",
-			code: "RTL_DISABLED",
-			id: "45a6eb02-7695-4393-b023-dd3be9aaaefe",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		withFiles: {
-			type: "boolean",
-			default: false,
-			description: "Only show notes that have attached files.",
-		},
-		fileType: {
-			type: "array",
-			items: {
-				type: "string",
-			},
-		},
-		excludeNsfw: { type: "boolean", default: false },
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-		sinceDate: { type: "integer" },
-		untilDate: { type: "integer" },
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const m = await fetchMeta();
-	if (m.disableRecommendedTimeline) {
-		if (user == null || !(user.isAdmin || user.isModerator)) {
-			throw new ApiError(meta.errors.rtlDisabled);
-		}
-	}
-
-	//#region Construct query
-	const query = makePaginationQuery(
-		Notes.createQueryBuilder("note"),
-		ps.sinceId,
-		ps.untilId,
-		ps.sinceDate,
-		ps.untilDate,
-	)
-		.andWhere(
-			`(note.userHost = ANY ('{"${m.recommendedInstances.join('","')}"}'))`,
-		)
-		.andWhere("(note.visibility = 'public')")
-		.innerJoinAndSelect("note.user", "user")
-		.leftJoinAndSelect("user.avatar", "avatar")
-		.leftJoinAndSelect("user.banner", "banner")
-		.leftJoinAndSelect("note.reply", "reply")
-		.leftJoinAndSelect("note.renote", "renote")
-		.leftJoinAndSelect("reply.user", "replyUser")
-		.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
-		.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
-		.leftJoinAndSelect("renote.user", "renoteUser")
-		.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
-		.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner");
-
-	generateChannelQuery(query, user);
-	generateRepliesQuery(query, user);
-	generateVisibilityQuery(query, user);
-	if (user) generateMutedUserQuery(query, user);
-	if (user) generateMutedNoteQuery(query, user);
-	if (user) generateBlockedUserQuery(query, user);
-	if (user) generateMutedUserRenotesQueryForNotes(query, user);
-
-	if (ps.withFiles) {
-		query.andWhere("note.fileIds != '{}'");
-	}
-
-	if (ps.fileType != null) {
-		query.andWhere("note.fileIds != '{}'");
-		query.andWhere(
-			new Brackets((qb) => {
-				for (const type of ps.fileType!) {
-					const i = ps.fileType!.indexOf(type);
-					qb.orWhere(`:type${i} = ANY(note.attachedFileTypes)`, {
-						[`type${i}`]: type,
-					});
-				}
-			}),
-		);
-
-		if (ps.excludeNsfw) {
-			query.andWhere("note.cw IS NULL");
-			query.andWhere(
-				'0 = (SELECT COUNT(*) FROM drive_file df WHERE df.id = ANY(note."fileIds") AND df."isSensitive" = TRUE)',
-			);
-		}
-	}
-	//#endregion
-
-	process.nextTick(() => {
-		if (user) {
-			activeUsersChart.read(user);
-		}
-	});
-
-	// We fetch more than requested because some may be filtered out, and if there's less than
-	// requested, the pagination stops.
-	const found = [];
-	const take = Math.floor(ps.limit * 1.5);
-	let skip = 0;
-	while (found.length < ps.limit) {
-		const notes = await query.take(take).skip(skip).getMany();
-		found.push(...(await Notes.packMany(notes, user)));
-		skip += take;
-		if (notes.length < take) break;
-	}
-
-	if (found.length > ps.limit) {
-		found.length = ps.limit;
-	}
-
-	return found;
-});
diff --git a/packages/backend/src/server/api/endpoints/notes/renotes.ts b/packages/backend/src/server/api/endpoints/notes/renotes.ts
deleted file mode 100644
index f313616be2..0000000000
--- a/packages/backend/src/server/api/endpoints/notes/renotes.ts
+++ /dev/null
@@ -1,94 +0,0 @@
-import { Notes } from "@/models/index.js";
-import define from "../../define.js";
-import { getNote } from "../../common/getters.js";
-import { ApiError } from "../../error.js";
-import { generateVisibilityQuery } from "../../common/generate-visibility-query.js";
-import { generateMutedUserQuery } from "../../common/generate-muted-user-query.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-import { generateBlockedUserQuery } from "../../common/generate-block-query.js";
-
-export const meta = {
-	tags: ["notes"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Note",
-		},
-	},
-
-	errors: {
-		noSuchNote: {
-			message: "No such note.",
-			code: "NO_SUCH_NOTE",
-			id: "12908022-2e21-46cd-ba6a-3edaf6093f46",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		noteId: { type: "string", format: "misskey:id" },
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-	},
-	required: ["noteId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const note = await getNote(ps.noteId, user).catch((err) => {
-		if (err.id === "9725d0ce-ba28-4dde-95a7-2cbb2c15de24")
-			throw new ApiError(meta.errors.noSuchNote);
-		throw err;
-	});
-
-	const query = makePaginationQuery(
-		Notes.createQueryBuilder("note"),
-		ps.sinceId,
-		ps.untilId,
-	)
-		.andWhere("note.renoteId = :renoteId", { renoteId: note.id })
-		.innerJoinAndSelect("note.user", "user")
-		.leftJoinAndSelect("user.avatar", "avatar")
-		.leftJoinAndSelect("user.banner", "banner")
-		.leftJoinAndSelect("note.reply", "reply")
-		.leftJoinAndSelect("note.renote", "renote")
-		.leftJoinAndSelect("reply.user", "replyUser")
-		.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
-		.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
-		.leftJoinAndSelect("renote.user", "renoteUser")
-		.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
-		.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner");
-
-	generateVisibilityQuery(query, user);
-	if (user) generateMutedUserQuery(query, user);
-	if (user) generateBlockedUserQuery(query, user);
-
-	// We fetch more than requested because some may be filtered out, and if there's less than
-	// requested, the pagination stops.
-	const found = [];
-	const take = Math.floor(ps.limit * 1.5);
-	let skip = 0;
-	while (found.length < ps.limit) {
-		const notes = await query.take(take).skip(skip).getMany();
-		found.push(...(await Notes.packMany(notes, user)));
-		skip += take;
-		if (notes.length < take) break;
-	}
-
-	if (found.length > ps.limit) {
-		found.length = ps.limit;
-	}
-
-	return found;
-});
diff --git a/packages/backend/src/server/api/endpoints/notes/replies.ts b/packages/backend/src/server/api/endpoints/notes/replies.ts
deleted file mode 100644
index 5ea4d479c5..0000000000
--- a/packages/backend/src/server/api/endpoints/notes/replies.ts
+++ /dev/null
@@ -1,78 +0,0 @@
-import { Notes } from "@/models/index.js";
-import define from "../../define.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-import { generateVisibilityQuery } from "../../common/generate-visibility-query.js";
-import { generateMutedUserQuery } from "../../common/generate-muted-user-query.js";
-import { generateBlockedUserQuery } from "../../common/generate-block-query.js";
-
-export const meta = {
-	tags: ["notes"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Note",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		noteId: { type: "string", format: "misskey:id" },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-	},
-	required: ["noteId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const query = makePaginationQuery(
-		Notes.createQueryBuilder("note"),
-		ps.sinceId,
-		ps.untilId,
-	)
-		.andWhere("note.replyId = :replyId", { replyId: ps.noteId })
-		.innerJoinAndSelect("note.user", "user")
-		.leftJoinAndSelect("user.avatar", "avatar")
-		.leftJoinAndSelect("user.banner", "banner")
-		.leftJoinAndSelect("note.reply", "reply")
-		.leftJoinAndSelect("note.renote", "renote")
-		.leftJoinAndSelect("reply.user", "replyUser")
-		.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
-		.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
-		.leftJoinAndSelect("renote.user", "renoteUser")
-		.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
-		.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner");
-
-	generateVisibilityQuery(query, user);
-	if (user) generateMutedUserQuery(query, user);
-	if (user) generateBlockedUserQuery(query, user);
-
-	// We fetch more than requested because some may be filtered out, and if there's less than
-	// requested, the pagination stops.
-	const found = [];
-	const take = Math.floor(ps.limit * 1.5);
-	let skip = 0;
-	while (found.length < ps.limit) {
-		const notes = await query.take(take).skip(skip).getMany();
-		found.push(...(await Notes.packMany(notes, user)));
-		skip += take;
-		if (notes.length < take) break;
-	}
-
-	if (found.length > ps.limit) {
-		found.length = ps.limit;
-	}
-
-	return found;
-});
diff --git a/packages/backend/src/server/api/endpoints/notes/search-by-tag.ts b/packages/backend/src/server/api/endpoints/notes/search-by-tag.ts
deleted file mode 100644
index f988acaa51..0000000000
--- a/packages/backend/src/server/api/endpoints/notes/search-by-tag.ts
+++ /dev/null
@@ -1,165 +0,0 @@
-import { Brackets } from "typeorm";
-import { Notes } from "@/models/index.js";
-import { safeForSql } from "@/misc/safe-for-sql.js";
-import { normalizeForSearch } from "@/misc/normalize-for-search.js";
-import define from "../../define.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-import { generateMutedUserQuery } from "../../common/generate-muted-user-query.js";
-import { generateVisibilityQuery } from "../../common/generate-visibility-query.js";
-import { generateBlockedUserQuery } from "../../common/generate-block-query.js";
-
-export const meta = {
-	tags: ["notes", "hashtags"],
-	requireCredentialPrivateMode: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Note",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		reply: { type: "boolean", nullable: true, default: null },
-		renote: { type: "boolean", nullable: true, default: null },
-		withFiles: {
-			type: "boolean",
-			default: false,
-			description: "Only show notes that have attached files.",
-		},
-		poll: { type: "boolean", nullable: true, default: null },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-	},
-	anyOf: [
-		{
-			properties: {
-				tag: { type: "string", minLength: 1 },
-			},
-			required: ["tag"],
-		},
-		{
-			properties: {
-				query: {
-					type: "array",
-					description:
-						"The outer arrays are chained with OR, the inner arrays are chained with AND.",
-					items: {
-						type: "array",
-						items: {
-							type: "string",
-							minLength: 1,
-						},
-						minItems: 1,
-					},
-					minItems: 1,
-				},
-			},
-			required: ["query"],
-		},
-	],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const query = makePaginationQuery(
-		Notes.createQueryBuilder("note"),
-		ps.sinceId,
-		ps.untilId,
-	)
-		.innerJoinAndSelect("note.user", "user")
-		.leftJoinAndSelect("user.avatar", "avatar")
-		.leftJoinAndSelect("user.banner", "banner")
-		.leftJoinAndSelect("note.reply", "reply")
-		.leftJoinAndSelect("note.renote", "renote")
-		.leftJoinAndSelect("reply.user", "replyUser")
-		.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
-		.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
-		.leftJoinAndSelect("renote.user", "renoteUser")
-		.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
-		.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner");
-
-	generateVisibilityQuery(query, me);
-	if (me) generateMutedUserQuery(query, me);
-	if (me) generateBlockedUserQuery(query, me);
-
-	try {
-		if (ps.tag) {
-			if (!safeForSql(normalizeForSearch(ps.tag))) throw "Injection";
-			query.andWhere(`'{"${normalizeForSearch(ps.tag)}"}' <@ note.tags`);
-		} else {
-			query.andWhere(
-				new Brackets((qb) => {
-					for (const tags of ps.query!) {
-						qb.orWhere(
-							new Brackets((qb) => {
-								for (const tag of tags) {
-									if (!safeForSql(normalizeForSearch(ps.tag)))
-										throw "Injection";
-									qb.andWhere(`'{"${normalizeForSearch(tag)}"}' <@ note.tags`);
-								}
-							}),
-						);
-					}
-				}),
-			);
-		}
-	} catch (e) {
-		if (e.message === "Injection") return [];
-		throw e;
-	}
-
-	if (ps.reply != null) {
-		if (ps.reply) {
-			query.andWhere("note.replyId IS NOT NULL");
-		} else {
-			query.andWhere("note.replyId IS NULL");
-		}
-	}
-
-	if (ps.renote != null) {
-		if (ps.renote) {
-			query.andWhere("note.renoteId IS NOT NULL");
-		} else {
-			query.andWhere("note.renoteId IS NULL");
-		}
-	}
-
-	if (ps.withFiles) {
-		query.andWhere("note.fileIds != '{}'");
-	}
-
-	if (ps.poll != null) {
-		if (ps.poll) {
-			query.andWhere("note.hasPoll = TRUE");
-		} else {
-			query.andWhere("note.hasPoll = FALSE");
-		}
-	}
-
-	// We fetch more than requested because some may be filtered out, and if there's less than
-	// requested, the pagination stops.
-	const found = [];
-	const take = Math.floor(ps.limit * 1.5);
-	let skip = 0;
-	while (found.length < ps.limit) {
-		const notes = await query.take(take).skip(skip).getMany();
-		found.push(...(await Notes.packMany(notes, me)));
-		skip += take;
-		if (notes.length < take) break;
-	}
-
-	if (found.length > ps.limit) {
-		found.length = ps.limit;
-	}
-
-	return found;
-});
diff --git a/packages/backend/src/server/api/endpoints/notes/search.ts b/packages/backend/src/server/api/endpoints/notes/search.ts
deleted file mode 100644
index 8f563c384f..0000000000
--- a/packages/backend/src/server/api/endpoints/notes/search.ts
+++ /dev/null
@@ -1,254 +0,0 @@
-import { In } from "typeorm";
-import { Notes } from "@/models/index.js";
-import { Note } from "@/models/entities/note.js";
-import config from "@/config/index.js";
-import es from "../../../../db/elasticsearch.js";
-import sonic from "../../../../db/sonic.js";
-import define from "../../define.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-import { generateVisibilityQuery } from "../../common/generate-visibility-query.js";
-import { generateMutedUserQuery } from "../../common/generate-muted-user-query.js";
-import { generateBlockedUserQuery } from "../../common/generate-block-query.js";
-
-export const meta = {
-	tags: ["notes"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Note",
-		},
-	},
-
-	errors: {},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		query: { type: "string" },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		offset: { type: "integer", default: 0 },
-		host: {
-			type: "string",
-			nullable: true,
-			description: "The local host is represented with `null`.",
-		},
-		userId: {
-			type: "string",
-			format: "misskey:id",
-			nullable: true,
-			default: null,
-		},
-		channelId: {
-			type: "string",
-			format: "misskey:id",
-			nullable: true,
-			default: null,
-		},
-	},
-	required: ["query"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	if (es == null && sonic == null) {
-		const query = makePaginationQuery(
-			Notes.createQueryBuilder("note"),
-			ps.sinceId,
-			ps.untilId,
-		);
-
-		if (ps.userId) {
-			query.andWhere("note.userId = :userId", { userId: ps.userId });
-		} else if (ps.channelId) {
-			query.andWhere("note.channelId = :channelId", {
-				channelId: ps.channelId,
-			});
-		}
-
-		query
-			.andWhere("note.text ILIKE :q", { q: `%${ps.query}%` })
-			.innerJoinAndSelect("note.user", "user")
-			.leftJoinAndSelect("user.avatar", "avatar")
-			.leftJoinAndSelect("user.banner", "banner")
-			.leftJoinAndSelect("note.reply", "reply")
-			.leftJoinAndSelect("note.renote", "renote")
-			.leftJoinAndSelect("reply.user", "replyUser")
-			.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
-			.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
-			.leftJoinAndSelect("renote.user", "renoteUser")
-			.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
-			.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner");
-
-		generateVisibilityQuery(query, me);
-		if (me) generateMutedUserQuery(query, me);
-		if (me) generateBlockedUserQuery(query, me);
-
-		const notes: Note[] = await query.take(ps.limit).getMany();
-
-		return await Notes.packMany(notes, me);
-	} else if (sonic) {
-		let start = 0;
-		const chunkSize = 100;
-
-		// Use sonic to fetch and step through all search results that could match the requirements
-		const ids = [];
-		while (true) {
-			const results = await sonic.search.query(
-				sonic.collection,
-				sonic.bucket,
-				ps.query,
-				{
-					limit: chunkSize,
-					offset: start,
-				},
-			);
-
-			start += chunkSize;
-
-			if (results.length === 0) {
-				break;
-			}
-
-			const res = results
-				.map((k) => JSON.parse(k))
-				.filter((key) => {
-					if (ps.userId && key.userId !== ps.userId) {
-						return false;
-					}
-					if (ps.channelId && key.channelId !== ps.channelId) {
-						return false;
-					}
-					if (ps.sinceId && key.id <= ps.sinceId) {
-						return false;
-					}
-					if (ps.untilId && key.id >= ps.untilId) {
-						return false;
-					}
-					return true;
-				})
-				.map((key) => key.id);
-
-			ids.push(...res);
-		}
-
-		// Sort all the results by note id DESC (newest first)
-		ids.sort((a, b) => b - a);
-
-		// Fetch the notes from the database until we have enough to satisfy the limit
-		start = 0;
-		const found = [];
-		while (found.length < ps.limit && start < ids.length) {
-			const chunk = ids.slice(start, start + chunkSize);
-			const notes: Note[] = await Notes.find({
-				where: {
-					id: In(chunk),
-				},
-				order: {
-					id: "DESC",
-				},
-			});
-
-			// The notes are checked for visibility and muted/blocked users when packed
-			found.push(...(await Notes.packMany(notes, me)));
-			start += chunkSize;
-		}
-
-		// If we have more results than the limit, trim them
-		if (found.length > ps.limit) {
-			found.length = ps.limit;
-		}
-
-		return found;
-	} else {
-		const userQuery =
-			ps.userId != null
-				? [
-						{
-							term: {
-								userId: ps.userId,
-							},
-						},
-				  ]
-				: [];
-
-		const hostQuery =
-			ps.userId == null
-				? ps.host === null
-					? [
-							{
-								bool: {
-									must_not: {
-										exists: {
-											field: "userHost",
-										},
-									},
-								},
-							},
-					  ]
-					: ps.host !== undefined
-					? [
-							{
-								term: {
-									userHost: ps.host,
-								},
-							},
-					  ]
-					: []
-				: [];
-
-		const result = await es.search({
-			index: config.elasticsearch.index || "misskey_note",
-			body: {
-				size: ps.limit,
-				from: ps.offset,
-				query: {
-					bool: {
-						must: [
-							{
-								simple_query_string: {
-									fields: ["text"],
-									query: ps.query.toLowerCase(),
-									default_operator: "and",
-								},
-							},
-							...hostQuery,
-							...userQuery,
-						],
-					},
-				},
-				sort: [
-					{
-						_doc: "desc",
-					},
-				],
-			},
-		});
-
-		const hits = result.body.hits.hits.map((hit: any) => hit._id);
-
-		if (hits.length === 0) return [];
-
-		// Fetch found notes
-		const notes = await Notes.find({
-			where: {
-				id: In(hits),
-			},
-			order: {
-				id: -1,
-			},
-		});
-
-		return await Notes.packMany(notes, me);
-	}
-});
diff --git a/packages/backend/src/server/api/endpoints/notes/show.ts b/packages/backend/src/server/api/endpoints/notes/show.ts
deleted file mode 100644
index 39d128134f..0000000000
--- a/packages/backend/src/server/api/endpoints/notes/show.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import { Notes } from "@/models/index.js";
-import define from "../../define.js";
-import { getNote } from "../../common/getters.js";
-import { ApiError } from "../../error.js";
-
-export const meta = {
-	tags: ["notes"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "Note",
-	},
-
-	errors: {
-		noSuchNote: {
-			message: "No such note.",
-			code: "NO_SUCH_NOTE",
-			id: "24fcbfc6-2e37-42b6-8388-c29b3861a08d",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		noteId: { type: "string", format: "misskey:id" },
-	},
-	required: ["noteId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const note = await getNote(ps.noteId, user).catch((err) => {
-		if (err.id === "9725d0ce-ba28-4dde-95a7-2cbb2c15de24")
-			throw new ApiError(meta.errors.noSuchNote);
-		throw err;
-	});
-
-	return await Notes.pack(note, user, {
-		// FIXME: packing with detail may throw an error if the reply or renote is not visible (#8774)
-		detail: true,
-	}).catch((err) => {
-		if (err.id === "9725d0ce-ba28-4dde-95a7-2cbb2c15de24")
-			throw new ApiError(meta.errors.noSuchNote);
-		throw err;
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/notes/state.ts b/packages/backend/src/server/api/endpoints/notes/state.ts
deleted file mode 100644
index 630b2a8007..0000000000
--- a/packages/backend/src/server/api/endpoints/notes/state.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-import {
-	NoteFavorites,
-	Notes,
-	NoteThreadMutings,
-	NoteWatchings,
-} from "@/models/index.js";
-import { getNote } from "../../common/getters.js";
-import define from "../../define.js";
-
-export const meta = {
-	tags: ["notes"],
-
-	requireCredential: true,
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		properties: {
-			isFavorited: {
-				type: "boolean",
-				optional: false,
-				nullable: false,
-			},
-			isWatching: {
-				type: "boolean",
-				optional: false,
-				nullable: false,
-			},
-			isMutedThread: {
-				type: "boolean",
-				optional: false,
-				nullable: false,
-			},
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		noteId: { type: "string", format: "misskey:id" },
-	},
-	required: ["noteId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const note = await getNote(ps.noteId, user);
-
-	const [favorite, watching, threadMuting] = await Promise.all([
-		NoteFavorites.count({
-			where: {
-				userId: user.id,
-				noteId: note.id,
-			},
-			take: 1,
-		}),
-		NoteWatchings.count({
-			where: {
-				userId: user.id,
-				noteId: note.id,
-			},
-			take: 1,
-		}),
-		NoteThreadMutings.count({
-			where: {
-				userId: user.id,
-				threadId: note.threadId || note.id,
-			},
-			take: 1,
-		}),
-	]);
-
-	return {
-		isFavorited: favorite !== 0,
-		isWatching: watching !== 0,
-		isMutedThread: threadMuting !== 0,
-	};
-});
diff --git a/packages/backend/src/server/api/endpoints/notes/thread-muting/create.ts b/packages/backend/src/server/api/endpoints/notes/thread-muting/create.ts
deleted file mode 100644
index e4803cc291..0000000000
--- a/packages/backend/src/server/api/endpoints/notes/thread-muting/create.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-import { Notes, NoteThreadMutings } from "@/models/index.js";
-import { genId } from "@/misc/gen-id.js";
-import readNote from "@/services/note/read.js";
-import define from "../../../define.js";
-import { getNote } from "../../../common/getters.js";
-import { ApiError } from "../../../error.js";
-
-export const meta = {
-	tags: ["notes"],
-
-	requireCredential: true,
-
-	kind: "write:account",
-
-	errors: {
-		noSuchNote: {
-			message: "No such note.",
-			code: "NO_SUCH_NOTE",
-			id: "5ff67ada-ed3b-2e71-8e87-a1a421e177d2",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		noteId: { type: "string", format: "misskey:id" },
-	},
-	required: ["noteId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const note = await getNote(ps.noteId, user).catch((err) => {
-		if (err.id === "9725d0ce-ba28-4dde-95a7-2cbb2c15de24")
-			throw new ApiError(meta.errors.noSuchNote);
-		throw err;
-	});
-
-	const mutedNotes = await Notes.find({
-		where: [
-			{
-				id: note.threadId || note.id,
-			},
-			{
-				threadId: note.threadId || note.id,
-			},
-		],
-	});
-
-	await readNote(user.id, mutedNotes);
-
-	await NoteThreadMutings.insert({
-		id: genId(),
-		createdAt: new Date(),
-		threadId: note.threadId || note.id,
-		userId: user.id,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/notes/thread-muting/delete.ts b/packages/backend/src/server/api/endpoints/notes/thread-muting/delete.ts
deleted file mode 100644
index c06fd59ba5..0000000000
--- a/packages/backend/src/server/api/endpoints/notes/thread-muting/delete.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import { NoteThreadMutings } from "@/models/index.js";
-import define from "../../../define.js";
-import { getNote } from "../../../common/getters.js";
-import { ApiError } from "../../../error.js";
-
-export const meta = {
-	tags: ["notes"],
-
-	requireCredential: true,
-
-	kind: "write:account",
-
-	errors: {
-		noSuchNote: {
-			message: "No such note.",
-			code: "NO_SUCH_NOTE",
-			id: "bddd57ac-ceb3-b29d-4334-86ea5fae481a",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		noteId: { type: "string", format: "misskey:id" },
-	},
-	required: ["noteId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const note = await getNote(ps.noteId, user).catch((err) => {
-		if (err.id === "9725d0ce-ba28-4dde-95a7-2cbb2c15de24")
-			throw new ApiError(meta.errors.noSuchNote);
-		throw err;
-	});
-
-	await NoteThreadMutings.delete({
-		threadId: note.threadId || note.id,
-		userId: user.id,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/notes/timeline.ts b/packages/backend/src/server/api/endpoints/notes/timeline.ts
deleted file mode 100644
index f85c0cfd32..0000000000
--- a/packages/backend/src/server/api/endpoints/notes/timeline.ts
+++ /dev/null
@@ -1,169 +0,0 @@
-import { Brackets } from "typeorm";
-import { Notes, Followings } from "@/models/index.js";
-import { activeUsersChart } from "@/services/chart/index.js";
-import define from "../../define.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-import { generateVisibilityQuery } from "../../common/generate-visibility-query.js";
-import { generateMutedUserQuery } from "../../common/generate-muted-user-query.js";
-import { generateRepliesQuery } from "../../common/generate-replies-query.js";
-import { generateMutedNoteQuery } from "../../common/generate-muted-note-query.js";
-import { generateChannelQuery } from "../../common/generate-channel-query.js";
-import { generateBlockedUserQuery } from "../../common/generate-block-query.js";
-import { generateMutedUserRenotesQueryForNotes } from "../../common/generated-muted-renote-query.js";
-
-export const meta = {
-	tags: ["notes"],
-
-	requireCredential: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Note",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-		sinceDate: { type: "integer" },
-		untilDate: { type: "integer" },
-		includeMyRenotes: { type: "boolean", default: true },
-		includeRenotedMyNotes: { type: "boolean", default: true },
-		includeLocalRenotes: { type: "boolean", default: true },
-		withFiles: {
-			type: "boolean",
-			default: false,
-			description: "Only show notes that have attached files.",
-		},
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const hasFollowing =
-		(await Followings.count({
-			where: {
-				followerId: user.id,
-			},
-			take: 1,
-		})) !== 0;
-
-	//#region Construct query
-	const followingQuery = Followings.createQueryBuilder("following")
-		.select("following.followeeId")
-		.where("following.followerId = :followerId", { followerId: user.id });
-
-	const query = makePaginationQuery(
-		Notes.createQueryBuilder("note"),
-		ps.sinceId,
-		ps.untilId,
-		ps.sinceDate,
-		ps.untilDate,
-	)
-		.andWhere(
-			new Brackets((qb) => {
-				qb.where("note.userId = :meId", { meId: user.id });
-				if (hasFollowing)
-					qb.orWhere(`note.userId IN (${followingQuery.getQuery()})`);
-			}),
-		)
-		.innerJoinAndSelect("note.user", "user")
-		.leftJoinAndSelect("user.avatar", "avatar")
-		.leftJoinAndSelect("user.banner", "banner")
-		.leftJoinAndSelect("note.reply", "reply")
-		.leftJoinAndSelect("note.renote", "renote")
-		.leftJoinAndSelect("reply.user", "replyUser")
-		.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
-		.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
-		.leftJoinAndSelect("renote.user", "renoteUser")
-		.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
-		.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner")
-		.setParameters(followingQuery.getParameters());
-
-	generateChannelQuery(query, user);
-	generateRepliesQuery(query, user);
-	generateVisibilityQuery(query, user);
-	generateMutedUserQuery(query, user);
-	generateMutedNoteQuery(query, user);
-	generateBlockedUserQuery(query, user);
-	generateMutedUserRenotesQueryForNotes(query, user);
-
-	if (ps.includeMyRenotes === false) {
-		query.andWhere(
-			new Brackets((qb) => {
-				qb.orWhere("note.userId != :meId", { meId: user.id });
-				qb.orWhere("note.renoteId IS NULL");
-				qb.orWhere("note.text IS NOT NULL");
-				qb.orWhere("note.fileIds != '{}'");
-				qb.orWhere(
-					'0 < (SELECT COUNT(*) FROM poll WHERE poll."noteId" = note.id)',
-				);
-			}),
-		);
-	}
-
-	if (ps.includeRenotedMyNotes === false) {
-		query.andWhere(
-			new Brackets((qb) => {
-				qb.orWhere("note.renoteUserId != :meId", { meId: user.id });
-				qb.orWhere("note.renoteId IS NULL");
-				qb.orWhere("note.text IS NOT NULL");
-				qb.orWhere("note.fileIds != '{}'");
-				qb.orWhere(
-					'0 < (SELECT COUNT(*) FROM poll WHERE poll."noteId" = note.id)',
-				);
-			}),
-		);
-	}
-
-	if (ps.includeLocalRenotes === false) {
-		query.andWhere(
-			new Brackets((qb) => {
-				qb.orWhere("note.renoteUserHost IS NOT NULL");
-				qb.orWhere("note.renoteId IS NULL");
-				qb.orWhere("note.text IS NOT NULL");
-				qb.orWhere("note.fileIds != '{}'");
-				qb.orWhere(
-					'0 < (SELECT COUNT(*) FROM poll WHERE poll."noteId" = note.id)',
-				);
-			}),
-		);
-	}
-
-	if (ps.withFiles) {
-		query.andWhere("note.fileIds != '{}'");
-	}
-	//#endregion
-
-	process.nextTick(() => {
-		activeUsersChart.read(user);
-	});
-
-	// We fetch more than requested because some may be filtered out, and if there's less than
-	// requested, the pagination stops.
-	const found = [];
-	const take = Math.floor(ps.limit * 1.5);
-	let skip = 0;
-	while (found.length < ps.limit) {
-		const notes = await query.take(take).skip(skip).getMany();
-		found.push(...(await Notes.packMany(notes, user)));
-		skip += take;
-		if (notes.length < take) break;
-	}
-
-	if (found.length > ps.limit) {
-		found.length = ps.limit;
-	}
-
-	return found;
-});
diff --git a/packages/backend/src/server/api/endpoints/notes/translate.ts b/packages/backend/src/server/api/endpoints/notes/translate.ts
deleted file mode 100644
index c6415ceef2..0000000000
--- a/packages/backend/src/server/api/endpoints/notes/translate.ts
+++ /dev/null
@@ -1,94 +0,0 @@
-import { URLSearchParams } from "node:url";
-import fetch from "node-fetch";
-import config from "@/config/index.js";
-import { getAgentByUrl } from "@/misc/fetch.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { Notes } from "@/models/index.js";
-import { ApiError } from "../../error.js";
-import { getNote } from "../../common/getters.js";
-import define from "../../define.js";
-
-export const meta = {
-	tags: ["notes"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-	},
-
-	errors: {
-		noSuchNote: {
-			message: "No such note.",
-			code: "NO_SUCH_NOTE",
-			id: "bea9b03f-36e0-49c5-a4db-627a029f8971",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		noteId: { type: "string", format: "misskey:id" },
-		targetLang: { type: "string" },
-	},
-	required: ["noteId", "targetLang"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const note = await getNote(ps.noteId, user).catch((err) => {
-		if (err.id === "9725d0ce-ba28-4dde-95a7-2cbb2c15de24")
-			throw new ApiError(meta.errors.noSuchNote);
-		throw err;
-	});
-
-	if (note.text == null) {
-		return 204;
-	}
-
-	const instance = await fetchMeta();
-
-	if (instance.deeplAuthKey == null) {
-		return 204; // TODO: 良い感じのエラー返す
-	}
-
-	let targetLang = ps.targetLang;
-	if (targetLang.includes("-")) targetLang = targetLang.split("-")[0];
-
-	const params = new URLSearchParams();
-	params.append("auth_key", instance.deeplAuthKey);
-	params.append("text", note.text);
-	params.append("target_lang", targetLang);
-
-	const endpoint = instance.deeplIsPro
-		? "https://api.deepl.com/v2/translate"
-		: "https://api-free.deepl.com/v2/translate";
-
-	const res = await fetch(endpoint, {
-		method: "POST",
-		headers: {
-			"Content-Type": "application/x-www-form-urlencoded",
-			"User-Agent": config.userAgent,
-			Accept: "application/json, */*",
-		},
-		body: params,
-		// TODO
-		//timeout: 10000,
-		agent: getAgentByUrl,
-	});
-
-	const json = (await res.json()) as {
-		translations: {
-			detected_source_language: string;
-			text: string;
-		}[];
-	};
-
-	return {
-		sourceLang: json.translations[0].detected_source_language,
-		text: json.translations[0].text,
-	};
-});
diff --git a/packages/backend/src/server/api/endpoints/notes/unrenote.ts b/packages/backend/src/server/api/endpoints/notes/unrenote.ts
deleted file mode 100644
index a30a19f190..0000000000
--- a/packages/backend/src/server/api/endpoints/notes/unrenote.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-import deleteNote from "@/services/note/delete.js";
-import { Notes, Users } from "@/models/index.js";
-import define from "../../define.js";
-import { getNote } from "../../common/getters.js";
-import { ApiError } from "../../error.js";
-import { SECOND, HOUR } from "@/const.js";
-
-export const meta = {
-	tags: ["notes"],
-
-	requireCredential: true,
-
-	kind: "write:notes",
-
-	limit: {
-		duration: HOUR,
-		max: 300,
-		minInterval: SECOND,
-	},
-
-	errors: {
-		noSuchNote: {
-			message: "No such note.",
-			code: "NO_SUCH_NOTE",
-			id: "efd4a259-2442-496b-8dd7-b255aa1a160f",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		noteId: { type: "string", format: "misskey:id" },
-	},
-	required: ["noteId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const note = await getNote(ps.noteId, user).catch((err) => {
-		if (err.id === "9725d0ce-ba28-4dde-95a7-2cbb2c15de24")
-			throw new ApiError(meta.errors.noSuchNote);
-		throw err;
-	});
-
-	const renotes = await Notes.findBy({
-		userId: user.id,
-		renoteId: note.id,
-	});
-
-	for (const note of renotes) {
-		deleteNote(await Users.findOneByOrFail({ id: user.id }), note);
-	}
-});
diff --git a/packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts b/packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts
deleted file mode 100644
index 03f5cee3f3..0000000000
--- a/packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts
+++ /dev/null
@@ -1,164 +0,0 @@
-import { Brackets } from "typeorm";
-import { UserLists, UserListJoinings, Notes } from "@/models/index.js";
-import { activeUsersChart } from "@/services/chart/index.js";
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-import { generateVisibilityQuery } from "../../common/generate-visibility-query.js";
-
-export const meta = {
-	tags: ["notes", "lists"],
-
-	requireCredential: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Note",
-		},
-	},
-
-	errors: {
-		noSuchList: {
-			message: "No such list.",
-			code: "NO_SUCH_LIST",
-			id: "8fb1fbd5-e476-4c37-9fb0-43d55b63a2ff",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		listId: { type: "string", format: "misskey:id" },
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-		sinceDate: { type: "integer" },
-		untilDate: { type: "integer" },
-		includeMyRenotes: { type: "boolean", default: true },
-		includeRenotedMyNotes: { type: "boolean", default: true },
-		includeLocalRenotes: { type: "boolean", default: true },
-		withFiles: {
-			type: "boolean",
-			default: false,
-			description: "Only show notes that have attached files.",
-		},
-	},
-	required: ["listId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const list = await UserLists.findOneBy({
-		id: ps.listId,
-		userId: user.id,
-	});
-
-	if (list == null) {
-		throw new ApiError(meta.errors.noSuchList);
-	}
-
-	//#region Construct query
-	const query = makePaginationQuery(
-		Notes.createQueryBuilder("note"),
-		ps.sinceId,
-		ps.untilId,
-	)
-		.innerJoin(
-			UserListJoinings.metadata.targetName,
-			"userListJoining",
-			"userListJoining.userId = note.userId",
-		)
-		.innerJoinAndSelect("note.user", "user")
-		.leftJoinAndSelect("user.avatar", "avatar")
-		.leftJoinAndSelect("user.banner", "banner")
-		.leftJoinAndSelect("note.reply", "reply")
-		.leftJoinAndSelect("note.renote", "renote")
-		.leftJoinAndSelect("reply.user", "replyUser")
-		.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
-		.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
-		.leftJoinAndSelect("renote.user", "renoteUser")
-		.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
-		.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner")
-		.andWhere("userListJoining.userListId = :userListId", {
-			userListId: list.id,
-		});
-
-	generateVisibilityQuery(query, user);
-
-	if (ps.includeMyRenotes === false) {
-		query.andWhere(
-			new Brackets((qb) => {
-				qb.orWhere("note.userId != :meId", { meId: user.id });
-				qb.orWhere("note.renoteId IS NULL");
-				qb.orWhere("note.text IS NOT NULL");
-				qb.orWhere("note.fileIds != '{}'");
-				qb.orWhere(
-					'0 < (SELECT COUNT(*) FROM poll WHERE poll."noteId" = note.id)',
-				);
-			}),
-		);
-	}
-
-	if (ps.includeRenotedMyNotes === false) {
-		query.andWhere(
-			new Brackets((qb) => {
-				qb.orWhere("note.renoteUserId != :meId", { meId: user.id });
-				qb.orWhere("note.renoteId IS NULL");
-				qb.orWhere("note.text IS NOT NULL");
-				qb.orWhere("note.fileIds != '{}'");
-				qb.orWhere(
-					'0 < (SELECT COUNT(*) FROM poll WHERE poll."noteId" = note.id)',
-				);
-			}),
-		);
-	}
-
-	if (ps.includeLocalRenotes === false) {
-		query.andWhere(
-			new Brackets((qb) => {
-				qb.orWhere("note.renoteUserHost IS NOT NULL");
-				qb.orWhere("note.renoteId IS NULL");
-				qb.orWhere("note.text IS NOT NULL");
-				qb.orWhere("note.fileIds != '{}'");
-				qb.orWhere(
-					'0 < (SELECT COUNT(*) FROM poll WHERE poll."noteId" = note.id)',
-				);
-			}),
-		);
-	}
-
-	if (ps.withFiles) {
-		query.andWhere("note.fileIds != '{}'");
-	}
-	//#endregion
-
-	process.nextTick(() => {
-		if (user) {
-			activeUsersChart.read(user);
-		}
-	});
-
-	// We fetch more than requested because some may be filtered out, and if there's less than
-	// requested, the pagination stops.
-	const found = [];
-	const take = Math.floor(ps.limit * 1.5);
-	let skip = 0;
-	while (found.length < ps.limit) {
-		const notes = await query.take(take).skip(skip).getMany();
-		found.push(...(await Notes.packMany(notes, user)));
-		skip += take;
-		if (notes.length < take) break;
-	}
-
-	if (found.length > ps.limit) {
-		found.length = ps.limit;
-	}
-
-	return found;
-});
diff --git a/packages/backend/src/server/api/endpoints/notes/watching/create.ts b/packages/backend/src/server/api/endpoints/notes/watching/create.ts
deleted file mode 100644
index f8921099a1..0000000000
--- a/packages/backend/src/server/api/endpoints/notes/watching/create.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import watch from "@/services/note/watch.js";
-import define from "../../../define.js";
-import { getNote } from "../../../common/getters.js";
-import { ApiError } from "../../../error.js";
-
-export const meta = {
-	tags: ["notes"],
-
-	requireCredential: true,
-
-	kind: "write:account",
-
-	errors: {
-		noSuchNote: {
-			message: "No such note.",
-			code: "NO_SUCH_NOTE",
-			id: "ea0e37a6-90a3-4f58-ba6b-c328ca206fc7",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		noteId: { type: "string", format: "misskey:id" },
-	},
-	required: ["noteId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const note = await getNote(ps.noteId, user).catch((err) => {
-		if (err.id === "9725d0ce-ba28-4dde-95a7-2cbb2c15de24")
-			throw new ApiError(meta.errors.noSuchNote);
-		throw err;
-	});
-
-	await watch(user.id, note);
-});
diff --git a/packages/backend/src/server/api/endpoints/notes/watching/delete.ts b/packages/backend/src/server/api/endpoints/notes/watching/delete.ts
deleted file mode 100644
index b441ad74b9..0000000000
--- a/packages/backend/src/server/api/endpoints/notes/watching/delete.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import unwatch from "@/services/note/unwatch.js";
-import define from "../../../define.js";
-import { getNote } from "../../../common/getters.js";
-import { ApiError } from "../../../error.js";
-
-export const meta = {
-	tags: ["notes"],
-
-	requireCredential: true,
-
-	kind: "write:account",
-
-	errors: {
-		noSuchNote: {
-			message: "No such note.",
-			code: "NO_SUCH_NOTE",
-			id: "09b3695c-f72c-4731-a428-7cff825fc82e",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		noteId: { type: "string", format: "misskey:id" },
-	},
-	required: ["noteId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const note = await getNote(ps.noteId, user).catch((err) => {
-		if (err.id === "9725d0ce-ba28-4dde-95a7-2cbb2c15de24")
-			throw new ApiError(meta.errors.noSuchNote);
-		throw err;
-	});
-
-	await unwatch(user.id, note);
-});
diff --git a/packages/backend/src/server/api/endpoints/notifications/create.ts b/packages/backend/src/server/api/endpoints/notifications/create.ts
deleted file mode 100644
index bc5723369c..0000000000
--- a/packages/backend/src/server/api/endpoints/notifications/create.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { createNotification } from "@/services/create-notification.js";
-import define from "../../define.js";
-
-export const meta = {
-	tags: ["notifications"],
-
-	requireCredential: true,
-
-	kind: "write:notifications",
-
-	errors: {},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		body: { type: "string" },
-		header: { type: "string", nullable: true },
-		icon: { type: "string", nullable: true },
-	},
-	required: ["body"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user, token) => {
-	createNotification(user.id, "app", {
-		appAccessTokenId: token ? token.id : null,
-		customBody: ps.body,
-		customHeader: ps.header,
-		customIcon: ps.icon,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/notifications/mark-all-as-read.ts b/packages/backend/src/server/api/endpoints/notifications/mark-all-as-read.ts
deleted file mode 100644
index e0888ad752..0000000000
--- a/packages/backend/src/server/api/endpoints/notifications/mark-all-as-read.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import { publishMainStream } from "@/services/stream.js";
-import { pushNotification } from "@/services/push-notification.js";
-import { Notifications } from "@/models/index.js";
-import define from "../../define.js";
-
-export const meta = {
-	tags: ["notifications", "account"],
-
-	requireCredential: true,
-
-	kind: "write:notifications",
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	// Update documents
-	await Notifications.update(
-		{
-			notifieeId: user.id,
-			isRead: false,
-		},
-		{
-			isRead: true,
-		},
-	);
-
-	// 全ての通知を読みましたよというイベントを発行
-	publishMainStream(user.id, "readAllNotifications");
-	pushNotification(user.id, "readAllNotifications", undefined);
-});
diff --git a/packages/backend/src/server/api/endpoints/notifications/read.ts b/packages/backend/src/server/api/endpoints/notifications/read.ts
deleted file mode 100644
index 9efb2fcc0b..0000000000
--- a/packages/backend/src/server/api/endpoints/notifications/read.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import define from "../../define.js";
-import { readNotification } from "../../common/read-notification.js";
-
-export const meta = {
-	tags: ["notifications", "account"],
-
-	requireCredential: true,
-
-	kind: "write:notifications",
-
-	description: "Mark a notification as read.",
-
-	errors: {
-		noSuchNotification: {
-			message: "No such notification.",
-			code: "NO_SUCH_NOTIFICATION",
-			id: "efa929d5-05b5-47d1-beec-e6a4dbed011e",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	oneOf: [
-		{
-			type: "object",
-			properties: {
-				notificationId: { type: "string", format: "misskey:id" },
-			},
-			required: ["notificationId"],
-		},
-		{
-			type: "object",
-			properties: {
-				notificationIds: {
-					type: "array",
-					items: { type: "string", format: "misskey:id" },
-					maxItems: 100,
-				},
-			},
-			required: ["notificationIds"],
-		},
-	],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	if ("notificationId" in ps)
-		return readNotification(user.id, [ps.notificationId]);
-	return readNotification(user.id, ps.notificationIds);
-});
diff --git a/packages/backend/src/server/api/endpoints/page-push.ts b/packages/backend/src/server/api/endpoints/page-push.ts
deleted file mode 100644
index a0f1e912fc..0000000000
--- a/packages/backend/src/server/api/endpoints/page-push.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-import { publishMainStream } from "@/services/stream.js";
-import { Users, Pages } from "@/models/index.js";
-import define from "../define.js";
-import { ApiError } from "../error.js";
-
-export const meta = {
-	requireCredential: true,
-	secure: true,
-
-	errors: {
-		noSuchPage: {
-			message: "No such page.",
-			code: "NO_SUCH_PAGE",
-			id: "4a13ad31-6729-46b4-b9af-e86b265c2e74",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		pageId: { type: "string", format: "misskey:id" },
-		event: { type: "string" },
-		var: {},
-	},
-	required: ["pageId", "event"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const page = await Pages.findOneBy({ id: ps.pageId });
-	if (page == null) {
-		throw new ApiError(meta.errors.noSuchPage);
-	}
-
-	publishMainStream(page.userId, "pageEvent", {
-		pageId: ps.pageId,
-		event: ps.event,
-		var: ps.var,
-		userId: user.id,
-		user: await Users.pack(
-			user.id,
-			{ id: page.userId },
-			{
-				detail: true,
-			},
-		),
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/pages/create.ts b/packages/backend/src/server/api/endpoints/pages/create.ts
deleted file mode 100644
index 716d3265cc..0000000000
--- a/packages/backend/src/server/api/endpoints/pages/create.ts
+++ /dev/null
@@ -1,123 +0,0 @@
-import { Pages, DriveFiles } from "@/models/index.js";
-import { genId } from "@/misc/gen-id.js";
-import { Page } from "@/models/entities/page.js";
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { HOUR } from "@/const.js";
-
-export const meta = {
-	tags: ["pages"],
-
-	requireCredential: true,
-
-	kind: "write:pages",
-
-	limit: {
-		duration: HOUR,
-		max: 300,
-	},
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "Page",
-	},
-
-	errors: {
-		noSuchFile: {
-			message: "No such file.",
-			code: "NO_SUCH_FILE",
-			id: "b7b97489-0f66-4b12-a5ff-b21bd63f6e1c",
-		},
-		nameAlreadyExists: {
-			message: "Specified name already exists.",
-			code: "NAME_ALREADY_EXISTS",
-			id: "4650348e-301c-499a-83c9-6aa988c66bc1",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		title: { type: "string" },
-		name: { type: "string", minLength: 1 },
-		summary: { type: "string", nullable: true },
-		content: {
-			type: "array",
-			items: {
-				type: "object",
-				additionalProperties: true,
-			},
-		},
-		variables: {
-			type: "array",
-			items: {
-				type: "object",
-				additionalProperties: true,
-			},
-		},
-		script: { type: "string" },
-		eyeCatchingImageId: {
-			type: "string",
-			format: "misskey:id",
-			nullable: true,
-		},
-		font: {
-			type: "string",
-			enum: ["serif", "sans-serif"],
-			default: "sans-serif",
-		},
-		alignCenter: { type: "boolean", default: false },
-		isPublic: { type: "boolean", default: true },
-		hideTitleWhenPinned: { type: "boolean", default: false },
-	},
-	required: ["title", "name", "content", "variables", "script"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	let eyeCatchingImage = null;
-	if (ps.eyeCatchingImageId != null) {
-		eyeCatchingImage = await DriveFiles.findOneBy({
-			id: ps.eyeCatchingImageId,
-			userId: user.id,
-		});
-
-		if (eyeCatchingImage == null) {
-			throw new ApiError(meta.errors.noSuchFile);
-		}
-	}
-
-	await Pages.findBy({
-		userId: user.id,
-		name: ps.name,
-	}).then((result) => {
-		if (result.length > 0) {
-			throw new ApiError(meta.errors.nameAlreadyExists);
-		}
-	});
-
-	const page = await Pages.insert(
-		new Page({
-			id: genId(),
-			createdAt: new Date(),
-			updatedAt: new Date(),
-			title: ps.title,
-			name: ps.name,
-			summary: ps.summary,
-			content: ps.content,
-			variables: ps.variables,
-			script: ps.script,
-			eyeCatchingImageId: eyeCatchingImage ? eyeCatchingImage.id : null,
-			userId: user.id,
-			visibility: "public",
-			alignCenter: ps.alignCenter,
-			hideTitleWhenPinned: ps.hideTitleWhenPinned,
-			font: ps.font,
-			isPublic: ps.isPublic,
-		}),
-	).then((x) => Pages.findOneByOrFail(x.identifiers[0]));
-
-	return await Pages.pack(page);
-});
diff --git a/packages/backend/src/server/api/endpoints/pages/delete.ts b/packages/backend/src/server/api/endpoints/pages/delete.ts
deleted file mode 100644
index 98b035f7c7..0000000000
--- a/packages/backend/src/server/api/endpoints/pages/delete.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import { Pages } from "@/models/index.js";
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-
-export const meta = {
-	tags: ["pages"],
-
-	requireCredential: true,
-
-	kind: "write:pages",
-
-	errors: {
-		noSuchPage: {
-			message: "No such page.",
-			code: "NO_SUCH_PAGE",
-			id: "eb0c6e1d-d519-4764-9486-52a7e1c6392a",
-		},
-
-		accessDenied: {
-			message: "Access denied.",
-			code: "ACCESS_DENIED",
-			id: "8b741b3e-2c22-44b3-a15f-29949aa1601e",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		pageId: { type: "string", format: "misskey:id" },
-	},
-	required: ["pageId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const page = await Pages.findOneBy({ id: ps.pageId });
-	if (page == null) {
-		throw new ApiError(meta.errors.noSuchPage);
-	}
-	if (page.userId !== user.id) {
-		throw new ApiError(meta.errors.accessDenied);
-	}
-
-	await Pages.delete(page.id);
-});
diff --git a/packages/backend/src/server/api/endpoints/pages/featured.ts b/packages/backend/src/server/api/endpoints/pages/featured.ts
deleted file mode 100644
index a763465897..0000000000
--- a/packages/backend/src/server/api/endpoints/pages/featured.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import { Pages } from "@/models/index.js";
-import define from "../../define.js";
-
-export const meta = {
-	tags: ["pages"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Page",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const query = Pages.createQueryBuilder("page")
-		.where("page.visibility = 'public'")
-		.andWhere("page.likedCount > 0")
-		.orderBy("page.likedCount", "DESC");
-
-	const pages = await query.take(10).getMany();
-
-	return await Pages.packMany(pages, me);
-});
diff --git a/packages/backend/src/server/api/endpoints/pages/like.ts b/packages/backend/src/server/api/endpoints/pages/like.ts
deleted file mode 100644
index f14ed39eb0..0000000000
--- a/packages/backend/src/server/api/endpoints/pages/like.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-import { Pages, PageLikes } from "@/models/index.js";
-import { genId } from "@/misc/gen-id.js";
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-
-export const meta = {
-	tags: ["pages"],
-
-	requireCredential: true,
-
-	kind: "write:page-likes",
-
-	errors: {
-		noSuchPage: {
-			message: "No such page.",
-			code: "NO_SUCH_PAGE",
-			id: "cc98a8a2-0dc3-4123-b198-62c71df18ed3",
-		},
-
-		alreadyLiked: {
-			message: "The page has already been liked.",
-			code: "ALREADY_LIKED",
-			id: "cc98a8a2-0dc3-4123-b198-62c71df18ed3",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		pageId: { type: "string", format: "misskey:id" },
-	},
-	required: ["pageId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const page = await Pages.findOneBy({ id: ps.pageId });
-	if (page == null) {
-		throw new ApiError(meta.errors.noSuchPage);
-	}
-
-	// if already liked
-	const exist = await PageLikes.findOneBy({
-		pageId: page.id,
-		userId: user.id,
-	});
-
-	if (exist != null) {
-		throw new ApiError(meta.errors.alreadyLiked);
-	}
-
-	// Create like
-	await PageLikes.insert({
-		id: genId(),
-		createdAt: new Date(),
-		pageId: page.id,
-		userId: user.id,
-	});
-
-	Pages.increment({ id: page.id }, "likedCount", 1);
-});
diff --git a/packages/backend/src/server/api/endpoints/pages/show.ts b/packages/backend/src/server/api/endpoints/pages/show.ts
deleted file mode 100644
index a25eb30b6d..0000000000
--- a/packages/backend/src/server/api/endpoints/pages/show.ts
+++ /dev/null
@@ -1,75 +0,0 @@
-import { IsNull } from "typeorm";
-import { Pages, Users } from "@/models/index.js";
-import type { Page } from "@/models/entities/page.js";
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-
-export const meta = {
-	tags: ["pages"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "Page",
-	},
-
-	errors: {
-		noSuchPage: {
-			message: "No such page.",
-			code: "NO_SUCH_PAGE",
-			id: "222120c0-3ead-4528-811b-b96f233388d7",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	anyOf: [
-		{
-			properties: {
-				pageId: { type: "string", format: "misskey:id" },
-			},
-			required: ["pageId"],
-		},
-		{
-			properties: {
-				name: { type: "string" },
-				username: { type: "string" },
-			},
-			required: ["name", "username"],
-		},
-	],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	let page: Page | null = null;
-
-	if (ps.pageId) {
-		page = await Pages.findOneBy({ id: ps.pageId });
-	} else if (ps.name && ps.username) {
-		const author = await Users.findOneBy({
-			host: IsNull(),
-			usernameLower: ps.username.toLowerCase(),
-		});
-		if (author) {
-			page = await Pages.findOneBy({
-				name: ps.name,
-				userId: author.id,
-			});
-		}
-	}
-
-	if (page == null) {
-		throw new ApiError(meta.errors.noSuchPage);
-	}
-
-	if (!page.isPublic && (user == null || page.userId !== user.id)) {
-		throw new ApiError(meta.errors.noSuchPage);
-	}
-
-	return await Pages.pack(page, user);
-});
diff --git a/packages/backend/src/server/api/endpoints/pages/unlike.ts b/packages/backend/src/server/api/endpoints/pages/unlike.ts
deleted file mode 100644
index 07bf3fbf48..0000000000
--- a/packages/backend/src/server/api/endpoints/pages/unlike.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-import { Pages, PageLikes } from "@/models/index.js";
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-
-export const meta = {
-	tags: ["pages"],
-
-	requireCredential: true,
-
-	kind: "write:page-likes",
-
-	errors: {
-		noSuchPage: {
-			message: "No such page.",
-			code: "NO_SUCH_PAGE",
-			id: "a0d41e20-1993-40bd-890e-f6e560ae648e",
-		},
-
-		notLiked: {
-			message: "You have not liked that page.",
-			code: "NOT_LIKED",
-			id: "f5e586b0-ce93-4050-b0e3-7f31af5259ee",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		pageId: { type: "string", format: "misskey:id" },
-	},
-	required: ["pageId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const page = await Pages.findOneBy({ id: ps.pageId });
-	if (page == null) {
-		throw new ApiError(meta.errors.noSuchPage);
-	}
-
-	const exist = await PageLikes.findOneBy({
-		pageId: page.id,
-		userId: user.id,
-	});
-
-	if (exist == null) {
-		throw new ApiError(meta.errors.notLiked);
-	}
-
-	// Delete like
-	await PageLikes.delete(exist.id);
-
-	Pages.decrement({ id: page.id }, "likedCount", 1);
-});
diff --git a/packages/backend/src/server/api/endpoints/pages/update.ts b/packages/backend/src/server/api/endpoints/pages/update.ts
deleted file mode 100644
index 65e1b3b2d2..0000000000
--- a/packages/backend/src/server/api/endpoints/pages/update.ts
+++ /dev/null
@@ -1,134 +0,0 @@
-import { Not } from "typeorm";
-import { Pages, DriveFiles } from "@/models/index.js";
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { HOUR } from "@/const.js";
-
-export const meta = {
-	tags: ["pages"],
-
-	requireCredential: true,
-
-	kind: "write:pages",
-
-	limit: {
-		duration: HOUR,
-		max: 300,
-	},
-
-	errors: {
-		noSuchPage: {
-			message: "No such page.",
-			code: "NO_SUCH_PAGE",
-			id: "21149b9e-3616-4778-9592-c4ce89f5a864",
-		},
-
-		accessDenied: {
-			message: "Access denied.",
-			code: "ACCESS_DENIED",
-			id: "3c15cd52-3b4b-4274-967d-6456fc4f792b",
-		},
-
-		noSuchFile: {
-			message: "No such file.",
-			code: "NO_SUCH_FILE",
-			id: "cfc23c7c-3887-490e-af30-0ed576703c82",
-		},
-		nameAlreadyExists: {
-			message: "Specified name already exists.",
-			code: "NAME_ALREADY_EXISTS",
-			id: "2298a392-d4a1-44c5-9ebb-ac1aeaa5a9ab",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		pageId: { type: "string", format: "misskey:id" },
-		title: { type: "string" },
-		name: { type: "string", minLength: 1 },
-		summary: { type: "string", nullable: true },
-		content: {
-			type: "array",
-			items: {
-				type: "object",
-				additionalProperties: true,
-			},
-		},
-		variables: {
-			type: "array",
-			items: {
-				type: "object",
-				additionalProperties: true,
-			},
-		},
-		script: { type: "string" },
-		eyeCatchingImageId: {
-			type: "string",
-			format: "misskey:id",
-			nullable: true,
-		},
-		font: { type: "string", enum: ["serif", "sans-serif"] },
-		alignCenter: { type: "boolean" },
-		hideTitleWhenPinned: { type: "boolean" },
-		isPublic: { type: "boolean" },
-	},
-	required: ["pageId", "title", "name", "content", "variables", "script"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const page = await Pages.findOneBy({ id: ps.pageId });
-	if (page == null) {
-		throw new ApiError(meta.errors.noSuchPage);
-	}
-	if (page.userId !== user.id) {
-		throw new ApiError(meta.errors.accessDenied);
-	}
-
-	let eyeCatchingImage = null;
-	if (ps.eyeCatchingImageId != null) {
-		eyeCatchingImage = await DriveFiles.findOneBy({
-			id: ps.eyeCatchingImageId,
-			userId: user.id,
-		});
-
-		if (eyeCatchingImage == null) {
-			throw new ApiError(meta.errors.noSuchFile);
-		}
-	}
-
-	await Pages.findBy({
-		id: Not(ps.pageId),
-		userId: user.id,
-		name: ps.name,
-	}).then((result) => {
-		if (result.length > 0) {
-			throw new ApiError(meta.errors.nameAlreadyExists);
-		}
-	});
-
-	await Pages.update(page.id, {
-		updatedAt: new Date(),
-		title: ps.title,
-		name: ps.name === undefined ? page.name : ps.name,
-		summary: ps.name === undefined ? page.summary : ps.summary,
-		content: ps.content,
-		variables: ps.variables,
-		script: ps.script,
-		isPublic: ps.isPublic,
-		alignCenter:
-			ps.alignCenter === undefined ? page.alignCenter : ps.alignCenter,
-		hideTitleWhenPinned:
-			ps.hideTitleWhenPinned === undefined
-				? page.hideTitleWhenPinned
-				: ps.hideTitleWhenPinned,
-		font: ps.font === undefined ? page.font : ps.font,
-		eyeCatchingImageId:
-			ps.eyeCatchingImageId === null
-				? null
-				: ps.eyeCatchingImageId === undefined
-				? page.eyeCatchingImageId
-				: eyeCatchingImage!.id,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/patrons.ts b/packages/backend/src/server/api/endpoints/patrons.ts
deleted file mode 100644
index d6ac6c3971..0000000000
--- a/packages/backend/src/server/api/endpoints/patrons.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import define from "../define.js";
-
-export const meta = {
-	tags: ["meta"],
-	description: "Get list of Calckey patrons from Codeberg",
-
-	requireCredential: false,
-	requireCredentialPrivateMode: false,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async () => {
-	let patrons;
-	await fetch(
-		"https://codeberg.org/calckey/calckey/raw/branch/develop/patrons.json",
-	)
-		.then((response) => response.json())
-		.then((data) => {
-			patrons = data["patrons"];
-		});
-
-	return patrons;
-});
diff --git a/packages/backend/src/server/api/endpoints/ping.ts b/packages/backend/src/server/api/endpoints/ping.ts
deleted file mode 100644
index c1f7e110bc..0000000000
--- a/packages/backend/src/server/api/endpoints/ping.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import define from "../define.js";
-
-export const meta = {
-	requireCredential: false,
-
-	tags: ["meta"],
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		properties: {
-			pong: {
-				type: "number",
-				optional: false,
-				nullable: false,
-			},
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async () => {
-	return {
-		pong: Date.now(),
-	};
-});
diff --git a/packages/backend/src/server/api/endpoints/pinned-users.ts b/packages/backend/src/server/api/endpoints/pinned-users.ts
deleted file mode 100644
index 22020068ce..0000000000
--- a/packages/backend/src/server/api/endpoints/pinned-users.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-import { IsNull } from "typeorm";
-import { Users } from "@/models/index.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import * as Acct from "@/misc/acct.js";
-import type { User } from "@/models/entities/user.js";
-import define from "../define.js";
-
-export const meta = {
-	tags: ["users"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: false,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "UserDetailed",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const meta = await fetchMeta();
-
-	const users = await Promise.all(
-		meta.pinnedUsers
-			.map((acct) => Acct.parse(acct))
-			.map((acct) =>
-				Users.findOneBy({
-					usernameLower: acct.username.toLowerCase(),
-					host: acct.host ?? IsNull(),
-				}),
-			),
-	);
-
-	return await Users.packMany(
-		users.filter((x) => x !== undefined) as User[],
-		me,
-		{ detail: true },
-	);
-});
diff --git a/packages/backend/src/server/api/endpoints/promo/read.ts b/packages/backend/src/server/api/endpoints/promo/read.ts
deleted file mode 100644
index 09c8cb6fab..0000000000
--- a/packages/backend/src/server/api/endpoints/promo/read.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import { PromoReads } from "@/models/index.js";
-import { genId } from "@/misc/gen-id.js";
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { getNote } from "../../common/getters.js";
-
-export const meta = {
-	tags: ["notes"],
-
-	requireCredential: true,
-
-	errors: {
-		noSuchNote: {
-			message: "No such note.",
-			code: "NO_SUCH_NOTE",
-			id: "d785b897-fcd3-4fe9-8fc3-b85c26e6c932",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		noteId: { type: "string", format: "misskey:id" },
-	},
-	required: ["noteId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const note = await getNote(ps.noteId, user).catch((err) => {
-		if (err.id === "9725d0ce-ba28-4dde-95a7-2cbb2c15de24")
-			throw new ApiError(meta.errors.noSuchNote);
-		throw err;
-	});
-
-	const exist = await PromoReads.findOneBy({
-		noteId: note.id,
-		userId: user.id,
-	});
-
-	if (exist != null) {
-		return;
-	}
-
-	await PromoReads.insert({
-		id: genId(),
-		createdAt: new Date(),
-		noteId: note.id,
-		userId: user.id,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/recommended-instances.ts b/packages/backend/src/server/api/endpoints/recommended-instances.ts
deleted file mode 100644
index 8407afb1d3..0000000000
--- a/packages/backend/src/server/api/endpoints/recommended-instances.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-// import { IsNull } from 'typeorm';
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import define from "../define.js";
-
-export const meta = {
-	tags: ["meta"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "string",
-			optional: false,
-			nullable: false,
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async () => {
-	const meta = await fetchMeta();
-	const instances = await Promise.all(meta.recommendedInstances.map((x) => x));
-	return instances;
-});
diff --git a/packages/backend/src/server/api/endpoints/release.ts b/packages/backend/src/server/api/endpoints/release.ts
deleted file mode 100644
index e5ebbb79a6..0000000000
--- a/packages/backend/src/server/api/endpoints/release.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import define from "../define.js";
-
-export const meta = {
-	tags: ["meta"],
-	description: "Get release notes from Codeberg",
-
-	requireCredential: false,
-	requireCredentialPrivateMode: false,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async () => {
-	let release;
-
-	await fetch(
-		"https://codeberg.org/calckey/calckey/raw/branch/develop/release.json",
-	)
-		.then((response) => response.json())
-		.then((data) => {
-			release = data;
-		});
-	return release;
-});
diff --git a/packages/backend/src/server/api/endpoints/renote-mute/create.ts b/packages/backend/src/server/api/endpoints/renote-mute/create.ts
deleted file mode 100644
index 857cbd9756..0000000000
--- a/packages/backend/src/server/api/endpoints/renote-mute/create.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-import { genId } from "@/misc/gen-id.js";
-import { RenoteMutings } from "@/models/index.js";
-import { RenoteMuting } from "@/models/entities/renote-muting.js";
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { getUser } from "../../common/getters.js";
-
-export const meta = {
-	tags: ["account"],
-
-	requireCredential: true,
-
-	kind: "write:mutes",
-
-	errors: {
-		noSuchUser: {
-			message: "No such user.",
-			code: "NO_SUCH_USER",
-			id: "6fef56f3-e765-4957-88e5-c6f65329b8a5",
-		},
-
-		alreadyMuting: {
-			message: "You are already muting that user.",
-			code: "ALREADY_MUTING",
-			id: "7e7359cb-160c-4956-b08f-4d1c653cd007",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		userId: { type: "string", format: "misskey:id" },
-	},
-	required: ["userId"],
-} as const;
-
-// eslint-disable-next-line import/no-default-export
-export default define(meta, paramDef, async (ps, user) => {
-	const muter = user;
-
-	// Get mutee
-	const mutee = await getUser(ps.userId).catch((e) => {
-		if (e.id === "15348ddd-432d-49c2-8a5a-8069753becff")
-			throw new ApiError(meta.errors.noSuchUser);
-		throw e;
-	});
-
-	// Check if already muting
-	const exist = await RenoteMutings.findOneBy({
-		muterId: muter.id,
-		muteeId: mutee.id,
-	});
-
-	if (exist != null) {
-		throw new ApiError(meta.errors.alreadyMuting);
-	}
-
-	// Create mute
-	await RenoteMutings.insert({
-		id: genId(),
-		createdAt: new Date(),
-		muterId: muter.id,
-		muteeId: mutee.id,
-	} as RenoteMuting);
-
-	// publishUserEvent(user.id, "mute", mutee);
-});
diff --git a/packages/backend/src/server/api/endpoints/renote-mute/delete.ts b/packages/backend/src/server/api/endpoints/renote-mute/delete.ts
deleted file mode 100644
index fb4c972af0..0000000000
--- a/packages/backend/src/server/api/endpoints/renote-mute/delete.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-import { RenoteMutings } from "@/models/index.js";
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { getUser } from "../../common/getters.js";
-
-export const meta = {
-	tags: ["account"],
-
-	requireCredential: true,
-
-	kind: "write:mutes",
-
-	errors: {
-		noSuchUser: {
-			message: "No such user.",
-			code: "NO_SUCH_USER",
-			id: "b851d00b-8ab1-4a56-8b1b-e24187cb48ef",
-		},
-
-		notMuting: {
-			message: "You are not muting that user.",
-			code: "NOT_MUTING",
-			id: "5467d020-daa9-4553-81e1-135c0c35a96d",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		userId: { type: "string", format: "misskey:id" },
-	},
-	required: ["userId"],
-} as const;
-
-// eslint-disable-next-line import/no-default-export
-export default define(meta, paramDef, async (ps, user) => {
-	const muter = user;
-
-	// Get mutee
-	const mutee = await getUser(ps.userId).catch((e) => {
-		if (e.id === "15348ddd-432d-49c2-8a5a-8069753becff")
-			throw new ApiError(meta.errors.noSuchUser);
-		throw e;
-	});
-
-	// Check not muting
-	const exist = await RenoteMutings.findOneBy({
-		muterId: muter.id,
-		muteeId: mutee.id,
-	});
-
-	if (exist == null) {
-		throw new ApiError(meta.errors.notMuting);
-	}
-
-	// Delete mute
-	await RenoteMutings.delete({
-		id: exist.id,
-	});
-
-	// publishUserEvent(user.id, "unmute", mutee);
-});
diff --git a/packages/backend/src/server/api/endpoints/renote-mute/list.ts b/packages/backend/src/server/api/endpoints/renote-mute/list.ts
deleted file mode 100644
index 9149dd9753..0000000000
--- a/packages/backend/src/server/api/endpoints/renote-mute/list.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import { RenoteMutings } from "@/models/index.js";
-import define from "../../define.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-
-export const meta = {
-	tags: ["account"],
-
-	requireCredential: true,
-
-	kind: "read:mutes",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "RenoteMuting",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 30 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-	},
-	required: [],
-} as const;
-
-// eslint-disable-next-line import/no-default-export
-export default define(meta, paramDef, async (ps, me) => {
-	const query = makePaginationQuery(
-		RenoteMutings.createQueryBuilder("muting"),
-		ps.sinceId,
-		ps.untilId,
-	).andWhere("muting.muterId = :meId", { meId: me.id });
-
-	const mutings = await query.take(ps.limit).getMany();
-
-	return await RenoteMutings.packMany(mutings, me);
-});
diff --git a/packages/backend/src/server/api/endpoints/request-reset-password.ts b/packages/backend/src/server/api/endpoints/request-reset-password.ts
deleted file mode 100644
index bac564c1d6..0000000000
--- a/packages/backend/src/server/api/endpoints/request-reset-password.ts
+++ /dev/null
@@ -1,76 +0,0 @@
-import rndstr from "rndstr";
-import { IsNull } from "typeorm";
-import { publishMainStream } from "@/services/stream.js";
-import config from "@/config/index.js";
-import { Users, UserProfiles, PasswordResetRequests } from "@/models/index.js";
-import { sendEmail } from "@/services/send-email.js";
-import { genId } from "@/misc/gen-id.js";
-import { ApiError } from "../error.js";
-import define from "../define.js";
-import { HOUR } from "@/const.js";
-
-export const meta = {
-	tags: ["reset password"],
-
-	requireCredential: false,
-
-	description: "Request a users password to be reset.",
-
-	limit: {
-		duration: HOUR,
-		max: 3,
-	},
-
-	errors: {},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		username: { type: "string" },
-		email: { type: "string" },
-	},
-	required: ["username", "email"],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	const user = await Users.findOneBy({
-		usernameLower: ps.username.toLowerCase(),
-		host: IsNull(),
-	});
-
-	// 合致するユーザーが登録されていなかったら無視
-	if (user == null) {
-		return;
-	}
-
-	const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
-
-	// 合致するメアドが登録されていなかったら無視
-	if (profile.email !== ps.email) {
-		return;
-	}
-
-	// メアドが認証されていなかったら無視
-	if (!profile.emailVerified) {
-		return;
-	}
-
-	const token = rndstr("a-z0-9", 64);
-
-	await PasswordResetRequests.insert({
-		id: genId(),
-		createdAt: new Date(),
-		userId: profile.userId,
-		token,
-	});
-
-	const link = `${config.url}/reset-password/${token}`;
-
-	sendEmail(
-		ps.email,
-		"Password reset requested",
-		`To reset password, please click this link:<br><a href="${link}">${link}</a>`,
-		`To reset password, please click this link: ${link}`,
-	);
-});
diff --git a/packages/backend/src/server/api/endpoints/reset-db.ts b/packages/backend/src/server/api/endpoints/reset-db.ts
deleted file mode 100644
index c64db7bca8..0000000000
--- a/packages/backend/src/server/api/endpoints/reset-db.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import { resetDb } from "@/db/postgre.js";
-import define from "../define.js";
-import { ApiError } from "../error.js";
-
-export const meta = {
-	tags: ["non-productive"],
-
-	requireCredential: false,
-
-	description:
-		"Only available when running with <code>NODE_ENV=testing</code>. Reset the database and flush Redis.",
-
-	errors: {},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	if (process.env.NODE_ENV !== "test")
-		throw new Error("NODE_ENV is not a test");
-
-	await resetDb();
-
-	await new Promise((resolve) => setTimeout(resolve, 1000));
-});
diff --git a/packages/backend/src/server/api/endpoints/reset-password.ts b/packages/backend/src/server/api/endpoints/reset-password.ts
deleted file mode 100644
index f695ae41f1..0000000000
--- a/packages/backend/src/server/api/endpoints/reset-password.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import { publishMainStream } from "@/services/stream.js";
-import { Users, UserProfiles, PasswordResetRequests } from "@/models/index.js";
-import define from "../define.js";
-import { ApiError } from "../error.js";
-import { hashPassword } from "@/misc/password.js";
-
-export const meta = {
-	tags: ["reset password"],
-
-	requireCredential: false,
-
-	description: "Complete the password reset that was previously requested.",
-
-	errors: {},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		token: { type: "string" },
-		password: { type: "string" },
-	},
-	required: ["token", "password"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const req = await PasswordResetRequests.findOneByOrFail({
-		token: ps.token,
-	});
-
-	// 発行してから30分以上経過していたら無効
-	if (Date.now() - req.createdAt.getTime() > 1000 * 60 * 30) {
-		throw new Error(); // TODO
-	}
-
-	// Generate hash of password
-	const hash = await hashPassword(ps.password);
-
-	await UserProfiles.update(req.userId, {
-		password: hash,
-	});
-
-	PasswordResetRequests.delete(req.id);
-});
diff --git a/packages/backend/src/server/api/endpoints/server-info.ts b/packages/backend/src/server/api/endpoints/server-info.ts
deleted file mode 100644
index 1ce27e2621..0000000000
--- a/packages/backend/src/server/api/endpoints/server-info.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import * as os from "node:os";
-import si from "systeminformation";
-import define from "../define.js";
-
-export const meta = {
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	tags: ["meta"],
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async () => {
-	const memStats = await si.mem();
-	const fsStats = await si.fsSize();
-
-	return {
-		machine: os.hostname(),
-		cpu: {
-			model: os.cpus()[0].model,
-			cores: os.cpus().length,
-		},
-		mem: {
-			total: memStats.total,
-		},
-		fs: {
-			total: fsStats[0].size,
-			used: fsStats[0].used,
-		},
-	};
-});
diff --git a/packages/backend/src/server/api/endpoints/stats.ts b/packages/backend/src/server/api/endpoints/stats.ts
deleted file mode 100644
index 8bd5597689..0000000000
--- a/packages/backend/src/server/api/endpoints/stats.ts
+++ /dev/null
@@ -1,92 +0,0 @@
-import { Instances, NoteReactions, Notes, Users } from "@/models/index.js";
-import define from "../define.js";
-import {} from "@/services/chart/index.js";
-import { IsNull } from "typeorm";
-
-export const meta = {
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	tags: ["meta"],
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		properties: {
-			notesCount: {
-				type: "number",
-				optional: false,
-				nullable: false,
-			},
-			originalNotesCount: {
-				type: "number",
-				optional: false,
-				nullable: false,
-			},
-			usersCount: {
-				type: "number",
-				optional: false,
-				nullable: false,
-			},
-			originalUsersCount: {
-				type: "number",
-				optional: false,
-				nullable: false,
-			},
-			instances: {
-				type: "number",
-				optional: false,
-				nullable: false,
-			},
-			driveUsageLocal: {
-				type: "number",
-				optional: false,
-				nullable: false,
-			},
-			driveUsageRemote: {
-				type: "number",
-				optional: false,
-				nullable: false,
-			},
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async () => {
-	const [
-		notesCount,
-		originalNotesCount,
-		usersCount,
-		originalUsersCount,
-		reactionsCount,
-		//originalReactionsCount,
-		instances,
-	] = await Promise.all([
-		Notes.count({ cache: 3600000 }), // 1 hour
-		Notes.count({ where: { userHost: IsNull() }, cache: 3600000 }),
-		Users.count({ cache: 3600000 }),
-		Users.count({ where: { host: IsNull() }, cache: 3600000 }),
-		NoteReactions.count({ cache: 3600000 }), // 1 hour
-		//NoteReactions.count({ where: { userHost: IsNull() }, cache: 3600000 }),
-		Instances.count({ cache: 3600000 }),
-	]);
-
-	return {
-		notesCount,
-		originalNotesCount,
-		usersCount,
-		originalUsersCount,
-		reactionsCount,
-		//originalReactionsCount,
-		instances,
-		driveUsageLocal: 0,
-		driveUsageRemote: 0,
-	};
-});
diff --git a/packages/backend/src/server/api/endpoints/sw/register.ts b/packages/backend/src/server/api/endpoints/sw/register.ts
deleted file mode 100644
index 42a35fb685..0000000000
--- a/packages/backend/src/server/api/endpoints/sw/register.ts
+++ /dev/null
@@ -1,97 +0,0 @@
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { genId } from "@/misc/gen-id.js";
-import { SwSubscriptions } from "@/models/index.js";
-import define from "../../define.js";
-
-export const meta = {
-	tags: ["account"],
-
-	requireCredential: true,
-
-	description: "Register to receive push notifications.",
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		properties: {
-			state: {
-				type: "string",
-				optional: true,
-				nullable: false,
-				enum: ["already-subscribed", "subscribed"],
-			},
-			key: {
-				type: "string",
-				optional: false,
-				nullable: true,
-			},
-			userId: {
-				type: "string",
-				optional: false,
-				nullable: false,
-			},
-			endpoint: {
-				type: "string",
-				optional: false,
-				nullable: false,
-			},
-			sendReadMessage: {
-				type: "boolean",
-				optional: false,
-				nullable: false,
-			},
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		endpoint: { type: "string" },
-		auth: { type: "string" },
-		publickey: { type: "string" },
-		sendReadMessage: { type: "boolean", default: false },
-	},
-	required: ["endpoint", "auth", "publickey"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	// if already subscribed
-	const exist = await SwSubscriptions.findOneBy({
-		userId: me.id,
-		endpoint: ps.endpoint,
-		auth: ps.auth,
-		publickey: ps.publickey,
-	});
-
-	const instance = await fetchMeta(true);
-
-	if (exist != null) {
-		return {
-			state: "already-subscribed" as const,
-			key: instance.swPublicKey,
-			userId: me.id,
-			endpoint: exist.endpoint,
-			sendReadMessage: exist.sendReadMessage,
-		};
-	}
-
-	await SwSubscriptions.insert({
-		id: genId(),
-		createdAt: new Date(),
-		userId: me.id,
-		endpoint: ps.endpoint,
-		auth: ps.auth,
-		publickey: ps.publickey,
-		sendReadMessage: ps.sendReadMessage,
-	});
-
-	return {
-		state: "subscribed" as const,
-		key: instance.swPublicKey,
-		userId: me.id,
-		endpoint: ps.endpoint,
-		sendReadMessage: ps.sendReadMessage,
-	};
-});
diff --git a/packages/backend/src/server/api/endpoints/sw/show-registration.ts b/packages/backend/src/server/api/endpoints/sw/show-registration.ts
deleted file mode 100644
index c7a9609cff..0000000000
--- a/packages/backend/src/server/api/endpoints/sw/show-registration.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import { SwSubscriptions } from "@/models/index.js";
-import define from "../../define.js";
-
-export const meta = {
-	tags: ["account"],
-
-	requireCredential: true,
-
-	description: "Check push notification registration exists.",
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: true,
-		properties: {
-			userId: {
-				type: "string",
-				optional: false,
-				nullable: false,
-			},
-			endpoint: {
-				type: "string",
-				optional: false,
-				nullable: false,
-			},
-			sendReadMessage: {
-				type: "boolean",
-				optional: false,
-				nullable: false,
-			},
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		endpoint: { type: "string" },
-	},
-	required: ["endpoint"],
-} as const;
-
-// eslint-disable-next-line import/no-default-export
-export default define(meta, paramDef, async (ps, me) => {
-	const exist = await SwSubscriptions.findOneBy({
-		userId: me.id,
-		endpoint: ps.endpoint,
-	});
-
-	if (exist != null) {
-		return {
-			userId: exist.userId,
-			endpoint: exist.endpoint,
-			sendReadMessage: exist.sendReadMessage,
-		};
-	}
-
-	return null;
-});
diff --git a/packages/backend/src/server/api/endpoints/sw/unregister.ts b/packages/backend/src/server/api/endpoints/sw/unregister.ts
deleted file mode 100644
index e2a40f51cb..0000000000
--- a/packages/backend/src/server/api/endpoints/sw/unregister.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { SwSubscriptions } from "@/models/index.js";
-import define from "../../define.js";
-
-export const meta = {
-	tags: ["account"],
-
-	requireCredential: false,
-
-	description: "Unregister from receiving push notifications.",
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		endpoint: { type: "string" },
-	},
-	required: ["endpoint"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	await SwSubscriptions.delete({
-		...(me ? { userId: me.id } : {}),
-		endpoint: ps.endpoint,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/sw/update-registration.ts b/packages/backend/src/server/api/endpoints/sw/update-registration.ts
deleted file mode 100644
index 5ba53ee8a7..0000000000
--- a/packages/backend/src/server/api/endpoints/sw/update-registration.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import { SwSubscriptions } from "@/models/index.js";
-import define from "../../define.js";
-
-export const meta = {
-	tags: ["account"],
-
-	requireCredential: true,
-
-	description: "Unregister from receiving push notifications.",
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		endpoint: { type: "string" },
-		sendReadMessage: { type: "boolean" },
-	},
-	required: ["endpoint"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const swSubscription = await SwSubscriptions.findOneBy({
-		userId: me.id,
-		endpoint: ps.endpoint,
-	});
-
-	if (swSubscription === null) {
-		throw new Error("No such registration");
-	}
-
-	if (ps.sendReadMessage !== undefined) {
-		swSubscription.sendReadMessage = ps.sendReadMessage;
-	}
-
-	await SwSubscriptions.update(swSubscription.id, {
-		sendReadMessage: swSubscription.sendReadMessage,
-	});
-
-	return {
-		userId: swSubscription.userId,
-		endpoint: swSubscription.endpoint,
-		sendReadMessage: swSubscription.sendReadMessage,
-	};
-});
diff --git a/packages/backend/src/server/api/endpoints/test.ts b/packages/backend/src/server/api/endpoints/test.ts
deleted file mode 100644
index 2c43c61152..0000000000
--- a/packages/backend/src/server/api/endpoints/test.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import define from "../define.js";
-
-export const meta = {
-	tags: ["non-productive"],
-
-	description: "Endpoint for testing input validation.",
-
-	requireCredential: false,
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		required: { type: "boolean" },
-		string: { type: "string" },
-		default: { type: "string", default: "hello" },
-		nullableDefault: { type: "string", nullable: true, default: "hello" },
-		id: { type: "string", format: "misskey:id" },
-	},
-	required: ["required"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	return ps;
-});
diff --git a/packages/backend/src/server/api/endpoints/username/available.ts b/packages/backend/src/server/api/endpoints/username/available.ts
deleted file mode 100644
index f5aa4ed1ea..0000000000
--- a/packages/backend/src/server/api/endpoints/username/available.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import { IsNull } from "typeorm";
-import { Users, UsedUsernames } from "@/models/index.js";
-import define from "../../define.js";
-
-export const meta = {
-	tags: ["users"],
-
-	requireCredential: false,
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		properties: {
-			available: {
-				type: "boolean",
-				optional: false,
-				nullable: false,
-			},
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		username: Users.localUsernameSchema,
-	},
-	required: ["username"],
-} as const;
-
-export default define(meta, paramDef, async (ps) => {
-	// Get exist
-	const exist = await Users.countBy({
-		host: IsNull(),
-		usernameLower: ps.username.toLowerCase(),
-	});
-
-	const exist2 = await UsedUsernames.countBy({
-		username: ps.username.toLowerCase(),
-	});
-
-	return {
-		available: exist === 0 && exist2 === 0,
-	};
-});
diff --git a/packages/backend/src/server/api/endpoints/users.ts b/packages/backend/src/server/api/endpoints/users.ts
deleted file mode 100644
index f0a8670902..0000000000
--- a/packages/backend/src/server/api/endpoints/users.ts
+++ /dev/null
@@ -1,134 +0,0 @@
-import { Users } from "@/models/index.js";
-import define from "../define.js";
-import { generateMutedUserQueryForUsers } from "../common/generate-muted-user-query.js";
-import { generateBlockQueryForUsers } from "../common/generate-block-query.js";
-
-export const meta = {
-	tags: ["users"],
-
-	requireCredential: true,
-	requireCredentialPrivateMode: true,
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "UserDetailed",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		offset: { type: "integer", default: 0 },
-		sort: {
-			type: "string",
-			enum: [
-				"+follower",
-				"-follower",
-				"+createdAt",
-				"-createdAt",
-				"+updatedAt",
-				"-updatedAt",
-			],
-		},
-		state: {
-			type: "string",
-			enum: ["all", "admin", "moderator", "adminOrModerator", "alive"],
-			default: "all",
-		},
-		origin: {
-			type: "string",
-			enum: ["combined", "local", "remote"],
-			default: "local",
-		},
-		hostname: {
-			type: "string",
-			nullable: true,
-			default: null,
-			description: "The local host is represented with `null`.",
-		},
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const query = Users.createQueryBuilder("user");
-	query.where("user.isExplorable = TRUE");
-
-	switch (ps.state) {
-		case "admin":
-			query.andWhere("user.isAdmin = TRUE");
-			break;
-		case "moderator":
-			query.andWhere("user.isModerator = TRUE");
-			break;
-		case "adminOrModerator":
-			query.andWhere("user.isAdmin = TRUE OR user.isModerator = TRUE");
-			break;
-		case "alive":
-			query.andWhere("user.updatedAt > :date", {
-				date: new Date(Date.now() - 1000 * 60 * 60 * 24 * 5),
-			});
-			break;
-	}
-
-	switch (ps.origin) {
-		case "local":
-			query.andWhere("user.host IS NULL");
-			break;
-		case "remote":
-			query.andWhere("user.host IS NOT NULL");
-			break;
-	}
-
-	if (ps.hostname) {
-		query.andWhere("user.host = :hostname", {
-			hostname: ps.hostname.toLowerCase(),
-		});
-	}
-
-	switch (ps.sort) {
-		case "+follower":
-			query.orderBy("user.followersCount", "DESC");
-			break;
-		case "-follower":
-			query.orderBy("user.followersCount", "ASC");
-			break;
-		case "+createdAt":
-			query.orderBy("user.createdAt", "DESC");
-			break;
-		case "-createdAt":
-			query.orderBy("user.createdAt", "ASC");
-			break;
-		case "+updatedAt":
-			query
-				.andWhere("user.updatedAt IS NOT NULL")
-				.orderBy("user.updatedAt", "DESC");
-			break;
-		case "-updatedAt":
-			query
-				.andWhere("user.updatedAt IS NOT NULL")
-				.orderBy("user.updatedAt", "ASC");
-			break;
-		default:
-			query.orderBy("user.id", "ASC");
-			break;
-	}
-
-	if (me) generateMutedUserQueryForUsers(query, me);
-	if (me) generateBlockQueryForUsers(query, me);
-
-	query.take(ps.limit);
-	query.skip(ps.offset);
-
-	const users = await query.getMany();
-
-	return await Users.packMany(users, me, { detail: true });
-});
diff --git a/packages/backend/src/server/api/endpoints/users/clips.ts b/packages/backend/src/server/api/endpoints/users/clips.ts
deleted file mode 100644
index 0dc90b8f99..0000000000
--- a/packages/backend/src/server/api/endpoints/users/clips.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import { Clips } from "@/models/index.js";
-import define from "../../define.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-
-export const meta = {
-	tags: ["users", "clips"],
-	requireCredentialPrivateMode: true,
-
-	description: "Show all clips this user owns.",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Clip",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		userId: { type: "string", format: "misskey:id" },
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-	},
-	required: ["userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const query = makePaginationQuery(
-		Clips.createQueryBuilder("clip"),
-		ps.sinceId,
-		ps.untilId,
-	)
-		.andWhere("clip.userId = :userId", { userId: ps.userId })
-		.andWhere("clip.isPublic = true");
-
-	const clips = await query.take(ps.limit).getMany();
-
-	return await Clips.packMany(clips);
-});
diff --git a/packages/backend/src/server/api/endpoints/users/followers.ts b/packages/backend/src/server/api/endpoints/users/followers.ts
deleted file mode 100644
index 138343d9f4..0000000000
--- a/packages/backend/src/server/api/endpoints/users/followers.ts
+++ /dev/null
@@ -1,116 +0,0 @@
-import { IsNull } from "typeorm";
-import { Users, Followings, UserProfiles } from "@/models/index.js";
-import { toPunyNullable } from "@/misc/convert-host.js";
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-
-export const meta = {
-	tags: ["users"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	description: "Show everyone that follows this user.",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Following",
-		},
-	},
-
-	errors: {
-		noSuchUser: {
-			message: "No such user.",
-			code: "NO_SUCH_USER",
-			id: "27fa5435-88ab-43de-9360-387de88727cd",
-		},
-
-		forbidden: {
-			message: "Forbidden.",
-			code: "FORBIDDEN",
-			id: "3c6a84db-d619-26af-ca14-06232a21df8a",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-	},
-	anyOf: [
-		{
-			properties: {
-				userId: { type: "string", format: "misskey:id" },
-			},
-			required: ["userId"],
-		},
-		{
-			properties: {
-				username: { type: "string" },
-				host: {
-					type: "string",
-					nullable: true,
-					description: "The local host is represented with `null`.",
-				},
-			},
-			required: ["username", "host"],
-		},
-	],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const user = await Users.findOneBy(
-		ps.userId != null
-			? { id: ps.userId }
-			: {
-					usernameLower: ps.username!.toLowerCase(),
-					host: toPunyNullable(ps.host) ?? IsNull(),
-			  },
-	);
-
-	if (user == null) {
-		throw new ApiError(meta.errors.noSuchUser);
-	}
-
-	const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
-
-	if (profile.ffVisibility === "private") {
-		if (me == null || me.id !== user.id) {
-			throw new ApiError(meta.errors.forbidden);
-		}
-	} else if (profile.ffVisibility === "followers") {
-		if (me == null) {
-			throw new ApiError(meta.errors.forbidden);
-		} else if (me.id !== user.id) {
-			const following = await Followings.findOneBy({
-				followeeId: user.id,
-				followerId: me.id,
-			});
-			if (following == null) {
-				throw new ApiError(meta.errors.forbidden);
-			}
-		}
-	}
-
-	const query = makePaginationQuery(
-		Followings.createQueryBuilder("following"),
-		ps.sinceId,
-		ps.untilId,
-	)
-		.andWhere("following.followeeId = :userId", { userId: user.id })
-		.innerJoinAndSelect("following.follower", "follower");
-
-	const followings = await query.take(ps.limit).getMany();
-
-	return await Followings.packMany(followings, me, { populateFollower: true });
-});
diff --git a/packages/backend/src/server/api/endpoints/users/following.ts b/packages/backend/src/server/api/endpoints/users/following.ts
deleted file mode 100644
index 967379d0c4..0000000000
--- a/packages/backend/src/server/api/endpoints/users/following.ts
+++ /dev/null
@@ -1,116 +0,0 @@
-import { IsNull } from "typeorm";
-import { Users, Followings, UserProfiles } from "@/models/index.js";
-import { toPunyNullable } from "@/misc/convert-host.js";
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-
-export const meta = {
-	tags: ["users"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	description: "Show everyone that this user is following.",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Following",
-		},
-	},
-
-	errors: {
-		noSuchUser: {
-			message: "No such user.",
-			code: "NO_SUCH_USER",
-			id: "63e4aba4-4156-4e53-be25-c9559e42d71b",
-		},
-
-		forbidden: {
-			message: "Forbidden.",
-			code: "FORBIDDEN",
-			id: "f6cdb0df-c19f-ec5c-7dbb-0ba84a1f92ba",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-	},
-	anyOf: [
-		{
-			properties: {
-				userId: { type: "string", format: "misskey:id" },
-			},
-			required: ["userId"],
-		},
-		{
-			properties: {
-				username: { type: "string" },
-				host: {
-					type: "string",
-					nullable: true,
-					description: "The local host is represented with `null`.",
-				},
-			},
-			required: ["username", "host"],
-		},
-	],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const user = await Users.findOneBy(
-		ps.userId != null
-			? { id: ps.userId }
-			: {
-					usernameLower: ps.username!.toLowerCase(),
-					host: toPunyNullable(ps.host) ?? IsNull(),
-			  },
-	);
-
-	if (user == null) {
-		throw new ApiError(meta.errors.noSuchUser);
-	}
-
-	const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
-
-	if (profile.ffVisibility === "private") {
-		if (me == null || me.id !== user.id) {
-			throw new ApiError(meta.errors.forbidden);
-		}
-	} else if (profile.ffVisibility === "followers") {
-		if (me == null) {
-			throw new ApiError(meta.errors.forbidden);
-		} else if (me.id !== user.id) {
-			const following = await Followings.findOneBy({
-				followeeId: user.id,
-				followerId: me.id,
-			});
-			if (following == null) {
-				throw new ApiError(meta.errors.forbidden);
-			}
-		}
-	}
-
-	const query = makePaginationQuery(
-		Followings.createQueryBuilder("following"),
-		ps.sinceId,
-		ps.untilId,
-	)
-		.andWhere("following.followerId = :userId", { userId: user.id })
-		.innerJoinAndSelect("following.followee", "followee");
-
-	const followings = await query.take(ps.limit).getMany();
-
-	return await Followings.packMany(followings, me, { populateFollowee: true });
-});
diff --git a/packages/backend/src/server/api/endpoints/users/gallery/posts.ts b/packages/backend/src/server/api/endpoints/users/gallery/posts.ts
deleted file mode 100644
index 5d64fb4727..0000000000
--- a/packages/backend/src/server/api/endpoints/users/gallery/posts.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import define from "../../../define.js";
-import { GalleryPosts } from "@/models/index.js";
-import { makePaginationQuery } from "../../../common/make-pagination-query.js";
-
-export const meta = {
-	tags: ["users", "gallery"],
-	requireCredentialPrivateMode: true,
-
-	description: "Show all gallery posts by the given user.",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "GalleryPost",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		userId: { type: "string", format: "misskey:id" },
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-	},
-	required: ["userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const query = makePaginationQuery(
-		GalleryPosts.createQueryBuilder("post"),
-		ps.sinceId,
-		ps.untilId,
-	).andWhere("post.userId = :userId", { userId: ps.userId });
-
-	const posts = await query.take(ps.limit).getMany();
-
-	return await GalleryPosts.packMany(posts, user);
-});
diff --git a/packages/backend/src/server/api/endpoints/users/get-frequently-replied-users.ts b/packages/backend/src/server/api/endpoints/users/get-frequently-replied-users.ts
deleted file mode 100644
index 9722804c8d..0000000000
--- a/packages/backend/src/server/api/endpoints/users/get-frequently-replied-users.ts
+++ /dev/null
@@ -1,124 +0,0 @@
-import { Not, In, IsNull } from "typeorm";
-import { maximum } from "@/prelude/array.js";
-import { Notes, Users } from "@/models/index.js";
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { getUser } from "../../common/getters.js";
-
-export const meta = {
-	tags: ["users"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	description:
-		"Get a list of other users that the specified user frequently replies to.",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			properties: {
-				user: {
-					type: "object",
-					optional: false,
-					nullable: false,
-					ref: "UserDetailed",
-				},
-				weight: {
-					type: "number",
-					optional: false,
-					nullable: false,
-				},
-			},
-		},
-	},
-
-	errors: {
-		noSuchUser: {
-			message: "No such user.",
-			code: "NO_SUCH_USER",
-			id: "e6965129-7b2a-40a4-bae2-cd84cd434822",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		userId: { type: "string", format: "misskey:id" },
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-	},
-	required: ["userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	// Lookup user
-	const user = await getUser(ps.userId).catch((e) => {
-		if (e.id === "15348ddd-432d-49c2-8a5a-8069753becff")
-			throw new ApiError(meta.errors.noSuchUser);
-		throw e;
-	});
-
-	// Fetch recent notes
-	const recentNotes = await Notes.find({
-		where: {
-			userId: user.id,
-			replyId: Not(IsNull()),
-		},
-		order: {
-			id: -1,
-		},
-		take: 1000,
-		select: ["replyId"],
-	});
-
-	// 投稿が少なかったら中断
-	if (recentNotes.length === 0) {
-		return [];
-	}
-
-	// TODO ミュートを考慮
-	const replyTargetNotes = await Notes.find({
-		where: {
-			id: In(recentNotes.map((p) => p.replyId)),
-		},
-		select: ["userId"],
-	});
-
-	const repliedUsers: any = {};
-
-	// Extract replies from recent notes
-	for (const userId of replyTargetNotes.map((x) => x.userId.toString())) {
-		if (repliedUsers[userId]) {
-			repliedUsers[userId]++;
-		} else {
-			repliedUsers[userId] = 1;
-		}
-	}
-
-	// Calc peak
-	const peak = maximum(Object.values(repliedUsers));
-
-	// Sort replies by frequency
-	const repliedUsersSorted = Object.keys(repliedUsers).sort(
-		(a, b) => repliedUsers[b] - repliedUsers[a],
-	);
-
-	// Extract top replied users
-	const topRepliedUsers = repliedUsersSorted.slice(0, ps.limit);
-
-	// Make replies object (includes weights)
-	const repliesObj = await Promise.all(
-		topRepliedUsers.map(async (user) => ({
-			user: await Users.pack(user, me, { detail: true }),
-			weight: repliedUsers[user] / peak,
-		})),
-	);
-
-	return repliesObj;
-});
diff --git a/packages/backend/src/server/api/endpoints/users/groups/create.ts b/packages/backend/src/server/api/endpoints/users/groups/create.ts
deleted file mode 100644
index 76bd78c49f..0000000000
--- a/packages/backend/src/server/api/endpoints/users/groups/create.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import { UserGroups, UserGroupJoinings } from "@/models/index.js";
-import { genId } from "@/misc/gen-id.js";
-import type { UserGroup } from "@/models/entities/user-group.js";
-import type { UserGroupJoining } from "@/models/entities/user-group-joining.js";
-import define from "../../../define.js";
-
-export const meta = {
-	tags: ["groups"],
-
-	requireCredential: true,
-
-	kind: "write:user-groups",
-
-	description: "Create a new group.",
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "UserGroup",
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		name: { type: "string", minLength: 1, maxLength: 100 },
-	},
-	required: ["name"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const userGroup = await UserGroups.insert({
-		id: genId(),
-		createdAt: new Date(),
-		userId: user.id,
-		name: ps.name,
-	} as UserGroup).then((x) => UserGroups.findOneByOrFail(x.identifiers[0]));
-
-	// Push the owner
-	await UserGroupJoinings.insert({
-		id: genId(),
-		createdAt: new Date(),
-		userId: user.id,
-		userGroupId: userGroup.id,
-	} as UserGroupJoining);
-
-	return await UserGroups.pack(userGroup);
-});
diff --git a/packages/backend/src/server/api/endpoints/users/groups/delete.ts b/packages/backend/src/server/api/endpoints/users/groups/delete.ts
deleted file mode 100644
index 81c15ad38e..0000000000
--- a/packages/backend/src/server/api/endpoints/users/groups/delete.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import { UserGroups } from "@/models/index.js";
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-
-export const meta = {
-	tags: ["groups"],
-
-	requireCredential: true,
-
-	kind: "write:user-groups",
-
-	description: "Delete an existing group.",
-
-	errors: {
-		noSuchGroup: {
-			message: "No such group.",
-			code: "NO_SUCH_GROUP",
-			id: "63dbd64c-cd77-413f-8e08-61781e210b38",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		groupId: { type: "string", format: "misskey:id" },
-	},
-	required: ["groupId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const userGroup = await UserGroups.findOneBy({
-		id: ps.groupId,
-		userId: user.id,
-	});
-
-	if (userGroup == null) {
-		throw new ApiError(meta.errors.noSuchGroup);
-	}
-
-	await UserGroups.delete(userGroup.id);
-});
diff --git a/packages/backend/src/server/api/endpoints/users/groups/invitations/accept.ts b/packages/backend/src/server/api/endpoints/users/groups/invitations/accept.ts
deleted file mode 100644
index 5cb3a7bad3..0000000000
--- a/packages/backend/src/server/api/endpoints/users/groups/invitations/accept.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-import { UserGroupJoinings, UserGroupInvitations } from "@/models/index.js";
-import { genId } from "@/misc/gen-id.js";
-import type { UserGroupJoining } from "@/models/entities/user-group-joining.js";
-import { ApiError } from "../../../../error.js";
-import define from "../../../../define.js";
-
-export const meta = {
-	tags: ["groups", "users"],
-
-	requireCredential: true,
-
-	kind: "write:user-groups",
-
-	description: "Join a group the authenticated user has been invited to.",
-
-	errors: {
-		noSuchInvitation: {
-			message: "No such invitation.",
-			code: "NO_SUCH_INVITATION",
-			id: "98c11eca-c890-4f42-9806-c8c8303ebb5e",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		invitationId: { type: "string", format: "misskey:id" },
-	},
-	required: ["invitationId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	// Fetch the invitation
-	const invitation = await UserGroupInvitations.findOneBy({
-		id: ps.invitationId,
-	});
-
-	if (invitation == null) {
-		throw new ApiError(meta.errors.noSuchInvitation);
-	}
-
-	if (invitation.userId !== user.id) {
-		throw new ApiError(meta.errors.noSuchInvitation);
-	}
-
-	// Push the user
-	await UserGroupJoinings.insert({
-		id: genId(),
-		createdAt: new Date(),
-		userId: user.id,
-		userGroupId: invitation.userGroupId,
-	} as UserGroupJoining);
-
-	UserGroupInvitations.delete(invitation.id);
-});
diff --git a/packages/backend/src/server/api/endpoints/users/groups/invitations/reject.ts b/packages/backend/src/server/api/endpoints/users/groups/invitations/reject.ts
deleted file mode 100644
index c04ebed23b..0000000000
--- a/packages/backend/src/server/api/endpoints/users/groups/invitations/reject.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import { UserGroupInvitations } from "@/models/index.js";
-import define from "../../../../define.js";
-import { ApiError } from "../../../../error.js";
-
-export const meta = {
-	tags: ["groups", "users"],
-
-	requireCredential: true,
-
-	kind: "write:user-groups",
-
-	description:
-		"Delete an existing group invitation for the authenticated user without joining the group.",
-
-	errors: {
-		noSuchInvitation: {
-			message: "No such invitation.",
-			code: "NO_SUCH_INVITATION",
-			id: "ad7471d4-2cd9-44b4-ac68-e7136b4ce656",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		invitationId: { type: "string", format: "misskey:id" },
-	},
-	required: ["invitationId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	// Fetch the invitation
-	const invitation = await UserGroupInvitations.findOneBy({
-		id: ps.invitationId,
-	});
-
-	if (invitation == null) {
-		throw new ApiError(meta.errors.noSuchInvitation);
-	}
-
-	if (invitation.userId !== user.id) {
-		throw new ApiError(meta.errors.noSuchInvitation);
-	}
-
-	await UserGroupInvitations.delete(invitation.id);
-});
diff --git a/packages/backend/src/server/api/endpoints/users/groups/invite.ts b/packages/backend/src/server/api/endpoints/users/groups/invite.ts
deleted file mode 100644
index 10cc215861..0000000000
--- a/packages/backend/src/server/api/endpoints/users/groups/invite.ts
+++ /dev/null
@@ -1,108 +0,0 @@
-import {
-	UserGroups,
-	UserGroupJoinings,
-	UserGroupInvitations,
-} from "@/models/index.js";
-import { genId } from "@/misc/gen-id.js";
-import type { UserGroupInvitation } from "@/models/entities/user-group-invitation.js";
-import { createNotification } from "@/services/create-notification.js";
-import { getUser } from "../../../common/getters.js";
-import { ApiError } from "../../../error.js";
-import define from "../../../define.js";
-
-export const meta = {
-	tags: ["groups", "users"],
-
-	requireCredential: true,
-
-	kind: "write:user-groups",
-
-	description: "Invite a user to an existing group.",
-
-	errors: {
-		noSuchGroup: {
-			message: "No such group.",
-			code: "NO_SUCH_GROUP",
-			id: "583f8bc0-8eee-4b78-9299-1e14fc91e409",
-		},
-
-		noSuchUser: {
-			message: "No such user.",
-			code: "NO_SUCH_USER",
-			id: "da52de61-002c-475b-90e1-ba64f9cf13a8",
-		},
-
-		alreadyAdded: {
-			message: "That user has already been added to that group.",
-			code: "ALREADY_ADDED",
-			id: "7e35c6a0-39b2-4488-aea6-6ee20bd5da2c",
-		},
-
-		alreadyInvited: {
-			message: "That user has already been invited to that group.",
-			code: "ALREADY_INVITED",
-			id: "ee0f58b4-b529-4d13-b761-b9a3e69f97e6",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		groupId: { type: "string", format: "misskey:id" },
-		userId: { type: "string", format: "misskey:id" },
-	},
-	required: ["groupId", "userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	// Fetch the group
-	const userGroup = await UserGroups.findOneBy({
-		id: ps.groupId,
-		userId: me.id,
-	});
-
-	if (userGroup == null) {
-		throw new ApiError(meta.errors.noSuchGroup);
-	}
-
-	// Fetch the user
-	const user = await getUser(ps.userId).catch((e) => {
-		if (e.id === "15348ddd-432d-49c2-8a5a-8069753becff")
-			throw new ApiError(meta.errors.noSuchUser);
-		throw e;
-	});
-
-	const joining = await UserGroupJoinings.findOneBy({
-		userGroupId: userGroup.id,
-		userId: user.id,
-	});
-
-	if (joining) {
-		throw new ApiError(meta.errors.alreadyAdded);
-	}
-
-	const existInvitation = await UserGroupInvitations.findOneBy({
-		userGroupId: userGroup.id,
-		userId: user.id,
-	});
-
-	if (existInvitation) {
-		throw new ApiError(meta.errors.alreadyInvited);
-	}
-
-	const invitation = await UserGroupInvitations.insert({
-		id: genId(),
-		createdAt: new Date(),
-		userId: user.id,
-		userGroupId: userGroup.id,
-	} as UserGroupInvitation).then((x) =>
-		UserGroupInvitations.findOneByOrFail(x.identifiers[0]),
-	);
-
-	// 通知を作成
-	createNotification(user.id, "groupInvited", {
-		notifierId: me.id,
-		userGroupInvitationId: invitation.id,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/users/groups/joined.ts b/packages/backend/src/server/api/endpoints/users/groups/joined.ts
deleted file mode 100644
index 8422cf586d..0000000000
--- a/packages/backend/src/server/api/endpoints/users/groups/joined.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-import { Not, In } from "typeorm";
-import { UserGroups, UserGroupJoinings } from "@/models/index.js";
-import define from "../../../define.js";
-
-export const meta = {
-	tags: ["groups", "account"],
-
-	requireCredential: true,
-
-	kind: "read:user-groups",
-
-	description: "List the groups that the authenticated user is a member of.",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "UserGroup",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const ownedGroups = await UserGroups.findBy({
-		userId: me.id,
-	});
-
-	const joinings = await UserGroupJoinings.findBy({
-		userId: me.id,
-		...(ownedGroups.length > 0
-			? {
-					userGroupId: Not(In(ownedGroups.map((x) => x.id))),
-			  }
-			: {}),
-	});
-
-	return await Promise.all(joinings.map((x) => UserGroups.pack(x.userGroupId)));
-});
diff --git a/packages/backend/src/server/api/endpoints/users/groups/leave.ts b/packages/backend/src/server/api/endpoints/users/groups/leave.ts
deleted file mode 100644
index d963b1826e..0000000000
--- a/packages/backend/src/server/api/endpoints/users/groups/leave.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-import { UserGroups, UserGroupJoinings } from "@/models/index.js";
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-
-export const meta = {
-	tags: ["groups", "users"],
-
-	requireCredential: true,
-
-	kind: "write:user-groups",
-
-	description:
-		"Leave a group. The owner of a group can not leave. They must transfer ownership or delete the group instead.",
-
-	errors: {
-		noSuchGroup: {
-			message: "No such group.",
-			code: "NO_SUCH_GROUP",
-			id: "62780270-1f67-5dc0-daca-3eb510612e31",
-		},
-
-		youAreOwner: {
-			message: "Your are the owner.",
-			code: "YOU_ARE_OWNER",
-			id: "b6d6e0c2-ef8a-9bb8-653d-79f4a3107c69",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		groupId: { type: "string", format: "misskey:id" },
-	},
-	required: ["groupId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	// Fetch the group
-	const userGroup = await UserGroups.findOneBy({
-		id: ps.groupId,
-	});
-
-	if (userGroup == null) {
-		throw new ApiError(meta.errors.noSuchGroup);
-	}
-
-	if (me.id === userGroup.userId) {
-		throw new ApiError(meta.errors.youAreOwner);
-	}
-
-	await UserGroupJoinings.delete({ userGroupId: userGroup.id, userId: me.id });
-});
diff --git a/packages/backend/src/server/api/endpoints/users/groups/owned.ts b/packages/backend/src/server/api/endpoints/users/groups/owned.ts
deleted file mode 100644
index d86185ff02..0000000000
--- a/packages/backend/src/server/api/endpoints/users/groups/owned.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import { UserGroups } from "@/models/index.js";
-import define from "../../../define.js";
-
-export const meta = {
-	tags: ["groups", "account"],
-
-	requireCredential: true,
-
-	kind: "read:user-groups",
-
-	description: "List the groups that the authenticated user is the owner of.",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "UserGroup",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const userGroups = await UserGroups.findBy({
-		userId: me.id,
-	});
-
-	return await Promise.all(userGroups.map((x) => UserGroups.pack(x)));
-});
diff --git a/packages/backend/src/server/api/endpoints/users/groups/pull.ts b/packages/backend/src/server/api/endpoints/users/groups/pull.ts
deleted file mode 100644
index 1f79a2d2b7..0000000000
--- a/packages/backend/src/server/api/endpoints/users/groups/pull.ts
+++ /dev/null
@@ -1,73 +0,0 @@
-import { UserGroups, UserGroupJoinings } from "@/models/index.js";
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-import { getUser } from "../../../common/getters.js";
-
-export const meta = {
-	tags: ["groups", "users"],
-
-	requireCredential: true,
-
-	kind: "write:user-groups",
-
-	description:
-		"Removes a specified user from a group. The owner can not be removed.",
-
-	errors: {
-		noSuchGroup: {
-			message: "No such group.",
-			code: "NO_SUCH_GROUP",
-			id: "4662487c-05b1-4b78-86e5-fd46998aba74",
-		},
-
-		noSuchUser: {
-			message: "No such user.",
-			code: "NO_SUCH_USER",
-			id: "0b5cc374-3681-41da-861e-8bc1146f7a55",
-		},
-
-		isOwner: {
-			message: "The user is the owner.",
-			code: "IS_OWNER",
-			id: "1546eed5-4414-4dea-81c1-b0aec4f6d2af",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		groupId: { type: "string", format: "misskey:id" },
-		userId: { type: "string", format: "misskey:id" },
-	},
-	required: ["groupId", "userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	// Fetch the group
-	const userGroup = await UserGroups.findOneBy({
-		id: ps.groupId,
-		userId: me.id,
-	});
-
-	if (userGroup == null) {
-		throw new ApiError(meta.errors.noSuchGroup);
-	}
-
-	// Fetch the user
-	const user = await getUser(ps.userId).catch((e) => {
-		if (e.id === "15348ddd-432d-49c2-8a5a-8069753becff")
-			throw new ApiError(meta.errors.noSuchUser);
-		throw e;
-	});
-
-	if (user.id === userGroup.userId) {
-		throw new ApiError(meta.errors.isOwner);
-	}
-
-	// Pull the user
-	await UserGroupJoinings.delete({
-		userGroupId: userGroup.id,
-		userId: user.id,
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/users/groups/show.ts b/packages/backend/src/server/api/endpoints/users/groups/show.ts
deleted file mode 100644
index 46f4410c84..0000000000
--- a/packages/backend/src/server/api/endpoints/users/groups/show.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-import { UserGroups, UserGroupJoinings } from "@/models/index.js";
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-
-export const meta = {
-	tags: ["groups", "account"],
-
-	requireCredential: true,
-
-	kind: "read:user-groups",
-
-	description: "Show the properties of a group.",
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "UserGroup",
-	},
-
-	errors: {
-		noSuchGroup: {
-			message: "No such group.",
-			code: "NO_SUCH_GROUP",
-			id: "ea04751e-9b7e-487b-a509-330fb6bd6b9b",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		groupId: { type: "string", format: "misskey:id" },
-	},
-	required: ["groupId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	// Fetch the group
-	const userGroup = await UserGroups.findOneBy({
-		id: ps.groupId,
-	});
-
-	if (userGroup == null) {
-		throw new ApiError(meta.errors.noSuchGroup);
-	}
-
-	const joining = await UserGroupJoinings.findOneBy({
-		userId: me.id,
-		userGroupId: userGroup.id,
-	});
-
-	if (joining == null && userGroup.userId !== me.id) {
-		throw new ApiError(meta.errors.noSuchGroup);
-	}
-
-	return await UserGroups.pack(userGroup);
-});
diff --git a/packages/backend/src/server/api/endpoints/users/groups/transfer.ts b/packages/backend/src/server/api/endpoints/users/groups/transfer.ts
deleted file mode 100644
index 0322441574..0000000000
--- a/packages/backend/src/server/api/endpoints/users/groups/transfer.ts
+++ /dev/null
@@ -1,85 +0,0 @@
-import { UserGroups, UserGroupJoinings } from "@/models/index.js";
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-import { getUser } from "../../../common/getters.js";
-
-export const meta = {
-	tags: ["groups", "users"],
-
-	requireCredential: true,
-
-	kind: "write:user-groups",
-
-	description:
-		"Transfer ownership of a group from the authenticated user to another user.",
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "UserGroup",
-	},
-
-	errors: {
-		noSuchGroup: {
-			message: "No such group.",
-			code: "NO_SUCH_GROUP",
-			id: "8e31d36b-2f88-4ccd-a438-e2d78a9162db",
-		},
-
-		noSuchUser: {
-			message: "No such user.",
-			code: "NO_SUCH_USER",
-			id: "711f7ebb-bbb9-4dfa-b540-b27809fed5e9",
-		},
-
-		noSuchGroupMember: {
-			message: "No such group member.",
-			code: "NO_SUCH_GROUP_MEMBER",
-			id: "d31bebee-196d-42c2-9a3e-9474d4be6cc4",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		groupId: { type: "string", format: "misskey:id" },
-		userId: { type: "string", format: "misskey:id" },
-	},
-	required: ["groupId", "userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	// Fetch the group
-	const userGroup = await UserGroups.findOneBy({
-		id: ps.groupId,
-		userId: me.id,
-	});
-
-	if (userGroup == null) {
-		throw new ApiError(meta.errors.noSuchGroup);
-	}
-
-	// Fetch the user
-	const user = await getUser(ps.userId).catch((e) => {
-		if (e.id === "15348ddd-432d-49c2-8a5a-8069753becff")
-			throw new ApiError(meta.errors.noSuchUser);
-		throw e;
-	});
-
-	const joining = await UserGroupJoinings.findOneBy({
-		userGroupId: userGroup.id,
-		userId: user.id,
-	});
-
-	if (joining == null) {
-		throw new ApiError(meta.errors.noSuchGroupMember);
-	}
-
-	await UserGroups.update(userGroup.id, {
-		userId: ps.userId,
-	});
-
-	return await UserGroups.pack(userGroup.id);
-});
diff --git a/packages/backend/src/server/api/endpoints/users/groups/update.ts b/packages/backend/src/server/api/endpoints/users/groups/update.ts
deleted file mode 100644
index fa720c9c45..0000000000
--- a/packages/backend/src/server/api/endpoints/users/groups/update.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-import { UserGroups } from "@/models/index.js";
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-
-export const meta = {
-	tags: ["groups"],
-
-	requireCredential: true,
-
-	kind: "write:user-groups",
-
-	description: "Update the properties of a group.",
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "UserGroup",
-	},
-
-	errors: {
-		noSuchGroup: {
-			message: "No such group.",
-			code: "NO_SUCH_GROUP",
-			id: "9081cda3-7a9e-4fac-a6ce-908d70f282f6",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		groupId: { type: "string", format: "misskey:id" },
-		name: { type: "string", minLength: 1, maxLength: 100 },
-	},
-	required: ["groupId", "name"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	// Fetch the group
-	const userGroup = await UserGroups.findOneBy({
-		id: ps.groupId,
-		userId: me.id,
-	});
-
-	if (userGroup == null) {
-		throw new ApiError(meta.errors.noSuchGroup);
-	}
-
-	await UserGroups.update(userGroup.id, {
-		name: ps.name,
-	});
-
-	return await UserGroups.pack(userGroup.id);
-});
diff --git a/packages/backend/src/server/api/endpoints/users/lists/create.ts b/packages/backend/src/server/api/endpoints/users/lists/create.ts
deleted file mode 100644
index 6bbbf603e5..0000000000
--- a/packages/backend/src/server/api/endpoints/users/lists/create.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import { UserLists } from "@/models/index.js";
-import { genId } from "@/misc/gen-id.js";
-import type { UserList } from "@/models/entities/user-list.js";
-import define from "../../../define.js";
-
-export const meta = {
-	tags: ["lists"],
-
-	requireCredential: true,
-
-	kind: "write:account",
-
-	description: "Create a new list of users.",
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "UserList",
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		name: { type: "string", minLength: 1, maxLength: 100 },
-	},
-	required: ["name"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const userList = await UserLists.insert({
-		id: genId(),
-		createdAt: new Date(),
-		userId: user.id,
-		name: ps.name,
-	} as UserList).then((x) => UserLists.findOneByOrFail(x.identifiers[0]));
-
-	return await UserLists.pack(userList);
-});
diff --git a/packages/backend/src/server/api/endpoints/users/lists/delete-all.ts b/packages/backend/src/server/api/endpoints/users/lists/delete-all.ts
deleted file mode 100644
index 49c4cf6f63..0000000000
--- a/packages/backend/src/server/api/endpoints/users/lists/delete-all.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import { UserLists } from "@/models/index.js";
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-
-export const meta = {
-	tags: ["lists"],
-
-	requireCredential: true,
-
-	kind: "write:account",
-
-	description: "Delete all lists of users.",
-
-	errors: {
-		noSuchList: {
-			message: "No such list.",
-			code: "NO_SUCH_LIST",
-			id: "78436795-db79-42f5-b1e2-55ea2cf19166",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	while ((await UserLists.findOneBy({ userId: user.id })) != null) {
-		const userList = await UserLists.findOneBy({ userId: user.id });
-		if (userList == null) {
-			throw new ApiError(meta.errors.noSuchList);
-		}
-		await UserLists.delete(userList.id);
-	}
-});
diff --git a/packages/backend/src/server/api/endpoints/users/lists/delete.ts b/packages/backend/src/server/api/endpoints/users/lists/delete.ts
deleted file mode 100644
index 4566295676..0000000000
--- a/packages/backend/src/server/api/endpoints/users/lists/delete.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import { UserLists } from "@/models/index.js";
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-
-export const meta = {
-	tags: ["lists"],
-
-	requireCredential: true,
-
-	kind: "write:account",
-
-	description: "Delete an existing list of users.",
-
-	errors: {
-		noSuchList: {
-			message: "No such list.",
-			code: "NO_SUCH_LIST",
-			id: "78436795-db79-42f5-b1e2-55ea2cf19166",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		listId: { type: "string", format: "misskey:id" },
-	},
-	required: ["listId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const userList = await UserLists.findOneBy({
-		id: ps.listId,
-		userId: user.id,
-	});
-
-	if (userList == null) {
-		throw new ApiError(meta.errors.noSuchList);
-	}
-
-	await UserLists.delete(userList.id);
-});
diff --git a/packages/backend/src/server/api/endpoints/users/lists/list.ts b/packages/backend/src/server/api/endpoints/users/lists/list.ts
deleted file mode 100644
index 5d590ee0ec..0000000000
--- a/packages/backend/src/server/api/endpoints/users/lists/list.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import { UserLists } from "@/models/index.js";
-import define from "../../../define.js";
-
-export const meta = {
-	tags: ["lists", "account"],
-
-	requireCredential: true,
-
-	kind: "read:account",
-
-	description: "Show all lists that the authenticated user has created.",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "UserList",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const userLists = await UserLists.findBy({
-		userId: me.id,
-	});
-
-	return await Promise.all(userLists.map((x) => UserLists.pack(x)));
-});
diff --git a/packages/backend/src/server/api/endpoints/users/lists/pull.ts b/packages/backend/src/server/api/endpoints/users/lists/pull.ts
deleted file mode 100644
index 07fae20675..0000000000
--- a/packages/backend/src/server/api/endpoints/users/lists/pull.ts
+++ /dev/null
@@ -1,62 +0,0 @@
-import { publishUserListStream } from "@/services/stream.js";
-import { UserLists, UserListJoinings, Users } from "@/models/index.js";
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-import { getUser } from "../../../common/getters.js";
-
-export const meta = {
-	tags: ["lists", "users"],
-
-	requireCredential: true,
-
-	kind: "write:account",
-
-	description: "Remove a user from a list.",
-
-	errors: {
-		noSuchList: {
-			message: "No such list.",
-			code: "NO_SUCH_LIST",
-			id: "7f44670e-ab16-43b8-b4c1-ccd2ee89cc02",
-		},
-
-		noSuchUser: {
-			message: "No such user.",
-			code: "NO_SUCH_USER",
-			id: "588e7f72-c744-4a61-b180-d354e912bda2",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		listId: { type: "string", format: "misskey:id" },
-		userId: { type: "string", format: "misskey:id" },
-	},
-	required: ["listId", "userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	// Fetch the list
-	const userList = await UserLists.findOneBy({
-		id: ps.listId,
-		userId: me.id,
-	});
-
-	if (userList == null) {
-		throw new ApiError(meta.errors.noSuchList);
-	}
-
-	// Fetch the user
-	const user = await getUser(ps.userId).catch((e) => {
-		if (e.id === "15348ddd-432d-49c2-8a5a-8069753becff")
-			throw new ApiError(meta.errors.noSuchUser);
-		throw e;
-	});
-
-	// Pull the user
-	await UserListJoinings.delete({ userListId: userList.id, userId: user.id });
-
-	publishUserListStream(userList.id, "userRemoved", await Users.pack(user));
-});
diff --git a/packages/backend/src/server/api/endpoints/users/lists/push.ts b/packages/backend/src/server/api/endpoints/users/lists/push.ts
deleted file mode 100644
index a14195bbc3..0000000000
--- a/packages/backend/src/server/api/endpoints/users/lists/push.ts
+++ /dev/null
@@ -1,93 +0,0 @@
-import { pushUserToUserList } from "@/services/user-list/push.js";
-import { UserLists, UserListJoinings, Blockings } from "@/models/index.js";
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-import { getUser } from "../../../common/getters.js";
-
-export const meta = {
-	tags: ["lists", "users"],
-
-	requireCredential: true,
-
-	kind: "write:account",
-
-	description: "Add a user to an existing list.",
-
-	errors: {
-		noSuchList: {
-			message: "No such list.",
-			code: "NO_SUCH_LIST",
-			id: "2214501d-ac96-4049-b717-91e42272a711",
-		},
-
-		noSuchUser: {
-			message: "No such user.",
-			code: "NO_SUCH_USER",
-			id: "a89abd3d-f0bc-4cce-beb1-2f446f4f1e6a",
-		},
-
-		alreadyAdded: {
-			message: "That user has already been added to that list.",
-			code: "ALREADY_ADDED",
-			id: "1de7c884-1595-49e9-857e-61f12f4d4fc5",
-		},
-
-		youHaveBeenBlocked: {
-			message:
-				"You cannot push this user because you have been blocked by this user.",
-			code: "YOU_HAVE_BEEN_BLOCKED",
-			id: "990232c5-3f9d-4d83-9f3f-ef27b6332a4b",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		listId: { type: "string", format: "misskey:id" },
-		userId: { type: "string", format: "misskey:id" },
-	},
-	required: ["listId", "userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	// Fetch the list
-	const userList = await UserLists.findOneBy({
-		id: ps.listId,
-		userId: me.id,
-	});
-
-	if (userList == null) {
-		throw new ApiError(meta.errors.noSuchList);
-	}
-
-	// Fetch the user
-	const user = await getUser(ps.userId).catch((e) => {
-		if (e.id === "15348ddd-432d-49c2-8a5a-8069753becff")
-			throw new ApiError(meta.errors.noSuchUser);
-		throw e;
-	});
-
-	// Check blocking
-	if (user.id !== me.id) {
-		const block = await Blockings.findOneBy({
-			blockerId: user.id,
-			blockeeId: me.id,
-		});
-		if (block) {
-			throw new ApiError(meta.errors.youHaveBeenBlocked);
-		}
-	}
-
-	const exist = await UserListJoinings.findOneBy({
-		userListId: userList.id,
-		userId: user.id,
-	});
-
-	if (exist) {
-		throw new ApiError(meta.errors.alreadyAdded);
-	}
-
-	// Push the user
-	await pushUserToUserList(user, userList);
-});
diff --git a/packages/backend/src/server/api/endpoints/users/lists/show.ts b/packages/backend/src/server/api/endpoints/users/lists/show.ts
deleted file mode 100644
index 716fd405dc..0000000000
--- a/packages/backend/src/server/api/endpoints/users/lists/show.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import { UserLists } from "@/models/index.js";
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-
-export const meta = {
-	tags: ["lists", "account"],
-
-	requireCredential: true,
-
-	kind: "read:account",
-
-	description: "Show the properties of a list.",
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "UserList",
-	},
-
-	errors: {
-		noSuchList: {
-			message: "No such list.",
-			code: "NO_SUCH_LIST",
-			id: "7bc05c21-1d7a-41ae-88f1-66820f4dc686",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		listId: { type: "string", format: "misskey:id" },
-	},
-	required: ["listId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	// Fetch the list
-	const userList = await UserLists.findOneBy({
-		id: ps.listId,
-		userId: me.id,
-	});
-
-	if (userList == null) {
-		throw new ApiError(meta.errors.noSuchList);
-	}
-
-	return await UserLists.pack(userList);
-});
diff --git a/packages/backend/src/server/api/endpoints/users/lists/update.ts b/packages/backend/src/server/api/endpoints/users/lists/update.ts
deleted file mode 100644
index 0ac788fd37..0000000000
--- a/packages/backend/src/server/api/endpoints/users/lists/update.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-import { UserLists } from "@/models/index.js";
-import define from "../../../define.js";
-import { ApiError } from "../../../error.js";
-
-export const meta = {
-	tags: ["lists"],
-
-	requireCredential: true,
-
-	kind: "write:account",
-
-	description: "Update the properties of a list.",
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		ref: "UserList",
-	},
-
-	errors: {
-		noSuchList: {
-			message: "No such list.",
-			code: "NO_SUCH_LIST",
-			id: "796666fe-3dff-4d39-becb-8a5932c1d5b7",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		listId: { type: "string", format: "misskey:id" },
-		name: { type: "string", minLength: 1, maxLength: 100 },
-	},
-	required: ["listId", "name"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	// Fetch the list
-	const userList = await UserLists.findOneBy({
-		id: ps.listId,
-		userId: user.id,
-	});
-
-	if (userList == null) {
-		throw new ApiError(meta.errors.noSuchList);
-	}
-
-	await UserLists.update(userList.id, {
-		name: ps.name,
-	});
-
-	return await UserLists.pack(userList.id);
-});
diff --git a/packages/backend/src/server/api/endpoints/users/notes.ts b/packages/backend/src/server/api/endpoints/users/notes.ts
deleted file mode 100644
index 724cfc9af1..0000000000
--- a/packages/backend/src/server/api/endpoints/users/notes.ts
+++ /dev/null
@@ -1,144 +0,0 @@
-import { Brackets } from "typeorm";
-import { Notes } from "@/models/index.js";
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-import { getUser } from "../../common/getters.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-import { generateVisibilityQuery } from "../../common/generate-visibility-query.js";
-import { generateMutedUserQuery } from "../../common/generate-muted-user-query.js";
-import { generateBlockedUserQuery } from "../../common/generate-block-query.js";
-
-export const meta = {
-	tags: ["users", "notes"],
-
-	requireCredentialPrivateMode: true,
-	description: "Show all notes that this user created.",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Note",
-		},
-	},
-
-	errors: {
-		noSuchUser: {
-			message: "No such user.",
-			code: "NO_SUCH_USER",
-			id: "27e494ba-2ac2-48e8-893b-10d4d8c2387b",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		userId: { type: "string", format: "misskey:id" },
-		includeReplies: { type: "boolean", default: true },
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-		sinceDate: { type: "integer" },
-		untilDate: { type: "integer" },
-		includeMyRenotes: { type: "boolean", default: true },
-		withFiles: { type: "boolean", default: false },
-		fileType: {
-			type: "array",
-			items: {
-				type: "string",
-			},
-		},
-		excludeNsfw: { type: "boolean", default: false },
-	},
-	required: ["userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	// Lookup user
-	const user = await getUser(ps.userId).catch((e) => {
-		if (e.id === "15348ddd-432d-49c2-8a5a-8069753becff")
-			throw new ApiError(meta.errors.noSuchUser);
-		throw e;
-	});
-
-	//#region Construct query
-	const query = makePaginationQuery(
-		Notes.createQueryBuilder("note"),
-		ps.sinceId,
-		ps.untilId,
-		ps.sinceDate,
-		ps.untilDate,
-	)
-		.andWhere("note.userId = :userId", { userId: user.id })
-		.innerJoinAndSelect("note.user", "user")
-		.leftJoinAndSelect("user.avatar", "avatar")
-		.leftJoinAndSelect("user.banner", "banner")
-		.leftJoinAndSelect("note.reply", "reply")
-		.leftJoinAndSelect("note.renote", "renote")
-		.leftJoinAndSelect("reply.user", "replyUser")
-		.leftJoinAndSelect("replyUser.avatar", "replyUserAvatar")
-		.leftJoinAndSelect("replyUser.banner", "replyUserBanner")
-		.leftJoinAndSelect("renote.user", "renoteUser")
-		.leftJoinAndSelect("renoteUser.avatar", "renoteUserAvatar")
-		.leftJoinAndSelect("renoteUser.banner", "renoteUserBanner");
-
-	generateVisibilityQuery(query, me);
-	if (me) {
-		generateMutedUserQuery(query, me, user);
-		generateBlockedUserQuery(query, me);
-	}
-
-	if (ps.withFiles) {
-		query.andWhere("note.fileIds != '{}'");
-	}
-
-	if (ps.fileType != null) {
-		query.andWhere("note.fileIds != '{}'");
-		query.andWhere(
-			new Brackets((qb) => {
-				for (const type of ps.fileType!) {
-					const i = ps.fileType!.indexOf(type);
-					qb.orWhere(`:type${i} = ANY(note.attachedFileTypes)`, {
-						[`type${i}`]: type,
-					});
-				}
-			}),
-		);
-
-		if (ps.excludeNsfw) {
-			query.andWhere("note.cw IS NULL");
-			query.andWhere(
-				'0 = (SELECT COUNT(*) FROM drive_file df WHERE df.id = ANY(note."fileIds") AND df."isSensitive" = TRUE)',
-			);
-		}
-	}
-
-	if (!ps.includeReplies) {
-		query.andWhere("note.replyId IS NULL");
-	}
-
-	if (ps.includeMyRenotes === false) {
-		query.andWhere(
-			new Brackets((qb) => {
-				qb.orWhere("note.userId != :userId", { userId: user.id });
-				qb.orWhere("note.renoteId IS NULL");
-				qb.orWhere("note.text IS NOT NULL");
-				qb.orWhere("note.fileIds != '{}'");
-				qb.orWhere(
-					'0 < (SELECT COUNT(*) FROM poll WHERE poll."noteId" = note.id)',
-				);
-			}),
-		);
-	}
-
-	//#endregion
-
-	const timeline = await query.take(ps.limit).getMany();
-
-	return await Notes.packMany(timeline, me);
-});
diff --git a/packages/backend/src/server/api/endpoints/users/pages.ts b/packages/backend/src/server/api/endpoints/users/pages.ts
deleted file mode 100644
index c08258b19d..0000000000
--- a/packages/backend/src/server/api/endpoints/users/pages.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-import { Pages } from "@/models/index.js";
-import define from "../../define.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-
-export const meta = {
-	tags: ["users", "pages"],
-	requireCredentialPrivateMode: true,
-
-	description: "Show all pages this user created.",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "Page",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		userId: { type: "string", format: "misskey:id" },
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-	},
-	required: ["userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, user) => {
-	const query = makePaginationQuery(
-		Pages.createQueryBuilder("page"),
-		ps.sinceId,
-		ps.untilId,
-	)
-		.andWhere("page.userId = :userId", { userId: ps.userId })
-		.andWhere("page.visibility = 'public'")
-		.andWhere("page.isPublic = true");
-
-	const pages = await query.take(ps.limit).getMany();
-
-	return await Pages.packMany(pages);
-});
diff --git a/packages/backend/src/server/api/endpoints/users/reactions.ts b/packages/backend/src/server/api/endpoints/users/reactions.ts
deleted file mode 100644
index 17b7a04a06..0000000000
--- a/packages/backend/src/server/api/endpoints/users/reactions.ts
+++ /dev/null
@@ -1,71 +0,0 @@
-import { NoteReactions, UserProfiles } from "@/models/index.js";
-import define from "../../define.js";
-import { makePaginationQuery } from "../../common/make-pagination-query.js";
-import { generateVisibilityQuery } from "../../common/generate-visibility-query.js";
-import { ApiError } from "../../error.js";
-
-export const meta = {
-	tags: ["users", "reactions"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	description: "Show all reactions this user made.",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "NoteReaction",
-		},
-	},
-
-	errors: {
-		reactionsNotPublic: {
-			message: "Reactions of the user is not public.",
-			code: "REACTIONS_NOT_PUBLIC",
-			id: "673a7dd2-6924-1093-e0c0-e68456ceae5c",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		userId: { type: "string", format: "misskey:id" },
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		sinceId: { type: "string", format: "misskey:id" },
-		untilId: { type: "string", format: "misskey:id" },
-		sinceDate: { type: "integer" },
-		untilDate: { type: "integer" },
-	},
-	required: ["userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const profile = await UserProfiles.findOneByOrFail({ userId: ps.userId });
-
-	if (me == null || (me.id !== ps.userId && !profile.publicReactions)) {
-		throw new ApiError(meta.errors.reactionsNotPublic);
-	}
-
-	const query = makePaginationQuery(
-		NoteReactions.createQueryBuilder("reaction"),
-		ps.sinceId,
-		ps.untilId,
-		ps.sinceDate,
-		ps.untilDate,
-	)
-		.andWhere("reaction.userId = :userId", { userId: ps.userId })
-		.leftJoinAndSelect("reaction.note", "note");
-
-	generateVisibilityQuery(query, me);
-
-	const reactions = await query.take(ps.limit).getMany();
-
-	return await NoteReactions.packMany(reactions, me, { withNote: true });
-});
diff --git a/packages/backend/src/server/api/endpoints/users/recommendation.ts b/packages/backend/src/server/api/endpoints/users/recommendation.ts
deleted file mode 100644
index 615cca7856..0000000000
--- a/packages/backend/src/server/api/endpoints/users/recommendation.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-import { Users, Followings } from "@/models/index.js";
-import define from "../../define.js";
-import { generateMutedUserQueryForUsers } from "../../common/generate-muted-user-query.js";
-import {
-	generateBlockedUserQuery,
-	generateBlockQueryForUsers,
-} from "../../common/generate-block-query.js";
-import { DAY } from "@/const.js";
-
-export const meta = {
-	tags: ["users"],
-
-	requireCredential: true,
-
-	kind: "read:account",
-
-	description:
-		"Show users that the authenticated user might be interested to follow.",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "UserDetailed",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		offset: { type: "integer", default: 0 },
-	},
-	required: [],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const query = Users.createQueryBuilder("user")
-		.where("user.isLocked = FALSE")
-		.andWhere("user.isExplorable = TRUE")
-		.andWhere("user.host IS NULL")
-		.andWhere("user.updatedAt >= :date", {
-			date: new Date(Date.now() - 7 * DAY),
-		})
-		.andWhere("user.id != :meId", { meId: me.id })
-		.orderBy("user.followersCount", "DESC");
-
-	generateMutedUserQueryForUsers(query, me);
-	generateBlockQueryForUsers(query, me);
-	generateBlockedUserQuery(query, me);
-
-	const followingQuery = Followings.createQueryBuilder("following")
-		.select("following.followeeId")
-		.where("following.followerId = :followerId", { followerId: me.id });
-
-	query.andWhere(`user.id NOT IN (${followingQuery.getQuery()})`);
-
-	query.setParameters(followingQuery.getParameters());
-
-	const users = await query.take(ps.limit).skip(ps.offset).getMany();
-
-	return await Users.packMany(users, me, { detail: true });
-});
diff --git a/packages/backend/src/server/api/endpoints/users/relation.ts b/packages/backend/src/server/api/endpoints/users/relation.ts
deleted file mode 100644
index 5580eaea0b..0000000000
--- a/packages/backend/src/server/api/endpoints/users/relation.ts
+++ /dev/null
@@ -1,151 +0,0 @@
-import { Users } from "@/models/index.js";
-import define from "../../define.js";
-
-export const meta = {
-	tags: ["users"],
-
-	requireCredential: true,
-
-	description:
-		"Show the different kinds of relations between the authenticated user and the specified user(s).",
-
-	res: {
-		optional: false,
-		nullable: false,
-		oneOf: [
-			{
-				type: "object",
-				properties: {
-					id: {
-						type: "string",
-						optional: false,
-						nullable: false,
-						format: "id",
-					},
-					isFollowing: {
-						type: "boolean",
-						optional: false,
-						nullable: false,
-					},
-					hasPendingFollowRequestFromYou: {
-						type: "boolean",
-						optional: false,
-						nullable: false,
-					},
-					hasPendingFollowRequestToYou: {
-						type: "boolean",
-						optional: false,
-						nullable: false,
-					},
-					isFollowed: {
-						type: "boolean",
-						optional: false,
-						nullable: false,
-					},
-					isBlocking: {
-						type: "boolean",
-						optional: false,
-						nullable: false,
-					},
-					isBlocked: {
-						type: "boolean",
-						optional: false,
-						nullable: false,
-					},
-					isMuted: {
-						type: "boolean",
-						optional: false,
-						nullable: false,
-					},
-					isRenoteMuted: {
-						type: "boolean",
-						optional: false,
-						nullable: false,
-					},
-				},
-			},
-			{
-				type: "array",
-				items: {
-					type: "object",
-					optional: false,
-					nullable: false,
-					properties: {
-						id: {
-							type: "string",
-							optional: false,
-							nullable: false,
-							format: "id",
-						},
-						isFollowing: {
-							type: "boolean",
-							optional: false,
-							nullable: false,
-						},
-						hasPendingFollowRequestFromYou: {
-							type: "boolean",
-							optional: false,
-							nullable: false,
-						},
-						hasPendingFollowRequestToYou: {
-							type: "boolean",
-							optional: false,
-							nullable: false,
-						},
-						isFollowed: {
-							type: "boolean",
-							optional: false,
-							nullable: false,
-						},
-						isBlocking: {
-							type: "boolean",
-							optional: false,
-							nullable: false,
-						},
-						isBlocked: {
-							type: "boolean",
-							optional: false,
-							nullable: false,
-						},
-						isMuted: {
-							type: "boolean",
-							optional: false,
-							nullable: false,
-						},
-						isRenoteMuted: {
-							type: "boolean",
-							optional: false,
-							nullable: false,
-						},
-					},
-				},
-			},
-		],
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		userId: {
-			anyOf: [
-				{ type: "string", format: "misskey:id" },
-				{
-					type: "array",
-					items: { type: "string", format: "misskey:id" },
-				},
-			],
-		},
-	},
-	required: ["userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const ids = Array.isArray(ps.userId) ? ps.userId : [ps.userId];
-
-	const relations = await Promise.all(
-		ids.map((id) => Users.getRelation(me.id, id)),
-	);
-
-	return Array.isArray(ps.userId) ? relations : relations[0];
-});
diff --git a/packages/backend/src/server/api/endpoints/users/report-abuse.ts b/packages/backend/src/server/api/endpoints/users/report-abuse.ts
deleted file mode 100644
index 44d3f9b500..0000000000
--- a/packages/backend/src/server/api/endpoints/users/report-abuse.ts
+++ /dev/null
@@ -1,106 +0,0 @@
-import * as sanitizeHtml from "sanitize-html";
-import { publishAdminStream } from "@/services/stream.js";
-import { AbuseUserReports, Users } from "@/models/index.js";
-import { genId } from "@/misc/gen-id.js";
-import { sendEmail } from "@/services/send-email.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { getUser } from "../../common/getters.js";
-import { ApiError } from "../../error.js";
-import define from "../../define.js";
-
-export const meta = {
-	tags: ["users"],
-
-	requireCredential: true,
-
-	description: "File a report.",
-
-	errors: {
-		noSuchUser: {
-			message: "No such user.",
-			code: "NO_SUCH_USER",
-			id: "1acefcb5-0959-43fd-9685-b48305736cb5",
-		},
-
-		cannotReportYourself: {
-			message: "Cannot report yourself.",
-			code: "CANNOT_REPORT_YOURSELF",
-			id: "1e13149e-b1e8-43cf-902e-c01dbfcb202f",
-		},
-
-		cannotReportAdmin: {
-			message: "Cannot report the admin.",
-			code: "CANNOT_REPORT_THE_ADMIN",
-			id: "35e166f5-05fb-4f87-a2d5-adb42676d48f",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		userId: { type: "string", format: "misskey:id" },
-		comment: { type: "string", minLength: 1, maxLength: 2048 },
-	},
-	required: ["userId", "comment"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	// Lookup user
-	const user = await getUser(ps.userId).catch((e) => {
-		if (e.id === "15348ddd-432d-49c2-8a5a-8069753becff")
-			throw new ApiError(meta.errors.noSuchUser);
-		throw e;
-	});
-
-	if (user.id === me.id) {
-		throw new ApiError(meta.errors.cannotReportYourself);
-	}
-
-	if (user.isAdmin) {
-		throw new ApiError(meta.errors.cannotReportAdmin);
-	}
-
-	const report = await AbuseUserReports.insert({
-		id: genId(),
-		createdAt: new Date(),
-		targetUserId: user.id,
-		targetUserHost: user.host,
-		reporterId: me.id,
-		reporterHost: null,
-		comment: ps.comment,
-	}).then((x) => AbuseUserReports.findOneByOrFail(x.identifiers[0]));
-
-	// Publish event to moderators
-	setImmediate(async () => {
-		const moderators = await Users.find({
-			where: [
-				{
-					isAdmin: true,
-				},
-				{
-					isModerator: true,
-				},
-			],
-		});
-
-		for (const moderator of moderators) {
-			publishAdminStream(moderator.id, "newAbuseUserReport", {
-				id: report.id,
-				targetUserId: report.targetUserId,
-				reporterId: report.reporterId,
-				comment: report.comment,
-			});
-		}
-
-		const meta = await fetchMeta();
-		if (meta.email) {
-			sendEmail(
-				meta.email,
-				"New abuse report",
-				sanitizeHtml(ps.comment),
-				sanitizeHtml(ps.comment),
-			);
-		}
-	});
-});
diff --git a/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts b/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts
deleted file mode 100644
index 99aa2f1af3..0000000000
--- a/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts
+++ /dev/null
@@ -1,127 +0,0 @@
-import { Brackets } from "typeorm";
-import { Followings, Users } from "@/models/index.js";
-import { USER_ACTIVE_THRESHOLD } from "@/const.js";
-import type { User } from "@/models/entities/user.js";
-import define from "../../define.js";
-
-export const meta = {
-	tags: ["users"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	description: "Search for a user by username and/or host.",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "User",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		username: { type: "string", nullable: true },
-		host: { type: "string", nullable: true },
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		detail: { type: "boolean", default: true },
-	},
-	anyOf: [{ required: ["username"] }, { required: ["host"] }],
-} as const;
-
-// TODO: avatar,bannerをJOINしたいけどエラーになる
-
-export default define(meta, paramDef, async (ps, me) => {
-	const activeThreshold = new Date(Date.now() - 1000 * 60 * 60 * 24 * 30); // 30日
-
-	if (ps.host) {
-		const q = Users.createQueryBuilder("user")
-			.where("user.isSuspended = FALSE")
-			.andWhere("user.host LIKE :host", { host: `${ps.host.toLowerCase()}%` });
-
-		if (ps.username) {
-			q.andWhere("user.usernameLower LIKE :username", {
-				username: `${ps.username.toLowerCase()}%`,
-			});
-		}
-
-		q.andWhere("user.updatedAt IS NOT NULL");
-		q.orderBy("user.updatedAt", "DESC");
-
-		const users = await q.take(ps.limit).getMany();
-
-		return await Users.packMany(users, me, { detail: ps.detail });
-	} else if (ps.username) {
-		let users: User[] = [];
-
-		if (me) {
-			const followingQuery = Followings.createQueryBuilder("following")
-				.select("following.followeeId")
-				.where("following.followerId = :followerId", { followerId: me.id });
-
-			const query = Users.createQueryBuilder("user")
-				.where(`user.id IN (${followingQuery.getQuery()})`)
-				.andWhere("user.id != :meId", { meId: me.id })
-				.andWhere("user.isSuspended = FALSE")
-				.andWhere("user.usernameLower LIKE :username", {
-					username: `${ps.username.toLowerCase()}%`,
-				})
-				.andWhere(
-					new Brackets((qb) => {
-						qb.where("user.updatedAt IS NULL").orWhere(
-							"user.updatedAt > :activeThreshold",
-							{ activeThreshold: activeThreshold },
-						);
-					}),
-				);
-
-			query.setParameters(followingQuery.getParameters());
-
-			users = await query
-				.orderBy("user.usernameLower", "ASC")
-				.take(ps.limit)
-				.getMany();
-
-			if (users.length < ps.limit) {
-				const otherQuery = await Users.createQueryBuilder("user")
-					.where(`user.id NOT IN (${followingQuery.getQuery()})`)
-					.andWhere("user.id != :meId", { meId: me.id })
-					.andWhere("user.isSuspended = FALSE")
-					.andWhere("user.usernameLower LIKE :username", {
-						username: `${ps.username.toLowerCase()}%`,
-					})
-					.andWhere("user.updatedAt IS NOT NULL");
-
-				otherQuery.setParameters(followingQuery.getParameters());
-
-				const otherUsers = await otherQuery
-					.orderBy("user.updatedAt", "DESC")
-					.take(ps.limit - users.length)
-					.getMany();
-
-				users = users.concat(otherUsers);
-			}
-		} else {
-			users = await Users.createQueryBuilder("user")
-				.where("user.isSuspended = FALSE")
-				.andWhere("user.usernameLower LIKE :username", {
-					username: `${ps.username.toLowerCase()}%`,
-				})
-				.andWhere("user.updatedAt IS NOT NULL")
-				.orderBy("user.updatedAt", "DESC")
-				.take(ps.limit - users.length)
-				.getMany();
-		}
-
-		return await Users.packMany(users, me, { detail: !!ps.detail });
-	}
-
-	return [];
-});
diff --git a/packages/backend/src/server/api/endpoints/users/search.ts b/packages/backend/src/server/api/endpoints/users/search.ts
deleted file mode 100644
index db687a1075..0000000000
--- a/packages/backend/src/server/api/endpoints/users/search.ts
+++ /dev/null
@@ -1,149 +0,0 @@
-import { Brackets } from "typeorm";
-import { UserProfiles, Users } from "@/models/index.js";
-import type { User } from "@/models/entities/user.js";
-import define from "../../define.js";
-
-export const meta = {
-	tags: ["users"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	description: "Search for users.",
-
-	res: {
-		type: "array",
-		optional: false,
-		nullable: false,
-		items: {
-			type: "object",
-			optional: false,
-			nullable: false,
-			ref: "User",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		query: { type: "string" },
-		offset: { type: "integer", default: 0 },
-		limit: { type: "integer", minimum: 1, maximum: 100, default: 10 },
-		origin: {
-			type: "string",
-			enum: ["local", "remote", "combined"],
-			default: "combined",
-		},
-		detail: { type: "boolean", default: true },
-	},
-	required: ["query"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const activeThreshold = new Date(Date.now() - 1000 * 60 * 60 * 24 * 30); // 30日
-
-	const isUsername = ps.query.startsWith("@");
-
-	let users: User[] = [];
-
-	if (isUsername) {
-		const usernameQuery = Users.createQueryBuilder("user")
-			.where("user.usernameLower LIKE :username", {
-				username: `${ps.query.replace("@", "").toLowerCase()}%`,
-			})
-			.andWhere(
-				new Brackets((qb) => {
-					qb.where("user.updatedAt IS NULL").orWhere(
-						"user.updatedAt > :activeThreshold",
-						{ activeThreshold: activeThreshold },
-					);
-				}),
-			)
-			.andWhere("user.isSuspended = FALSE");
-
-		if (ps.origin === "local") {
-			usernameQuery.andWhere("user.host IS NULL");
-		} else if (ps.origin === "remote") {
-			usernameQuery.andWhere("user.host IS NOT NULL");
-		}
-
-		users = await usernameQuery
-			.orderBy("user.updatedAt", "DESC", "NULLS LAST")
-			.take(ps.limit)
-			.skip(ps.offset)
-			.getMany();
-	} else {
-		const nameQuery = Users.createQueryBuilder("user")
-			.where(
-				new Brackets((qb) => {
-					qb.where("user.name ILIKE :query", { query: `%${ps.query}%` });
-
-					// Also search username if it qualifies as username
-					if (Users.validateLocalUsername(ps.query)) {
-						qb.orWhere("user.usernameLower LIKE :username", {
-							username: `%${ps.query.toLowerCase()}%`,
-						});
-					}
-				}),
-			)
-			.andWhere(
-				new Brackets((qb) => {
-					qb.where("user.updatedAt IS NULL").orWhere(
-						"user.updatedAt > :activeThreshold",
-						{ activeThreshold: activeThreshold },
-					);
-				}),
-			)
-			.andWhere("user.isSuspended = FALSE");
-
-		if (ps.origin === "local") {
-			nameQuery.andWhere("user.host IS NULL");
-		} else if (ps.origin === "remote") {
-			nameQuery.andWhere("user.host IS NOT NULL");
-		}
-
-		users = await nameQuery
-			.orderBy("user.updatedAt", "DESC", "NULLS LAST")
-			.take(ps.limit)
-			.skip(ps.offset)
-			.getMany();
-
-		if (users.length < ps.limit) {
-			const profQuery = UserProfiles.createQueryBuilder("prof")
-				.select("prof.userId")
-				.where("prof.description ILIKE :query", {
-					query: `%${ps.query}%`,
-				});
-
-			if (ps.origin === "local") {
-				profQuery.andWhere("prof.userHost IS NULL");
-			} else if (ps.origin === "remote") {
-				profQuery.andWhere("prof.userHost IS NOT NULL");
-			}
-
-			const query = Users.createQueryBuilder("user")
-				.where(`user.id IN (${profQuery.getQuery()})`)
-				.andWhere(
-					new Brackets((qb) => {
-						qb.where("user.updatedAt IS NULL").orWhere(
-							"user.updatedAt > :activeThreshold",
-							{ activeThreshold: activeThreshold },
-						);
-					}),
-				)
-				.andWhere("user.isSuspended = FALSE")
-				.setParameters(profQuery.getParameters());
-
-			users = users.concat(
-				await query
-					.orderBy("user.updatedAt", "DESC", "NULLS LAST")
-					.take(ps.limit)
-					.skip(ps.offset)
-					.getMany(),
-			);
-		}
-	}
-
-	return await Users.packMany(users, me, { detail: ps.detail });
-});
diff --git a/packages/backend/src/server/api/endpoints/users/show.ts b/packages/backend/src/server/api/endpoints/users/show.ts
deleted file mode 100644
index 49cac81fdb..0000000000
--- a/packages/backend/src/server/api/endpoints/users/show.ts
+++ /dev/null
@@ -1,146 +0,0 @@
-import type { FindOptionsWhere } from "typeorm";
-import { In, IsNull } from "typeorm";
-import { resolveUser } from "@/remote/resolve-user.js";
-import { Users } from "@/models/index.js";
-import type { User } from "@/models/entities/user.js";
-import define from "../../define.js";
-import { apiLogger } from "../../logger.js";
-import { ApiError } from "../../error.js";
-
-export const meta = {
-	tags: ["users"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	description: "Show the properties of a user.",
-
-	res: {
-		optional: false,
-		nullable: false,
-		oneOf: [
-			{
-				type: "object",
-				ref: "UserDetailed",
-			},
-			{
-				type: "array",
-				items: {
-					type: "object",
-					ref: "UserDetailed",
-				},
-			},
-		],
-	},
-
-	errors: {
-		failedToResolveRemoteUser: {
-			message: "Failed to resolve remote user.",
-			code: "FAILED_TO_RESOLVE_REMOTE_USER",
-			id: "ef7b9be4-9cba-4e6f-ab41-90ed171c7d3c",
-			kind: "server",
-		},
-
-		noSuchUser: {
-			message: "No such user.",
-			code: "NO_SUCH_USER",
-			id: "4362f8dc-731f-4ad8-a694-be5a88922a24",
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	anyOf: [
-		{
-			properties: {
-				userId: { type: "string", format: "misskey:id" },
-			},
-			required: ["userId"],
-		},
-		{
-			properties: {
-				userIds: {
-					type: "array",
-					uniqueItems: true,
-					items: {
-						type: "string",
-						format: "misskey:id",
-					},
-				},
-			},
-			required: ["userIds"],
-		},
-		{
-			properties: {
-				username: { type: "string" },
-				host: {
-					type: "string",
-					nullable: true,
-					description: "The local host is represented with `null`.",
-				},
-			},
-			required: ["username"],
-		},
-	],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	let user;
-
-	const isAdminOrModerator = me && (me.isAdmin || me.isModerator);
-
-	if (ps.userIds) {
-		if (ps.userIds.length === 0) {
-			return [];
-		}
-
-		const users = await Users.findBy(
-			isAdminOrModerator
-				? {
-						id: In(ps.userIds),
-				  }
-				: {
-						id: In(ps.userIds),
-						isSuspended: false,
-				  },
-		);
-
-		// リクエストされた通りに並べ替え
-		const _users: User[] = [];
-		for (const id of ps.userIds) {
-			_users.push(users.find((x) => x.id === id)!);
-		}
-
-		return await Promise.all(
-			_users.map((u) =>
-				Users.pack(u, me, {
-					detail: true,
-				}),
-			),
-		);
-	} else {
-		// Lookup user
-		if (typeof ps.host === "string" && typeof ps.username === "string") {
-			user = await resolveUser(ps.username, ps.host).catch((e) => {
-				apiLogger.warn(`failed to resolve remote user: ${e}`);
-				throw new ApiError(meta.errors.failedToResolveRemoteUser);
-			});
-		} else {
-			const q: FindOptionsWhere<User> =
-				ps.userId != null
-					? { id: ps.userId }
-					: { usernameLower: ps.username!.toLowerCase(), host: IsNull() };
-
-			user = await Users.findOneBy(q);
-		}
-
-		if (user == null || (!isAdminOrModerator && user.isSuspended)) {
-			throw new ApiError(meta.errors.noSuchUser);
-		}
-
-		return await Users.pack(user, me, {
-			detail: true,
-		});
-	}
-});
diff --git a/packages/backend/src/server/api/endpoints/users/stats.ts b/packages/backend/src/server/api/endpoints/users/stats.ts
deleted file mode 100644
index 83e821f498..0000000000
--- a/packages/backend/src/server/api/endpoints/users/stats.ts
+++ /dev/null
@@ -1,225 +0,0 @@
-import {
-	DriveFiles,
-	Followings,
-	NoteFavorites,
-	NoteReactions,
-	Notes,
-	PageLikes,
-	PollVotes,
-	Users,
-} from "@/models/index.js";
-import { awaitAll } from "@/prelude/await-all.js";
-import define from "../../define.js";
-import { ApiError } from "../../error.js";
-
-export const meta = {
-	tags: ["users"],
-
-	requireCredential: false,
-	requireCredentialPrivateMode: true,
-
-	description: "Show statistics about a user.",
-
-	errors: {
-		noSuchUser: {
-			message: "No such user.",
-			code: "NO_SUCH_USER",
-			id: "9e638e45-3b25-4ef7-8f95-07e8498f1819",
-		},
-	},
-
-	res: {
-		type: "object",
-		optional: false,
-		nullable: false,
-		properties: {
-			notesCount: {
-				type: "integer",
-				optional: false,
-				nullable: false,
-			},
-			repliesCount: {
-				type: "integer",
-				optional: false,
-				nullable: false,
-			},
-			renotesCount: {
-				type: "integer",
-				optional: false,
-				nullable: false,
-			},
-			repliedCount: {
-				type: "integer",
-				optional: false,
-				nullable: false,
-			},
-			renotedCount: {
-				type: "integer",
-				optional: false,
-				nullable: false,
-			},
-			pollVotesCount: {
-				type: "integer",
-				optional: false,
-				nullable: false,
-			},
-			pollVotedCount: {
-				type: "integer",
-				optional: false,
-				nullable: false,
-			},
-			localFollowingCount: {
-				type: "integer",
-				optional: false,
-				nullable: false,
-			},
-			remoteFollowingCount: {
-				type: "integer",
-				optional: false,
-				nullable: false,
-			},
-			localFollowersCount: {
-				type: "integer",
-				optional: false,
-				nullable: false,
-			},
-			remoteFollowersCount: {
-				type: "integer",
-				optional: false,
-				nullable: false,
-			},
-			followingCount: {
-				type: "integer",
-				optional: false,
-				nullable: false,
-			},
-			followersCount: {
-				type: "integer",
-				optional: false,
-				nullable: false,
-			},
-			sentReactionsCount: {
-				type: "integer",
-				optional: false,
-				nullable: false,
-			},
-			receivedReactionsCount: {
-				type: "integer",
-				optional: false,
-				nullable: false,
-			},
-			noteFavoritesCount: {
-				type: "integer",
-				optional: false,
-				nullable: false,
-			},
-			pageLikesCount: {
-				type: "integer",
-				optional: false,
-				nullable: false,
-			},
-			pageLikedCount: {
-				type: "integer",
-				optional: false,
-				nullable: false,
-			},
-			driveFilesCount: {
-				type: "integer",
-				optional: false,
-				nullable: false,
-			},
-			driveUsage: {
-				type: "integer",
-				optional: false,
-				nullable: false,
-				description: "Drive usage in bytes",
-			},
-		},
-	},
-} as const;
-
-export const paramDef = {
-	type: "object",
-	properties: {
-		userId: { type: "string", format: "misskey:id" },
-	},
-	required: ["userId"],
-} as const;
-
-export default define(meta, paramDef, async (ps, me) => {
-	const user = await Users.findOneBy({ id: ps.userId });
-	if (user == null) {
-		throw new ApiError(meta.errors.noSuchUser);
-	}
-
-	const result = await awaitAll({
-		notesCount: Notes.createQueryBuilder("note")
-			.where("note.userId = :userId", { userId: user.id })
-			.getCount(),
-		repliesCount: Notes.createQueryBuilder("note")
-			.where("note.userId = :userId", { userId: user.id })
-			.andWhere("note.replyId IS NOT NULL")
-			.getCount(),
-		renotesCount: Notes.createQueryBuilder("note")
-			.where("note.userId = :userId", { userId: user.id })
-			.andWhere("note.renoteId IS NOT NULL")
-			.getCount(),
-		repliedCount: Notes.createQueryBuilder("note")
-			.where("note.replyUserId = :userId", { userId: user.id })
-			.getCount(),
-		renotedCount: Notes.createQueryBuilder("note")
-			.where("note.renoteUserId = :userId", { userId: user.id })
-			.getCount(),
-		pollVotesCount: PollVotes.createQueryBuilder("vote")
-			.where("vote.userId = :userId", { userId: user.id })
-			.getCount(),
-		pollVotedCount: PollVotes.createQueryBuilder("vote")
-			.innerJoin("vote.note", "note")
-			.where("note.userId = :userId", { userId: user.id })
-			.getCount(),
-		localFollowingCount: Followings.createQueryBuilder("following")
-			.where("following.followerId = :userId", { userId: user.id })
-			.andWhere("following.followeeHost IS NULL")
-			.getCount(),
-		remoteFollowingCount: Followings.createQueryBuilder("following")
-			.where("following.followerId = :userId", { userId: user.id })
-			.andWhere("following.followeeHost IS NOT NULL")
-			.getCount(),
-		localFollowersCount: Followings.createQueryBuilder("following")
-			.where("following.followeeId = :userId", { userId: user.id })
-			.andWhere("following.followerHost IS NULL")
-			.getCount(),
-		remoteFollowersCount: Followings.createQueryBuilder("following")
-			.where("following.followeeId = :userId", { userId: user.id })
-			.andWhere("following.followerHost IS NOT NULL")
-			.getCount(),
-		sentReactionsCount: NoteReactions.createQueryBuilder("reaction")
-			.where("reaction.userId = :userId", { userId: user.id })
-			.getCount(),
-		receivedReactionsCount: NoteReactions.createQueryBuilder("reaction")
-			.innerJoin("reaction.note", "note")
-			.where("note.userId = :userId", { userId: user.id })
-			.getCount(),
-		noteFavoritesCount: NoteFavorites.createQueryBuilder("favorite")
-			.where("favorite.userId = :userId", { userId: user.id })
-			.getCount(),
-		pageLikesCount: PageLikes.createQueryBuilder("like")
-			.where("like.userId = :userId", { userId: user.id })
-			.getCount(),
-		pageLikedCount: PageLikes.createQueryBuilder("like")
-			.innerJoin("like.page", "page")
-			.where("page.userId = :userId", { userId: user.id })
-			.getCount(),
-		driveFilesCount: DriveFiles.createQueryBuilder("file")
-			.where("file.userId = :userId", { userId: user.id })
-			.getCount(),
-		driveUsage: DriveFiles.calcDriveUsageOf(user),
-	});
-
-	result.followingCount =
-		result.localFollowingCount + result.remoteFollowingCount;
-	result.followersCount =
-		result.localFollowersCount + result.remoteFollowersCount;
-
-	return result;
-});
diff --git a/packages/backend/src/server/api/error.ts b/packages/backend/src/server/api/error.ts
deleted file mode 100644
index c58561a04e..0000000000
--- a/packages/backend/src/server/api/error.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-type E = {
-	message: string;
-	code: string;
-	id: string;
-	kind?: "client" | "server";
-	httpStatusCode?: number;
-};
-
-export class ApiError extends Error {
-	public message: string;
-	public code: string;
-	public id: string;
-	public kind: string;
-	public httpStatusCode?: number;
-	public info?: any;
-
-	constructor(e?: E | null | undefined, info?: any | null | undefined) {
-		if (e == null)
-			e = {
-				message:
-					"Internal error occurred. Please contact us if the error persists.",
-				code: "INTERNAL_ERROR",
-				id: "5d37dbcb-891e-41ca-a3d6-e690c97775ac",
-				kind: "server",
-				httpStatusCode: 500,
-			};
-
-		super(e.message);
-		this.message = e.message;
-		this.code = e.code;
-		this.id = e.id;
-		this.kind = e.kind || "client";
-		this.httpStatusCode = e.httpStatusCode;
-		this.info = info;
-	}
-}
diff --git a/packages/backend/src/server/api/index.ts b/packages/backend/src/server/api/index.ts
deleted file mode 100644
index b8e4231655..0000000000
--- a/packages/backend/src/server/api/index.ts
+++ /dev/null
@@ -1,230 +0,0 @@
-/**
- * API Server
- */
-
-import Koa from "koa";
-import Router from "@koa/router";
-import multer from "@koa/multer";
-import bodyParser from "koa-bodyparser";
-import cors from "@koa/cors";
-import {
-	apiMastodonCompatible,
-	getClient,
-} from "./mastodon/ApiMastodonCompatibleService.js";
-import { Instances, AccessTokens, Users } from "@/models/index.js";
-import config from "@/config/index.js";
-import fs from "fs";
-import endpoints from "./endpoints.js";
-import compatibility from "./compatibility.js";
-import handler from "./api-handler.js";
-import signup from "./private/signup.js";
-import signin from "./private/signin.js";
-import signupPending from "./private/signup-pending.js";
-import discord from "./service/discord.js";
-import github from "./service/github.js";
-import twitter from "./service/twitter.js";
-import { koaBody } from "koa-body";
-import {
-	convertId,
-	IdConvertType as IdType,
-} from "../../../native-utils/built/index.js";
-
-// re-export native rust id conversion (function and enum)
-export { IdType, convertId };
-
-// Init app
-const app = new Koa();
-
-app.use(
-	cors({
-		origin: "*",
-	}),
-);
-
-// No caching
-app.use(async (ctx, next) => {
-	ctx.set("Cache-Control", "private, max-age=0, must-revalidate");
-	await next();
-});
-
-// Init router
-const router = new Router();
-const mastoRouter = new Router();
-const mastoFileRouter = new Router();
-const errorRouter = new Router();
-
-// Init multer instance
-const upload = multer({
-	storage: multer.diskStorage({}),
-	limits: {
-		fileSize: config.maxFileSize || 262144000,
-		files: 1,
-	},
-});
-
-router.use(
-	bodyParser({
-		// リクエストが multipart/form-data でない限りはJSONだと見なす
-		detectJSON: (ctx) =>
-			!(
-				ctx.is("multipart/form-data") ||
-				ctx.is("application/x-www-form-urlencoded")
-			),
-	}),
-);
-
-mastoRouter.use(
-	koaBody({
-		multipart: true,
-		urlencoded: true,
-	}),
-);
-
-mastoFileRouter.post("/v1/media", upload.single("file"), async (ctx) => {
-	const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-	const accessTokens = ctx.headers.authorization;
-	const client = getClient(BASE_URL, accessTokens);
-	try {
-		let multipartData = await ctx.file;
-		if (!multipartData) {
-			ctx.body = { error: "No image" };
-			ctx.status = 401;
-			return;
-		}
-		const data = await client.uploadMedia(multipartData);
-		ctx.body = data.data;
-	} catch (e: any) {
-		console.error(e);
-		ctx.status = 401;
-		ctx.body = e.response.data;
-	}
-});
-mastoFileRouter.post("/v2/media", upload.single("file"), async (ctx) => {
-	const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-	const accessTokens = ctx.headers.authorization;
-	const client = getClient(BASE_URL, accessTokens);
-	try {
-		let multipartData = await ctx.file;
-		if (!multipartData) {
-			ctx.body = { error: "No image" };
-			ctx.status = 401;
-			return;
-		}
-		const data = await client.uploadMedia(multipartData);
-		ctx.body = data.data;
-	} catch (e: any) {
-		console.error(e);
-		ctx.status = 401;
-		ctx.body = e.response.data;
-	}
-});
-
-mastoRouter.use(async (ctx, next) => {
-	if (ctx.request.query) {
-		if (!ctx.request.body || Object.keys(ctx.request.body).length === 0) {
-			ctx.request.body = ctx.request.query;
-		} else {
-			ctx.request.body = { ...ctx.request.body, ...ctx.request.query };
-		}
-	}
-	await next();
-});
-
-apiMastodonCompatible(mastoRouter);
-
-/**
- * Register endpoint handlers
- */
-for (const endpoint of [...endpoints, ...compatibility]) {
-	if (endpoint.meta.requireFile) {
-		router.post(
-			`/${endpoint.name}`,
-			upload.single("file"),
-			handler.bind(null, endpoint),
-		);
-	} else {
-		// 後方互換性のため
-		if (endpoint.name.includes("-")) {
-			router.post(
-				`/${endpoint.name.replace(/-/g, "_")}`,
-				handler.bind(null, endpoint),
-			);
-
-			if (endpoint.meta.allowGet) {
-				router.get(
-					`/${endpoint.name.replace(/-/g, "_")}`,
-					handler.bind(null, endpoint),
-				);
-			} else {
-				router.get(`/${endpoint.name.replace(/-/g, "_")}`, async (ctx) => {
-					ctx.status = 405;
-				});
-			}
-		}
-
-		router.post(`/${endpoint.name}`, handler.bind(null, endpoint));
-
-		if (endpoint.meta.allowGet) {
-			router.get(`/${endpoint.name}`, handler.bind(null, endpoint));
-		} else {
-			router.get(`/${endpoint.name}`, async (ctx) => {
-				ctx.status = 405;
-			});
-		}
-	}
-}
-
-router.post("/signup", signup);
-router.post("/signin", signin);
-router.post("/signup-pending", signupPending);
-
-router.use(discord.routes());
-router.use(github.routes());
-router.use(twitter.routes());
-
-router.get("/v1/instance/peers", async (ctx) => {
-	const instances = await Instances.find({
-		select: ["host"],
-		where: {
-			isSuspended: false,
-		},
-	});
-
-	ctx.body = instances.map((instance) => instance.host);
-});
-
-router.post("/miauth/:session/check", async (ctx) => {
-	const token = await AccessTokens.findOneBy({
-		session: ctx.params.session,
-	});
-
-	if (token?.session != null && !token.fetched) {
-		AccessTokens.update(token.id, {
-			fetched: true,
-		});
-
-		ctx.body = {
-			ok: true,
-			token: token.token,
-			user: await Users.pack(token.userId, null, { detail: true }),
-		};
-	} else {
-		ctx.body = {
-			ok: false,
-		};
-	}
-});
-
-// Return 404 for unknown API
-errorRouter.all("(.*)", async (ctx) => {
-	ctx.status = 404;
-});
-
-// Register router
-app.use(mastoFileRouter.routes());
-app.use(mastoRouter.routes());
-app.use(mastoRouter.allowedMethods());
-app.use(router.routes());
-app.use(errorRouter.routes());
-
-export default app;
diff --git a/packages/backend/src/server/api/limiter.ts b/packages/backend/src/server/api/limiter.ts
deleted file mode 100644
index dd005ad136..0000000000
--- a/packages/backend/src/server/api/limiter.ts
+++ /dev/null
@@ -1,85 +0,0 @@
-import Limiter from "ratelimiter";
-import { CacheableLocalUser, User } from "@/models/entities/user.js";
-import Logger from "@/services/logger.js";
-import { redisClient } from "../../db/redis.js";
-import type { IEndpointMeta } from "./endpoints.js";
-
-const logger = new Logger("limiter");
-
-export const limiter = (
-	limitation: IEndpointMeta["limit"] & { key: NonNullable<string> },
-	actor: string,
-) =>
-	new Promise<void>((ok, reject) => {
-		if (process.env.NODE_ENV === "test") ok();
-
-		const hasShortTermLimit = typeof limitation.minInterval === "number";
-
-		const hasLongTermLimit =
-			typeof limitation.duration === "number" &&
-			typeof limitation.max === "number";
-
-		if (hasShortTermLimit) {
-			min();
-		} else if (hasLongTermLimit) {
-			max();
-		} else {
-			ok();
-		}
-
-		// Short-term limit
-		function min(): void {
-			const minIntervalLimiter = new Limiter({
-				id: `${actor}:${limitation.key}:min`,
-				duration: limitation.minInterval,
-				max: 1,
-				db: redisClient,
-			});
-
-			minIntervalLimiter.get((err, info) => {
-				if (err) {
-					return reject("ERR");
-				}
-
-				logger.debug(
-					`${actor} ${limitation.key} min remaining: ${info.remaining}`,
-				);
-
-				if (info.remaining === 0) {
-					reject("BRIEF_REQUEST_INTERVAL");
-				} else {
-					if (hasLongTermLimit) {
-						max();
-					} else {
-						ok();
-					}
-				}
-			});
-		}
-
-		// Long term limit
-		function max(): void {
-			const limiter = new Limiter({
-				id: `${actor}:${limitation.key}`,
-				duration: limitation.duration,
-				max: limitation.max,
-				db: redisClient,
-			});
-
-			limiter.get((err, info) => {
-				if (err) {
-					return reject("ERR");
-				}
-
-				logger.debug(
-					`${actor} ${limitation.key} max remaining: ${info.remaining}`,
-				);
-
-				if (info.remaining === 0) {
-					reject("RATE_LIMIT_EXCEEDED");
-				} else {
-					ok();
-				}
-			});
-		}
-	});
diff --git a/packages/backend/src/server/api/logger.ts b/packages/backend/src/server/api/logger.ts
deleted file mode 100644
index 083888ed77..0000000000
--- a/packages/backend/src/server/api/logger.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import Logger from "@/services/logger.js";
-
-export const apiLogger = new Logger("api");
diff --git a/packages/backend/src/server/api/mastodon/ApiMastodonCompatibleService.ts b/packages/backend/src/server/api/mastodon/ApiMastodonCompatibleService.ts
deleted file mode 100644
index e8dfe52812..0000000000
--- a/packages/backend/src/server/api/mastodon/ApiMastodonCompatibleService.ts
+++ /dev/null
@@ -1,140 +0,0 @@
-import Router from "@koa/router";
-import megalodon, { MegalodonInterface } from "@calckey/megalodon";
-import { apiAuthMastodon } from "./endpoints/auth.js";
-import { apiAccountMastodon } from "./endpoints/account.js";
-import { apiStatusMastodon } from "./endpoints/status.js";
-import { apiFilterMastodon } from "./endpoints/filter.js";
-import { apiTimelineMastodon } from "./endpoints/timeline.js";
-import { apiNotificationsMastodon } from "./endpoints/notifications.js";
-import { apiSearchMastodon } from "./endpoints/search.js";
-import { getInstance } from "./endpoints/meta.js";
-
-export function getClient(
-	BASE_URL: string,
-	authorization: string | undefined,
-): MegalodonInterface {
-	const accessTokenArr = authorization?.split(" ") ?? [null];
-	const accessToken = accessTokenArr[accessTokenArr.length - 1];
-	const generator = (megalodon as any).default;
-	const client = generator(
-		"misskey",
-		BASE_URL,
-		accessToken,
-	) as MegalodonInterface;
-	return client;
-}
-
-export function apiMastodonCompatible(router: Router): void {
-	apiAuthMastodon(router);
-	apiAccountMastodon(router);
-	apiStatusMastodon(router);
-	apiFilterMastodon(router);
-	apiTimelineMastodon(router);
-	apiNotificationsMastodon(router);
-	apiSearchMastodon(router);
-
-	router.get("/v1/custom_emojis", async (ctx) => {
-		const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`;
-		const accessTokens = ctx.request.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens);
-		try {
-			const data = await client.getInstanceCustomEmojis();
-			ctx.body = data.data;
-		} catch (e: any) {
-			console.error(e);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-
-	router.get("/v1/instance", async (ctx) => {
-		const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`;
-		const accessTokens = ctx.request.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens); // we are using this here, because in private mode some info isnt
-		// displayed without being logged in
-		try {
-			const data = await client.getInstance();
-			ctx.body = await getInstance(data.data);
-		} catch (e: any) {
-			console.error(e);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-
-	router.get("/v1/announcements", async (ctx) => {
-		const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`;
-		const accessTokens = ctx.request.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens);
-		try {
-			const data = await client.getInstanceAnnouncements();
-			ctx.body = data.data;
-		} catch (e: any) {
-			console.error(e);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-
-	router.post<{ Params: { id: string } }>(
-		"/v1/announcements/:id/dismiss",
-		async (ctx) => {
-			const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`;
-			const accessTokens = ctx.request.headers.authorization;
-			const client = getClient(BASE_URL, accessTokens);
-			try {
-				const data = await client.dismissInstanceAnnouncement(ctx.params.id);
-				ctx.body = data.data;
-			} catch (e: any) {
-				console.error(e);
-				ctx.status = 401;
-				ctx.body = e.response.data;
-			}
-		},
-	);
-
-	router.get("/v1/filters", async (ctx) => {
-		const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`;
-		const accessTokens = ctx.request.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens); // we are using this here, because in private mode some info isnt
-		// displayed without being logged in
-		try {
-			const data = await client.getFilters();
-			ctx.body = data.data;
-		} catch (e: any) {
-			console.error(e);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-
-	router.get("/v1/trends", async (ctx) => {
-		const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`;
-		const accessTokens = ctx.request.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens); // we are using this here, because in private mode some info isnt
-		// displayed without being logged in
-		try {
-			const data = await client.getInstanceTrends();
-			ctx.body = data.data;
-		} catch (e: any) {
-			console.error(e);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-
-	router.get("/v1/preferences", async (ctx) => {
-		const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`;
-		const accessTokens = ctx.request.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens); // we are using this here, because in private mode some info isnt
-		// displayed without being logged in
-		try {
-			const data = await client.getPreferences();
-			ctx.body = data.data;
-		} catch (e: any) {
-			console.error(e);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-}
diff --git a/packages/backend/src/server/api/mastodon/endpoints/account.ts b/packages/backend/src/server/api/mastodon/endpoints/account.ts
deleted file mode 100644
index 70bdb74f34..0000000000
--- a/packages/backend/src/server/api/mastodon/endpoints/account.ts
+++ /dev/null
@@ -1,545 +0,0 @@
-import { Users } from "@/models/index.js";
-import { resolveUser } from "@/remote/resolve-user.js";
-import Router from "@koa/router";
-import { FindOptionsWhere, IsNull } from "typeorm";
-import { getClient } from "../ApiMastodonCompatibleService.js";
-import { argsToBools, limitToInt } from "./timeline.js";
-import { convertId, IdType } from "../../index.js";
-
-const relationshipModel = {
-	id: "",
-	following: false,
-	followed_by: false,
-	delivery_following: false,
-	blocking: false,
-	blocked_by: false,
-	muting: false,
-	muting_notifications: false,
-	requested: false,
-	domain_blocking: false,
-	showing_reblogs: false,
-	endorsed: false,
-	notifying: false,
-	note: "",
-};
-
-export function apiAccountMastodon(router: Router): void {
-	router.get("/v1/accounts/verify_credentials", async (ctx) => {
-		const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-		const accessTokens = ctx.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens);
-		try {
-			const data = await client.verifyAccountCredentials();
-			let acct = data.data;
-			acct.id = convertId(acct.id, IdType.MastodonId);
-			acct.display_name = acct.display_name || acct.username;
-			acct.url = `${BASE_URL}/@${acct.url}`;
-			acct.note = acct.note || "";
-			acct.avatar_static = acct.avatar;
-			acct.header = acct.header || "https://http.cat/404";
-			acct.header_static = acct.header || "https://http.cat/404";
-			acct.source = {
-				note: acct.note,
-				fields: acct.fields,
-				privacy: "public",
-				sensitive: false,
-				language: "",
-			};
-			console.log(acct);
-			ctx.body = acct;
-		} catch (e: any) {
-			console.error(e);
-			console.error(e.response.data);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-	router.patch("/v1/accounts/update_credentials", async (ctx) => {
-		const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-		const accessTokens = ctx.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens);
-		try {
-			const data = await client.updateCredentials(
-				(ctx.request as any).body as any,
-			);
-			let resp = data.data;
-			resp.id = convertId(resp.id, IdType.MastodonId);
-			ctx.body = resp;
-		} catch (e: any) {
-			console.error(e);
-			console.error(e.response.data);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-	router.get("/v1/accounts/lookup", async (ctx) => {
-		const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-		const accessTokens = ctx.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens);
-		try {
-			const data = await client.search(
-				(ctx.request.query as any).acct,
-				"accounts",
-			);
-			let resp = data.data.accounts[0];
-			resp.id = convertId(resp.id, IdType.MastodonId);
-			ctx.body = resp;
-		} catch (e: any) {
-			console.error(e);
-			console.error(e.response.data);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-	router.get<{ Params: { id: string } }>("/v1/accounts/:id", async (ctx) => {
-		const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-		const accessTokens = ctx.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens);
-		try {
-			const calcId = convertId(ctx.params.id, IdType.CalckeyId);
-			const data = await client.getAccount(calcId);
-			let resp = data.data;
-			resp.id = convertId(resp.id, IdType.MastodonId);
-			ctx.body = resp;
-		} catch (e: any) {
-			console.error(e);
-			console.error(e.response.data);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-	router.get<{ Params: { id: string } }>(
-		"/v1/accounts/:id/statuses",
-		async (ctx) => {
-			const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-			const accessTokens = ctx.headers.authorization;
-			const client = getClient(BASE_URL, accessTokens);
-			try {
-				const data = await client.getAccountStatuses(
-					convertId(ctx.params.id, IdType.CalckeyId),
-					argsToBools(limitToInt(ctx.query as any)),
-				);
-				let resp = data.data;
-				for (let statIdx = 0; statIdx < resp.length; statIdx++) {
-					resp[statIdx].id = convertId(resp[statIdx].id, IdType.MastodonId);
-					resp[statIdx].in_reply_to_account_id = resp[statIdx]
-						.in_reply_to_account_id
-						? convertId(resp[statIdx].in_reply_to_account_id, IdType.MastodonId)
-						: null;
-					resp[statIdx].in_reply_to_id = resp[statIdx].in_reply_to_id
-						? convertId(resp[statIdx].in_reply_to_id, IdType.MastodonId)
-						: null;
-					let mentions = resp[statIdx].mentions;
-					for (let mtnIdx = 0; mtnIdx < mentions.length; mtnIdx++) {
-						resp[statIdx].mentions[mtnIdx].id = convertId(
-							mentions[mtnIdx].id,
-							IdType.MastodonId,
-						);
-					}
-				}
-				ctx.body = resp;
-			} catch (e: any) {
-				console.error(e);
-				console.error(e.response.data);
-				ctx.status = 401;
-				ctx.body = e.response.data;
-			}
-		},
-	);
-	router.get<{ Params: { id: string } }>(
-		"/v1/accounts/:id/followers",
-		async (ctx) => {
-			const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-			const accessTokens = ctx.headers.authorization;
-			const client = getClient(BASE_URL, accessTokens);
-			try {
-				const data = await client.getAccountFollowers(
-					convertId(ctx.params.id, IdType.CalckeyId),
-					limitToInt(ctx.query as any),
-				);
-				let resp = data.data;
-				for (let acctIdx = 0; acctIdx < resp.length; acctIdx++) {
-					resp[acctIdx].id = convertId(resp[acctIdx].id, IdType.MastodonId);
-				}
-				ctx.body = resp;
-			} catch (e: any) {
-				console.error(e);
-				console.error(e.response.data);
-				ctx.status = 401;
-				ctx.body = e.response.data;
-			}
-		},
-	);
-	router.get<{ Params: { id: string } }>(
-		"/v1/accounts/:id/following",
-		async (ctx) => {
-			const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-			const accessTokens = ctx.headers.authorization;
-			const client = getClient(BASE_URL, accessTokens);
-			try {
-				const data = await client.getAccountFollowing(
-					convertId(ctx.params.id, IdType.CalckeyId),
-					limitToInt(ctx.query as any),
-				);
-				let resp = data.data;
-				for (let acctIdx = 0; acctIdx < resp.length; acctIdx++) {
-					resp[acctIdx].id = convertId(resp[acctIdx].id, IdType.MastodonId);
-				}
-				ctx.body = resp;
-			} catch (e: any) {
-				console.error(e);
-				console.error(e.response.data);
-				ctx.status = 401;
-				ctx.body = e.response.data;
-			}
-		},
-	);
-	router.get<{ Params: { id: string } }>(
-		"/v1/accounts/:id/lists",
-		async (ctx) => {
-			const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-			const accessTokens = ctx.headers.authorization;
-			const client = getClient(BASE_URL, accessTokens);
-			try {
-				const data = await client.getAccountLists(ctx.params.id);
-				ctx.body = data.data;
-			} catch (e: any) {
-				console.error(e);
-				console.error(e.response.data);
-				ctx.status = 401;
-				ctx.body = e.response.data;
-			}
-		},
-	);
-	router.post<{ Params: { id: string } }>(
-		"/v1/accounts/:id/follow",
-		async (ctx) => {
-			const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-			const accessTokens = ctx.headers.authorization;
-			const client = getClient(BASE_URL, accessTokens);
-			try {
-				const data = await client.followAccount(
-					convertId(ctx.params.id, IdType.CalckeyId),
-				);
-				let acct = data.data;
-				acct.following = true;
-				acct.id = convertId(acct.id, IdType.MastodonId);
-				ctx.body = acct;
-			} catch (e: any) {
-				console.error(e);
-				console.error(e.response.data);
-				ctx.status = 401;
-				ctx.body = e.response.data;
-			}
-		},
-	);
-	router.post<{ Params: { id: string } }>(
-		"/v1/accounts/:id/unfollow",
-		async (ctx) => {
-			const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-			const accessTokens = ctx.headers.authorization;
-			const client = getClient(BASE_URL, accessTokens);
-			try {
-				const data = await client.unfollowAccount(
-					convertId(ctx.params.id, IdType.CalckeyId),
-				);
-				let acct = data.data;
-				acct.id = convertId(acct.id, IdType.MastodonId);
-				acct.following = false;
-				ctx.body = acct;
-			} catch (e: any) {
-				console.error(e);
-				console.error(e.response.data);
-				ctx.status = 401;
-				ctx.body = e.response.data;
-			}
-		},
-	);
-	router.post<{ Params: { id: string } }>(
-		"/v1/accounts/:id/block",
-		async (ctx) => {
-			const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-			const accessTokens = ctx.headers.authorization;
-			const client = getClient(BASE_URL, accessTokens);
-			try {
-				const data = await client.blockAccount(
-					convertId(ctx.params.id, IdType.CalckeyId),
-				);
-				let resp = data.data;
-				resp.id = convertId(resp.id, IdType.MastodonId);
-				ctx.body = resp;
-			} catch (e: any) {
-				console.error(e);
-				console.error(e.response.data);
-				ctx.status = 401;
-				ctx.body = e.response.data;
-			}
-		},
-	);
-	router.post<{ Params: { id: string } }>(
-		"/v1/accounts/:id/unblock",
-		async (ctx) => {
-			const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-			const accessTokens = ctx.headers.authorization;
-			const client = getClient(BASE_URL, accessTokens);
-			try {
-				const data = await client.unblockAccount(
-					convertId(ctx.params.id, IdType.MastodonId),
-				);
-				let resp = data.data;
-				resp.id = convertId(resp.id, IdType.MastodonId);
-				ctx.body = resp;
-			} catch (e: any) {
-				console.error(e);
-				console.error(e.response.data);
-				ctx.status = 401;
-				ctx.body = e.response.data;
-			}
-		},
-	);
-	router.post<{ Params: { id: string } }>(
-		"/v1/accounts/:id/mute",
-		async (ctx) => {
-			const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-			const accessTokens = ctx.headers.authorization;
-			const client = getClient(BASE_URL, accessTokens);
-			try {
-				const data = await client.muteAccount(
-					convertId(ctx.params.id, IdType.CalckeyId),
-					(ctx.request as any).body as any,
-				);
-				let resp = data.data;
-				resp.id = convertId(resp.id, IdType.MastodonId);
-				ctx.body = resp;
-			} catch (e: any) {
-				console.error(e);
-				console.error(e.response.data);
-				ctx.status = 401;
-				ctx.body = e.response.data;
-			}
-		},
-	);
-	router.post<{ Params: { id: string } }>(
-		"/v1/accounts/:id/unmute",
-		async (ctx) => {
-			const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-			const accessTokens = ctx.headers.authorization;
-			const client = getClient(BASE_URL, accessTokens);
-			try {
-				const data = await client.unmuteAccount(
-					convertId(ctx.params.id, IdType.CalckeyId),
-				);
-				let resp = data.data;
-				resp.id = convertId(resp.id, IdType.MastodonId);
-				ctx.body = resp;
-			} catch (e: any) {
-				console.error(e);
-				console.error(e.response.data);
-				ctx.status = 401;
-				ctx.body = e.response.data;
-			}
-		},
-	);
-	router.get("/v1/accounts/relationships", async (ctx) => {
-		const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-		const accessTokens = ctx.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens);
-		let users;
-		try {
-			// TODO: this should be body
-			let ids = ctx.request.query ? ctx.request.query["id[]"] : null;
-			if (typeof ids === "string") {
-				ids = [ids];
-			}
-			users = ids;
-			relationshipModel.id = ids?.toString() || "1";
-			if (!ids) {
-				ctx.body = [relationshipModel];
-				return;
-			}
-
-			let reqIds = [];
-			for (let i = 0; i < ids.length; i++) {
-				reqIds.push(convertId(ids[i], IdType.CalckeyId));
-			}
-
-			const data = await client.getRelationships(reqIds);
-			let resp = data.data;
-			for (let acctIdx = 0; acctIdx < resp.length; acctIdx++) {
-				resp[acctIdx].id = convertId(resp[acctIdx].id, IdType.MastodonId);
-			}
-			ctx.body = resp;
-		} catch (e: any) {
-			console.error(e);
-			let data = e.response.data;
-			data.users = users;
-			console.error(data);
-			ctx.status = 401;
-			ctx.body = data;
-		}
-	});
-	router.get("/v1/bookmarks", async (ctx) => {
-		const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-		const accessTokens = ctx.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens);
-		try {
-			const data = (await client.getBookmarks(
-				limitToInt(ctx.query as any),
-			)) as any;
-			let resp = data.data;
-			for (let statIdx = 0; statIdx < resp.length; statIdx++) {
-				resp[statIdx].id = convertId(resp[statIdx].id, IdType.MastodonId);
-				resp[statIdx].in_reply_to_account_id = resp[statIdx]
-					.in_reply_to_account_id
-					? convertId(resp[statIdx].in_reply_to_account_id, IdType.MastodonId)
-					: null;
-				resp[statIdx].in_reply_to_id = resp[statIdx].in_reply_to_id
-					? convertId(resp[statIdx].in_reply_to_id, IdType.MastodonId)
-					: null;
-				let mentions = resp[statIdx].mentions;
-				for (let mtnIdx = 0; mtnIdx < mentions.length; mtnIdx++) {
-					resp[statIdx].mentions[mtnIdx].id = convertId(
-						mentions[mtnIdx].id,
-						IdType.MastodonId,
-					);
-				}
-			}
-			ctx.body = resp;
-		} catch (e: any) {
-			console.error(e);
-			console.error(e.response.data);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-	router.get("/v1/favourites", async (ctx) => {
-		const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-		const accessTokens = ctx.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens);
-		try {
-			const data = await client.getFavourites(limitToInt(ctx.query as any));
-			let resp = data.data;
-			for (let statIdx = 0; statIdx < resp.length; statIdx++) {
-				resp[statIdx].id = convertId(resp[statIdx].id, IdType.MastodonId);
-				resp[statIdx].in_reply_to_account_id = resp[statIdx]
-					.in_reply_to_account_id
-					? convertId(resp[statIdx].in_reply_to_account_id, IdType.MastodonId)
-					: null;
-				resp[statIdx].in_reply_to_id = resp[statIdx].in_reply_to_id
-					? convertId(resp[statIdx].in_reply_to_id, IdType.MastodonId)
-					: null;
-				let mentions = resp[statIdx].mentions;
-				for (let mtnIdx = 0; mtnIdx < mentions.length; mtnIdx++) {
-					resp[statIdx].mentions[mtnIdx].id = convertId(
-						mentions[mtnIdx].id,
-						IdType.MastodonId,
-					);
-				}
-			}
-			ctx.body = resp;
-		} catch (e: any) {
-			console.error(e);
-			console.error(e.response.data);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-	router.get("/v1/mutes", async (ctx) => {
-		const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-		const accessTokens = ctx.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens);
-		try {
-			const data = await client.getMutes(limitToInt(ctx.query as any));
-			let resp = data.data;
-			for (let acctIdx = 0; acctIdx < resp.length; acctIdx++) {
-				resp[acctIdx].id = convertId(resp[acctIdx].id, IdType.MastodonId);
-			}
-			ctx.body = resp;
-		} catch (e: any) {
-			console.error(e);
-			console.error(e.response.data);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-	router.get("/v1/blocks", async (ctx) => {
-		const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-		const accessTokens = ctx.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens);
-		try {
-			const data = await client.getBlocks(limitToInt(ctx.query as any));
-			let resp = data.data;
-			for (let acctIdx = 0; acctIdx < resp.length; acctIdx++) {
-				resp[acctIdx].id = convertId(resp[acctIdx].id, IdType.MastodonId);
-			}
-			ctx.body = resp;
-		} catch (e: any) {
-			console.error(e);
-			console.error(e.response.data);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-	router.get("/v1/follow_requests", async (ctx) => {
-		const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-		const accessTokens = ctx.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens);
-		try {
-			const data = await client.getFollowRequests(
-				((ctx.query as any) || { limit: 20 }).limit,
-			);
-			let resp = data.data;
-			for (let acctIdx = 0; acctIdx < resp.length; acctIdx++) {
-				resp[acctIdx].id = convertId(resp[acctIdx].id, IdType.MastodonId);
-			}
-			ctx.body = resp;
-		} catch (e: any) {
-			console.error(e);
-			console.error(e.response.data);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-	router.post<{ Params: { id: string } }>(
-		"/v1/follow_requests/:id/authorize",
-		async (ctx) => {
-			const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-			const accessTokens = ctx.headers.authorization;
-			const client = getClient(BASE_URL, accessTokens);
-			try {
-				const data = await client.acceptFollowRequest(
-					convertId(ctx.params.id, IdType.CalckeyId),
-				);
-				let resp = data.data;
-				resp.id = convertId(resp.id, IdType.MastodonId);
-				ctx.body = resp;
-			} catch (e: any) {
-				console.error(e);
-				console.error(e.response.data);
-				ctx.status = 401;
-				ctx.body = e.response.data;
-			}
-		},
-	);
-	router.post<{ Params: { id: string } }>(
-		"/v1/follow_requests/:id/reject",
-		async (ctx) => {
-			const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-			const accessTokens = ctx.headers.authorization;
-			const client = getClient(BASE_URL, accessTokens);
-			try {
-				const data = await client.rejectFollowRequest(
-					convertId(ctx.params.id, IdType.CalckeyId),
-				);
-				let resp = data.data;
-				resp.id = convertId(resp.id, IdType.MastodonId);
-				ctx.body = resp;
-			} catch (e: any) {
-				console.error(e);
-				console.error(e.response.data);
-				ctx.status = 401;
-				ctx.body = e.response.data;
-			}
-		},
-	);
-}
diff --git a/packages/backend/src/server/api/mastodon/endpoints/auth.ts b/packages/backend/src/server/api/mastodon/endpoints/auth.ts
deleted file mode 100644
index e2cfc47aff..0000000000
--- a/packages/backend/src/server/api/mastodon/endpoints/auth.ts
+++ /dev/null
@@ -1,81 +0,0 @@
-import megalodon, { MegalodonInterface } from "@calckey/megalodon";
-import Router from "@koa/router";
-import { koaBody } from "koa-body";
-import { getClient } from "../ApiMastodonCompatibleService.js";
-import bodyParser from "koa-bodyparser";
-
-const readScope = [
-	"read:account",
-	"read:drive",
-	"read:blocks",
-	"read:favorites",
-	"read:following",
-	"read:messaging",
-	"read:mutes",
-	"read:notifications",
-	"read:reactions",
-	"read:pages",
-	"read:page-likes",
-	"read:user-groups",
-	"read:channels",
-	"read:gallery",
-	"read:gallery-likes",
-];
-const writeScope = [
-	"write:account",
-	"write:drive",
-	"write:blocks",
-	"write:favorites",
-	"write:following",
-	"write:messaging",
-	"write:mutes",
-	"write:notes",
-	"write:notifications",
-	"write:reactions",
-	"write:votes",
-	"write:pages",
-	"write:page-likes",
-	"write:user-groups",
-	"write:channels",
-	"write:gallery",
-	"write:gallery-likes",
-];
-
-export function apiAuthMastodon(router: Router): void {
-	router.post("/v1/apps", async (ctx) => {
-		const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`;
-		const client = getClient(BASE_URL, "");
-		const body: any = ctx.request.body || ctx.request.query;
-		try {
-			let scope = body.scopes;
-			if (typeof scope === "string") scope = scope.split(" ");
-			const pushScope = new Set<string>();
-			for (const s of scope) {
-				if (s.match(/^read/)) for (const r of readScope) pushScope.add(r);
-				if (s.match(/^write/)) for (const r of writeScope) pushScope.add(r);
-			}
-			const scopeArr = Array.from(pushScope);
-
-			const red = body.redirect_uris;
-			const appData = await client.registerApp(body.client_name, {
-				scopes: scopeArr,
-				redirect_uris: red,
-				website: body.website,
-			});
-			const returns = {
-				id: Math.floor(Math.random() * 100).toString(),
-				name: appData.name,
-				website: body.website,
-				redirect_uri: red,
-				client_id: Buffer.from(appData.url || "").toString("base64"),
-				client_secret: appData.clientSecret,
-			};
-			console.log(returns);
-			ctx.body = returns;
-		} catch (e: any) {
-			console.error(e);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-}
diff --git a/packages/backend/src/server/api/mastodon/endpoints/filter.ts b/packages/backend/src/server/api/mastodon/endpoints/filter.ts
deleted file mode 100644
index d21bc1d330..0000000000
--- a/packages/backend/src/server/api/mastodon/endpoints/filter.ts
+++ /dev/null
@@ -1,84 +0,0 @@
-import megalodon, { MegalodonInterface } from "@calckey/megalodon";
-import Router from "@koa/router";
-import { getClient } from "../ApiMastodonCompatibleService.js";
-
-export function apiFilterMastodon(router: Router): void {
-	router.get("/v1/filters", async (ctx) => {
-		const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`;
-		const accessTokens = ctx.request.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens);
-		const body: any = ctx.request.body;
-		try {
-			const data = await client.getFilters();
-			ctx.body = data.data;
-		} catch (e: any) {
-			console.error(e);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-
-	router.get("/v1/filters/:id", async (ctx) => {
-		const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`;
-		const accessTokens = ctx.request.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens);
-		const body: any = ctx.request.body;
-		try {
-			const data = await client.getFilter(ctx.params.id);
-			ctx.body = data.data;
-		} catch (e: any) {
-			console.error(e);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-
-	router.post("/v1/filters", async (ctx) => {
-		const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`;
-		const accessTokens = ctx.request.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens);
-		const body: any = ctx.request.body;
-		try {
-			const data = await client.createFilter(body.phrase, body.context, body);
-			ctx.body = data.data;
-		} catch (e: any) {
-			console.error(e);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-
-	router.post("/v1/filters/:id", async (ctx) => {
-		const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`;
-		const accessTokens = ctx.request.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens);
-		const body: any = ctx.request.body;
-		try {
-			const data = await client.updateFilter(
-				ctx.params.id,
-				body.phrase,
-				body.context,
-			);
-			ctx.body = data.data;
-		} catch (e: any) {
-			console.error(e);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-
-	router.delete("/v1/filters/:id", async (ctx) => {
-		const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`;
-		const accessTokens = ctx.request.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens);
-		const body: any = ctx.request.body;
-		try {
-			const data = await client.deleteFilter(ctx.params.id);
-			ctx.body = data.data;
-		} catch (e: any) {
-			console.error(e);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-}
diff --git a/packages/backend/src/server/api/mastodon/endpoints/meta.ts b/packages/backend/src/server/api/mastodon/endpoints/meta.ts
deleted file mode 100644
index d362d1b9e5..0000000000
--- a/packages/backend/src/server/api/mastodon/endpoints/meta.ts
+++ /dev/null
@@ -1,111 +0,0 @@
-import { Entity } from "@calckey/megalodon";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { Users, Notes } from "@/models/index.js";
-import { IsNull, MoreThan } from "typeorm";
-
-// TODO: add calckey features
-export async function getInstance(response: Entity.Instance) {
-	const meta = await fetchMeta(true);
-	const totalUsers = Users.count({ where: { host: IsNull() } });
-	const totalStatuses = Notes.count({ where: { userHost: IsNull() } });
-	return {
-		uri: response.uri,
-		title: response.title || "Calckey",
-		short_description:
-			response.description.substring(0, 50) || "See real server website",
-		description:
-			response.description ||
-			"This is a vanilla Calckey Instance. It doesnt seem to have a description. BTW you are using the Mastodon api to access this server :)",
-		email: response.email || "",
-		version: "3.0.0 compatible (3.5+ Calckey)", //I hope this version string is correct, we will need to test it.
-		urls: response.urls,
-		stats: {
-			user_count: await totalUsers,
-			status_count: await totalStatuses,
-			domain_count: response.stats.domain_count,
-		},
-		thumbnail: response.thumbnail || "https://http.cat/404",
-		languages: meta.langs,
-		registrations: !meta.disableRegistration || response.registrations,
-		approval_required: !response.registrations,
-		invites_enabled: response.registrations,
-		configuration: {
-			accounts: {
-				max_featured_tags: 20,
-			},
-			statuses: {
-				max_characters: 3000,
-				max_media_attachments: 4,
-				characters_reserved_per_url: response.uri.length,
-			},
-			media_attachments: {
-				supported_mime_types: [
-					"image/jpeg",
-					"image/png",
-					"image/gif",
-					"image/heic",
-					"image/heif",
-					"image/webp",
-					"image/avif",
-					"video/webm",
-					"video/mp4",
-					"video/quicktime",
-					"video/ogg",
-					"audio/wave",
-					"audio/wav",
-					"audio/x-wav",
-					"audio/x-pn-wave",
-					"audio/vnd.wave",
-					"audio/ogg",
-					"audio/vorbis",
-					"audio/mpeg",
-					"audio/mp3",
-					"audio/webm",
-					"audio/flac",
-					"audio/aac",
-					"audio/m4a",
-					"audio/x-m4a",
-					"audio/mp4",
-					"audio/3gpp",
-					"video/x-ms-asf",
-				],
-				image_size_limit: 10485760,
-				image_matrix_limit: 16777216,
-				video_size_limit: 41943040,
-				video_frame_rate_limit: 60,
-				video_matrix_limit: 2304000,
-			},
-			polls: {
-				max_options: 8,
-				max_characters_per_option: 50,
-				min_expiration: 300,
-				max_expiration: 2629746,
-			},
-		},
-		contact_account: {
-			id: "1",
-			username: "admin",
-			acct: "admin",
-			display_name: "admin",
-			locked: true,
-			bot: true,
-			discoverable: false,
-			group: false,
-			created_at: new Date().toISOString(),
-			note: "<p>Please refer to the original instance for the actual admin contact.</p>",
-			url: `${response.uri}/`,
-			avatar: `${response.uri}/static-assets/badges/info.png`,
-			avatar_static: `${response.uri}/static-assets/badges/info.png`,
-			header: "https://http.cat/404",
-			header_static: "https://http.cat/404",
-			followers_count: -1,
-			following_count: 0,
-			statuses_count: 0,
-			last_status_at: new Date().toISOString(),
-			noindex: true,
-			emojis: [],
-			fields: [],
-		},
-		rules: [],
-	};
-}
diff --git a/packages/backend/src/server/api/mastodon/endpoints/notifications.ts b/packages/backend/src/server/api/mastodon/endpoints/notifications.ts
deleted file mode 100644
index 8508f1d486..0000000000
--- a/packages/backend/src/server/api/mastodon/endpoints/notifications.ts
+++ /dev/null
@@ -1,90 +0,0 @@
-import megalodon, { MegalodonInterface } from "@calckey/megalodon";
-import Router from "@koa/router";
-import { koaBody } from "koa-body";
-import { getClient } from "../ApiMastodonCompatibleService.js";
-import { toTextWithReaction } from "./timeline.js";
-function toLimitToInt(q: any) {
-	if (q.limit) if (typeof q.limit === "string") q.limit = parseInt(q.limit, 10);
-	return q;
-}
-
-export function apiNotificationsMastodon(router: Router): void {
-	router.get("/v1/notifications", async (ctx) => {
-		const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`;
-		const accessTokens = ctx.request.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens);
-		const body: any = ctx.request.body;
-		try {
-			const data = await client.getNotifications(toLimitToInt(ctx.query));
-			const notfs = data.data;
-			const ret = notfs.map((n) => {
-				if (n.type !== "follow" && n.type !== "follow_request") {
-					if (n.type === "reaction") n.type = "favourite";
-					n.status = toTextWithReaction(
-						n.status ? [n.status] : [],
-						ctx.hostname,
-					)[0];
-					return n;
-				} else {
-					return n;
-				}
-			});
-			ctx.body = ret;
-		} catch (e: any) {
-			console.error(e);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-
-	router.get("/v1/notification/:id", async (ctx) => {
-		const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`;
-		const accessTokens = ctx.request.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens);
-		const body: any = ctx.request.body;
-		try {
-			const dataRaw = await client.getNotification(ctx.params.id);
-			const data = dataRaw.data;
-			if (data.type !== "follow" && data.type !== "follow_request") {
-				if (data.type === "reaction") data.type = "favourite";
-				ctx.body = toTextWithReaction([data as any], ctx.request.hostname)[0];
-			} else {
-				ctx.body = data;
-			}
-		} catch (e: any) {
-			console.error(e);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-
-	router.post("/v1/notifications/clear", async (ctx) => {
-		const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`;
-		const accessTokens = ctx.request.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens);
-		const body: any = ctx.request.body;
-		try {
-			const data = await client.dismissNotifications();
-			ctx.body = data.data;
-		} catch (e: any) {
-			console.error(e);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-
-	router.post("/v1/notification/:id/dismiss", async (ctx) => {
-		const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`;
-		const accessTokens = ctx.request.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens);
-		const body: any = ctx.request.body;
-		try {
-			const data = await client.dismissNotification(ctx.params.id);
-			ctx.body = data.data;
-		} catch (e: any) {
-			console.error(e);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-}
diff --git a/packages/backend/src/server/api/mastodon/endpoints/search.ts b/packages/backend/src/server/api/mastodon/endpoints/search.ts
deleted file mode 100644
index e4990811ae..0000000000
--- a/packages/backend/src/server/api/mastodon/endpoints/search.ts
+++ /dev/null
@@ -1,135 +0,0 @@
-import megalodon, { MegalodonInterface } from "@calckey/megalodon";
-import Router from "@koa/router";
-import { getClient } from "../ApiMastodonCompatibleService.js";
-import axios from "axios";
-import { Converter } from "@calckey/megalodon";
-import { limitToInt } from "./timeline.js";
-
-export function apiSearchMastodon(router: Router): void {
-	router.get("/v1/search", async (ctx) => {
-		const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`;
-		const accessTokens = ctx.request.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens);
-		const body: any = ctx.request.body;
-		try {
-			const query: any = limitToInt(ctx.query);
-			const type = query.type || "";
-			const data = await client.search(query.q, type, query);
-			ctx.body = data.data;
-		} catch (e: any) {
-			console.error(e);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-	router.get("/v2/search", async (ctx) => {
-		const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`;
-		const accessTokens = ctx.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens);
-		try {
-			const query: any = limitToInt(ctx.query);
-			const type = query.type;
-			if (type) {
-				const data = await client.search(query.q, type, query);
-				ctx.body = data.data;
-			} else {
-				const acct = await client.search(query.q, "accounts", query);
-				const stat = await client.search(query.q, "statuses", query);
-				const tags = await client.search(query.q, "hashtags", query);
-				ctx.body = {
-					accounts: acct.data.accounts,
-					statuses: stat.data.statuses,
-					hashtags: tags.data.hashtags,
-				};
-			}
-		} catch (e: any) {
-			console.error(e);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-	router.get("/v1/trends/statuses", async (ctx) => {
-		const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`;
-		const accessTokens = ctx.headers.authorization;
-		try {
-			const data = await getHighlight(
-				BASE_URL,
-				ctx.request.hostname,
-				accessTokens,
-			);
-			ctx.body = data;
-		} catch (e: any) {
-			console.error(e);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-	router.get("/v2/suggestions", async (ctx) => {
-		const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`;
-		const accessTokens = ctx.headers.authorization;
-		try {
-			const query: any = ctx.query;
-			const data = await getFeaturedUser(
-				BASE_URL,
-				ctx.request.hostname,
-				accessTokens,
-				query.limit || 20,
-			);
-			console.log(data);
-			ctx.body = data;
-		} catch (e: any) {
-			console.error(e);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-}
-async function getHighlight(
-	BASE_URL: string,
-	domain: string,
-	accessTokens: string | undefined,
-) {
-	const accessTokenArr = accessTokens?.split(" ") ?? [null];
-	const accessToken = accessTokenArr[accessTokenArr.length - 1];
-	try {
-		const api = await axios.post(`${BASE_URL}/api/notes/featured`, {
-			i: accessToken,
-		});
-		const data: MisskeyEntity.Note[] = api.data;
-		return data.map((note) => Converter.note(note, domain));
-	} catch (e: any) {
-		console.log(e);
-		console.log(e.response.data);
-		return [];
-	}
-}
-async function getFeaturedUser(
-	BASE_URL: string,
-	host: string,
-	accessTokens: string | undefined,
-	limit: number,
-) {
-	const accessTokenArr = accessTokens?.split(" ") ?? [null];
-	const accessToken = accessTokenArr[accessTokenArr.length - 1];
-	try {
-		const api = await axios.post(`${BASE_URL}/api/users`, {
-			i: accessToken,
-			limit,
-			origin: "local",
-			sort: "+follower",
-			state: "alive",
-		});
-		const data: MisskeyEntity.UserDetail[] = api.data;
-		console.log(data);
-		return data.map((u) => {
-			return {
-				source: "past_interactions",
-				account: Converter.userDetail(u, host),
-			};
-		});
-	} catch (e: any) {
-		console.log(e);
-		console.log(e.response.data);
-		return [];
-	}
-}
diff --git a/packages/backend/src/server/api/mastodon/endpoints/status.ts b/packages/backend/src/server/api/mastodon/endpoints/status.ts
deleted file mode 100644
index fcfbd6aaaf..0000000000
--- a/packages/backend/src/server/api/mastodon/endpoints/status.ts
+++ /dev/null
@@ -1,445 +0,0 @@
-import Router from "@koa/router";
-import { getClient } from "../ApiMastodonCompatibleService.js";
-import { emojiRegexAtStartToEnd } from "@/misc/emoji-regex.js";
-import axios from "axios";
-import querystring from "node:querystring";
-import qs from "qs";
-import { limitToInt } from "./timeline.js";
-
-function normalizeQuery(data: any) {
-	const str = querystring.stringify(data);
-	return qs.parse(str);
-}
-
-export function apiStatusMastodon(router: Router): void {
-	router.post("/v1/statuses", async (ctx) => {
-		const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-		const accessTokens = ctx.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens);
-		try {
-			let body: any = ctx.request.body;
-			if (
-				(!body.poll && body["poll[options][]"]) ||
-				(!body.media_ids && body["media_ids[]"])
-			) {
-				body = normalizeQuery(body);
-			}
-			const text = body.status;
-			const removed = text.replace(/@\S+/g, "").replace(/\s|​/g, "");
-			const isDefaultEmoji = emojiRegexAtStartToEnd.test(removed);
-			const isCustomEmoji = /^:[a-zA-Z0-9@_]+:$/.test(removed);
-			if ((body.in_reply_to_id && isDefaultEmoji) || isCustomEmoji) {
-				const a = await client.createEmojiReaction(
-					body.in_reply_to_id,
-					removed,
-				);
-				ctx.body = a.data;
-			}
-			if (body.in_reply_to_id && removed === "/unreact") {
-				try {
-					const id = body.in_reply_to_id;
-					const post = await client.getStatus(id);
-					const react = post.data.emoji_reactions.filter((e) => e.me)[0].name;
-					const data = await client.deleteEmojiReaction(id, react);
-					ctx.body = data.data;
-				} catch (e: any) {
-					console.error(e);
-					ctx.status = 401;
-					ctx.body = e.response.data;
-				}
-			}
-			if (!body.media_ids) body.media_ids = undefined;
-			if (body.media_ids && !body.media_ids.length) body.media_ids = undefined;
-			const { sensitive } = body;
-			body.sensitive =
-				typeof sensitive === "string" ? sensitive === "true" : sensitive;
-			const data = await client.postStatus(text, body);
-			ctx.body = data.data;
-		} catch (e: any) {
-			console.error(e);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-	router.get<{ Params: { id: string } }>("/v1/statuses/:id", async (ctx) => {
-		const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-		const accessTokens = ctx.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens);
-		try {
-			const data = await client.getStatus(ctx.params.id);
-			ctx.body = data.data;
-		} catch (e: any) {
-			console.error(e);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-	router.delete<{ Params: { id: string } }>("/v1/statuses/:id", async (ctx) => {
-		const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-		const accessTokens = ctx.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens);
-		try {
-			const data = await client.deleteStatus(ctx.params.id);
-			ctx.body = data.data;
-		} catch (e: any) {
-			console.error(e.response.data, request.params.id);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-	interface IReaction {
-		id: string;
-		createdAt: string;
-		user: MisskeyEntity.User;
-		type: string;
-	}
-	router.get<{ Params: { id: string } }>(
-		"/v1/statuses/:id/context",
-		async (ctx) => {
-			const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-			const accessTokens = ctx.headers.authorization;
-			const client = getClient(BASE_URL, accessTokens);
-			try {
-				const id = ctx.params.id;
-				const data = await client.getStatusContext(
-					id,
-					limitToInt(ctx.query as any),
-				);
-				const status = await client.getStatus(id);
-				let reqInstance = axios.create({
-					headers: {
-						Authorization: ctx.headers.authorization,
-					},
-				});
-				const reactionsAxios = await reqInstance.get(
-					`${BASE_URL}/api/notes/reactions?noteId=${id}`,
-				);
-				const reactions: IReaction[] = reactionsAxios.data;
-				const text = reactions
-					.map((r) => `${r.type.replace("@.", "")} ${r.user.username}`)
-					.join("<br />");
-				data.data.descendants.unshift(
-					statusModel(
-						status.data.id,
-						status.data.account.id,
-						status.data.emojis,
-						text,
-					),
-				);
-				ctx.body = data.data;
-			} catch (e: any) {
-				console.error(e);
-				ctx.status = 401;
-				ctx.body = e.response.data;
-			}
-		},
-	);
-	router.get<{ Params: { id: string } }>(
-		"/v1/statuses/:id/reblogged_by",
-		async (ctx) => {
-			const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-			const accessTokens = ctx.headers.authorization;
-			const client = getClient(BASE_URL, accessTokens);
-			try {
-				const data = await client.getStatusRebloggedBy(ctx.params.id);
-				ctx.body = data.data;
-			} catch (e: any) {
-				console.error(e);
-				ctx.status = 401;
-				ctx.body = e.response.data;
-			}
-		},
-	);
-	router.get<{ Params: { id: string } }>(
-		"/v1/statuses/:id/favourited_by",
-		async (ctx) => {
-			ctx.body = [];
-		},
-	);
-	router.post<{ Params: { id: string } }>(
-		"/v1/statuses/:id/favourite",
-		async (ctx) => {
-			const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-			const accessTokens = ctx.headers.authorization;
-			const client = getClient(BASE_URL, accessTokens);
-			const react = await getFirstReaction(BASE_URL, accessTokens);
-			try {
-				const a = (await client.createEmojiReaction(
-					ctx.params.id,
-					react,
-				)) as any;
-				//const data = await client.favouriteStatus(ctx.params.id) as any;
-				ctx.body = a.data;
-			} catch (e: any) {
-				console.error(e);
-				console.error(e.response.data);
-				ctx.status = 401;
-				ctx.body = e.response.data;
-			}
-		},
-	);
-	router.post<{ Params: { id: string } }>(
-		"/v1/statuses/:id/unfavourite",
-		async (ctx) => {
-			const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-			const accessTokens = ctx.headers.authorization;
-			const client = getClient(BASE_URL, accessTokens);
-			const react = await getFirstReaction(BASE_URL, accessTokens);
-			try {
-				const data = await client.deleteEmojiReaction(ctx.params.id, react);
-				ctx.body = data.data;
-			} catch (e: any) {
-				console.error(e);
-				ctx.status = 401;
-				ctx.body = e.response.data;
-			}
-		},
-	);
-
-	router.post<{ Params: { id: string } }>(
-		"/v1/statuses/:id/reblog",
-		async (ctx) => {
-			const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-			const accessTokens = ctx.headers.authorization;
-			const client = getClient(BASE_URL, accessTokens);
-			try {
-				const data = await client.reblogStatus(ctx.params.id);
-				ctx.body = data.data;
-			} catch (e: any) {
-				console.error(e);
-				ctx.status = 401;
-				ctx.body = e.response.data;
-			}
-		},
-	);
-
-	router.post<{ Params: { id: string } }>(
-		"/v1/statuses/:id/unreblog",
-		async (ctx) => {
-			const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-			const accessTokens = ctx.headers.authorization;
-			const client = getClient(BASE_URL, accessTokens);
-			try {
-				const data = await client.unreblogStatus(ctx.params.id);
-				ctx.body = data.data;
-			} catch (e: any) {
-				console.error(e);
-				ctx.status = 401;
-				ctx.body = e.response.data;
-			}
-		},
-	);
-
-	router.post<{ Params: { id: string } }>(
-		"/v1/statuses/:id/bookmark",
-		async (ctx) => {
-			const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-			const accessTokens = ctx.headers.authorization;
-			const client = getClient(BASE_URL, accessTokens);
-			try {
-				const data = await client.bookmarkStatus(ctx.params.id);
-				ctx.body = data.data;
-			} catch (e: any) {
-				console.error(e);
-				ctx.status = 401;
-				ctx.body = e.response.data;
-			}
-		},
-	);
-
-	router.post<{ Params: { id: string } }>(
-		"/v1/statuses/:id/unbookmark",
-		async (ctx) => {
-			const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-			const accessTokens = ctx.headers.authorization;
-			const client = getClient(BASE_URL, accessTokens);
-			try {
-				const data = (await client.unbookmarkStatus(ctx.params.id)) as any;
-				ctx.body = data.data;
-			} catch (e: any) {
-				console.error(e);
-				ctx.status = 401;
-				ctx.body = e.response.data;
-			}
-		},
-	);
-
-	router.post<{ Params: { id: string } }>(
-		"/v1/statuses/:id/pin",
-		async (ctx) => {
-			const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-			const accessTokens = ctx.headers.authorization;
-			const client = getClient(BASE_URL, accessTokens);
-			try {
-				const data = await client.pinStatus(ctx.params.id);
-				ctx.body = data.data;
-			} catch (e: any) {
-				console.error(e);
-				ctx.status = 401;
-				ctx.body = e.response.data;
-			}
-		},
-	);
-
-	router.post<{ Params: { id: string } }>(
-		"/v1/statuses/:id/unpin",
-		async (ctx) => {
-			const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-			const accessTokens = ctx.headers.authorization;
-			const client = getClient(BASE_URL, accessTokens);
-			try {
-				const data = await client.unpinStatus(ctx.params.id);
-				ctx.body = data.data;
-			} catch (e: any) {
-				console.error(e);
-				ctx.status = 401;
-				ctx.body = e.response.data;
-			}
-		},
-	);
-	router.get<{ Params: { id: string } }>("/v1/media/:id", async (ctx) => {
-		const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-		const accessTokens = ctx.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens);
-		try {
-			const data = await client.getMedia(ctx.params.id);
-			ctx.body = data.data;
-		} catch (e: any) {
-			console.error(e);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-	router.put<{ Params: { id: string } }>("/v1/media/:id", async (ctx) => {
-		const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-		const accessTokens = ctx.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens);
-		try {
-			const data = await client.updateMedia(
-				ctx.params.id,
-				ctx.request.body as any,
-			);
-			ctx.body = data.data;
-		} catch (e: any) {
-			console.error(e);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-	router.get<{ Params: { id: string } }>("/v1/polls/:id", async (ctx) => {
-		const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-		const accessTokens = ctx.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens);
-		try {
-			const data = await client.getPoll(ctx.params.id);
-			ctx.body = data.data;
-		} catch (e: any) {
-			console.error(e);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-	router.post<{ Params: { id: string } }>(
-		"/v1/polls/:id/votes",
-		async (ctx) => {
-			const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-			const accessTokens = ctx.headers.authorization;
-			const client = getClient(BASE_URL, accessTokens);
-			try {
-				const data = await client.votePoll(
-					ctx.params.id,
-					(ctx.request.body as any).choices,
-				);
-				ctx.body = data.data;
-			} catch (e: any) {
-				console.error(e);
-				ctx.status = 401;
-				ctx.body = e.response.data;
-			}
-		},
-	);
-}
-
-async function getFirstReaction(
-	BASE_URL: string,
-	accessTokens: string | undefined,
-) {
-	const accessTokenArr = accessTokens?.split(" ") ?? [null];
-	const accessToken = accessTokenArr[accessTokenArr.length - 1];
-	let react = "⭐";
-	try {
-		const api = await axios.post(`${BASE_URL}/api/i/registry/get-unsecure`, {
-			scope: ["client", "base"],
-			key: "reactions",
-			i: accessToken,
-		});
-		const reactRaw = api.data;
-		react = Array.isArray(reactRaw) ? api.data[0] : "⭐";
-		console.log(api.data);
-		return react;
-	} catch (e) {
-		return react;
-	}
-}
-
-export function statusModel(
-	id: string | null,
-	acctId: string | null,
-	emojis: MastodonEntity.Emoji[],
-	content: string,
-) {
-	const now = Math.floor(new Date().getTime() / 1000);
-	return {
-		id: "9atm5frjhb",
-		uri: "https://http.cat/404", // ""
-		url: "https://http.cat/404", // "",
-		account: {
-			id: "9arzuvv0sw",
-			username: "Reactions",
-			acct: "Reactions",
-			display_name: "Reactions to this post",
-			locked: false,
-			created_at: now,
-			followers_count: 0,
-			following_count: 0,
-			statuses_count: 0,
-			note: "",
-			url: "https://http.cat/404",
-			avatar: "/static-assets/badges/info.png",
-			avatar_static: "/static-assets/badges/info.png",
-			header: "https://http.cat/404", // ""
-			header_static: "https://http.cat/404", // ""
-			emojis: [],
-			fields: [],
-			moved: null,
-			bot: false,
-		},
-		in_reply_to_id: id,
-		in_reply_to_account_id: acctId,
-		reblog: null,
-		content: `<p>${content}</p>`,
-		plain_content: null,
-		created_at: now,
-		emojis: emojis,
-		replies_count: 0,
-		reblogs_count: 0,
-		favourites_count: 0,
-		favourited: false,
-		reblogged: false,
-		muted: false,
-		sensitive: false,
-		spoiler_text: "",
-		visibility: "public" as const,
-		media_attachments: [],
-		mentions: [],
-		tags: [],
-		card: null,
-		poll: null,
-		application: null,
-		language: null,
-		pinned: false,
-		emoji_reactions: [],
-		bookmarked: false,
-		quote: null,
-	};
-}
diff --git a/packages/backend/src/server/api/mastodon/endpoints/timeline.ts b/packages/backend/src/server/api/mastodon/endpoints/timeline.ts
deleted file mode 100644
index ce3a4dc958..0000000000
--- a/packages/backend/src/server/api/mastodon/endpoints/timeline.ts
+++ /dev/null
@@ -1,336 +0,0 @@
-import Router from "@koa/router";
-import megalodon, { Entity, MegalodonInterface } from "@calckey/megalodon";
-import { getClient } from "../ApiMastodonCompatibleService.js";
-import { statusModel } from "./status.js";
-import Autolinker from "autolinker";
-import { ParsedUrlQuery } from "querystring";
-
-export function limitToInt(q: ParsedUrlQuery) {
-	let object: any = q;
-	if (q.limit)
-		if (typeof q.limit === "string") object.limit = parseInt(q.limit, 10);
-	if (q.offset)
-		if (typeof q.offset === "string") object.offset = parseInt(q.offset, 10);
-	return object;
-}
-
-export function argsToBools(q: ParsedUrlQuery) {
-	// Values taken from https://docs.joinmastodon.org/client/intro/#boolean
-	const toBoolean = (value: string) =>
-		!["0", "f", "F", "false", "FALSE", "off", "OFF"].includes(value);
-
-	let object: any = q;
-	if (q.only_media)
-		if (typeof q.only_media === "string")
-			object.only_media = toBoolean(q.only_media);
-	if (q.exclude_replies)
-		if (typeof q.exclude_replies === "string")
-			object.exclude_replies = toBoolean(q.exclude_replies);
-	return q;
-}
-
-export function toTextWithReaction(status: Entity.Status[], host: string) {
-	return status.map((t) => {
-		if (!t) return statusModel(null, null, [], "no content");
-		t.quote = null as any;
-		if (!t.emoji_reactions) return t;
-		if (t.reblog) t.reblog = toTextWithReaction([t.reblog], host)[0];
-		const reactions = t.emoji_reactions.map((r) => {
-			const emojiNotation = r.url ? `:${r.name.replace("@.", "")}:` : r.name;
-			return `${emojiNotation} (${r.count}${r.me ? `* ` : ""})`;
-		});
-		const reaction = t.emoji_reactions as Entity.Reaction[];
-		const emoji = t.emojis || [];
-		for (const r of reaction) {
-			if (!r.url) continue;
-			emoji.push({
-				shortcode: r.name,
-				url: r.url,
-				static_url: r.url,
-				visible_in_picker: true,
-				category: "",
-			});
-		}
-		const isMe = reaction.findIndex((r) => r.me) > -1;
-		const total = reaction.reduce((sum, reaction) => sum + reaction.count, 0);
-		t.favourited = isMe;
-		t.favourites_count = total;
-		t.emojis = emoji;
-		t.content = `<p>${autoLinker(t.content, host)}</p><p>${reactions.join(
-			", ",
-		)}</p>`;
-		return t;
-	});
-}
-export function autoLinker(input: string, host: string) {
-	return Autolinker.link(input, {
-		hashtag: "twitter",
-		mention: "twitter",
-		email: false,
-		stripPrefix: false,
-		replaceFn: function (match) {
-			switch (match.type) {
-				case "url":
-					return true;
-				case "mention":
-					console.log("Mention: ", match.getMention());
-					console.log("Mention Service Name: ", match.getServiceName());
-					return `<a href="https://${host}/@${encodeURIComponent(
-						match.getMention(),
-					)}" target="_blank">@${match.getMention()}</a>`;
-				case "hashtag":
-					console.log("Hashtag: ", match.getHashtag());
-					return `<a href="https://${host}/tags/${encodeURIComponent(
-						match.getHashtag(),
-					)}" target="_blank">#${match.getHashtag()}</a>`;
-			}
-			return false;
-		},
-	});
-}
-
-export function apiTimelineMastodon(router: Router): void {
-	router.get("/v1/timelines/public", async (ctx, reply) => {
-		const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-		const accessTokens = ctx.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens);
-		try {
-			const query: any = ctx.query;
-			const data = query.local
-				? await client.getLocalTimeline(argsToBools(limitToInt(query)))
-				: await client.getPublicTimeline(argsToBools(limitToInt(query)));
-			ctx.body = toTextWithReaction(data.data, ctx.hostname);
-		} catch (e: any) {
-			console.error(e);
-			console.error(e.response.data);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-	router.get<{ Params: { hashtag: string } }>(
-		"/v1/timelines/tag/:hashtag",
-		async (ctx, reply) => {
-			const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-			const accessTokens = ctx.headers.authorization;
-			const client = getClient(BASE_URL, accessTokens);
-			try {
-				const data = await client.getTagTimeline(
-					ctx.params.hashtag,
-					argsToBools(limitToInt(ctx.query)),
-				);
-				ctx.body = toTextWithReaction(data.data, ctx.hostname);
-			} catch (e: any) {
-				console.error(e);
-				console.error(e.response.data);
-				ctx.status = 401;
-				ctx.body = e.response.data;
-			}
-		},
-	);
-	router.get("/v1/timelines/home", async (ctx, reply) => {
-		const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-		const accessTokens = ctx.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens);
-		try {
-			const data = await client.getHomeTimeline(limitToInt(ctx.query));
-			ctx.body = toTextWithReaction(data.data, ctx.hostname);
-		} catch (e: any) {
-			console.error(e);
-			console.error(e.response.data);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-	router.get<{ Params: { listId: string } }>(
-		"/v1/timelines/list/:listId",
-		async (ctx, reply) => {
-			const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-			const accessTokens = ctx.headers.authorization;
-			const client = getClient(BASE_URL, accessTokens);
-			try {
-				const data = await client.getListTimeline(
-					ctx.params.listId,
-					limitToInt(ctx.query),
-				);
-				ctx.body = toTextWithReaction(data.data, ctx.hostname);
-			} catch (e: any) {
-				console.error(e);
-				console.error(e.response.data);
-				ctx.status = 401;
-				ctx.body = e.response.data;
-			}
-		},
-	);
-	router.get("/v1/conversations", async (ctx, reply) => {
-		const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-		const accessTokens = ctx.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens);
-		try {
-			const data = await client.getConversationTimeline(limitToInt(ctx.query));
-			ctx.body = data.data;
-		} catch (e: any) {
-			console.error(e);
-			console.error(e.response.data);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-	router.get("/v1/lists", async (ctx, reply) => {
-		const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-		const accessTokens = ctx.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens);
-		try {
-			const data = await client.getLists();
-			ctx.body = data.data;
-		} catch (e: any) {
-			console.error(e);
-			console.error(e.response.data);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-	router.get<{ Params: { id: string } }>(
-		"/v1/lists/:id",
-		async (ctx, reply) => {
-			const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-			const accessTokens = ctx.headers.authorization;
-			const client = getClient(BASE_URL, accessTokens);
-			try {
-				const data = await client.getList(ctx.params.id);
-				ctx.body = data.data;
-			} catch (e: any) {
-				console.error(e);
-				console.error(e.response.data);
-				ctx.status = 401;
-				ctx.body = e.response.data;
-			}
-		},
-	);
-	router.post("/v1/lists", async (ctx, reply) => {
-		const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-		const accessTokens = ctx.headers.authorization;
-		const client = getClient(BASE_URL, accessTokens);
-		try {
-			const data = await client.createList((ctx.query as any).title);
-			ctx.body = data.data;
-		} catch (e: any) {
-			console.error(e);
-			console.error(e.response.data);
-			ctx.status = 401;
-			ctx.body = e.response.data;
-		}
-	});
-	router.put<{ Params: { id: string } }>(
-		"/v1/lists/:id",
-		async (ctx, reply) => {
-			const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-			const accessTokens = ctx.headers.authorization;
-			const client = getClient(BASE_URL, accessTokens);
-			try {
-				const data = await client.updateList(ctx.params.id, ctx.query as any);
-				ctx.body = data.data;
-			} catch (e: any) {
-				console.error(e);
-				console.error(e.response.data);
-				ctx.status = 401;
-				ctx.body = e.response.data;
-			}
-		},
-	);
-	router.delete<{ Params: { id: string } }>(
-		"/v1/lists/:id",
-		async (ctx, reply) => {
-			const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-			const accessTokens = ctx.headers.authorization;
-			const client = getClient(BASE_URL, accessTokens);
-			try {
-				const data = await client.deleteList(ctx.params.id);
-				ctx.body = data.data;
-			} catch (e: any) {
-				console.error(e);
-				console.error(e.response.data);
-				ctx.status = 401;
-				ctx.body = e.response.data;
-			}
-		},
-	);
-	router.get<{ Params: { id: string } }>(
-		"/v1/lists/:id/accounts",
-		async (ctx, reply) => {
-			const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-			const accessTokens = ctx.headers.authorization;
-			const client = getClient(BASE_URL, accessTokens);
-			try {
-				const data = await client.getAccountsInList(
-					ctx.params.id,
-					ctx.query as any,
-				);
-				ctx.body = data.data;
-			} catch (e: any) {
-				console.error(e);
-				console.error(e.response.data);
-				ctx.status = 401;
-				ctx.body = e.response.data;
-			}
-		},
-	);
-	router.post<{ Params: { id: string } }>(
-		"/v1/lists/:id/accounts",
-		async (ctx, reply) => {
-			const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-			const accessTokens = ctx.headers.authorization;
-			const client = getClient(BASE_URL, accessTokens);
-			try {
-				const data = await client.addAccountsToList(
-					ctx.params.id,
-					(ctx.query as any).account_ids,
-				);
-				ctx.body = data.data;
-			} catch (e: any) {
-				console.error(e);
-				console.error(e.response.data);
-				ctx.status = 401;
-				ctx.body = e.response.data;
-			}
-		},
-	);
-	router.delete<{ Params: { id: string } }>(
-		"/v1/lists/:id/accounts",
-		async (ctx, reply) => {
-			const BASE_URL = `${ctx.protocol}://${ctx.hostname}`;
-			const accessTokens = ctx.headers.authorization;
-			const client = getClient(BASE_URL, accessTokens);
-			try {
-				const data = await client.deleteAccountsFromList(
-					ctx.params.id,
-					(ctx.query as any).account_ids,
-				);
-				ctx.body = data.data;
-			} catch (e: any) {
-				console.error(e);
-				console.error(e.response.data);
-				ctx.status = 401;
-				ctx.body = e.response.data;
-			}
-		},
-	);
-}
-function escapeHTML(str: string) {
-	if (!str) {
-		return "";
-	}
-	return str
-		.replace(/&/g, "&amp;")
-		.replace(/</g, "&lt;")
-		.replace(/>/g, "&gt;")
-		.replace(/"/g, "&quot;")
-		.replace(/'/g, "&#039;");
-}
-function nl2br(str: string) {
-	if (!str) {
-		return "";
-	}
-	str = str.replace(/\r\n/g, "<br />");
-	str = str.replace(/(\n|\r)/g, "<br />");
-	return str;
-}
diff --git a/packages/backend/src/server/api/openapi/errors.ts b/packages/backend/src/server/api/openapi/errors.ts
deleted file mode 100644
index 0fe229d88e..0000000000
--- a/packages/backend/src/server/api/openapi/errors.ts
+++ /dev/null
@@ -1,71 +0,0 @@
-export const errors = {
-	"400": {
-		INVALID_PARAM: {
-			value: {
-				error: {
-					message: "Invalid param.",
-					code: "INVALID_PARAM",
-					id: "3d81ceae-475f-4600-b2a8-2bc116157532",
-				},
-			},
-		},
-	},
-	"401": {
-		CREDENTIAL_REQUIRED: {
-			value: {
-				error: {
-					message: "Credential required.",
-					code: "CREDENTIAL_REQUIRED",
-					id: "1384574d-a912-4b81-8601-c7b1c4085df1",
-				},
-			},
-		},
-	},
-	"403": {
-		AUTHENTICATION_FAILED: {
-			value: {
-				error: {
-					message:
-						"Authentication failed. Please ensure your token is correct.",
-					code: "AUTHENTICATION_FAILED",
-					id: "b0a7f5f8-dc2f-4171-b91f-de88ad238e14",
-				},
-			},
-		},
-	},
-	"418": {
-		I_AM_CALC: {
-			value: {
-				error: {
-					message:
-						"You sent a request to Calc, Calckey's resident stoner furry, instead of the server.",
-					code: "I_AM_CALC",
-					id: "60c46cd1-f23a-46b1-bebe-5d2b73951a84",
-				},
-			},
-		},
-	},
-	"429": {
-		RATE_LIMIT_EXCEEDED: {
-			value: {
-				error: {
-					message: "Rate limit exceeded. Please try again later.",
-					code: "RATE_LIMIT_EXCEEDED",
-					id: "d5826d14-3982-4d2e-8011-b9e9f02499ef",
-				},
-			},
-		},
-	},
-	"500": {
-		INTERNAL_ERROR: {
-			value: {
-				error: {
-					message:
-						"Internal error occurred. Please contact us if the error persists.",
-					code: "INTERNAL_ERROR",
-					id: "5d37dbcb-891e-41ca-a3d6-e690c97775ac",
-				},
-			},
-		},
-	},
-};
diff --git a/packages/backend/src/server/api/openapi/gen-spec.ts b/packages/backend/src/server/api/openapi/gen-spec.ts
deleted file mode 100644
index dfaacf9e50..0000000000
--- a/packages/backend/src/server/api/openapi/gen-spec.ts
+++ /dev/null
@@ -1,226 +0,0 @@
-import endpoints from "../endpoints.js";
-import config from "@/config/index.js";
-import { errors as basicErrors } from "./errors.js";
-import { schemas, convertSchemaToOpenApiSchema } from "./schemas.js";
-
-export function genOpenapiSpec() {
-	const spec = {
-		openapi: "3.0.0",
-
-		info: {
-			version: "v1",
-			title: "Calckey API",
-			"x-logo": { url: "/static-assets/api-doc.png" },
-		},
-
-		externalDocs: {
-			description: "Repository",
-			url: "https://codeberg.org/calckey/calckey",
-		},
-
-		servers: [
-			{
-				url: config.apiUrl,
-			},
-		],
-
-		paths: {} as any,
-
-		components: {
-			schemas: schemas,
-
-			securitySchemes: {
-				ApiKeyAuth: {
-					type: "apiKey",
-					in: "body",
-					name: "i",
-				},
-				// TODO: change this to oauth2 when the remaining oauth stuff is set up
-				Bearer: {
-					type: "http",
-					scheme: "bearer",
-				},
-			},
-		},
-	};
-
-	for (const endpoint of endpoints.filter((ep) => !ep.meta.secure)) {
-		const errors = {} as any;
-
-		if (endpoint.meta.errors) {
-			for (const e of Object.values(endpoint.meta.errors)) {
-				errors[e.code] = {
-					value: {
-						error: e,
-					},
-				};
-			}
-		}
-
-		const resSchema = endpoint.meta.res
-			? convertSchemaToOpenApiSchema(endpoint.meta.res)
-			: {};
-
-		let desc =
-			(endpoint.meta.description
-				? endpoint.meta.description
-				: "No description provided.") + "\n\n";
-		desc += `**Credential required**: *${
-			endpoint.meta.requireCredential ? "Yes" : "No"
-		}*`;
-		if (endpoint.meta.kind) {
-			const kind = endpoint.meta.kind;
-			desc += ` / **Permission**: *${kind}*`;
-		}
-
-		const requestType = endpoint.meta.requireFile
-			? "multipart/form-data"
-			: "application/json";
-		const schema = endpoint.params;
-
-		if (endpoint.meta.requireFile) {
-			schema.properties.file = {
-				type: "string",
-				format: "binary",
-				description: "The file contents.",
-			};
-			schema.required.push("file");
-		}
-
-		const security = [
-			{
-				ApiKeyAuth: [],
-			},
-			{
-				Bearer: [],
-			},
-		];
-		if (!endpoint.meta.requireCredential) {
-			// add this to make authentication optional
-			security.push({});
-		}
-
-		const info = {
-			operationId: endpoint.name,
-			summary: endpoint.name,
-			description: desc,
-			externalDocs: {
-				description: "Source code",
-				url: `https://codeberg.org/calckey/calckey/src/branch/develop/packages/backend/src/server/api/endpoints/${endpoint.name}.ts`,
-			},
-			tags: endpoint.meta.tags || undefined,
-			security,
-			requestBody: {
-				required: true,
-				content: {
-					[requestType]: {
-						schema,
-					},
-				},
-			},
-			responses: {
-				...(endpoint.meta.res
-					? {
-							"200": {
-								description: "OK (with results)",
-								content: {
-									"application/json": {
-										schema: resSchema,
-									},
-								},
-							},
-					  }
-					: {
-							"204": {
-								description: "OK (without any results)",
-							},
-					  }),
-				"400": {
-					description: "Client error",
-					content: {
-						"application/json": {
-							schema: {
-								$ref: "#/components/schemas/Error",
-							},
-							examples: { ...errors, ...basicErrors["400"] },
-						},
-					},
-				},
-				"401": {
-					description: "Authentication error",
-					content: {
-						"application/json": {
-							schema: {
-								$ref: "#/components/schemas/Error",
-							},
-							examples: basicErrors["401"],
-						},
-					},
-				},
-				"403": {
-					description: "Forbidden error",
-					content: {
-						"application/json": {
-							schema: {
-								$ref: "#/components/schemas/Error",
-							},
-							examples: basicErrors["403"],
-						},
-					},
-				},
-				"418": {
-					description: "I'm Calc",
-					content: {
-						"application/json": {
-							schema: {
-								$ref: "#/components/schemas/Error",
-							},
-							examples: basicErrors["418"],
-						},
-					},
-				},
-				...(endpoint.meta.limit
-					? {
-							"429": {
-								description: "To many requests",
-								content: {
-									"application/json": {
-										schema: {
-											$ref: "#/components/schemas/Error",
-										},
-										examples: basicErrors["429"],
-									},
-								},
-							},
-					  }
-					: {}),
-				"500": {
-					description: "Internal server error",
-					content: {
-						"application/json": {
-							schema: {
-								$ref: "#/components/schemas/Error",
-							},
-							examples: basicErrors["500"],
-						},
-					},
-				},
-			},
-		};
-
-		const path = {
-			post: info,
-		};
-		if (endpoint.meta.allowGet) {
-			path.get = { ...info };
-			// API Key authentication is not permitted for GET requests
-			path.get.security = path.get.security.filter(
-				(elem) => !Object.prototype.hasOwnProperty.call(elem, "ApiKeyAuth"),
-			);
-		}
-
-		spec.paths[`/${endpoint.name}`] = path;
-	}
-
-	return spec;
-}
diff --git a/packages/backend/src/server/api/openapi/schemas.ts b/packages/backend/src/server/api/openapi/schemas.ts
deleted file mode 100644
index 68b15d5677..0000000000
--- a/packages/backend/src/server/api/openapi/schemas.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-import type { Schema } from "@/misc/schema.js";
-import { refs } from "@/misc/schema.js";
-
-export function convertSchemaToOpenApiSchema(schema: Schema) {
-	const res: any = schema;
-
-	if (schema.type === "object" && schema.properties) {
-		res.required = Object.entries(schema.properties)
-			.filter(([k, v]) => !v.optional)
-			.map(([k]) => k);
-
-		for (const k of Object.keys(schema.properties)) {
-			res.properties[k] = convertSchemaToOpenApiSchema(schema.properties[k]);
-		}
-	}
-
-	if (schema.type === "array" && schema.items) {
-		res.items = convertSchemaToOpenApiSchema(schema.items);
-	}
-
-	if (schema.anyOf) res.anyOf = schema.anyOf.map(convertSchemaToOpenApiSchema);
-	if (schema.oneOf) res.oneOf = schema.oneOf.map(convertSchemaToOpenApiSchema);
-	if (schema.allOf) res.allOf = schema.allOf.map(convertSchemaToOpenApiSchema);
-
-	if (schema.ref) {
-		res.$ref = `#/components/schemas/${schema.ref}`;
-	}
-
-	return res;
-}
-
-export const schemas = {
-	Error: {
-		type: "object",
-		properties: {
-			error: {
-				type: "object",
-				description: "An error object.",
-				properties: {
-					code: {
-						type: "string",
-						description: "An error code. Unique within the endpoint.",
-					},
-					message: {
-						type: "string",
-						description: "An error message.",
-					},
-					id: {
-						type: "string",
-						format: "uuid",
-						description: "An error ID. This ID is static.",
-					},
-				},
-				required: ["code", "id", "message"],
-			},
-		},
-		required: ["error"],
-	},
-
-	...Object.fromEntries(
-		Object.entries(refs).map(([key, schema]) => [
-			key,
-			convertSchemaToOpenApiSchema(schema),
-		]),
-	),
-};
diff --git a/packages/backend/src/server/api/private/signin.ts b/packages/backend/src/server/api/private/signin.ts
deleted file mode 100644
index ef5b137813..0000000000
--- a/packages/backend/src/server/api/private/signin.ts
+++ /dev/null
@@ -1,270 +0,0 @@
-import type Koa from "koa";
-import * as speakeasy from "speakeasy";
-import signin from "../common/signin.js";
-import config from "@/config/index.js";
-import {
-	Users,
-	Signins,
-	UserProfiles,
-	UserSecurityKeys,
-	AttestationChallenges,
-} from "@/models/index.js";
-import type { ILocalUser } from "@/models/entities/user.js";
-import { genId } from "@/misc/gen-id.js";
-import {
-	comparePassword,
-	hashPassword,
-	isOldAlgorithm,
-} from "@/misc/password.js";
-import { verifyLogin, hash } from "../2fa.js";
-import { randomBytes } from "node:crypto";
-import { IsNull } from "typeorm";
-import { limiter } from "../limiter.js";
-import { getIpHash } from "@/misc/get-ip-hash.js";
-
-export default async (ctx: Koa.Context) => {
-	ctx.set("Access-Control-Allow-Origin", config.url);
-	ctx.set("Access-Control-Allow-Credentials", "true");
-
-	const body = ctx.request.body as any;
-	const username = body["username"];
-	const password = body["password"];
-	const token = body["token"];
-
-	function error(status: number, error: { id: string }) {
-		ctx.status = status;
-		ctx.body = { error };
-	}
-
-	try {
-		// not more than 1 attempt per second and not more than 10 attempts per hour
-		await limiter(
-			{ key: "signin", duration: 60 * 60 * 1000, max: 10, minInterval: 1000 },
-			getIpHash(ctx.ip),
-		);
-	} catch (err) {
-		ctx.status = 429;
-		ctx.body = {
-			error: {
-				message: "Too many failed attempts to sign in. Try again later.",
-				code: "TOO_MANY_AUTHENTICATION_FAILURES",
-				id: "22d05606-fbcf-421a-a2db-b32610dcfd1b",
-			},
-		};
-		return;
-	}
-
-	if (typeof username !== "string") {
-		ctx.status = 400;
-		return;
-	}
-
-	if (typeof password !== "string") {
-		ctx.status = 400;
-		return;
-	}
-
-	if (token != null && typeof token !== "string") {
-		ctx.status = 400;
-		return;
-	}
-
-	// Fetch user
-	const user = (await Users.findOneBy({
-		usernameLower: username.toLowerCase(),
-		host: IsNull(),
-	})) as ILocalUser;
-
-	if (user == null) {
-		error(404, {
-			id: "6cc579cc-885d-43d8-95c2-b8c7fc963280",
-		});
-		return;
-	}
-
-	if (user.isSuspended) {
-		error(403, {
-			id: "e03a5f46-d309-4865-9b69-56282d94e1eb",
-		});
-		return;
-	}
-
-	const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
-
-	// Compare password
-	const same = await comparePassword(password, profile.password!);
-
-	if (same && isOldAlgorithm(profile.password!)) {
-		profile.password = await hashPassword(password);
-		await UserProfiles.save(profile);
-	}
-
-	async function fail(status?: number, failure?: { id: string }) {
-		// Append signin history
-		await Signins.insert({
-			id: genId(),
-			createdAt: new Date(),
-			userId: user.id,
-			ip: ctx.ip,
-			headers: ctx.headers,
-			success: false,
-		});
-
-		error(
-			status || 500,
-			failure || { id: "4e30e80c-e338-45a0-8c8f-44455efa3b76" },
-		);
-	}
-
-	if (!profile.twoFactorEnabled) {
-		if (same) {
-			signin(ctx, user);
-			return;
-		} else {
-			await fail(403, {
-				id: "932c904e-9460-45b7-9ce6-7ed33be7eb2c",
-			});
-			return;
-		}
-	}
-
-	if (token) {
-		if (!same) {
-			await fail(403, {
-				id: "932c904e-9460-45b7-9ce6-7ed33be7eb2c",
-			});
-			return;
-		}
-
-		const verified = (speakeasy as any).totp.verify({
-			secret: profile.twoFactorSecret,
-			encoding: "base32",
-			token: token,
-			window: 2,
-		});
-
-		if (verified) {
-			signin(ctx, user);
-			return;
-		} else {
-			await fail(403, {
-				id: "cdf1235b-ac71-46d4-a3a6-84ccce48df6f",
-			});
-			return;
-		}
-	} else if (body.credentialId) {
-		if (!(same || profile.usePasswordLessLogin)) {
-			await fail(403, {
-				id: "932c904e-9460-45b7-9ce6-7ed33be7eb2c",
-			});
-			return;
-		}
-
-		const clientDataJSON = Buffer.from(body.clientDataJSON, "hex");
-		const clientData = JSON.parse(clientDataJSON.toString("utf-8"));
-		const challenge = await AttestationChallenges.findOneBy({
-			userId: user.id,
-			id: body.challengeId,
-			registrationChallenge: false,
-			challenge: hash(clientData.challenge).toString("hex"),
-		});
-
-		if (!challenge) {
-			await fail(403, {
-				id: "2715a88a-2125-4013-932f-aa6fe72792da",
-			});
-			return;
-		}
-
-		await AttestationChallenges.delete({
-			userId: user.id,
-			id: body.challengeId,
-		});
-
-		if (new Date().getTime() - challenge.createdAt.getTime() >= 5 * 60 * 1000) {
-			await fail(403, {
-				id: "2715a88a-2125-4013-932f-aa6fe72792da",
-			});
-			return;
-		}
-
-		const securityKey = await UserSecurityKeys.findOneBy({
-			id: Buffer.from(
-				body.credentialId.replace(/-/g, "+").replace(/_/g, "/"),
-				"base64",
-			).toString("hex"),
-		});
-
-		if (!securityKey) {
-			await fail(403, {
-				id: "66269679-aeaf-4474-862b-eb761197e046",
-			});
-			return;
-		}
-
-		const isValid = verifyLogin({
-			publicKey: Buffer.from(securityKey.publicKey, "hex"),
-			authenticatorData: Buffer.from(body.authenticatorData, "hex"),
-			clientDataJSON,
-			clientData,
-			signature: Buffer.from(body.signature, "hex"),
-			challenge: challenge.challenge,
-		});
-
-		if (isValid) {
-			signin(ctx, user);
-			return;
-		} else {
-			await fail(403, {
-				id: "93b86c4b-72f9-40eb-9815-798928603d1e",
-			});
-			return;
-		}
-	} else {
-		if (!(same || profile.usePasswordLessLogin)) {
-			await fail(403, {
-				id: "932c904e-9460-45b7-9ce6-7ed33be7eb2c",
-			});
-			return;
-		}
-
-		const keys = await UserSecurityKeys.findBy({
-			userId: user.id,
-		});
-
-		if (keys.length === 0) {
-			await fail(403, {
-				id: "f27fd449-9af4-4841-9249-1f989b9fa4a4",
-			});
-			return;
-		}
-
-		// 32 byte challenge
-		const challenge = randomBytes(32)
-			.toString("base64")
-			.replace(/=/g, "")
-			.replace(/\+/g, "-")
-			.replace(/\//g, "_");
-
-		const challengeId = genId();
-
-		await AttestationChallenges.insert({
-			userId: user.id,
-			id: challengeId,
-			challenge: hash(Buffer.from(challenge, "utf-8")).toString("hex"),
-			createdAt: new Date(),
-			registrationChallenge: false,
-		});
-
-		ctx.body = {
-			challenge,
-			challengeId,
-			securityKeys: keys.map((key) => ({
-				id: key.id,
-			})),
-		};
-		ctx.status = 200;
-		return;
-	}
-	// never get here
-};
diff --git a/packages/backend/src/server/api/private/signup-pending.ts b/packages/backend/src/server/api/private/signup-pending.ts
deleted file mode 100644
index c7fdcea221..0000000000
--- a/packages/backend/src/server/api/private/signup-pending.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import type Koa from "koa";
-import { Users, UserPendings, UserProfiles } from "@/models/index.js";
-import { signup } from "../common/signup.js";
-import signin from "../common/signin.js";
-
-export default async (ctx: Koa.Context) => {
-	const body = ctx.request.body;
-
-	const code = body["code"];
-
-	try {
-		const pendingUser = await UserPendings.findOneByOrFail({ code });
-
-		const { account, secret } = await signup({
-			username: pendingUser.username,
-			passwordHash: pendingUser.password,
-		});
-
-		UserPendings.delete({
-			id: pendingUser.id,
-		});
-
-		const profile = await UserProfiles.findOneByOrFail({ userId: account.id });
-
-		await UserProfiles.update(
-			{ userId: profile.userId },
-			{
-				email: pendingUser.email,
-				emailVerified: true,
-				emailVerifyCode: null,
-			},
-		);
-
-		signin(ctx, account);
-	} catch (e) {
-		ctx.throw(400, e);
-	}
-};
diff --git a/packages/backend/src/server/api/private/signup.ts b/packages/backend/src/server/api/private/signup.ts
deleted file mode 100644
index 754d86c3b8..0000000000
--- a/packages/backend/src/server/api/private/signup.ts
+++ /dev/null
@@ -1,123 +0,0 @@
-import type Koa from "koa";
-import rndstr from "rndstr";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { verifyHcaptcha, verifyRecaptcha } from "@/misc/captcha.js";
-import { Users, RegistrationTickets, UserPendings } from "@/models/index.js";
-import { signup } from "../common/signup.js";
-import config from "@/config/index.js";
-import { sendEmail } from "@/services/send-email.js";
-import { genId } from "@/misc/gen-id.js";
-import { validateEmailForAccount } from "@/services/validate-email-for-account.js";
-import { hashPassword } from "@/misc/password.js";
-
-export default async (ctx: Koa.Context) => {
-	const body = ctx.request.body;
-
-	const instance = await fetchMeta(true);
-
-	// Verify *Captcha
-	// ただしテスト時はこの機構は障害となるため無効にする
-	if (process.env.NODE_ENV !== "test") {
-		if (instance.enableHcaptcha && instance.hcaptchaSecretKey) {
-			await verifyHcaptcha(
-				instance.hcaptchaSecretKey,
-				body["hcaptcha-response"],
-			).catch((e) => {
-				ctx.throw(400, e);
-			});
-		}
-
-		if (instance.enableRecaptcha && instance.recaptchaSecretKey) {
-			await verifyRecaptcha(
-				instance.recaptchaSecretKey,
-				body["g-recaptcha-response"],
-			).catch((e) => {
-				ctx.throw(400, e);
-			});
-		}
-	}
-
-	const username = body["username"];
-	const password = body["password"];
-	const host: string | null =
-		process.env.NODE_ENV === "test" ? body["host"] || null : null;
-	const invitationCode = body["invitationCode"];
-	const emailAddress = body["emailAddress"];
-
-	if (instance.emailRequiredForSignup) {
-		if (emailAddress == null || typeof emailAddress !== "string") {
-			ctx.status = 400;
-			return;
-		}
-
-		const available = await validateEmailForAccount(emailAddress);
-		if (!available) {
-			ctx.status = 400;
-			return;
-		}
-	}
-
-	if (instance.disableRegistration) {
-		if (invitationCode == null || typeof invitationCode !== "string") {
-			ctx.status = 400;
-			return;
-		}
-
-		const ticket = await RegistrationTickets.findOneBy({
-			code: invitationCode,
-		});
-
-		if (ticket == null) {
-			ctx.status = 400;
-			return;
-		}
-
-		RegistrationTickets.delete(ticket.id);
-	}
-
-	if (instance.emailRequiredForSignup) {
-		const code = rndstr("a-z0-9", 16);
-
-		// Generate hash of password
-		const hash = await hashPassword(password);
-
-		await UserPendings.insert({
-			id: genId(),
-			createdAt: new Date(),
-			code,
-			email: emailAddress,
-			username: username,
-			password: hash,
-		});
-
-		const link = `${config.url}/signup-complete/${code}`;
-
-		sendEmail(
-			emailAddress,
-			"Signup",
-			`To complete signup, please click this link:<br><a href="${link}">${link}</a>`,
-			`To complete signup, please click this link: ${link}`,
-		);
-
-		ctx.status = 204;
-	} else {
-		try {
-			const { account, secret } = await signup({
-				username,
-				password,
-				host,
-			});
-
-			const res = await Users.pack(account, account, {
-				detail: true,
-				includeSecrets: true,
-			});
-
-			(res as any).token = secret;
-
-			ctx.body = res;
-		} catch (e) {
-			ctx.throw(400, e);
-		}
-	}
-};
diff --git a/packages/backend/src/server/api/service/discord.ts b/packages/backend/src/server/api/service/discord.ts
deleted file mode 100644
index 9906d2f7ca..0000000000
--- a/packages/backend/src/server/api/service/discord.ts
+++ /dev/null
@@ -1,333 +0,0 @@
-import type Koa from "koa";
-import Router from "@koa/router";
-import { OAuth2 } from "oauth";
-import { v4 as uuid } from "uuid";
-import { IsNull } from "typeorm";
-import { getJson } from "@/misc/fetch.js";
-import config from "@/config/index.js";
-import { publishMainStream } from "@/services/stream.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { Users, UserProfiles } from "@/models/index.js";
-import type { ILocalUser } from "@/models/entities/user.js";
-import { redisClient } from "../../../db/redis.js";
-import signin from "../common/signin.js";
-
-function getUserToken(ctx: Koa.BaseContext): string | null {
-	return ((ctx.headers["cookie"] || "").match(/igi=(\w+)/) || [null, null])[1];
-}
-
-function compareOrigin(ctx: Koa.BaseContext): boolean {
-	function normalizeUrl(url?: string): string {
-		return url ? (url.endsWith("/") ? url.substr(0, url.length - 1) : url) : "";
-	}
-
-	const referer = ctx.headers["referer"];
-
-	return normalizeUrl(referer) === normalizeUrl(config.url);
-}
-
-// Init router
-const router = new Router();
-
-router.get("/disconnect/discord", async (ctx) => {
-	if (!compareOrigin(ctx)) {
-		ctx.throw(400, "invalid origin");
-		return;
-	}
-
-	const userToken = getUserToken(ctx);
-	if (!userToken) {
-		ctx.throw(400, "signin required");
-		return;
-	}
-
-	const user = await Users.findOneByOrFail({
-		host: IsNull(),
-		token: userToken,
-	});
-
-	const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
-
-	profile.integrations.discord = undefined;
-
-	await UserProfiles.update(user.id, {
-		integrations: profile.integrations,
-	});
-
-	ctx.body = "Discordの連携を解除しました :v:";
-
-	// Publish i updated event
-	publishMainStream(
-		user.id,
-		"meUpdated",
-		await Users.pack(user, user, {
-			detail: true,
-			includeSecrets: true,
-		}),
-	);
-});
-
-async function getOAuth2() {
-	const meta = await fetchMeta(true);
-
-	if (meta.enableDiscordIntegration) {
-		return new OAuth2(
-			meta.discordClientId!,
-			meta.discordClientSecret!,
-			"https://discord.com/",
-			"api/oauth2/authorize",
-			"api/oauth2/token",
-		);
-	} else {
-		return null;
-	}
-}
-
-router.get("/connect/discord", async (ctx) => {
-	if (!compareOrigin(ctx)) {
-		ctx.throw(400, "invalid origin");
-		return;
-	}
-
-	const userToken = getUserToken(ctx);
-	if (!userToken) {
-		ctx.throw(400, "signin required");
-		return;
-	}
-
-	const params = {
-		redirect_uri: `${config.url}/api/dc/cb`,
-		scope: ["identify"],
-		state: uuid(),
-		response_type: "code",
-	};
-
-	redisClient.set(userToken, JSON.stringify(params));
-
-	const oauth2 = await getOAuth2();
-	ctx.redirect(oauth2!.getAuthorizeUrl(params));
-});
-
-router.get("/signin/discord", async (ctx) => {
-	const sessid = uuid();
-
-	const params = {
-		redirect_uri: `${config.url}/api/dc/cb`,
-		scope: ["identify"],
-		state: uuid(),
-		response_type: "code",
-	};
-
-	ctx.cookies.set("signin_with_discord_sid", sessid, {
-		path: "/",
-		secure: config.url.startsWith("https"),
-		httpOnly: true,
-	});
-
-	redisClient.set(sessid, JSON.stringify(params));
-
-	const oauth2 = await getOAuth2();
-	ctx.redirect(oauth2!.getAuthorizeUrl(params));
-});
-
-router.get("/dc/cb", async (ctx) => {
-	const userToken = getUserToken(ctx);
-
-	const oauth2 = await getOAuth2();
-
-	if (!userToken) {
-		const sessid = ctx.cookies.get("signin_with_discord_sid");
-
-		if (!sessid) {
-			ctx.throw(400, "invalid session");
-			return;
-		}
-
-		const code = ctx.query.code;
-
-		if (!code || typeof code !== "string") {
-			ctx.throw(400, "invalid session");
-			return;
-		}
-
-		const { redirect_uri, state } = await new Promise<any>((res, rej) => {
-			redisClient.get(sessid, async (_, state) => {
-				res(JSON.parse(state));
-			});
-		});
-
-		if (ctx.query.state !== state) {
-			ctx.throw(400, "invalid session");
-			return;
-		}
-
-		const { accessToken, refreshToken, expiresDate } = await new Promise<any>(
-			(res, rej) =>
-				oauth2!.getOAuthAccessToken(
-					code,
-					{
-						grant_type: "authorization_code",
-						redirect_uri,
-					},
-					(err, accessToken, refreshToken, result) => {
-						if (err) {
-							rej(err);
-						} else if (result.error) {
-							rej(result.error);
-						} else {
-							res({
-								accessToken,
-								refreshToken,
-								expiresDate: Date.now() + Number(result.expires_in) * 1000,
-							});
-						}
-					},
-				),
-		);
-
-		const { id, username, discriminator } = (await getJson(
-			"https://discord.com/api/users/@me",
-			"*/*",
-			10 * 1000,
-			{
-				Authorization: `Bearer ${accessToken}`,
-			},
-		)) as Record<string, unknown>;
-
-		if (
-			typeof id !== "string" ||
-			typeof username !== "string" ||
-			typeof discriminator !== "string"
-		) {
-			ctx.throw(400, "invalid session");
-			return;
-		}
-
-		const profile = await UserProfiles.createQueryBuilder()
-			.where("\"integrations\"->'discord'->>'id' = :id", { id: id })
-			.andWhere('"userHost" IS NULL')
-			.getOne();
-
-		if (profile == null) {
-			ctx.throw(
-				404,
-				`@${username}#${discriminator}と連携しているMisskeyアカウントはありませんでした...`,
-			);
-			return;
-		}
-
-		await UserProfiles.update(profile.userId, {
-			integrations: {
-				...profile.integrations,
-				discord: {
-					id: id,
-					accessToken: accessToken,
-					refreshToken: refreshToken,
-					expiresDate: expiresDate,
-					username: username,
-					discriminator: discriminator,
-				},
-			},
-		});
-
-		signin(
-			ctx,
-			(await Users.findOneBy({ id: profile.userId })) as ILocalUser,
-			true,
-		);
-	} else {
-		const code = ctx.query.code;
-
-		if (!code || typeof code !== "string") {
-			ctx.throw(400, "invalid session");
-			return;
-		}
-
-		const { redirect_uri, state } = await new Promise<any>((res, rej) => {
-			redisClient.get(userToken, async (_, state) => {
-				res(JSON.parse(state));
-			});
-		});
-
-		if (ctx.query.state !== state) {
-			ctx.throw(400, "invalid session");
-			return;
-		}
-
-		const { accessToken, refreshToken, expiresDate } = await new Promise<any>(
-			(res, rej) =>
-				oauth2!.getOAuthAccessToken(
-					code,
-					{
-						grant_type: "authorization_code",
-						redirect_uri,
-					},
-					(err, accessToken, refreshToken, result) => {
-						if (err) {
-							rej(err);
-						} else if (result.error) {
-							rej(result.error);
-						} else {
-							res({
-								accessToken,
-								refreshToken,
-								expiresDate: Date.now() + Number(result.expires_in) * 1000,
-							});
-						}
-					},
-				),
-		);
-
-		const { id, username, discriminator } = (await getJson(
-			"https://discord.com/api/users/@me",
-			"*/*",
-			10 * 1000,
-			{
-				Authorization: `Bearer ${accessToken}`,
-			},
-		)) as Record<string, unknown>;
-		if (
-			typeof id !== "string" ||
-			typeof username !== "string" ||
-			typeof discriminator !== "string"
-		) {
-			ctx.throw(400, "invalid session");
-			return;
-		}
-
-		const user = await Users.findOneByOrFail({
-			host: IsNull(),
-			token: userToken,
-		});
-
-		const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
-
-		await UserProfiles.update(user.id, {
-			integrations: {
-				...profile.integrations,
-				discord: {
-					accessToken: accessToken,
-					refreshToken: refreshToken,
-					expiresDate: expiresDate,
-					id: id,
-					username: username,
-					discriminator: discriminator,
-				},
-			},
-		});
-
-		ctx.body = `Discord: @${username}#${discriminator} を、Misskey: @${user.username} に接続しました!`;
-
-		// Publish i updated event
-		publishMainStream(
-			user.id,
-			"meUpdated",
-			await Users.pack(user, user, {
-				detail: true,
-				includeSecrets: true,
-			}),
-		);
-	}
-});
-
-export default router;
diff --git a/packages/backend/src/server/api/service/github.ts b/packages/backend/src/server/api/service/github.ts
deleted file mode 100644
index f77c5f795d..0000000000
--- a/packages/backend/src/server/api/service/github.ts
+++ /dev/null
@@ -1,296 +0,0 @@
-import type Koa from "koa";
-import Router from "@koa/router";
-import { OAuth2 } from "oauth";
-import { v4 as uuid } from "uuid";
-import { IsNull } from "typeorm";
-import { getJson } from "@/misc/fetch.js";
-import config from "@/config/index.js";
-import { publishMainStream } from "@/services/stream.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { Users, UserProfiles } from "@/models/index.js";
-import type { ILocalUser } from "@/models/entities/user.js";
-import { redisClient } from "../../../db/redis.js";
-import signin from "../common/signin.js";
-
-function getUserToken(ctx: Koa.BaseContext): string | null {
-	return ((ctx.headers["cookie"] || "").match(/igi=(\w+)/) || [null, null])[1];
-}
-
-function compareOrigin(ctx: Koa.BaseContext): boolean {
-	function normalizeUrl(url?: string): string {
-		return url ? (url.endsWith("/") ? url.substr(0, url.length - 1) : url) : "";
-	}
-
-	const referer = ctx.headers["referer"];
-
-	return normalizeUrl(referer) === normalizeUrl(config.url);
-}
-
-// Init router
-const router = new Router();
-
-router.get("/disconnect/github", async (ctx) => {
-	if (!compareOrigin(ctx)) {
-		ctx.throw(400, "invalid origin");
-		return;
-	}
-
-	const userToken = getUserToken(ctx);
-	if (!userToken) {
-		ctx.throw(400, "signin required");
-		return;
-	}
-
-	const user = await Users.findOneByOrFail({
-		host: IsNull(),
-		token: userToken,
-	});
-
-	const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
-
-	profile.integrations.github = undefined;
-
-	await UserProfiles.update(user.id, {
-		integrations: profile.integrations,
-	});
-
-	ctx.body = "GitHubの連携を解除しました :v:";
-
-	// Publish i updated event
-	publishMainStream(
-		user.id,
-		"meUpdated",
-		await Users.pack(user, user, {
-			detail: true,
-			includeSecrets: true,
-		}),
-	);
-});
-
-async function getOath2() {
-	const meta = await fetchMeta(true);
-
-	if (
-		meta.enableGithubIntegration &&
-		meta.githubClientId &&
-		meta.githubClientSecret
-	) {
-		return new OAuth2(
-			meta.githubClientId,
-			meta.githubClientSecret,
-			"https://github.com/",
-			"login/oauth/authorize",
-			"login/oauth/access_token",
-		);
-	} else {
-		return null;
-	}
-}
-
-router.get("/connect/github", async (ctx) => {
-	if (!compareOrigin(ctx)) {
-		ctx.throw(400, "invalid origin");
-		return;
-	}
-
-	const userToken = getUserToken(ctx);
-	if (!userToken) {
-		ctx.throw(400, "signin required");
-		return;
-	}
-
-	const params = {
-		redirect_uri: `${config.url}/api/gh/cb`,
-		scope: ["read:user"],
-		state: uuid(),
-	};
-
-	redisClient.set(userToken, JSON.stringify(params));
-
-	const oauth2 = await getOath2();
-	ctx.redirect(oauth2!.getAuthorizeUrl(params));
-});
-
-router.get("/signin/github", async (ctx) => {
-	const sessid = uuid();
-
-	const params = {
-		redirect_uri: `${config.url}/api/gh/cb`,
-		scope: ["read:user"],
-		state: uuid(),
-	};
-
-	ctx.cookies.set("signin_with_github_sid", sessid, {
-		path: "/",
-		secure: config.url.startsWith("https"),
-		httpOnly: true,
-	});
-
-	redisClient.set(sessid, JSON.stringify(params));
-
-	const oauth2 = await getOath2();
-	ctx.redirect(oauth2!.getAuthorizeUrl(params));
-});
-
-router.get("/gh/cb", async (ctx) => {
-	const userToken = getUserToken(ctx);
-
-	const oauth2 = await getOath2();
-
-	if (!userToken) {
-		const sessid = ctx.cookies.get("signin_with_github_sid");
-
-		if (!sessid) {
-			ctx.throw(400, "invalid session");
-			return;
-		}
-
-		const code = ctx.query.code;
-
-		if (!code || typeof code !== "string") {
-			ctx.throw(400, "invalid session");
-			return;
-		}
-
-		const { redirect_uri, state } = await new Promise<any>((res, rej) => {
-			redisClient.get(sessid, async (_, state) => {
-				res(JSON.parse(state));
-			});
-		});
-
-		if (ctx.query.state !== state) {
-			ctx.throw(400, "invalid session");
-			return;
-		}
-
-		const { accessToken } = await new Promise<any>((res, rej) =>
-			oauth2!.getOAuthAccessToken(
-				code,
-				{
-					redirect_uri,
-				},
-				(err, accessToken, refresh, result) => {
-					if (err) {
-						rej(err);
-					} else if (result.error) {
-						rej(result.error);
-					} else {
-						res({ accessToken });
-					}
-				},
-			),
-		);
-
-		const { login, id } = (await getJson(
-			"https://api.github.com/user",
-			"application/vnd.github.v3+json",
-			10 * 1000,
-			{
-				Authorization: `bearer ${accessToken}`,
-			},
-		)) as Record<string, unknown>;
-		if (typeof login !== "string" || typeof id !== "string") {
-			ctx.throw(400, "invalid session");
-			return;
-		}
-
-		const link = await UserProfiles.createQueryBuilder()
-			.where("\"integrations\"->'github'->>'id' = :id", { id: id })
-			.andWhere('"userHost" IS NULL')
-			.getOne();
-
-		if (link == null) {
-			ctx.throw(
-				404,
-				`@${login}と連携しているMisskeyアカウントはありませんでした...`,
-			);
-			return;
-		}
-
-		signin(
-			ctx,
-			(await Users.findOneBy({ id: link.userId })) as ILocalUser,
-			true,
-		);
-	} else {
-		const code = ctx.query.code;
-
-		if (!code || typeof code !== "string") {
-			ctx.throw(400, "invalid session");
-			return;
-		}
-
-		const { redirect_uri, state } = await new Promise<any>((res, rej) => {
-			redisClient.get(userToken, async (_, state) => {
-				res(JSON.parse(state));
-			});
-		});
-
-		if (ctx.query.state !== state) {
-			ctx.throw(400, "invalid session");
-			return;
-		}
-
-		const { accessToken } = await new Promise<any>((res, rej) =>
-			oauth2!.getOAuthAccessToken(
-				code,
-				{ redirect_uri },
-				(err, accessToken, refresh, result) => {
-					if (err) {
-						rej(err);
-					} else if (result.error) {
-						rej(result.error);
-					} else {
-						res({ accessToken });
-					}
-				},
-			),
-		);
-
-		const { login, id } = (await getJson(
-			"https://api.github.com/user",
-			"application/vnd.github.v3+json",
-			10 * 1000,
-			{
-				Authorization: `bearer ${accessToken}`,
-			},
-		)) as Record<string, unknown>;
-
-		if (typeof login !== "string" || typeof id !== "string") {
-			ctx.throw(400, "invalid session");
-			return;
-		}
-
-		const user = await Users.findOneByOrFail({
-			host: IsNull(),
-			token: userToken,
-		});
-
-		const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
-
-		await UserProfiles.update(user.id, {
-			integrations: {
-				...profile.integrations,
-				github: {
-					accessToken: accessToken,
-					id: id,
-					login: login,
-				},
-			},
-		});
-
-		ctx.body = `GitHub: @${login} を、Misskey: @${user.username} に接続しました!`;
-
-		// Publish i updated event
-		publishMainStream(
-			user.id,
-			"meUpdated",
-			await Users.pack(user, user, {
-				detail: true,
-				includeSecrets: true,
-			}),
-		);
-	}
-});
-
-export default router;
diff --git a/packages/backend/src/server/api/service/twitter.ts b/packages/backend/src/server/api/service/twitter.ts
deleted file mode 100644
index 3695592410..0000000000
--- a/packages/backend/src/server/api/service/twitter.ts
+++ /dev/null
@@ -1,226 +0,0 @@
-import type Koa from "koa";
-import Router from "@koa/router";
-import { v4 as uuid } from "uuid";
-import autwh from "autwh";
-import { IsNull } from "typeorm";
-import { publishMainStream } from "@/services/stream.js";
-import config from "@/config/index.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { Users, UserProfiles } from "@/models/index.js";
-import type { ILocalUser } from "@/models/entities/user.js";
-import signin from "../common/signin.js";
-import { redisClient } from "../../../db/redis.js";
-
-function getUserToken(ctx: Koa.BaseContext): string | null {
-	return ((ctx.headers["cookie"] || "").match(/igi=(\w+)/) || [null, null])[1];
-}
-
-function compareOrigin(ctx: Koa.BaseContext): boolean {
-	function normalizeUrl(url?: string): string {
-		return url == null
-			? ""
-			: url.endsWith("/")
-			? url.substr(0, url.length - 1)
-			: url;
-	}
-
-	const referer = ctx.headers["referer"];
-
-	return normalizeUrl(referer) === normalizeUrl(config.url);
-}
-
-// Init router
-const router = new Router();
-
-router.get("/disconnect/twitter", async (ctx) => {
-	if (!compareOrigin(ctx)) {
-		ctx.throw(400, "invalid origin");
-		return;
-	}
-
-	const userToken = getUserToken(ctx);
-	if (userToken == null) {
-		ctx.throw(400, "signin required");
-		return;
-	}
-
-	const user = await Users.findOneByOrFail({
-		host: IsNull(),
-		token: userToken,
-	});
-
-	const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
-
-	profile.integrations.twitter = undefined;
-
-	await UserProfiles.update(user.id, {
-		integrations: profile.integrations,
-	});
-
-	ctx.body = "Twitterの連携を解除しました :v:";
-
-	// Publish i updated event
-	publishMainStream(
-		user.id,
-		"meUpdated",
-		await Users.pack(user, user, {
-			detail: true,
-			includeSecrets: true,
-		}),
-	);
-});
-
-async function getTwAuth() {
-	const meta = await fetchMeta(true);
-
-	if (
-		meta.enableTwitterIntegration &&
-		meta.twitterConsumerKey &&
-		meta.twitterConsumerSecret
-	) {
-		return autwh({
-			consumerKey: meta.twitterConsumerKey,
-			consumerSecret: meta.twitterConsumerSecret,
-			callbackUrl: `${config.url}/api/tw/cb`,
-		});
-	} else {
-		return null;
-	}
-}
-
-router.get("/connect/twitter", async (ctx) => {
-	if (!compareOrigin(ctx)) {
-		ctx.throw(400, "invalid origin");
-		return;
-	}
-
-	const userToken = getUserToken(ctx);
-	if (userToken == null) {
-		ctx.throw(400, "signin required");
-		return;
-	}
-
-	const twAuth = await getTwAuth();
-	const twCtx = await twAuth!.begin();
-	redisClient.set(userToken, JSON.stringify(twCtx));
-	ctx.redirect(twCtx.url);
-});
-
-router.get("/signin/twitter", async (ctx) => {
-	const twAuth = await getTwAuth();
-	const twCtx = await twAuth!.begin();
-
-	const sessid = uuid();
-
-	redisClient.set(sessid, JSON.stringify(twCtx));
-
-	ctx.cookies.set("signin_with_twitter_sid", sessid, {
-		path: "/",
-		secure: config.url.startsWith("https"),
-		httpOnly: true,
-	});
-
-	ctx.redirect(twCtx.url);
-});
-
-router.get("/tw/cb", async (ctx) => {
-	const userToken = getUserToken(ctx);
-
-	const twAuth = await getTwAuth();
-
-	if (userToken == null) {
-		const sessid = ctx.cookies.get("signin_with_twitter_sid");
-
-		if (sessid == null) {
-			ctx.throw(400, "invalid session");
-			return;
-		}
-
-		const get = new Promise<any>((res, rej) => {
-			redisClient.get(sessid, async (_, twCtx) => {
-				res(twCtx);
-			});
-		});
-
-		const twCtx = await get;
-
-		const verifier = ctx.query.oauth_verifier;
-		if (!verifier || typeof verifier !== "string") {
-			ctx.throw(400, "invalid session");
-			return;
-		}
-
-		const result = await twAuth!.done(JSON.parse(twCtx), verifier);
-
-		const link = await UserProfiles.createQueryBuilder()
-			.where("\"integrations\"->'twitter'->>'userId' = :id", {
-				id: result.userId,
-			})
-			.andWhere('"userHost" IS NULL')
-			.getOne();
-
-		if (link == null) {
-			ctx.throw(
-				404,
-				`@${result.screenName}と連携しているMisskeyアカウントはありませんでした...`,
-			);
-			return;
-		}
-
-		signin(
-			ctx,
-			(await Users.findOneBy({ id: link.userId })) as ILocalUser,
-			true,
-		);
-	} else {
-		const verifier = ctx.query.oauth_verifier;
-
-		if (!verifier || typeof verifier !== "string") {
-			ctx.throw(400, "invalid session");
-			return;
-		}
-
-		const get = new Promise<any>((res, rej) => {
-			redisClient.get(userToken, async (_, twCtx) => {
-				res(twCtx);
-			});
-		});
-
-		const twCtx = await get;
-
-		const result = await twAuth!.done(JSON.parse(twCtx), verifier);
-
-		const user = await Users.findOneByOrFail({
-			host: IsNull(),
-			token: userToken,
-		});
-
-		const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
-
-		await UserProfiles.update(user.id, {
-			integrations: {
-				...profile.integrations,
-				twitter: {
-					accessToken: result.accessToken,
-					accessTokenSecret: result.accessTokenSecret,
-					userId: result.userId,
-					screenName: result.screenName,
-				},
-			},
-		});
-
-		ctx.body = `Twitter: @${result.screenName} を、Misskey: @${user.username} に接続しました!`;
-
-		// Publish i updated event
-		publishMainStream(
-			user.id,
-			"meUpdated",
-			await Users.pack(user, user, {
-				detail: true,
-				includeSecrets: true,
-			}),
-		);
-	}
-});
-
-export default router;
diff --git a/packages/backend/src/server/api/stream/channel.ts b/packages/backend/src/server/api/stream/channel.ts
deleted file mode 100644
index fc8e0ce35e..0000000000
--- a/packages/backend/src/server/api/stream/channel.ts
+++ /dev/null
@@ -1,99 +0,0 @@
-import type Connection from ".";
-import type { Note } from "@/models/entities/note.js";
-import { Notes } from "@/models/index.js";
-import type { Packed } from "@/misc/schema.js";
-import { IdentifiableError } from "@/misc/identifiable-error.js";
-
-/**
- * Stream channel
- */
-export default abstract class Channel {
-	protected connection: Connection;
-	public id: string;
-	public abstract readonly chName: string;
-	public static readonly shouldShare: boolean;
-	public static readonly requireCredential: boolean;
-
-	protected get user() {
-		return this.connection.user;
-	}
-
-	protected get userProfile() {
-		return this.connection.userProfile;
-	}
-
-	protected get following() {
-		return this.connection.following;
-	}
-
-	protected get muting() {
-		return this.connection.muting;
-	}
-
-	protected get renoteMuting() {
-		return this.connection.renoteMuting;
-	}
-
-	protected get blocking() {
-		return this.connection.blocking;
-	}
-
-	protected get followingChannels() {
-		return this.connection.followingChannels;
-	}
-
-	protected get subscriber() {
-		return this.connection.subscriber;
-	}
-
-	constructor(id: string, connection: Connection) {
-		this.id = id;
-		this.connection = connection;
-	}
-
-	public send(typeOrPayload: any, payload?: any) {
-		const type = payload === undefined ? typeOrPayload.type : typeOrPayload;
-		const body = payload === undefined ? typeOrPayload.body : payload;
-
-		this.connection.sendMessageToWs("channel", {
-			id: this.id,
-			type: type,
-			body: body,
-		});
-	}
-
-	protected withPackedNote(
-		callback: (note: Packed<"Note">) => void,
-	): (Note) => void {
-		return async (note: Note) => {
-			try {
-				// because `note` was previously JSON.stringify'ed, the fields that
-				// were objects before are now strings and have to be restored or
-				// removed from the object
-				note.createdAt = new Date(note.createdAt);
-				note.reply = undefined;
-				note.renote = undefined;
-				note.user = undefined;
-				note.channel = undefined;
-
-				const packed = await Notes.pack(note, this.user, { detail: true });
-
-				callback(packed);
-			} catch (err) {
-				if (
-					err instanceof IdentifiableError &&
-					err.id === "9725d0ce-ba28-4dde-95a7-2cbb2c15de24"
-				) {
-					// skip: note not visible to user
-					return;
-				} else {
-					throw err;
-				}
-			}
-		};
-	}
-
-	public abstract init(params: any): void;
-	public dispose?(): void;
-	public onMessage?(type: string, body: any): void;
-}
diff --git a/packages/backend/src/server/api/stream/channels/admin.ts b/packages/backend/src/server/api/stream/channels/admin.ts
deleted file mode 100644
index 59ae228250..0000000000
--- a/packages/backend/src/server/api/stream/channels/admin.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import Channel from "../channel.js";
-
-export default class extends Channel {
-	public readonly chName = "admin";
-	public static shouldShare = true;
-	public static requireCredential = true;
-
-	public async init(params: any) {
-		// Subscribe admin stream
-		this.subscriber.on(`adminStream:${this.user!.id}`, (data) => {
-			this.send(data);
-		});
-	}
-}
diff --git a/packages/backend/src/server/api/stream/channels/antenna.ts b/packages/backend/src/server/api/stream/channels/antenna.ts
deleted file mode 100644
index 050a8d1019..0000000000
--- a/packages/backend/src/server/api/stream/channels/antenna.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-import Channel from "../channel.js";
-import { Notes } from "@/models/index.js";
-import { isUserRelated } from "@/misc/is-user-related.js";
-import type { StreamMessages } from "../types.js";
-import { IdentifiableError } from "@/misc/identifiable-error.js";
-
-export default class extends Channel {
-	public readonly chName = "antenna";
-	public static shouldShare = false;
-	public static requireCredential = false;
-	private antennaId: string;
-
-	constructor(id: string, connection: Channel["connection"]) {
-		super(id, connection);
-		this.onEvent = this.onEvent.bind(this);
-	}
-
-	public async init(params: any) {
-		this.antennaId = params.antennaId as string;
-
-		// Subscribe stream
-		this.subscriber.on(`antennaStream:${this.antennaId}`, this.onEvent);
-	}
-
-	private async onEvent(data: StreamMessages["antenna"]["payload"]) {
-		if (data.type === "note") {
-			try {
-				const note = await Notes.pack(data.body.id, this.user, {
-					detail: true,
-				});
-
-				// 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する
-				if (isUserRelated(note, this.muting)) return;
-				// 流れてきたNoteがブロックされているユーザーが関わるものだったら無視する
-				if (isUserRelated(note, this.blocking)) return;
-
-				if (note.renote && !note.text && isUserRelated(note, this.renoteMuting))
-					return;
-
-				this.connection.cacheNote(note);
-
-				this.send("note", note);
-			} catch (e) {
-				if (
-					e instanceof IdentifiableError &&
-					e.id === "9725d0ce-ba28-4dde-95a7-2cbb2c15de24"
-				) {
-					// skip: note not visible to user
-					return;
-				} else {
-					throw e;
-				}
-			}
-		} else {
-			this.send(data.type, data.body);
-		}
-	}
-
-	public dispose() {
-		// Unsubscribe events
-		this.subscriber.off(`antennaStream:${this.antennaId}`, this.onEvent);
-	}
-}
diff --git a/packages/backend/src/server/api/stream/channels/channel.ts b/packages/backend/src/server/api/stream/channels/channel.ts
deleted file mode 100644
index d046579f42..0000000000
--- a/packages/backend/src/server/api/stream/channels/channel.ts
+++ /dev/null
@@ -1,84 +0,0 @@
-import Channel from "../channel.js";
-import { Users } from "@/models/index.js";
-import { isUserRelated } from "@/misc/is-user-related.js";
-import type { User } from "@/models/entities/user.js";
-import type { StreamMessages } from "../types.js";
-import type { Packed } from "@/misc/schema.js";
-
-export default class extends Channel {
-	public readonly chName = "channel";
-	public static shouldShare = false;
-	public static requireCredential = false;
-	private channelId: string;
-	private typers: Map<User["id"], Date> = new Map();
-	private emitTypersIntervalId: ReturnType<typeof setInterval>;
-
-	constructor(id: string, connection: Channel["connection"]) {
-		super(id, connection);
-		this.onNote = this.onNote.bind(this);
-		this.emitTypers = this.emitTypers.bind(this);
-	}
-
-	public async init(params: any) {
-		this.channelId = params.channelId as string;
-
-		// Subscribe stream
-		this.subscriber.on("notesStream", this.onNote);
-		this.subscriber.on(`channelStream:${this.channelId}`, this.onEvent);
-		this.emitTypersIntervalId = setInterval(this.emitTypers, 5000);
-	}
-
-	private async onNote(note: Packed<"Note">) {
-		if (note.channelId !== this.channelId) return;
-
-		// 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する
-		if (isUserRelated(note, this.muting)) return;
-		// 流れてきたNoteがブロックされているユーザーが関わるものだったら無視する
-		if (isUserRelated(note, this.blocking)) return;
-
-		if (note.renote && !note.text && isUserRelated(note, this.renoteMuting))
-			return;
-
-		this.connection.cacheNote(note);
-
-		this.send("note", note);
-	}
-
-	private onEvent(data: StreamMessages["channel"]["payload"]) {
-		if (data.type === "typing") {
-			const id = data.body;
-			const begin = !this.typers.has(id);
-			this.typers.set(id, new Date());
-			if (begin) {
-				this.emitTypers();
-			}
-		}
-	}
-
-	private async emitTypers() {
-		const now = new Date();
-
-		// Remove not typing users
-		for (const [userId, date] of Object.entries(this.typers)) {
-			if (now.getTime() - date.getTime() > 5000) this.typers.delete(userId);
-		}
-
-		const userIds = Array.from(this.typers.keys());
-		const users = await Users.packMany(userIds, null, {
-			detail: false,
-		});
-
-		this.send({
-			type: "typers",
-			body: users,
-		});
-	}
-
-	public dispose() {
-		// Unsubscribe events
-		this.subscriber.off("notesStream", this.onNote);
-		this.subscriber.off(`channelStream:${this.channelId}`, this.onEvent);
-
-		clearInterval(this.emitTypersIntervalId);
-	}
-}
diff --git a/packages/backend/src/server/api/stream/channels/drive.ts b/packages/backend/src/server/api/stream/channels/drive.ts
deleted file mode 100644
index 275730eae5..0000000000
--- a/packages/backend/src/server/api/stream/channels/drive.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import Channel from "../channel.js";
-
-export default class extends Channel {
-	public readonly chName = "drive";
-	public static shouldShare = true;
-	public static requireCredential = true;
-
-	public async init(params: any) {
-		// Subscribe drive stream
-		this.subscriber.on(`driveStream:${this.user!.id}`, (data) => {
-			this.send(data);
-		});
-	}
-}
diff --git a/packages/backend/src/server/api/stream/channels/global-timeline.ts b/packages/backend/src/server/api/stream/channels/global-timeline.ts
deleted file mode 100644
index aa3844c7e3..0000000000
--- a/packages/backend/src/server/api/stream/channels/global-timeline.ts
+++ /dev/null
@@ -1,82 +0,0 @@
-import Channel from "../channel.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { getWordMute } from "@/misc/check-word-mute.js";
-import { isInstanceMuted } from "@/misc/is-instance-muted.js";
-import { isUserRelated } from "@/misc/is-user-related.js";
-import type { Packed } from "@/misc/schema.js";
-
-export default class extends Channel {
-	public readonly chName = "globalTimeline";
-	public static shouldShare = true;
-	public static requireCredential = false;
-
-	constructor(id: string, connection: Channel["connection"]) {
-		super(id, connection);
-		this.onNote = this.withPackedNote(this.onNote.bind(this));
-	}
-
-	public async init(params: any) {
-		const meta = await fetchMeta();
-		if (meta.disableGlobalTimeline) {
-			if (this.user == null || !(this.user.isAdmin || this.user.isModerator))
-				return;
-		}
-
-		// Subscribe events
-		this.subscriber.on("notesStream", this.onNote);
-	}
-
-	private async onNote(note: Packed<"Note">) {
-		if (note.visibility !== "public") return;
-		if (note.channelId != null) return;
-
-		// 関係ない返信は除外
-		if (note.reply && !this.user!.showTimelineReplies) {
-			const reply = note.reply;
-			// 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合
-			if (
-				reply.userId !== this.user!.id &&
-				note.userId !== this.user!.id &&
-				reply.userId !== note.userId
-			)
-				return;
-		}
-
-		// Ignore notes from instances the user has muted
-		if (
-			isInstanceMuted(
-				note,
-				new Set<string>(this.userProfile?.mutedInstances ?? []),
-			)
-		)
-			return;
-
-		// 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する
-		if (isUserRelated(note, this.muting)) return;
-		// 流れてきたNoteがブロックされているユーザーが関わるものだったら無視する
-		if (isUserRelated(note, this.blocking)) return;
-
-		if (note.renote && !note.text && isUserRelated(note, this.renoteMuting))
-			return;
-
-		// 流れてきたNoteがミュートすべきNoteだったら無視する
-		// TODO: 将来的には、単にMutedNoteテーブルにレコードがあるかどうかで判定したい(以下の理由により難しそうではある)
-		// 現状では、ワードミュートにおけるMutedNoteレコードの追加処理はストリーミングに流す処理と並列で行われるため、
-		// レコードが追加されるNoteでも追加されるより先にここのストリーミングの処理に到達することが起こる。
-		// そのためレコードが存在するかのチェックでは不十分なので、改めてgetWordMuteを呼んでいる
-		if (
-			this.userProfile &&
-			(await getWordMute(note, this.user, this.userProfile.mutedWords)).muted
-		)
-			return;
-
-		this.connection.cacheNote(note);
-
-		this.send("note", note);
-	}
-
-	public dispose() {
-		// Unsubscribe events
-		this.subscriber.off("notesStream", this.onNote);
-	}
-}
diff --git a/packages/backend/src/server/api/stream/channels/hashtag.ts b/packages/backend/src/server/api/stream/channels/hashtag.ts
deleted file mode 100644
index a2e5481abb..0000000000
--- a/packages/backend/src/server/api/stream/channels/hashtag.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-import Channel from "../channel.js";
-import { normalizeForSearch } from "@/misc/normalize-for-search.js";
-import { isUserRelated } from "@/misc/is-user-related.js";
-import type { Packed } from "@/misc/schema.js";
-
-export default class extends Channel {
-	public readonly chName = "hashtag";
-	public static shouldShare = false;
-	public static requireCredential = false;
-	private q: string[][];
-
-	constructor(id: string, connection: Channel["connection"]) {
-		super(id, connection);
-		this.onNote = this.withPackedNote(this.onNote.bind(this));
-	}
-
-	public async init(params: any) {
-		this.q = params.q;
-
-		if (this.q == null) return;
-
-		// Subscribe stream
-		this.subscriber.on("notesStream", this.onNote);
-	}
-
-	private async onNote(note: Packed<"Note">) {
-		const noteTags = note.tags
-			? note.tags.map((t: string) => t.toLowerCase())
-			: [];
-		const matched = this.q.some((tags) =>
-			tags.every((tag) => noteTags.includes(normalizeForSearch(tag))),
-		);
-		if (!matched) return;
-
-		// 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する
-		if (isUserRelated(note, this.muting)) return;
-		// 流れてきたNoteがブロックされているユーザーが関わるものだったら無視する
-		if (isUserRelated(note, this.blocking)) return;
-
-		if (note.renote && !note.text && isUserRelated(note, this.renoteMuting))
-			return;
-
-		this.connection.cacheNote(note);
-
-		this.send("note", note);
-	}
-
-	public dispose() {
-		// Unsubscribe events
-		this.subscriber.off("notesStream", this.onNote);
-	}
-}
diff --git a/packages/backend/src/server/api/stream/channels/home-timeline.ts b/packages/backend/src/server/api/stream/channels/home-timeline.ts
deleted file mode 100644
index fa4a8a3901..0000000000
--- a/packages/backend/src/server/api/stream/channels/home-timeline.ts
+++ /dev/null
@@ -1,80 +0,0 @@
-import Channel from "../channel.js";
-import { getWordMute } from "@/misc/check-word-mute.js";
-import { isUserRelated } from "@/misc/is-user-related.js";
-import { isInstanceMuted } from "@/misc/is-instance-muted.js";
-import type { Packed } from "@/misc/schema.js";
-
-export default class extends Channel {
-	public readonly chName = "homeTimeline";
-	public static shouldShare = true;
-	public static requireCredential = true;
-
-	constructor(id: string, connection: Channel["connection"]) {
-		super(id, connection);
-		this.onNote = this.withPackedNote(this.onNote.bind(this));
-	}
-
-	public async init(params: any) {
-		// Subscribe events
-		this.subscriber.on("notesStream", this.onNote);
-	}
-
-	private async onNote(note: Packed<"Note">) {
-		if (note.channelId) {
-			if (!this.followingChannels.has(note.channelId)) return;
-		} else {
-			// その投稿のユーザーをフォローしていなかったら弾く
-			if (this.user!.id !== note.userId && !this.following.has(note.userId))
-				return;
-		}
-
-		// Ignore notes from instances the user has muted
-		if (
-			isInstanceMuted(
-				note,
-				new Set<string>(this.userProfile?.mutedInstances ?? []),
-			)
-		)
-			return;
-
-		// 関係ない返信は除外
-		if (note.reply && !this.user!.showTimelineReplies) {
-			const reply = note.reply;
-			// 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合
-			if (
-				reply.userId !== this.user!.id &&
-				note.userId !== this.user!.id &&
-				reply.userId !== note.userId
-			)
-				return;
-		}
-
-		// 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する
-		if (isUserRelated(note, this.muting)) return;
-		// 流れてきたNoteがブロックされているユーザーが関わるものだったら無視する
-		if (isUserRelated(note, this.blocking)) return;
-
-		if (note.renote && !note.text && isUserRelated(note, this.renoteMuting))
-			return;
-
-		// 流れてきたNoteがミュートすべきNoteだったら無視する
-		// TODO: 将来的には、単にMutedNoteテーブルにレコードがあるかどうかで判定したい(以下の理由により難しそうではある)
-		// 現状では、ワードミュートにおけるMutedNoteレコードの追加処理はストリーミングに流す処理と並列で行われるため、
-		// レコードが追加されるNoteでも追加されるより先にここのストリーミングの処理に到達することが起こる。
-		// そのためレコードが存在するかのチェックでは不十分なので、改めてgetWordMuteを呼んでいる
-		if (
-			this.userProfile &&
-			(await getWordMute(note, this.user, this.userProfile.mutedWords)).muted
-		)
-			return;
-
-		this.connection.cacheNote(note);
-
-		this.send("note", note);
-	}
-
-	public dispose() {
-		// Unsubscribe events
-		this.subscriber.off("notesStream", this.onNote);
-	}
-}
diff --git a/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts b/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts
deleted file mode 100644
index 557bb96827..0000000000
--- a/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts
+++ /dev/null
@@ -1,97 +0,0 @@
-import Channel from "../channel.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { getWordMute } from "@/misc/check-word-mute.js";
-import { isUserRelated } from "@/misc/is-user-related.js";
-import { isInstanceMuted } from "@/misc/is-instance-muted.js";
-import type { Packed } from "@/misc/schema.js";
-
-export default class extends Channel {
-	public readonly chName = "hybridTimeline";
-	public static shouldShare = true;
-	public static requireCredential = true;
-
-	constructor(id: string, connection: Channel["connection"]) {
-		super(id, connection);
-		this.onNote = this.withPackedNote(this.onNote.bind(this));
-	}
-
-	public async init(params: any) {
-		const meta = await fetchMeta();
-		if (
-			meta.disableLocalTimeline &&
-			!this.user!.isAdmin &&
-			!this.user!.isModerator
-		)
-			return;
-
-		// Subscribe events
-		this.subscriber.on("notesStream", this.onNote);
-	}
-
-	private async onNote(note: Packed<"Note">) {
-		// チャンネルの投稿ではなく、自分自身の投稿 または
-		// チャンネルの投稿ではなく、その投稿のユーザーをフォローしている または
-		// チャンネルの投稿ではなく、全体公開のローカルの投稿 または
-		// フォローしているチャンネルの投稿 の場合だけ
-		if (
-			!(
-				(note.channelId == null && this.user!.id === note.userId) ||
-				(note.channelId == null && this.following.has(note.userId)) ||
-				(note.channelId == null &&
-					note.user.host == null &&
-					note.visibility === "public") ||
-				(note.channelId != null && this.followingChannels.has(note.channelId))
-			)
-		)
-			return;
-
-		// Ignore notes from instances the user has muted
-		if (
-			isInstanceMuted(
-				note,
-				new Set<string>(this.userProfile?.mutedInstances ?? []),
-			)
-		)
-			return;
-
-		// 関係ない返信は除外
-		if (note.reply && !this.user!.showTimelineReplies) {
-			const reply = note.reply;
-			// 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合
-			if (
-				reply.userId !== this.user!.id &&
-				note.userId !== this.user!.id &&
-				reply.userId !== note.userId
-			)
-				return;
-		}
-
-		// 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する
-		if (isUserRelated(note, this.muting)) return;
-		// 流れてきたNoteがブロックされているユーザーが関わるものだったら無視する
-		if (isUserRelated(note, this.blocking)) return;
-
-		if (note.renote && !note.text && isUserRelated(note, this.renoteMuting))
-			return;
-
-		// 流れてきたNoteがミュートすべきNoteだったら無視する
-		// TODO: 将来的には、単にMutedNoteテーブルにレコードがあるかどうかで判定したい(以下の理由により難しそうではある)
-		// 現状では、ワードミュートにおけるMutedNoteレコードの追加処理はストリーミングに流す処理と並列で行われるため、
-		// レコードが追加されるNoteでも追加されるより先にここのストリーミングの処理に到達することが起こる。
-		// そのためレコードが存在するかのチェックでは不十分なので、改めてgetWordMuteを呼んでいる
-		if (
-			this.userProfile &&
-			(await getWordMute(note, this.user, this.userProfile.mutedWords)).muted
-		)
-			return;
-
-		this.connection.cacheNote(note);
-
-		this.send("note", note);
-	}
-
-	public dispose() {
-		// Unsubscribe events
-		this.subscriber.off("notesStream", this.onNote);
-	}
-}
diff --git a/packages/backend/src/server/api/stream/channels/index.ts b/packages/backend/src/server/api/stream/channels/index.ts
deleted file mode 100644
index d1127be47c..0000000000
--- a/packages/backend/src/server/api/stream/channels/index.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import main from "./main.js";
-import homeTimeline from "./home-timeline.js";
-import localTimeline from "./local-timeline.js";
-import hybridTimeline from "./hybrid-timeline.js";
-import recommendedTimeline from "./recommended-timeline.js";
-import globalTimeline from "./global-timeline.js";
-import serverStats from "./server-stats.js";
-import queueStats from "./queue-stats.js";
-import userList from "./user-list.js";
-import antenna from "./antenna.js";
-import messaging from "./messaging.js";
-import messagingIndex from "./messaging-index.js";
-import drive from "./drive.js";
-import hashtag from "./hashtag.js";
-import channel from "./channel.js";
-import admin from "./admin.js";
-
-export default {
-	main,
-	homeTimeline,
-	localTimeline,
-	recommendedTimeline,
-	hybridTimeline,
-	globalTimeline,
-	serverStats,
-	queueStats,
-	userList,
-	antenna,
-	messaging,
-	messagingIndex,
-	drive,
-	hashtag,
-	channel,
-	admin,
-};
diff --git a/packages/backend/src/server/api/stream/channels/local-timeline.ts b/packages/backend/src/server/api/stream/channels/local-timeline.ts
deleted file mode 100644
index dc3aab8d7d..0000000000
--- a/packages/backend/src/server/api/stream/channels/local-timeline.ts
+++ /dev/null
@@ -1,74 +0,0 @@
-import Channel from "../channel.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { getWordMute } from "@/misc/check-word-mute.js";
-import { isUserRelated } from "@/misc/is-user-related.js";
-import type { Packed } from "@/misc/schema.js";
-
-export default class extends Channel {
-	public readonly chName = "localTimeline";
-	public static shouldShare = true;
-	public static requireCredential = false;
-
-	constructor(id: string, connection: Channel["connection"]) {
-		super(id, connection);
-		this.onNote = this.withPackedNote(this.onNote.bind(this));
-	}
-
-	public async init(params: any) {
-		const meta = await fetchMeta();
-		if (meta.disableLocalTimeline) {
-			if (this.user == null || !(this.user.isAdmin || this.user.isModerator))
-				return;
-		}
-
-		// Subscribe events
-		this.subscriber.on("notesStream", this.onNote);
-	}
-
-	private async onNote(note: Packed<"Note">) {
-		if (note.user.host !== null) return;
-		if (note.visibility !== "public") return;
-		if (note.channelId != null && !this.followingChannels.has(note.channelId))
-			return;
-
-		// 関係ない返信は除外
-		if (note.reply && !this.user!.showTimelineReplies) {
-			const reply = note.reply;
-			// 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合
-			if (
-				reply.userId !== this.user!.id &&
-				note.userId !== this.user!.id &&
-				reply.userId !== note.userId
-			)
-				return;
-		}
-
-		// 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する
-		if (isUserRelated(note, this.muting)) return;
-		// 流れてきたNoteがブロックされているユーザーが関わるものだったら無視する
-		if (isUserRelated(note, this.blocking)) return;
-
-		if (note.renote && !note.text && isUserRelated(note, this.renoteMuting))
-			return;
-
-		// 流れてきたNoteがミュートすべきNoteだったら無視する
-		// TODO: 将来的には、単にMutedNoteテーブルにレコードがあるかどうかで判定したい(以下の理由により難しそうではある)
-		// 現状では、ワードミュートにおけるMutedNoteレコードの追加処理はストリーミングに流す処理と並列で行われるため、
-		// レコードが追加されるNoteでも追加されるより先にここのストリーミングの処理に到達することが起こる。
-		// そのためレコードが存在するかのチェックでは不十分なので、改めてgetWordMuteを呼んでいる
-		if (
-			this.userProfile &&
-			(await getWordMute(note, this.user, this.userProfile.mutedWords)).muted
-		)
-			return;
-
-		this.connection.cacheNote(note);
-
-		this.send("note", note);
-	}
-
-	public dispose() {
-		// Unsubscribe events
-		this.subscriber.off("notesStream", this.onNote);
-	}
-}
diff --git a/packages/backend/src/server/api/stream/channels/main.ts b/packages/backend/src/server/api/stream/channels/main.ts
deleted file mode 100644
index b8c72442ff..0000000000
--- a/packages/backend/src/server/api/stream/channels/main.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import Channel from "../channel.js";
-import {
-	isInstanceMuted,
-	isUserFromMutedInstance,
-} from "@/misc/is-instance-muted.js";
-
-export default class extends Channel {
-	public readonly chName = "main";
-	public static shouldShare = true;
-	public static requireCredential = true;
-
-	public async init(params: any) {
-		// Subscribe main stream channel
-		this.subscriber.on(`mainStream:${this.user!.id}`, async (data) => {
-			switch (data.type) {
-				case "notification": {
-					// Ignore notifications from instances the user has muted
-					if (
-						isUserFromMutedInstance(
-							data.body,
-							new Set<string>(this.userProfile?.mutedInstances ?? []),
-						)
-					)
-						return;
-					if (data.body.userId && this.muting.has(data.body.userId)) return;
-
-					break;
-				}
-				case "mention": {
-					if (
-						isInstanceMuted(
-							data.body,
-							new Set<string>(this.userProfile?.mutedInstances ?? []),
-						)
-					)
-						return;
-
-					if (this.muting.has(data.body.userId)) return;
-					break;
-				}
-			}
-
-			this.send(data.type, data.body);
-		});
-	}
-}
diff --git a/packages/backend/src/server/api/stream/channels/messaging-index.ts b/packages/backend/src/server/api/stream/channels/messaging-index.ts
deleted file mode 100644
index 8165172d73..0000000000
--- a/packages/backend/src/server/api/stream/channels/messaging-index.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import Channel from "../channel.js";
-
-export default class extends Channel {
-	public readonly chName = "messagingIndex";
-	public static shouldShare = true;
-	public static requireCredential = true;
-
-	public async init(params: any) {
-		// Subscribe messaging index stream
-		this.subscriber.on(`messagingIndexStream:${this.user!.id}`, (data) => {
-			this.send(data);
-		});
-	}
-}
diff --git a/packages/backend/src/server/api/stream/channels/messaging.ts b/packages/backend/src/server/api/stream/channels/messaging.ts
deleted file mode 100644
index 0622bd4649..0000000000
--- a/packages/backend/src/server/api/stream/channels/messaging.ts
+++ /dev/null
@@ -1,130 +0,0 @@
-import {
-	readUserMessagingMessage,
-	readGroupMessagingMessage,
-	deliverReadActivity,
-} from "../../common/read-messaging-message.js";
-import Channel from "../channel.js";
-import { UserGroupJoinings, Users, MessagingMessages } from "@/models/index.js";
-import type { User, ILocalUser, IRemoteUser } from "@/models/entities/user.js";
-import type { UserGroup } from "@/models/entities/user-group.js";
-import type { StreamMessages } from "../types.js";
-
-export default class extends Channel {
-	public readonly chName = "messaging";
-	public static shouldShare = false;
-	public static requireCredential = true;
-
-	private otherpartyId: string | null;
-	private otherparty: User | null;
-	private groupId: string | null;
-	private subCh:
-		| `messagingStream:${User["id"]}-${User["id"]}`
-		| `messagingStream:${UserGroup["id"]}`;
-	private typers: Map<User["id"], Date> = new Map();
-	private emitTypersIntervalId: ReturnType<typeof setInterval>;
-
-	constructor(id: string, connection: Channel["connection"]) {
-		super(id, connection);
-		this.onEvent = this.onEvent.bind(this);
-		this.onMessage = this.onMessage.bind(this);
-		this.emitTypers = this.emitTypers.bind(this);
-	}
-
-	public async init(params: any) {
-		this.otherpartyId = params.otherparty;
-		this.otherparty = this.otherpartyId
-			? await Users.findOneByOrFail({ id: this.otherpartyId })
-			: null;
-		this.groupId = params.group;
-
-		// Check joining
-		if (this.groupId) {
-			const joining = await UserGroupJoinings.findOneBy({
-				userId: this.user!.id,
-				userGroupId: this.groupId,
-			});
-
-			if (joining == null) {
-				return;
-			}
-		}
-
-		this.emitTypersIntervalId = setInterval(this.emitTypers, 5000);
-
-		this.subCh = this.otherpartyId
-			? `messagingStream:${this.user!.id}-${this.otherpartyId}`
-			: `messagingStream:${this.groupId}`;
-
-		// Subscribe messaging stream
-		this.subscriber.on(this.subCh, this.onEvent);
-	}
-
-	private onEvent(
-		data:
-			| StreamMessages["messaging"]["payload"]
-			| StreamMessages["groupMessaging"]["payload"],
-	) {
-		if (data.type === "typing") {
-			const id = data.body;
-			const begin = !this.typers.has(id);
-			this.typers.set(id, new Date());
-			if (begin) {
-				this.emitTypers();
-			}
-		} else {
-			this.send(data);
-		}
-	}
-
-	public onMessage(type: string, body: any) {
-		switch (type) {
-			case "read":
-				if (this.otherpartyId) {
-					readUserMessagingMessage(this.user!.id, this.otherpartyId, [body.id]);
-
-					// リモートユーザーからのメッセージだったら既読配信
-					if (
-						Users.isLocalUser(this.user!) &&
-						Users.isRemoteUser(this.otherparty!)
-					) {
-						MessagingMessages.findOneBy({ id: body.id }).then((message) => {
-							if (message)
-								deliverReadActivity(
-									this.user as ILocalUser,
-									this.otherparty as IRemoteUser,
-									message,
-								);
-						});
-					}
-				} else if (this.groupId) {
-					readGroupMessagingMessage(this.user!.id, this.groupId, [body.id]);
-				}
-				break;
-		}
-	}
-
-	private async emitTypers() {
-		const now = new Date();
-
-		// Remove not typing users
-		for (const [userId, date] of this.typers.entries()) {
-			if (now.getTime() - date.getTime() > 5000) this.typers.delete(userId);
-		}
-
-		const userIds = Array.from(this.typers.keys());
-		const users = await Users.packMany(userIds, null, {
-			detail: false,
-		});
-
-		this.send({
-			type: "typers",
-			body: users,
-		});
-	}
-
-	public dispose() {
-		this.subscriber.off(this.subCh, this.onEvent);
-
-		clearInterval(this.emitTypersIntervalId);
-	}
-}
diff --git a/packages/backend/src/server/api/stream/channels/queue-stats.ts b/packages/backend/src/server/api/stream/channels/queue-stats.ts
deleted file mode 100644
index a5a93c332e..0000000000
--- a/packages/backend/src/server/api/stream/channels/queue-stats.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import Xev from "xev";
-import Channel from "../channel.js";
-
-const ev = new Xev();
-
-export default class extends Channel {
-	public readonly chName = "queueStats";
-	public static shouldShare = true;
-	public static requireCredential = false;
-
-	constructor(id: string, connection: Channel["connection"]) {
-		super(id, connection);
-		this.onStats = this.onStats.bind(this);
-		this.onMessage = this.onMessage.bind(this);
-	}
-
-	public async init(params: any) {
-		ev.addListener("queueStats", this.onStats);
-	}
-
-	private onStats(stats: any) {
-		this.send("stats", stats);
-	}
-
-	public onMessage(type: string, body: any) {
-		switch (type) {
-			case "requestLog":
-				ev.once(`queueStatsLog:${body.id}`, (statsLog) => {
-					this.send("statsLog", statsLog);
-				});
-				ev.emit("requestQueueStatsLog", {
-					id: body.id,
-					length: body.length,
-				});
-				break;
-		}
-	}
-
-	public dispose() {
-		ev.removeListener("queueStats", this.onStats);
-	}
-}
diff --git a/packages/backend/src/server/api/stream/channels/recommended-timeline.ts b/packages/backend/src/server/api/stream/channels/recommended-timeline.ts
deleted file mode 100644
index 6baec77442..0000000000
--- a/packages/backend/src/server/api/stream/channels/recommended-timeline.ts
+++ /dev/null
@@ -1,95 +0,0 @@
-import Channel from "../channel.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { getWordMute } from "@/misc/check-word-mute.js";
-import { isUserRelated } from "@/misc/is-user-related.js";
-import { isInstanceMuted } from "@/misc/is-instance-muted.js";
-import type { Packed } from "@/misc/schema.js";
-
-export default class extends Channel {
-	public readonly chName = "recommendedTimeline";
-	public static shouldShare = true;
-	public static requireCredential = true;
-
-	constructor(id: string, connection: Channel["connection"]) {
-		super(id, connection);
-		this.onNote = this.withPackedNote(this.onNote.bind(this));
-	}
-
-	public async init(params: any) {
-		const meta = await fetchMeta();
-		if (
-			meta.disableRecommendedTimeline &&
-			!this.user!.isAdmin &&
-			!this.user!.isModerator
-		)
-			return;
-
-		// Subscribe events
-		this.subscriber.on("notesStream", this.onNote);
-	}
-
-	private async onNote(note: Packed<"Note">) {
-		// チャンネルの投稿ではなく、自分自身の投稿 または
-		// チャンネルの投稿ではなく、その投稿のユーザーをフォローしている または
-		// チャンネルの投稿ではなく、全体公開のローカルの投稿 または
-		// フォローしているチャンネルの投稿 の場合だけ
-		const meta = await fetchMeta();
-		if (
-			!(
-				note.user.host != null &&
-				meta.recommendedInstances.includes(note.user.host) &&
-				note.visibility === "public"
-			)
-		)
-			return;
-
-		// Ignore notes from instances the user has muted
-		if (
-			isInstanceMuted(
-				note,
-				new Set<string>(this.userProfile?.mutedInstances ?? []),
-			)
-		)
-			return;
-
-		// 関係ない返信は除外
-		if (note.reply && !this.user!.showTimelineReplies) {
-			const reply = note.reply;
-			// 「チャンネル接続主への返信」でもなければ、「チャンネル接続主が行った返信」でもなければ、「投稿者の投稿者自身への返信」でもない場合
-			if (
-				reply.userId !== this.user!.id &&
-				note.userId !== this.user!.id &&
-				reply.userId !== note.userId
-			)
-				return;
-		}
-
-		// 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する
-		if (isUserRelated(note, this.muting)) return;
-		// 流れてきたNoteがブロックされているユーザーが関わるものだったら無視する
-		if (isUserRelated(note, this.blocking)) return;
-
-		if (note.renote && !note.text && isUserRelated(note, this.renoteMuting))
-			return;
-
-		// 流れてきたNoteがミュートすべきNoteだったら無視する
-		// TODO: 将来的には、単にMutedNoteテーブルにレコードがあるかどうかで判定したい(以下の理由により難しそうではある)
-		// 現状では、ワードミュートにおけるMutedNoteレコードの追加処理はストリーミングに流す処理と並列で行われるため、
-		// レコードが追加されるNoteでも追加されるより先にここのストリーミングの処理に到達することが起こる。
-		// そのためレコードが存在するかのチェックでは不十分なので、改めてgetWordMuteを呼んでいる
-		if (
-			this.userProfile &&
-			(await getWordMute(note, this.user, this.userProfile.mutedWords)).muted
-		)
-			return;
-
-		this.connection.cacheNote(note);
-
-		this.send("note", note);
-	}
-
-	public dispose() {
-		// Unsubscribe events
-		this.subscriber.off("notesStream", this.onNote);
-	}
-}
diff --git a/packages/backend/src/server/api/stream/channels/server-stats.ts b/packages/backend/src/server/api/stream/channels/server-stats.ts
deleted file mode 100644
index 58659138de..0000000000
--- a/packages/backend/src/server/api/stream/channels/server-stats.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import Xev from "xev";
-import Channel from "../channel.js";
-
-const ev = new Xev();
-
-export default class extends Channel {
-	public readonly chName = "serverStats";
-	public static shouldShare = true;
-	public static requireCredential = false;
-
-	constructor(id: string, connection: Channel["connection"]) {
-		super(id, connection);
-		this.onStats = this.onStats.bind(this);
-		this.onMessage = this.onMessage.bind(this);
-	}
-
-	public async init(params: any) {
-		ev.addListener("serverStats", this.onStats);
-	}
-
-	private onStats(stats: any) {
-		this.send("stats", stats);
-	}
-
-	public onMessage(type: string, body: any) {
-		switch (type) {
-			case "requestLog":
-				ev.once(`serverStatsLog:${body.id}`, (statsLog) => {
-					this.send("statsLog", statsLog);
-				});
-				ev.emit("requestServerStatsLog", {
-					id: body.id,
-					length: body.length,
-				});
-				break;
-		}
-	}
-
-	public dispose() {
-		ev.removeListener("serverStats", this.onStats);
-	}
-}
diff --git a/packages/backend/src/server/api/stream/channels/user-list.ts b/packages/backend/src/server/api/stream/channels/user-list.ts
deleted file mode 100644
index 105c45955c..0000000000
--- a/packages/backend/src/server/api/stream/channels/user-list.ts
+++ /dev/null
@@ -1,72 +0,0 @@
-import Channel from "../channel.js";
-import { UserListJoinings, UserLists } from "@/models/index.js";
-import type { User } from "@/models/entities/user.js";
-import { isUserRelated } from "@/misc/is-user-related.js";
-import type { Packed } from "@/misc/schema.js";
-
-export default class extends Channel {
-	public readonly chName = "userList";
-	public static shouldShare = false;
-	public static requireCredential = false;
-	private listId: string;
-	public listUsers: User["id"][] = [];
-	private listUsersClock: NodeJS.Timer;
-
-	constructor(id: string, connection: Channel["connection"]) {
-		super(id, connection);
-		this.updateListUsers = this.updateListUsers.bind(this);
-		this.onNote = this.withPackedNote(this.onNote.bind(this));
-	}
-
-	public async init(params: any) {
-		this.listId = params.listId as string;
-
-		// Check existence and owner
-		const list = await UserLists.findOneBy({
-			id: this.listId,
-			userId: this.user!.id,
-		});
-		if (!list) return;
-
-		// Subscribe stream
-		this.subscriber.on(`userListStream:${this.listId}`, this.send);
-
-		this.subscriber.on("notesStream", this.onNote);
-
-		this.updateListUsers();
-		this.listUsersClock = setInterval(this.updateListUsers, 5000);
-	}
-
-	private async updateListUsers() {
-		const users = await UserListJoinings.find({
-			where: {
-				userListId: this.listId,
-			},
-			select: ["userId"],
-		});
-
-		this.listUsers = users.map((x) => x.userId);
-	}
-
-	private async onNote(note: Packed<"Note">) {
-		if (!this.listUsers.includes(note.userId)) return;
-
-		// 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する
-		if (isUserRelated(note, this.muting)) return;
-		// 流れてきたNoteがブロックされているユーザーが関わるものだったら無視する
-		if (isUserRelated(note, this.blocking)) return;
-
-		if (note.renote && !note.text && isUserRelated(note, this.renoteMuting))
-			return;
-
-		this.send("note", note);
-	}
-
-	public dispose() {
-		// Unsubscribe events
-		this.subscriber.off(`userListStream:${this.listId}`, this.send);
-		this.subscriber.off("notesStream", this.onNote);
-
-		clearInterval(this.listUsersClock);
-	}
-}
diff --git a/packages/backend/src/server/api/stream/index.ts b/packages/backend/src/server/api/stream/index.ts
deleted file mode 100644
index 055fe200b7..0000000000
--- a/packages/backend/src/server/api/stream/index.ts
+++ /dev/null
@@ -1,621 +0,0 @@
-import type { EventEmitter } from "events";
-import type * as websocket from "websocket";
-import readNote from "@/services/note/read.js";
-import type { User } from "@/models/entities/user.js";
-import type { Channel as ChannelModel } from "@/models/entities/channel.js";
-import {
-	Users,
-	Followings,
-	Mutings,
-	RenoteMutings,
-	UserProfiles,
-	ChannelFollowings,
-	Blockings,
-} from "@/models/index.js";
-import type { AccessToken } from "@/models/entities/access-token.js";
-import type { UserProfile } from "@/models/entities/user-profile.js";
-import {
-	publishChannelStream,
-	publishGroupMessagingStream,
-	publishMessagingStream,
-} from "@/services/stream.js";
-import type { UserGroup } from "@/models/entities/user-group.js";
-import type { Packed } from "@/misc/schema.js";
-import { readNotification } from "../common/read-notification.js";
-import channels from "./channels/index.js";
-import type Channel from "./channel.js";
-import type { StreamEventEmitter, StreamMessages } from "./types.js";
-import { Converter } from "@calckey/megalodon";
-import { getClient } from "../mastodon/ApiMastodonCompatibleService.js";
-import { toTextWithReaction } from "../mastodon/endpoints/timeline.js";
-
-/**
- * Main stream connection
- */
-export default class Connection {
-	public user?: User;
-	public userProfile?: UserProfile | null;
-	public following: Set<User["id"]> = new Set();
-	public muting: Set<User["id"]> = new Set();
-	public renoteMuting: Set<User["id"]> = new Set();
-	public blocking: Set<User["id"]> = new Set(); // "被"blocking
-	public followingChannels: Set<ChannelModel["id"]> = new Set();
-	public token?: AccessToken;
-	private wsConnection: websocket.connection;
-	public subscriber: StreamEventEmitter;
-	private channels: Channel[] = [];
-	private subscribingNotes: Map<string, number> = new Map();
-	private cachedNotes: Packed<"Note">[] = [];
-	private isMastodonCompatible: boolean = false;
-	private host: string;
-	private accessToken: string;
-	private currentSubscribe: string[][] = [];
-
-	constructor(
-		wsConnection: websocket.connection,
-		subscriber: EventEmitter,
-		user: User | null | undefined,
-		token: AccessToken | null | undefined,
-		host: string,
-		accessToken: string,
-		prepareStream: string | undefined,
-	) {
-		console.log("constructor", prepareStream);
-		this.wsConnection = wsConnection;
-		this.subscriber = subscriber;
-		if (user) this.user = user;
-		if (token) this.token = token;
-		if (host) this.host = host;
-		if (accessToken) this.accessToken = accessToken;
-
-		this.onWsConnectionMessage = this.onWsConnectionMessage.bind(this);
-		this.onUserEvent = this.onUserEvent.bind(this);
-		this.onNoteStreamMessage = this.onNoteStreamMessage.bind(this);
-		this.onBroadcastMessage = this.onBroadcastMessage.bind(this);
-
-		this.wsConnection.on("message", this.onWsConnectionMessage);
-
-		this.subscriber.on("broadcast", (data) => {
-			this.onBroadcastMessage(data);
-		});
-
-		if (this.user) {
-			this.updateFollowing();
-			this.updateMuting();
-			this.updateRenoteMuting();
-			this.updateBlocking();
-			this.updateFollowingChannels();
-			this.updateUserProfile();
-
-			this.subscriber.on(`user:${this.user.id}`, this.onUserEvent);
-		}
-		console.log("prepare", prepareStream);
-		if (prepareStream) {
-			this.onWsConnectionMessage({
-				type: "utf8",
-				utf8Data: JSON.stringify({ stream: prepareStream, type: "subscribe" }),
-			});
-		}
-	}
-
-	private onUserEvent(data: StreamMessages["user"]["payload"]) {
-		// { type, body }と展開するとそれぞれ型が分離してしまう
-		switch (data.type) {
-			case "follow":
-				this.following.add(data.body.id);
-				break;
-
-			case "unfollow":
-				this.following.delete(data.body.id);
-				break;
-
-			case "mute":
-				this.muting.add(data.body.id);
-				break;
-
-			case "unmute":
-				this.muting.delete(data.body.id);
-				break;
-
-			// TODO: renote mute events
-			// TODO: block events
-
-			case "followChannel":
-				this.followingChannels.add(data.body.id);
-				break;
-
-			case "unfollowChannel":
-				this.followingChannels.delete(data.body.id);
-				break;
-
-			case "updateUserProfile":
-				this.userProfile = data.body;
-				break;
-
-			case "terminate":
-				this.wsConnection.close();
-				this.dispose();
-				break;
-
-			default:
-				break;
-		}
-	}
-
-	/**
-	 * クライアントからメッセージ受信時
-	 */
-	private async onWsConnectionMessage(data: websocket.Message) {
-		if (data.type !== "utf8") return;
-		if (data.utf8Data == null) return;
-
-		let objs: Record<string, any>[];
-
-		try {
-			objs = [JSON.parse(data.utf8Data)];
-		} catch (e) {
-			return;
-		}
-
-		const simpleObj = objs[0];
-		if (simpleObj.stream) {
-			// is Mastodon Compatible
-			this.isMastodonCompatible = true;
-			if (simpleObj.type === "subscribe") {
-				let forSubscribe = [];
-				if (simpleObj.stream === "user") {
-					this.currentSubscribe.push(["user"]);
-					objs = [
-						{
-							type: "connect",
-							body: {
-								channel: "main",
-								id: simpleObj.stream,
-							},
-						},
-						{
-							type: "connect",
-							body: {
-								channel: "homeTimeline",
-								id: simpleObj.stream,
-							},
-						},
-					];
-					const client = getClient(this.host, this.accessToken);
-					try {
-						const tl = await client.getHomeTimeline();
-						for (const t of tl.data) forSubscribe.push(t.id);
-					} catch (e: any) {
-						console.log(e);
-						console.error(e.response.data);
-					}
-				} else if (simpleObj.stream === "public:local") {
-					this.currentSubscribe.push(["public:local"]);
-					objs = [
-						{
-							type: "connect",
-							body: {
-								channel: "localTimeline",
-								id: simpleObj.stream,
-							},
-						},
-					];
-					const client = getClient(this.host, this.accessToken);
-					const tl = await client.getLocalTimeline();
-					for (const t of tl.data) forSubscribe.push(t.id);
-				} else if (simpleObj.stream === "public") {
-					this.currentSubscribe.push(["public"]);
-					objs = [
-						{
-							type: "connect",
-							body: {
-								channel: "globalTimeline",
-								id: simpleObj.stream,
-							},
-						},
-					];
-					const client = getClient(this.host, this.accessToken);
-					const tl = await client.getPublicTimeline();
-					for (const t of tl.data) forSubscribe.push(t.id);
-				} else if (simpleObj.stream === "list") {
-					this.currentSubscribe.push(["list", simpleObj.list]);
-					objs = [
-						{
-							type: "connect",
-							body: {
-								channel: "list",
-								id: simpleObj.stream,
-								params: {
-									listId: simpleObj.list,
-								},
-							},
-						},
-					];
-					const client = getClient(this.host, this.accessToken);
-					const tl = await client.getListTimeline(simpleObj.list);
-					for (const t of tl.data) forSubscribe.push(t.id);
-				}
-				for (const s of forSubscribe) {
-					objs.push({
-						type: "s",
-						body: {
-							id: s,
-						},
-					});
-				}
-			}
-		}
-
-		for (const obj of objs) {
-			const { type, body } = obj;
-			console.log(type, body);
-			switch (type) {
-				case "readNotification":
-					this.onReadNotification(body);
-					break;
-				case "subNote":
-					this.onSubscribeNote(body);
-					break;
-				case "s":
-					this.onSubscribeNote(body);
-					break; // alias
-				case "sr":
-					this.onSubscribeNote(body);
-					this.readNote(body);
-					break;
-				case "unsubNote":
-					this.onUnsubscribeNote(body);
-					break;
-				case "un":
-					this.onUnsubscribeNote(body);
-					break; // alias
-				case "connect":
-					this.onChannelConnectRequested(body);
-					break;
-				case "disconnect":
-					this.onChannelDisconnectRequested(body);
-					break;
-				case "channel":
-					this.onChannelMessageRequested(body);
-					break;
-				case "ch":
-					this.onChannelMessageRequested(body);
-					break; // alias
-
-				// 個々のチャンネルではなくルートレベルでこれらのメッセージを受け取る理由は、
-				// クライアントの事情を考慮したとき、入力フォームはノートチャンネルやメッセージのメインコンポーネントとは別
-				// なこともあるため、それらのコンポーネントがそれぞれ各チャンネルに接続するようにするのは面倒なため。
-				case "typingOnChannel":
-					this.typingOnChannel(body.channel);
-					break;
-				case "typingOnMessaging":
-					this.typingOnMessaging(body);
-					break;
-			}
-		}
-	}
-
-	private onBroadcastMessage(data: StreamMessages["broadcast"]["payload"]) {
-		this.sendMessageToWs(data.type, data.body);
-	}
-
-	public cacheNote(note: Packed<"Note">) {
-		const add = (note: Packed<"Note">) => {
-			const existIndex = this.cachedNotes.findIndex((n) => n.id === note.id);
-			if (existIndex > -1) {
-				this.cachedNotes[existIndex] = note;
-				return;
-			}
-
-			this.cachedNotes.unshift(note);
-			if (this.cachedNotes.length > 32) {
-				this.cachedNotes.splice(32);
-			}
-		};
-
-		add(note);
-		if (note.reply) add(note.reply);
-		if (note.renote) add(note.renote);
-	}
-
-	private readNote(body: any) {
-		const id = body.id;
-
-		const note = this.cachedNotes.find((n) => n.id === id);
-		if (note == null) return;
-
-		if (this.user && note.userId !== this.user.id) {
-			readNote(this.user.id, [note], {
-				following: this.following,
-				followingChannels: this.followingChannels,
-			});
-		}
-	}
-
-	private onReadNotification(payload: any) {
-		if (!payload.id) return;
-		readNotification(this.user!.id, [payload.id]);
-	}
-
-	/**
-	 * 投稿購読要求時
-	 */
-	private onSubscribeNote(payload: any) {
-		if (!payload.id) return;
-
-		const current = this.subscribingNotes.get(payload.id) || 0;
-		this.subscribingNotes.set(payload.id, current + 1);
-
-		if (!current) {
-			this.subscriber.on(`noteStream:${payload.id}`, this.onNoteStreamMessage);
-		}
-	}
-
-	/**
-	 * 投稿購読解除要求時
-	 */
-	private onUnsubscribeNote(payload: any) {
-		if (!payload.id) return;
-
-		const current = this.subscribingNotes.get(payload.id) || 0;
-		if (current <= 1) {
-			this.subscribingNotes.delete(payload.id);
-			this.subscriber.off(`noteStream:${payload.id}`, this.onNoteStreamMessage);
-			return;
-		}
-		this.subscribingNotes.set(payload.id, current - 1);
-	}
-
-	private async onNoteStreamMessage(data: StreamMessages["note"]["payload"]) {
-		this.sendMessageToWs("noteUpdated", {
-			id: data.body.id,
-			type: data.type,
-			body: data.body.body,
-		});
-	}
-
-	/**
-	 * チャンネル接続要求時
-	 */
-	private onChannelConnectRequested(payload: any) {
-		const { channel, id, params, pong } = payload;
-		this.connectChannel(id, params, channel, pong);
-	}
-
-	/**
-	 * チャンネル切断要求時
-	 */
-	private onChannelDisconnectRequested(payload: any) {
-		const { id } = payload;
-		this.disconnectChannel(id);
-	}
-
-	/**
-	 * クライアントにメッセージ送信
-	 */
-	public sendMessageToWs(type: string, payload: any) {
-		console.log(payload, this.isMastodonCompatible);
-		if (this.isMastodonCompatible) {
-			if (payload.type === "note") {
-				this.wsConnection.send(
-					JSON.stringify({
-						stream: [payload.id],
-						event: "update",
-						payload: JSON.stringify(
-							toTextWithReaction(
-								[Converter.note(payload.body, this.host)],
-								this.host,
-							)[0],
-						),
-					}),
-				);
-				this.onSubscribeNote({
-					id: payload.body.id,
-				});
-			} else if (payload.type === "reacted" || payload.type === "unreacted") {
-				// reaction
-				const client = getClient(this.host, this.accessToken);
-				client.getStatus(payload.id).then((data) => {
-					const newPost = toTextWithReaction([data.data], this.host);
-					const targetPost = newPost[0];
-					for (const stream of this.currentSubscribe) {
-						this.wsConnection.send(
-							JSON.stringify({
-								stream,
-								event: "status.update",
-								payload: JSON.stringify(targetPost),
-							}),
-						);
-					}
-				});
-			} else if (payload.type === "deleted") {
-				// delete
-				for (const stream of this.currentSubscribe) {
-					this.wsConnection.send(
-						JSON.stringify({
-							stream,
-							event: "delete",
-							payload: payload.id,
-						}),
-					);
-				}
-			} else if (payload.type === "unreadNotification") {
-				if (payload.id === "user") {
-					const body = Converter.notification(payload.body, this.host);
-					if (body.type === "reaction") body.type = "favourite";
-					body.status = toTextWithReaction(
-						body.status ? [body.status] : [],
-						"",
-					)[0];
-					this.wsConnection.send(
-						JSON.stringify({
-							stream: ["user"],
-							event: "notification",
-							payload: JSON.stringify(body),
-						}),
-					);
-				}
-			}
-		} else {
-			this.wsConnection.send(
-				JSON.stringify({
-					type: type,
-					body: payload,
-				}),
-			);
-		}
-	}
-
-	/**
-	 * チャンネルに接続
-	 */
-	public connectChannel(
-		id: string,
-		params: any,
-		channel: string,
-		pong = false,
-	) {
-		if ((channels as any)[channel].requireCredential && this.user == null) {
-			return;
-		}
-
-		// 共有可能チャンネルに接続しようとしていて、かつそのチャンネルに既に接続していたら無意味なので無視
-		if (
-			(channels as any)[channel].shouldShare &&
-			this.channels.some((c) => c.chName === channel)
-		) {
-			return;
-		}
-
-		const ch: Channel = new (channels as any)[channel](id, this);
-		this.channels.push(ch);
-		ch.init(params);
-
-		if (pong) {
-			this.sendMessageToWs("connected", {
-				id: id,
-			});
-		}
-	}
-
-	/**
-	 * チャンネルから切断
-	 * @param id チャンネルコネクションID
-	 */
-	public disconnectChannel(id: string) {
-		const channel = this.channels.find((c) => c.id === id);
-
-		if (channel) {
-			if (channel.dispose) channel.dispose();
-			this.channels = this.channels.filter((c) => c.id !== id);
-		}
-	}
-
-	/**
-	 * チャンネルへメッセージ送信要求時
-	 * @param data メッセージ
-	 */
-	private onChannelMessageRequested(data: any) {
-		const channel = this.channels.find((c) => c.id === data.id);
-		if (channel?.onMessage != null) {
-			channel.onMessage(data.type, data.body);
-		}
-	}
-
-	private typingOnChannel(channel: ChannelModel["id"]) {
-		if (this.user) {
-			publishChannelStream(channel, "typing", this.user.id);
-		}
-	}
-
-	private typingOnMessaging(param: {
-		partner?: User["id"];
-		group?: UserGroup["id"];
-	}) {
-		if (this.user) {
-			if (param.partner) {
-				publishMessagingStream(
-					param.partner,
-					this.user.id,
-					"typing",
-					this.user.id,
-				);
-			} else if (param.group) {
-				publishGroupMessagingStream(param.group, "typing", this.user.id);
-			}
-		}
-	}
-
-	private async updateFollowing() {
-		const followings = await Followings.find({
-			where: {
-				followerId: this.user!.id,
-			},
-			select: ["followeeId"],
-		});
-
-		this.following = new Set<string>(followings.map((x) => x.followeeId));
-	}
-
-	private async updateMuting() {
-		const mutings = await Mutings.find({
-			where: {
-				muterId: this.user!.id,
-			},
-			select: ["muteeId"],
-		});
-
-		this.muting = new Set<string>(mutings.map((x) => x.muteeId));
-	}
-
-	private async updateRenoteMuting() {
-		const renoteMutings = await RenoteMutings.find({
-			where: {
-				muterId: this.user!.id,
-			},
-			select: ["muteeId"],
-		});
-
-		this.renoteMuting = new Set<string>(renoteMutings.map((x) => x.muteeId));
-	}
-
-	private async updateBlocking() {
-		// ここでいうBlockingは被Blockingの意
-		const blockings = await Blockings.find({
-			where: {
-				blockeeId: this.user!.id,
-			},
-			select: ["blockerId"],
-		});
-
-		this.blocking = new Set<string>(blockings.map((x) => x.blockerId));
-	}
-
-	private async updateFollowingChannels() {
-		const followings = await ChannelFollowings.find({
-			where: {
-				followerId: this.user!.id,
-			},
-			select: ["followeeId"],
-		});
-
-		this.followingChannels = new Set<string>(
-			followings.map((x) => x.followeeId),
-		);
-	}
-
-	private async updateUserProfile() {
-		this.userProfile = await UserProfiles.findOneBy({
-			userId: this.user!.id,
-		});
-	}
-
-	/**
-	 * ストリームが切れたとき
-	 */
-	public dispose() {
-		for (const c of this.channels.filter((c) => c.dispose)) {
-			if (c.dispose) c.dispose();
-		}
-	}
-}
diff --git a/packages/backend/src/server/api/stream/types.ts b/packages/backend/src/server/api/stream/types.ts
deleted file mode 100644
index 9becf9f642..0000000000
--- a/packages/backend/src/server/api/stream/types.ts
+++ /dev/null
@@ -1,292 +0,0 @@
-import type { EventEmitter } from "events";
-import type Emitter from "strict-event-emitter-types";
-import type { Channel } from "@/models/entities/channel.js";
-import type { User } from "@/models/entities/user.js";
-import type { UserProfile } from "@/models/entities/user-profile.js";
-import type { Note } from "@/models/entities/note.js";
-import type { Antenna } from "@/models/entities/antenna.js";
-import type { DriveFile } from "@/models/entities/drive-file.js";
-import type { DriveFolder } from "@/models/entities/drive-folder.js";
-import type { UserList } from "@/models/entities/user-list.js";
-import type { MessagingMessage } from "@/models/entities/messaging-message.js";
-import type { UserGroup } from "@/models/entities/user-group.js";
-import type { AbuseUserReport } from "@/models/entities/abuse-user-report.js";
-import type { Signin } from "@/models/entities/signin.js";
-import type { Page } from "@/models/entities/page.js";
-import type { Packed } from "@/misc/schema.js";
-import type { Webhook } from "@/models/entities/webhook";
-
-//#region Stream type-body definitions
-export interface InternalStreamTypes {
-	userChangeSuspendedState: {
-		id: User["id"];
-		isSuspended: User["isSuspended"];
-	};
-	userChangeSilencedState: {
-		id: User["id"];
-		isSilenced: User["isSilenced"];
-	};
-	userChangeModeratorState: {
-		id: User["id"];
-		isModerator: User["isModerator"];
-	};
-	userTokenRegenerated: {
-		id: User["id"];
-		oldToken: User["token"];
-		newToken: User["token"];
-	};
-	localUserUpdated: {
-		id: User["id"];
-	};
-	remoteUserUpdated: {
-		id: User["id"];
-	};
-	webhookCreated: Webhook;
-	webhookDeleted: Webhook;
-	webhookUpdated: Webhook;
-	antennaCreated: Antenna;
-	antennaDeleted: Antenna;
-	antennaUpdated: Antenna;
-}
-
-export interface BroadcastTypes {
-	emojiAdded: {
-		emoji: Packed<"Emoji">;
-	};
-}
-
-export interface UserStreamTypes {
-	terminate: Record<string, unknown>;
-	followChannel: Channel;
-	unfollowChannel: Channel;
-	updateUserProfile: UserProfile;
-	mute: User;
-	unmute: User;
-	follow: Packed<"UserDetailedNotMe">;
-	unfollow: Packed<"User">;
-	userAdded: Packed<"User">;
-}
-
-export interface MainStreamTypes {
-	notification: Packed<"Notification">;
-	mention: Packed<"Note">;
-	reply: Packed<"Note">;
-	renote: Packed<"Note">;
-	follow: Packed<"UserDetailedNotMe">;
-	followed: Packed<"User">;
-	unfollow: Packed<"User">;
-	meUpdated: Packed<"User">;
-	pageEvent: {
-		pageId: Page["id"];
-		event: string;
-		var: any;
-		userId: User["id"];
-		user: Packed<"User">;
-	};
-	urlUploadFinished: {
-		marker?: string | null;
-		file: Packed<"DriveFile">;
-	};
-	readAllNotifications: undefined;
-	unreadNotification: Packed<"Notification">;
-	unreadMention: Note["id"];
-	readAllUnreadMentions: undefined;
-	unreadSpecifiedNote: Note["id"];
-	readAllUnreadSpecifiedNotes: undefined;
-	readAllMessagingMessages: undefined;
-	messagingMessage: Packed<"MessagingMessage">;
-	unreadMessagingMessage: Packed<"MessagingMessage">;
-	readAllAntennas: undefined;
-	unreadAntenna: Antenna;
-	readAllAnnouncements: undefined;
-	readAllChannels: undefined;
-	unreadChannel: Note["id"];
-	myTokenRegenerated: undefined;
-	signin: Signin;
-	registryUpdated: {
-		scope?: string[];
-		key: string;
-		value: any | null;
-	};
-	driveFileCreated: Packed<"DriveFile">;
-	readAntenna: Antenna;
-	receiveFollowRequest: Packed<"User">;
-}
-
-export interface DriveStreamTypes {
-	fileCreated: Packed<"DriveFile">;
-	fileDeleted: DriveFile["id"];
-	fileUpdated: Packed<"DriveFile">;
-	folderCreated: Packed<"DriveFolder">;
-	folderDeleted: DriveFolder["id"];
-	folderUpdated: Packed<"DriveFolder">;
-}
-
-export interface NoteStreamTypes {
-	pollVoted: {
-		choice: number;
-		userId: User["id"];
-	};
-	deleted: {
-		deletedAt: Date;
-	};
-	reacted: {
-		reaction: string;
-		emoji?: {
-			name: string;
-			url: string;
-		} | null;
-		userId: User["id"];
-	};
-	unreacted: {
-		reaction: string;
-		userId: User["id"];
-	};
-	replied: {
-		id: Note["id"];
-	};
-}
-type NoteStreamEventTypes = {
-	[key in keyof NoteStreamTypes]: {
-		id: Note["id"];
-		body: NoteStreamTypes[key];
-	};
-};
-
-export interface ChannelStreamTypes {
-	typing: User["id"];
-}
-
-export interface UserListStreamTypes {
-	userAdded: Packed<"User">;
-	userRemoved: Packed<"User">;
-}
-
-export interface AntennaStreamTypes {
-	note: Note;
-}
-
-export interface MessagingStreamTypes {
-	read: MessagingMessage["id"][];
-	typing: User["id"];
-	message: Packed<"MessagingMessage">;
-	deleted: MessagingMessage["id"];
-}
-
-export interface GroupMessagingStreamTypes {
-	read: {
-		ids: MessagingMessage["id"][];
-		userId: User["id"];
-	};
-	typing: User["id"];
-	message: Packed<"MessagingMessage">;
-	deleted: MessagingMessage["id"];
-}
-
-export interface MessagingIndexStreamTypes {
-	read: MessagingMessage["id"][];
-	message: Packed<"MessagingMessage">;
-}
-
-export interface AdminStreamTypes {
-	newAbuseUserReport: {
-		id: AbuseUserReport["id"];
-		targetUserId: User["id"];
-		reporterId: User["id"];
-		comment: string;
-	};
-}
-//#endregion
-
-// 辞書(interface or type)から{ type, body }ユニオンを定義
-// https://stackoverflow.com/questions/49311989/can-i-infer-the-type-of-a-value-using-extends-keyof-type
-// VS Codeの展開を防止するためにEvents型を定義
-type Events<T extends object> = { [K in keyof T]: { type: K; body: T[K] } };
-type EventUnionFromDictionary<T extends object, U = Events<T>> = U[keyof U];
-
-// name/messages(spec) pairs dictionary
-export type StreamMessages = {
-	internal: {
-		name: "internal";
-		payload: EventUnionFromDictionary<InternalStreamTypes>;
-	};
-	broadcast: {
-		name: "broadcast";
-		payload: EventUnionFromDictionary<BroadcastTypes>;
-	};
-	user: {
-		name: `user:${User["id"]}`;
-		payload: EventUnionFromDictionary<UserStreamTypes>;
-	};
-	main: {
-		name: `mainStream:${User["id"]}`;
-		payload: EventUnionFromDictionary<MainStreamTypes>;
-	};
-	drive: {
-		name: `driveStream:${User["id"]}`;
-		payload: EventUnionFromDictionary<DriveStreamTypes>;
-	};
-	note: {
-		name: `noteStream:${Note["id"]}`;
-		payload: EventUnionFromDictionary<NoteStreamEventTypes>;
-	};
-	channel: {
-		name: `channelStream:${Channel["id"]}`;
-		payload: EventUnionFromDictionary<ChannelStreamTypes>;
-	};
-	userList: {
-		name: `userListStream:${UserList["id"]}`;
-		payload: EventUnionFromDictionary<UserListStreamTypes>;
-	};
-	antenna: {
-		name: `antennaStream:${Antenna["id"]}`;
-		payload: EventUnionFromDictionary<AntennaStreamTypes>;
-	};
-	messaging: {
-		name: `messagingStream:${User["id"]}-${User["id"]}`;
-		payload: EventUnionFromDictionary<MessagingStreamTypes>;
-	};
-	groupMessaging: {
-		name: `messagingStream:${UserGroup["id"]}`;
-		payload: EventUnionFromDictionary<GroupMessagingStreamTypes>;
-	};
-	messagingIndex: {
-		name: `messagingIndexStream:${User["id"]}`;
-		payload: EventUnionFromDictionary<MessagingIndexStreamTypes>;
-	};
-	admin: {
-		name: `adminStream:${User["id"]}`;
-		payload: EventUnionFromDictionary<AdminStreamTypes>;
-	};
-	notes: {
-		name: "notesStream";
-		payload: Note;
-	};
-};
-
-// API event definitions
-// ストリームごとのEmitterの辞書を用意
-type EventEmitterDictionary = {
-	[x in keyof StreamMessages]: Emitter<
-		EventEmitter,
-		{
-			[y in StreamMessages[x]["name"]]: (
-				e: StreamMessages[x]["payload"],
-			) => void;
-		}
-	>;
-};
-// 共用体型を交差型にする型 https://stackoverflow.com/questions/54938141/typescript-convert-union-to-intersection
-type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
-	k: infer I,
-) => void
-	? I
-	: never;
-// Emitter辞書から共用体型を作り、UnionToIntersectionで交差型にする
-export type StreamEventEmitter = UnionToIntersection<
-	EventEmitterDictionary[keyof StreamMessages]
->;
-// { [y in name]: (e: spec) => void }をまとめてその交差型をEmitterにかけるとts(2590)にひっかかる
-
-// provide stream channels union
-export type StreamChannels = StreamMessages[keyof StreamMessages]["name"];
diff --git a/packages/backend/src/server/api/streaming.ts b/packages/backend/src/server/api/streaming.ts
deleted file mode 100644
index 14e07b7487..0000000000
--- a/packages/backend/src/server/api/streaming.ts
+++ /dev/null
@@ -1,89 +0,0 @@
-import type * as http from "node:http";
-import { EventEmitter } from "events";
-import type { ParsedUrlQuery } from "querystring";
-import * as websocket from "websocket";
-
-import { subscriber as redisClient } from "@/db/redis.js";
-import { Users } from "@/models/index.js";
-import MainStreamConnection from "./stream/index.js";
-import authenticate from "./authenticate.js";
-
-export const initializeStreamingServer = (server: http.Server) => {
-	// Init websocket server
-	const ws = new websocket.server({
-		httpServer: server,
-	});
-
-	ws.on("request", async (request) => {
-		const q = request.resourceURL.query as ParsedUrlQuery;
-		const headers = request.httpRequest.headers["sec-websocket-protocol"] || "";
-		const cred = q.i || q.access_token || headers;
-		const accessToken = cred.toString();
-
-		const [user, app] = await authenticate(
-			request.httpRequest.headers.authorization,
-			accessToken,
-		).catch((err) => {
-			request.reject(403, err.message);
-			return [];
-		});
-		if (typeof user === "undefined") {
-			return;
-		}
-
-		if (user?.isSuspended) {
-			request.reject(400);
-			return;
-		}
-
-		const connection = request.accept();
-
-		const ev = new EventEmitter();
-
-		async function onRedisMessage(_: string, data: string) {
-			const parsed = JSON.parse(data);
-			ev.emit(parsed.channel, parsed.message);
-		}
-
-		redisClient.on("message", onRedisMessage);
-		const host = `https://${request.host}`;
-		const prepareStream = q.stream?.toString();
-		console.log("start", q);
-
-		const main = new MainStreamConnection(
-			connection,
-			ev,
-			user,
-			app,
-			host,
-			accessToken,
-			prepareStream,
-		);
-
-		const intervalId = user
-			? setInterval(() => {
-					Users.update(user.id, {
-						lastActiveDate: new Date(),
-					});
-			  }, 1000 * 60 * 5)
-			: null;
-		if (user) {
-			Users.update(user.id, {
-				lastActiveDate: new Date(),
-			});
-		}
-
-		connection.once("close", () => {
-			ev.removeAllListeners();
-			main.dispose();
-			redisClient.off("message", onRedisMessage);
-			if (intervalId) clearInterval(intervalId);
-		});
-
-		connection.on("message", async (data) => {
-			if (data.type === "utf8" && data.utf8Data === "ping") {
-				connection.send("pong");
-			}
-		});
-	});
-};
diff --git a/packages/backend/src/server/file/assets/bad-egg.png b/packages/backend/src/server/file/assets/bad-egg.png
deleted file mode 100644
index e96ba0dcc1c9e074f27bf75c291017899015bdf8..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 1676
zcmZ{kQE(I26^75fd!^l#WoacDglqvTTf)J}jtr{n%BHz8wvoX$3pEKOBrGw+q|jIs
ztDu6Xxt2@nQV5D6i39Fb(@7h*L#f)(#t9+0$`IlQKX@h(GAV60Dbq|lF8F~ICC$`b
z`>hXs_|AXMKj)u0Pv=Kk_r_9NxeWkHI})wi0Fc=tAc83ucKv?4DWosn6$kk3sgkeu
zSj<`NO>FA|I1&P2!vJ5*oBDTv??wRrp##Lm0KEO9yWeX!cdNC|o;JqV;lqc0KA&l<
z1-K1hMn-jg4&#^m`tHf{KTT(T{^q~7?>0Bk<C{0O+J|1-+G`GSGO=?2pv1EPg0thx
zOjAsCbhU|}iVjEFii)wp1^`P}M{B$%{qg0GFQ0s(O*!_-@Uagoo-atkGiUAX36ifI
ze)QK%MVIjI)m0E2#8<|Cdgs!;2M^!)Wo-LT=;b4Cz350D{maQ;-233OKVG_Ys{idf
zZ_NMo{?n{3bCmT`X8{?@W;P_D(UMa9s2eRO8`%I|Uyu#Iwk3%tNsnh7)uHR8j~$@3
z1&dLxZBC*Hu8}W5I}H_<aN9&x1kSS<7Px()G7r<N2A6QhL?D7@SvmITZY{10gI70r
zhf3$<Q(eTvPNlzHIR?$Wca>?dwmS=UUB9SwB5Qj|p-k6P%Cy;v1;4IGl`uSpe<d%4
z`_X%34ZFb}&Me^v=<0&osLhS)^4wA_k+-Iu6IDBex5P89gYXpEPAb?V)Kzd8b-8DC
zG3nJ>@|H>Gg!&P_DV8a-$bpVz*7E@EHlWcuA^YKds2>uIvRr5m#_=npjt#I;Zb>>6
zcM<AP46o!N+HR0Z>x488H^4RI<<g9jMkhcXs^B(FnMCIS4Xxz%DNhkivnWEkxL1~-
zN$ud!iJvBR9#q>Xn#OBM84s&*jyi=;iJwQ+PKu|6pOGMMRudeD@#7@SE7evioX3?U
z%4<~0g|LvuD|8?A5cm*<<Df66?pA0({y5P+)b#^6gzRxi_fq8w`~iJGvy3<JE`@v~
zrsWL$8>-`F++|da;6}WQ?13%phpOF>lgbse3mwfgvNihVEX-MEB{#gyO5;}U%deV(
zM&U)W8v6Nh)nb(HP;S9ZG?4MLCVf+u%!$*|DEx=Xh1Z|?8;rm?<4zD<x_hu#EpxJi
zJPE6~Iwff6p-eL@Nd^>1qCSkko2=9zi#B2l_>yWC^5`CMLxb@g6{vVqib9Gv4N1(I
zu2Rq(`VFaJl$Q+IR3)<F1$dslDh6m!Z?>Tpw8a@?8ZQ>C#om<VtAl@@|MKWV{MNd=
z{rgj1Isd?h-Sf7Sw{ybC$=fQC7K@9@N`Sf57FbOgY-4~fLh~Y5Ac_{a2H{0+K@cr)
z7yOIZ;67Xi8cE>6FKXY2x4VtrL&GQh{MFB9t-cO+*Iuz$cCs+~9qh!fpiz<#f^t@z
za;eU26$7;m5IqhyW=Cb<!wGPcECi(-8u3s;sb-Se2`)MYHS9jr16%PFWJnef*}UIH
zMWu=<YAXcj2y9{!Is-18K$v7Pk#ZJ8UO=_x7Rgz4c>z^a7s-i+w15WGl>=5uEwF*v
z;8_R(L7PCr*PtkCf>BLf>>RYgQ@97EWzAxQsE?h7eb9}sp`xUTMimXPAHy-I!#y}H
zX|fTZtIZGjb8z5mcvj9^i=Tg^B45SJjd$vg%bGnOqF>|B!F6cDXM}^2=Ew)=dVUr@
zhXXhYVR;7fK`Qd&upHLlix8G(a9*WOJ`U?)07p@$JVPQO>g6ZkQTSG-f%)PU{6x;F
zx6Fu<z<!dK%hAD1H=NFScyPZZFFlOHna5x_=jG~t>!dp>?2_L^b>vUr%^YIu;!XVJ
z+)5)c_rUd+(5){Y`NVwk5K6V}NbTK|+8676dY>t<Hd5bM8~J)|eYB@O8e1EQt&6OQ
nL}HQ1)~hu0KY{P`?|t%#@BROPdan3QGXNcJ-K`f|^vr(&)8p}6

diff --git a/packages/backend/src/server/file/assets/cache-expired.png b/packages/backend/src/server/file/assets/cache-expired.png
deleted file mode 100644
index 5d988c502bc8426d2764cc9d9006be7f0e2e3ac6..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 6048
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
LKV5Xv_4@w+k2RB#

diff --git a/packages/backend/src/server/file/assets/dummy.png b/packages/backend/src/server/file/assets/dummy.png
deleted file mode 100644
index 39332b0c1beeda1edb90d78d25c16e7372aff030..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 6285
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
IqD|EQ01tF`Q2+n{

diff --git a/packages/backend/src/server/file/assets/not-an-image.png b/packages/backend/src/server/file/assets/not-an-image.png
deleted file mode 100644
index 39e4aa0892118918a1566881113200284ed6cb6a..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 2780
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
MskKSzCCsmX1IGX9?*IS*

diff --git a/packages/backend/src/server/file/assets/thumbnail-not-available.png b/packages/backend/src/server/file/assets/thumbnail-not-available.png
deleted file mode 100644
index 07cad9919c5a1c6a9398799fc75c989c602386ff..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 5705
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
z%0DVB7#XK|Op7cWUWFl#{`hcV6kW~VikqaNKM(nu1zvIA%^y?|+->~q{R!G$!f%KM
z38*gFYl)snE}T;_Iv*N`_h^S<cpsrN3qfwdo>P4wMzT=(ws6$sqMwte2ZUQzrsQh+
zpTz|HJ&1LN3v<@r{u9Vjjloa1OhvdC)LnX)E<xKVeuPZN=PT7MLz4B5lEnTRxl9=k
zDPB)B;C}}F)JQM@=Kh0v=Wy-u!?$VU2F~bZG$u>_o{Let1QC3bCgI-Cs%XK2(i9;D
zSUP^n#g+UTyex=&^5Mo^IP$77Ec)J(f~`4fQQtJ|yx|Ao4}I*(7Qir{i>KhZfAlok
zw7Aub6H-)YL;W*`T4=kID?`1C&ZVuP?&f8cw#m23zO<{r$?AY`H~10>EY#@2FocN@
z!+BF#zr}mLlNTF|a#h<h#p)%b{0z9ixB5N1(Cnf=RNWqOgV+Q|y+@YxK%Rovgm0e*
ztmcca1zy2bnxnTqEDm~{>dax=euy4Dkn=ca(dkaNaG2_;qbG*zF&OaBcw+<+EPd6G
zT5{bQ?@%GcJt)k{>qzKw(RYT9N>-QX6dsYJJwk22A61NVBLdP*K?c9;;Omo23`8rD
zjZH{v#B|7;Bs-aoMY318sjOen_t-V7LXkjhIJt6LdLnJJNYmUKvu+hr%z<*{ExbzK
z5($;?=KHe=>3(FL-s#ZkiT_Fx-11W~nAr2Xy1!q>0DHS7Y}CoCmORzbcH4RaUyu?F
zXULA%yf52|em2nia`1G$q+_Rx!2XwqeVKx7jD3Evfglzx{h2q)K5(+mnw4d!M#;!8
zr)*J1jx*;A2HuD_Il1tg3r|0@w{l{XV5=z~8zPjpSAWKJS=b@{JYap3Pqy^JKKf%o
zckR4_NckeIj)+B$OSr=YIpP@FVL(-|5WCI4PzPn*C#d=x66=<3eJ#Ca%~WvEgbj~7
zLChU|2V%6`$Ufu|Nme-}dofWlPrT`l!;c#KoBE(9`F5@N7lG^DyCjxkcUxJ)c7xXK
zv$!5_(^w&C%QwD_9*g2ze_OV>xF#;PMW#*T+PkLPu-x<!Yuz*{@lH42-#y{t%cLrG
zxPKWE5R5lG9ZPB!dplU5ux#AuAyG|_xJ9WwIWjJn+`d1b*VRL3aU<#8<A{6PT<M9*
zjQ4JQ3?Vsdw+5{G6=_O;mH4fFPR}>Zi#xP8#8X9ndB<M*ui150OXW;v#U`@sR!~Z7
zq_S}vCF0IO;KA<H@5nK?zklYu)_$w<e~rRV%=pV>xKBiL+G<^~o#7`pxqFPCw~2k)
zn4Z4(*Qq$FG7ho5KlrY3M)&5j**)l50g*Jjxtt=0J#JI~T`491-i0Mc2uO5#OhhNk
zPi4dUR$_g!b$QAj($Iov5!~wdV@7o_Zv)trd`F;Kzgtupvq?cYG*Cbb-~a)T00nT=
zK9KmlRue>bFPw&=KnaYG0L+-*GX6KFym!nxBa69IU;tXXzrozI#F4webr{_`7x~&l
zHE?|Hh4RtS=J0IWnRpbIyH_?f_rml2E4$o#QN59LT?||AcALpFT^bc%e^{qad;7c4
zi14wmFn<@m6zGeWO?Pc7f_!3VYYDy4@UbwXy`V>X9+EIA)Yh`6_Ex3lcJ&&1tX&)%
z?5MlXORbFAd;78)We;bLiyD;U702JK(xdYg?~>lgL&A~XJ&%CK?T~N$d!?Hf(t>O#
zA+&D45T9ksv127o4@e)w&(O_4<ukO?JWTPFsg3TEh*z^!FTj=qcR4%ivd*{jH_rM>
z6l;S0vp6l;TM4Jl9c>yfKu4B*e_8?OUlE6UU2?aKm6CX3)^CYJM<RWHQcK3gO3kM1
zGjdVSbhUT(0Bt$_G;xqgA6dZV58Tc_(_<krB2by5^{o4W4FxsZ@)Gq~jJO5Lbp*<y
z&~Seb=k-heq|CY%=%V>+3lc1(vuItIpTDJ1CE%{J5Q}2QuDTrR@|j`Ok8=v-AiUTh
zz<z##vJfNSNXe+J>dJ15<kKuah2Ys1k?|giBc{n8_ng_wxuAEtRz`9N`1iSei!8ag
zMg;M#p>vX{ms{85z6t_Wc0n#!R%H8fm3v`lFwuf&V_dlv>g@X58ln%8zt2cpZVN4N
z4O?^Fk|{q6TwVVGTY5m_rHv?(c_8mY84BDN!>K_?1A9KZWwYbGn{deTeby1~cRw6a
zR^dBqt~vh7RpI&N;!sicxRFd76PLP3d8N;hV9OY2=H@G4xhZDLd|?L-7B?80IApoN
zHqB<DUXYcvan|<F4Ap%Ev;|rqaKPTkD*wv~)0}#{uR=*v;LvKA^81;UbO~J}cg!V$
zsI{hcj#l|~XW#wJTgF*I8v%bV9Y6K{E#a<Dt`1^r^*4OXZ3@G}BhR0-01dY%abIjd
zOU!&`h~|d|SG7+1Df0F)^2vPeln?$mG|74@xW2=_4UCr$CeD@hi0|8J9?9MvFZ<x1
z)715;<so3Hxjok==d~ZclfTMTaEk5=l$QCP#LkG#KdFCaqwu_#<a0ETc#7rnML9O2
z?B1d?C((-d{BSMe(VrezT>7V2)1W1a15foS7NmHZpk2*TucmFx%>7uX*{B+8xg|w&
zRAJ-_gWY#}J{Q(?cVT|>suhZv<v1rSPUJ1UJX_o)%6m47>!`wx7Xwmx;Ic%Lh{KhA
zTNPNdK7`McGsV^6$ruG+_0kHYMbtRcq(#WL%;Fk&)Kf=HX|rDdxE*6Sas3Z1gl}HH
zocoyw|B39|)<k;)T6I@49M#P50#uWBK9rojiw0>eyb#Z4ZuCc*;QsLK%K8vLV~8L;
z+Zcj?AW*T>H)(xpq3r`Aeh5@PJDVK&M79@AC=&N|@bl~G=y1_nlh{-UJX<M6K8R#%
zuxC^BiK0eRErR<!SmWI>k(q@Us{k?DBSOPP-J-YWUYuG<zW4__qNzrc^U(zg=fTXc
z?b-9Hl<IfnF2LAkMfgj9Gz=t#30}<>#?_bEj!N0#n}b9eIZ-TqvW1s=AGXuwX>6?S
zY4DY+DYNpHkFx{^Rb5uN^ROM~eqdN49e~7@EQ=nu>fch+>w=6Ib-R1jt*V7U1*8s?
zVw?Axipr-GTzN6WSq+ij8$r&eR$K4qmGs6j$n;9%qTq;If}jraHT%hg*%OFwYM7|_
z(MTQW$dsb!tbKg-wRodV#c3fS$3$0@^8``AkezOX_GdF*+YYsR*qp)6h1KFH_lL9u
zesNtjO=%mLP);%I`2`Ot<aL^US$F>t#1s;|g5XBn-sCE~5pM#%^w6Lz@Xqx|4j&$I
zy7kPM=cRF+)k4u84Rd2Si0kCd!OJPNkC;WJaR>Wry)*dGVW{Y<G`KLD=Zeg|R!?-H
z%kG1-j~gH{OlFMPDdId7){*nvvc!?`cV^yWznLLuUGsWjf6CT&l<k<S`_;U=NZh)@
z$wUaXrRz6imqkj69VTR{OjLk#)A{>K&IUNbzNdbnB@3<tS0HJ2O31;U=IQT>u;!&w
zSlsEv`Hb1pvh@2#s9S|U5LDzBe}>nI>~(#~lk>SCW}>N7J;-MG@zam&7_&uA+H4u5
zbmD<0WFWL{@TJKqSf7uc5?nTMw7p|d$hwf10jZ?N#@jcajfSqD#wfVIcR%_h^beT<
z`94}FI^SL7juJVo)Z~y!tB;~X!*fDS7n-6XNwC1f;Ww4%pd*6|KS$17w4Silhe~Y+
zJb7>O&8?RU*N=+=YQ~NIa11(>+5U)JPY@t7MWkXUOQg&#cLo$qjFQ}A#e3QQ1C;tA
zfe`|`Nhui&M9+X?j;<$ibvnb!8I_nt7i(ObrUi{&Bd!0?&w?R#+?3ImJIO(<>B_xo
zx^u;wHS6(Jgn_)f!nn6pSsa!k%u0z!ei*xw`zkwmK|ek!f5?*C>Z`bzbpo@Rr7HU|
zsO_QBnX(i6V2Ez+ZxIw@b0K}@58)2U*xctr3Dfh>lu-fW<RT7~;39N}Zot23Pq9aX
zt_0?Dm|fCAehyvAEGmr=8W)f~SoIKGG^&EaXSFS8JU4j9HMsQ#WGCb@xvnp$fvW4T
zN?Umt?|om;CBFl-bOS}j1G=G`VUUqb?!yE2Gb#D}a669O)o|V9!Hnmn9sS9Kcp!{F
zELm*v+NDXDyJ|cvKe_6f9oc)YUZCJl;1Wl`glJ9DxUg3u6?{1qVd`vN+?3$yNW;e*
z;tPptUOw0l3PPJS_~}$WkKgU(jbQi-=@}hJCOiR3Hby)cxZTm<rSSY-X=0jilI627
z72ouH1M);NcS2r8TaS*w&j4K0K;TuamMl587XpcNuLh5N_e`rjxn#0WpV!!SeW@<`
z!;PW511q4TIlH<|&a_#e5nf3oh?z?PhE@hVq(ah{*T`Pp?DWmCLnSu+iPxDcvao{Z
z@x>F%jJ}3Q*jUK`GcCe~3BhZ(%y`liXGbpL>GbZU|0Fa?Zk8`k8sz;jH!PsE1hJ9+
zn^)wA^T{^hK`boVvKGeLZmc^8P#PUN@{q{2t)lg=%z<aC;#L;jE!L^;OcKGTZJi~i
z$CXRf4`T6N`OIq9)TTa`-p4IQaV#*r@;)29VI+q@^`}ANb0}QVi(Ms0Khxso-jZeO
zRDR5?TZkIC>0a-*dUp1^OPQn{*^x=*0*~ss-w9#*1$-jQ2hJ>=`mr%}^xq%kRS)Ex
z?U<S{!_>Coe0?7nhsD`CpwJK%!F|;*-DOJ`#f*!Y5tNCKpQrPyb**)lrVNAATjv)R
z7T%$0ekEQtAv+67*?oT(O?g!cce$1cdvNhbYItM%#g5s$_~;&rSdW<UB;CJNX8-RH
zj)6kYrYS-*abwt;dYVuG+AP4yKEPSg(a)JW0VxSd`707~S0rUjBxMw(Bow73E=foz
lN=O*Cq8|K@055MRH<ytAJph@$qkNpNHrhbFRL$<ezW~Qj8{Pl_

diff --git a/packages/backend/src/server/file/assets/tombstone.png b/packages/backend/src/server/file/assets/tombstone.png
deleted file mode 100644
index 83159d6b3c181a5df2afc00481354270e0798e6a..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 5028
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
SV^ec~{A;>KIwe<}9{m^SoJF+&

diff --git a/packages/backend/src/server/file/index.ts b/packages/backend/src/server/file/index.ts
deleted file mode 100644
index 26df1de51d..0000000000
--- a/packages/backend/src/server/file/index.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * File Server
- */
-
-import * as fs from "node:fs";
-import { fileURLToPath } from "node:url";
-import { dirname } from "node:path";
-import Koa from "koa";
-import cors from "@koa/cors";
-import Router from "@koa/router";
-import sendDriveFile from "./send-drive-file.js";
-
-const _filename = fileURLToPath(import.meta.url);
-const _dirname = dirname(_filename);
-
-// Init app
-const app = new Koa();
-app.use(cors());
-app.use(async (ctx, next) => {
-	ctx.set(
-		"Content-Security-Policy",
-		`default-src 'none'; img-src 'self'; media-src 'self'; style-src 'unsafe-inline'`,
-	);
-	await next();
-});
-
-// Init router
-const router = new Router();
-
-router.get("/app-default.jpg", (ctx) => {
-	const file = fs.createReadStream(`${_dirname}/assets/dummy.png`);
-	ctx.body = file;
-	ctx.set("Content-Type", "image/jpeg");
-	ctx.set("Cache-Control", "max-age=31536000, immutable");
-});
-
-router.get("/:key", sendDriveFile);
-router.get("/:key/(.*)", sendDriveFile);
-
-// Register router
-app.use(router.routes());
-
-export default app;
diff --git a/packages/backend/src/server/file/send-drive-file.ts b/packages/backend/src/server/file/send-drive-file.ts
deleted file mode 100644
index 0877369025..0000000000
--- a/packages/backend/src/server/file/send-drive-file.ts
+++ /dev/null
@@ -1,152 +0,0 @@
-import * as fs from "node:fs";
-import { fileURLToPath } from "node:url";
-import { dirname } from "node:path";
-import type Koa from "koa";
-import send from "koa-send";
-import rename from "rename";
-import { serverLogger } from "../index.js";
-import { contentDisposition } from "@/misc/content-disposition.js";
-import { DriveFiles } from "@/models/index.js";
-import { InternalStorage } from "@/services/drive/internal-storage.js";
-import { createTemp } from "@/misc/create-temp.js";
-import { downloadUrl } from "@/misc/download-url.js";
-import { detectType } from "@/misc/get-file-info.js";
-import { convertToWebp } from "@/services/drive/image-processor.js";
-import { GenerateVideoThumbnail } from "@/services/drive/generate-video-thumbnail.js";
-import { StatusError } from "@/misc/fetch.js";
-import { FILE_TYPE_BROWSERSAFE } from "@/const.js";
-
-const _filename = fileURLToPath(import.meta.url);
-const _dirname = dirname(_filename);
-
-const assets = `${_dirname}/../../server/file/assets/`;
-
-const commonReadableHandlerGenerator =
-	(ctx: Koa.Context) => (e: Error): void => {
-		serverLogger.error(e);
-		ctx.status = 500;
-		ctx.set("Cache-Control", "max-age=300");
-	};
-
-export default async function (ctx: Koa.Context) {
-	const key = ctx.params.key;
-
-	// Fetch drive file
-	const file = await DriveFiles.createQueryBuilder("file")
-		.where("file.accessKey = :accessKey", { accessKey: key })
-		.orWhere("file.thumbnailAccessKey = :thumbnailAccessKey", {
-			thumbnailAccessKey: key,
-		})
-		.orWhere("file.webpublicAccessKey = :webpublicAccessKey", {
-			webpublicAccessKey: key,
-		})
-		.getOne();
-
-	if (file == null) {
-		ctx.status = 404;
-		ctx.set("Cache-Control", "max-age=86400");
-		await send(ctx as any, "/dummy.png", { root: assets });
-		return;
-	}
-
-	const isThumbnail = file.thumbnailAccessKey === key;
-	const isWebpublic = file.webpublicAccessKey === key;
-
-	if (!file.storedInternal) {
-		if (file.isLink && file.uri) {
-			// 期限切れリモートファイル
-			const [path, cleanup] = await createTemp();
-
-			try {
-				await downloadUrl(file.uri, path);
-
-				const { mime, ext } = await detectType(path);
-
-				const convertFile = async () => {
-					if (isThumbnail) {
-						if (
-							[
-								"image/jpeg",
-								"image/webp",
-								"image/png",
-								"image/svg+xml",
-								"image/avif",
-							].includes(mime)
-						) {
-							return await convertToWebp(path, 996, 560);
-						} else if (mime.startsWith("video/")) {
-							return await GenerateVideoThumbnail(path);
-						}
-					}
-
-					if (isWebpublic) {
-						if (["image/svg+xml"].includes(mime)) {
-							return await convertToWebp(path, 2048, 2048, 100);
-						}
-					}
-
-					return {
-						data: fs.readFileSync(path),
-						ext,
-						type: mime,
-					};
-				};
-
-				const image = await convertFile();
-				ctx.body = image.data;
-				ctx.set(
-					"Content-Type",
-					FILE_TYPE_BROWSERSAFE.includes(image.type)
-						? image.type
-						: "application/octet-stream",
-				);
-				ctx.set("Cache-Control", "max-age=31536000, immutable");
-			} catch (e) {
-				serverLogger.error(`${e}`);
-
-				if (e instanceof StatusError && e.isClientError) {
-					ctx.status = e.statusCode;
-					ctx.set("Cache-Control", "max-age=86400");
-				} else {
-					ctx.status = 500;
-					ctx.set("Cache-Control", "max-age=300");
-				}
-			} finally {
-				cleanup();
-			}
-			return;
-		}
-
-		ctx.status = 204;
-		ctx.set("Cache-Control", "max-age=86400");
-		return;
-	}
-
-	if (isThumbnail || isWebpublic) {
-		const { mime, ext } = await detectType(InternalStorage.resolvePath(key));
-		const filename = rename(file.name, {
-			suffix: isThumbnail ? "-thumb" : "-web",
-			extname: ext ? `.${ext}` : undefined,
-		}).toString();
-
-		ctx.body = InternalStorage.read(key);
-		ctx.set(
-			"Content-Type",
-			FILE_TYPE_BROWSERSAFE.includes(mime) ? mime : "application/octet-stream",
-		);
-		ctx.set("Cache-Control", "max-age=31536000, immutable");
-		ctx.set("Content-Disposition", contentDisposition("inline", filename));
-	} else {
-		const readable = InternalStorage.read(file.accessKey!);
-		readable.on("error", commonReadableHandlerGenerator(ctx));
-		ctx.body = readable;
-		ctx.set(
-			"Content-Type",
-			FILE_TYPE_BROWSERSAFE.includes(file.type)
-				? file.type
-				: "application/octet-stream",
-		);
-		ctx.set("Cache-Control", "max-age=31536000, immutable");
-		ctx.set("Content-Disposition", contentDisposition("inline", file.name));
-	}
-}
diff --git a/packages/backend/src/server/index.ts b/packages/backend/src/server/index.ts
deleted file mode 100644
index 7d274f7d28..0000000000
--- a/packages/backend/src/server/index.ts
+++ /dev/null
@@ -1,286 +0,0 @@
-/**
- * Core Server
- */
-
-import cluster from "node:cluster";
-import * as fs from "node:fs";
-import * as http from "node:http";
-import Koa from "koa";
-import Router from "@koa/router";
-import mount from "koa-mount";
-import koaLogger from "koa-logger";
-import * as slow from "koa-slow";
-import { IsNull } from "typeorm";
-import config from "@/config/index.js";
-import Logger from "@/services/logger.js";
-import { UserProfiles, Users } from "@/models/index.js";
-import { genIdenticon } from "@/misc/gen-identicon.js";
-import { createTemp } from "@/misc/create-temp.js";
-import { publishMainStream } from "@/services/stream.js";
-import * as Acct from "@/misc/acct.js";
-import { envOption } from "@/env.js";
-import megalodon, { MegalodonInterface } from "@calckey/megalodon";
-import activityPub from "./activitypub.js";
-import nodeinfo from "./nodeinfo.js";
-import wellKnown from "./well-known.js";
-import apiServer from "./api/index.js";
-import fileServer from "./file/index.js";
-import proxyServer from "./proxy/index.js";
-import webServer from "./web/index.js";
-import { initializeStreamingServer } from "./api/streaming.js";
-import { koaBody } from "koa-body";
-import { v4 as uuid } from "uuid";
-
-export const serverLogger = new Logger("server", "gray", false);
-
-// Init app
-const app = new Koa();
-app.proxy = true;
-
-// Replace trailing slashes
-app.use(async (ctx, next) => {
-	if (ctx.request.path !== "/" && ctx.request.path.endsWith("/"))
-		return ctx.redirect(ctx.request.path.replace(/\/$/, ""));
-	else await next();
-});
-
-if (!["production", "test"].includes(process.env.NODE_ENV || "")) {
-	// Logger
-	app.use(
-		koaLogger((str) => {
-			serverLogger.info(str);
-		}),
-	);
-
-	// Delay
-	if (envOption.slow) {
-		app.use(
-			slow({
-				delay: 3000,
-			}),
-		);
-	}
-}
-
-// HSTS
-// 6months (15552000sec)
-if (config.url.startsWith("https") && !config.disableHsts) {
-	app.use(async (ctx, next) => {
-		ctx.set("strict-transport-security", "max-age=15552000; preload");
-		await next();
-	});
-}
-
-app.use(mount("/api", apiServer));
-app.use(mount("/files", fileServer));
-app.use(mount("/proxy", proxyServer));
-
-// Init router
-const router = new Router();
-const mastoRouter = new Router();
-
-mastoRouter.use(
-	koaBody({
-		urlencoded: true,
-		multipart: true,
-	}),
-);
-
-mastoRouter.use(async (ctx, next) => {
-	if (ctx.request.query) {
-		if (!ctx.request.body || Object.keys(ctx.request.body).length === 0) {
-			ctx.request.body = ctx.request.query;
-		} else {
-			ctx.request.body = { ...ctx.request.body, ...ctx.request.query };
-		}
-	}
-	await next();
-});
-
-// Routing
-router.use(activityPub.routes());
-router.use(nodeinfo.routes());
-router.use(wellKnown.routes());
-
-router.get("/avatar/@:acct", async (ctx) => {
-	const { username, host } = Acct.parse(ctx.params.acct);
-	const user = await Users.findOne({
-		where: {
-			usernameLower: username.toLowerCase(),
-			host: host == null || host === config.host ? IsNull() : host,
-			isSuspended: false,
-		},
-		relations: ["avatar"],
-	});
-
-	if (user) {
-		ctx.redirect(Users.getAvatarUrlSync(user));
-	} else {
-		ctx.redirect("/static-assets/user-unknown.png");
-	}
-});
-
-router.get("/identicon/:x", async (ctx) => {
-	const [temp, cleanup] = await createTemp();
-	await genIdenticon(ctx.params.x, fs.createWriteStream(temp));
-	ctx.set("Content-Type", "image/png");
-	ctx.body = fs.createReadStream(temp).on("close", () => cleanup());
-});
-
-router.get("/verify-email/:code", async (ctx) => {
-	const profile = await UserProfiles.findOneBy({
-		emailVerifyCode: ctx.params.code,
-	});
-
-	if (profile != null) {
-		ctx.body = "Verify succeeded!";
-		ctx.status = 200;
-
-		await UserProfiles.update(
-			{ userId: profile.userId },
-			{
-				emailVerified: true,
-				emailVerifyCode: null,
-			},
-		);
-
-		publishMainStream(
-			profile.userId,
-			"meUpdated",
-			await Users.pack(
-				profile.userId,
-				{ id: profile.userId },
-				{
-					detail: true,
-					includeSecrets: true,
-				},
-			),
-		);
-	} else {
-		ctx.status = 404;
-	}
-});
-
-mastoRouter.get("/oauth/authorize", async (ctx) => {
-	const { client_id, state, redirect_uri } = ctx.request.query;
-	console.log(ctx.request.req);
-	let param = "mastodon=true";
-	if (state) param += `&state=${state}`;
-	if (redirect_uri) param += `&redirect_uri=${redirect_uri}`;
-	const client = client_id ? client_id : "";
-	ctx.redirect(
-		`${Buffer.from(client.toString(), "base64").toString()}?${param}`,
-	);
-});
-
-mastoRouter.post("/oauth/token", async (ctx) => {
-	const body: any = ctx.request.body || ctx.request.query;
-	console.log("token-request", body);
-	console.log("token-query", ctx.request.query);
-	if (body.grant_type === "client_credentials") {
-		const ret = {
-			access_token: uuid(),
-			token_type: "Bearer",
-			scope: "read",
-			created_at: Math.floor(new Date().getTime() / 1000),
-		};
-		ctx.body = ret;
-		return;
-	}
-	let client_id: any = body.client_id;
-	const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`;
-	const generator = (megalodon as any).default;
-	const client = generator("misskey", BASE_URL, null) as MegalodonInterface;
-	let m = null;
-	let token = null;
-	if (body.code) {
-		//m = body.code.match(/^([a-zA-Z0-9]{8})([a-zA-Z0-9]{4})([a-zA-Z0-9]{4})([a-zA-Z0-9]{4})([a-zA-Z0-9]{12})/);
-		//if (!m.length) {
-		//	ctx.body = { error: "Invalid code" };
-		//	return;
-		//}
-		//token = `${m[1]}-${m[2]}-${m[3]}-${m[4]}-${m[5]}`
-		console.log(body.code, token);
-		token = body.code;
-	}
-	if (client_id instanceof Array) {
-		client_id = client_id.toString();
-	} else if (!client_id) {
-		client_id = null;
-	}
-	try {
-		const atData = await client.fetchAccessToken(
-			client_id,
-			body.client_secret,
-			token ? token : "",
-		);
-		const ret = {
-			access_token: atData.accessToken,
-			token_type: "Bearer",
-			scope: body.scope || "read write follow push",
-			created_at: Math.floor(new Date().getTime() / 1000),
-		};
-		console.log("token-response", ret);
-		ctx.body = ret;
-	} catch (err: any) {
-		console.error(err);
-		ctx.status = 401;
-		ctx.body = err.response.data;
-	}
-});
-
-// Register router
-app.use(mastoRouter.routes());
-app.use(router.routes());
-
-app.use(mount(webServer));
-
-function createServer() {
-	return http.createServer(app.callback());
-}
-
-// For testing
-export const startServer = () => {
-	const server = createServer();
-
-	initializeStreamingServer(server);
-
-	server.listen(config.port);
-
-	return server;
-};
-
-export default () =>
-	new Promise((resolve) => {
-		const server = createServer();
-
-		initializeStreamingServer(server);
-
-		server.on("error", (e) => {
-			switch ((e as any).code) {
-				case "EACCES":
-					serverLogger.error(
-						`You do not have permission to listen on port ${config.port}.`,
-					);
-					break;
-				case "EADDRINUSE":
-					serverLogger.error(
-						`Port ${config.port} is already in use by another process.`,
-					);
-					break;
-				default:
-					serverLogger.error(e);
-					break;
-			}
-
-			if (cluster.isWorker) {
-				process.send!("listenFailed");
-			} else {
-				// disableClustering
-				process.exit(1);
-			}
-		});
-
-		// @ts-ignore
-		server.listen(config.port, resolve);
-	});
diff --git a/packages/backend/src/server/nodeinfo.ts b/packages/backend/src/server/nodeinfo.ts
deleted file mode 100644
index 8563573d47..0000000000
--- a/packages/backend/src/server/nodeinfo.ts
+++ /dev/null
@@ -1,119 +0,0 @@
-import Router from "@koa/router";
-import config from "@/config/index.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { Users, Notes } from "@/models/index.js";
-import { IsNull, MoreThan } from "typeorm";
-import { MAX_NOTE_TEXT_LENGTH, MAX_CAPTION_TEXT_LENGTH } from "@/const.js";
-import { Cache } from "@/misc/cache.js";
-
-const router = new Router();
-
-const nodeinfo2_1path = "/nodeinfo/2.1";
-const nodeinfo2_0path = "/nodeinfo/2.0";
-
-// to cleo: leave this http or bonks
-export const links = [
-	{
-		rel: "http://nodeinfo.diaspora.software/ns/schema/2.1",
-		href: config.url + nodeinfo2_1path,
-	},
-	{
-		rel: "http://nodeinfo.diaspora.software/ns/schema/2.0",
-		href: config.url + nodeinfo2_0path,
-	},
-];
-
-const nodeinfo2 = async () => {
-	const now = Date.now();
-	const [meta, total, activeHalfyear, activeMonth, localPosts] =
-		await Promise.all([
-			fetchMeta(true),
-			Users.count({ where: { host: IsNull() } }),
-			Users.count({
-				where: {
-					host: IsNull(),
-					lastActiveDate: MoreThan(new Date(now - 15552000000)),
-				},
-			}),
-			Users.count({
-				where: {
-					host: IsNull(),
-					lastActiveDate: MoreThan(new Date(now - 2592000000)),
-				},
-			}),
-			Notes.count({ where: { userHost: IsNull() } }),
-		]);
-
-	const proxyAccount = meta.proxyAccountId
-		? await Users.pack(meta.proxyAccountId).catch(() => null)
-		: null;
-
-	return {
-		software: {
-			name: "calckey",
-			version: config.version,
-			repository: meta.repositoryUrl,
-			homepage: "https://calckey.cloud",
-		},
-		protocols: ["activitypub"],
-		services: {
-			inbound: [] as string[],
-			outbound: ["atom1.0", "rss2.0"],
-		},
-		openRegistrations: !meta.disableRegistration,
-		usage: {
-			users: { total, activeHalfyear, activeMonth },
-			localPosts,
-			localComments: 0,
-		},
-		metadata: {
-			nodeName: meta.name,
-			nodeDescription: meta.description,
-			maintainer: {
-				name: meta.maintainerName,
-				email: meta.maintainerEmail,
-			},
-			langs: meta.langs,
-			tosUrl: meta.ToSUrl,
-			repositoryUrl: meta.repositoryUrl,
-			feedbackUrl: meta.feedbackUrl,
-			disableRegistration: meta.disableRegistration,
-			disableLocalTimeline: meta.disableLocalTimeline,
-			disableRecommendedTimeline: meta.disableRecommendedTimeline,
-			disableGlobalTimeline: meta.disableGlobalTimeline,
-			emailRequiredForSignup: meta.emailRequiredForSignup,
-			enableHcaptcha: meta.enableHcaptcha,
-			enableRecaptcha: meta.enableRecaptcha,
-			maxNoteTextLength: MAX_NOTE_TEXT_LENGTH,
-			maxCaptionTextLength: MAX_CAPTION_TEXT_LENGTH,
-			enableTwitterIntegration: meta.enableTwitterIntegration,
-			enableGithubIntegration: meta.enableGithubIntegration,
-			enableDiscordIntegration: meta.enableDiscordIntegration,
-			enableEmail: meta.enableEmail,
-			enableServiceWorker: meta.enableServiceWorker,
-			proxyAccountName: proxyAccount ? proxyAccount.username : null,
-			themeColor: meta.themeColor || "#31748f",
-		},
-	};
-};
-
-const cache = new Cache<Awaited<ReturnType<typeof nodeinfo2>>>(1000 * 60 * 10);
-
-router.get(nodeinfo2_1path, async (ctx) => {
-	const base = await cache.fetch(null, () => nodeinfo2());
-
-	ctx.body = { version: "2.1", ...base };
-	ctx.set("Cache-Control", "public, max-age=600");
-});
-
-router.get(nodeinfo2_0path, async (ctx) => {
-	const base = await cache.fetch(null, () => nodeinfo2());
-
-	// @ts-ignore
-	base.software.repository = undefined;
-
-	ctx.body = { version: "2.0", ...base };
-	ctx.set("Cache-Control", "public, max-age=600");
-});
-
-export default router;
diff --git a/packages/backend/src/server/proxy/index.ts b/packages/backend/src/server/proxy/index.ts
deleted file mode 100644
index 004b3779fb..0000000000
--- a/packages/backend/src/server/proxy/index.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * Media Proxy
- */
-
-import Koa from "koa";
-import cors from "@koa/cors";
-import Router from "@koa/router";
-import { proxyMedia } from "./proxy-media.js";
-
-// Init app
-const app = new Koa();
-app.use(cors());
-app.use(async (ctx, next) => {
-	ctx.set(
-		"Content-Security-Policy",
-		`default-src 'none'; img-src 'self'; media-src 'self'; style-src 'unsafe-inline'`,
-	);
-	await next();
-});
-
-// Init router
-const router = new Router();
-
-router.get("/:url*", proxyMedia);
-
-// Register router
-app.use(router.routes());
-
-export default app;
diff --git a/packages/backend/src/server/proxy/proxy-media.ts b/packages/backend/src/server/proxy/proxy-media.ts
deleted file mode 100644
index a9c257bfeb..0000000000
--- a/packages/backend/src/server/proxy/proxy-media.ts
+++ /dev/null
@@ -1,105 +0,0 @@
-import * as fs from "node:fs";
-import type Koa from "koa";
-import sharp from "sharp";
-import type { IImage } from "@/services/drive/image-processor.js";
-import { convertToWebp } from "@/services/drive/image-processor.js";
-import { createTemp } from "@/misc/create-temp.js";
-import { downloadUrl } from "@/misc/download-url.js";
-import { detectType } from "@/misc/get-file-info.js";
-import { StatusError } from "@/misc/fetch.js";
-import { FILE_TYPE_BROWSERSAFE } from "@/const.js";
-import { serverLogger } from "../index.js";
-import { isMimeImage } from "@/misc/is-mime-image.js";
-
-export async function proxyMedia(ctx: Koa.Context) {
-	const url = "url" in ctx.query ? ctx.query.url : `https://${ctx.params.url}`;
-
-	if (typeof url !== "string") {
-		ctx.status = 400;
-		return;
-	}
-
-	// Create temp file
-	const [path, cleanup] = await createTemp();
-
-	try {
-		await downloadUrl(url, path);
-
-		const { mime, ext } = await detectType(path);
-		const isConvertibleImage = isMimeImage(mime, "sharp-convertible-image");
-
-		let image: IImage;
-
-		if ("static" in ctx.query && isConvertibleImage) {
-			image = await convertToWebp(path, 996, 560);
-		} else if ("preview" in ctx.query && isConvertibleImage) {
-			image = await convertToWebp(path, 400, 400);
-		} else if ("badge" in ctx.query) {
-			if (!isConvertibleImage) {
-				// 画像でないなら404でお茶を濁す
-				throw new StatusError("Unexpected mime", 404);
-			}
-
-			const mask = sharp(path)
-				.resize(96, 96, {
-					fit: "inside",
-					withoutEnlargement: false,
-				})
-				.greyscale()
-				.normalise()
-				.linear(1.75, -(128 * 1.75) + 128) // 1.75x contrast
-				.flatten({ background: "#000" })
-				.toColorspace("b-w");
-
-			const stats = await mask.clone().stats();
-
-			if (stats.entropy < 0.1) {
-				// エントロピーがあまりない場合は404にする
-				throw new StatusError("Skip to provide badge", 404);
-			}
-
-			const data = sharp({
-				create: {
-					width: 96,
-					height: 96,
-					channels: 4,
-					background: { r: 0, g: 0, b: 0, alpha: 0 },
-				},
-			})
-				.pipelineColorspace("b-w")
-				.boolean(await mask.png().toBuffer(), "eor");
-
-			image = {
-				data: await data.png().toBuffer(),
-				ext: "png",
-				type: "image/png",
-			};
-		} else if (mime === "image/svg+xml") {
-			image = await convertToWebp(path, 2048, 2048, 1);
-		} else if (
-			!(mime.startsWith("image/") && FILE_TYPE_BROWSERSAFE.includes(mime))
-		) {
-			throw new StatusError("Rejected type", 403, "Rejected type");
-		} else {
-			image = {
-				data: fs.readFileSync(path),
-				ext,
-				type: mime,
-			};
-		}
-
-		ctx.set("Content-Type", image.type);
-		ctx.set("Cache-Control", "max-age=31536000, immutable");
-		ctx.body = image.data;
-	} catch (e) {
-		serverLogger.error(`${e}`);
-
-		if (e instanceof StatusError && (e.statusCode === 302 || e.isClientError)) {
-			ctx.status = e.statusCode;
-		} else {
-			ctx.status = 500;
-		}
-	} finally {
-		cleanup();
-	}
-}
diff --git a/packages/backend/src/server/web/bios.css b/packages/backend/src/server/web/bios.css
deleted file mode 100644
index e79fc0657b..0000000000
--- a/packages/backend/src/server/web/bios.css
+++ /dev/null
@@ -1,147 +0,0 @@
-main > .tabs {
-	padding: 16px;
-	border-bottom: 4px solid #908caa;
-}
-#lsEditor > .adder {
-	margin: 16px;
-	padding: 16px;
-	border: 2px solid #908caa;
-}
-#lsEditor > .adder > textarea {
-	display: block;
-	width: 100%;
-	min-height: 5em;
-	box-sizing: border-box;
-}
-#lsEditor > .record {
-	padding: 16px;
-	border-bottom: 1px solid #908caa;
-}
-#lsEditor > .record > header {
-	font-weight: 700;
-}
-#lsEditor > .record > textarea {
-	display: block;
-	width: 100%;
-	min-height: 5em;
-	box-sizing: border-box;
-}
-
-html {
-	background: #191724;
-}
-main {
-	background: #1f1d2e;
-	border-radius: 10px;
-}
-#tl > div {
-	padding: 16px;
-	border-bottom: 1px solid #908caa;
-}
-#tl > div > header {
-	font-weight: 700;
-}
-
-* {
-	font-family: BIZ UDGothic, Roboto, HelveticaNeue, Arial, sans-serif;
-}
-#calckey_app {
-	display: none !important;
-}
-body,
-html {
-	background-color: #191724;
-	color: #e0def4;
-	justify-content: center;
-	margin: auto;
-	padding: 10px;
-	text-align: center;
-}
-button {
-	border-radius: 999px;
-	padding: 0px 12px 0px 12px;
-	border: none;
-	cursor: pointer;
-	margin-bottom: 12px;
-	background: linear-gradient(90deg, rgb(156, 207, 216), rgb(49, 116, 143));
-	line-height: 50px;
-	color: #191724;
-	font-weight: bold;
-	font-size: 20px;
-	padding: 12px;
-}
-button {
-	border-radius: 999px;
-	padding: 0px 12px 0px 12px;
-	border: none;
-	cursor: pointer;
-	margin-bottom: 12px;
-}
-button {
-	background: #444;
-	line-height: 40px;
-	color: rgb(156, 207, 216);
-	font-size: 16px;
-  padding: 0 20px;
-  margin-right: 5px;
-  margin-left: 5px;
-}
-button:hover {
-	background: #555;
-}
-#ls {
-	background: linear-gradient(90deg, rgb(156, 207, 216), rgb(49, 116, 143));
-	line-height: 30px;
-	color: #191724;
-	font-weight: bold;
-	font-size: 18px;
-	padding: 12px;
-}
-#ls:hover {
-	background: rgb(156, 207, 216);
-}
-a {
-	color: rgb(156, 207, 216);
-	text-decoration: none;
-}
-p,
-li {
-	font-size: 16px;
-}
-
-h1 {
-	font-size: 32px;
-}
-code {
-	font-family: Fira, FiraCode, monospace;
-}
-textarea {
-	background-color: #444;
-	border: solid #aaa;
-	border-radius: 10px;
-	color: #e0def4;
-	margin-top: 1rem;
-	margin-bottom: 1rem;
-	width: 20rem;
-	height: 7.5rem;
-	padding: 0.5rem;
-}
-
-textarea:focus {
-	border: solid #eee;
-}
-input {
-	background-color: #666;
-	border: solid #aaa;
-	border-radius: 10px;
-	color: #e0def4;
-	margin-top: 1rem;
-	margin-bottom: 1rem;
-	width: 10rem;
-	height: 1rem;
-	padding: 0.5rem;
-}
-
-input:focus {
-	border: solid #eee;
-}
diff --git a/packages/backend/src/server/web/bios.js b/packages/backend/src/server/web/bios.js
deleted file mode 100644
index e715a01068..0000000000
--- a/packages/backend/src/server/web/bios.js
+++ /dev/null
@@ -1,89 +0,0 @@
-"use strict";
-
-window.onload = async () => {
-	const account = JSON.parse(localStorage.getItem("account"));
-	const i = account.token;
-
-	const api = (endpoint, data = {}) => {
-		const promise = new Promise((resolve, reject) => {
-			// Append a credential
-			if (i) data.i = i;
-
-			// Send request
-			fetch(endpoint.indexOf("://") > -1 ? endpoint : `/api/${endpoint}`, {
-				method: "POST",
-				body: JSON.stringify(data),
-				credentials: "omit",
-				cache: "no-cache",
-			})
-				.then(async (res) => {
-					const body = res.status === 204 ? null : await res.json();
-
-					if (res.status === 200) {
-						resolve(body);
-					} else if (res.status === 204) {
-						resolve();
-					} else {
-						reject(body.error);
-					}
-				})
-				.catch(reject);
-		});
-
-		return promise;
-	};
-
-	const content = document.getElementById("content");
-
-	document.getElementById("ls").addEventListener("click", () => {
-		content.innerHTML = "";
-
-		const lsEditor = document.createElement("div");
-		lsEditor.id = "lsEditor";
-
-		const adder = document.createElement("div");
-		adder.classList.add("adder");
-		const addKeyInput = document.createElement("input");
-		const addValueTextarea = document.createElement("textarea");
-		const addButton = document.createElement("button");
-		addButton.textContent = "Add";
-		addButton.addEventListener("click", () => {
-			localStorage.setItem(addKeyInput.value, addValueTextarea.value);
-			location.reload();
-		});
-
-		adder.appendChild(addKeyInput);
-		adder.appendChild(addValueTextarea);
-		adder.appendChild(addButton);
-		lsEditor.appendChild(adder);
-
-		for (let i = 0; i < localStorage.length; i++) {
-			const k = localStorage.key(i);
-			const record = document.createElement("div");
-			record.classList.add("record");
-			const header = document.createElement("header");
-			header.textContent = k;
-			const textarea = document.createElement("textarea");
-			textarea.textContent = localStorage.getItem(k);
-			const saveButton = document.createElement("button");
-			saveButton.textContent = "Save";
-			saveButton.addEventListener("click", () => {
-				localStorage.setItem(k, textarea.value);
-				location.reload();
-			});
-			const removeButton = document.createElement("button");
-			removeButton.textContent = "Remove";
-			removeButton.addEventListener("click", () => {
-				localStorage.removeItem(k);
-				location.reload();
-			});
-			record.appendChild(header);
-			record.appendChild(textarea);
-			record.appendChild(saveButton);
-			record.appendChild(removeButton);
-			lsEditor.appendChild(record);
-		}
-
-		content.appendChild(lsEditor);
-	});
-};
diff --git a/packages/backend/src/server/web/boot.js b/packages/backend/src/server/web/boot.js
deleted file mode 100644
index e7e859d20c..0000000000
--- a/packages/backend/src/server/web/boot.js
+++ /dev/null
@@ -1,319 +0,0 @@
-/**
- * BOOT LOADER
- * サーバーからレスポンスされるHTMLに埋め込まれるスクリプトで、以下の役割を持ちます。
- * - 翻訳ファイルをフェッチする。
- * - バージョンに基づいて適切なメインスクリプトを読み込む。
- * - キャッシュされたコンパイル済みテーマを適用する。
- * - クライアントの設定値に基づいて対応するHTMLクラス等を設定する。
- * テーマをこの段階で設定するのは、メインスクリプトが読み込まれる間もテーマを適用したいためです。
- * 注: webpackは介さないため、このファイルではrequireやimportは使えません。
- */
-
-"use strict";
-
-// ブロックの中に入れないと、定義した変数がブラウザのグローバルスコープに登録されてしまい邪魔なので
-(async () => {
-	window.onerror = (e) => {
-		console.error(e);
-		renderError("SOMETHING_HAPPENED", e);
-	};
-	window.onunhandledrejection = (e) => {
-		console.error(e);
-		renderError("SOMETHING_HAPPENED_IN_PROMISE", e);
-	};
-
-	//#region Detect language & fetch translations
-	const v = localStorage.getItem("v") || VERSION;
-
-	const supportedLangs = LANGS;
-	let lang = localStorage.getItem("lang");
-	if (lang == null || !supportedLangs.includes(lang)) {
-		if (supportedLangs.includes(navigator.language)) {
-			lang = navigator.language;
-		} else {
-			lang = supportedLangs.find((x) => x.split("-")[0] === navigator.language);
-
-			// Fallback
-			if (lang == null) lang = "en-US";
-		}
-	}
-
-	const res = await fetch(`/assets/locales/${lang}.${v}.json`);
-	if (res.status === 200) {
-		localStorage.setItem("lang", lang);
-		localStorage.setItem("locale", await res.text());
-		localStorage.setItem("localeVersion", v);
-	} else {
-		await checkUpdate();
-		renderError("LOCALE_FETCH");
-		return;
-	}
-	//#endregion
-
-	//#region Script
-	function importAppScript() {
-		import(`/assets/${CLIENT_ENTRY}`).catch(async (e) => {
-			await checkUpdate();
-			console.error(e);
-			renderError("APP_IMPORT", e);
-		});
-	}
-
-	// タイミングによっては、この時点でDOMの構築が済んでいる場合とそうでない場合とがある
-	if (document.readyState !== "loading") {
-		importAppScript();
-	} else {
-		window.addEventListener("DOMContentLoaded", () => {
-			importAppScript();
-		});
-	}
-	//#endregion
-
-	//#region Theme
-	const theme = localStorage.getItem("theme");
-	if (theme) {
-		for (const [k, v] of Object.entries(JSON.parse(theme))) {
-			document.documentElement.style.setProperty(`--${k}`, v.toString());
-
-			// HTMLの theme-color 適用
-			if (k === "htmlThemeColor") {
-				for (const tag of document.head.children) {
-					if (
-						tag.tagName === "META" &&
-						tag.getAttribute("name") === "theme-color"
-					) {
-						tag.setAttribute("content", v);
-						break;
-					}
-				}
-			}
-		}
-	}
-	const colorSchema = localStorage.getItem("colorSchema");
-	if (colorSchema) {
-		document.documentElement.style.setProperty("color-schema", colorSchema);
-	}
-	//#endregion
-
-	const fontSize = localStorage.getItem("fontSize");
-	if (fontSize) {
-		document.documentElement.classList.add("f-" + fontSize);
-	}
-
-	const useSystemFont = localStorage.getItem("useSystemFont");
-	if (useSystemFont) {
-		document.documentElement.classList.add("useSystemFont");
-	}
-
-	const wallpaper = localStorage.getItem("wallpaper");
-	if (wallpaper) {
-		document.documentElement.style.backgroundImage = `url(${wallpaper})`;
-	}
-
-	const customCss = localStorage.getItem("customCss");
-	if (customCss && customCss.length > 0) {
-		const style = document.createElement("style");
-		style.innerHTML = customCss;
-		document.head.appendChild(style);
-	}
-
-	async function addStyle(styleText) {
-		let css = document.createElement("style");
-		css.appendChild(document.createTextNode(styleText));
-		document.head.appendChild(css);
-	}
-
-	function renderError(code, details) {
-		let errorsElement = document.getElementById("errors");
-
-		if (!errorsElement) {
-			document.body.innerHTML = `
-			<svg class="icon-warning" xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-alert-triangle" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
-				<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
-				<path d="M12 9v2m0 4v.01"></path>
-				<path d="M5 19h14a2 2 0 0 0 1.84 -2.75l-7.1 -12.25a2 2 0 0 0 -3.5 0l-7.1 12.25a2 2 0 0 0 1.75 2.75"></path>
-			</svg>
-			<h1>An error has occurred!</h1>
-			<button class="button-big" onclick="location.reload(true);">
-				<span class="button-label-big">Refresh</span>
-			</button>
-			<p class="dont-worry">Don't worry, it's (probably) not your fault.</p>
-			<p>Please make sure your browser is up-to-date and any AdBlockers are off.</p>
-			<p>If the problem persists after refreshing, please contact your instance's administrator.<br>You may also try the following options:</p>
-			<a href="/flush">
-				<button class="button-small">
-					<span class="button-label-small">Clear preferences and cache</span>
-				</button>
-			</a>
-			<br>
-			<a href="/cli">
-				<button class="button-small">
-					<span class="button-label-small">Start the simple client</span>
-				</button>
-			</a>
-			<br>
-			<a href="/bios">
-				<button class="button-small">
-					<span class="button-label-small">Start the repair tool</span>
-				</button>
-			</a>
-			<br>
-			<div id="errors"></div>
-			`;
-			errorsElement = document.getElementById("errors");
-		}
-		const detailsElement = document.createElement("details");
-		detailsElement.innerHTML = `
-		<br>
-		<summary>
-			<code>ERROR CODE: ${code}</code>
-		</summary>
-		<code>${JSON.stringify(details)}</code>`;
-		errorsElement.appendChild(detailsElement);
-		addStyle(`
-		* {
-			font-family: BIZ UDGothic, Roboto, HelveticaNeue, Arial, sans-serif;
-		}
-
-		#calckey_app,
-		#splash {
-			display: none !important;
-		}
-
-		body,
-		html {
-			background-color: #191724;
-			color: #e0def4;
-			justify-content: center;
-			margin: auto;
-			padding: 10px;
-			text-align: center;
-		}
-
-		button {
-			border-radius: 999px;
-			padding: 0px 12px 0px 12px;
-			border: none;
-			cursor: pointer;
-			margin-bottom: 12px;
-		}
-
-		.button-big {
-			background: linear-gradient(90deg, rgb(196, 167, 231), rgb(235, 188, 186));
-			line-height: 50px;
-		}
-
-		.button-big:hover {
-			background: rgb(49, 116, 143);
-		}
-
-		.button-small {
-			background: #444;
-			line-height: 40px;
-		}
-
-		.button-small:hover {
-			background: #555;
-		}
-
-		.button-label-big {
-			color: #191724;
-			font-weight: bold;
-			font-size: 20px;
-			padding: 12px;
-		}
-
-		.button-label-small {
-			color: rgb(156, 207, 216);
-			font-size: 16px;
-			padding: 12px;
-		}
-
-		a {
-			color: rgb(156, 207, 216);
-			text-decoration: none;
-		}
-
-		p,
-		li {
-			font-size: 16px;
-		}
-
-		.dont-worry,
-		#msg {
-			font-size: 18px;
-		}
-
-		.icon-warning {
-			color: #f6c177;
-			height: 4rem;
-			padding-top: 2rem;
-		}
-
-		h1 {
-			font-size: 32px;
-		}
-
-		code {
-			font-family: Fira, FiraCode, monospace;
-		}
-
-		details {
-			background: #1f1d2e;
-			margin-bottom: 2rem;
-			padding: 0.5rem 1rem;
-			width: 40rem;
-			border-radius: 10px;
-			justify-content: center;
-			margin: auto;
-		}
-
-		summary {
-			cursor: pointer;
-		}
-
-		summary > * {
-			display: inline;
-		}
-
-		@media screen and (max-width: 500px) {
-			details {
-				width: 50%;
-			}
-		`);
-	}
-
-	async function checkUpdate() {
-		try {
-			const res = await fetch("/api/meta", {
-				method: "POST",
-				cache: "no-cache",
-			});
-
-			const meta = await res.json();
-
-			if (meta.version != v) {
-				localStorage.setItem("v", meta.version);
-				refresh();
-			}
-		} catch (e) {
-			console.error(e);
-			renderError("UPDATE_CHECK", e);
-			throw e;
-		}
-	}
-
-	function refresh() {
-		// Clear cache (service worker)
-		try {
-			navigator.serviceWorker.controller.postMessage("clear");
-			navigator.serviceWorker.getRegistrations().then((registrations) => {
-				registrations.forEach((registration) => registration.unregister());
-			});
-		} catch (e) {
-			console.error(e);
-		}
-
-		location.reload();
-	}
-})();
diff --git a/packages/backend/src/server/web/cli.css b/packages/backend/src/server/web/cli.css
deleted file mode 100644
index 460a7b7f31..0000000000
--- a/packages/backend/src/server/web/cli.css
+++ /dev/null
@@ -1,92 +0,0 @@
-html {
-	background: #191724;
-}
-main {
-	background: #1f1d2e;
-	border-radius: 10px;
-}
-#tl > div {
-	border: 1px solid #908caa;
-  border-radius: 10px;
-  margin: 10px;
-  padding: 10px;
-	width: fit-content;
-}
-#tl > div > header {
-	font-weight: 700;
-	display: inline-flex;
-}
-
-img {
-	border-radius: 10px;
-	margin-right: 10px;
-}
-
-#form {
-	text-align: center;
-}
-
-#calckey_app {
-	display: none !important;
-}
-
-body,
-html {
-	font-family: BIZ UDGothic, Roboto, HelveticaNeue, Arial, sans-serif;
-	background-color: #191724;
-	color: #e0def4;
-	justify-content: center;
-	margin: auto;
-	padding: 10px;
-}
-button {
-	border-radius:999px;
-	padding:0 40px;
-	margin-top: 1rem;
-	border:none;
-	cursor:pointer;
-	margin-bottom:12px;
-	background:linear-gradient(90deg,#9ccfd8,#31748f);
-	line-height:50px;
-	color:#191724;
-	font-weight:700;
-	font-size:20px;
- }
-button:hover {
-	background: rgb(156, 207, 216);
-}
-a {
-	color: rgb(156, 207, 216);
-	text-decoration: none;
-}
-p,
-li {
-	font-size: 16px;
-}
-
-h1 {
-	font-size: 32px;
-}
-code {
-	font-family: Fira, FiraCode, monospace;
-}
-#text {
-	background-color: #444;
-	border: solid #aaa;
-	border-radius: 10px;
-	color: #e0def4;
-	margin-top: 3rem;
-	width: 20rem;
-	height: 5rem;
-	padding: 0.5rem;
-}
-
-#text:focus {
-	border: solid #eee;
-}
-
-@media screen and (max-width: 500px) {
-  #text {
-    width: 80%
-  }
-}
diff --git a/packages/backend/src/server/web/cli.js b/packages/backend/src/server/web/cli.js
deleted file mode 100644
index 85a61a2446..0000000000
--- a/packages/backend/src/server/web/cli.js
+++ /dev/null
@@ -1,72 +0,0 @@
-"use strict";
-
-window.onload = async () => {
-	const account = JSON.parse(localStorage.getItem("account"));
-	const i = account.token;
-
-	const api = (endpoint, data = {}) => {
-		const promise = new Promise((resolve, reject) => {
-			// Append a credential
-			if (i) data.i = i;
-
-			// Send request
-			fetch(endpoint.indexOf("://") > -1 ? endpoint : `/api/${endpoint}`, {
-				method: "POST",
-				body: JSON.stringify(data),
-				credentials: "omit",
-				cache: "no-cache",
-			})
-				.then(async (res) => {
-					const body = res.status === 204 ? null : await res.json();
-
-					if (res.status === 200) {
-						resolve(body);
-					} else if (res.status === 204) {
-						resolve();
-					} else {
-						reject(body.error);
-					}
-				})
-				.catch(reject);
-		});
-
-		return promise;
-	};
-
-	document.getElementById("submit").addEventListener("click", () => {
-		api("notes/create", {
-			text: document.getElementById("text").value,
-		}).then(() => {
-			location.reload();
-		});
-	});
-
-	api("notes/timeline").then((notes) => {
-		const tl = document.getElementById("tl");
-		for (const note of notes) {
-			const el = document.createElement("div");
-			const header = document.createElement("header");
-			const name = document.createElement("p");
-			const avatar = document.createElement("img");
-			name.textContent = `${note.user.name} @${note.user.username}`;
-			avatar.src = note.user.avatarUrl;
-			avatar.style = "height: 40px";
-			const text = document.createElement("div");
-			text.textContent = `${note.text}`;
-			el.appendChild(header);
-			header.appendChild(avatar);
-			header.appendChild(name);
-			if (note.text) {
-				el.appendChild(text);
-			}
-			if (note.files) {
-				for (const file of note.files) {
-					const img = document.createElement("img");
-					img.src = file.properties.thumbnailUrl;
-					el.appendChild(img);
-				}
-			}
-			tl.appendChild(el);
-		}
-	});
-};
diff --git a/packages/backend/src/server/web/feed.ts b/packages/backend/src/server/web/feed.ts
deleted file mode 100644
index 9cbeb28ae1..0000000000
--- a/packages/backend/src/server/web/feed.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-import { Feed } from "feed";
-import { In, IsNull } from "typeorm";
-import config from "@/config/index.js";
-import type { User } from "@/models/entities/user.js";
-import { Notes, DriveFiles, UserProfiles, Users } from "@/models/index.js";
-
-export default async function (user: User) {
-	const author = {
-		link: `${config.url}/@${user.username}`,
-		name: user.name || user.username,
-	};
-
-	const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
-
-	const notes = await Notes.find({
-		where: {
-			userId: user.id,
-			renoteId: IsNull(),
-			visibility: In(["public", "home"]),
-		},
-		order: { createdAt: -1 },
-		take: 20,
-	});
-
-	const feed = new Feed({
-		id: author.link,
-		title: `${author.name} (@${user.username}@${config.host})`,
-		updated: notes[0].createdAt,
-		generator: "Calckey",
-		description: `${user.notesCount} Notes, ${
-			profile.ffVisibility === "public" ? user.followingCount : "?"
-		} Following, ${
-			profile.ffVisibility === "public" ? user.followersCount : "?"
-		} Followers${profile.description ? ` · ${profile.description}` : ""}`,
-		link: author.link,
-		image: await Users.getAvatarUrl(user),
-		feedLinks: {
-			json: `${author.link}.json`,
-			atom: `${author.link}.atom`,
-		},
-		author,
-		copyright: user.name || user.username,
-	});
-
-	for (const note of notes) {
-		const files =
-			note.fileIds.length > 0
-				? await DriveFiles.findBy({
-						id: In(note.fileIds),
-				  })
-				: [];
-		const file = files.find((file) => file.type.startsWith("image/"));
-
-		feed.addItem({
-			title: `New note by ${author.name}`,
-			link: `${config.url}/notes/${note.id}`,
-			date: note.createdAt,
-			description: note.cw || undefined,
-			content: note.text || undefined,
-			image: file ? DriveFiles.getPublicUrl(file) || undefined : undefined,
-		});
-	}
-
-	return feed;
-}
diff --git a/packages/backend/src/server/web/index.ts b/packages/backend/src/server/web/index.ts
deleted file mode 100644
index 028170cd75..0000000000
--- a/packages/backend/src/server/web/index.ts
+++ /dev/null
@@ -1,677 +0,0 @@
-/**
- * Web Client Server
- */
-
-import { dirname } from "node:path";
-import { fileURLToPath } from "node:url";
-import { readFileSync } from "node:fs";
-import Koa from "koa";
-import Router from "@koa/router";
-import send from "koa-send";
-import views from "koa-views";
-import sharp from "sharp";
-import { createBullBoard } from "@bull-board/api";
-import { BullAdapter } from "@bull-board/api/bullAdapter.js";
-import { KoaAdapter } from "@bull-board/koa";
-import { In, IsNull } from "typeorm";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import config from "@/config/index.js";
-import {
-	Users,
-	Notes,
-	UserProfiles,
-	Pages,
-	Channels,
-	Clips,
-	GalleryPosts,
-} from "@/models/index.js";
-import * as Acct from "@/misc/acct.js";
-import { getNoteSummary } from "@/misc/get-note-summary.js";
-import { queues } from "@/queue/queues.js";
-import { genOpenapiSpec } from "../api/openapi/gen-spec.js";
-import { urlPreviewHandler } from "./url-preview.js";
-import { manifestHandler } from "./manifest.js";
-import packFeed from "./feed.js";
-import { MINUTE, DAY } from "@/const.js";
-
-const _filename = fileURLToPath(import.meta.url);
-const _dirname = dirname(_filename);
-
-const staticAssets = `${_dirname}/../../../assets/`;
-const clientAssets = `${_dirname}/../../../../client/assets/`;
-const assets = `${_dirname}/../../../../../built/_client_dist_/`;
-const swAssets = `${_dirname}/../../../../../built/_sw_dist_/`;
-
-// Init app
-const app = new Koa();
-
-//#region Bull Dashboard
-const bullBoardPath = "/queue";
-
-// Authenticate
-app.use(async (ctx, next) => {
-	if (ctx.path === bullBoardPath || ctx.path.startsWith(`${bullBoardPath}/`)) {
-		const token = ctx.cookies.get("token");
-		if (token == null) {
-			ctx.status = 401;
-			return;
-		}
-		const user = await Users.findOneBy({ token });
-		if (user == null || !(user.isAdmin || user.isModerator)) {
-			ctx.status = 403;
-			return;
-		}
-	}
-	await next();
-});
-
-const serverAdapter = new KoaAdapter();
-
-createBullBoard({
-	queues: queues.map((q) => new BullAdapter(q)),
-	serverAdapter,
-});
-
-serverAdapter.setBasePath(bullBoardPath);
-app.use(serverAdapter.registerPlugin());
-//#endregion
-
-// Init renderer
-app.use(
-	views(`${_dirname}/views`, {
-		extension: "pug",
-		options: {
-			version: config.version,
-			getClientEntry: () =>
-				process.env.NODE_ENV === "production"
-					? config.clientEntry
-					: JSON.parse(
-							readFileSync(
-								`${_dirname}/../../../../../built/_client_dist_/manifest.json`,
-								"utf-8",
-							),
-					  )["src/init.ts"],
-			config,
-		},
-	}),
-);
-
-// Favicon Router
-app.use(async (ctx, next) => {
-	if (ctx.path != "/favicon.ico") return next();
-	const meta = await fetchMeta();
-	if (meta.iconUrl === "")
-		ctx.body = readFileSync(`${_dirname}/../../../assets/favicon.ico`);
-	else ctx.redirect(meta.iconUrl);
-});
-
-// Common request handler
-app.use(async (ctx, next) => {
-	// IFrameの中に入れられないようにする
-	ctx.set("X-Frame-Options", "DENY");
-	await next();
-});
-
-// Init router
-const router = new Router();
-
-//#region static assets
-
-router.get("/static-assets/(.*)", async (ctx) => {
-	await send(ctx as any, ctx.path.replace("/static-assets/", ""), {
-		root: staticAssets,
-		maxage: 7 * DAY,
-	});
-});
-
-router.get("/client-assets/(.*)", async (ctx) => {
-	await send(ctx as any, ctx.path.replace("/client-assets/", ""), {
-		root: clientAssets,
-		maxage: 7 * DAY,
-	});
-});
-
-router.get("/assets/(.*)", async (ctx) => {
-	await send(ctx as any, ctx.path.replace("/assets/", ""), {
-		root: assets,
-		maxage: 7 * DAY,
-	});
-});
-
-// Apple touch icon
-router.get("/apple-touch-icon.png", async (ctx) => {
-	await send(ctx as any, "/apple-touch-icon.png", {
-		root: staticAssets,
-	});
-});
-
-router.get("/twemoji/(.*)", async (ctx) => {
-	const path = ctx.path.replace("/twemoji/", "");
-
-	if (!path.match(/^[0-9a-f-]+\.svg$/)) {
-		ctx.status = 404;
-		return;
-	}
-
-	ctx.set(
-		"Content-Security-Policy",
-		"default-src 'none'; style-src 'unsafe-inline'",
-	);
-
-	await send(ctx as any, path, {
-		root: `${_dirname}/../../../node_modules/@discordapp/twemoji/dist/svg/`,
-		maxage: 30 * DAY,
-	});
-});
-
-router.get("/twemoji-badge/(.*)", async (ctx) => {
-	const path = ctx.path.replace("/twemoji-badge/", "");
-
-	if (!path.match(/^[0-9a-f-]+\.png$/)) {
-		ctx.status = 404;
-		return;
-	}
-
-	const mask = await sharp(
-		`${_dirname}/../../../node_modules/@discordapp/twemoji/dist/svg/${path.replace(
-			".png",
-			"",
-		)}.svg`,
-		{ density: 1000 },
-	)
-		.resize(488, 488)
-		.greyscale()
-		.normalise()
-		.linear(1.75, -(128 * 1.75) + 128) // 1.75x contrast
-		.flatten({ background: "#000" })
-		.extend({
-			top: 12,
-			bottom: 12,
-			left: 12,
-			right: 12,
-			background: "#000",
-		})
-		.toColorspace("b-w")
-		.png()
-		.toBuffer();
-
-	const buffer = await sharp({
-		create: {
-			width: 512,
-			height: 512,
-			channels: 4,
-			background: { r: 0, g: 0, b: 0, alpha: 0 },
-		},
-	})
-		.pipelineColorspace("b-w")
-		.boolean(mask, "eor")
-		.resize(96, 96)
-		.png()
-		.toBuffer();
-
-	ctx.set(
-		"Content-Security-Policy",
-		"default-src 'none'; style-src 'unsafe-inline'",
-	);
-	ctx.set("Cache-Control", "max-age=2592000");
-	ctx.set("Content-Type", "image/png");
-	ctx.body = buffer;
-});
-
-// ServiceWorker
-router.get("/sw.js", async (ctx) => {
-	await send(ctx as any, "/sw.js", {
-		root: swAssets,
-		maxage: 10 * MINUTE,
-	});
-});
-
-// Manifest
-router.get("/manifest.json", manifestHandler);
-
-router.get("/robots.txt", async (ctx) => {
-	await send(ctx as any, "/robots.txt", {
-		root: staticAssets,
-	});
-});
-
-//#endregion
-
-// Docs
-router.get("/api-doc", async (ctx) => {
-	await send(ctx as any, "/redoc.html", {
-		root: staticAssets,
-	});
-});
-
-// URL preview endpoint
-router.get("/url", urlPreviewHandler);
-
-router.get("/api.json", async (ctx) => {
-	ctx.body = genOpenapiSpec();
-});
-
-const getFeed = async (acct: string) => {
-	const meta = await fetchMeta();
-	if (meta.privateMode) {
-		return;
-	}
-	const { username, host } = Acct.parse(acct);
-	const user = await Users.findOneBy({
-		usernameLower: username.toLowerCase(),
-		host: host ?? IsNull(),
-		isSuspended: false,
-	});
-
-	return user && (await packFeed(user));
-};
-
-// As the /@user[.json|.rss|.atom]/sub endpoint is complicated, we will use a regex to switch between them.
-const reUser = new RegExp(
-	"^/@(?<user>[^/]+?)(?:.(?<feed>json|rss|atom))?(?:/(?<sub>[^/]+))?$",
-);
-router.get(reUser, async (ctx, next) => {
-	const groups = reUser.exec(ctx.originalUrl)?.groups;
-	if (!groups) {
-		await next();
-		return;
-	}
-
-	ctx.params = groups;
-
-	console.log(ctx, ctx.params);
-	if (groups.feed) {
-		if (groups.sub) {
-			await next();
-			return;
-		}
-
-		switch (groups.feed) {
-			case "json":
-				await jsonFeed(ctx, next);
-				break;
-			case "rss":
-				await rssFeed(ctx, next);
-				break;
-			case "atom":
-				await atomFeed(ctx, next);
-				break;
-		}
-		return;
-	}
-
-	await userPage(ctx, next);
-});
-
-// Atom
-const atomFeed: Router.Middleware = async (ctx) => {
-	const feed = await getFeed(ctx.params.user);
-
-	if (feed) {
-		ctx.set("Content-Type", "application/atom+xml; charset=utf-8");
-		ctx.body = feed.atom1();
-	} else {
-		ctx.status = 404;
-	}
-};
-
-// RSS
-const rssFeed: Router.Middleware = async (ctx) => {
-	const feed = await getFeed(ctx.params.user);
-
-	if (feed) {
-		ctx.set("Content-Type", "application/rss+xml; charset=utf-8");
-		ctx.body = feed.rss2();
-	} else {
-		ctx.status = 404;
-	}
-};
-
-// JSON
-const jsonFeed: Router.Middleware = async (ctx) => {
-	const feed = await getFeed(ctx.params.user);
-
-	if (feed) {
-		ctx.set("Content-Type", "application/json; charset=utf-8");
-		ctx.body = feed.json1();
-	} else {
-		ctx.status = 404;
-	}
-};
-
-//#region SSR (for crawlers)
-// User
-const userPage: Router.Middleware = async (ctx, next) => {
-	const userParam = ctx.params.user;
-	const subParam = ctx.params.sub;
-	const { username, host } = Acct.parse(userParam);
-
-	const user = await Users.findOneBy({
-		usernameLower: username.toLowerCase(),
-		host: host ?? IsNull(),
-		isSuspended: false,
-	});
-
-	if (user === null) {
-		await next();
-		return;
-	}
-
-	const profile = await UserProfiles.findOneByOrFail({ userId: user.id });
-	const meta = await fetchMeta();
-	const me = profile.fields
-		? profile.fields
-				.filter((filed) => filed.value?.match(/^https?:/))
-				.map((field) => field.value)
-		: [];
-
-	const userDetail = {
-		user,
-		profile,
-		me,
-		avatarUrl: await Users.getAvatarUrl(user),
-		sub: subParam,
-		instanceName: meta.name || "Calckey",
-		icon: meta.iconUrl,
-		themeColor: meta.themeColor,
-		privateMode: meta.privateMode,
-	};
-
-	await ctx.render("user", userDetail);
-	ctx.set("Cache-Control", "public, max-age=15");
-};
-
-router.get("/users/:user", async (ctx) => {
-	const user = await Users.findOneBy({
-		id: ctx.params.user,
-		host: IsNull(),
-		isSuspended: false,
-	});
-
-	if (user == null) {
-		ctx.status = 404;
-		return;
-	}
-
-	ctx.redirect(`/@${user.username}${user.host == null ? "" : `@${user.host}`}`);
-});
-
-// Note
-router.get("/notes/:note", async (ctx, next) => {
-	const note = await Notes.findOneBy({
-		id: ctx.params.note,
-		visibility: In(["public", "home"]),
-	});
-
-	if (note) {
-		const _note = await Notes.pack(note);
-		const profile = await UserProfiles.findOneByOrFail({ userId: note.userId });
-		const meta = await fetchMeta();
-		await ctx.render("note", {
-			note: _note,
-			profile,
-			avatarUrl: await Users.getAvatarUrl(
-				await Users.findOneByOrFail({ id: note.userId }),
-			),
-			// TODO: Let locale changeable by instance setting
-			summary: getNoteSummary(_note),
-			instanceName: meta.name || "Calckey",
-			icon: meta.iconUrl,
-			privateMode: meta.privateMode,
-			themeColor: meta.themeColor,
-		});
-
-		ctx.set("Cache-Control", "public, max-age=15");
-
-		return;
-	}
-
-	await next();
-});
-
-router.get("/posts/:note", async (ctx, next) => {
-	const note = await Notes.findOneBy({
-		id: ctx.params.note,
-		visibility: In(["public", "home"]),
-	});
-
-	if (note) {
-		const _note = await Notes.pack(note);
-		const profile = await UserProfiles.findOneByOrFail({ userId: note.userId });
-		const meta = await fetchMeta();
-		await ctx.render("note", {
-			note: _note,
-			profile,
-			avatarUrl: await Users.getAvatarUrl(
-				await Users.findOneByOrFail({ id: note.userId }),
-			),
-			// TODO: Let locale changeable by instance setting
-			summary: getNoteSummary(_note),
-			instanceName: meta.name || "Calckey",
-			icon: meta.iconUrl,
-			privateMode: meta.privateMode,
-			themeColor: meta.themeColor,
-		});
-
-		ctx.set("Cache-Control", "public, max-age=15");
-
-		return;
-	}
-
-	await next();
-});
-
-// Page
-router.get("/@:user/pages/:page", async (ctx, next) => {
-	const { username, host } = Acct.parse(ctx.params.user);
-	const user = await Users.findOneBy({
-		usernameLower: username.toLowerCase(),
-		host: host ?? IsNull(),
-	});
-
-	if (user == null) return;
-
-	const page = await Pages.findOneBy({
-		name: ctx.params.page,
-		userId: user.id,
-	});
-
-	if (page) {
-		const _page = await Pages.pack(page);
-		const profile = await UserProfiles.findOneByOrFail({ userId: page.userId });
-		const meta = await fetchMeta();
-		await ctx.render("page", {
-			page: _page,
-			profile,
-			avatarUrl: await Users.getAvatarUrl(
-				await Users.findOneByOrFail({ id: page.userId }),
-			),
-			instanceName: meta.name || "Calckey",
-			icon: meta.iconUrl,
-			themeColor: meta.themeColor,
-			privateMode: meta.privateMode,
-		});
-
-		if (["public"].includes(page.visibility)) {
-			ctx.set("Cache-Control", "public, max-age=15");
-		} else {
-			ctx.set("Cache-Control", "private, max-age=0, must-revalidate");
-		}
-
-		return;
-	}
-
-	await next();
-});
-
-// Clip
-// TODO: handling of private clips
-router.get("/clips/:clip", async (ctx, next) => {
-	const clip = await Clips.findOneBy({
-		id: ctx.params.clip,
-	});
-
-	if (clip) {
-		const _clip = await Clips.pack(clip);
-		const profile = await UserProfiles.findOneByOrFail({ userId: clip.userId });
-		const meta = await fetchMeta();
-		await ctx.render("clip", {
-			clip: _clip,
-			profile,
-			avatarUrl: await Users.getAvatarUrl(
-				await Users.findOneByOrFail({ id: clip.userId }),
-			),
-			instanceName: meta.name || "Calckey",
-			privateMode: meta.privateMode,
-			icon: meta.iconUrl,
-			themeColor: meta.themeColor,
-		});
-
-		ctx.set("Cache-Control", "public, max-age=15");
-
-		return;
-	}
-
-	await next();
-});
-
-// Gallery post
-router.get("/gallery/:post", async (ctx, next) => {
-	const post = await GalleryPosts.findOneBy({ id: ctx.params.post });
-
-	if (post) {
-		const _post = await GalleryPosts.pack(post);
-		const profile = await UserProfiles.findOneByOrFail({ userId: post.userId });
-		const meta = await fetchMeta();
-		await ctx.render("gallery-post", {
-			post: _post,
-			profile,
-			avatarUrl: await Users.getAvatarUrl(
-				await Users.findOneByOrFail({ id: post.userId }),
-			),
-			instanceName: meta.name || "Calckey",
-			icon: meta.iconUrl,
-			themeColor: meta.themeColor,
-			privateMode: meta.privateMode,
-		});
-
-		ctx.set("Cache-Control", "public, max-age=15");
-
-		return;
-	}
-
-	await next();
-});
-
-// Channel
-router.get("/channels/:channel", async (ctx, next) => {
-	const channel = await Channels.findOneBy({
-		id: ctx.params.channel,
-	});
-
-	if (channel) {
-		const _channel = await Channels.pack(channel);
-		const meta = await fetchMeta();
-		await ctx.render("channel", {
-			channel: _channel,
-			instanceName: meta.name || "Calckey",
-			icon: meta.iconUrl,
-			themeColor: meta.themeColor,
-			privateMode: meta.privateMode,
-		});
-
-		ctx.set("Cache-Control", "public, max-age=15");
-
-		return;
-	}
-
-	await next();
-});
-//#endregion
-
-router.get("/_info_card_", async (ctx) => {
-	const meta = await fetchMeta(true);
-	if (meta.privateMode) {
-		ctx.status = 403;
-		return;
-	}
-
-	ctx.remove("X-Frame-Options");
-
-	await ctx.render("info-card", {
-		version: config.version,
-		host: config.host,
-		meta: meta,
-		originalUsersCount: await Users.countBy({ host: IsNull() }),
-		originalNotesCount: await Notes.countBy({ userHost: IsNull() }),
-	});
-});
-
-router.get("/bios", async (ctx) => {
-	await ctx.render("bios", {
-		version: config.version,
-	});
-});
-
-router.get("/cli", async (ctx) => {
-	await ctx.render("cli", {
-		version: config.version,
-	});
-});
-
-const override = (source: string, target: string, depth = 0) =>
-	[
-		undefined,
-		...target.split("/").filter((x) => x),
-		...source
-			.split("/")
-			.filter((x) => x)
-			.splice(depth),
-	].join("/");
-
-router.get("/flush", async (ctx) => {
-	await ctx.render("flush");
-});
-
-// If a non-WebSocket request comes in to streaming and base html is returned with cache, the path will be cached by Proxy, etc. and it will be wrong.
-router.get("/streaming", async (ctx) => {
-	ctx.status = 503;
-	ctx.set("Cache-Control", "private, max-age=0");
-});
-router.get("/api/v1/streaming", async (ctx) => {
-	ctx.status = 503;
-	ctx.set("Cache-Control", "private, max-age=0");
-});
-
-// Render base html for all requests
-router.get("(.*)", async (ctx) => {
-	const meta = await fetchMeta();
-	let motd = ["Loading..."];
-	if (meta.customMOTD.length > 0) {
-		motd = meta.customMOTD;
-	}
-	let splashIconUrl = meta.iconUrl;
-	if (meta.customSplashIcons.length > 0) {
-		splashIconUrl =
-			meta.customSplashIcons[
-				Math.floor(Math.random() * meta.customSplashIcons.length)
-			];
-	}
-	await ctx.render("base", {
-		img: meta.bannerUrl,
-		title: meta.name || "Calckey",
-		instanceName: meta.name || "Calckey",
-		desc: meta.description,
-		icon: meta.iconUrl,
-		splashIcon: splashIconUrl,
-		themeColor: meta.themeColor,
-		randomMOTD: motd[Math.floor(Math.random() * motd.length)],
-		privateMode: meta.privateMode,
-	});
-	ctx.set("Cache-Control", "public, max-age=3");
-});
-
-// Register router
-app.use(router.routes());
-
-export default app;
diff --git a/packages/backend/src/server/web/manifest.json b/packages/backend/src/server/web/manifest.json
deleted file mode 100644
index 1e662fb202..0000000000
--- a/packages/backend/src/server/web/manifest.json
+++ /dev/null
@@ -1,74 +0,0 @@
-{
-	"short_name": "Calckey",
-	"name": "Calckey",
-	"description": "An open source, decentralized social media platform that's free forever!",
-	"start_url": "/",
-	"display": "standalone",
-	"background_color": "#1f1d2e",
-	"theme_color": "#31748f",
-	"orientation": "portrait-primary",
-	"icons": [
-		{
-			"src": "/static-assets/icons/192.png",
-			"sizes": "192x192",
-			"type": "image/png",
-			"purpose": "any"
-		},
-		{
-			"src": "/static-assets/icons/512.png",
-			"sizes": "512x512",
-			"type": "image/png",
-			"purpose": "any"
-		},
-		{
-			"src": "/static-assets/icons/maskable.png",
-			"sizes": "512x512",
-			"type": "image/png",
-			"purpose": "maskable"
-		},
-		{
-			"src": "/static-assets/icons/monochrome.png",
-			"sizes": "512x512",
-			"type": "image/png",
-			"purpose": "monochrome"
-		}
-	],
-	"share_target": {
-		"action": "/share/",
-		"params": {
-			"title": "title",
-			"text": "text",
-			"url": "url"
-		}
-	},
-	"screenshots" : [
-		{
-			"src": "/static-assets/screenshots/1.webp",
-			"sizes": "1195x579",
-			"type": "image/webp",
-			"platform": "narrow",
-			"label": "Profile page"
-		},
-		{
-			"src": "/static-assets/screenshots/2.webp",
-			"sizes": "1195x579",
-			"type": "image/webp",
-			"platform": "narrow",
-			"label": "Posts"
-		}
-	],
-	"shortcuts" : [
-		{
-			"name": "Notifications",
-			"short_name": "Notifs",
-			"url": "/my/notifications"
-		},
-		{
-			"name": "Chats",
-			"url": "/my/messaging"
-		}
-	],
-	"categories": [
-    "social"
-  ]
-}
diff --git a/packages/backend/src/server/web/manifest.ts b/packages/backend/src/server/web/manifest.ts
deleted file mode 100644
index 31acc42f6b..0000000000
--- a/packages/backend/src/server/web/manifest.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import type Koa from "koa";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import manifest from "./manifest.json" assert { type: "json" };
-
-export const manifestHandler = async (ctx: Koa.Context) => {
-	// TODO
-	//const res = structuredClone(manifest);
-	const res = JSON.parse(JSON.stringify(manifest));
-
-	const instance = await fetchMeta(true);
-
-	res.short_name = instance.name || "Calckey";
-	res.name = instance.name || "Calckey";
-	if (instance.themeColor) res.theme_color = instance.themeColor;
-
-	ctx.set("Cache-Control", "max-age=300");
-	ctx.body = res;
-};
diff --git a/packages/backend/src/server/web/style.css b/packages/backend/src/server/web/style.css
deleted file mode 100644
index ee42b9deba..0000000000
--- a/packages/backend/src/server/web/style.css
+++ /dev/null
@@ -1,127 +0,0 @@
-html, body {
-	background-color: var(--bg);
-	color: var(--fg);
-}
-
-#splash {
-	position: fixed;
-	z-index: 10000;
-	top: 0;
-	left: 0;
-	width: 100vw;
-	height: 100vh;
-	cursor: wait;
-	background-color: var(--bg);
-	opacity: 1;
-	transition: opacity 0.2s ease;
-}
-
-#splashIcon {
-	position: absolute;
-	top: 0;
-	right: 0;
-	bottom: 0;
-	left: 0;
-	margin: auto;
-	width: 64px;
-	height: 64px;
-	pointer-events: none;
-	animation-duration: 1s;
-	animation-iteration-count: infinite;
-	animation-name: tada;
-}
-
-#splashSpinner {
-	position: absolute;
-	top: 0;
-	right: 0;
-	bottom: 0;
-	left: 0;
-	margin: auto;
-	display: inline-block;
-	width: 28px;
-	height: 28px;
-	transform: translateY(110px);
-	display: none;
-	color: var(--accent);
-}
-#splashSpinner > .spinner {
-	position: absolute;
-	top: 0;
-	left: 0;
-	width: 28px;
-	height: 28px;
-	fill-rule: evenodd;
-	clip-rule: evenodd;
-	stroke-linecap: round;
-	stroke-linejoin: round;
-	stroke-miterlimit: 1.5;
-}
-#splashSpinner > .spinner.bg {
-	opacity: 0.275;
-}
-#splashSpinner > .spinner.fg {
-	animation: splashSpinner 0.5s linear infinite;
-}
-
-@keyframes splashSpinner {
-	0% {
-		transform: rotate(0deg);
-	}
-	100% {
-		transform: rotate(360deg);
-	}
-}
-
-@keyframes tada {
-	0% {
-		transform: scale3d(1, 1, 1);
-	}
-
-	10%,
-	20% {
-		transform: scale3d(0.9, 0.9, 0.9) rotate3d(0, 0, 1, -3deg);
-	}
-
-	30%,
-	50%,
-	70%,
-	90% {
-		transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg);
-	}
-
-	40%,
-	60%,
-	80% {
-		transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg);
-	}
-
-	100% {
-		transform: scale3d(1, 1, 1);
-	}
-}
-
-@media(prefers-reduced-motion) {
-	#splashSpinner {
-		display: block;
-	}
-
-	#splashIcon {
-		animation: none;
-	}
-}
-
-#splashText {
-	position: absolute;
-	top: 0;
-	right: 0;
-	bottom: 0;
-	left: 0;
-	margin: auto;
-	display: inline-block;
-	width: 70%;
-	height: 0;
-	text-align: center;
-	padding-top: 100px;
-	font-family: sans-serif;
-}
diff --git a/packages/backend/src/server/web/url-preview.ts b/packages/backend/src/server/web/url-preview.ts
deleted file mode 100644
index c9f3b6cac9..0000000000
--- a/packages/backend/src/server/web/url-preview.ts
+++ /dev/null
@@ -1,88 +0,0 @@
-import type Koa from "koa";
-import summaly from "summaly";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import Logger from "@/services/logger.js";
-import config from "@/config/index.js";
-import { query } from "@/prelude/url.js";
-import { getJson } from "@/misc/fetch.js";
-
-const logger = new Logger("url-preview");
-
-export const urlPreviewHandler = async (ctx: Koa.Context) => {
-	const url = ctx.query.url;
-	if (typeof url !== "string") {
-		ctx.status = 400;
-		return;
-	}
-
-	const lang = ctx.query.lang;
-	if (Array.isArray(lang)) {
-		ctx.status = 400;
-		return;
-	}
-
-	const meta = await fetchMeta();
-
-	logger.info(
-		meta.summalyProxy
-			? `(Proxy) Getting preview of ${url}@${lang} ...`
-			: `Getting preview of ${url}@${lang} ...`,
-	);
-
-	try {
-		const summary = meta.summalyProxy
-			? await getJson(
-					`${meta.summalyProxy}?${query({
-						url: url,
-						lang: lang ?? "en-US",
-					})}`,
-			  )
-			: await summaly.default(url, {
-					followRedirects: false,
-					lang: lang ?? "en-US",
-			  });
-
-		logger.succ(`Got preview of ${url}: ${summary.title}`);
-
-		if (
-			summary.url &&
-			!(summary.url.startsWith("http://") || summary.url.startsWith("https://"))
-		) {
-			throw new Error("unsupported schema included");
-		}
-
-		if (
-			summary.player?.url &&
-			!(
-				summary.player.url.startsWith("http://") ||
-				summary.player.url.startsWith("https://")
-			)
-		) {
-			throw new Error("unsupported schema included");
-		}
-
-		summary.icon = wrap(summary.icon);
-		summary.thumbnail = wrap(summary.thumbnail);
-
-		// Cache 7days
-		ctx.set("Cache-Control", "max-age=604800, immutable");
-
-		ctx.body = summary;
-	} catch (err) {
-		logger.warn(`Failed to get preview of ${url}: ${err}`);
-		ctx.status = 200;
-		ctx.set("Cache-Control", "max-age=86400, immutable");
-		ctx.body = "{}";
-	}
-};
-
-function wrap(url?: string): string | null {
-	return url != null
-		? url.match(/^https?:\/\//)
-			? `${config.url}/proxy/preview.webp?${query({
-					url,
-					preview: "1",
-			  })}`
-			: url
-		: null;
-}
diff --git a/packages/backend/src/server/web/views/base.pug b/packages/backend/src/server/web/views/base.pug
deleted file mode 100644
index b5841883bd..0000000000
--- a/packages/backend/src/server/web/views/base.pug
+++ /dev/null
@@ -1,96 +0,0 @@
-block vars
-
-block loadClientEntry
-	- const clientEntry = getClientEntry();
-
-doctype html
-
-//
-	-
-	   ___      _      _              
-	  / __\__ _| | ___| | _____ _   _ 
-	 / /  / _` | |/ __| |/ / _ \ | | |
-	/ /__| (_| | | (__|   <  __/ |_| |
-	\____/\__,_|_|\___|_|\_\___|\__, |
-	                            (___/
-
-		Thank you for using Calckey!
-		If you are reading this message... how about joining the development?
-		https://codeberg.org/calckey/calckey
-
-html
-
-	- var timestamp = Date.now();
-
-	head
-		meta(charset='utf-8')
-		meta(name='application-name' content='Calckey')
-		meta(name='referrer' content='origin')
-		meta(name='darkreader-lock' content='')
-		meta(name='theme-color' content= themeColor || '#31748f')
-		meta(name='theme-color-orig' content= themeColor || '#31748f')
-		meta(property='twitter:card' content='summary')
-		meta(property='og:site_name' content= instanceName || 'Calckey')
-		meta(name='viewport' content='width=device-width, initial-scale=1')
-		link(rel='icon' href= icon || `/favicon.ico?${ timestamp }`)
-		link(rel='apple-touch-icon' href= icon || `/apple-touch-icon.png?${ timestamp }`)
-		link(rel='manifest' href='/manifest.json')
-		link(rel='prefetch' href=`/static-assets/badges/info.png?${ timestamp }`)
-		link(rel='prefetch' href=`/static-assets/badges/not-found.png?${ timestamp }`)
-		link(rel='prefetch' href=`/static-assets/badges/error.png?${ timestamp }`)
-		link(rel='stylesheet' href=`/static-assets/instance.css?${ timestamp }`)
-		link(rel='modulepreload' href=`/assets/${clientEntry.file}`)
-
-		if Array.isArray(clientEntry.css)
-			each href in clientEntry.css
-				link(rel='stylesheet' href=`/assets/${href}`)
-
-		title
-			block title
-				= title || 'Calckey'
-
-		block desc
-			meta(name='description' content=desc || 'An open source, decentralized social media platform that\'s free forever! 🚀')
-
-		block meta
-			if privateMode
-				meta(name='robots' content='noindex')
-
-		block og
-			meta(property='og:title'       content=title || 'Calckey')
-			meta(property='og:description' content=desc || 'An open source, decentralized social media platform that\'s free forever! 🚀')
-			meta(property='og:image'       content=img)
-			meta(property='og:image:alt'   content=alt || 'Pfp')
-
-		style
-			include ../style.css
-
-		script.
-			var VERSION = "#{version}";
-			var CLIENT_ENTRY = "#{clientEntry.file}";
-
-		script
-			include ../boot.js
-
-	body
-		noscript: p
-			| JavaScriptを有効にしてください
-			br
-			| Please turn on your JavaScript
-		div#splash
-			img#splashIcon(src= splashIcon || `/static-assets/splash.png?${ timestamp }`)
-			span#splashText
-				block randomMOTD
-					= randomMOTD
-			div#splashSpinner
-				<svg class="spinner bg" viewBox="0 0 152 152" xmlns="http://www.w3.org/2000/svg">
-					<g transform="matrix(1,0,0,1,12,12)">
-						<circle cx="64" cy="64" r="64" style="fill:none;stroke:currentColor;stroke-width:24px;"/>
-					</g>
-				</svg>
-				<svg class="spinner fg" viewBox="0 0 152 152" xmlns="http://www.w3.org/2000/svg">
-					<g transform="matrix(1,0,0,1,12,12)">
-						<path d="M128,64C128,28.654 99.346,0 64,0C99.346,0 128,28.654 128,64Z" style="fill:none;stroke:currentColor;stroke-width:24px;"/>
-					</g>
-				</svg>
-		block content
diff --git a/packages/backend/src/server/web/views/bios.pug b/packages/backend/src/server/web/views/bios.pug
deleted file mode 100644
index 408ebb27b1..0000000000
--- a/packages/backend/src/server/web/views/bios.pug
+++ /dev/null
@@ -1,21 +0,0 @@
-doctype html
-
-html
-
-	head
-		meta(charset='utf-8')
-		meta(name='application-name' content='Calckey')
-		meta(name='viewport' content='width=device-width, initial-scale=1.0')
-		title Calckey Repair Tool
-		style
-			include ../bios.css
-		script
-			include ../bios.js
-
-	body
-		header
-			h1 Calckey Repair Tool v#{version}
-		main
-			div.tabs
-				button#ls Edit local storage
-			div#content
diff --git a/packages/backend/src/server/web/views/channel.pug b/packages/backend/src/server/web/views/channel.pug
deleted file mode 100644
index c4594b7666..0000000000
--- a/packages/backend/src/server/web/views/channel.pug
+++ /dev/null
@@ -1,20 +0,0 @@
-extends ./base
-
-block vars
-	- const title = privateMode ? instanceName : channel.name;
-	- const url = `${config.url}/channels/${channel.id}`;
-
-block title
-	= `${title} | ${instanceName}`
-
-block desc
-	unless privateMode
-		meta(name='description' content=channel.description)
-
-block og
-	unless privateMode
-		meta(property='og:type'        content='article')
-		meta(property='og:title'       content= title)
-		meta(property='og:description' content= channel.description)
-		meta(property='og:url'         content= url)
-		meta(property='og:image'       content= channel.bannerUrl)
diff --git a/packages/backend/src/server/web/views/cli.pug b/packages/backend/src/server/web/views/cli.pug
deleted file mode 100644
index 2abd5ae950..0000000000
--- a/packages/backend/src/server/web/views/cli.pug
+++ /dev/null
@@ -1,23 +0,0 @@
-doctype html
-
-html
-
-	head
-		meta(charset='utf-8')
-		meta(name='application-name' content='Calckey')
-		meta(name='viewport' content='width=device-width, initial-scale=1.0')
-		title Calckey Cli
-		style
-			include ../cli.css
-		script
-			include ../cli.js
-
-	body
-		header
-			h1 Calckey Simple Client v#{version}
-		main
-			div#form
-				textarea#text
-				br
-				button#submit Post
-			div#tl
diff --git a/packages/backend/src/server/web/views/clip.pug b/packages/backend/src/server/web/views/clip.pug
deleted file mode 100644
index 2432470c10..0000000000
--- a/packages/backend/src/server/web/views/clip.pug
+++ /dev/null
@@ -1,34 +0,0 @@
-extends ./base
-
-block vars
-	- const user = clip.user;
-	- const title = privateMode ? instanceName : clip.name;
-	- const url = `${config.url}/clips/${clip.id}`;
-
-block title
-	= `${title} | ${instanceName}`
-
-block desc
-	unless privateMode
-		meta(name='description' content= clip.description)
-
-block og
-	unless privateMode
-		meta(property='og:type'        content='article')
-		meta(property='og:title'       content= title)
-		meta(property='og:description' content= clip.description)
-		meta(property='og:url'         content= url)
-		meta(property='og:image'       content= avatarUrl)
-
-block meta
-	unless privateMode
-		if profile.noCrawle
-			meta(name='robots' content='noindex')
-
-		meta(name='misskey:user-username' content=user.username)
-		meta(name='misskey:user-id' content=user.id)
-		meta(name='misskey:clip-id' content=clip.id)
-
-		// todo
-		if user.twitter
-			meta(name='twitter:creator' content=`@${user.twitter.screenName}`)
diff --git a/packages/backend/src/server/web/views/flush.pug b/packages/backend/src/server/web/views/flush.pug
deleted file mode 100644
index c3de247270..0000000000
--- a/packages/backend/src/server/web/views/flush.pug
+++ /dev/null
@@ -1,71 +0,0 @@
-doctype html
-
-html
-	head
-		meta(charset='utf-8')
-		meta(name='application-name' content='Calckey')
-		meta(name='viewport' content='width=device-width, initial-scale=1.0')
-		title Flush Calckey
-		style.
-			* {
-				font-family: BIZ UDGothic, Roboto, HelveticaNeue, Arial, sans-serif;
-			}
-			body,
-			html {
-				background-color: #191724;
-				color: #e0def4;
-				justify-content: center;
-				margin: auto;
-				padding: 10px;
-				text-align: center;
-			}
-			a {
-				color: rgb(156, 207, 216);
-				text-decoration: none;
-			}
-
-	body
-		#msg
-		script.
-			const msg = document.getElementById('msg');
-			const successText = `\nSuccess Flush! <a href="/">Back to Calckey</a>\n成功しました。<a href="/">Calckeyを開き直してください。</a>`;
-
-			message('Start flushing.');
-
-			(async function() {
-				try {
-					localStorage.clear();
-					message('localStorage cleared.');
-
-					const idbPromises = ['MisskeyClient', 'keyval-store'].map((name, i, arr) => new Promise((res, rej) => {
-						const delidb = indexedDB.deleteDatabase(name);
-						delidb.onsuccess = () => res(message(`indexedDB "${name}" cleared. (${i + 1}/${arr.length})`));
-						delidb.onerror = e => rej(e)
-					}));
-
-					await Promise.all(idbPromises);
-
-					if (navigator.serviceWorker.controller) {
-						navigator.serviceWorker.controller.postMessage('clear');
-						await navigator.serviceWorker.getRegistrations()
-							.then(registrations => {
-								return Promise.all(registrations.map(registration => registration.unregister()));
-							})
-							.catch(e => { throw new Error(e) });
-					}
-
-					message(successText);
-				} catch (e) {
-					message(`\n${e}\n\nFlush Failed. <a href="/flush">Please retry.</a>\n失敗しました。<a href="/flush">もう一度試してみてください。</a>`);
-					message(`\nIf you retry more than 3 times, clear the browser cache or contact to instance admin.\n3回以上試しても失敗する場合、ブラウザのキャッシュを消去し、それでもだめならインスタンス管理者に連絡してみてください。\n`)
-
-					console.error(e);
-					setTimeout(() => {
-						location = '/';
-					}, 10000)
-				}
-			})();
-
-			function message(text) {
-				msg.insertAdjacentHTML('beforeend', `<p>[${(new Date()).toString()}] ${text.replace(/\n/g,'<br>')}</p>`)
-			}
diff --git a/packages/backend/src/server/web/views/gallery-post.pug b/packages/backend/src/server/web/views/gallery-post.pug
deleted file mode 100644
index 1b1c2fbfbd..0000000000
--- a/packages/backend/src/server/web/views/gallery-post.pug
+++ /dev/null
@@ -1,36 +0,0 @@
-extends ./base
-
-block vars
-	- const user = post.user;
-	- const title = privateMode ? instanceName : post.title;
-	- const url = `${config.url}/gallery/${post.id}`;
-
-block title
-	= `${title} | ${instanceName}`
-
-block desc
-	unless privateMode
-		meta(name='description' content= post.description)
-
-block og
-	unless privateMode
-		meta(property='og:type'        content='article')
-		meta(property='og:title'       content= title)
-		meta(property='og:description' content= post.description)
-		meta(property='og:url'         content= url)
-		meta(property='og:image'       content= post.files[0].thumbnailUrl)
-
-block meta
-	unless privateMode
-		if user.host || profile.noCrawle
-			meta(name='robots' content='noindex')
-
-		meta(name='misskey:user-username' content=user.username)
-		meta(name='misskey:user-id' content=user.id)
-
-		// todo
-		if user.twitter
-			meta(name='twitter:creator' content=`@${user.twitter.screenName}`)
-
-		if !user.host
-			link(rel='alternate' href=url type='application/activity+json')
diff --git a/packages/backend/src/server/web/views/info-card.pug b/packages/backend/src/server/web/views/info-card.pug
deleted file mode 100644
index be52d0c39f..0000000000
--- a/packages/backend/src/server/web/views/info-card.pug
+++ /dev/null
@@ -1,50 +0,0 @@
-doctype html
-
-html
-
-	head
-		meta(charset='utf-8')
-		meta(name='application-name' content='Calckey')
-		title= meta.name || host
-		style.
-			html, body {
-				margin: 0;
-				padding: 0;
-				min-height: 100vh;
-				background: #fff;
-			}
-
-			#a {
-				display: block;
-			}
-
-			#banner {
-				background-size: cover;
-				background-position: center center;
-			}
-
-			#title {
-				display: inline-block;
-				margin: 24px;
-				padding: 0.5em 0.8em;
-				color: #fff;
-				background: rgba(0, 0, 0, 0.5);
-				font-weight: bold;
-				font-size: 1.3em;
-			}
-
-			#content {
-				overflow: auto;
-				color: #353c3e;
-			}
-
-			#description {
-				margin: 24px;
-			}
-
-	body
-		a#a(href=`https://${host}` target="_blank")
-			header#banner(style=`background-image: url(${meta.bannerUrl})`)
-				div#title= meta.name || host
-		div#content
-			div#description= meta.description
diff --git a/packages/backend/src/server/web/views/note.pug b/packages/backend/src/server/web/views/note.pug
deleted file mode 100644
index 476d42d9e8..0000000000
--- a/packages/backend/src/server/web/views/note.pug
+++ /dev/null
@@ -1,56 +0,0 @@
-extends ./base
-
-block vars
-	- const user = note.user;
-	- const title = privateMode ? instanceName : (user.name ? `${user.name} (@${user.username}${user.host ? `@${user.host}` : ''})` : `@${user.username}`);
-	- const url = `${config.url}/notes/${note.id}`;
-	- const isRenote = note.renote && note.text == null && note.fileIds.length == 0 && note.poll == null;
-	- const isImage = note.files.length !== 0 && note.files[0].type.startsWith('image');
-	- const isVideo = note.files.length !== 0 && note.files[0].type.startsWith('video');
-	- const imageUrl = isImage ? note.files[0].url : isVideo ? note.files[0].thumbnailUrl : avatarUrl;
-
-block title
-	= `${title} | ${instanceName}`
-
-block desc
-	unless privateMode
-		meta(name='description' content= summary)
-
-block og
-	unless privateMode
-		meta(property='og:type'        content='article')
-		meta(property='og:title'       content= title)
-		meta(property='og:description' content= summary)
-		meta(property='og:url'         content= url)
-		meta(property='og:image'       content= imageUrl)
-		if isImage && !note.files[0].isSensitive
-			meta(property='og:image:width'     content=note.files[0].properties.width)
-			meta(property='og:image:height'    content=note.files[0].properties.height)
-			meta(property='og:image:type'      content=note.files[0].type)
-			meta(property='twitter:card'       content="summary_large_image")
-		if isVideo
-			meta(property='og:video:type'      content=note.files[0].type)
-			meta(property='og:video'           content=note.files[0].url)
-
-block meta
-	unless privateMode
-		if user.host || isRenote || profile.noCrawle
-			meta(name='robots' content='noindex')
-
-		meta(name='misskey:user-username' content=user.username)
-		meta(name='misskey:user-id' content=user.id)
-		meta(name='misskey:note-id' content=note.id)
-
-		// todo
-		if user.twitter
-			meta(name='twitter:creator' content=`@${user.twitter.screenName}`)
-
-		if note.prev
-			link(rel='prev' href=`${config.url}/notes/${note.prev}`)
-		if note.next
-			link(rel='next' href=`${config.url}/notes/${note.next}`)
-
-		if !user.host
-			link(rel='alternate' href=url type='application/activity+json')
-		if note.uri
-			link(rel='alternate' href=note.uri type='application/activity+json')
diff --git a/packages/backend/src/server/web/views/page.pug b/packages/backend/src/server/web/views/page.pug
deleted file mode 100644
index 1095282131..0000000000
--- a/packages/backend/src/server/web/views/page.pug
+++ /dev/null
@@ -1,34 +0,0 @@
-extends ./base
-
-block vars
-	- const user = page.user;
-	- const title = privateMode ? instanceName : page.title;
-	- const url = `${config.url}/@${user.username}/${page.name}`;
-
-block title
-	= `${title} | ${instanceName}`
-
-block desc
-	unless privateMode
-		meta(name='description' content= page.summary)
-
-block og
-	unless privateMode
-		meta(property='og:type'        content='article')
-		meta(property='og:title'       content= title)
-		meta(property='og:description' content= page.summary)
-		meta(property='og:url'         content= url)
-		meta(property='og:image'       content= page.eyeCatchingImage ? page.eyeCatchingImage.thumbnailUrl : avatarUrl)
-
-block meta
-	unless privateMode
-		if profile.noCrawle
-			meta(name='robots' content='noindex')
-
-		meta(name='misskey:user-username' content=user.username)
-		meta(name='misskey:user-id' content=user.id)
-		meta(name='misskey:page-id' content=page.id)
-
-		// todo
-		if user.twitter
-			meta(name='twitter:creator' content=`@${user.twitter.screenName}`)
diff --git a/packages/backend/src/server/web/views/user.pug b/packages/backend/src/server/web/views/user.pug
deleted file mode 100644
index cc14dedb3a..0000000000
--- a/packages/backend/src/server/web/views/user.pug
+++ /dev/null
@@ -1,42 +0,0 @@
-extends ./base
-
-block vars
-	- const title = privateMode ? instanceName : (user.name ? `${user.name} (@${user.username})` : `@${user.username}`);
-	- const url = `${config.url}/@${(user.host ? `${user.username}@${user.host}` : user.username)}`;
-
-block title
-	= `${title} | ${instanceName}`
-
-block desc
-	unless privateMode
-		meta(name='description' content= profile.description)
-
-block og
-	unless privateMode
-		meta(property='og:type'        content='blog')
-		meta(property='og:title'       content= title)
-		meta(property='og:description' content= profile.description)
-		meta(property='og:url'         content= url)
-		meta(property='og:image'       content= avatarUrl)
-
-block meta
-	unless privateMode
-		if user.host || profile.noCrawle
-			meta(name='robots' content='noindex')
-
-		meta(name='misskey:user-username' content=user.username)
-		meta(name='misskey:user-id' content=user.id)
-
-		if profile.twitter
-			meta(name='twitter:creator' content=`@${profile.twitter.screenName}`)
-
-		if !sub
-			if !user.host
-				link(rel='alternate' href=`${config.url}/users/${user.id}` type='application/activity+json')
-			if user.uri
-				link(rel='alternate' href=user.uri type='application/activity+json')
-			if profile.url
-				link(rel='alternate' href=profile.url type='text/html')
-
-		each m in me
-			link(rel='me' href=`${m}`)
diff --git a/packages/backend/src/server/well-known.ts b/packages/backend/src/server/well-known.ts
deleted file mode 100644
index 5af3b2c84b..0000000000
--- a/packages/backend/src/server/well-known.ts
+++ /dev/null
@@ -1,191 +0,0 @@
-import Router from "@koa/router";
-
-import config from "@/config/index.js";
-import * as Acct from "@/misc/acct.js";
-import { links } from "./nodeinfo.js";
-import { escapeAttribute, escapeValue } from "@/prelude/xml.js";
-import { Users } from "@/models/index.js";
-import type { User } from "@/models/entities/user.js";
-import type { FindOptionsWhere } from "typeorm";
-import { IsNull } from "typeorm";
-
-// Init router
-const router = new Router();
-
-const XRD = (
-	...x: {
-		element: string;
-		value?: string;
-		attributes?: Record<string, string>;
-	}[]
-) =>
-	`<?xml version="1.0" encoding="UTF-8"?><XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">${x
-		.map(
-			({ element, value, attributes }) =>
-				`<${Object.entries(
-					(typeof attributes === "object" && attributes) || {},
-				).reduce((a, [k, v]) => `${a} ${k}="${escapeAttribute(v)}"`, element)}${
-					typeof value === "string" ? `>${escapeValue(value)}</${element}` : "/"
-				}>`,
-		)
-		.reduce((a, c) => a + c, "")}</XRD>`;
-
-const allPath = "/.well-known/(.*)";
-const webFingerPath = "/.well-known/webfinger";
-const jrd = "application/jrd+json";
-const xrd = "application/xrd+xml";
-
-router.use(allPath, async (ctx, next) => {
-	ctx.set({
-		"Access-Control-Allow-Headers": "Accept",
-		"Access-Control-Allow-Methods": "GET, OPTIONS",
-		"Access-Control-Allow-Origin": "*",
-		"Access-Control-Expose-Headers": "Vary",
-	});
-	await next();
-});
-
-router.options(allPath, async (ctx) => {
-	ctx.status = 204;
-});
-
-router.get("/.well-known/host-meta", async (ctx) => {
-	ctx.set("Content-Type", xrd);
-	ctx.body = XRD({
-		element: "Link",
-		attributes: {
-			rel: "lrdd",
-			type: xrd,
-			template: `${config.url}${webFingerPath}?resource={uri}`,
-		},
-	});
-});
-
-router.get("/.well-known/host-meta.json", async (ctx) => {
-	ctx.set("Content-Type", jrd);
-	ctx.body = {
-		links: [
-			{
-				rel: "lrdd",
-				type: jrd,
-				template: `${config.url}${webFingerPath}?resource={uri}`,
-			},
-		],
-	};
-});
-
-if (config.twa != null) {
-	router.get("/.well-known/assetlinks.json", async (ctx) => {
-		ctx.set("Content-Type", "application/json");
-		ctx.body = [
-			{
-				relation: ["delegate_permission/common.handle_all_urls"],
-				target: {
-					namespace: config.twa.nameSpace,
-					package_name: config.twa.packageName,
-					sha256_cert_fingerprints: config.twa.sha256CertFingerprints,
-				},
-			},
-		];
-	});
-}
-
-router.get("/.well-known/nodeinfo", async (ctx) => {
-	ctx.body = { links };
-});
-
-/* TODO
-router.get('/.well-known/change-password', async ctx => {
-});
-*/
-
-router.get(webFingerPath, async (ctx) => {
-	const fromId = (id: User["id"]): FindOptionsWhere<User> => ({
-		id,
-		host: IsNull(),
-		isSuspended: false,
-	});
-
-	const generateQuery = (resource: string): FindOptionsWhere<User> | number =>
-		resource.startsWith(`${config.url.toLowerCase()}/users/`)
-			? fromId(resource.split("/").pop()!)
-			: fromAcct(
-					Acct.parse(
-						resource.startsWith(`${config.url.toLowerCase()}/@`)
-							? resource.split("/").pop()!
-							: resource.startsWith("acct:")
-							? resource.slice("acct:".length)
-							: resource,
-					),
-			  );
-
-	const fromAcct = (acct: Acct.Acct): FindOptionsWhere<User> | number =>
-		!acct.host || acct.host === config.host.toLowerCase()
-			? {
-					usernameLower: acct.username,
-					host: IsNull(),
-					isSuspended: false,
-			  }
-			: 422;
-
-	if (typeof ctx.query.resource !== "string") {
-		ctx.status = 400;
-		return;
-	}
-
-	const query = generateQuery(ctx.query.resource.toLowerCase());
-
-	if (typeof query === "number") {
-		ctx.status = query;
-		return;
-	}
-
-	const user = await Users.findOneBy(query);
-
-	if (user == null) {
-		ctx.status = 404;
-		return;
-	}
-
-	const subject = `acct:${user.username}@${config.host}`;
-	const self = {
-		rel: "self",
-		type: "application/activity+json",
-		href: `${config.url}/users/${user.id}`,
-	};
-	const profilePage = {
-		rel: "http://webfinger.net/rel/profile-page",
-		type: "text/html",
-		href: `${config.url}/@${user.username}`,
-	};
-	const subscribe = {
-		rel: "http://ostatus.org/schema/1.0/subscribe",
-		template: `${config.url}/authorize-follow?acct={uri}`,
-	};
-
-	if (ctx.accepts(jrd, xrd) === xrd) {
-		ctx.body = XRD(
-			{ element: "Subject", value: subject },
-			{ element: "Link", attributes: self },
-			{ element: "Link", attributes: profilePage },
-			{ element: "Link", attributes: subscribe },
-		);
-		ctx.type = xrd;
-	} else {
-		ctx.body = {
-			subject,
-			links: [self, profilePage, subscribe],
-		};
-		ctx.type = jrd;
-	}
-
-	ctx.vary("Accept");
-	ctx.set("Cache-Control", "public, max-age=180");
-});
-
-// Return 404 for other .well-known
-router.all(allPath, async (ctx) => {
-	ctx.status = 404;
-});
-
-export default router;
diff --git a/packages/backend/src/services/add-note-to-antenna.ts b/packages/backend/src/services/add-note-to-antenna.ts
deleted file mode 100644
index 38979acb40..0000000000
--- a/packages/backend/src/services/add-note-to-antenna.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-import type { Antenna } from "@/models/entities/antenna.js";
-import type { Note } from "@/models/entities/note.js";
-import { AntennaNotes, Mutings, Notes } from "@/models/index.js";
-import { genId } from "@/misc/gen-id.js";
-import { isUserRelated } from "@/misc/is-user-related.js";
-import { publishAntennaStream, publishMainStream } from "@/services/stream.js";
-import type { User } from "@/models/entities/user.js";
-
-export async function addNoteToAntenna(
-	antenna: Antenna,
-	note: Note,
-	noteUser: { id: User["id"] },
-) {
-	// 通知しない設定になっているか、自分自身の投稿なら既読にする
-	const read = !antenna.notify || antenna.userId === noteUser.id;
-
-	AntennaNotes.insert({
-		id: genId(),
-		antennaId: antenna.id,
-		noteId: note.id,
-		read: read,
-	});
-
-	publishAntennaStream(antenna.id, "note", note);
-
-	if (!read) {
-		const mutings = await Mutings.find({
-			where: {
-				muterId: antenna.userId,
-			},
-			select: ["muteeId"],
-		});
-
-		// Copy
-		const _note: Note = {
-			...note,
-		};
-
-		if (note.replyId != null) {
-			_note.reply = await Notes.findOneByOrFail({ id: note.replyId });
-		}
-		if (note.renoteId != null) {
-			_note.renote = await Notes.findOneByOrFail({ id: note.renoteId });
-		}
-
-		if (isUserRelated(_note, new Set<string>(mutings.map((x) => x.muteeId)))) {
-			return;
-		}
-
-		// 2秒経っても既読にならなかったら通知
-		setTimeout(async () => {
-			const unread = await AntennaNotes.findOneBy({
-				antennaId: antenna.id,
-				read: false,
-			});
-			if (unread) {
-				publishMainStream(antenna.userId, "unreadAntenna", antenna);
-			}
-		}, 2000);
-	}
-}
diff --git a/packages/backend/src/services/blocking/create.ts b/packages/backend/src/services/blocking/create.ts
deleted file mode 100644
index 60bd6e9431..0000000000
--- a/packages/backend/src/services/blocking/create.ts
+++ /dev/null
@@ -1,165 +0,0 @@
-import { publishMainStream, publishUserEvent } from "@/services/stream.js";
-import { renderActivity } from "@/remote/activitypub/renderer/index.js";
-import renderFollow from "@/remote/activitypub/renderer/follow.js";
-import renderUndo from "@/remote/activitypub/renderer/undo.js";
-import { renderBlock } from "@/remote/activitypub/renderer/block.js";
-import { deliver } from "@/queue/index.js";
-import renderReject from "@/remote/activitypub/renderer/reject.js";
-import type { Blocking } from "@/models/entities/blocking.js";
-import type { User } from "@/models/entities/user.js";
-import {
-	Blockings,
-	Users,
-	FollowRequests,
-	Followings,
-	UserListJoinings,
-	UserLists,
-} from "@/models/index.js";
-import { perUserFollowingChart } from "@/services/chart/index.js";
-import { genId } from "@/misc/gen-id.js";
-import { IdentifiableError } from "@/misc/identifiable-error.js";
-import { getActiveWebhooks } from "@/misc/webhook-cache.js";
-import { webhookDeliver } from "@/queue/index.js";
-
-export default async function (blocker: User, blockee: User) {
-	await Promise.all([
-		cancelRequest(blocker, blockee),
-		cancelRequest(blockee, blocker),
-		unFollow(blocker, blockee),
-		unFollow(blockee, blocker),
-		removeFromList(blockee, blocker),
-	]);
-
-	const blocking = {
-		id: genId(),
-		createdAt: new Date(),
-		blocker,
-		blockerId: blocker.id,
-		blockee,
-		blockeeId: blockee.id,
-	} as Blocking;
-
-	await Blockings.insert(blocking);
-
-	if (Users.isLocalUser(blocker) && Users.isRemoteUser(blockee)) {
-		const content = renderActivity(renderBlock(blocking));
-		deliver(blocker, content, blockee.inbox);
-	}
-}
-
-async function cancelRequest(follower: User, followee: User) {
-	const request = await FollowRequests.findOneBy({
-		followeeId: followee.id,
-		followerId: follower.id,
-	});
-
-	if (request == null) {
-		return;
-	}
-
-	await FollowRequests.delete({
-		followeeId: followee.id,
-		followerId: follower.id,
-	});
-
-	if (Users.isLocalUser(followee)) {
-		Users.pack(followee, followee, {
-			detail: true,
-		}).then((packed) => publishMainStream(followee.id, "meUpdated", packed));
-	}
-
-	if (Users.isLocalUser(follower)) {
-		Users.pack(followee, follower, {
-			detail: true,
-		}).then(async (packed) => {
-			publishUserEvent(follower.id, "unfollow", packed);
-			publishMainStream(follower.id, "unfollow", packed);
-
-			const webhooks = (await getActiveWebhooks()).filter(
-				(x) => x.userId === follower.id && x.on.includes("unfollow"),
-			);
-			for (const webhook of webhooks) {
-				webhookDeliver(webhook, "unfollow", {
-					user: packed,
-				});
-			}
-		});
-	}
-
-	// リモートにフォローリクエストをしていたらUndoFollow送信
-	if (Users.isLocalUser(follower) && Users.isRemoteUser(followee)) {
-		const content = renderActivity(
-			renderUndo(renderFollow(follower, followee), follower),
-		);
-		deliver(follower, content, followee.inbox);
-	}
-
-	// リモートからフォローリクエストを受けていたらReject送信
-	if (Users.isRemoteUser(follower) && Users.isLocalUser(followee)) {
-		const content = renderActivity(
-			renderReject(
-				renderFollow(follower, followee, request.requestId!),
-				followee,
-			),
-		);
-		deliver(followee, content, follower.inbox);
-	}
-}
-
-async function unFollow(follower: User, followee: User) {
-	const following = await Followings.findOneBy({
-		followerId: follower.id,
-		followeeId: followee.id,
-	});
-
-	if (following == null) {
-		return;
-	}
-
-	await Promise.all([
-		Followings.delete(following.id),
-		Users.decrement({ id: follower.id }, "followingCount", 1),
-		Users.decrement({ id: followee.id }, "followersCount", 1),
-		perUserFollowingChart.update(follower, followee, false),
-	]);
-
-	// Publish unfollow event
-	if (Users.isLocalUser(follower)) {
-		Users.pack(followee, follower, {
-			detail: true,
-		}).then(async (packed) => {
-			publishUserEvent(follower.id, "unfollow", packed);
-			publishMainStream(follower.id, "unfollow", packed);
-
-			const webhooks = (await getActiveWebhooks()).filter(
-				(x) => x.userId === follower.id && x.on.includes("unfollow"),
-			);
-			for (const webhook of webhooks) {
-				webhookDeliver(webhook, "unfollow", {
-					user: packed,
-				});
-			}
-		});
-	}
-
-	// リモートにフォローをしていたらUndoFollow送信
-	if (Users.isLocalUser(follower) && Users.isRemoteUser(followee)) {
-		const content = renderActivity(
-			renderUndo(renderFollow(follower, followee), follower),
-		);
-		deliver(follower, content, followee.inbox);
-	}
-}
-
-async function removeFromList(listOwner: User, user: User) {
-	const userLists = await UserLists.findBy({
-		userId: listOwner.id,
-	});
-
-	for (const userList of userLists) {
-		await UserListJoinings.delete({
-			userListId: userList.id,
-			userId: user.id,
-		});
-	}
-}
diff --git a/packages/backend/src/services/blocking/delete.ts b/packages/backend/src/services/blocking/delete.ts
deleted file mode 100644
index 67f1e76f0e..0000000000
--- a/packages/backend/src/services/blocking/delete.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import { renderActivity } from "@/remote/activitypub/renderer/index.js";
-import { renderBlock } from "@/remote/activitypub/renderer/block.js";
-import renderUndo from "@/remote/activitypub/renderer/undo.js";
-import { deliver } from "@/queue/index.js";
-import Logger from "../logger.js";
-import type { CacheableUser } from "@/models/entities/user.js";
-import { User } from "@/models/entities/user.js";
-import { Blockings, Users } from "@/models/index.js";
-
-const logger = new Logger("blocking/delete");
-
-export default async function (blocker: CacheableUser, blockee: CacheableUser) {
-	const blocking = await Blockings.findOneBy({
-		blockerId: blocker.id,
-		blockeeId: blockee.id,
-	});
-
-	if (blocking == null) {
-		logger.warn(
-			"ブロック解除がリクエストされましたがブロックしていませんでした",
-		);
-		return;
-	}
-
-	// Since we already have the blocker and blockee, we do not need to fetch
-	// them in the query above and can just manually insert them here.
-	blocking.blocker = blocker;
-	blocking.blockee = blockee;
-
-	Blockings.delete(blocking.id);
-
-	// deliver if remote bloking
-	if (Users.isLocalUser(blocker) && Users.isRemoteUser(blockee)) {
-		const content = renderActivity(renderUndo(renderBlock(blocking), blocker));
-		deliver(blocker, content, blockee.inbox);
-	}
-}
diff --git a/packages/backend/src/services/chart/charts/active-users.ts b/packages/backend/src/services/chart/charts/active-users.ts
deleted file mode 100644
index 7a0c45cfaf..0000000000
--- a/packages/backend/src/services/chart/charts/active-users.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import type { KVs } from "../core.js";
-import Chart from "../core.js";
-import type { User } from "@/models/entities/user.js";
-import { Users } from "@/models/index.js";
-import { name, schema } from "./entities/active-users.js";
-
-const week = 1000 * 60 * 60 * 24 * 7;
-const month = 1000 * 60 * 60 * 24 * 30;
-const year = 1000 * 60 * 60 * 24 * 365;
-
-/**
- * アクティブユーザーに関するチャート
- */
-
-export default class ActiveUsersChart extends Chart<typeof schema> {
-	constructor() {
-		super(name, schema);
-	}
-
-	protected async tickMajor(): Promise<Partial<KVs<typeof schema>>> {
-		return {};
-	}
-
-	protected async tickMinor(): Promise<Partial<KVs<typeof schema>>> {
-		return {};
-	}
-
-	public async read(user: {
-		id: User["id"];
-		host: null;
-		createdAt: User["createdAt"];
-	}): Promise<void> {
-		await this.commit({
-			read: [user.id],
-			registeredWithinWeek:
-				Date.now() - user.createdAt.getTime() < week ? [user.id] : [],
-			registeredWithinMonth:
-				Date.now() - user.createdAt.getTime() < month ? [user.id] : [],
-			registeredWithinYear:
-				Date.now() - user.createdAt.getTime() < year ? [user.id] : [],
-			registeredOutsideWeek:
-				Date.now() - user.createdAt.getTime() > week ? [user.id] : [],
-			registeredOutsideMonth:
-				Date.now() - user.createdAt.getTime() > month ? [user.id] : [],
-			registeredOutsideYear:
-				Date.now() - user.createdAt.getTime() > year ? [user.id] : [],
-		});
-	}
-
-	public async write(user: {
-		id: User["id"];
-		host: null;
-		createdAt: User["createdAt"];
-	}): Promise<void> {
-		await this.commit({
-			write: [user.id],
-		});
-	}
-}
diff --git a/packages/backend/src/services/chart/charts/ap-request.ts b/packages/backend/src/services/chart/charts/ap-request.ts
deleted file mode 100644
index 6e56be0b36..0000000000
--- a/packages/backend/src/services/chart/charts/ap-request.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-import type { KVs } from "../core.js";
-import Chart from "../core.js";
-import { name, schema } from "./entities/ap-request.js";
-
-/**
- * Chart about ActivityPub requests
- */
-
-export default class ApRequestChart extends Chart<typeof schema> {
-	constructor() {
-		super(name, schema);
-	}
-
-	protected async tickMajor(): Promise<Partial<KVs<typeof schema>>> {
-		return {};
-	}
-
-	protected async tickMinor(): Promise<Partial<KVs<typeof schema>>> {
-		return {};
-	}
-
-	public async deliverSucc(): Promise<void> {
-		await this.commit({
-			deliverSucceeded: 1,
-		});
-	}
-
-	public async deliverFail(): Promise<void> {
-		await this.commit({
-			deliverFailed: 1,
-		});
-	}
-
-	public async inbox(): Promise<void> {
-		await this.commit({
-			inboxReceived: 1,
-		});
-	}
-}
diff --git a/packages/backend/src/services/chart/charts/drive.ts b/packages/backend/src/services/chart/charts/drive.ts
deleted file mode 100644
index 9793ff79dc..0000000000
--- a/packages/backend/src/services/chart/charts/drive.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import type { KVs } from "../core.js";
-import Chart from "../core.js";
-import { DriveFiles } from "@/models/index.js";
-import { Not, IsNull } from "typeorm";
-import type { DriveFile } from "@/models/entities/drive-file.js";
-import { name, schema } from "./entities/drive.js";
-
-/**
- * ドライブに関するチャート
- */
-
-export default class DriveChart extends Chart<typeof schema> {
-	constructor() {
-		super(name, schema);
-	}
-
-	protected async tickMajor(): Promise<Partial<KVs<typeof schema>>> {
-		return {};
-	}
-
-	protected async tickMinor(): Promise<Partial<KVs<typeof schema>>> {
-		return {};
-	}
-
-	public async update(file: DriveFile, isAdditional: boolean): Promise<void> {
-		const fileSizeKb = file.size / 1000;
-		await this.commit(
-			file.userHost === null
-				? {
-						"local.incCount": isAdditional ? 1 : 0,
-						"local.incSize": isAdditional ? fileSizeKb : 0,
-						"local.decCount": isAdditional ? 0 : 1,
-						"local.decSize": isAdditional ? 0 : fileSizeKb,
-				  }
-				: {
-						"remote.incCount": isAdditional ? 1 : 0,
-						"remote.incSize": isAdditional ? fileSizeKb : 0,
-						"remote.decCount": isAdditional ? 0 : 1,
-						"remote.decSize": isAdditional ? 0 : fileSizeKb,
-				  },
-		);
-	}
-}
diff --git a/packages/backend/src/services/chart/charts/entities/active-users.ts b/packages/backend/src/services/chart/charts/entities/active-users.ts
deleted file mode 100644
index 4e5fa37a27..0000000000
--- a/packages/backend/src/services/chart/charts/entities/active-users.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import Chart from "../../core.js";
-
-export const name = "activeUsers";
-
-export const schema = {
-	readWrite: { intersection: ["read", "write"], range: "small" },
-	read: { uniqueIncrement: true, range: "small" },
-	write: { uniqueIncrement: true, range: "small" },
-	registeredWithinWeek: { uniqueIncrement: true, range: "small" },
-	registeredWithinMonth: { uniqueIncrement: true, range: "small" },
-	registeredWithinYear: { uniqueIncrement: true, range: "small" },
-	registeredOutsideWeek: { uniqueIncrement: true, range: "small" },
-	registeredOutsideMonth: { uniqueIncrement: true, range: "small" },
-	registeredOutsideYear: { uniqueIncrement: true, range: "small" },
-} as const;
-
-export const entity = Chart.schemaToEntity(name, schema);
diff --git a/packages/backend/src/services/chart/charts/entities/ap-request.ts b/packages/backend/src/services/chart/charts/entities/ap-request.ts
deleted file mode 100644
index eb02201742..0000000000
--- a/packages/backend/src/services/chart/charts/entities/ap-request.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import Chart from "../../core.js";
-
-export const name = "apRequest";
-
-export const schema = {
-	deliverFailed: {},
-	deliverSucceeded: {},
-	inboxReceived: {},
-} as const;
-
-export const entity = Chart.schemaToEntity(name, schema);
diff --git a/packages/backend/src/services/chart/charts/entities/drive.ts b/packages/backend/src/services/chart/charts/entities/drive.ts
deleted file mode 100644
index 0280ec655f..0000000000
--- a/packages/backend/src/services/chart/charts/entities/drive.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import Chart from "../../core.js";
-
-export const name = "drive";
-
-export const schema = {
-	"local.incCount": {},
-	"local.incSize": {}, // in kilobyte
-	"local.decCount": {},
-	"local.decSize": {}, // in kilobyte
-	"remote.incCount": {},
-	"remote.incSize": {}, // in kilobyte
-	"remote.decCount": {},
-	"remote.decSize": {}, // in kilobyte
-} as const;
-
-export const entity = Chart.schemaToEntity(name, schema);
diff --git a/packages/backend/src/services/chart/charts/entities/federation.ts b/packages/backend/src/services/chart/charts/entities/federation.ts
deleted file mode 100644
index b77e020961..0000000000
--- a/packages/backend/src/services/chart/charts/entities/federation.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import Chart from "../../core.js";
-
-export const name = "federation";
-
-export const schema = {
-	deliveredInstances: { uniqueIncrement: true, range: "small" },
-	inboxInstances: { uniqueIncrement: true, range: "small" },
-	stalled: { uniqueIncrement: true, range: "small" },
-	sub: { accumulate: true, range: "small" },
-	pub: { accumulate: true, range: "small" },
-	pubsub: { accumulate: true, range: "small" },
-	subActive: { accumulate: true, range: "small" },
-	pubActive: { accumulate: true, range: "small" },
-} as const;
-
-export const entity = Chart.schemaToEntity(name, schema);
diff --git a/packages/backend/src/services/chart/charts/entities/hashtag.ts b/packages/backend/src/services/chart/charts/entities/hashtag.ts
deleted file mode 100644
index 77964b4ca1..0000000000
--- a/packages/backend/src/services/chart/charts/entities/hashtag.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import Chart from "../../core.js";
-
-export const name = "hashtag";
-
-export const schema = {
-	"local.users": { uniqueIncrement: true },
-	"remote.users": { uniqueIncrement: true },
-} as const;
-
-export const entity = Chart.schemaToEntity(name, schema, true);
diff --git a/packages/backend/src/services/chart/charts/entities/instance.ts b/packages/backend/src/services/chart/charts/entities/instance.ts
deleted file mode 100644
index a75dea475b..0000000000
--- a/packages/backend/src/services/chart/charts/entities/instance.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import Chart from "../../core.js";
-
-export const name = "instance";
-
-export const schema = {
-	"requests.failed": { range: "small" },
-	"requests.succeeded": { range: "small" },
-	"requests.received": { range: "small" },
-	"notes.total": { accumulate: true },
-	"notes.inc": {},
-	"notes.dec": {},
-	"notes.diffs.normal": {},
-	"notes.diffs.reply": {},
-	"notes.diffs.renote": {},
-	"notes.diffs.withFile": {},
-	"users.total": { accumulate: true },
-	"users.inc": { range: "small" },
-	"users.dec": { range: "small" },
-	"following.total": { accumulate: true },
-	"following.inc": { range: "small" },
-	"following.dec": { range: "small" },
-	"followers.total": { accumulate: true },
-	"followers.inc": { range: "small" },
-	"followers.dec": { range: "small" },
-	"drive.totalFiles": { accumulate: true },
-	"drive.incFiles": {},
-	"drive.decFiles": {},
-	"drive.incUsage": {}, // in kilobyte
-	"drive.decUsage": {}, // in kilobyte
-} as const;
-
-export const entity = Chart.schemaToEntity(name, schema, true);
diff --git a/packages/backend/src/services/chart/charts/entities/notes.ts b/packages/backend/src/services/chart/charts/entities/notes.ts
deleted file mode 100644
index 04e75a2f29..0000000000
--- a/packages/backend/src/services/chart/charts/entities/notes.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import Chart from "../../core.js";
-
-export const name = "notes";
-
-export const schema = {
-	"local.total": { accumulate: true },
-	"local.inc": {},
-	"local.dec": {},
-	"local.diffs.normal": {},
-	"local.diffs.reply": {},
-	"local.diffs.renote": {},
-	"local.diffs.withFile": {},
-	"remote.total": { accumulate: true },
-	"remote.inc": {},
-	"remote.dec": {},
-	"remote.diffs.normal": {},
-	"remote.diffs.reply": {},
-	"remote.diffs.renote": {},
-	"remote.diffs.withFile": {},
-} as const;
-
-export const entity = Chart.schemaToEntity(name, schema);
diff --git a/packages/backend/src/services/chart/charts/entities/per-user-drive.ts b/packages/backend/src/services/chart/charts/entities/per-user-drive.ts
deleted file mode 100644
index d9dcd3d35e..0000000000
--- a/packages/backend/src/services/chart/charts/entities/per-user-drive.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import Chart from "../../core.js";
-
-export const name = "perUserDrive";
-
-export const schema = {
-	totalCount: { accumulate: true },
-	totalSize: { accumulate: true }, // in kilobyte
-	incCount: { range: "small" },
-	incSize: {}, // in kilobyte
-	decCount: { range: "small" },
-	decSize: {}, // in kilobyte
-} as const;
-
-export const entity = Chart.schemaToEntity(name, schema, true);
diff --git a/packages/backend/src/services/chart/charts/entities/per-user-following.ts b/packages/backend/src/services/chart/charts/entities/per-user-following.ts
deleted file mode 100644
index 3cbeec1114..0000000000
--- a/packages/backend/src/services/chart/charts/entities/per-user-following.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import Chart from "../../core.js";
-
-export const name = "perUserFollowing";
-
-export const schema = {
-	"local.followings.total": { accumulate: true },
-	"local.followings.inc": { range: "small" },
-	"local.followings.dec": { range: "small" },
-	"local.followers.total": { accumulate: true },
-	"local.followers.inc": { range: "small" },
-	"local.followers.dec": { range: "small" },
-	"remote.followings.total": { accumulate: true },
-	"remote.followings.inc": { range: "small" },
-	"remote.followings.dec": { range: "small" },
-	"remote.followers.total": { accumulate: true },
-	"remote.followers.inc": { range: "small" },
-	"remote.followers.dec": { range: "small" },
-} as const;
-
-export const entity = Chart.schemaToEntity(name, schema, true);
diff --git a/packages/backend/src/services/chart/charts/entities/per-user-notes.ts b/packages/backend/src/services/chart/charts/entities/per-user-notes.ts
deleted file mode 100644
index 30c22e2f46..0000000000
--- a/packages/backend/src/services/chart/charts/entities/per-user-notes.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import Chart from "../../core.js";
-
-export const name = "perUserNotes";
-
-export const schema = {
-	total: { accumulate: true },
-	inc: { range: "small" },
-	dec: { range: "small" },
-	"diffs.normal": { range: "small" },
-	"diffs.reply": { range: "small" },
-	"diffs.renote": { range: "small" },
-	"diffs.withFile": { range: "small" },
-} as const;
-
-export const entity = Chart.schemaToEntity(name, schema, true);
diff --git a/packages/backend/src/services/chart/charts/entities/per-user-reactions.ts b/packages/backend/src/services/chart/charts/entities/per-user-reactions.ts
deleted file mode 100644
index f281531c0c..0000000000
--- a/packages/backend/src/services/chart/charts/entities/per-user-reactions.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import Chart from "../../core.js";
-
-export const name = "perUserReaction";
-
-export const schema = {
-	"local.count": { range: "small" },
-	"remote.count": { range: "small" },
-} as const;
-
-export const entity = Chart.schemaToEntity(name, schema, true);
diff --git a/packages/backend/src/services/chart/charts/entities/test-grouped.ts b/packages/backend/src/services/chart/charts/entities/test-grouped.ts
deleted file mode 100644
index 428f2bb36c..0000000000
--- a/packages/backend/src/services/chart/charts/entities/test-grouped.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import Chart from "../../core.js";
-
-export const name = "testGrouped";
-
-export const schema = {
-	"foo.total": { accumulate: true },
-	"foo.inc": {},
-	"foo.dec": {},
-} as const;
-
-export const entity = Chart.schemaToEntity(name, schema, true);
diff --git a/packages/backend/src/services/chart/charts/entities/test-intersection.ts b/packages/backend/src/services/chart/charts/entities/test-intersection.ts
deleted file mode 100644
index 30d8753d7a..0000000000
--- a/packages/backend/src/services/chart/charts/entities/test-intersection.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import Chart from "../../core.js";
-
-export const name = "testIntersection";
-
-export const schema = {
-	a: { uniqueIncrement: true },
-	b: { uniqueIncrement: true },
-	aAndB: { intersection: ["a", "b"] },
-} as const;
-
-export const entity = Chart.schemaToEntity(name, schema);
diff --git a/packages/backend/src/services/chart/charts/entities/test-unique.ts b/packages/backend/src/services/chart/charts/entities/test-unique.ts
deleted file mode 100644
index 03b8a7653e..0000000000
--- a/packages/backend/src/services/chart/charts/entities/test-unique.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import Chart from "../../core.js";
-
-export const name = "testUnique";
-
-export const schema = {
-	foo: { uniqueIncrement: true },
-} as const;
-
-export const entity = Chart.schemaToEntity(name, schema);
diff --git a/packages/backend/src/services/chart/charts/entities/test.ts b/packages/backend/src/services/chart/charts/entities/test.ts
deleted file mode 100644
index a11d53e32e..0000000000
--- a/packages/backend/src/services/chart/charts/entities/test.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import Chart from "../../core.js";
-
-export const name = "test";
-
-export const schema = {
-	"foo.total": { accumulate: true },
-	"foo.inc": {},
-	"foo.dec": {},
-} as const;
-
-export const entity = Chart.schemaToEntity(name, schema);
diff --git a/packages/backend/src/services/chart/charts/entities/users.ts b/packages/backend/src/services/chart/charts/entities/users.ts
deleted file mode 100644
index a9544d77b1..0000000000
--- a/packages/backend/src/services/chart/charts/entities/users.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import Chart from "../../core.js";
-
-export const name = "users";
-
-export const schema = {
-	"local.total": { accumulate: true },
-	"local.inc": { range: "small" },
-	"local.dec": { range: "small" },
-	"remote.total": { accumulate: true },
-	"remote.inc": { range: "small" },
-	"remote.dec": { range: "small" },
-} as const;
-
-export const entity = Chart.schemaToEntity(name, schema);
diff --git a/packages/backend/src/services/chart/charts/federation.ts b/packages/backend/src/services/chart/charts/federation.ts
deleted file mode 100644
index 1a03d574df..0000000000
--- a/packages/backend/src/services/chart/charts/federation.ts
+++ /dev/null
@@ -1,142 +0,0 @@
-import type { KVs } from "../core.js";
-import Chart from "../core.js";
-import { Followings, Instances } from "@/models/index.js";
-import { name, schema } from "./entities/federation.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-
-/**
- * フェデレーションに関するチャート
- */
-
-export default class FederationChart extends Chart<typeof schema> {
-	constructor() {
-		super(name, schema);
-	}
-
-	protected async tickMajor(): Promise<Partial<KVs<typeof schema>>> {
-		return {};
-	}
-
-	protected async tickMinor(): Promise<Partial<KVs<typeof schema>>> {
-		const meta = await fetchMeta();
-
-		const suspendedInstancesQuery = Instances.createQueryBuilder("instance")
-			.select("instance.host")
-			.where("instance.isSuspended = true");
-
-		const pubsubSubQuery = Followings.createQueryBuilder("f")
-			.select("f.followerHost")
-			.where("f.followerHost IS NOT NULL");
-
-		const subInstancesQuery = Followings.createQueryBuilder("f")
-			.select("f.followeeHost")
-			.where("f.followeeHost IS NOT NULL");
-
-		const pubInstancesQuery = Followings.createQueryBuilder("f")
-			.select("f.followerHost")
-			.where("f.followerHost IS NOT NULL");
-
-		const [sub, pub, pubsub, subActive, pubActive] = await Promise.all([
-			Followings.createQueryBuilder("following")
-				.select("COUNT(DISTINCT following.followeeHost)")
-				.where("following.followeeHost IS NOT NULL")
-				.andWhere(
-					meta.blockedHosts.length === 0
-						? "1=1"
-						: "following.followeeHost NOT IN (:...blocked)",
-					{ blocked: meta.blockedHosts },
-				)
-				.andWhere(
-					`following.followeeHost NOT IN (${suspendedInstancesQuery.getQuery()})`,
-				)
-				.getRawOne()
-				.then((x) => parseInt(x.count, 10)),
-			Followings.createQueryBuilder("following")
-				.select("COUNT(DISTINCT following.followerHost)")
-				.where("following.followerHost IS NOT NULL")
-				.andWhere(
-					meta.blockedHosts.length === 0
-						? "1=1"
-						: "following.followerHost NOT IN (:...blocked)",
-					{ blocked: meta.blockedHosts },
-				)
-				.andWhere(
-					`following.followerHost NOT IN (${suspendedInstancesQuery.getQuery()})`,
-				)
-				.getRawOne()
-				.then((x) => parseInt(x.count, 10)),
-			Followings.createQueryBuilder("following")
-				.select("COUNT(DISTINCT following.followeeHost)")
-				.where("following.followeeHost IS NOT NULL")
-				.andWhere(
-					meta.blockedHosts.length === 0
-						? "1=1"
-						: "following.followeeHost NOT IN (:...blocked)",
-					{ blocked: meta.blockedHosts },
-				)
-				.andWhere(
-					`following.followeeHost NOT IN (${suspendedInstancesQuery.getQuery()})`,
-				)
-				.andWhere(`following.followeeHost IN (${pubsubSubQuery.getQuery()})`)
-				.setParameters(pubsubSubQuery.getParameters())
-				.getRawOne()
-				.then((x) => parseInt(x.count, 10)),
-			Instances.createQueryBuilder("instance")
-				.select("COUNT(instance.id)")
-				.where(`instance.host IN (${subInstancesQuery.getQuery()})`)
-				.andWhere(
-					meta.blockedHosts.length === 0
-						? "1=1"
-						: "instance.host NOT IN (:...blocked)",
-					{ blocked: meta.blockedHosts },
-				)
-				.andWhere("instance.isSuspended = false")
-				.andWhere("instance.lastCommunicatedAt > :gt", {
-					gt: new Date(Date.now() - 1000 * 60 * 60 * 24 * 30),
-				})
-				.getRawOne()
-				.then((x) => parseInt(x.count, 10)),
-			Instances.createQueryBuilder("instance")
-				.select("COUNT(instance.id)")
-				.where(`instance.host IN (${pubInstancesQuery.getQuery()})`)
-				.andWhere(
-					meta.blockedHosts.length === 0
-						? "1=1"
-						: "instance.host NOT IN (:...blocked)",
-					{ blocked: meta.blockedHosts },
-				)
-				.andWhere("instance.isSuspended = false")
-				.andWhere("instance.lastCommunicatedAt > :gt", {
-					gt: new Date(Date.now() - 1000 * 60 * 60 * 24 * 30),
-				})
-				.getRawOne()
-				.then((x) => parseInt(x.count, 10)),
-		]);
-
-		return {
-			sub: sub,
-			pub: pub,
-			pubsub: pubsub,
-			subActive: subActive,
-			pubActive: pubActive,
-		};
-	}
-
-	public async deliverd(host: string, succeeded: boolean): Promise<void> {
-		await this.commit(
-			succeeded
-				? {
-						deliveredInstances: [host],
-				  }
-				: {
-						stalled: [host],
-				  },
-		);
-	}
-
-	public async inbox(host: string): Promise<void> {
-		await this.commit({
-			inboxInstances: [host],
-		});
-	}
-}
diff --git a/packages/backend/src/services/chart/charts/hashtag.ts b/packages/backend/src/services/chart/charts/hashtag.ts
deleted file mode 100644
index 0211df857f..0000000000
--- a/packages/backend/src/services/chart/charts/hashtag.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import type { KVs } from "../core.js";
-import Chart from "../core.js";
-import type { User } from "@/models/entities/user.js";
-import { Users } from "@/models/index.js";
-import { name, schema } from "./entities/hashtag.js";
-
-/**
- * ハッシュタグに関するチャート
- */
-
-export default class HashtagChart extends Chart<typeof schema> {
-	constructor() {
-		super(name, schema, true);
-	}
-
-	protected async tickMajor(): Promise<Partial<KVs<typeof schema>>> {
-		return {};
-	}
-
-	protected async tickMinor(): Promise<Partial<KVs<typeof schema>>> {
-		return {};
-	}
-
-	public async update(
-		hashtag: string,
-		user: { id: User["id"]; host: User["host"] },
-	): Promise<void> {
-		await this.commit(
-			{
-				"local.users": Users.isLocalUser(user) ? [user.id] : [],
-				"remote.users": Users.isLocalUser(user) ? [] : [user.id],
-			},
-			hashtag,
-		);
-	}
-}
diff --git a/packages/backend/src/services/chart/charts/instance.ts b/packages/backend/src/services/chart/charts/instance.ts
deleted file mode 100644
index d6e3483d8e..0000000000
--- a/packages/backend/src/services/chart/charts/instance.ts
+++ /dev/null
@@ -1,142 +0,0 @@
-import type { KVs } from "../core.js";
-import Chart from "../core.js";
-import { DriveFiles, Followings, Users, Notes } from "@/models/index.js";
-import type { DriveFile } from "@/models/entities/drive-file.js";
-import type { Note } from "@/models/entities/note.js";
-import { toPuny } from "@/misc/convert-host.js";
-import { name, schema } from "./entities/instance.js";
-
-/**
- * インスタンスごとのチャート
- */
-
-export default class InstanceChart extends Chart<typeof schema> {
-	constructor() {
-		super(name, schema, true);
-	}
-
-	protected async tickMajor(
-		group: string,
-	): Promise<Partial<KVs<typeof schema>>> {
-		const [notesCount, usersCount, followingCount, followersCount, driveFiles] =
-			await Promise.all([
-				Notes.countBy({ userHost: group }),
-				Users.countBy({ host: group }),
-				Followings.countBy({ followerHost: group }),
-				Followings.countBy({ followeeHost: group }),
-				DriveFiles.countBy({ userHost: group }),
-			]);
-
-		return {
-			"notes.total": notesCount,
-			"users.total": usersCount,
-			"following.total": followingCount,
-			"followers.total": followersCount,
-			"drive.totalFiles": driveFiles,
-		};
-	}
-
-	protected async tickMinor(): Promise<Partial<KVs<typeof schema>>> {
-		return {};
-	}
-
-	public async requestReceived(host: string): Promise<void> {
-		await this.commit(
-			{
-				"requests.received": 1,
-			},
-			toPuny(host),
-		);
-	}
-
-	public async requestSent(host: string, isSucceeded: boolean): Promise<void> {
-		await this.commit(
-			{
-				"requests.succeeded": isSucceeded ? 1 : 0,
-				"requests.failed": isSucceeded ? 0 : 1,
-			},
-			toPuny(host),
-		);
-	}
-
-	public async newUser(host: string): Promise<void> {
-		await this.commit(
-			{
-				"users.total": 1,
-				"users.inc": 1,
-			},
-			toPuny(host),
-		);
-	}
-
-	public async updateNote(
-		host: string,
-		note: Note,
-		isAdditional: boolean,
-	): Promise<void> {
-		await this.commit(
-			{
-				"notes.total": isAdditional ? 1 : -1,
-				"notes.inc": isAdditional ? 1 : 0,
-				"notes.dec": isAdditional ? 0 : 1,
-				"notes.diffs.normal":
-					note.replyId == null && note.renoteId == null
-						? isAdditional
-							? 1
-							: -1
-						: 0,
-				"notes.diffs.renote":
-					note.renoteId != null ? (isAdditional ? 1 : -1) : 0,
-				"notes.diffs.reply": note.replyId != null ? (isAdditional ? 1 : -1) : 0,
-				"notes.diffs.withFile":
-					note.fileIds.length > 0 ? (isAdditional ? 1 : -1) : 0,
-			},
-			toPuny(host),
-		);
-	}
-
-	public async updateFollowing(
-		host: string,
-		isAdditional: boolean,
-	): Promise<void> {
-		await this.commit(
-			{
-				"following.total": isAdditional ? 1 : -1,
-				"following.inc": isAdditional ? 1 : 0,
-				"following.dec": isAdditional ? 0 : 1,
-			},
-			toPuny(host),
-		);
-	}
-
-	public async updateFollowers(
-		host: string,
-		isAdditional: boolean,
-	): Promise<void> {
-		await this.commit(
-			{
-				"followers.total": isAdditional ? 1 : -1,
-				"followers.inc": isAdditional ? 1 : 0,
-				"followers.dec": isAdditional ? 0 : 1,
-			},
-			toPuny(host),
-		);
-	}
-
-	public async updateDrive(
-		file: DriveFile,
-		isAdditional: boolean,
-	): Promise<void> {
-		const fileSizeKb = file.size / 1000;
-		await this.commit(
-			{
-				"drive.totalFiles": isAdditional ? 1 : -1,
-				"drive.incFiles": isAdditional ? 1 : 0,
-				"drive.incUsage": isAdditional ? fileSizeKb : 0,
-				"drive.decFiles": isAdditional ? 1 : 0,
-				"drive.decUsage": isAdditional ? fileSizeKb : 0,
-			},
-			file.userHost,
-		);
-	}
-}
diff --git a/packages/backend/src/services/chart/charts/notes.ts b/packages/backend/src/services/chart/charts/notes.ts
deleted file mode 100644
index 9ec347b470..0000000000
--- a/packages/backend/src/services/chart/charts/notes.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-import type { KVs } from "../core.js";
-import Chart from "../core.js";
-import { Notes } from "@/models/index.js";
-import { Not, IsNull } from "typeorm";
-import type { Note } from "@/models/entities/note.js";
-import { name, schema } from "./entities/notes.js";
-
-/**
- * ノートに関するチャート
- */
-
-export default class NotesChart extends Chart<typeof schema> {
-	constructor() {
-		super(name, schema);
-	}
-
-	protected async tickMajor(): Promise<Partial<KVs<typeof schema>>> {
-		const [localCount, remoteCount] = await Promise.all([
-			Notes.countBy({ userHost: IsNull() }),
-			Notes.countBy({ userHost: Not(IsNull()) }),
-		]);
-
-		return {
-			"local.total": localCount,
-			"remote.total": remoteCount,
-		};
-	}
-
-	protected async tickMinor(): Promise<Partial<KVs<typeof schema>>> {
-		return {};
-	}
-
-	public async update(note: Note, isAdditional: boolean): Promise<void> {
-		const prefix = note.userHost === null ? "local" : "remote";
-
-		await this.commit({
-			[`${prefix}.total`]: isAdditional ? 1 : -1,
-			[`${prefix}.inc`]: isAdditional ? 1 : 0,
-			[`${prefix}.dec`]: isAdditional ? 0 : 1,
-			[`${prefix}.diffs.normal`]:
-				note.replyId == null && note.renoteId == null
-					? isAdditional
-						? 1
-						: -1
-					: 0,
-			[`${prefix}.diffs.renote`]:
-				note.renoteId != null ? (isAdditional ? 1 : -1) : 0,
-			[`${prefix}.diffs.reply`]:
-				note.replyId != null ? (isAdditional ? 1 : -1) : 0,
-			[`${prefix}.diffs.withFile`]:
-				note.fileIds.length > 0 ? (isAdditional ? 1 : -1) : 0,
-		});
-	}
-}
diff --git a/packages/backend/src/services/chart/charts/per-user-drive.ts b/packages/backend/src/services/chart/charts/per-user-drive.ts
deleted file mode 100644
index 18589bb84a..0000000000
--- a/packages/backend/src/services/chart/charts/per-user-drive.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-import type { KVs } from "../core.js";
-import Chart from "../core.js";
-import { DriveFiles } from "@/models/index.js";
-import type { DriveFile } from "@/models/entities/drive-file.js";
-import { name, schema } from "./entities/per-user-drive.js";
-
-/**
- * ユーザーごとのドライブに関するチャート
- */
-
-export default class PerUserDriveChart extends Chart<typeof schema> {
-	constructor() {
-		super(name, schema, true);
-	}
-
-	protected async tickMajor(
-		group: string,
-	): Promise<Partial<KVs<typeof schema>>> {
-		const [count, size] = await Promise.all([
-			DriveFiles.countBy({ userId: group }),
-			DriveFiles.calcDriveUsageOf(group),
-		]);
-
-		return {
-			totalCount: count,
-			totalSize: size,
-		};
-	}
-
-	protected async tickMinor(): Promise<Partial<KVs<typeof schema>>> {
-		return {};
-	}
-
-	public async update(file: DriveFile, isAdditional: boolean): Promise<void> {
-		const fileSizeKb = file.size / 1000;
-		await this.commit(
-			{
-				totalCount: isAdditional ? 1 : -1,
-				totalSize: isAdditional ? fileSizeKb : -fileSizeKb,
-				incCount: isAdditional ? 1 : 0,
-				incSize: isAdditional ? fileSizeKb : 0,
-				decCount: isAdditional ? 0 : 1,
-				decSize: isAdditional ? 0 : fileSizeKb,
-			},
-			file.userId,
-		);
-	}
-}
diff --git a/packages/backend/src/services/chart/charts/per-user-following.ts b/packages/backend/src/services/chart/charts/per-user-following.ts
deleted file mode 100644
index 3e8b576f20..0000000000
--- a/packages/backend/src/services/chart/charts/per-user-following.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-import type { KVs } from "../core.js";
-import Chart from "../core.js";
-import { Followings, Users } from "@/models/index.js";
-import { Not, IsNull } from "typeorm";
-import type { User } from "@/models/entities/user.js";
-import { name, schema } from "./entities/per-user-following.js";
-
-/**
- * ユーザーごとのフォローに関するチャート
- */
-
-export default class PerUserFollowingChart extends Chart<typeof schema> {
-	constructor() {
-		super(name, schema, true);
-	}
-
-	protected async tickMajor(
-		group: string,
-	): Promise<Partial<KVs<typeof schema>>> {
-		const [
-			localFollowingsCount,
-			localFollowersCount,
-			remoteFollowingsCount,
-			remoteFollowersCount,
-		] = await Promise.all([
-			Followings.countBy({ followerId: group, followeeHost: IsNull() }),
-			Followings.countBy({ followeeId: group, followerHost: IsNull() }),
-			Followings.countBy({ followerId: group, followeeHost: Not(IsNull()) }),
-			Followings.countBy({ followeeId: group, followerHost: Not(IsNull()) }),
-		]);
-
-		return {
-			"local.followings.total": localFollowingsCount,
-			"local.followers.total": localFollowersCount,
-			"remote.followings.total": remoteFollowingsCount,
-			"remote.followers.total": remoteFollowersCount,
-		};
-	}
-
-	protected async tickMinor(): Promise<Partial<KVs<typeof schema>>> {
-		return {};
-	}
-
-	public async update(
-		follower: { id: User["id"]; host: User["host"] },
-		followee: { id: User["id"]; host: User["host"] },
-		isFollow: boolean,
-	): Promise<void> {
-		const prefixFollower = Users.isLocalUser(follower) ? "local" : "remote";
-		const prefixFollowee = Users.isLocalUser(followee) ? "local" : "remote";
-
-		this.commit(
-			{
-				[`${prefixFollower}.followings.total`]: isFollow ? 1 : -1,
-				[`${prefixFollower}.followings.inc`]: isFollow ? 1 : 0,
-				[`${prefixFollower}.followings.dec`]: isFollow ? 0 : 1,
-			},
-			follower.id,
-		);
-		this.commit(
-			{
-				[`${prefixFollowee}.followers.total`]: isFollow ? 1 : -1,
-				[`${prefixFollowee}.followers.inc`]: isFollow ? 1 : 0,
-				[`${prefixFollowee}.followers.dec`]: isFollow ? 0 : 1,
-			},
-			followee.id,
-		);
-	}
-}
diff --git a/packages/backend/src/services/chart/charts/per-user-notes.ts b/packages/backend/src/services/chart/charts/per-user-notes.ts
deleted file mode 100644
index d0190cefd0..0000000000
--- a/packages/backend/src/services/chart/charts/per-user-notes.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-import type { KVs } from "../core.js";
-import Chart from "../core.js";
-import type { User } from "@/models/entities/user.js";
-import { Notes } from "@/models/index.js";
-import type { Note } from "@/models/entities/note.js";
-import { name, schema } from "./entities/per-user-notes.js";
-
-/**
- * ユーザーごとのノートに関するチャート
- */
-
-export default class PerUserNotesChart extends Chart<typeof schema> {
-	constructor() {
-		super(name, schema, true);
-	}
-
-	protected async tickMajor(
-		group: string,
-	): Promise<Partial<KVs<typeof schema>>> {
-		const [count] = await Promise.all([Notes.countBy({ userId: group })]);
-
-		return {
-			total: count,
-		};
-	}
-
-	protected async tickMinor(): Promise<Partial<KVs<typeof schema>>> {
-		return {};
-	}
-
-	public async update(
-		user: { id: User["id"] },
-		note: Note,
-		isAdditional: boolean,
-	): Promise<void> {
-		await this.commit(
-			{
-				total: isAdditional ? 1 : -1,
-				inc: isAdditional ? 1 : 0,
-				dec: isAdditional ? 0 : 1,
-				"diffs.normal":
-					note.replyId == null && note.renoteId == null
-						? isAdditional
-							? 1
-							: -1
-						: 0,
-				"diffs.renote": note.renoteId != null ? (isAdditional ? 1 : -1) : 0,
-				"diffs.reply": note.replyId != null ? (isAdditional ? 1 : -1) : 0,
-				"diffs.withFile": note.fileIds.length > 0 ? (isAdditional ? 1 : -1) : 0,
-			},
-			user.id,
-		);
-	}
-}
diff --git a/packages/backend/src/services/chart/charts/per-user-reactions.ts b/packages/backend/src/services/chart/charts/per-user-reactions.ts
deleted file mode 100644
index 75def3de04..0000000000
--- a/packages/backend/src/services/chart/charts/per-user-reactions.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-import type { KVs } from "../core.js";
-import Chart from "../core.js";
-import type { User } from "@/models/entities/user.js";
-import type { Note } from "@/models/entities/note.js";
-import { Users } from "@/models/index.js";
-import { name, schema } from "./entities/per-user-reactions.js";
-
-/**
- * ユーザーごとのリアクションに関するチャート
- */
-
-export default class PerUserReactionsChart extends Chart<typeof schema> {
-	constructor() {
-		super(name, schema, true);
-	}
-
-	protected async tickMajor(
-		group: string,
-	): Promise<Partial<KVs<typeof schema>>> {
-		return {};
-	}
-
-	protected async tickMinor(): Promise<Partial<KVs<typeof schema>>> {
-		return {};
-	}
-
-	public async update(
-		user: { id: User["id"]; host: User["host"] },
-		note: Note,
-	): Promise<void> {
-		const prefix = Users.isLocalUser(user) ? "local" : "remote";
-		this.commit(
-			{
-				[`${prefix}.count`]: 1,
-			},
-			note.userId,
-		);
-	}
-}
diff --git a/packages/backend/src/services/chart/charts/test-grouped.ts b/packages/backend/src/services/chart/charts/test-grouped.ts
deleted file mode 100644
index 6520099fe6..0000000000
--- a/packages/backend/src/services/chart/charts/test-grouped.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import type { KVs } from "../core.js";
-import Chart from "../core.js";
-import { name, schema } from "./entities/test-grouped.js";
-
-/**
- * For testing
- */
-
-export default class TestGroupedChart extends Chart<typeof schema> {
-	private total = {} as Record<string, number>;
-
-	constructor() {
-		super(name, schema, true);
-	}
-
-	protected async tickMajor(
-		group: string,
-	): Promise<Partial<KVs<typeof schema>>> {
-		return {
-			"foo.total": this.total[group],
-		};
-	}
-
-	protected async tickMinor(): Promise<Partial<KVs<typeof schema>>> {
-		return {};
-	}
-
-	public async increment(group: string): Promise<void> {
-		if (this.total[group] == null) this.total[group] = 0;
-
-		this.total[group]++;
-
-		await this.commit(
-			{
-				"foo.total": 1,
-				"foo.inc": 1,
-			},
-			group,
-		);
-	}
-}
diff --git a/packages/backend/src/services/chart/charts/test-intersection.ts b/packages/backend/src/services/chart/charts/test-intersection.ts
deleted file mode 100644
index 0fa973861f..0000000000
--- a/packages/backend/src/services/chart/charts/test-intersection.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import type { KVs } from "../core.js";
-import Chart from "../core.js";
-import { name, schema } from "./entities/test-intersection.js";
-
-/**
- * For testing
- */
-
-export default class TestIntersectionChart extends Chart<typeof schema> {
-	constructor() {
-		super(name, schema);
-	}
-
-	protected async tickMajor(): Promise<Partial<KVs<typeof schema>>> {
-		return {};
-	}
-
-	protected async tickMinor(): Promise<Partial<KVs<typeof schema>>> {
-		return {};
-	}
-
-	public async addA(key: string): Promise<void> {
-		await this.commit({
-			a: [key],
-		});
-	}
-
-	public async addB(key: string): Promise<void> {
-		await this.commit({
-			b: [key],
-		});
-	}
-}
diff --git a/packages/backend/src/services/chart/charts/test-unique.ts b/packages/backend/src/services/chart/charts/test-unique.ts
deleted file mode 100644
index 095021622c..0000000000
--- a/packages/backend/src/services/chart/charts/test-unique.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import type { KVs } from "../core.js";
-import Chart from "../core.js";
-import { name, schema } from "./entities/test-unique.js";
-
-/**
- * For testing
- */
-
-export default class TestUniqueChart extends Chart<typeof schema> {
-	constructor() {
-		super(name, schema);
-	}
-
-	protected async tickMajor(): Promise<Partial<KVs<typeof schema>>> {
-		return {};
-	}
-
-	protected async tickMinor(): Promise<Partial<KVs<typeof schema>>> {
-		return {};
-	}
-
-	public async uniqueIncrement(key: string): Promise<void> {
-		await this.commit({
-			foo: [key],
-		});
-	}
-}
diff --git a/packages/backend/src/services/chart/charts/test.ts b/packages/backend/src/services/chart/charts/test.ts
deleted file mode 100644
index afdb3bf14e..0000000000
--- a/packages/backend/src/services/chart/charts/test.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import type { KVs } from "../core.js";
-import Chart from "../core.js";
-import { name, schema } from "./entities/test.js";
-
-/**
- * For testing
- */
-
-export default class TestChart extends Chart<typeof schema> {
-	public total = 0; // publicにするのはテストのため
-
-	constructor() {
-		super(name, schema);
-	}
-
-	protected async tickMajor(): Promise<Partial<KVs<typeof schema>>> {
-		return {
-			"foo.total": this.total,
-		};
-	}
-
-	protected async tickMinor(): Promise<Partial<KVs<typeof schema>>> {
-		return {};
-	}
-
-	public async increment(): Promise<void> {
-		this.total++;
-
-		await this.commit({
-			"foo.total": 1,
-			"foo.inc": 1,
-		});
-	}
-
-	public async decrement(): Promise<void> {
-		this.total--;
-
-		await this.commit({
-			"foo.total": -1,
-			"foo.dec": 1,
-		});
-	}
-}
diff --git a/packages/backend/src/services/chart/charts/users.ts b/packages/backend/src/services/chart/charts/users.ts
deleted file mode 100644
index 6fef9ecf7b..0000000000
--- a/packages/backend/src/services/chart/charts/users.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import type { KVs } from "../core.js";
-import Chart from "../core.js";
-import { Users } from "@/models/index.js";
-import { Not, IsNull } from "typeorm";
-import type { User } from "@/models/entities/user.js";
-import { name, schema } from "./entities/users.js";
-
-/**
- * ユーザー数に関するチャート
- */
-
-export default class UsersChart extends Chart<typeof schema> {
-	constructor() {
-		super(name, schema);
-	}
-
-	protected async tickMajor(): Promise<Partial<KVs<typeof schema>>> {
-		const [localCount, remoteCount] = await Promise.all([
-			Users.countBy({ host: IsNull() }),
-			Users.countBy({ host: Not(IsNull()) }),
-		]);
-
-		return {
-			"local.total": localCount,
-			"remote.total": remoteCount,
-		};
-	}
-
-	protected async tickMinor(): Promise<Partial<KVs<typeof schema>>> {
-		return {};
-	}
-
-	public async update(
-		user: { id: User["id"]; host: User["host"] },
-		isAdditional: boolean,
-	): Promise<void> {
-		const prefix = Users.isLocalUser(user) ? "local" : "remote";
-
-		await this.commit({
-			[`${prefix}.total`]: isAdditional ? 1 : -1,
-			[`${prefix}.inc`]: isAdditional ? 1 : 0,
-			[`${prefix}.dec`]: isAdditional ? 0 : 1,
-		});
-	}
-}
diff --git a/packages/backend/src/services/chart/core.ts b/packages/backend/src/services/chart/core.ts
deleted file mode 100644
index 36fe373269..0000000000
--- a/packages/backend/src/services/chart/core.ts
+++ /dev/null
@@ -1,922 +0,0 @@
-/**
- * チャートエンジン
- *
- * Tests located in test/chart
- */
-
-import * as nestedProperty from "nested-property";
-import Logger from "../logger.js";
-import type { Repository } from "typeorm";
-import { EntitySchema, LessThan, Between } from "typeorm";
-import {
-	dateUTC,
-	isTimeSame,
-	isTimeBefore,
-	subtractTime,
-	addTime,
-} from "@/prelude/time.js";
-import { getChartInsertLock } from "@/misc/app-lock.js";
-import { db } from "@/db/postgre.js";
-import promiseLimit from "promise-limit";
-
-const logger = new Logger("chart", "white", process.env.NODE_ENV !== "test");
-
-const columnPrefix = "___" as const;
-const uniqueTempColumnPrefix = "unique_temp___" as const;
-const columnDot = "_" as const;
-
-type Schema = Record<
-	string,
-	{
-		uniqueIncrement?: boolean;
-
-		intersection?: string[] | ReadonlyArray<string>;
-
-		range?: "big" | "small" | "medium";
-
-		// previousな値を引き継ぐかどうか
-		accumulate?: boolean;
-	}
->;
-
-type KeyToColumnName<T extends string> = T extends `${infer R1}.${infer R2}`
-	? `${R1}${typeof columnDot}${KeyToColumnName<R2>}`
-	: T;
-
-type Columns<S extends Schema> = {
-	[K in
-		keyof S as `${typeof columnPrefix}${KeyToColumnName<string & K>}`]: number;
-};
-
-type TempColumnsForUnique<S extends Schema> = {
-	[K in
-		keyof S as `${typeof uniqueTempColumnPrefix}${KeyToColumnName<
-			string & K
-		>}`]: S[K]["uniqueIncrement"] extends true ? string[] : never;
-};
-
-type RawRecord<S extends Schema> = {
-	id: number;
-
-	/**
-	 * 集計のグループ
-	 */
-	group?: string | null;
-
-	/**
-	 * 集計日時のUnixタイムスタンプ(秒)
-	 */
-	date: number;
-} & TempColumnsForUnique<S> &
-	Columns<S>;
-
-const camelToSnake = (str: string): string => {
-	return str.replace(/([A-Z])/g, (s) => `_${s.charAt(0).toLowerCase()}`);
-};
-
-const removeDuplicates = (array: any[]) => Array.from(new Set(array));
-
-type Commit<S extends Schema> = {
-	[K in keyof S]?: S[K]["uniqueIncrement"] extends true ? string[] : number;
-};
-
-export type KVs<S extends Schema> = {
-	[K in keyof S]: number;
-};
-
-type ChartResult<T extends Schema> = {
-	[P in keyof T]: number[];
-};
-
-type UnionToIntersection<T> = (T extends any ? (x: T) => any : never) extends (
-	x: infer R,
-) => any
-	? R
-	: never;
-
-type UnflattenSingleton<K extends string, V> = K extends `${infer A}.${infer B}`
-	? {
-			[_ in A]: UnflattenSingleton<B, V>;
-	  }
-	: {
-			[_ in K]: V;
-	  };
-
-type Unflatten<T extends Record<string, any>> = UnionToIntersection<
-	{
-		[K in Extract<keyof T, string>]: UnflattenSingleton<K, T[K]>;
-	}[Extract<keyof T, string>]
->;
-
-type ToJsonSchema<S> = {
-	type: "object";
-	properties: {
-		[K in keyof S]: S[K] extends number[]
-			? { type: "array"; items: { type: "number" } }
-			: ToJsonSchema<S[K]>;
-	};
-	required: (keyof S)[];
-};
-
-export function getJsonSchema<S extends Schema>(
-	schema: S,
-): ToJsonSchema<Unflatten<ChartResult<S>>> {
-	const jsonSchema = {
-		type: "object",
-		properties: {} as Record<string, unknown>,
-		required: [],
-	};
-
-	for (const k in schema) {
-		jsonSchema.properties[k] = {
-			type: "array",
-			items: { type: "number" },
-		};
-	}
-
-	return jsonSchema as ToJsonSchema<Unflatten<ChartResult<S>>>;
-}
-
-/**
- * 様々なチャートの管理を司るクラス
- */
-
-export default abstract class Chart<T extends Schema> {
-	public schema: T;
-
-	private name: string;
-	private buffer: {
-		diff: Commit<T>;
-		group: string | null;
-	}[] = [];
-	// ↓にしたいけどfindOneとかで型エラーになる
-	//private repositoryForHour: Repository<RawRecord<T>>;
-	//private repositoryForDay: Repository<RawRecord<T>>;
-	private repositoryForHour: Repository<{
-		id: number;
-		group?: string | null;
-		date: number;
-	}>;
-	private repositoryForDay: Repository<{
-		id: number;
-		group?: string | null;
-		date: number;
-	}>;
-
-	/**
-	 * 1日に一回程度実行されれば良いような計算処理を入れる(主にCASCADE削除などアプリケーション側で感知できない変動によるズレの修正用)
-	 */
-	protected abstract tickMajor(group: string | null): Promise<Partial<KVs<T>>>;
-
-	/**
-	 * 少なくとも最小スパン内に1回は実行されて欲しい計算処理を入れる
-	 */
-	protected abstract tickMinor(group: string | null): Promise<Partial<KVs<T>>>;
-
-	private static convertSchemaToColumnDefinitions(
-		schema: Schema,
-	): Record<string, { type: string; array?: boolean; default?: any }> {
-		const columns = {} as Record<
-			string,
-			{ type: string; array?: boolean; default?: any }
-		>;
-		for (const [k, v] of Object.entries(schema)) {
-			const name = k.replaceAll(".", columnDot);
-			const type =
-				v.range === "big"
-					? "bigint"
-					: v.range === "small"
-					? "smallint"
-					: "integer";
-			if (v.uniqueIncrement) {
-				columns[uniqueTempColumnPrefix + name] = {
-					type: "varchar",
-					array: true,
-					default: "{}",
-				};
-				columns[columnPrefix + name] = {
-					type,
-					default: 0,
-				};
-			} else {
-				columns[columnPrefix + name] = {
-					type,
-					default: 0,
-				};
-			}
-		}
-		return columns;
-	}
-
-	private static dateToTimestamp(x: Date): number {
-		return Math.floor(x.getTime() / 1000);
-	}
-
-	private static parseDate(
-		date: Date,
-	): [number, number, number, number, number, number, number] {
-		const y = date.getUTCFullYear();
-		const m = date.getUTCMonth();
-		const d = date.getUTCDate();
-		const h = date.getUTCHours();
-		const _m = date.getUTCMinutes();
-		const _s = date.getUTCSeconds();
-		const _ms = date.getUTCMilliseconds();
-
-		return [y, m, d, h, _m, _s, _ms];
-	}
-
-	private static getCurrentDate() {
-		return Chart.parseDate(new Date());
-	}
-
-	public static schemaToEntity(
-		name: string,
-		schema: Schema,
-		grouped = false,
-	): {
-		hour: EntitySchema;
-		day: EntitySchema;
-	} {
-		const createEntity = (span: "hour" | "day"): EntitySchema =>
-			new EntitySchema({
-				name:
-					span === "hour"
-						? `__chart__${camelToSnake(name)}`
-						: span === "day"
-						? `__chart_day__${camelToSnake(name)}`
-						: (new Error("not happen") as never),
-				columns: {
-					id: {
-						type: "integer",
-						primary: true,
-						generated: true,
-					},
-					date: {
-						type: "integer",
-					},
-					...(grouped
-						? {
-								group: {
-									type: "varchar",
-									length: 128,
-								},
-						  }
-						: {}),
-					...Chart.convertSchemaToColumnDefinitions(schema),
-				},
-				indices: [
-					{
-						columns: grouped ? ["date", "group"] : ["date"],
-						unique: true,
-					},
-				],
-				uniques: [
-					{
-						columns: grouped ? ["date", "group"] : ["date"],
-					},
-				],
-				relations: {
-					/* TODO
-					group: {
-						target: () => Foo,
-						type: 'many-to-one',
-						onDelete: 'CASCADE',
-					},
-				*/
-				},
-			});
-
-		return {
-			hour: createEntity("hour"),
-			day: createEntity("day"),
-		};
-	}
-
-	constructor(name: string, schema: T, grouped = false) {
-		this.name = name;
-		this.schema = schema;
-
-		const { hour, day } = Chart.schemaToEntity(name, schema, grouped);
-		this.repositoryForHour = db.getRepository<{
-			id: number;
-			group?: string | null;
-			date: number;
-		}>(hour);
-		this.repositoryForDay = db.getRepository<{
-			id: number;
-			group?: string | null;
-			date: number;
-		}>(day);
-	}
-
-	private convertRawRecord(x: RawRecord<T>): KVs<T> {
-		const kvs = {} as Record<string, number>;
-		for (const k of Object.keys(x).filter((k) =>
-			k.startsWith(columnPrefix),
-		) as (keyof Columns<T>)[]) {
-			kvs[
-				(k as string).substr(columnPrefix.length).split(columnDot).join(".")
-			] = x[k];
-		}
-		return kvs as KVs<T>;
-	}
-
-	private getNewLog(latest: KVs<T> | null): KVs<T> {
-		const log = {} as Record<keyof T, number>;
-		for (const [k, v] of Object.entries(this.schema) as [
-			keyof typeof this["schema"],
-			this["schema"][string],
-		][]) {
-			if (v.accumulate && latest) {
-				log[k] = latest[k];
-			} else {
-				log[k] = 0;
-			}
-		}
-		return log as KVs<T>;
-	}
-
-	private getLatestLog(
-		group: string | null,
-		span: "hour" | "day",
-	): Promise<RawRecord<T> | null> {
-		const repository =
-			span === "hour"
-				? this.repositoryForHour
-				: span === "day"
-				? this.repositoryForDay
-				: (new Error("not happen") as never);
-
-		return repository
-			.findOne({
-				where: group
-					? {
-							group: group,
-					  }
-					: {},
-				order: {
-					date: -1,
-				},
-			})
-			.then((x) => x ?? null) as Promise<RawRecord<T> | null>;
-	}
-
-	/**
-	 * 現在(=今のHour or Day)のログをデータベースから探して、あればそれを返し、なければ作成して返します。
-	 */
-	private async claimCurrentLog(
-		group: string | null,
-		span: "hour" | "day",
-	): Promise<RawRecord<T>> {
-		const [y, m, d, h] = Chart.getCurrentDate();
-
-		const current = dateUTC(
-			span === "hour"
-				? [y, m, d, h]
-				: span === "day"
-				? [y, m, d]
-				: (new Error("not happen") as never),
-		);
-
-		const repository =
-			span === "hour"
-				? this.repositoryForHour
-				: span === "day"
-				? this.repositoryForDay
-				: (new Error("not happen") as never);
-
-		// 現在(=今のHour or Day)のログ
-		const currentLog = (await repository.findOneBy({
-			date: Chart.dateToTimestamp(current),
-			...(group ? { group: group } : {}),
-		})) as RawRecord<T> | undefined;
-
-		// ログがあればそれを返して終了
-		if (currentLog != null) {
-			return currentLog;
-		}
-
-		let log: RawRecord<T>;
-		let data: KVs<T>;
-
-		// 集計期間が変わってから、初めてのチャート更新なら
-		// 最も最近のログを持ってくる
-		// * 例えば集計期間が「日」である場合で考えると、
-		// * 昨日何もチャートを更新するような出来事がなかった場合は、
-		// * ログがそもそも作られずドキュメントが存在しないということがあり得るため、
-		// * 「昨日の」と決め打ちせずに「もっとも最近の」とします
-		const latest = await this.getLatestLog(group, span);
-
-		if (latest != null) {
-			// 空ログデータを作成
-			data = this.getNewLog(this.convertRawRecord(latest));
-		} else {
-			// ログが存在しなかったら
-			// (Misskeyインスタンスを建てて初めてのチャート更新時など)
-
-			// 初期ログデータを作成
-			data = this.getNewLog(null);
-
-			logger.info(
-				`${
-					this.name + (group ? `:${group}` : "")
-				}(${span}): Initial commit created`,
-			);
-		}
-
-		const date = Chart.dateToTimestamp(current);
-		const lockKey = group
-			? `${this.name}:${date}:${span}:${group}`
-			: `${this.name}:${date}:${span}`;
-
-		const unlock = await getChartInsertLock(lockKey);
-		try {
-			// ロック内でもう1回チェックする
-			const currentLog = (await repository.findOneBy({
-				date: date,
-				...(group ? { group: group } : {}),
-			})) as RawRecord<T> | undefined;
-
-			// ログがあればそれを返して終了
-			if (currentLog != null) return currentLog;
-
-			const columns = {} as Record<string, number | unknown[]>;
-			for (const [k, v] of Object.entries(data)) {
-				const name = k.replaceAll(".", columnDot);
-				columns[columnPrefix + name] = v;
-			}
-
-			// 新規ログ挿入
-			log = (await repository
-				.insert({
-					date: date,
-					...(group ? { group: group } : {}),
-					...columns,
-				})
-				.then((x) =>
-					repository.findOneByOrFail(x.identifiers[0]),
-				)) as RawRecord<T>;
-
-			logger.info(
-				`${
-					this.name + (group ? `:${group}` : "")
-				}(${span}): New commit created`,
-			);
-
-			return log;
-		} finally {
-			unlock();
-		}
-	}
-
-	protected commit(diff: Commit<T>, group: string | null = null): void {
-		for (const [k, v] of Object.entries(diff)) {
-			if (v == null || v === 0 || (Array.isArray(v) && v.length === 0))
-				// rome-ignore lint/performance/noDelete: needs to be deleted not just set to undefined
-				delete diff[k];
-		}
-		this.buffer.push({
-			diff,
-			group,
-		});
-	}
-
-	public async save(): Promise<void> {
-		if (this.buffer.length === 0) {
-			logger.info(`${this.name}: Write skipped`);
-			return;
-		}
-
-		// TODO: 前の時間のログがbufferにあった場合のハンドリング
-		// 例えば、save が20分ごとに行われるとして、前回行われたのは 01:50 だったとする。
-		// 次に save が行われるのは 02:10 ということになるが、もし 01:55 に新規ログが buffer に追加されたとすると、
-		// そのログは本来は 01:00~ のログとしてDBに保存されて欲しいのに、02:00~ のログ扱いになってしまう。
-		// これを回避するための実装は複雑になりそうなため、一旦保留。
-
-		const update = async (
-			logHour: RawRecord<T>,
-			logDay: RawRecord<T>,
-		): Promise<void> => {
-			const finalDiffs = {} as Record<string, number | string[]>;
-
-			for (const diff of this.buffer
-				.filter((q) => q.group == null || q.group === logHour.group)
-				.map((q) => q.diff)) {
-				for (const [k, v] of Object.entries(diff)) {
-					if (finalDiffs[k] == null) {
-						finalDiffs[k] = v;
-					} else {
-						if (typeof finalDiffs[k] === "number") {
-							(finalDiffs[k] as number) += v as number;
-						} else {
-							(finalDiffs[k] as string[]) = (finalDiffs[k] as string[]).concat(
-								v,
-							);
-						}
-					}
-				}
-			}
-
-			const queryForHour: Record<keyof RawRecord<T>, number | (() => string)> =
-				{} as any;
-			const queryForDay: Record<keyof RawRecord<T>, number | (() => string)> =
-				{} as any;
-			for (const [k, v] of Object.entries(finalDiffs)) {
-				if (typeof v === "number") {
-					const name = (columnPrefix +
-						k.replaceAll(".", columnDot)) as keyof Columns<T>;
-					if (v > 0) queryForHour[name] = () => `"${name}" + ${v}`;
-					if (v < 0) queryForHour[name] = () => `"${name}" - ${Math.abs(v)}`;
-					if (v > 0) queryForDay[name] = () => `"${name}" + ${v}`;
-					if (v < 0) queryForDay[name] = () => `"${name}" - ${Math.abs(v)}`;
-				} else if (Array.isArray(v) && v.length > 0) {
-					// ユニークインクリメント
-					const tempColumnName = (uniqueTempColumnPrefix +
-						k.replaceAll(".", columnDot)) as keyof TempColumnsForUnique<T>;
-					// TODO: item をSQLエスケープ
-					const itemsForHour = v
-						.filter((item) => !logHour[tempColumnName].includes(item))
-						.map((item) => `"${item}"`);
-					const itemsForDay = v
-						.filter((item) => !logDay[tempColumnName].includes(item))
-						.map((item) => `"${item}"`);
-					if (itemsForHour.length > 0)
-						queryForHour[tempColumnName] = () =>
-							`array_cat("${tempColumnName}", '{${itemsForHour.join(
-								",",
-							)}}'::varchar[])`;
-					if (itemsForDay.length > 0)
-						queryForDay[tempColumnName] = () =>
-							`array_cat("${tempColumnName}", '{${itemsForDay.join(
-								",",
-							)}}'::varchar[])`;
-				}
-			}
-
-			// bake unique count
-			for (const [k, v] of Object.entries(finalDiffs)) {
-				if (
-					this.schema[k].uniqueIncrement &&
-					Array.isArray(v) &&
-					v.length > 0
-				) {
-					const name = (columnPrefix +
-						k.replaceAll(".", columnDot)) as keyof Columns<T>;
-					const tempColumnName = (uniqueTempColumnPrefix +
-						k.replaceAll(".", columnDot)) as keyof TempColumnsForUnique<T>;
-					queryForHour[name] = new Set([
-						...(v as string[]),
-						...logHour[tempColumnName],
-					]).size;
-					queryForDay[name] = new Set([
-						...(v as string[]),
-						...logDay[tempColumnName],
-					]).size;
-				}
-			}
-
-			// compute intersection
-			// TODO: intersectionに指定されたカラムがintersectionだった場合の対応
-			for (const [k, v] of Object.entries(this.schema)) {
-				const intersection = v.intersection;
-				if (intersection) {
-					const name = (columnPrefix +
-						k.replaceAll(".", columnDot)) as keyof Columns<T>;
-					const firstKey = intersection[0];
-					const firstTempColumnName = (uniqueTempColumnPrefix +
-						firstKey.replaceAll(
-							".",
-							columnDot,
-						)) as keyof TempColumnsForUnique<T>;
-					const firstValues = finalDiffs[firstKey] as string[] | undefined;
-					const currentValuesForHour = new Set([
-						...(firstValues ?? []),
-						...logHour[firstTempColumnName],
-					]);
-					const currentValuesForDay = new Set([
-						...(firstValues ?? []),
-						...logDay[firstTempColumnName],
-					]);
-					for (let i = 1; i < intersection.length; i++) {
-						const targetKey = intersection[i];
-						const targetTempColumnName = (uniqueTempColumnPrefix +
-							targetKey.replaceAll(
-								".",
-								columnDot,
-							)) as keyof TempColumnsForUnique<T>;
-						const targetValues = finalDiffs[targetKey] as string[] | undefined;
-						const targetValuesForHour = new Set([
-							...(targetValues ?? []),
-							...logHour[targetTempColumnName],
-						]);
-						const targetValuesForDay = new Set([
-							...(targetValues ?? []),
-							...logDay[targetTempColumnName],
-						]);
-						currentValuesForHour.forEach((v) => {
-							if (!targetValuesForHour.has(v)) currentValuesForHour.delete(v);
-						});
-						currentValuesForDay.forEach((v) => {
-							if (!targetValuesForDay.has(v)) currentValuesForDay.delete(v);
-						});
-					}
-					queryForHour[name] = currentValuesForHour.size;
-					queryForDay[name] = currentValuesForDay.size;
-				}
-			}
-
-			// ログ更新
-			await Promise.all([
-				this.repositoryForHour
-					.createQueryBuilder()
-					.update()
-					.set(queryForHour as any)
-					.where("id = :id", { id: logHour.id })
-					.execute(),
-				this.repositoryForDay
-					.createQueryBuilder()
-					.update()
-					.set(queryForDay as any)
-					.where("id = :id", { id: logDay.id })
-					.execute(),
-			]);
-
-			logger.info(
-				`${this.name + (logHour.group ? `:${logHour.group}` : "")}: Updated`,
-			);
-
-			// TODO: この一連の処理が始まった後に新たにbufferに入ったものは消さないようにする
-			this.buffer = this.buffer.filter(
-				(q) => q.group != null && q.group !== logHour.group,
-			);
-		};
-
-		const startCount = this.buffer.length;
-
-		const groups = removeDuplicates(this.buffer.map((log) => log.group));
-		const groupCount = groups.length;
-
-		// Limit the number of concurrent chart update queries executed on the database
-		// to 25 at a time, so as avoid excessive IO spinlocks like when 8k queries are
-		// sent out at once.
-		const limit = promiseLimit(25);
-
-		const startTime = Date.now();
-		await Promise.all(
-			groups.map((group) =>
-				limit(() =>
-					Promise.all([
-						this.claimCurrentLog(group, "hour"),
-						this.claimCurrentLog(group, "day"),
-					]).then(([logHour, logDay]) => update(logHour, logDay)),
-				),
-			),
-		);
-
-		const duration = Date.now() - startTime;
-		logger.info(
-			`Saved ${startCount} (${groupCount} unique) ${this.name} items in ${duration}ms (${this.buffer.length} remaining)`,
-		);
-	}
-
-	public async tick(
-		major: boolean,
-		group: string | null = null,
-	): Promise<void> {
-		const data = major
-			? await this.tickMajor(group)
-			: await this.tickMinor(group);
-
-		const columns = {} as Record<keyof Columns<T>, number>;
-		for (const [k, v] of Object.entries(data) as [
-			keyof typeof data,
-			number,
-		][]) {
-			const name = (columnPrefix +
-				(k as string).replaceAll(".", columnDot)) as keyof Columns<T>;
-			columns[name] = v;
-		}
-
-		if (Object.keys(columns).length === 0) {
-			return;
-		}
-
-		const update = async (
-			logHour: RawRecord<T>,
-			logDay: RawRecord<T>,
-		): Promise<void> => {
-			await Promise.all([
-				this.repositoryForHour
-					.createQueryBuilder()
-					.update()
-					.set(columns)
-					.where("id = :id", { id: logHour.id })
-					.execute(),
-				this.repositoryForDay
-					.createQueryBuilder()
-					.update()
-					.set(columns)
-					.where("id = :id", { id: logDay.id })
-					.execute(),
-			]);
-		};
-
-		return Promise.all([
-			this.claimCurrentLog(group, "hour"),
-			this.claimCurrentLog(group, "day"),
-		]).then(([logHour, logDay]) => update(logHour, logDay));
-	}
-
-	public resync(group: string | null = null): Promise<void> {
-		return this.tick(true, group);
-	}
-
-	public async clean(): Promise<void> {
-		const current = dateUTC(Chart.getCurrentDate());
-
-		// 一日以上前かつ三日以内
-		const gt = Chart.dateToTimestamp(current) - 60 * 60 * 24 * 3;
-		const lt = Chart.dateToTimestamp(current) - 60 * 60 * 24;
-
-		const columns = {} as Record<keyof TempColumnsForUnique<T>, []>;
-		for (const [k, v] of Object.entries(this.schema)) {
-			if (v.uniqueIncrement) {
-				const name = (uniqueTempColumnPrefix +
-					k.replaceAll(".", columnDot)) as keyof TempColumnsForUnique<T>;
-				columns[name] = [];
-			}
-		}
-
-		if (Object.keys(columns).length === 0) {
-			return;
-		}
-
-		await Promise.all([
-			this.repositoryForHour
-				.createQueryBuilder()
-				.update()
-				.set(columns)
-				.where("date > :gt", { gt })
-				.andWhere("date < :lt", { lt })
-				.execute(),
-			this.repositoryForDay
-				.createQueryBuilder()
-				.update()
-				.set(columns)
-				.where("date > :gt", { gt })
-				.andWhere("date < :lt", { lt })
-				.execute(),
-		]);
-	}
-
-	public async getChartRaw(
-		span: "hour" | "day",
-		amount: number,
-		cursor: Date | null,
-		group: string | null = null,
-	): Promise<ChartResult<T>> {
-		const [y, m, d, h, _m, _s, _ms] = cursor
-			? Chart.parseDate(subtractTime(addTime(cursor, 1, span), 1))
-			: Chart.getCurrentDate();
-		const [y2, m2, d2, h2] = cursor
-			? Chart.parseDate(addTime(cursor, 1, span))
-			: ([] as never);
-
-		const lt = dateUTC([y, m, d, h, _m, _s, _ms]);
-
-		const gt =
-			span === "day"
-				? subtractTime(
-						cursor ? dateUTC([y2, m2, d2, 0]) : dateUTC([y, m, d, 0]),
-						amount - 1,
-						"day",
-				  )
-				: span === "hour"
-				? subtractTime(
-						cursor ? dateUTC([y2, m2, d2, h2]) : dateUTC([y, m, d, h]),
-						amount - 1,
-						"hour",
-				  )
-				: (new Error("not happen") as never);
-
-		const repository =
-			span === "hour"
-				? this.repositoryForHour
-				: span === "day"
-				? this.repositoryForDay
-				: (new Error("not happen") as never);
-
-		// ログ取得
-		let logs = (await repository.find({
-			where: {
-				date: Between(Chart.dateToTimestamp(gt), Chart.dateToTimestamp(lt)),
-				...(group ? { group: group } : {}),
-			},
-			order: {
-				date: -1,
-			},
-		})) as RawRecord<T>[];
-
-		// 要求された範囲にログがひとつもなかったら
-		if (logs.length === 0) {
-			// もっとも新しいログを持ってくる
-			// (すくなくともひとつログが無いと隙間埋めできないため)
-			const recentLog = (await repository.findOne({
-				where: group
-					? {
-							group: group,
-					  }
-					: {},
-				order: {
-					date: -1,
-				},
-			})) as RawRecord<T> | undefined;
-
-			if (recentLog) {
-				logs = [recentLog];
-			}
-
-			// 要求された範囲の最も古い箇所に位置するログが存在しなかったら
-		} else if (!isTimeSame(new Date(logs[logs.length - 1].date * 1000), gt)) {
-			// 要求された範囲の最も古い箇所時点での最も新しいログを持ってきて末尾に追加する
-			// (隙間埋めできないため)
-			const outdatedLog = (await repository.findOne({
-				where: {
-					date: LessThan(Chart.dateToTimestamp(gt)),
-					...(group ? { group: group } : {}),
-				},
-				order: {
-					date: -1,
-				},
-			})) as RawRecord<T> | undefined;
-
-			if (outdatedLog) {
-				logs.push(outdatedLog);
-			}
-		}
-
-		const chart: KVs<T>[] = [];
-
-		for (let i = amount - 1; i >= 0; i--) {
-			const current =
-				span === "hour"
-					? subtractTime(dateUTC([y, m, d, h]), i, "hour")
-					: span === "day"
-					? subtractTime(dateUTC([y, m, d]), i, "day")
-					: (new Error("not happen") as never);
-
-			const log = logs.find((l) =>
-				isTimeSame(new Date(l.date * 1000), current),
-			);
-
-			if (log) {
-				chart.unshift(this.convertRawRecord(log));
-			} else {
-				// 隙間埋め
-				const latest = logs.find((l) =>
-					isTimeBefore(new Date(l.date * 1000), current),
-				);
-				const data = latest ? this.convertRawRecord(latest) : null;
-				chart.unshift(this.getNewLog(data));
-			}
-		}
-
-		const res = {} as ChartResult<T>;
-
-		/**
-		 * [{ foo: 1, bar: 5 }, { foo: 2, bar: 6 }, { foo: 3, bar: 7 }]
-		 * を
-		 * { foo: [1, 2, 3], bar: [5, 6, 7] }
-		 * にする
-		 */
-		for (const record of chart) {
-			for (const [k, v] of Object.entries(record) as [
-				keyof typeof record,
-				number,
-			][]) {
-				if (res[k]) {
-					res[k].push(v);
-				} else {
-					res[k] = [v];
-				}
-			}
-		}
-
-		return res;
-	}
-
-	public async getChart(
-		span: "hour" | "day",
-		amount: number,
-		cursor: Date | null,
-		group: string | null = null,
-	): Promise<Unflatten<ChartResult<T>>> {
-		const result = await this.getChartRaw(span, amount, cursor, group);
-		const object = {};
-		for (const [k, v] of Object.entries(result)) {
-			nestedProperty.set(object, k, v);
-		}
-		return object as Unflatten<ChartResult<T>>;
-	}
-}
diff --git a/packages/backend/src/services/chart/entities.ts b/packages/backend/src/services/chart/entities.ts
deleted file mode 100644
index e203dffdff..0000000000
--- a/packages/backend/src/services/chart/entities.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-import { entity as FederationChart } from "./charts/entities/federation.js";
-import { entity as NotesChart } from "./charts/entities/notes.js";
-import { entity as UsersChart } from "./charts/entities/users.js";
-import { entity as ActiveUsersChart } from "./charts/entities/active-users.js";
-import { entity as InstanceChart } from "./charts/entities/instance.js";
-import { entity as PerUserNotesChart } from "./charts/entities/per-user-notes.js";
-import { entity as DriveChart } from "./charts/entities/drive.js";
-import { entity as PerUserReactionsChart } from "./charts/entities/per-user-reactions.js";
-import { entity as HashtagChart } from "./charts/entities/hashtag.js";
-import { entity as PerUserFollowingChart } from "./charts/entities/per-user-following.js";
-import { entity as PerUserDriveChart } from "./charts/entities/per-user-drive.js";
-import { entity as ApRequestChart } from "./charts/entities/ap-request.js";
-
-import { entity as TestChart } from "./charts/entities/test.js";
-import { entity as TestGroupedChart } from "./charts/entities/test-grouped.js";
-import { entity as TestUniqueChart } from "./charts/entities/test-unique.js";
-import { entity as TestIntersectionChart } from "./charts/entities/test-intersection.js";
-
-export const entities = [
-	FederationChart.hour,
-	FederationChart.day,
-	NotesChart.hour,
-	NotesChart.day,
-	UsersChart.hour,
-	UsersChart.day,
-	ActiveUsersChart.hour,
-	ActiveUsersChart.day,
-	InstanceChart.hour,
-	InstanceChart.day,
-	PerUserNotesChart.hour,
-	PerUserNotesChart.day,
-	DriveChart.hour,
-	DriveChart.day,
-	PerUserReactionsChart.hour,
-	PerUserReactionsChart.day,
-	HashtagChart.hour,
-	HashtagChart.day,
-	PerUserFollowingChart.hour,
-	PerUserFollowingChart.day,
-	PerUserDriveChart.hour,
-	PerUserDriveChart.day,
-	ApRequestChart.hour,
-	ApRequestChart.day,
-
-	...(process.env.NODE_ENV === "test"
-		? [
-				TestChart.hour,
-				TestChart.day,
-				TestGroupedChart.hour,
-				TestGroupedChart.day,
-				TestUniqueChart.hour,
-				TestUniqueChart.day,
-				TestIntersectionChart.hour,
-				TestIntersectionChart.day,
-		  ]
-		: []),
-];
diff --git a/packages/backend/src/services/chart/index.ts b/packages/backend/src/services/chart/index.ts
deleted file mode 100644
index 969cdab6d7..0000000000
--- a/packages/backend/src/services/chart/index.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import { beforeShutdown } from "@/misc/before-shutdown.js";
-
-import FederationChart from "./charts/federation.js";
-import NotesChart from "./charts/notes.js";
-import UsersChart from "./charts/users.js";
-import ActiveUsersChart from "./charts/active-users.js";
-import InstanceChart from "./charts/instance.js";
-import PerUserNotesChart from "./charts/per-user-notes.js";
-import DriveChart from "./charts/drive.js";
-import PerUserReactionsChart from "./charts/per-user-reactions.js";
-import HashtagChart from "./charts/hashtag.js";
-import PerUserFollowingChart from "./charts/per-user-following.js";
-import PerUserDriveChart from "./charts/per-user-drive.js";
-import ApRequestChart from "./charts/ap-request.js";
-
-export const federationChart = new FederationChart();
-export const notesChart = new NotesChart();
-export const usersChart = new UsersChart();
-export const activeUsersChart = new ActiveUsersChart();
-export const instanceChart = new InstanceChart();
-export const perUserNotesChart = new PerUserNotesChart();
-export const driveChart = new DriveChart();
-export const perUserReactionsChart = new PerUserReactionsChart();
-export const hashtagChart = new HashtagChart();
-export const perUserFollowingChart = new PerUserFollowingChart();
-export const perUserDriveChart = new PerUserDriveChart();
-export const apRequestChart = new ApRequestChart();
-
-const charts = [
-	federationChart,
-	notesChart,
-	usersChart,
-	activeUsersChart,
-	instanceChart,
-	perUserNotesChart,
-	driveChart,
-	perUserReactionsChart,
-	hashtagChart,
-	perUserFollowingChart,
-	perUserDriveChart,
-	apRequestChart,
-];
-
-// 20分おきにメモリ情報をDBに書き込み
-setInterval(() => {
-	for (const chart of charts) {
-		chart.save();
-	}
-}, 1000 * 60 * 20);
-
-beforeShutdown(() => Promise.all(charts.map((chart) => chart.save())));
diff --git a/packages/backend/src/services/create-notification.ts b/packages/backend/src/services/create-notification.ts
deleted file mode 100644
index f6545b131c..0000000000
--- a/packages/backend/src/services/create-notification.ts
+++ /dev/null
@@ -1,91 +0,0 @@
-import { publishMainStream } from "@/services/stream.js";
-import { pushNotification } from "@/services/push-notification.js";
-import {
-	Notifications,
-	Mutings,
-	NoteThreadMutings,
-	UserProfiles,
-	Users,
-} from "@/models/index.js";
-import { genId } from "@/misc/gen-id.js";
-import type { User } from "@/models/entities/user.js";
-import type { Notification } from "@/models/entities/notification.js";
-import { sendEmailNotification } from "./send-email-notification.js";
-
-export async function createNotification(
-	notifieeId: User["id"],
-	type: Notification["type"],
-	data: Partial<Notification>,
-) {
-	if (data.notifierId && notifieeId === data.notifierId) {
-		return null;
-	}
-
-	const profile = await UserProfiles.findOneBy({ userId: notifieeId });
-
-	const isMuted = profile?.mutingNotificationTypes.includes(type);
-
-	if (data.note != null) {
-		const threadMute = await NoteThreadMutings.findOneBy({
-			userId: notifieeId,
-			threadId: data.note.threadId || data.note.id,
-		});
-
-		if (threadMute) {
-			return null;
-		}
-	}
-
-	// Create notification
-	const notification = await Notifications.insert({
-		id: genId(),
-		createdAt: new Date(),
-		notifieeId: notifieeId,
-		type: type,
-		// 相手がこの通知をミュートしているようなら、既読を予めつけておく
-		isRead: isMuted,
-		...data,
-	} as Partial<Notification>).then((x) =>
-		Notifications.findOneByOrFail(x.identifiers[0]),
-	);
-
-	const packed = await Notifications.pack(notification, {});
-
-	// Publish notification event
-	publishMainStream(notifieeId, "notification", packed);
-
-	// 2秒経っても(今回作成した)通知が既読にならなかったら「未読の通知がありますよ」イベントを発行する
-	setTimeout(async () => {
-		const fresh = await Notifications.findOneBy({ id: notification.id });
-		if (fresh == null) return; // 既に削除されているかもしれない
-		if (fresh.isRead) return;
-
-		//#region ただしミュートしているユーザーからの通知なら無視
-		const mutings = await Mutings.findBy({
-			muterId: notifieeId,
-		});
-		if (
-			data.notifierId &&
-			mutings.map((m) => m.muteeId).includes(data.notifierId)
-		) {
-			return;
-		}
-		//#endregion
-
-		publishMainStream(notifieeId, "unreadNotification", packed);
-		pushNotification(notifieeId, "notification", packed);
-
-		if (type === "follow")
-			sendEmailNotification.follow(
-				notifieeId,
-				await Users.findOneByOrFail({ id: data.notifierId! }),
-			);
-		if (type === "receiveFollowRequest")
-			sendEmailNotification.receiveFollowRequest(
-				notifieeId,
-				await Users.findOneByOrFail({ id: data.notifierId! }),
-			);
-	}, 2000);
-
-	return notification;
-}
diff --git a/packages/backend/src/services/create-system-user.ts b/packages/backend/src/services/create-system-user.ts
deleted file mode 100644
index 24536090a9..0000000000
--- a/packages/backend/src/services/create-system-user.ts
+++ /dev/null
@@ -1,71 +0,0 @@
-import { v4 as uuid } from "uuid";
-import generateNativeUserToken from "../server/api/common/generate-native-user-token.js";
-import { genRsaKeyPair } from "@/misc/gen-key-pair.js";
-import { User } from "@/models/entities/user.js";
-import { UserProfile } from "@/models/entities/user-profile.js";
-import { IsNull } from "typeorm";
-import { genId } from "@/misc/gen-id.js";
-import { UserKeypair } from "@/models/entities/user-keypair.js";
-import { UsedUsername } from "@/models/entities/used-username.js";
-import { db } from "@/db/postgre.js";
-import { hashPassword } from "@/misc/password.js";
-
-export async function createSystemUser(username: string) {
-	const password = uuid();
-
-	// Generate hash of password
-	const hash = await hashPassword(password);
-
-	// Generate secret
-	const secret = generateNativeUserToken();
-
-	const keyPair = await genRsaKeyPair(4096);
-
-	let account!: User;
-
-	// Start transaction
-	await db.transaction(async (transactionalEntityManager) => {
-		const exist = await transactionalEntityManager.findOneBy(User, {
-			usernameLower: username.toLowerCase(),
-			host: IsNull(),
-		});
-
-		if (exist) throw new Error("the user is already exists");
-
-		account = await transactionalEntityManager
-			.insert(User, {
-				id: genId(),
-				createdAt: new Date(),
-				username: username,
-				usernameLower: username.toLowerCase(),
-				host: null,
-				token: secret,
-				isAdmin: false,
-				isLocked: true,
-				isExplorable: false,
-				isBot: true,
-			})
-			.then((x) =>
-				transactionalEntityManager.findOneByOrFail(User, x.identifiers[0]),
-			);
-
-		await transactionalEntityManager.insert(UserKeypair, {
-			publicKey: keyPair.publicKey,
-			privateKey: keyPair.privateKey,
-			userId: account.id,
-		});
-
-		await transactionalEntityManager.insert(UserProfile, {
-			userId: account.id,
-			autoAcceptFollowed: false,
-			password: hash,
-		});
-
-		await transactionalEntityManager.insert(UsedUsername, {
-			createdAt: new Date(),
-			username: username.toLowerCase(),
-		});
-	});
-
-	return account;
-}
diff --git a/packages/backend/src/services/delete-account.ts b/packages/backend/src/services/delete-account.ts
deleted file mode 100644
index 927776199a..0000000000
--- a/packages/backend/src/services/delete-account.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import { Users } from "@/models/index.js";
-import { createDeleteAccountJob } from "@/queue/index.js";
-import { publishUserEvent } from "./stream.js";
-import { doPostSuspend } from "./suspend-user.js";
-
-export async function deleteAccount(user: {
-	id: string;
-	host: string | null;
-}): Promise<void> {
-	// 物理削除する前にDelete activityを送信する
-	await doPostSuspend(user).catch((e) => {});
-
-	createDeleteAccountJob(user, {
-		soft: false,
-	});
-
-	await Users.update(user.id, {
-		isDeleted: true,
-	});
-
-	// Terminate streaming
-	publishUserEvent(user.id, "terminate", {});
-}
diff --git a/packages/backend/src/services/detect-sensitive.ts b/packages/backend/src/services/detect-sensitive.ts
deleted file mode 100644
index df695e86da..0000000000
--- a/packages/backend/src/services/detect-sensitive.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-import * as fs from "node:fs";
-import { fileURLToPath } from "node:url";
-import { dirname } from "node:path";
-import * as nsfw from "nsfwjs";
-import si from "systeminformation";
-
-const _filename = fileURLToPath(import.meta.url);
-const _dirname = dirname(_filename);
-
-const REQUIRED_CPU_FLAGS = ["avx2", "fma"];
-let isSupportedCpu: undefined | boolean = undefined;
-
-let model: nsfw.NSFWJS;
-
-export async function detectSensitive(
-	path: string,
-): Promise<nsfw.predictionType[] | null> {
-	try {
-		if (isSupportedCpu === undefined) {
-			const cpuFlags = await getCpuFlags();
-			isSupportedCpu = REQUIRED_CPU_FLAGS.every((required) =>
-				cpuFlags.includes(required),
-			);
-		}
-
-		if (!isSupportedCpu) {
-			console.error("This CPU cannot use TensorFlow.");
-			return null;
-		}
-
-		const tf = await import("@tensorflow/tfjs-node");
-
-		if (model == null)
-			model = await nsfw.load(`file://${_dirname}/../../nsfw-model/`, {
-				size: 299,
-			});
-
-		const buffer = await fs.promises.readFile(path);
-		const image = (await tf.node.decodeImage(buffer, 3)) as any;
-		try {
-			const predictions = await model.classify(image);
-			return predictions;
-		} finally {
-			image.dispose();
-		}
-	} catch (err) {
-		console.error(err);
-		return null;
-	}
-}
-
-async function getCpuFlags(): Promise<string[]> {
-	const str = await si.cpuFlags();
-	return str.split(/\s+/);
-}
diff --git a/packages/backend/src/services/drive/add-file.ts b/packages/backend/src/services/drive/add-file.ts
deleted file mode 100644
index b25375b947..0000000000
--- a/packages/backend/src/services/drive/add-file.ts
+++ /dev/null
@@ -1,671 +0,0 @@
-import * as fs from "node:fs";
-
-import { v4 as uuid } from "uuid";
-
-import type S3 from "aws-sdk/clients/s3.js";
-import sharp from "sharp";
-import { IsNull } from "typeorm";
-import { publishMainStream, publishDriveStream } from "@/services/stream.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { contentDisposition } from "@/misc/content-disposition.js";
-import { getFileInfo } from "@/misc/get-file-info.js";
-import {
-	DriveFiles,
-	DriveFolders,
-	Users,
-	Instances,
-	UserProfiles,
-} from "@/models/index.js";
-import { DriveFile } from "@/models/entities/drive-file.js";
-import type { IRemoteUser, User } from "@/models/entities/user.js";
-import {
-	driveChart,
-	perUserDriveChart,
-	instanceChart,
-} from "@/services/chart/index.js";
-import { genId } from "@/misc/gen-id.js";
-import { isDuplicateKeyValueError } from "@/misc/is-duplicate-key-value-error.js";
-import { FILE_TYPE_BROWSERSAFE } from "@/const.js";
-import { IdentifiableError } from "@/misc/identifiable-error.js";
-import { getS3 } from "./s3.js";
-import { InternalStorage } from "./internal-storage.js";
-import type { IImage } from "./image-processor.js";
-import { convertSharpToWebp } from "./image-processor.js";
-import { driveLogger } from "./logger.js";
-import { GenerateVideoThumbnail } from "./generate-video-thumbnail.js";
-import { deleteFile } from "./delete-file.js";
-
-const logger = driveLogger.createSubLogger("register", "yellow");
-
-/***
- * Save file
- * @param path Path for original
- * @param name Name for original
- * @param type Content-Type for original
- * @param hash Hash for original
- * @param size Size for original
- */
-async function save(
-	file: DriveFile,
-	path: string,
-	name: string,
-	type: string,
-	hash: string,
-	size: number,
-): Promise<DriveFile> {
-	// thunbnail, webpublic を必要なら生成
-	const alts = await generateAlts(path, type, !file.uri);
-
-	const meta = await fetchMeta();
-
-	if (meta.useObjectStorage) {
-		//#region ObjectStorage params
-		let [ext] = name.match(/\.([a-zA-Z0-9_-]+)$/) || [""];
-
-		if (ext === "") {
-			if (type === "image/jpeg") ext = ".jpg";
-			if (type === "image/png") ext = ".png";
-			if (type === "image/webp") ext = ".webp";
-			if (type === "image/apng") ext = ".apng";
-			if (type === "image/avif") ext = ".avif";
-			if (type === "image/vnd.mozilla.apng") ext = ".apng";
-		}
-
-		// Some cloud providers (notably upcloud) will infer the content-type based
-		// on extension, so we remove extensions from non-browser-safe types.
-		if (!FILE_TYPE_BROWSERSAFE.includes(type)) {
-			ext = "";
-		}
-
-		const baseUrl =
-			meta.objectStorageBaseUrl ||
-			`${meta.objectStorageUseSSL ? "https" : "http"}://${
-				meta.objectStorageEndpoint
-			}${meta.objectStoragePort ? `:${meta.objectStoragePort}` : ""}/${
-				meta.objectStorageBucket
-			}`;
-
-		// for original
-		const key = `${meta.objectStoragePrefix}/${uuid()}${ext}`;
-		const url = `${baseUrl}/${key}`;
-
-		// for alts
-		let webpublicKey: string | null = null;
-		let webpublicUrl: string | null = null;
-		let thumbnailKey: string | null = null;
-		let thumbnailUrl: string | null = null;
-		//#endregion
-
-		//#region Uploads
-		logger.info(`uploading original: ${key}`);
-		const uploads = [upload(key, fs.createReadStream(path), type, name)];
-
-		if (alts.webpublic) {
-			webpublicKey = `${meta.objectStoragePrefix}/webpublic-${uuid()}.${
-				alts.webpublic.ext
-			}`;
-			webpublicUrl = `${baseUrl}/${webpublicKey}`;
-
-			logger.info(`uploading webpublic: ${webpublicKey}`);
-			uploads.push(
-				upload(webpublicKey, alts.webpublic.data, alts.webpublic.type, name),
-			);
-		}
-
-		if (alts.thumbnail) {
-			thumbnailKey = `${meta.objectStoragePrefix}/thumbnail-${uuid()}.${
-				alts.thumbnail.ext
-			}`;
-			thumbnailUrl = `${baseUrl}/${thumbnailKey}`;
-
-			logger.info(`uploading thumbnail: ${thumbnailKey}`);
-			uploads.push(
-				upload(thumbnailKey, alts.thumbnail.data, alts.thumbnail.type),
-			);
-		}
-
-		await Promise.all(uploads);
-		//#endregion
-
-		file.url = url;
-		file.thumbnailUrl = thumbnailUrl;
-		file.webpublicUrl = webpublicUrl;
-		file.accessKey = key;
-		file.thumbnailAccessKey = thumbnailKey;
-		file.webpublicAccessKey = webpublicKey;
-		file.webpublicType = alts.webpublic?.type ?? null;
-		file.name = name;
-		file.type = type;
-		file.md5 = hash;
-		file.size = size;
-		file.storedInternal = false;
-
-		return await DriveFiles.insert(file).then((x) =>
-			DriveFiles.findOneByOrFail(x.identifiers[0]),
-		);
-	} else {
-		// use internal storage
-		const accessKey = uuid();
-		const thumbnailAccessKey = `thumbnail-${uuid()}`;
-		const webpublicAccessKey = `webpublic-${uuid()}`;
-
-		const url = InternalStorage.saveFromPath(accessKey, path);
-
-		let thumbnailUrl: string | null = null;
-		let webpublicUrl: string | null = null;
-
-		if (alts.thumbnail) {
-			thumbnailUrl = InternalStorage.saveFromBuffer(
-				thumbnailAccessKey,
-				alts.thumbnail.data,
-			);
-			logger.info(`thumbnail stored: ${thumbnailAccessKey}`);
-		}
-
-		if (alts.webpublic) {
-			webpublicUrl = InternalStorage.saveFromBuffer(
-				webpublicAccessKey,
-				alts.webpublic.data,
-			);
-			logger.info(`web stored: ${webpublicAccessKey}`);
-		}
-
-		file.storedInternal = true;
-		file.url = url;
-		file.thumbnailUrl = thumbnailUrl;
-		file.webpublicUrl = webpublicUrl;
-		file.accessKey = accessKey;
-		file.thumbnailAccessKey = thumbnailAccessKey;
-		file.webpublicAccessKey = webpublicAccessKey;
-		file.webpublicType = alts.webpublic?.type ?? null;
-		file.name = name;
-		file.type = type;
-		file.md5 = hash;
-		file.size = size;
-
-		return await DriveFiles.insert(file).then((x) =>
-			DriveFiles.findOneByOrFail(x.identifiers[0]),
-		);
-	}
-}
-
-/**
- * Generate webpublic, thumbnail, etc
- * @param path Path for original
- * @param type Content-Type for original
- * @param generateWeb Generate webpublic or not
- */
-export async function generateAlts(
-	path: string,
-	type: string,
-	generateWeb: boolean,
-) {
-	if (type.startsWith("video/")) {
-		try {
-			const thumbnail = await GenerateVideoThumbnail(path);
-			return {
-				webpublic: null,
-				thumbnail,
-			};
-		} catch (err) {
-			logger.warn(`GenerateVideoThumbnail failed: ${err}`);
-			return {
-				webpublic: null,
-				thumbnail: null,
-			};
-		}
-	}
-
-	if (
-		![
-			"image/jpeg",
-			"image/png",
-			"image/webp",
-			"image/svg+xml",
-			"image/avif",
-		].includes(type)
-	) {
-		logger.debug("web image and thumbnail not created (not an required file)");
-		return {
-			webpublic: null,
-			thumbnail: null,
-		};
-	}
-
-	let img: sharp.Sharp | null = null;
-	let satisfyWebpublic: boolean;
-
-	try {
-		img = sharp(path);
-		const metadata = await img.metadata();
-		const isAnimated = metadata.pages && metadata.pages > 1;
-
-		// skip animated
-		if (isAnimated) {
-			return {
-				webpublic: null,
-				thumbnail: null,
-			};
-		}
-
-		satisfyWebpublic = !!(
-			type !== "image/svg+xml" &&
-			type !== "image/webp" &&
-			!(
-				metadata.exif ||
-				metadata.iptc ||
-				metadata.xmp ||
-				metadata.tifftagPhotoshop
-			) &&
-			metadata.width &&
-			metadata.width <= 2048 &&
-			metadata.height &&
-			metadata.height <= 2048
-		);
-	} catch (err) {
-		logger.warn(`sharp failed: ${err}`);
-		return {
-			webpublic: null,
-			thumbnail: null,
-		};
-	}
-
-	// #region webpublic
-	let webpublic: IImage | null = null;
-
-	if (generateWeb && !satisfyWebpublic) {
-		logger.info("creating web image");
-
-		try {
-			if (["image/jpeg"].includes(type)) {
-				webpublic = await convertSharpToWebp(img, 2048, 2048);
-			} else if (["image/webp"].includes(type)) {
-				webpublic = await convertSharpToWebp(img, 2048, 2048);
-			} else if (["image/png"].includes(type)) {
-				webpublic = await convertSharpToWebp(img, 2048, 2048, 100);
-			} else if (["image/svg+xml"].includes(type)) {
-				webpublic = await convertSharpToWebp(img, 2048, 2048);
-			} else {
-				logger.debug("web image not created (not an required image)");
-			}
-		} catch (err) {
-			logger.warn("web image not created (an error occured)", err as Error);
-		}
-	} else {
-		if (satisfyWebpublic)
-			logger.info("web image not created (original satisfies webpublic)");
-		else logger.info("web image not created (from remote)");
-	}
-	// #endregion webpublic
-
-	// #region thumbnail
-	let thumbnail: IImage | null = null;
-
-	try {
-		if (
-			[
-				"image/jpeg",
-				"image/webp",
-				"image/png",
-				"image/svg+xml",
-				"image/avif",
-			].includes(type)
-		) {
-			thumbnail = await convertSharpToWebp(img, 996, 560);
-		} else {
-			logger.debug("thumbnail not created (not an required file)");
-		}
-	} catch (err) {
-		logger.warn("thumbnail not created (an error occured)", err as Error);
-	}
-	// #endregion thumbnail
-
-	return {
-		webpublic,
-		thumbnail,
-	};
-}
-
-/**
- * Upload to ObjectStorage
- */
-async function upload(
-	key: string,
-	stream: fs.ReadStream | Buffer,
-	type: string,
-	filename?: string,
-) {
-	if (type === "image/apng") type = "image/png";
-	if (!FILE_TYPE_BROWSERSAFE.includes(type)) type = "application/octet-stream";
-
-	const meta = await fetchMeta();
-
-	const params = {
-		Bucket: meta.objectStorageBucket,
-		Key: key,
-		Body: stream,
-		ContentType: type,
-		CacheControl: "max-age=31536000, immutable",
-	} as S3.PutObjectRequest;
-
-	if (filename)
-		params.ContentDisposition = contentDisposition("inline", filename);
-	if (meta.objectStorageSetPublicRead) params.ACL = "public-read";
-
-	const s3 = getS3(meta);
-
-	const upload = s3.upload(params, {
-		partSize:
-			s3.endpoint.hostname === "storage.googleapis.com"
-				? 500 * 1024 * 1024
-				: 8 * 1024 * 1024,
-	});
-
-	const result = await upload.promise();
-	if (result)
-		logger.debug(
-			`Uploaded: ${result.Bucket}/${result.Key} => ${result.Location}`,
-		);
-}
-
-async function deleteOldFile(user: IRemoteUser) {
-	const q = DriveFiles.createQueryBuilder("file")
-		.where("file.userId = :userId", { userId: user.id })
-		.andWhere("file.isLink = FALSE");
-
-	if (user.avatarId) {
-		q.andWhere("file.id != :avatarId", { avatarId: user.avatarId });
-	}
-
-	if (user.bannerId) {
-		q.andWhere("file.id != :bannerId", { bannerId: user.bannerId });
-	}
-
-	q.orderBy("file.id", "ASC");
-
-	const oldFile = await q.getOne();
-
-	if (oldFile) {
-		deleteFile(oldFile, true);
-	}
-}
-
-type AddFileArgs = {
-	/** User who wish to add file */
-	user: {
-		id: User["id"];
-		host: User["host"];
-		driveCapacityOverrideMb: User["driveCapacityOverrideMb"];
-	} | null;
-	/** File path */
-	path: string;
-	/** Name */
-	name?: string | null;
-	/** Comment */
-	comment?: string | null;
-	/** Folder ID */
-	folderId?: any;
-	/** If set to true, forcibly upload the file even if there is a file with the same hash. */
-	force?: boolean;
-	/** Do not save file to local */
-	isLink?: boolean;
-	/** URL of source (URLからアップロードされた場合(ローカル/リモート)の元URL) */
-	url?: string | null;
-	/** URL of source (リモートインスタンスのURLからアップロードされた場合の元URL) */
-	uri?: string | null;
-	/** Mark file as sensitive */
-	sensitive?: boolean | null;
-
-	requestIp?: string | null;
-	requestHeaders?: Record<string, string> | null;
-};
-
-/**
- * Add file to drive
- *
- */
-export async function addFile({
-	user,
-	path,
-	name = null,
-	comment = null,
-	folderId = null,
-	force = false,
-	isLink = false,
-	url = null,
-	uri = null,
-	sensitive = null,
-	requestIp = null,
-	requestHeaders = null,
-}: AddFileArgs): Promise<DriveFile> {
-	let skipNsfwCheck = false;
-	const instance = await fetchMeta();
-	if (user == null) skipNsfwCheck = true;
-	if (instance.sensitiveMediaDetection === "none") skipNsfwCheck = true;
-	if (
-		user &&
-		instance.sensitiveMediaDetection === "local" &&
-		Users.isRemoteUser(user)
-	)
-		skipNsfwCheck = true;
-	if (
-		user &&
-		instance.sensitiveMediaDetection === "remote" &&
-		Users.isLocalUser(user)
-	)
-		skipNsfwCheck = true;
-
-	const info = await getFileInfo(path, {
-		skipSensitiveDetection: skipNsfwCheck,
-		sensitiveThreshold: // 感度が高いほどしきい値は低くすることになる
-			instance.sensitiveMediaDetectionSensitivity === "veryHigh"
-				? 0.1
-				: instance.sensitiveMediaDetectionSensitivity === "high"
-				? 0.3
-				: instance.sensitiveMediaDetectionSensitivity === "low"
-				? 0.7
-				: instance.sensitiveMediaDetectionSensitivity === "veryLow"
-				? 0.9
-				: 0.5,
-		sensitiveThresholdForPorn: 0.75,
-		enableSensitiveMediaDetectionForVideos:
-			instance.enableSensitiveMediaDetectionForVideos,
-	});
-	logger.info(`${JSON.stringify(info)}`);
-
-	// 現状 false positive が多すぎて実用に耐えない
-	//if (info.porn && instance.disallowUploadWhenPredictedAsPorn) {
-	//	throw new IdentifiableError('282f77bf-5816-4f72-9264-aa14d8261a21', 'Detected as porn.');
-	//}
-
-	// detect name
-	const detectedName =
-		name || (info.type.ext ? `untitled.${info.type.ext}` : "untitled");
-
-	if (user && !force) {
-		// Check if there is a file with the same hash
-		const much = await DriveFiles.findOneBy({
-			md5: info.md5,
-			userId: user.id,
-		});
-
-		if (much) {
-			logger.info(`file with same hash is found: ${much.id}`);
-			return much;
-		}
-	}
-
-	//#region Check drive usage
-	if (user && !isLink) {
-		const usage = await DriveFiles.calcDriveUsageOf(user);
-		const u = await Users.findOneBy({ id: user.id });
-
-		const instance = await fetchMeta();
-		let driveCapacity =
-			1024 *
-			1024 *
-			(Users.isLocalUser(user)
-				? instance.localDriveCapacityMb
-				: instance.remoteDriveCapacityMb);
-
-		if (Users.isLocalUser(user) && u?.driveCapacityOverrideMb != null) {
-			driveCapacity = 1024 * 1024 * u.driveCapacityOverrideMb;
-			logger.debug("drive capacity override applied");
-			logger.debug(
-				`overrideCap: ${driveCapacity}bytes, usage: ${usage}bytes, u+s: ${
-					usage + info.size
-				}bytes`,
-			);
-		}
-
-		logger.debug(`drive usage is ${usage} (max: ${driveCapacity})`);
-
-		// If usage limit exceeded
-		if (usage + info.size > driveCapacity) {
-			if (Users.isLocalUser(user)) {
-				throw new IdentifiableError(
-					"c6244ed2-a39a-4e1c-bf93-f0fbd7764fa6",
-					"No free space.",
-				);
-			} else {
-				// (アバターまたはバナーを含まず)最も古いファイルを削除する
-				deleteOldFile(
-					(await Users.findOneByOrFail({ id: user.id })) as IRemoteUser,
-				);
-			}
-		}
-	}
-	//#endregion
-
-	const fetchFolder = async () => {
-		if (!folderId) {
-			return null;
-		}
-
-		const driveFolder = await DriveFolders.findOneBy({
-			id: folderId,
-			userId: user ? user.id : IsNull(),
-		});
-
-		if (driveFolder == null) throw new Error("folder-not-found");
-
-		return driveFolder;
-	};
-
-	const properties: {
-		width?: number;
-		height?: number;
-		orientation?: number;
-	} = {};
-
-	if (info.width) {
-		properties["width"] = info.width;
-		properties["height"] = info.height;
-	}
-	if (info.orientation != null) {
-		properties["orientation"] = info.orientation;
-	}
-
-	const profile = user
-		? await UserProfiles.findOneBy({ userId: user.id })
-		: null;
-
-	const folder = await fetchFolder();
-
-	let file = new DriveFile();
-	file.id = genId();
-	file.createdAt = new Date();
-	file.userId = user ? user.id : null;
-	file.userHost = user ? user.host : null;
-	file.folderId = folder !== null ? folder.id : null;
-	file.comment = comment;
-	file.properties = properties;
-	file.blurhash = info.blurhash || null;
-	file.isLink = isLink;
-	file.requestIp = requestIp;
-	file.requestHeaders = requestHeaders;
-	file.maybeSensitive = info.sensitive;
-	file.maybePorn = info.porn;
-	file.isSensitive = user
-		? Users.isLocalUser(user) && profile!.alwaysMarkNsfw
-			? true
-			: sensitive !== null && sensitive !== undefined
-			? sensitive
-			: false
-		: false;
-
-	if (info.sensitive && profile!.autoSensitive) file.isSensitive = true;
-	if (info.sensitive && instance.setSensitiveFlagAutomatically)
-		file.isSensitive = true;
-
-	if (url !== null) {
-		file.src = url;
-
-		if (isLink) {
-			file.url = url;
-			// ローカルプロキシ用
-			file.accessKey = uuid();
-			file.thumbnailAccessKey = `thumbnail-${uuid()}`;
-			file.webpublicAccessKey = `webpublic-${uuid()}`;
-		}
-	}
-
-	if (uri !== null) {
-		file.uri = uri;
-	}
-
-	if (isLink) {
-		try {
-			file.size = 0;
-			file.md5 = info.md5;
-			file.name = detectedName;
-			file.type = info.type.mime;
-			file.storedInternal = false;
-
-			file = await DriveFiles.insert(file).then((x) =>
-				DriveFiles.findOneByOrFail(x.identifiers[0]),
-			);
-		} catch (err) {
-			// duplicate key error (when already registered)
-			if (isDuplicateKeyValueError(err)) {
-				logger.info(`already registered ${file.uri}`);
-
-				file = (await DriveFiles.findOneBy({
-					uri: file.uri!,
-					userId: user ? user.id : IsNull(),
-				})) as DriveFile;
-			} else {
-				logger.error(err as Error);
-				throw err;
-			}
-		}
-	} else {
-		file = await save(
-			file,
-			path,
-			detectedName,
-			info.type.mime,
-			info.md5,
-			info.size,
-		);
-	}
-
-	logger.succ(`drive file has been created ${file.id}`);
-
-	if (user) {
-		DriveFiles.pack(file, { self: true }).then((packedFile) => {
-			// Publish driveFileCreated event
-			publishMainStream(user.id, "driveFileCreated", packedFile);
-			publishDriveStream(user.id, "fileCreated", packedFile);
-		});
-	}
-
-	// 統計を更新
-	driveChart.update(file, true);
-	perUserDriveChart.update(file, true);
-	if (file.userHost !== null) {
-		instanceChart.updateDrive(file, true);
-	}
-
-	return file;
-}
diff --git a/packages/backend/src/services/drive/delete-file.ts b/packages/backend/src/services/drive/delete-file.ts
deleted file mode 100644
index 215270df69..0000000000
--- a/packages/backend/src/services/drive/delete-file.ts
+++ /dev/null
@@ -1,107 +0,0 @@
-import type { DriveFile } from "@/models/entities/drive-file.js";
-import { InternalStorage } from "./internal-storage.js";
-import { DriveFiles, Instances } from "@/models/index.js";
-import {
-	driveChart,
-	perUserDriveChart,
-	instanceChart,
-} from "@/services/chart/index.js";
-import { createDeleteObjectStorageFileJob } from "@/queue/index.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import { getS3 } from "./s3.js";
-import { v4 as uuid } from "uuid";
-
-export async function deleteFile(file: DriveFile, isExpired = false) {
-	if (file.storedInternal) {
-		InternalStorage.del(file.accessKey!);
-
-		if (file.thumbnailUrl) {
-			InternalStorage.del(file.thumbnailAccessKey!);
-		}
-
-		if (file.webpublicUrl) {
-			InternalStorage.del(file.webpublicAccessKey!);
-		}
-	} else if (!file.isLink) {
-		createDeleteObjectStorageFileJob(file.accessKey!);
-
-		if (file.thumbnailUrl) {
-			createDeleteObjectStorageFileJob(file.thumbnailAccessKey!);
-		}
-
-		if (file.webpublicUrl) {
-			createDeleteObjectStorageFileJob(file.webpublicAccessKey!);
-		}
-	}
-
-	postProcess(file, isExpired);
-}
-
-export async function deleteFileSync(file: DriveFile, isExpired = false) {
-	if (file.storedInternal) {
-		InternalStorage.del(file.accessKey!);
-
-		if (file.thumbnailUrl) {
-			InternalStorage.del(file.thumbnailAccessKey!);
-		}
-
-		if (file.webpublicUrl) {
-			InternalStorage.del(file.webpublicAccessKey!);
-		}
-	} else if (!file.isLink) {
-		const promises = [];
-
-		promises.push(deleteObjectStorageFile(file.accessKey!));
-
-		if (file.thumbnailUrl) {
-			promises.push(deleteObjectStorageFile(file.thumbnailAccessKey!));
-		}
-
-		if (file.webpublicUrl) {
-			promises.push(deleteObjectStorageFile(file.webpublicAccessKey!));
-		}
-
-		await Promise.all(promises);
-	}
-
-	postProcess(file, isExpired);
-}
-
-async function postProcess(file: DriveFile, isExpired = false) {
-	// リモートファイル期限切れ削除後は直リンクにする
-	if (isExpired && file.userHost !== null && file.uri != null) {
-		DriveFiles.update(file.id, {
-			isLink: true,
-			url: file.uri,
-			thumbnailUrl: null,
-			webpublicUrl: null,
-			storedInternal: false,
-			// ローカルプロキシ用
-			accessKey: uuid(),
-			thumbnailAccessKey: `thumbnail-${uuid()}`,
-			webpublicAccessKey: `webpublic-${uuid()}`,
-		});
-	} else {
-		DriveFiles.delete(file.id);
-	}
-
-	// 統計を更新
-	driveChart.update(file, false);
-	perUserDriveChart.update(file, false);
-	if (file.userHost !== null) {
-		instanceChart.updateDrive(file, false);
-	}
-}
-
-export async function deleteObjectStorageFile(key: string) {
-	const meta = await fetchMeta();
-
-	const s3 = getS3(meta);
-
-	await s3
-		.deleteObject({
-			Bucket: meta.objectStorageBucket!,
-			Key: key,
-		})
-		.promise();
-}
diff --git a/packages/backend/src/services/drive/generate-video-thumbnail.ts b/packages/backend/src/services/drive/generate-video-thumbnail.ts
deleted file mode 100644
index 356623e79a..0000000000
--- a/packages/backend/src/services/drive/generate-video-thumbnail.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import * as fs from "node:fs";
-import { createTempDir } from "@/misc/create-temp.js";
-import type { IImage } from "./image-processor.js";
-import { convertToWebp } from "./image-processor.js";
-import FFmpeg from "fluent-ffmpeg";
-
-export async function GenerateVideoThumbnail(source: string): Promise<IImage> {
-	const [dir, cleanup] = await createTempDir();
-
-	try {
-		await new Promise((res, rej) => {
-			FFmpeg({
-				source,
-			})
-				.on("end", res)
-				.on("error", rej)
-				.screenshot({
-					folder: dir,
-					filename: "out.png", // must have .png extension
-					count: 1,
-					timestamps: ["5%"],
-				});
-		});
-
-		return await convertToWebp(`${dir}/out.png`, 996, 560);
-	} finally {
-		cleanup();
-	}
-}
diff --git a/packages/backend/src/services/drive/image-processor.ts b/packages/backend/src/services/drive/image-processor.ts
deleted file mode 100644
index 55869f478f..0000000000
--- a/packages/backend/src/services/drive/image-processor.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import sharp from "sharp";
-
-export type IImage = {
-	data: Buffer;
-	ext: string | null;
-	type: string;
-};
-
-/**
- * Convert to WebP
- *   with resize, remove metadata, resolve orientation, stop animation
- */
-export async function convertToWebp(
-	path: string,
-	width: number,
-	height: number,
-	quality: number = 85,
-): Promise<IImage> {
-	return convertSharpToWebp(await sharp(path), width, height, quality);
-}
-
-export async function convertSharpToWebp(
-	sharp: sharp.Sharp,
-	width: number,
-	height: number,
-	quality: number = 85,
-): Promise<IImage> {
-	const data = await sharp
-		.resize(width, height, {
-			fit: "inside",
-			withoutEnlargement: true,
-		})
-		.rotate()
-		.webp({
-			quality,
-		})
-		.toBuffer();
-
-	return {
-		data,
-		ext: "webp",
-		type: "image/webp",
-	};
-}
diff --git a/packages/backend/src/services/drive/internal-storage.ts b/packages/backend/src/services/drive/internal-storage.ts
deleted file mode 100644
index bccb123be4..0000000000
--- a/packages/backend/src/services/drive/internal-storage.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import * as fs from "node:fs";
-import * as Path from "node:path";
-import { fileURLToPath } from "node:url";
-import { dirname } from "node:path";
-import config from "@/config/index.js";
-
-const _filename = fileURLToPath(import.meta.url);
-const _dirname = dirname(_filename);
-
-export class InternalStorage {
-	private static readonly path = Path.resolve(_dirname, "../../../../../files");
-
-	public static resolvePath = (key: string) =>
-		Path.resolve(InternalStorage.path, key);
-
-	public static read(key: string) {
-		return fs.createReadStream(InternalStorage.resolvePath(key));
-	}
-
-	public static saveFromPath(key: string, srcPath: string) {
-		fs.mkdirSync(InternalStorage.path, { recursive: true });
-		fs.copyFileSync(srcPath, InternalStorage.resolvePath(key));
-		return `${config.url}/files/${key}`;
-	}
-
-	public static saveFromBuffer(key: string, data: Buffer) {
-		fs.mkdirSync(InternalStorage.path, { recursive: true });
-		fs.writeFileSync(InternalStorage.resolvePath(key), data);
-		return `${config.url}/files/${key}`;
-	}
-
-	public static del(key: string) {
-		fs.unlink(InternalStorage.resolvePath(key), () => {});
-	}
-}
diff --git a/packages/backend/src/services/drive/logger.ts b/packages/backend/src/services/drive/logger.ts
deleted file mode 100644
index ebde2d7058..0000000000
--- a/packages/backend/src/services/drive/logger.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import Logger from "../logger.js";
-
-export const driveLogger = new Logger("drive", "blue");
diff --git a/packages/backend/src/services/drive/s3.ts b/packages/backend/src/services/drive/s3.ts
deleted file mode 100644
index ca356e9124..0000000000
--- a/packages/backend/src/services/drive/s3.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import { URL } from "node:url";
-import S3 from "aws-sdk/clients/s3.js";
-import type { Meta } from "@/models/entities/meta.js";
-import { getAgentByUrl } from "@/misc/fetch.js";
-
-export function getS3(meta: Meta) {
-	const u =
-		meta.objectStorageEndpoint != null
-			? `${meta.objectStorageUseSSL ? "https://" : "http://"}${
-					meta.objectStorageEndpoint
-			  }`
-			: `${meta.objectStorageUseSSL ? "https://" : "http://"}example.net`;
-
-	return new S3({
-		endpoint: meta.objectStorageEndpoint || undefined,
-		accessKeyId: meta.objectStorageAccessKey!,
-		secretAccessKey: meta.objectStorageSecretKey!,
-		region: meta.objectStorageRegion || undefined,
-		sslEnabled: meta.objectStorageUseSSL,
-		s3ForcePathStyle: !meta.objectStorageEndpoint // AWS with endPoint omitted
-			? false
-			: meta.objectStorageS3ForcePathStyle,
-		httpOptions: {
-			agent: getAgentByUrl(new URL(u), !meta.objectStorageUseProxy),
-		},
-	});
-}
diff --git a/packages/backend/src/services/drive/upload-from-url.ts b/packages/backend/src/services/drive/upload-from-url.ts
deleted file mode 100644
index 9d71757e35..0000000000
--- a/packages/backend/src/services/drive/upload-from-url.ts
+++ /dev/null
@@ -1,81 +0,0 @@
-import { URL } from "node:url";
-import type { User } from "@/models/entities/user.js";
-import { createTemp } from "@/misc/create-temp.js";
-import { downloadUrl } from "@/misc/download-url.js";
-import type { DriveFolder } from "@/models/entities/drive-folder.js";
-import type { DriveFile } from "@/models/entities/drive-file.js";
-import { DriveFiles } from "@/models/index.js";
-import { driveLogger } from "./logger.js";
-import { addFile } from "./add-file.js";
-
-const logger = driveLogger.createSubLogger("downloader");
-
-type Args = {
-	url: string;
-	user: { id: User["id"]; host: User["host"] } | null;
-	folderId?: DriveFolder["id"] | null;
-	uri?: string | null;
-	sensitive?: boolean;
-	force?: boolean;
-	isLink?: boolean;
-	comment?: string | null;
-	requestIp?: string | null;
-	requestHeaders?: Record<string, string> | null;
-};
-
-export async function uploadFromUrl({
-	url,
-	user,
-	folderId = null,
-	uri = null,
-	sensitive = false,
-	force = false,
-	isLink = false,
-	comment = null,
-	requestIp = null,
-	requestHeaders = null,
-}: Args): Promise<DriveFile> {
-	let name = new URL(url).pathname.split("/").pop() || null;
-	if (name == null || !DriveFiles.validateFileName(name)) {
-		name = null;
-	}
-
-	// If the comment is same as the name, skip comment
-	// (image.name is passed in when receiving attachment)
-	if (comment !== null && name === comment) {
-		comment = null;
-	}
-
-	// Create temp file
-	const [path, cleanup] = await createTemp();
-
-	try {
-		// write content at URL to temp file
-		await downloadUrl(url, path);
-
-		const driveFile = await addFile({
-			user,
-			path,
-			name,
-			comment,
-			folderId,
-			force,
-			isLink,
-			url,
-			uri,
-			sensitive,
-			requestIp,
-			requestHeaders,
-		});
-		logger.succ(`Got: ${driveFile.id}`);
-		return driveFile!;
-	} catch (e) {
-		logger.error(`Failed to create drive file: ${e}`, {
-			url: url,
-			e: e,
-		});
-		throw e;
-	} finally {
-		cleanup();
-	}
-}
diff --git a/packages/backend/src/services/fetch-instance-metadata.ts b/packages/backend/src/services/fetch-instance-metadata.ts
deleted file mode 100644
index 79354448f5..0000000000
--- a/packages/backend/src/services/fetch-instance-metadata.ts
+++ /dev/null
@@ -1,321 +0,0 @@
-import { URL } from "node:url";
-import { JSDOM } from "jsdom";
-import fetch from "node-fetch";
-import tinycolor from "tinycolor2";
-import { getJson, getHtml, getAgentByUrl } from "@/misc/fetch.js";
-import type { Instance } from "@/models/entities/instance.js";
-import { Instances } from "@/models/index.js";
-import { getFetchInstanceMetadataLock } from "@/misc/app-lock.js";
-import Logger from "./logger.js";
-import type { DOMWindow } from "jsdom";
-
-const logger = new Logger("metadata", "cyan");
-
-export async function fetchInstanceMetadata(
-	instance: Instance,
-	force = false,
-): Promise<void> {
-	const unlock = await getFetchInstanceMetadataLock(instance.host);
-
-	if (!force) {
-		const _instance = await Instances.findOneBy({ host: instance.host });
-		const now = Date.now();
-		if (
-			_instance?.infoUpdatedAt &&
-			now - _instance.infoUpdatedAt.getTime() < 1000 * 60 * 60 * 24
-		) {
-			unlock();
-			return;
-		}
-	}
-
-	logger.info(`Fetching metadata of ${instance.host} ...`);
-
-	try {
-		const [info, dom, manifest] = await Promise.all([
-			fetchNodeinfo(instance).catch(() => null),
-			fetchDom(instance).catch(() => null),
-			fetchManifest(instance).catch(() => null),
-		]);
-
-		const [favicon, icon, themeColor, name, description] = await Promise.all([
-			fetchFaviconUrl(instance, dom).catch(() => null),
-			fetchIconUrl(instance, dom, manifest).catch(() => null),
-			getThemeColor(info, dom, manifest).catch(() => null),
-			getSiteName(info, dom, manifest).catch(() => null),
-			getDescription(info, dom, manifest).catch(() => null),
-		]);
-
-		logger.succ(`Successfuly fetched metadata of ${instance.host}`);
-
-		const updates = {
-			infoUpdatedAt: new Date(),
-		} as Record<string, any>;
-
-		if (info) {
-			updates.softwareName = info.software?.name.toLowerCase();
-			updates.softwareVersion = info.software?.version;
-			updates.openRegistrations = info.openRegistrations;
-			updates.maintainerName = info.metadata
-				? info.metadata.maintainer
-					? info.metadata.maintainer.name || null
-					: null
-				: null;
-			updates.maintainerEmail = info.metadata
-				? info.metadata.maintainer
-					? info.metadata.maintainer.email || null
-					: null
-				: null;
-		}
-
-		if (name) updates.name = name;
-		if (description) updates.description = description;
-		if (icon || favicon) updates.iconUrl = icon || favicon;
-		if (favicon) updates.faviconUrl = favicon;
-		if (themeColor) updates.themeColor = themeColor;
-
-		await Instances.update(instance.id, updates);
-
-		logger.succ(`Successfuly updated metadata of ${instance.host}`);
-	} catch (e) {
-		logger.error(`Failed to update metadata of ${instance.host}: ${e}`);
-	} finally {
-		unlock();
-	}
-}
-
-type NodeInfo = {
-	openRegistrations?: any;
-	software?: {
-		name?: any;
-		version?: any;
-	};
-	metadata?: {
-		name?: any;
-		nodeName?: any;
-		nodeDescription?: any;
-		description?: any;
-		maintainer?: {
-			name?: any;
-			email?: any;
-		};
-	};
-};
-
-async function fetchNodeinfo(instance: Instance): Promise<NodeInfo> {
-	logger.info(`Fetching nodeinfo of ${instance.host} ...`);
-
-	try {
-		const wellknown = (await getJson(
-			`https://${instance.host}/.well-known/nodeinfo`,
-		).catch((e) => {
-			if (e.statusCode === 404) {
-				throw new Error("No nodeinfo provided");
-			} else {
-				throw new Error(e.statusCode || e.message);
-			}
-		})) as Record<string, unknown>;
-
-		if (wellknown.links == null || !Array.isArray(wellknown.links)) {
-			throw new Error("No wellknown links");
-		}
-
-		const links = wellknown.links as any[];
-
-		const lnik1_0 = links.find(
-			(link) => link.rel === "http://nodeinfo.diaspora.software/ns/schema/1.0",
-		);
-		const lnik2_0 = links.find(
-			(link) => link.rel === "http://nodeinfo.diaspora.software/ns/schema/2.0",
-		);
-		const lnik2_1 = links.find(
-			(link) => link.rel === "http://nodeinfo.diaspora.software/ns/schema/2.1",
-		);
-		const link = lnik2_1 || lnik2_0 || lnik1_0;
-
-		if (link == null) {
-			throw new Error("No nodeinfo link provided");
-		}
-
-		const info = await getJson(link.href).catch((e) => {
-			throw new Error(e.statusCode || e.message);
-		});
-
-		logger.succ(`Successfuly fetched nodeinfo of ${instance.host}`);
-
-		return info as NodeInfo;
-	} catch (e) {
-		logger.error(`Failed to fetch nodeinfo of ${instance.host}: ${e.message}`);
-
-		throw e;
-	}
-}
-
-async function fetchDom(instance: Instance): Promise<DOMWindow["document"]> {
-	logger.info(`Fetching HTML of ${instance.host} ...`);
-
-	const url = `https://${instance.host}`;
-
-	const html = await getHtml(url);
-
-	const { window } = new JSDOM(html);
-	const doc = window.document;
-
-	return doc;
-}
-
-async function fetchManifest(
-	instance: Instance,
-): Promise<Record<string, unknown> | null> {
-	const url = `https://${instance.host}`;
-
-	const manifestUrl = `${url}/manifest.json`;
-
-	const manifest = (await getJson(manifestUrl)) as Record<string, unknown>;
-
-	return manifest;
-}
-
-async function fetchFaviconUrl(
-	instance: Instance,
-	doc: DOMWindow["document"] | null,
-): Promise<string | null> {
-	const url = `https://${instance.host}`;
-
-	if (doc) {
-		// https://github.com/misskey-dev/misskey/pull/8220#issuecomment-1025104043
-		const href = Array.from(doc.getElementsByTagName("link"))
-			.reverse()
-			.find((link) => link.relList.contains("icon"))?.href;
-
-		if (href) {
-			return new URL(href, url).href;
-		}
-	}
-
-	const faviconUrl = `${url}/favicon.ico`;
-
-	const favicon = await fetch(faviconUrl, {
-		// TODO
-		//timeout: 10000,
-		agent: getAgentByUrl,
-	});
-
-	if (favicon.ok) {
-		return faviconUrl;
-	}
-
-	return null;
-}
-
-async function fetchIconUrl(
-	instance: Instance,
-	doc: DOMWindow["document"] | null,
-	manifest: Record<string, any> | null,
-): Promise<string | null> {
-	if (manifest?.icons && manifest.icons.length > 0 && manifest.icons[0].src) {
-		const url = `https://${instance.host}`;
-		return new URL(manifest.icons[0].src, url).href;
-	}
-
-	if (doc) {
-		const url = `https://${instance.host}`;
-
-		// https://github.com/misskey-dev/misskey/pull/8220#issuecomment-1025104043
-		const links = Array.from(doc.getElementsByTagName("link")).reverse();
-		// https://github.com/misskey-dev/misskey/pull/8220/files/0ec4eba22a914e31b86874f12448f88b3e58dd5a#r796487559
-		const href = [
-			links.find((link) =>
-				link.relList.contains("apple-touch-icon-precomposed"),
-			)?.href,
-			links.find((link) => link.relList.contains("apple-touch-icon"))?.href,
-			links.find((link) => link.relList.contains("icon"))?.href,
-		].find((href) => href);
-
-		if (href) {
-			return new URL(href, url).href;
-		}
-	}
-
-	return null;
-}
-
-async function getThemeColor(
-	info: NodeInfo | null,
-	doc: DOMWindow["document"] | null,
-	manifest: Record<string, any> | null,
-): Promise<string | null> {
-	const themeColor =
-		info?.metadata?.themeColor ||
-		doc?.querySelector('meta[name="theme-color"]')?.getAttribute("content") ||
-		manifest?.theme_color;
-
-	if (themeColor) {
-		const color = new tinycolor(themeColor);
-		if (color.isValid()) return color.toHexString();
-	}
-
-	return null;
-}
-
-async function getSiteName(
-	info: NodeInfo | null,
-	doc: DOMWindow["document"] | null,
-	manifest: Record<string, any> | null,
-): Promise<string | null> {
-	if (info?.metadata) {
-		if (info.metadata.nodeName || info.metadata.name) {
-			return info.metadata.nodeName || info.metadata.name;
-		}
-	}
-
-	if (doc) {
-		const og = doc
-			.querySelector('meta[property="og:title"]')
-			?.getAttribute("content");
-
-		if (og) {
-			return og;
-		}
-	}
-
-	if (manifest) {
-		return manifest.name || manifest.short_name;
-	}
-
-	return null;
-}
-
-async function getDescription(
-	info: NodeInfo | null,
-	doc: DOMWindow["document"] | null,
-	manifest: Record<string, any> | null,
-): Promise<string | null> {
-	if (info?.metadata) {
-		if (info.metadata.nodeDescription || info.metadata.description) {
-			return info.metadata.nodeDescription || info.metadata.description;
-		}
-	}
-
-	if (doc) {
-		const meta = doc
-			.querySelector('meta[name="description"]')
-			?.getAttribute("content");
-		if (meta) {
-			return meta;
-		}
-
-		const og = doc
-			.querySelector('meta[property="og:description"]')
-			?.getAttribute("content");
-		if (og) {
-			return og;
-		}
-	}
-
-	if (manifest) {
-		return manifest.name || manifest.short_name;
-	}
-
-	return null;
-}
diff --git a/packages/backend/src/services/following/create.ts b/packages/backend/src/services/following/create.ts
deleted file mode 100644
index 61a8c6b268..0000000000
--- a/packages/backend/src/services/following/create.ts
+++ /dev/null
@@ -1,276 +0,0 @@
-import { publishMainStream, publishUserEvent } from "@/services/stream.js";
-import { renderActivity } from "@/remote/activitypub/renderer/index.js";
-import renderFollow from "@/remote/activitypub/renderer/follow.js";
-import renderAccept from "@/remote/activitypub/renderer/accept.js";
-import renderReject from "@/remote/activitypub/renderer/reject.js";
-import { deliver } from "@/queue/index.js";
-import createFollowRequest from "./requests/create.js";
-import { registerOrFetchInstanceDoc } from "../register-or-fetch-instance-doc.js";
-import Logger from "../logger.js";
-import { IdentifiableError } from "@/misc/identifiable-error.js";
-import type { User } from "@/models/entities/user.js";
-import {
-	Followings,
-	Users,
-	FollowRequests,
-	Blockings,
-	Instances,
-	UserProfiles,
-} from "@/models/index.js";
-import {
-	instanceChart,
-	perUserFollowingChart,
-} from "@/services/chart/index.js";
-import { genId } from "@/misc/gen-id.js";
-import { createNotification } from "../create-notification.js";
-import { isDuplicateKeyValueError } from "@/misc/is-duplicate-key-value-error.js";
-import type { Packed } from "@/misc/schema.js";
-import { getActiveWebhooks } from "@/misc/webhook-cache.js";
-import { webhookDeliver } from "@/queue/index.js";
-
-const logger = new Logger("following/create");
-
-export async function insertFollowingDoc(
-	followee: {
-		id: User["id"];
-		host: User["host"];
-		uri: User["host"];
-		inbox: User["inbox"];
-		sharedInbox: User["sharedInbox"];
-	},
-	follower: {
-		id: User["id"];
-		host: User["host"];
-		uri: User["host"];
-		inbox: User["inbox"];
-		sharedInbox: User["sharedInbox"];
-	},
-) {
-	if (follower.id === followee.id) return;
-
-	let alreadyFollowed = false;
-
-	await Followings.insert({
-		id: genId(),
-		createdAt: new Date(),
-		followerId: follower.id,
-		followeeId: followee.id,
-
-		// 非正規化
-		followerHost: follower.host,
-		followerInbox: Users.isRemoteUser(follower) ? follower.inbox : null,
-		followerSharedInbox: Users.isRemoteUser(follower)
-			? follower.sharedInbox
-			: null,
-		followeeHost: followee.host,
-		followeeInbox: Users.isRemoteUser(followee) ? followee.inbox : null,
-		followeeSharedInbox: Users.isRemoteUser(followee)
-			? followee.sharedInbox
-			: null,
-	}).catch((e) => {
-		if (
-			isDuplicateKeyValueError(e) &&
-			Users.isRemoteUser(follower) &&
-			Users.isLocalUser(followee)
-		) {
-			logger.info(`Insert duplicated ignore. ${follower.id} => ${followee.id}`);
-			alreadyFollowed = true;
-		} else {
-			throw e;
-		}
-	});
-
-	const req = await FollowRequests.findOneBy({
-		followeeId: followee.id,
-		followerId: follower.id,
-	});
-
-	if (req) {
-		await FollowRequests.delete({
-			followeeId: followee.id,
-			followerId: follower.id,
-		});
-
-		// Create notification that request was accepted.
-		createNotification(follower.id, "followRequestAccepted", {
-			notifierId: followee.id,
-		});
-	}
-
-	if (alreadyFollowed) return;
-
-	//#region Increment counts
-	await Promise.all([
-		Users.increment({ id: follower.id }, "followingCount", 1),
-		Users.increment({ id: followee.id }, "followersCount", 1),
-	]);
-	//#endregion
-
-	//#region Update instance stats
-	if (Users.isRemoteUser(follower) && Users.isLocalUser(followee)) {
-		registerOrFetchInstanceDoc(follower.host).then((i) => {
-			Instances.increment({ id: i.id }, "followingCount", 1);
-			instanceChart.updateFollowing(i.host, true);
-		});
-	} else if (Users.isLocalUser(follower) && Users.isRemoteUser(followee)) {
-		registerOrFetchInstanceDoc(followee.host).then((i) => {
-			Instances.increment({ id: i.id }, "followersCount", 1);
-			instanceChart.updateFollowers(i.host, true);
-		});
-	}
-	//#endregion
-
-	perUserFollowingChart.update(follower, followee, true);
-
-	// Publish follow event
-	if (Users.isLocalUser(follower)) {
-		Users.pack(followee.id, follower, {
-			detail: true,
-		}).then(async (packed) => {
-			publishUserEvent(
-				follower.id,
-				"follow",
-				packed as Packed<"UserDetailedNotMe">,
-			);
-			publishMainStream(
-				follower.id,
-				"follow",
-				packed as Packed<"UserDetailedNotMe">,
-			);
-
-			const webhooks = (await getActiveWebhooks()).filter(
-				(x) => x.userId === follower.id && x.on.includes("follow"),
-			);
-			for (const webhook of webhooks) {
-				webhookDeliver(webhook, "follow", {
-					user: packed,
-				});
-			}
-		});
-	}
-
-	// Publish followed event
-	if (Users.isLocalUser(followee)) {
-		Users.pack(follower.id, followee).then(async (packed) => {
-			publishMainStream(followee.id, "followed", packed);
-
-			const webhooks = (await getActiveWebhooks()).filter(
-				(x) => x.userId === followee.id && x.on.includes("followed"),
-			);
-			for (const webhook of webhooks) {
-				webhookDeliver(webhook, "followed", {
-					user: packed,
-				});
-			}
-		});
-
-		// 通知を作成
-		createNotification(followee.id, "follow", {
-			notifierId: follower.id,
-		});
-	}
-}
-
-export default async function (
-	_follower: { id: User["id"] },
-	_followee: { id: User["id"] },
-	requestId?: string,
-) {
-	const [follower, followee] = await Promise.all([
-		Users.findOneByOrFail({ id: _follower.id }),
-		Users.findOneByOrFail({ id: _followee.id }),
-	]);
-
-	// check blocking
-	const [blocking, blocked] = await Promise.all([
-		Blockings.findOneBy({
-			blockerId: follower.id,
-			blockeeId: followee.id,
-		}),
-		Blockings.findOneBy({
-			blockerId: followee.id,
-			blockeeId: follower.id,
-		}),
-	]);
-
-	if (Users.isRemoteUser(follower) && Users.isLocalUser(followee) && blocked) {
-		// リモートフォローを受けてブロックしていた場合は、エラーにするのではなくRejectを送り返しておしまい。
-		const content = renderActivity(
-			renderReject(renderFollow(follower, followee, requestId), followee),
-		);
-		deliver(followee, content, follower.inbox);
-		return;
-	} else if (
-		Users.isRemoteUser(follower) &&
-		Users.isLocalUser(followee) &&
-		blocking
-	) {
-		// リモートフォローを受けてブロックされているはずの場合だったら、ブロック解除しておく。
-		await Blockings.delete(blocking.id);
-	} else {
-		// それ以外は単純に例外
-		if (blocking)
-			throw new IdentifiableError(
-				"710e8fb0-b8c3-4922-be49-d5d93d8e6a6e",
-				"blocking",
-			);
-		if (blocked)
-			throw new IdentifiableError(
-				"3338392a-f764-498d-8855-db939dcf8c48",
-				"blocked",
-			);
-	}
-
-	const followeeProfile = await UserProfiles.findOneByOrFail({
-		userId: followee.id,
-	});
-
-	// フォロー対象が鍵アカウントである or
-	// フォロワーがBotであり、フォロー対象がBotからのフォローに慎重である or
-	// フォロワーがローカルユーザーであり、フォロー対象がリモートユーザーである
-	// 上記のいずれかに当てはまる場合はすぐフォローせずにフォローリクエストを発行しておく
-	if (
-		followee.isLocked ||
-		(followeeProfile.carefulBot && follower.isBot) ||
-		(Users.isLocalUser(follower) && Users.isRemoteUser(followee))
-	) {
-		let autoAccept = false;
-
-		// 鍵アカウントであっても、既にフォローされていた場合はスルー
-		const following = await Followings.findOneBy({
-			followerId: follower.id,
-			followeeId: followee.id,
-		});
-		if (following) {
-			autoAccept = true;
-		}
-
-		// フォローしているユーザーは自動承認オプション
-		if (
-			!autoAccept &&
-			Users.isLocalUser(followee) &&
-			followeeProfile.autoAcceptFollowed
-		) {
-			const followed = await Followings.findOneBy({
-				followerId: followee.id,
-				followeeId: follower.id,
-			});
-
-			if (followed) autoAccept = true;
-		}
-
-		if (!autoAccept) {
-			await createFollowRequest(follower, followee, requestId);
-			return;
-		}
-	}
-
-	await insertFollowingDoc(followee, follower);
-
-	if (Users.isRemoteUser(follower) && Users.isLocalUser(followee)) {
-		const content = renderActivity(
-			renderAccept(renderFollow(follower, followee, requestId), followee),
-		);
-		deliver(followee, content, follower.inbox);
-	}
-}
diff --git a/packages/backend/src/services/following/delete.ts b/packages/backend/src/services/following/delete.ts
deleted file mode 100644
index fae4bd3cec..0000000000
--- a/packages/backend/src/services/following/delete.ts
+++ /dev/null
@@ -1,113 +0,0 @@
-import { publishMainStream, publishUserEvent } from "@/services/stream.js";
-import { renderActivity } from "@/remote/activitypub/renderer/index.js";
-import renderFollow from "@/remote/activitypub/renderer/follow.js";
-import renderUndo from "@/remote/activitypub/renderer/undo.js";
-import renderReject from "@/remote/activitypub/renderer/reject.js";
-import { deliver, webhookDeliver } from "@/queue/index.js";
-import Logger from "../logger.js";
-import { registerOrFetchInstanceDoc } from "../register-or-fetch-instance-doc.js";
-import type { User } from "@/models/entities/user.js";
-import { Followings, Users, Instances } from "@/models/index.js";
-import {
-	instanceChart,
-	perUserFollowingChart,
-} from "@/services/chart/index.js";
-import { getActiveWebhooks } from "@/misc/webhook-cache.js";
-
-const logger = new Logger("following/delete");
-
-export default async function (
-	follower: {
-		id: User["id"];
-		host: User["host"];
-		uri: User["host"];
-		inbox: User["inbox"];
-		sharedInbox: User["sharedInbox"];
-	},
-	followee: {
-		id: User["id"];
-		host: User["host"];
-		uri: User["host"];
-		inbox: User["inbox"];
-		sharedInbox: User["sharedInbox"];
-	},
-	silent = false,
-) {
-	const following = await Followings.findOneBy({
-		followerId: follower.id,
-		followeeId: followee.id,
-	});
-
-	if (following == null) {
-		logger.warn(
-			"フォロー解除がリクエストされましたがフォローしていませんでした",
-		);
-		return;
-	}
-
-	await Followings.delete(following.id);
-
-	decrementFollowing(follower, followee);
-
-	// Publish unfollow event
-	if (!silent && Users.isLocalUser(follower)) {
-		Users.pack(followee.id, follower, {
-			detail: true,
-		}).then(async (packed) => {
-			publishUserEvent(follower.id, "unfollow", packed);
-			publishMainStream(follower.id, "unfollow", packed);
-
-			const webhooks = (await getActiveWebhooks()).filter(
-				(x) => x.userId === follower.id && x.on.includes("unfollow"),
-			);
-			for (const webhook of webhooks) {
-				webhookDeliver(webhook, "unfollow", {
-					user: packed,
-				});
-			}
-		});
-	}
-
-	if (Users.isLocalUser(follower) && Users.isRemoteUser(followee)) {
-		const content = renderActivity(
-			renderUndo(renderFollow(follower, followee), follower),
-		);
-		deliver(follower, content, followee.inbox);
-	}
-
-	if (Users.isLocalUser(followee) && Users.isRemoteUser(follower)) {
-		// local user has null host
-		const content = renderActivity(
-			renderReject(renderFollow(follower, followee), followee),
-		);
-		deliver(followee, content, follower.inbox);
-	}
-}
-
-export async function decrementFollowing(
-	follower: { id: User["id"]; host: User["host"] },
-	followee: { id: User["id"]; host: User["host"] },
-) {
-	//#region Decrement following / followers counts
-	await Promise.all([
-		Users.decrement({ id: follower.id }, "followingCount", 1),
-		Users.decrement({ id: followee.id }, "followersCount", 1),
-	]);
-	//#endregion
-
-	//#region Update instance stats
-	if (Users.isRemoteUser(follower) && Users.isLocalUser(followee)) {
-		registerOrFetchInstanceDoc(follower.host).then((i) => {
-			Instances.decrement({ id: i.id }, "followingCount", 1);
-			instanceChart.updateFollowing(i.host, false);
-		});
-	} else if (Users.isLocalUser(follower) && Users.isRemoteUser(followee)) {
-		registerOrFetchInstanceDoc(followee.host).then((i) => {
-			Instances.decrement({ id: i.id }, "followersCount", 1);
-			instanceChart.updateFollowers(i.host, false);
-		});
-	}
-	//#endregion
-
-	perUserFollowingChart.update(follower, followee, false);
-}
diff --git a/packages/backend/src/services/following/reject.ts b/packages/backend/src/services/following/reject.ts
deleted file mode 100644
index 7464219bf6..0000000000
--- a/packages/backend/src/services/following/reject.ts
+++ /dev/null
@@ -1,134 +0,0 @@
-import { renderActivity } from "@/remote/activitypub/renderer/index.js";
-import renderFollow from "@/remote/activitypub/renderer/follow.js";
-import renderReject from "@/remote/activitypub/renderer/reject.js";
-import { deliver, webhookDeliver } from "@/queue/index.js";
-import { publishMainStream, publishUserEvent } from "@/services/stream.js";
-import type { ILocalUser, IRemoteUser } from "@/models/entities/user.js";
-import { User } from "@/models/entities/user.js";
-import { Users, FollowRequests, Followings } from "@/models/index.js";
-import { decrementFollowing } from "./delete.js";
-import { getActiveWebhooks } from "@/misc/webhook-cache.js";
-
-type Local =
-	| ILocalUser
-	| {
-			id: ILocalUser["id"];
-			host: ILocalUser["host"];
-			uri: ILocalUser["uri"];
-	  };
-type Remote =
-	| IRemoteUser
-	| {
-			id: IRemoteUser["id"];
-			host: IRemoteUser["host"];
-			uri: IRemoteUser["uri"];
-			inbox: IRemoteUser["inbox"];
-	  };
-type Both = Local | Remote;
-
-/**
- * API following/request/reject
- */
-export async function rejectFollowRequest(user: Local, follower: Both) {
-	if (Users.isRemoteUser(follower)) {
-		deliverReject(user, follower);
-	}
-
-	await removeFollowRequest(user, follower);
-
-	if (Users.isLocalUser(follower)) {
-		publishUnfollow(user, follower);
-	}
-}
-
-/**
- * API following/reject
- */
-export async function rejectFollow(user: Local, follower: Both) {
-	if (Users.isRemoteUser(follower)) {
-		deliverReject(user, follower);
-	}
-
-	await removeFollow(user, follower);
-
-	if (Users.isLocalUser(follower)) {
-		publishUnfollow(user, follower);
-	}
-}
-
-/**
- * AP Reject/Follow
- */
-export async function remoteReject(actor: Remote, follower: Local) {
-	await removeFollowRequest(actor, follower);
-	await removeFollow(actor, follower);
-	publishUnfollow(actor, follower);
-}
-
-/**
- * Remove follow request record
- */
-async function removeFollowRequest(followee: Both, follower: Both) {
-	const request = await FollowRequests.findOneBy({
-		followeeId: followee.id,
-		followerId: follower.id,
-	});
-
-	if (!request) return;
-
-	await FollowRequests.delete(request.id);
-}
-
-/**
- * Remove follow record
- */
-async function removeFollow(followee: Both, follower: Both) {
-	const following = await Followings.findOneBy({
-		followeeId: followee.id,
-		followerId: follower.id,
-	});
-
-	if (!following) return;
-
-	await Followings.delete(following.id);
-	decrementFollowing(follower, followee);
-}
-
-/**
- * Deliver Reject to remote
- */
-async function deliverReject(followee: Local, follower: Remote) {
-	const request = await FollowRequests.findOneBy({
-		followeeId: followee.id,
-		followerId: follower.id,
-	});
-
-	const content = renderActivity(
-		renderReject(
-			renderFollow(follower, followee, request?.requestId || undefined),
-			followee,
-		),
-	);
-	deliver(followee, content, follower.inbox);
-}
-
-/**
- * Publish unfollow to local
- */
-async function publishUnfollow(followee: Both, follower: Local) {
-	const packedFollowee = await Users.pack(followee.id, follower, {
-		detail: true,
-	});
-
-	publishUserEvent(follower.id, "unfollow", packedFollowee);
-	publishMainStream(follower.id, "unfollow", packedFollowee);
-
-	const webhooks = (await getActiveWebhooks()).filter(
-		(x) => x.userId === follower.id && x.on.includes("unfollow"),
-	);
-	for (const webhook of webhooks) {
-		webhookDeliver(webhook, "unfollow", {
-			user: packedFollowee,
-		});
-	}
-}
diff --git a/packages/backend/src/services/following/requests/accept-all.ts b/packages/backend/src/services/following/requests/accept-all.ts
deleted file mode 100644
index 2692433799..0000000000
--- a/packages/backend/src/services/following/requests/accept-all.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import accept from "./accept.js";
-import type { User } from "@/models/entities/user.js";
-import { FollowRequests, Users } from "@/models/index.js";
-
-/**
- * Approve all follow requests for the specified user
- * @param user User.
- */
-export default async function (user: {
-	id: User["id"];
-	host: User["host"];
-	uri: User["host"];
-	inbox: User["inbox"];
-	sharedInbox: User["sharedInbox"];
-}) {
-	const requests = await FollowRequests.findBy({
-		followeeId: user.id,
-	});
-
-	for (const request of requests) {
-		const follower = await Users.findOneByOrFail({ id: request.followerId });
-		accept(user, follower);
-	}
-}
diff --git a/packages/backend/src/services/following/requests/accept.ts b/packages/backend/src/services/following/requests/accept.ts
deleted file mode 100644
index 6aa17b09ad..0000000000
--- a/packages/backend/src/services/following/requests/accept.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import { renderActivity } from "@/remote/activitypub/renderer/index.js";
-import renderFollow from "@/remote/activitypub/renderer/follow.js";
-import renderAccept from "@/remote/activitypub/renderer/accept.js";
-import { deliver } from "@/queue/index.js";
-import { publishMainStream } from "@/services/stream.js";
-import { insertFollowingDoc } from "../create.js";
-import type { User, CacheableUser } from "@/models/entities/user.js";
-import { ILocalUser } from "@/models/entities/user.js";
-import { FollowRequests, Users } from "@/models/index.js";
-import { IdentifiableError } from "@/misc/identifiable-error.js";
-
-export default async function (
-	followee: {
-		id: User["id"];
-		host: User["host"];
-		uri: User["host"];
-		inbox: User["inbox"];
-		sharedInbox: User["sharedInbox"];
-	},
-	follower: CacheableUser,
-) {
-	const request = await FollowRequests.findOneBy({
-		followeeId: followee.id,
-		followerId: follower.id,
-	});
-
-	if (request == null) {
-		throw new IdentifiableError(
-			"8884c2dd-5795-4ac9-b27e-6a01d38190f9",
-			"No follow request.",
-		);
-	}
-
-	await insertFollowingDoc(followee, follower);
-
-	if (Users.isRemoteUser(follower) && Users.isLocalUser(followee)) {
-		const content = renderActivity(
-			renderAccept(
-				renderFollow(follower, followee, request.requestId!),
-				followee,
-			),
-		);
-		deliver(followee, content, follower.inbox);
-	}
-
-	Users.pack(followee.id, followee, {
-		detail: true,
-	}).then((packed) => publishMainStream(followee.id, "meUpdated", packed));
-}
diff --git a/packages/backend/src/services/following/requests/cancel.ts b/packages/backend/src/services/following/requests/cancel.ts
deleted file mode 100644
index 00daae380d..0000000000
--- a/packages/backend/src/services/following/requests/cancel.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import { renderActivity } from "@/remote/activitypub/renderer/index.js";
-import renderFollow from "@/remote/activitypub/renderer/follow.js";
-import renderUndo from "@/remote/activitypub/renderer/undo.js";
-import { deliver } from "@/queue/index.js";
-import { publishMainStream } from "@/services/stream.js";
-import { IdentifiableError } from "@/misc/identifiable-error.js";
-import type { User } from "@/models/entities/user.js";
-import { ILocalUser } from "@/models/entities/user.js";
-import { Users, FollowRequests } from "@/models/index.js";
-
-export default async function (
-	followee: {
-		id: User["id"];
-		host: User["host"];
-		uri: User["host"];
-		inbox: User["inbox"];
-	},
-	follower: { id: User["id"]; host: User["host"]; uri: User["host"] },
-) {
-	if (Users.isRemoteUser(followee)) {
-		const content = renderActivity(
-			renderUndo(renderFollow(follower, followee), follower),
-		);
-
-		if (Users.isLocalUser(follower)) {
-			// 本来このチェックは不要だけどTSに怒られるので
-			deliver(follower, content, followee.inbox);
-		}
-	}
-
-	const request = await FollowRequests.findOneBy({
-		followeeId: followee.id,
-		followerId: follower.id,
-	});
-
-	if (request == null) {
-		throw new IdentifiableError(
-			"17447091-ce07-46dd-b331-c1fd4f15b1e7",
-			"request not found",
-		);
-	}
-
-	await FollowRequests.delete({
-		followeeId: followee.id,
-		followerId: follower.id,
-	});
-
-	Users.pack(followee.id, followee, {
-		detail: true,
-	}).then((packed) => publishMainStream(followee.id, "meUpdated", packed));
-}
diff --git a/packages/backend/src/services/following/requests/create.ts b/packages/backend/src/services/following/requests/create.ts
deleted file mode 100644
index 8b2e86ab5b..0000000000
--- a/packages/backend/src/services/following/requests/create.ts
+++ /dev/null
@@ -1,85 +0,0 @@
-import { publishMainStream } from "@/services/stream.js";
-import { renderActivity } from "@/remote/activitypub/renderer/index.js";
-import renderFollow from "@/remote/activitypub/renderer/follow.js";
-import { deliver } from "@/queue/index.js";
-import type { User } from "@/models/entities/user.js";
-import { Blockings, FollowRequests, Users } from "@/models/index.js";
-import { genId } from "@/misc/gen-id.js";
-import { createNotification } from "../../create-notification.js";
-
-export default async function (
-	follower: {
-		id: User["id"];
-		host: User["host"];
-		uri: User["host"];
-		inbox: User["inbox"];
-		sharedInbox: User["sharedInbox"];
-	},
-	followee: {
-		id: User["id"];
-		host: User["host"];
-		uri: User["host"];
-		inbox: User["inbox"];
-		sharedInbox: User["sharedInbox"];
-	},
-	requestId?: string,
-) {
-	if (follower.id === followee.id) return;
-
-	// check blocking
-	const [blocking, blocked] = await Promise.all([
-		Blockings.findOneBy({
-			blockerId: follower.id,
-			blockeeId: followee.id,
-		}),
-		Blockings.findOneBy({
-			blockerId: followee.id,
-			blockeeId: follower.id,
-		}),
-	]);
-
-	if (blocking) throw new Error("blocking");
-	if (blocked) throw new Error("blocked");
-
-	const followRequest = await FollowRequests.insert({
-		id: genId(),
-		createdAt: new Date(),
-		followerId: follower.id,
-		followeeId: followee.id,
-		requestId,
-
-		// 非正規化
-		followerHost: follower.host,
-		followerInbox: Users.isRemoteUser(follower) ? follower.inbox : undefined,
-		followerSharedInbox: Users.isRemoteUser(follower)
-			? follower.sharedInbox
-			: undefined,
-		followeeHost: followee.host,
-		followeeInbox: Users.isRemoteUser(followee) ? followee.inbox : undefined,
-		followeeSharedInbox: Users.isRemoteUser(followee)
-			? followee.sharedInbox
-			: undefined,
-	}).then((x) => FollowRequests.findOneByOrFail(x.identifiers[0]));
-
-	// Publish receiveRequest event
-	if (Users.isLocalUser(followee)) {
-		Users.pack(follower.id, followee).then((packed) =>
-			publishMainStream(followee.id, "receiveFollowRequest", packed),
-		);
-
-		Users.pack(followee.id, followee, {
-			detail: true,
-		}).then((packed) => publishMainStream(followee.id, "meUpdated", packed));
-
-		// 通知を作成
-		createNotification(followee.id, "receiveFollowRequest", {
-			notifierId: follower.id,
-			followRequestId: followRequest.id,
-		});
-	}
-
-	if (Users.isLocalUser(follower) && Users.isRemoteUser(followee)) {
-		const content = renderActivity(renderFollow(follower, followee));
-		deliver(follower, content, followee.inbox);
-	}
-}
diff --git a/packages/backend/src/services/i/pin.ts b/packages/backend/src/services/i/pin.ts
deleted file mode 100644
index 97045a9fa9..0000000000
--- a/packages/backend/src/services/i/pin.ts
+++ /dev/null
@@ -1,118 +0,0 @@
-import config from "@/config/index.js";
-import renderAdd from "@/remote/activitypub/renderer/add.js";
-import renderRemove from "@/remote/activitypub/renderer/remove.js";
-import { renderActivity } from "@/remote/activitypub/renderer/index.js";
-import { IdentifiableError } from "@/misc/identifiable-error.js";
-import type { User } from "@/models/entities/user.js";
-import type { Note } from "@/models/entities/note.js";
-import { Notes, UserNotePinings, Users } from "@/models/index.js";
-import type { UserNotePining } from "@/models/entities/user-note-pining.js";
-import { genId } from "@/misc/gen-id.js";
-import { deliverToFollowers } from "@/remote/activitypub/deliver-manager.js";
-import { deliverToRelays } from "../relay.js";
-
-/**
- * 指定した投稿をピン留めします
- * @param user
- * @param noteId
- */
-export async function addPinned(
-	user: { id: User["id"]; host: User["host"] },
-	noteId: Note["id"],
-) {
-	// Fetch pinee
-	const note = await Notes.findOneBy({
-		id: noteId,
-		userId: user.id,
-	});
-
-	if (note == null) {
-		throw new IdentifiableError(
-			"70c4e51f-5bea-449c-a030-53bee3cce202",
-			"No such note.",
-		);
-	}
-
-	const pinings = await UserNotePinings.findBy({ userId: user.id });
-
-	if (pinings.length >= 5) {
-		throw new IdentifiableError(
-			"15a018eb-58e5-4da1-93be-330fcc5e4e1a",
-			"You can not pin notes any more.",
-		);
-	}
-
-	if (pinings.some((pining) => pining.noteId === note.id)) {
-		throw new IdentifiableError(
-			"23f0cf4e-59a3-4276-a91d-61a5891c1514",
-			"That note has already been pinned.",
-		);
-	}
-
-	await UserNotePinings.insert({
-		id: genId(),
-		createdAt: new Date(),
-		userId: user.id,
-		noteId: note.id,
-	} as UserNotePining);
-
-	// Deliver to remote followers
-	if (Users.isLocalUser(user)) {
-		deliverPinnedChange(user.id, note.id, true);
-	}
-}
-
-/**
- * 指定した投稿のピン留めを解除します
- * @param user
- * @param noteId
- */
-export async function removePinned(
-	user: { id: User["id"]; host: User["host"] },
-	noteId: Note["id"],
-) {
-	// Fetch unpinee
-	const note = await Notes.findOneBy({
-		id: noteId,
-		userId: user.id,
-	});
-
-	if (note == null) {
-		throw new IdentifiableError(
-			"b302d4cf-c050-400a-bbb3-be208681f40c",
-			"No such note.",
-		);
-	}
-
-	UserNotePinings.delete({
-		userId: user.id,
-		noteId: note.id,
-	});
-
-	// Deliver to remote followers
-	if (Users.isLocalUser(user)) {
-		deliverPinnedChange(user.id, noteId, false);
-	}
-}
-
-export async function deliverPinnedChange(
-	userId: User["id"],
-	noteId: Note["id"],
-	isAddition: boolean,
-) {
-	const user = await Users.findOneBy({ id: userId });
-	if (user == null) throw new Error("user not found");
-
-	if (!Users.isLocalUser(user)) return;
-
-	const target = `${config.url}/users/${user.id}/collections/featured`;
-	const item = `${config.url}/notes/${noteId}`;
-	const content = renderActivity(
-		isAddition
-			? renderAdd(user, target, item)
-			: renderRemove(user, target, item),
-	);
-
-	deliverToFollowers(user, content);
-	deliverToRelays(user, content);
-}
diff --git a/packages/backend/src/services/i/update.ts b/packages/backend/src/services/i/update.ts
deleted file mode 100644
index cc950ac85a..0000000000
--- a/packages/backend/src/services/i/update.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import renderUpdate from "@/remote/activitypub/renderer/update.js";
-import { renderActivity } from "@/remote/activitypub/renderer/index.js";
-import { Users } from "@/models/index.js";
-import type { User } from "@/models/entities/user.js";
-import { renderPerson } from "@/remote/activitypub/renderer/person.js";
-import { deliverToFollowers } from "@/remote/activitypub/deliver-manager.js";
-import { deliverToRelays } from "../relay.js";
-
-export async function publishToFollowers(userId: User["id"]) {
-	const user = await Users.findOneBy({ id: userId });
-	if (user == null) throw new Error("user not found");
-
-	// フォロワーがリモートユーザーかつ投稿者がローカルユーザーならUpdateを配信
-	if (Users.isLocalUser(user)) {
-		const content = renderActivity(
-			renderUpdate(await renderPerson(user), user),
-		);
-		deliverToFollowers(user, content);
-		deliverToRelays(user, content);
-	}
-}
diff --git a/packages/backend/src/services/insert-moderation-log.ts b/packages/backend/src/services/insert-moderation-log.ts
deleted file mode 100644
index 8e2c5b78a1..0000000000
--- a/packages/backend/src/services/insert-moderation-log.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { ModerationLogs } from "@/models/index.js";
-import { genId } from "@/misc/gen-id.js";
-import type { User } from "@/models/entities/user.js";
-
-export async function insertModerationLog(
-	moderator: { id: User["id"] },
-	type: string,
-	info?: Record<string, any>,
-) {
-	await ModerationLogs.insert({
-		id: genId(),
-		createdAt: new Date(),
-		userId: moderator.id,
-		type: type,
-		info: info || {},
-	});
-}
diff --git a/packages/backend/src/services/instance-actor.ts b/packages/backend/src/services/instance-actor.ts
deleted file mode 100644
index 50ce227eba..0000000000
--- a/packages/backend/src/services/instance-actor.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import { createSystemUser } from "./create-system-user.js";
-import type { ILocalUser } from "@/models/entities/user.js";
-import { Users } from "@/models/index.js";
-import { Cache } from "@/misc/cache.js";
-import { IsNull } from "typeorm";
-
-const ACTOR_USERNAME = "instance.actor" as const;
-
-const cache = new Cache<ILocalUser>(Infinity);
-
-export async function getInstanceActor(): Promise<ILocalUser> {
-	const cached = cache.get(null);
-	if (cached) return cached;
-
-	const user = (await Users.findOneBy({
-		host: IsNull(),
-		username: ACTOR_USERNAME,
-	})) as ILocalUser | undefined;
-
-	if (user) {
-		cache.set(null, user);
-		return user;
-	} else {
-		const created = (await createSystemUser(ACTOR_USERNAME)) as ILocalUser;
-		cache.set(null, created);
-		return created;
-	}
-}
diff --git a/packages/backend/src/services/logger.ts b/packages/backend/src/services/logger.ts
deleted file mode 100644
index 86e1d10d32..0000000000
--- a/packages/backend/src/services/logger.ts
+++ /dev/null
@@ -1,199 +0,0 @@
-import cluster from "node:cluster";
-import chalk from "chalk";
-import { default as convertColor } from "color-convert";
-import { format as dateFormat } from "date-fns";
-import { envOption } from "../env.js";
-import config from "@/config/index.js";
-
-import * as SyslogPro from "syslog-pro";
-
-type Domain = {
-	name: string;
-	color?: string;
-};
-
-type Level = "error" | "success" | "warning" | "debug" | "info";
-
-export default class Logger {
-	private domain: Domain;
-	private parentLogger: Logger | null = null;
-	private store: boolean;
-	private syslogClient: any | null = null;
-
-	constructor(domain: string, color?: string, store = true) {
-		this.domain = {
-			name: domain,
-			color: color,
-		};
-		this.store = store;
-
-		if (config.syslog) {
-			this.syslogClient = new SyslogPro.RFC5424({
-				applacationName: "Calckey",
-				timestamp: true,
-				encludeStructuredData: true,
-				color: true,
-				extendedColor: true,
-				server: {
-					target: config.syslog.host,
-					port: config.syslog.port,
-				},
-			});
-		}
-	}
-
-	public createSubLogger(domain: string, color?: string, store = true): Logger {
-		const logger = new Logger(domain, color, store);
-		logger.parentLogger = this;
-		return logger;
-	}
-
-	private log(
-		level: Level,
-		message: string,
-		data?: Record<string, any> | null,
-		important = false,
-		subDomains: Domain[] = [],
-		store = true,
-	): void {
-		if (envOption.quiet) return;
-		if (!this.store) store = false;
-		if (level === "debug") store = false;
-
-		if (this.parentLogger) {
-			this.parentLogger.log(
-				level,
-				message,
-				data,
-				important,
-				[this.domain].concat(subDomains),
-				store,
-			);
-			return;
-		}
-
-		const time = dateFormat(new Date(), "HH:mm:ss");
-		const worker = cluster.isPrimary ? "*" : cluster.worker.id;
-		const l =
-			level === "error"
-				? important
-					? chalk.bgRed.white("ERR ")
-					: chalk.red("ERR ")
-				: level === "warning"
-				? chalk.yellow("WARN")
-				: level === "success"
-				? important
-					? chalk.bgGreen.white("DONE")
-					: chalk.green("DONE")
-				: level === "debug"
-				? chalk.gray("VERB")
-				: level === "info"
-				? chalk.blue("INFO")
-				: null;
-		const domains = [this.domain]
-			.concat(subDomains)
-			.map((d) =>
-				d.color
-					? chalk.rgb(...convertColor.keyword.rgb(d.color))(d.name)
-					: chalk.white(d.name),
-			);
-		const m =
-			level === "error"
-				? chalk.red(message)
-				: level === "warning"
-				? chalk.yellow(message)
-				: level === "success"
-				? chalk.green(message)
-				: level === "debug"
-				? chalk.gray(message)
-				: level === "info"
-				? message
-				: null;
-
-		let log = `${l} ${worker}\t[${domains.join(" ")}]\t${m}`;
-		if (envOption.withLogTime) log = `${chalk.gray(time)} ${log}`;
-
-		console.log(important ? chalk.bold(log) : log);
-
-		if (store) {
-			if (this.syslogClient) {
-				const send =
-					level === "error"
-						? this.syslogClient.error
-						: level === "warning"
-						? this.syslogClient.warning
-						: level === "success"
-						? this.syslogClient.info
-						: level === "debug"
-						? this.syslogClient.info
-						: level === "info"
-						? this.syslogClient.info
-						: (null as never);
-
-				send
-					.bind(this.syslogClient)(message)
-					.catch(() => {});
-			}
-		}
-	}
-
-	public error(
-		x: string | Error,
-		data?: Record<string, any> | null,
-		important = false,
-	): void {
-		// 実行を継続できない状況で使う
-		if (x instanceof Error) {
-			data = data || {};
-			data.e = x;
-			this.log("error", x.toString(), data, important);
-		} else if (typeof x === "object") {
-			this.log(
-				"error",
-				`${(x as any).message || (x as any).name || x}`,
-				data,
-				important,
-			);
-		} else {
-			this.log("error", `${x}`, data, important);
-		}
-	}
-
-	public warn(
-		message: string,
-		data?: Record<string, any> | null,
-		important = false,
-	): void {
-		// 実行を継続できるが改善すべき状況で使う
-		this.log("warning", message, data, important);
-	}
-
-	public succ(
-		message: string,
-		data?: Record<string, any> | null,
-		important = false,
-	): void {
-		// 何かに成功した状況で使う
-		this.log("success", message, data, important);
-	}
-
-	public debug(
-		message: string,
-		data?: Record<string, any> | null,
-		important = false,
-	): void {
-		// デバッグ用に使う(開発者に必要だが利用者に不要な情報)
-		if (process.env.NODE_ENV !== "production" || envOption.verbose) {
-			this.log("debug", message, data, important);
-		}
-	}
-
-	public info(
-		message: string,
-		data?: Record<string, any> | null,
-		important = false,
-	): void {
-		// それ以外
-		this.log("info", message, data, important);
-	}
-}
diff --git a/packages/backend/src/services/messages/create.ts b/packages/backend/src/services/messages/create.ts
deleted file mode 100644
index 506f299966..0000000000
--- a/packages/backend/src/services/messages/create.ts
+++ /dev/null
@@ -1,148 +0,0 @@
-import type { CacheableUser, User } from "@/models/entities/user.js";
-import type { UserGroup } from "@/models/entities/user-group.js";
-import type { DriveFile } from "@/models/entities/drive-file.js";
-import {
-	MessagingMessages,
-	UserGroupJoinings,
-	Mutings,
-	Users,
-} from "@/models/index.js";
-import { genId } from "@/misc/gen-id.js";
-import type { MessagingMessage } from "@/models/entities/messaging-message.js";
-import {
-	publishMessagingStream,
-	publishMessagingIndexStream,
-	publishMainStream,
-	publishGroupMessagingStream,
-} from "@/services/stream.js";
-import { pushNotification } from "@/services/push-notification.js";
-import { Not } from "typeorm";
-import type { Note } from "@/models/entities/note.js";
-import renderNote from "@/remote/activitypub/renderer/note.js";
-import renderCreate from "@/remote/activitypub/renderer/create.js";
-import { renderActivity } from "@/remote/activitypub/renderer/index.js";
-import { deliver } from "@/queue/index.js";
-
-export async function createMessage(
-	user: { id: User["id"]; host: User["host"] },
-	recipientUser: CacheableUser | undefined,
-	recipientGroup: UserGroup | undefined,
-	text: string | null | undefined,
-	file: DriveFile | null,
-	uri?: string,
-) {
-	const message = {
-		id: genId(),
-		createdAt: new Date(),
-		fileId: file ? file.id : null,
-		recipientId: recipientUser ? recipientUser.id : null,
-		groupId: recipientGroup ? recipientGroup.id : null,
-		text: text ? text.trim() : null,
-		userId: user.id,
-		isRead: false,
-		reads: [] as any[],
-		uri,
-	} as MessagingMessage;
-
-	await MessagingMessages.insert(message);
-
-	const messageObj = await MessagingMessages.pack(message);
-
-	if (recipientUser) {
-		if (Users.isLocalUser(user)) {
-			// 自分のストリーム
-			publishMessagingStream(
-				message.userId,
-				recipientUser.id,
-				"message",
-				messageObj,
-			);
-			publishMessagingIndexStream(message.userId, "message", messageObj);
-			publishMainStream(message.userId, "messagingMessage", messageObj);
-		}
-
-		if (Users.isLocalUser(recipientUser)) {
-			// 相手のストリーム
-			publishMessagingStream(
-				recipientUser.id,
-				message.userId,
-				"message",
-				messageObj,
-			);
-			publishMessagingIndexStream(recipientUser.id, "message", messageObj);
-			publishMainStream(recipientUser.id, "messagingMessage", messageObj);
-		}
-	} else if (recipientGroup) {
-		// グループのストリーム
-		publishGroupMessagingStream(recipientGroup.id, "message", messageObj);
-
-		// メンバーのストリーム
-		const joinings = await UserGroupJoinings.findBy({
-			userGroupId: recipientGroup.id,
-		});
-		for (const joining of joinings) {
-			publishMessagingIndexStream(joining.userId, "message", messageObj);
-			publishMainStream(joining.userId, "messagingMessage", messageObj);
-		}
-	}
-
-	// 2秒経っても(今回作成した)メッセージが既読にならなかったら「未読のメッセージがありますよ」イベントを発行する
-	setTimeout(async () => {
-		const freshMessage = await MessagingMessages.findOneBy({ id: message.id });
-		if (freshMessage == null) return; // メッセージが削除されている場合もある
-
-		if (recipientUser && Users.isLocalUser(recipientUser)) {
-			if (freshMessage.isRead) return; // 既読
-
-			//#region ただしミュートされているなら発行しない
-			const mute = await Mutings.findBy({
-				muterId: recipientUser.id,
-			});
-			if (mute.map((m) => m.muteeId).includes(user.id)) return;
-			//#endregion
-
-			publishMainStream(recipientUser.id, "unreadMessagingMessage", messageObj);
-			pushNotification(recipientUser.id, "unreadMessagingMessage", messageObj);
-		} else if (recipientGroup) {
-			const joinings = await UserGroupJoinings.findBy({
-				userGroupId: recipientGroup.id,
-				userId: Not(user.id),
-			});
-			for (const joining of joinings) {
-				if (freshMessage.reads.includes(joining.userId)) return; // 既読
-				publishMainStream(joining.userId, "unreadMessagingMessage", messageObj);
-				pushNotification(joining.userId, "unreadMessagingMessage", messageObj);
-			}
-		}
-	}, 2000);
-
-	if (
-		recipientUser &&
-		Users.isLocalUser(user) &&
-		Users.isRemoteUser(recipientUser)
-	) {
-		const note = {
-			id: message.id,
-			createdAt: message.createdAt,
-			fileIds: message.fileId ? [message.fileId] : [],
-			text: message.text,
-			userId: message.userId,
-			visibility: "specified",
-			mentions: [recipientUser].map((u) => u.id),
-			mentionedRemoteUsers: JSON.stringify(
-				[recipientUser].map((u) => ({
-					uri: u.uri,
-					username: u.username,
-					host: u.host,
-				})),
-			),
-		} as Note;
-
-		const activity = renderActivity(
-			renderCreate(await renderNote(note, false, true), note),
-		);
-
-		deliver(user, activity, recipientUser.inbox);
-	}
-	return messageObj;
-}
diff --git a/packages/backend/src/services/messages/delete.ts b/packages/backend/src/services/messages/delete.ts
deleted file mode 100644
index 77caba80ce..0000000000
--- a/packages/backend/src/services/messages/delete.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import config from "@/config/index.js";
-import { MessagingMessages, Users } from "@/models/index.js";
-import type { MessagingMessage } from "@/models/entities/messaging-message.js";
-import {
-	publishGroupMessagingStream,
-	publishMessagingStream,
-} from "@/services/stream.js";
-import { renderActivity } from "@/remote/activitypub/renderer/index.js";
-import renderDelete from "@/remote/activitypub/renderer/delete.js";
-import renderTombstone from "@/remote/activitypub/renderer/tombstone.js";
-import { deliver } from "@/queue/index.js";
-
-export async function deleteMessage(message: MessagingMessage) {
-	await MessagingMessages.delete(message.id);
-	postDeleteMessage(message);
-}
-
-async function postDeleteMessage(message: MessagingMessage) {
-	if (message.recipientId) {
-		const user = await Users.findOneByOrFail({ id: message.userId });
-		const recipient = await Users.findOneByOrFail({ id: message.recipientId });
-
-		if (Users.isLocalUser(user))
-			publishMessagingStream(
-				message.userId,
-				message.recipientId,
-				"deleted",
-				message.id,
-			);
-		if (Users.isLocalUser(recipient))
-			publishMessagingStream(
-				message.recipientId,
-				message.userId,
-				"deleted",
-				message.id,
-			);
-
-		if (Users.isLocalUser(user) && Users.isRemoteUser(recipient)) {
-			const activity = renderActivity(
-				renderDelete(
-					renderTombstone(`${config.url}/notes/${message.id}`),
-					user,
-				),
-			);
-			deliver(user, activity, recipient.inbox);
-		}
-	} else if (message.groupId) {
-		publishGroupMessagingStream(message.groupId, "deleted", message.id);
-	}
-}
diff --git a/packages/backend/src/services/note/create.ts b/packages/backend/src/services/note/create.ts
deleted file mode 100644
index 5dd324d89a..0000000000
--- a/packages/backend/src/services/note/create.ts
+++ /dev/null
@@ -1,871 +0,0 @@
-import * as mfm from "mfm-js";
-import es from "../../db/elasticsearch.js";
-import sonic from "../../db/sonic.js";
-import {
-	publishMainStream,
-	publishNotesStream,
-	publishNoteStream,
-} from "@/services/stream.js";
-import DeliverManager from "@/remote/activitypub/deliver-manager.js";
-import renderNote from "@/remote/activitypub/renderer/note.js";
-import renderCreate from "@/remote/activitypub/renderer/create.js";
-import renderAnnounce from "@/remote/activitypub/renderer/announce.js";
-import { renderActivity } from "@/remote/activitypub/renderer/index.js";
-import { resolveUser } from "@/remote/resolve-user.js";
-import config from "@/config/index.js";
-import { updateHashtags } from "../update-hashtag.js";
-import { concat } from "@/prelude/array.js";
-import { insertNoteUnread } from "@/services/note/unread.js";
-import { registerOrFetchInstanceDoc } from "../register-or-fetch-instance-doc.js";
-import { extractMentions } from "@/misc/extract-mentions.js";
-import { extractCustomEmojisFromMfm } from "@/misc/extract-custom-emojis-from-mfm.js";
-import { extractHashtags } from "@/misc/extract-hashtags.js";
-import type { IMentionedRemoteUsers } from "@/models/entities/note.js";
-import { Note } from "@/models/entities/note.js";
-import {
-	Mutings,
-	Users,
-	NoteWatchings,
-	Notes,
-	Instances,
-	UserProfiles,
-	Antennas,
-	Followings,
-	MutedNotes,
-	Channels,
-	ChannelFollowings,
-	Blockings,
-	NoteThreadMutings,
-} from "@/models/index.js";
-import type { DriveFile } from "@/models/entities/drive-file.js";
-import type { App } from "@/models/entities/app.js";
-import { Not, In } from "typeorm";
-import type { User, ILocalUser, IRemoteUser } from "@/models/entities/user.js";
-import { genId } from "@/misc/gen-id.js";
-import {
-	notesChart,
-	perUserNotesChart,
-	activeUsersChart,
-	instanceChart,
-} from "@/services/chart/index.js";
-import type { IPoll } from "@/models/entities/poll.js";
-import { Poll } from "@/models/entities/poll.js";
-import { createNotification } from "../create-notification.js";
-import { isDuplicateKeyValueError } from "@/misc/is-duplicate-key-value-error.js";
-import { checkHitAntenna } from "@/misc/check-hit-antenna.js";
-import { getWordMute } from "@/misc/check-word-mute.js";
-import { addNoteToAntenna } from "../add-note-to-antenna.js";
-import { countSameRenotes } from "@/misc/count-same-renotes.js";
-import { deliverToRelays } from "../relay.js";
-import type { Channel } from "@/models/entities/channel.js";
-import { normalizeForSearch } from "@/misc/normalize-for-search.js";
-import { getAntennas } from "@/misc/antenna-cache.js";
-import { endedPollNotificationQueue } from "@/queue/queues.js";
-import { webhookDeliver } from "@/queue/index.js";
-import { Cache } from "@/misc/cache.js";
-import type { UserProfile } from "@/models/entities/user-profile.js";
-import { db } from "@/db/postgre.js";
-import { getActiveWebhooks } from "@/misc/webhook-cache.js";
-
-const mutedWordsCache = new Cache<
-	{ userId: UserProfile["userId"]; mutedWords: UserProfile["mutedWords"] }[]
->(1000 * 60 * 5);
-
-type NotificationType = "reply" | "renote" | "quote" | "mention";
-
-class NotificationManager {
-	private notifier: { id: User["id"] };
-	private note: Note;
-	private queue: {
-		target: ILocalUser["id"];
-		reason: NotificationType;
-	}[];
-
-	constructor(notifier: { id: User["id"] }, note: Note) {
-		this.notifier = notifier;
-		this.note = note;
-		this.queue = [];
-	}
-
-	public push(notifiee: ILocalUser["id"], reason: NotificationType) {
-		// 自分自身へは通知しない
-		if (this.notifier.id === notifiee) return;
-
-		const exist = this.queue.find((x) => x.target === notifiee);
-
-		if (exist) {
-			// 「メンションされているかつ返信されている」場合は、メンションとしての通知ではなく返信としての通知にする
-			if (reason !== "mention") {
-				exist.reason = reason;
-			}
-		} else {
-			this.queue.push({
-				reason: reason,
-				target: notifiee,
-			});
-		}
-	}
-
-	public async deliver() {
-		for (const x of this.queue) {
-			// ミュート情報を取得
-			const mentioneeMutes = await Mutings.findBy({
-				muterId: x.target,
-			});
-
-			const mentioneesMutedUserIds = mentioneeMutes.map((m) => m.muteeId);
-
-			// 通知される側のユーザーが通知する側のユーザーをミュートしていない限りは通知する
-			if (!mentioneesMutedUserIds.includes(this.notifier.id)) {
-				createNotification(x.target, x.reason, {
-					notifierId: this.notifier.id,
-					noteId: this.note.id,
-					note: this.note,
-				});
-			}
-		}
-	}
-}
-
-type MinimumUser = {
-	id: User["id"];
-	host: User["host"];
-	username: User["username"];
-	uri: User["uri"];
-};
-
-type Option = {
-	createdAt?: Date | null;
-	name?: string | null;
-	text?: string | null;
-	reply?: Note | null;
-	renote?: Note | null;
-	files?: DriveFile[] | null;
-	poll?: IPoll | null;
-	localOnly?: boolean | null;
-	cw?: string | null;
-	visibility?: string;
-	visibleUsers?: MinimumUser[] | null;
-	channel?: Channel | null;
-	apMentions?: MinimumUser[] | null;
-	apHashtags?: string[] | null;
-	apEmojis?: string[] | null;
-	uri?: string | null;
-	url?: string | null;
-	app?: App | null;
-};
-
-export default async (
-	user: {
-		id: User["id"];
-		username: User["username"];
-		host: User["host"];
-		isSilenced: User["isSilenced"];
-		createdAt: User["createdAt"];
-	},
-	data: Option,
-	silent = false,
-) =>
-	new Promise<Note>(async (res, rej) => {
-		// If you reply outside the channel, match the scope of the target.
-		// TODO (I think it's a process that could be done on the client side, but it's server side for now.)
-		if (
-			data.reply &&
-			data.channel &&
-			data.reply.channelId !== data.channel.id
-		) {
-			if (data.reply.channelId) {
-				data.channel = await Channels.findOneBy({ id: data.reply.channelId });
-			} else {
-				data.channel = null;
-			}
-		}
-
-		// When you reply in a channel, match the scope of the target
-		// TODO (I think it's a process that could be done on the client side, but it's server side for now.)
-		if (data.reply && data.channel == null && data.reply.channelId) {
-			data.channel = await Channels.findOneBy({ id: data.reply.channelId });
-		}
-
-		if (data.createdAt == null) data.createdAt = new Date();
-		if (data.visibility == null) data.visibility = "public";
-		if (data.localOnly == null) data.localOnly = false;
-		if (data.channel != null) data.visibility = "public";
-		if (data.channel != null) data.visibleUsers = [];
-		if (data.channel != null) data.localOnly = true;
-
-		// enforce silent clients on server
-		if (
-			user.isSilenced &&
-			data.visibility === "public" &&
-			data.channel == null
-		) {
-			data.visibility = "home";
-		}
-
-		// Reject if the target of the renote is a public range other than "Home or Entire".
-		if (
-			data.renote &&
-			data.renote.visibility !== "public" &&
-			data.renote.visibility !== "home" &&
-			data.renote.userId !== user.id
-		) {
-			return rej("Renote target is not public or home");
-		}
-
-		// If the target of the renote is not public, make it home.
-		if (
-			data.renote &&
-			data.renote.visibility !== "public" &&
-			data.visibility === "public"
-		) {
-			data.visibility = "home";
-		}
-
-		// If the target of Renote is followers, make it followers.
-		if (data.renote && data.renote.visibility === "followers") {
-			data.visibility = "followers";
-		}
-
-		// If the reply target is not public, make it home.
-		if (
-			data.reply &&
-			data.reply.visibility !== "public" &&
-			data.visibility === "public"
-		) {
-			data.visibility = "home";
-		}
-
-		// Renote local only if you Renote local only.
-		if (data.renote?.localOnly && data.channel == null) {
-			data.localOnly = true;
-		}
-
-		// If you reply to local only, make it local only.
-		if (data.reply?.localOnly && data.channel == null) {
-			data.localOnly = true;
-		}
-
-		if (data.text) {
-			data.text = data.text.trim();
-		} else {
-			data.text = null;
-		}
-
-		let tags = data.apHashtags;
-		let emojis = data.apEmojis;
-		let mentionedUsers = data.apMentions;
-
-		// Parse MFM if needed
-		if (!(tags && emojis && mentionedUsers)) {
-			const tokens = data.text ? mfm.parse(data.text)! : [];
-			const cwTokens = data.cw ? mfm.parse(data.cw)! : [];
-			const choiceTokens = data.poll?.choices
-				? concat(data.poll.choices.map((choice) => mfm.parse(choice)!))
-				: [];
-
-			const combinedTokens = tokens.concat(cwTokens).concat(choiceTokens);
-
-			tags = data.apHashtags || extractHashtags(combinedTokens);
-
-			emojis = data.apEmojis || extractCustomEmojisFromMfm(combinedTokens);
-
-			mentionedUsers =
-				data.apMentions || (await extractMentionedUsers(user, combinedTokens));
-		}
-
-		tags = tags
-			.filter((tag) => Array.from(tag || "").length <= 128)
-			.splice(0, 32);
-
-		if (
-			data.reply &&
-			user.id !== data.reply.userId &&
-			!mentionedUsers.some((u) => u.id === data.reply!.userId)
-		) {
-			mentionedUsers.push(
-				await Users.findOneByOrFail({ id: data.reply!.userId }),
-			);
-		}
-
-		if (data.visibility === "specified") {
-			if (data.visibleUsers == null) throw new Error("invalid param");
-
-			for (const u of data.visibleUsers) {
-				if (!mentionedUsers.some((x) => x.id === u.id)) {
-					mentionedUsers.push(u);
-				}
-			}
-
-			if (
-				data.reply &&
-				!data.visibleUsers.some((x) => x.id === data.reply!.userId)
-			) {
-				data.visibleUsers.push(
-					await Users.findOneByOrFail({ id: data.reply!.userId }),
-				);
-			}
-		}
-
-		const note = await insertNote(user, data, tags, emojis, mentionedUsers);
-
-		res(note);
-
-		// 統計を更新
-		notesChart.update(note, true);
-		perUserNotesChart.update(user, note, true);
-
-		// Register host
-		if (Users.isRemoteUser(user)) {
-			registerOrFetchInstanceDoc(user.host).then((i) => {
-				Instances.increment({ id: i.id }, "notesCount", 1);
-				instanceChart.updateNote(i.host, note, true);
-			});
-		}
-
-		// ハッシュタグ更新
-		if (data.visibility === "public" || data.visibility === "home") {
-			updateHashtags(user, tags);
-		}
-
-		// Increment notes count (user)
-		incNotesCountOfUser(user);
-
-		// Word mute
-		mutedWordsCache
-			.fetch(null, () =>
-				UserProfiles.find({
-					where: {
-						enableWordMute: true,
-					},
-					select: ["userId", "mutedWords"],
-				}),
-			)
-			.then((us) => {
-				for (const u of us) {
-					getWordMute(note, { id: u.userId }, u.mutedWords).then(
-						(shouldMute) => {
-							if (shouldMute.muted) {
-								MutedNotes.insert({
-									id: genId(),
-									userId: u.userId,
-									noteId: note.id,
-									reason: "word",
-								});
-							}
-						},
-					);
-				}
-			});
-
-		// Antenna
-		for (const antenna of await getAntennas()) {
-			checkHitAntenna(antenna, note, user).then((hit) => {
-				if (hit) {
-					addNoteToAntenna(antenna, note, user);
-				}
-			});
-		}
-
-		// Channel
-		if (note.channelId) {
-			ChannelFollowings.findBy({ followeeId: note.channelId }).then(
-				(followings) => {
-					for (const following of followings) {
-						insertNoteUnread(following.followerId, note, {
-							isSpecified: false,
-							isMentioned: false,
-						});
-					}
-				},
-			);
-		}
-
-		if (data.reply) {
-			saveReply(data.reply, note);
-		}
-
-		// この投稿を除く指定したユーザーによる指定したノートのリノートが存在しないとき
-		if (
-			data.renote &&
-			(await countSameRenotes(user.id, data.renote.id, note.id)) === 0
-		) {
-			incRenoteCount(data.renote);
-		}
-
-		if (data.poll?.expiresAt) {
-			const delay = data.poll.expiresAt.getTime() - Date.now();
-			endedPollNotificationQueue.add(
-				{
-					noteId: note.id,
-				},
-				{
-					delay,
-					removeOnComplete: true,
-				},
-			);
-		}
-
-		if (!silent) {
-			if (Users.isLocalUser(user)) activeUsersChart.write(user);
-
-			// 未読通知を作成
-			if (data.visibility === "specified") {
-				if (data.visibleUsers == null) throw new Error("invalid param");
-
-				for (const u of data.visibleUsers) {
-					// ローカルユーザーのみ
-					if (!Users.isLocalUser(u)) continue;
-
-					insertNoteUnread(u.id, note, {
-						isSpecified: true,
-						isMentioned: false,
-					});
-				}
-			} else {
-				for (const u of mentionedUsers) {
-					// ローカルユーザーのみ
-					if (!Users.isLocalUser(u)) continue;
-
-					insertNoteUnread(u.id, note, {
-						isSpecified: false,
-						isMentioned: true,
-					});
-				}
-			}
-
-			publishNotesStream(note);
-			if (note.replyId != null) {
-				// Only provide the reply note id here as the recipient may not be authorized to see the note.
-				publishNoteStream(note.replyId, "replied", {
-					id: note.id,
-				});
-			}
-
-			const webhooks = await getActiveWebhooks().then((webhooks) =>
-				webhooks.filter((x) => x.userId === user.id && x.on.includes("note")),
-			);
-
-			for (const webhook of webhooks) {
-				webhookDeliver(webhook, "note", {
-					note: await Notes.pack(note, user),
-				});
-			}
-
-			const nm = new NotificationManager(user, note);
-			const nmRelatedPromises = [];
-
-			await createMentionedEvents(mentionedUsers, note, nm);
-
-			// If has in reply to note
-			if (data.reply) {
-				// Fetch watchers
-				nmRelatedPromises.push(notifyToWatchersOfReplyee(data.reply, user, nm));
-
-				// 通知
-				if (data.reply.userHost === null) {
-					const threadMuted = await NoteThreadMutings.findOneBy({
-						userId: data.reply.userId,
-						threadId: data.reply.threadId || data.reply.id,
-					});
-
-					if (!threadMuted) {
-						nm.push(data.reply.userId, "reply");
-
-						const packedReply = await Notes.pack(note, {
-							id: data.reply.userId,
-						});
-						publishMainStream(data.reply.userId, "reply", packedReply);
-
-						const webhooks = (await getActiveWebhooks()).filter(
-							(x) => x.userId === data.reply!.userId && x.on.includes("reply"),
-						);
-						for (const webhook of webhooks) {
-							webhookDeliver(webhook, "reply", {
-								note: packedReply,
-							});
-						}
-					}
-				}
-			}
-
-			// If it is renote
-			if (data.renote) {
-				const type = data.text ? "quote" : "renote";
-
-				// Notify
-				if (data.renote.userHost === null) {
-					const threadMuted = await NoteThreadMutings.findOneBy({
-						userId: data.renote.userId,
-						threadId: data.renote.threadId || data.renote.id,
-					});
-
-					if (!threadMuted) {
-						nm.push(data.renote.userId, type);
-					}
-				}
-
-				// Fetch watchers
-				nmRelatedPromises.push(
-					notifyToWatchersOfRenotee(data.renote, user, nm, type),
-				);
-
-				// Publish event
-				if (user.id !== data.renote.userId && data.renote.userHost === null) {
-					const packedRenote = await Notes.pack(note, {
-						id: data.renote.userId,
-					});
-					publishMainStream(data.renote.userId, "renote", packedRenote);
-
-					const webhooks = (await getActiveWebhooks()).filter(
-						(x) => x.userId === data.renote!.userId && x.on.includes("renote"),
-					);
-					for (const webhook of webhooks) {
-						webhookDeliver(webhook, "renote", {
-							note: packedRenote,
-						});
-					}
-				}
-			}
-
-			Promise.all(nmRelatedPromises).then(() => {
-				nm.deliver();
-			});
-
-			//#region AP deliver
-			if (Users.isLocalUser(user)) {
-				(async () => {
-					const noteActivity = await renderNoteOrRenoteActivity(data, note);
-					const dm = new DeliverManager(user, noteActivity);
-
-					// メンションされたリモートユーザーに配送
-					for (const u of mentionedUsers.filter((u) => Users.isRemoteUser(u))) {
-						dm.addDirectRecipe(u as IRemoteUser);
-					}
-
-					// 投稿がリプライかつ投稿者がローカルユーザーかつリプライ先の投稿の投稿者がリモートユーザーなら配送
-					if (data.reply && data.reply.userHost !== null) {
-						const u = await Users.findOneBy({ id: data.reply.userId });
-						if (u && Users.isRemoteUser(u)) dm.addDirectRecipe(u);
-					}
-
-					// 投稿がRenoteかつ投稿者がローカルユーザーかつRenote元の投稿の投稿者がリモートユーザーなら配送
-					if (data.renote && data.renote.userHost !== null) {
-						const u = await Users.findOneBy({ id: data.renote.userId });
-						if (u && Users.isRemoteUser(u)) dm.addDirectRecipe(u);
-					}
-
-					// フォロワーに配送
-					if (["public", "home", "followers"].includes(note.visibility)) {
-						dm.addFollowersRecipe();
-					}
-
-					if (["public"].includes(note.visibility)) {
-						deliverToRelays(user, noteActivity);
-					}
-
-					dm.execute();
-				})();
-			}
-			//#endregion
-		}
-
-		if (data.channel) {
-			Channels.increment({ id: data.channel.id }, "notesCount", 1);
-			Channels.update(data.channel.id, {
-				lastNotedAt: new Date(),
-			});
-
-			const count = await Notes.countBy({
-				userId: user.id,
-				channelId: data.channel.id,
-			}).then((count) => {
-				// この処理が行われるのはノート作成後なので、ノートが一つしかなかったら最初の投稿だと判断できる
-				// TODO: とはいえノートを削除して何回も投稿すればその分だけインクリメントされる雑さもあるのでどうにかしたい
-				if (count === 1) {
-					Channels.increment({ id: data.channel!.id }, "usersCount", 1);
-				}
-			});
-		}
-
-		// Register to search database
-		await index(note);
-	});
-
-async function renderNoteOrRenoteActivity(data: Option, note: Note) {
-	if (data.localOnly) return null;
-
-	const content =
-		data.renote &&
-		data.text == null &&
-		data.poll == null &&
-		(data.files == null || data.files.length === 0)
-			? renderAnnounce(
-					data.renote.uri
-						? data.renote.uri
-						: `${config.url}/notes/${data.renote.id}`,
-					note,
-			  )
-			: renderCreate(await renderNote(note, false), note);
-
-	return renderActivity(content);
-}
-
-function incRenoteCount(renote: Note) {
-	Notes.createQueryBuilder()
-		.update()
-		.set({
-			renoteCount: () => '"renoteCount" + 1',
-			score: () => '"score" + 1',
-		})
-		.where("id = :id", { id: renote.id })
-		.execute();
-}
-
-async function insertNote(
-	user: { id: User["id"]; host: User["host"] },
-	data: Option,
-	tags: string[],
-	emojis: string[],
-	mentionedUsers: MinimumUser[],
-) {
-	const insert = new Note({
-		id: genId(data.createdAt!),
-		createdAt: data.createdAt!,
-		fileIds: data.files ? data.files.map((file) => file.id) : [],
-		replyId: data.reply ? data.reply.id : null,
-		renoteId: data.renote ? data.renote.id : null,
-		channelId: data.channel ? data.channel.id : null,
-		threadId: data.reply
-			? data.reply.threadId
-				? data.reply.threadId
-				: data.reply.id
-			: null,
-		name: data.name,
-		text: data.text,
-		hasPoll: data.poll != null,
-		cw: data.cw == null ? null : data.cw,
-		tags: tags.map((tag) => normalizeForSearch(tag)),
-		emojis,
-		userId: user.id,
-		localOnly: data.localOnly!,
-		visibility: data.visibility as any,
-		visibleUserIds:
-			data.visibility === "specified"
-				? data.visibleUsers
-					? data.visibleUsers.map((u) => u.id)
-					: []
-				: [],
-
-		attachedFileTypes: data.files ? data.files.map((file) => file.type) : [],
-
-		// 以下非正規化データ
-		replyUserId: data.reply ? data.reply.userId : null,
-		replyUserHost: data.reply ? data.reply.userHost : null,
-		renoteUserId: data.renote ? data.renote.userId : null,
-		renoteUserHost: data.renote ? data.renote.userHost : null,
-		userHost: user.host,
-	});
-
-	if (data.uri != null) insert.uri = data.uri;
-	if (data.url != null) insert.url = data.url;
-
-	// Append mentions data
-	if (mentionedUsers.length > 0) {
-		insert.mentions = mentionedUsers.map((u) => u.id);
-		const profiles = await UserProfiles.findBy({ userId: In(insert.mentions) });
-		insert.mentionedRemoteUsers = JSON.stringify(
-			mentionedUsers
-				.filter((u) => Users.isRemoteUser(u))
-				.map((u) => {
-					const profile = profiles.find((p) => p.userId === u.id);
-					const url = profile != null ? profile.url : null;
-					return {
-						uri: u.uri,
-						url: url == null ? undefined : url,
-						username: u.username,
-						host: u.host,
-					} as IMentionedRemoteUsers[0];
-				}),
-		);
-	}
-
-	// 投稿を作成
-	try {
-		if (insert.hasPoll) {
-			// Start transaction
-			await db.transaction(async (transactionalEntityManager) => {
-				await transactionalEntityManager.insert(Note, insert);
-
-				const poll = new Poll({
-					noteId: insert.id,
-					choices: data.poll!.choices,
-					expiresAt: data.poll!.expiresAt,
-					multiple: data.poll!.multiple,
-					votes: new Array(data.poll!.choices.length).fill(0),
-					noteVisibility: insert.visibility,
-					userId: user.id,
-					userHost: user.host,
-				});
-
-				await transactionalEntityManager.insert(Poll, poll);
-			});
-		} else {
-			await Notes.insert(insert);
-		}
-
-		return insert;
-	} catch (e) {
-		// duplicate key error
-		if (isDuplicateKeyValueError(e)) {
-			const err = new Error("Duplicated note");
-			err.name = "duplicated";
-			throw err;
-		}
-
-		console.error(e);
-
-		throw e;
-	}
-}
-
-export async function index(note: Note): Promise<void> {
-	if (!note.text) return;
-
-	if (config.elasticsearch && es) {
-		es.index({
-			index: config.elasticsearch.index || "misskey_note",
-			id: note.id.toString(),
-			body: {
-				text: normalizeForSearch(note.text),
-				userId: note.userId,
-				userHost: note.userHost,
-			},
-		});
-	}
-
-	if (sonic) {
-		await sonic.ingest.push(
-			sonic.collection,
-			sonic.bucket,
-			JSON.stringify({
-				id: note.id,
-				userId: note.userId,
-				userHost: note.userHost,
-				channelId: note.channelId,
-			}),
-			note.text,
-		);
-	}
-}
-
-async function notifyToWatchersOfRenotee(
-	renote: Note,
-	user: { id: User["id"] },
-	nm: NotificationManager,
-	type: NotificationType,
-) {
-	const watchers = await NoteWatchings.findBy({
-		noteId: renote.id,
-		userId: Not(user.id),
-	});
-
-	for (const watcher of watchers) {
-		nm.push(watcher.userId, type);
-	}
-}
-
-async function notifyToWatchersOfReplyee(
-	reply: Note,
-	user: { id: User["id"] },
-	nm: NotificationManager,
-) {
-	const watchers = await NoteWatchings.findBy({
-		noteId: reply.id,
-		userId: Not(user.id),
-	});
-
-	for (const watcher of watchers) {
-		nm.push(watcher.userId, "reply");
-	}
-}
-
-async function createMentionedEvents(
-	mentionedUsers: MinimumUser[],
-	note: Note,
-	nm: NotificationManager,
-) {
-	for (const u of mentionedUsers.filter((u) => Users.isLocalUser(u))) {
-		const threadMuted = await NoteThreadMutings.findOneBy({
-			userId: u.id,
-			threadId: note.threadId || note.id,
-		});
-
-		if (threadMuted) {
-			continue;
-		}
-
-		// note with "specified" visibility might not be visible to mentioned users
-		try {
-			const detailPackedNote = await Notes.pack(note, u, {
-				detail: true,
-			});
-
-			publishMainStream(u.id, "mention", detailPackedNote);
-
-			const webhooks = (await getActiveWebhooks()).filter(
-				(x) => x.userId === u.id && x.on.includes("mention"),
-			);
-			for (const webhook of webhooks) {
-				webhookDeliver(webhook, "mention", {
-					note: detailPackedNote,
-				});
-			}
-		} catch (err) {
-			if (err.id === "9725d0ce-ba28-4dde-95a7-2cbb2c15de24") continue;
-			throw err;
-		}
-
-		// Create notification
-		nm.push(u.id, "mention");
-	}
-}
-
-function saveReply(reply: Note, note: Note) {
-	Notes.increment({ id: reply.id }, "repliesCount", 1);
-}
-
-function incNotesCountOfUser(user: { id: User["id"] }) {
-	Users.createQueryBuilder()
-		.update()
-		.set({
-			updatedAt: new Date(),
-			notesCount: () => '"notesCount" + 1',
-		})
-		.where("id = :id", { id: user.id })
-		.execute();
-}
-
-async function extractMentionedUsers(
-	user: { host: User["host"] },
-	tokens: mfm.MfmNode[],
-): Promise<User[]> {
-	if (tokens == null) return [];
-
-	const mentions = extractMentions(tokens);
-
-	let mentionedUsers = (
-		await Promise.all(
-			mentions.map((m) =>
-				resolveUser(m.username, m.host || user.host).catch(() => null),
-			),
-		)
-	).filter((x) => x != null) as User[];
-
-	// Drop duplicate users
-	mentionedUsers = mentionedUsers.filter(
-		(u, i, self) => i === self.findIndex((u2) => u.id === u2.id),
-	);
-
-	return mentionedUsers;
-}
diff --git a/packages/backend/src/services/note/delete.ts b/packages/backend/src/services/note/delete.ts
deleted file mode 100644
index 392578e2f6..0000000000
--- a/packages/backend/src/services/note/delete.ts
+++ /dev/null
@@ -1,185 +0,0 @@
-import { Brackets, In } from "typeorm";
-import { publishNoteStream } from "@/services/stream.js";
-import renderDelete from "@/remote/activitypub/renderer/delete.js";
-import renderAnnounce from "@/remote/activitypub/renderer/announce.js";
-import renderUndo from "@/remote/activitypub/renderer/undo.js";
-import { renderActivity } from "@/remote/activitypub/renderer/index.js";
-import renderTombstone from "@/remote/activitypub/renderer/tombstone.js";
-import config from "@/config/index.js";
-import type { User, ILocalUser, IRemoteUser } from "@/models/entities/user.js";
-import type { Note, IMentionedRemoteUsers } from "@/models/entities/note.js";
-import { Notes, Users, Instances } from "@/models/index.js";
-import {
-	notesChart,
-	perUserNotesChart,
-	instanceChart,
-} from "@/services/chart/index.js";
-import {
-	deliverToFollowers,
-	deliverToUser,
-} from "@/remote/activitypub/deliver-manager.js";
-import { countSameRenotes } from "@/misc/count-same-renotes.js";
-import { registerOrFetchInstanceDoc } from "../register-or-fetch-instance-doc.js";
-import { deliverToRelays } from "../relay.js";
-
-/**
- * 投稿を削除します。
- * @param user 投稿者
- * @param note 投稿
- */
-export default async function (
-	user: { id: User["id"]; uri: User["uri"]; host: User["host"] },
-	note: Note,
-	quiet = false,
-) {
-	const deletedAt = new Date();
-
-	// この投稿を除く指定したユーザーによる指定したノートのリノートが存在しないとき
-	if (
-		note.renoteId &&
-		(await countSameRenotes(user.id, note.renoteId, note.id)) === 0
-	) {
-		Notes.decrement({ id: note.renoteId }, "renoteCount", 1);
-		Notes.decrement({ id: note.renoteId }, "score", 1);
-	}
-
-	if (note.replyId) {
-		await Notes.decrement({ id: note.replyId }, "repliesCount", 1);
-	}
-
-	if (!quiet) {
-		publishNoteStream(note.id, "deleted", {
-			deletedAt: deletedAt,
-		});
-
-		//#region ローカルの投稿なら削除アクティビティを配送
-		if (Users.isLocalUser(user) && !note.localOnly) {
-			let renote: Note | null = null;
-
-			// if deletd note is renote
-			if (
-				note.renoteId &&
-				note.text == null &&
-				!note.hasPoll &&
-				(note.fileIds == null || note.fileIds.length === 0)
-			) {
-				renote = await Notes.findOneBy({
-					id: note.renoteId,
-				});
-			}
-
-			const content = renderActivity(
-				renote
-					? renderUndo(
-							renderAnnounce(
-								renote.uri || `${config.url}/notes/${renote.id}`,
-								note,
-							),
-							user,
-					  )
-					: renderDelete(
-							renderTombstone(`${config.url}/notes/${note.id}`),
-							user,
-					  ),
-			);
-
-			deliverToConcerned(user, note, content);
-		}
-
-		// also deliever delete activity to cascaded notes
-		const cascadingNotes = (await findCascadingNotes(note)).filter(
-			(note) => !note.localOnly,
-		); // filter out local-only notes
-		for (const cascadingNote of cascadingNotes) {
-			if (!cascadingNote.user) continue;
-			if (!Users.isLocalUser(cascadingNote.user)) continue;
-			const content = renderActivity(
-				renderDelete(
-					renderTombstone(`${config.url}/notes/${cascadingNote.id}`),
-					cascadingNote.user,
-				),
-			);
-			deliverToConcerned(cascadingNote.user, cascadingNote, content);
-		}
-		//#endregion
-
-		// 統計を更新
-		notesChart.update(note, false);
-		perUserNotesChart.update(user, note, false);
-
-		if (Users.isRemoteUser(user)) {
-			registerOrFetchInstanceDoc(user.host).then((i) => {
-				Instances.decrement({ id: i.id }, "notesCount", 1);
-				instanceChart.updateNote(i.host, note, false);
-			});
-		}
-	}
-
-	await Notes.delete({
-		id: note.id,
-		userId: user.id,
-	});
-}
-
-async function findCascadingNotes(note: Note) {
-	const cascadingNotes: Note[] = [];
-
-	const recursive = async (noteId: string) => {
-		const query = Notes.createQueryBuilder("note")
-			.where("note.replyId = :noteId", { noteId })
-			.orWhere(
-				new Brackets((q) => {
-					q.where("note.renoteId = :noteId", { noteId }).andWhere(
-						"note.text IS NOT NULL",
-					);
-				}),
-			)
-			.leftJoinAndSelect("note.user", "user");
-		const replies = await query.getMany();
-		for (const reply of replies) {
-			cascadingNotes.push(reply);
-			await recursive(reply.id);
-		}
-	};
-	await recursive(note.id);
-
-	return cascadingNotes.filter((note) => note.userHost === null); // filter out non-local users
-}
-
-async function getMentionedRemoteUsers(note: Note) {
-	const where = [] as any[];
-
-	// mention / reply / dm
-	const uris = (
-		JSON.parse(note.mentionedRemoteUsers) as IMentionedRemoteUsers
-	).map((x) => x.uri);
-	if (uris.length > 0) {
-		where.push({ uri: In(uris) });
-	}
-
-	// renote / quote
-	if (note.renoteUserId) {
-		where.push({
-			id: note.renoteUserId,
-		});
-	}
-
-	if (where.length === 0) return [];
-
-	return (await Users.find({
-		where,
-	})) as IRemoteUser[];
-}
-
-async function deliverToConcerned(
-	user: { id: ILocalUser["id"]; host: null },
-	note: Note,
-	content: any,
-) {
-	deliverToFollowers(user, content);
-	deliverToRelays(user, content);
-	const remoteUsers = await getMentionedRemoteUsers(note);
-	for (const remoteUser of remoteUsers) {
-		deliverToUser(user, content, remoteUser);
-	}
-}
diff --git a/packages/backend/src/services/note/polls/update.ts b/packages/backend/src/services/note/polls/update.ts
deleted file mode 100644
index e02d48d055..0000000000
--- a/packages/backend/src/services/note/polls/update.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import renderUpdate from "@/remote/activitypub/renderer/update.js";
-import { renderActivity } from "@/remote/activitypub/renderer/index.js";
-import renderNote from "@/remote/activitypub/renderer/note.js";
-import { Users, Notes } from "@/models/index.js";
-import type { Note } from "@/models/entities/note.js";
-import { deliverToFollowers } from "@/remote/activitypub/deliver-manager.js";
-import { deliverToRelays } from "../../relay.js";
-
-export async function deliverQuestionUpdate(noteId: Note["id"]) {
-	const note = await Notes.findOneBy({ id: noteId });
-	if (note == null) throw new Error("note not found");
-
-	const user = await Users.findOneBy({ id: note.userId });
-	if (user == null) throw new Error("note not found");
-
-	if (Users.isLocalUser(user)) {
-		const content = renderActivity(
-			renderUpdate(await renderNote(note, false), user),
-		);
-		deliverToFollowers(user, content);
-		deliverToRelays(user, content);
-	}
-}
diff --git a/packages/backend/src/services/note/polls/vote.ts b/packages/backend/src/services/note/polls/vote.ts
deleted file mode 100644
index 582af0b17b..0000000000
--- a/packages/backend/src/services/note/polls/vote.ts
+++ /dev/null
@@ -1,87 +0,0 @@
-import { publishNoteStream } from "@/services/stream.js";
-import type { CacheableUser } from "@/models/entities/user.js";
-import { User } from "@/models/entities/user.js";
-import type { Note } from "@/models/entities/note.js";
-import { PollVotes, NoteWatchings, Polls, Blockings } from "@/models/index.js";
-import { Not } from "typeorm";
-import { genId } from "@/misc/gen-id.js";
-import { createNotification } from "../../create-notification.js";
-
-export default async function (
-	user: CacheableUser,
-	note: Note,
-	choice: number,
-) {
-	const poll = await Polls.findOneBy({ noteId: note.id });
-
-	if (poll == null) throw new Error("poll not found");
-
-	// Check whether is valid choice
-	if (poll.choices[choice] == null) throw new Error("invalid choice param");
-
-	// Check blocking
-	if (note.userId !== user.id) {
-		const block = await Blockings.findOneBy({
-			blockerId: note.userId,
-			blockeeId: user.id,
-		});
-		if (block) {
-			throw new Error("blocked");
-		}
-	}
-
-	// if already voted
-	const exist = await PollVotes.findBy({
-		noteId: note.id,
-		userId: user.id,
-	});
-
-	if (poll.multiple) {
-		if (exist.some((x) => x.choice === choice)) {
-			throw new Error("already voted");
-		}
-	} else if (exist.length !== 0) {
-		throw new Error("already voted");
-	}
-
-	// Create vote
-	await PollVotes.insert({
-		id: genId(),
-		createdAt: new Date(),
-		noteId: note.id,
-		userId: user.id,
-		choice: choice,
-	});
-
-	// Increment votes count
-	const index = choice + 1; // In SQL, array index is 1 based
-	await Polls.query(
-		`UPDATE poll SET votes[${index}] = votes[${index}] + 1 WHERE "noteId" = '${poll.noteId}'`,
-	);
-
-	publishNoteStream(note.id, "pollVoted", {
-		choice: choice,
-		userId: user.id,
-	});
-
-	// Notify
-	createNotification(note.userId, "pollVote", {
-		notifierId: user.id,
-		noteId: note.id,
-		choice: choice,
-	});
-
-	// Fetch watchers
-	NoteWatchings.findBy({
-		noteId: note.id,
-		userId: Not(user.id),
-	}).then((watchers) => {
-		for (const watcher of watchers) {
-			createNotification(watcher.userId, "pollVote", {
-				notifierId: user.id,
-				noteId: note.id,
-				choice: choice,
-			});
-		}
-	});
-}
diff --git a/packages/backend/src/services/note/reaction/create.ts b/packages/backend/src/services/note/reaction/create.ts
deleted file mode 100644
index 1a3c52eb51..0000000000
--- a/packages/backend/src/services/note/reaction/create.ts
+++ /dev/null
@@ -1,169 +0,0 @@
-import { publishNoteStream } from "@/services/stream.js";
-import { renderLike } from "@/remote/activitypub/renderer/like.js";
-import DeliverManager from "@/remote/activitypub/deliver-manager.js";
-import { renderActivity } from "@/remote/activitypub/renderer/index.js";
-import { toDbReaction, decodeReaction } from "@/misc/reaction-lib.js";
-import type { User, IRemoteUser } from "@/models/entities/user.js";
-import type { Note } from "@/models/entities/note.js";
-import {
-	NoteReactions,
-	Users,
-	NoteWatchings,
-	Notes,
-	Emojis,
-	Blockings,
-} from "@/models/index.js";
-import { IsNull, Not } from "typeorm";
-import { perUserReactionsChart } from "@/services/chart/index.js";
-import { genId } from "@/misc/gen-id.js";
-import { createNotification } from "../../create-notification.js";
-import deleteReaction from "./delete.js";
-import { isDuplicateKeyValueError } from "@/misc/is-duplicate-key-value-error.js";
-import type { NoteReaction } from "@/models/entities/note-reaction.js";
-import { IdentifiableError } from "@/misc/identifiable-error.js";
-
-export default async (
-	user: { id: User["id"]; host: User["host"] },
-	note: Note,
-	reaction?: string,
-) => {
-	// Check blocking
-	if (note.userId !== user.id) {
-		const block = await Blockings.findOneBy({
-			blockerId: note.userId,
-			blockeeId: user.id,
-		});
-		if (block) {
-			throw new IdentifiableError("e70412a4-7197-4726-8e74-f3e0deb92aa7");
-		}
-	}
-
-	// check visibility
-	if (!(await Notes.isVisibleForMe(note, user.id))) {
-		throw new IdentifiableError(
-			"68e9d2d1-48bf-42c2-b90a-b20e09fd3d48",
-			"Note not accessible for you.",
-		);
-	}
-
-	// TODO: cache
-	reaction = await toDbReaction(reaction, user.host);
-
-	const record: NoteReaction = {
-		id: genId(),
-		createdAt: new Date(),
-		noteId: note.id,
-		userId: user.id,
-		reaction,
-	};
-
-	// Create reaction
-	try {
-		await NoteReactions.insert(record);
-	} catch (e) {
-		if (isDuplicateKeyValueError(e)) {
-			const exists = await NoteReactions.findOneByOrFail({
-				noteId: note.id,
-				userId: user.id,
-			});
-
-			if (exists.reaction !== reaction) {
-				// 別のリアクションがすでにされていたら置き換える
-				await deleteReaction(user, note);
-				await NoteReactions.insert(record);
-			} else {
-				// 同じリアクションがすでにされていたらエラー
-				throw new IdentifiableError("51c42bb4-931a-456b-bff7-e5a8a70dd298");
-			}
-		} else {
-			throw e;
-		}
-	}
-
-	// Increment reactions count
-	const sql = `jsonb_set("reactions", '{${reaction}}', (COALESCE("reactions"->>'${reaction}', '0')::int + 1)::text::jsonb)`;
-	await Notes.createQueryBuilder()
-		.update()
-		.set({
-			reactions: () => sql,
-			score: () => '"score" + 1',
-		})
-		.where("id = :id", { id: note.id })
-		.execute();
-
-	perUserReactionsChart.update(user, note);
-
-	// カスタム絵文字リアクションだったら絵文字情報も送る
-	const decodedReaction = decodeReaction(reaction);
-
-	const emoji = await Emojis.findOne({
-		where: {
-			name: decodedReaction.name,
-			host: decodedReaction.host ?? IsNull(),
-		},
-		select: ["name", "host", "originalUrl", "publicUrl"],
-	});
-
-	publishNoteStream(note.id, "reacted", {
-		reaction: decodedReaction.reaction,
-		emoji:
-			emoji != null
-				? {
-						name: emoji.host
-							? `${emoji.name}@${emoji.host}`
-							: `${emoji.name}@.`,
-						url: emoji.publicUrl || emoji.originalUrl, // || emoji.originalUrl してるのは後方互換性のため
-				  }
-				: null,
-		userId: user.id,
-	});
-
-	// リアクションされたユーザーがローカルユーザーなら通知を作成
-	if (note.userHost === null) {
-		createNotification(note.userId, "reaction", {
-			notifierId: user.id,
-			note: note,
-			noteId: note.id,
-			reaction: reaction,
-		});
-	}
-
-	// Fetch watchers
-	NoteWatchings.findBy({
-		noteId: note.id,
-		userId: Not(user.id),
-	}).then((watchers) => {
-		for (const watcher of watchers) {
-			createNotification(watcher.userId, "reaction", {
-				notifierId: user.id,
-				note: note,
-				noteId: note.id,
-				reaction: reaction,
-			});
-		}
-	});
-
-	//#region 配信
-	if (Users.isLocalUser(user) && !note.localOnly) {
-		const content = renderActivity(await renderLike(record, note));
-		const dm = new DeliverManager(user, content);
-		if (note.userHost !== null) {
-			const reactee = await Users.findOneBy({ id: note.userId });
-			dm.addDirectRecipe(reactee as IRemoteUser);
-		}
-
-		if (["public", "home", "followers"].includes(note.visibility)) {
-			dm.addFollowersRecipe();
-		} else if (note.visibility === "specified") {
-			const visibleUsers = await Promise.all(
-				note.visibleUserIds.map((id) => Users.findOneBy({ id })),
-			);
-			for (const u of visibleUsers.filter((u) => u && Users.isRemoteUser(u))) {
-				dm.addDirectRecipe(u as IRemoteUser);
-			}
-		}
-
-		dm.execute();
-	}
-	//#endregion
-};
diff --git a/packages/backend/src/services/note/reaction/delete.ts b/packages/backend/src/services/note/reaction/delete.ts
deleted file mode 100644
index 82648249e6..0000000000
--- a/packages/backend/src/services/note/reaction/delete.ts
+++ /dev/null
@@ -1,70 +0,0 @@
-import { publishNoteStream } from "@/services/stream.js";
-import { renderLike } from "@/remote/activitypub/renderer/like.js";
-import renderUndo from "@/remote/activitypub/renderer/undo.js";
-import { renderActivity } from "@/remote/activitypub/renderer/index.js";
-import DeliverManager from "@/remote/activitypub/deliver-manager.js";
-import { IdentifiableError } from "@/misc/identifiable-error.js";
-import type { User, IRemoteUser } from "@/models/entities/user.js";
-import type { Note } from "@/models/entities/note.js";
-import { NoteReactions, Users, Notes } from "@/models/index.js";
-import { decodeReaction } from "@/misc/reaction-lib.js";
-
-export default async (
-	user: { id: User["id"]; host: User["host"] },
-	note: Note,
-) => {
-	// if already unreacted
-	const exist = await NoteReactions.findOneBy({
-		noteId: note.id,
-		userId: user.id,
-	});
-
-	if (exist == null) {
-		throw new IdentifiableError(
-			"60527ec9-b4cb-4a88-a6bd-32d3ad26817d",
-			"not reacted",
-		);
-	}
-
-	// Delete reaction
-	const result = await NoteReactions.delete(exist.id);
-
-	if (result.affected !== 1) {
-		throw new IdentifiableError(
-			"60527ec9-b4cb-4a88-a6bd-32d3ad26817d",
-			"not reacted",
-		);
-	}
-
-	// Decrement reactions count
-	const sql = `jsonb_set("reactions", '{${exist.reaction}}', (COALESCE("reactions"->>'${exist.reaction}', '0')::int - 1)::text::jsonb)`;
-	await Notes.createQueryBuilder()
-		.update()
-		.set({
-			reactions: () => sql,
-		})
-		.where("id = :id", { id: note.id })
-		.execute();
-
-	Notes.decrement({ id: note.id }, "score", 1);
-
-	publishNoteStream(note.id, "unreacted", {
-		reaction: decodeReaction(exist.reaction).reaction,
-		userId: user.id,
-	});
-
-	//#region 配信
-	if (Users.isLocalUser(user) && !note.localOnly) {
-		const content = renderActivity(
-			renderUndo(await renderLike(exist, note), user),
-		);
-		const dm = new DeliverManager(user, content);
-		if (note.userHost !== null) {
-			const reactee = await Users.findOneBy({ id: note.userId });
-			dm.addDirectRecipe(reactee as IRemoteUser);
-		}
-		dm.addFollowersRecipe();
-		dm.execute();
-	}
-	//#endregion
-};
diff --git a/packages/backend/src/services/note/read.ts b/packages/backend/src/services/note/read.ts
deleted file mode 100644
index 53188f15f7..0000000000
--- a/packages/backend/src/services/note/read.ts
+++ /dev/null
@@ -1,173 +0,0 @@
-import { publishMainStream } from "@/services/stream.js";
-import type { Note } from "@/models/entities/note.js";
-import type { User } from "@/models/entities/user.js";
-import {
-	NoteUnreads,
-	AntennaNotes,
-	Users,
-	Followings,
-	ChannelFollowings,
-} from "@/models/index.js";
-import { Not, IsNull, In } from "typeorm";
-import type { Channel } from "@/models/entities/channel.js";
-import { checkHitAntenna } from "@/misc/check-hit-antenna.js";
-import { getAntennas } from "@/misc/antenna-cache.js";
-import { readNotificationByQuery } from "@/server/api/common/read-notification.js";
-import type { Packed } from "@/misc/schema.js";
-
-/**
- * Mark notes as read
- */
-export default async function (
-	userId: User["id"],
-	notes: (Note | Packed<"Note">)[],
-	info?: {
-		following: Set<User["id"]>;
-		followingChannels: Set<Channel["id"]>;
-	},
-) {
-	const following = info?.following
-		? info.following
-		: new Set<string>(
-				(
-					await Followings.find({
-						where: {
-							followerId: userId,
-						},
-						select: ["followeeId"],
-					})
-				).map((x) => x.followeeId),
-		  );
-	const followingChannels = info?.followingChannels
-		? info.followingChannels
-		: new Set<string>(
-				(
-					await ChannelFollowings.find({
-						where: {
-							followerId: userId,
-						},
-						select: ["followeeId"],
-					})
-				).map((x) => x.followeeId),
-		  );
-
-	const myAntennas = (await getAntennas()).filter((a) => a.userId === userId);
-	const readMentions: (Note | Packed<"Note">)[] = [];
-	const readSpecifiedNotes: (Note | Packed<"Note">)[] = [];
-	const readChannelNotes: (Note | Packed<"Note">)[] = [];
-	const readAntennaNotes: (Note | Packed<"Note">)[] = [];
-
-	for (const note of notes) {
-		if (note.mentions?.includes(userId)) {
-			readMentions.push(note);
-		} else if (note.visibleUserIds?.includes(userId)) {
-			readSpecifiedNotes.push(note);
-		}
-
-		if (note.channelId && followingChannels.has(note.channelId)) {
-			readChannelNotes.push(note);
-		}
-
-		if (note.user != null) {
-			// たぶんnullになることは無いはずだけど一応
-			for (const antenna of myAntennas) {
-				if (
-					await checkHitAntenna(
-						antenna,
-						note,
-						note.user,
-						undefined,
-						Array.from(following),
-					)
-				) {
-					readAntennaNotes.push(note);
-				}
-			}
-		}
-	}
-
-	if (
-		readMentions.length > 0 ||
-		readSpecifiedNotes.length > 0 ||
-		readChannelNotes.length > 0
-	) {
-		// Remove the record
-		await NoteUnreads.delete({
-			userId: userId,
-			noteId: In([
-				...readMentions.map((n) => n.id),
-				...readSpecifiedNotes.map((n) => n.id),
-				...readChannelNotes.map((n) => n.id),
-			]),
-		});
-
-		// TODO: ↓まとめてクエリしたい
-
-		NoteUnreads.countBy({
-			userId: userId,
-			isMentioned: true,
-		}).then((mentionsCount) => {
-			if (mentionsCount === 0) {
-				// 全て既読になったイベントを発行
-				publishMainStream(userId, "readAllUnreadMentions");
-			}
-		});
-
-		NoteUnreads.countBy({
-			userId: userId,
-			isSpecified: true,
-		}).then((specifiedCount) => {
-			if (specifiedCount === 0) {
-				// 全て既読になったイベントを発行
-				publishMainStream(userId, "readAllUnreadSpecifiedNotes");
-			}
-		});
-
-		NoteUnreads.countBy({
-			userId: userId,
-			noteChannelId: Not(IsNull()),
-		}).then((channelNoteCount) => {
-			if (channelNoteCount === 0) {
-				// 全て既読になったイベントを発行
-				publishMainStream(userId, "readAllChannels");
-			}
-		});
-
-		readNotificationByQuery(userId, {
-			noteId: In([
-				...readMentions.map((n) => n.id),
-				...readSpecifiedNotes.map((n) => n.id),
-			]),
-		});
-	}
-
-	if (readAntennaNotes.length > 0) {
-		await AntennaNotes.update(
-			{
-				antennaId: In(myAntennas.map((a) => a.id)),
-				noteId: In(readAntennaNotes.map((n) => n.id)),
-			},
-			{
-				read: true,
-			},
-		);
-
-		// TODO: まとめてクエリしたい
-		for (const antenna of myAntennas) {
-			const count = await AntennaNotes.countBy({
-				antennaId: antenna.id,
-				read: false,
-			});
-
-			if (count === 0) {
-				publishMainStream(userId, "readAntenna", antenna);
-			}
-		}
-
-		Users.getHasUnreadAntenna(userId).then((unread) => {
-			if (!unread) {
-				publishMainStream(userId, "readAllAntennas");
-			}
-		});
-	}
-}
diff --git a/packages/backend/src/services/note/unread.ts b/packages/backend/src/services/note/unread.ts
deleted file mode 100644
index 275b230d47..0000000000
--- a/packages/backend/src/services/note/unread.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import type { Note } from "@/models/entities/note.js";
-import { publishMainStream } from "@/services/stream.js";
-import type { User } from "@/models/entities/user.js";
-import { Mutings, NoteThreadMutings, NoteUnreads } from "@/models/index.js";
-import { genId } from "@/misc/gen-id.js";
-
-export async function insertNoteUnread(
-	userId: User["id"],
-	note: Note,
-	params: {
-		// NOTE: isSpecifiedがtrueならisMentionedは必ずfalse
-		isSpecified: boolean;
-		isMentioned: boolean;
-	},
-) {
-	//#region ミュートしているなら無視
-	// TODO: 現在の仕様ではChannelにミュートは適用されないのでよしなにケアする
-	const mute = await Mutings.findBy({
-		muterId: userId,
-	});
-	if (mute.map((m) => m.muteeId).includes(note.userId)) return;
-	//#endregion
-
-	// スレッドミュート
-	const threadMute = await NoteThreadMutings.findOneBy({
-		userId: userId,
-		threadId: note.threadId || note.id,
-	});
-	if (threadMute) return;
-
-	const unread = {
-		id: genId(),
-		noteId: note.id,
-		userId: userId,
-		isSpecified: params.isSpecified,
-		isMentioned: params.isMentioned,
-		noteChannelId: note.channelId,
-		noteUserId: note.userId,
-	};
-
-	await NoteUnreads.insert(unread);
-
-	// 2秒経っても既読にならなかったら「未読の投稿がありますよ」イベントを発行する
-	setTimeout(async () => {
-		const exist = await NoteUnreads.findOneBy({ id: unread.id });
-
-		if (exist == null) return;
-
-		if (params.isMentioned) {
-			publishMainStream(userId, "unreadMention", note.id);
-		}
-		if (params.isSpecified) {
-			publishMainStream(userId, "unreadSpecifiedNote", note.id);
-		}
-		if (note.channelId) {
-			publishMainStream(userId, "unreadChannel", note.id);
-		}
-	}, 2000);
-}
diff --git a/packages/backend/src/services/note/unwatch.ts b/packages/backend/src/services/note/unwatch.ts
deleted file mode 100644
index b4da5e86da..0000000000
--- a/packages/backend/src/services/note/unwatch.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import type { User } from "@/models/entities/user.js";
-import { NoteWatchings } from "@/models/index.js";
-import type { Note } from "@/models/entities/note.js";
-
-export default async (me: User["id"], note: Note) => {
-	await NoteWatchings.delete({
-		noteId: note.id,
-		userId: me,
-	});
-};
diff --git a/packages/backend/src/services/note/watch.ts b/packages/backend/src/services/note/watch.ts
deleted file mode 100644
index 2a99dd6949..0000000000
--- a/packages/backend/src/services/note/watch.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import type { User } from "@/models/entities/user.js";
-import type { Note } from "@/models/entities/note.js";
-import { NoteWatchings } from "@/models/index.js";
-import { genId } from "@/misc/gen-id.js";
-import type { NoteWatching } from "@/models/entities/note-watching.js";
-
-export default async (me: User["id"], note: Note) => {
-	// 自分の投稿はwatchできない
-	if (me === note.userId) {
-		return;
-	}
-
-	await NoteWatchings.insert({
-		id: genId(),
-		createdAt: new Date(),
-		noteId: note.id,
-		userId: me,
-		noteUserId: note.userId,
-	} as NoteWatching);
-};
diff --git a/packages/backend/src/services/push-notification.ts b/packages/backend/src/services/push-notification.ts
deleted file mode 100644
index a207fae391..0000000000
--- a/packages/backend/src/services/push-notification.ts
+++ /dev/null
@@ -1,116 +0,0 @@
-import push from "web-push";
-import config from "@/config/index.js";
-import { SwSubscriptions } from "@/models/index.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import type { Packed } from "@/misc/schema.js";
-import { getNoteSummary } from "@/misc/get-note-summary.js";
-
-// Defined also packages/sw/types.ts#L14-L21
-type pushNotificationsTypes = {
-	notification: Packed<"Notification">;
-	unreadMessagingMessage: Packed<"MessagingMessage">;
-	readNotifications: { notificationIds: string[] };
-	readAllNotifications: undefined;
-	readAllMessagingMessages: undefined;
-	readAllMessagingMessagesOfARoom: { userId: string } | { groupId: string };
-};
-
-// プッシュメッセージサーバーには文字数制限があるため、内容を削減します
-function truncateNotification(notification: Packed<"Notification">): any {
-	if (notification.note) {
-		return {
-			...notification,
-			note: {
-				...notification.note,
-				// textをgetNoteSummaryしたものに置き換える
-				text: getNoteSummary(
-					notification.type === "renote"
-						? (notification.note.renote as Packed<"Note">)
-						: notification.note,
-				),
-
-				cw: undefined,
-				reply: undefined,
-				renote: undefined,
-				user: undefined as any, // 通知を受け取ったユーザーである場合が多いのでこれも捨てる
-			},
-		};
-	}
-
-	return notification;
-}
-
-export async function pushNotification<T extends keyof pushNotificationsTypes>(
-	userId: string,
-	type: T,
-	body: pushNotificationsTypes[T],
-) {
-	const meta = await fetchMeta();
-
-	if (
-		!meta.enableServiceWorker ||
-		meta.swPublicKey == null ||
-		meta.swPrivateKey == null
-	)
-		return;
-
-	// アプリケーションの連絡先と、サーバーサイドの鍵ペアの情報を登録
-	push.setVapidDetails(config.url, meta.swPublicKey, meta.swPrivateKey);
-
-	// Fetch
-	const subscriptions = await SwSubscriptions.findBy({
-		userId: userId,
-	});
-
-	for (const subscription of subscriptions) {
-		if (
-			[
-				"readNotifications",
-				"readAllNotifications",
-				"readAllMessagingMessages",
-				"readAllMessagingMessagesOfARoom",
-			].includes(type) &&
-			!subscription.sendReadMessage
-		)
-			continue;
-
-		const pushSubscription = {
-			endpoint: subscription.endpoint,
-			keys: {
-				auth: subscription.auth,
-				p256dh: subscription.publickey,
-			},
-		};
-
-		push
-			.sendNotification(
-				pushSubscription,
-				JSON.stringify({
-					type,
-					body:
-						type === "notification"
-							? truncateNotification(body as Packed<"Notification">)
-							: body,
-					userId,
-					dateTime: new Date().getTime(),
-				}),
-				{
-					proxy: config.proxy,
-				},
-			)
-			.catch((err: any) => {
-				//swLogger.info(err.statusCode);
-				//swLogger.info(err.headers);
-				//swLogger.info(err.body);
-
-				if (err.statusCode === 410) {
-					SwSubscriptions.delete({
-						userId: userId,
-						endpoint: subscription.endpoint,
-						auth: subscription.auth,
-						publickey: subscription.publickey,
-					});
-				}
-			});
-	}
-}
diff --git a/packages/backend/src/services/register-or-fetch-instance-doc.ts b/packages/backend/src/services/register-or-fetch-instance-doc.ts
deleted file mode 100644
index 4c3570e907..0000000000
--- a/packages/backend/src/services/register-or-fetch-instance-doc.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import type { Instance } from "@/models/entities/instance.js";
-import { Instances } from "@/models/index.js";
-import { genId } from "@/misc/gen-id.js";
-import { toPuny } from "@/misc/convert-host.js";
-import { Cache } from "@/misc/cache.js";
-
-const cache = new Cache<Instance>(1000 * 60 * 60);
-
-export async function registerOrFetchInstanceDoc(
-	host: string,
-): Promise<Instance> {
-	host = toPuny(host);
-
-	const cached = cache.get(host);
-	if (cached) return cached;
-
-	const index = await Instances.findOneBy({ host });
-
-	if (index == null) {
-		const i = await Instances.insert({
-			id: genId(),
-			host,
-			caughtAt: new Date(),
-			lastCommunicatedAt: new Date(),
-		}).then((x) => Instances.findOneByOrFail(x.identifiers[0]));
-
-		cache.set(host, i);
-		return i;
-	} else {
-		cache.set(host, index);
-		return index;
-	}
-}
diff --git a/packages/backend/src/services/relay.ts b/packages/backend/src/services/relay.ts
deleted file mode 100644
index 244e05c030..0000000000
--- a/packages/backend/src/services/relay.ts
+++ /dev/null
@@ -1,109 +0,0 @@
-import { IsNull } from "typeorm";
-import { renderFollowRelay } from "@/remote/activitypub/renderer/follow-relay.js";
-import {
-	renderActivity,
-	attachLdSignature,
-} from "@/remote/activitypub/renderer/index.js";
-import renderUndo from "@/remote/activitypub/renderer/undo.js";
-import { deliver } from "@/queue/index.js";
-import type { ILocalUser, User } from "@/models/entities/user.js";
-import { Users, Relays } from "@/models/index.js";
-import { genId } from "@/misc/gen-id.js";
-import { Cache } from "@/misc/cache.js";
-import type { Relay } from "@/models/entities/relay.js";
-import { createSystemUser } from "./create-system-user.js";
-
-const ACTOR_USERNAME = "relay.actor" as const;
-
-const relaysCache = new Cache<Relay[]>(1000 * 60 * 10);
-
-export async function getRelayActor(): Promise<ILocalUser> {
-	const user = await Users.findOneBy({
-		host: IsNull(),
-		username: ACTOR_USERNAME,
-	});
-
-	if (user) return user as ILocalUser;
-
-	const created = await createSystemUser(ACTOR_USERNAME);
-	return created as ILocalUser;
-}
-
-export async function addRelay(inbox: string) {
-	const relay = await Relays.insert({
-		id: genId(),
-		inbox,
-		status: "requesting",
-	}).then((x) => Relays.findOneByOrFail(x.identifiers[0]));
-
-	const relayActor = await getRelayActor();
-	const follow = await renderFollowRelay(relay, relayActor);
-	const activity = renderActivity(follow);
-	deliver(relayActor, activity, relay.inbox);
-
-	return relay;
-}
-
-export async function removeRelay(inbox: string) {
-	const relay = await Relays.findOneBy({
-		inbox,
-	});
-
-	if (relay == null) {
-		throw new Error("relay not found");
-	}
-
-	const relayActor = await getRelayActor();
-	const follow = renderFollowRelay(relay, relayActor);
-	const undo = renderUndo(follow, relayActor);
-	const activity = renderActivity(undo);
-	deliver(relayActor, activity, relay.inbox);
-
-	await Relays.delete(relay.id);
-}
-
-export async function listRelay() {
-	const relays = await Relays.find();
-	return relays;
-}
-
-export async function relayAccepted(id: string) {
-	const result = await Relays.update(id, {
-		status: "accepted",
-	});
-
-	return JSON.stringify(result);
-}
-
-export async function relayRejected(id: string) {
-	const result = await Relays.update(id, {
-		status: "rejected",
-	});
-
-	return JSON.stringify(result);
-}
-
-export async function deliverToRelays(
-	user: { id: User["id"]; host: null },
-	activity: any,
-) {
-	if (activity == null) return;
-
-	const relays = await relaysCache.fetch(null, () =>
-		Relays.findBy({
-			status: "accepted",
-		}),
-	);
-	if (relays.length === 0) return;
-
-	// TODO
-	//const copy = structuredClone(activity);
-	const copy = JSON.parse(JSON.stringify(activity));
-	if (!copy.to) copy.to = ["https://www.w3.org/ns/activitystreams#Public"];
-
-	const signed = await attachLdSignature(copy, user);
-
-	for (const relay of relays) {
-		deliver(user, signed, relay.inbox);
-	}
-}
diff --git a/packages/backend/src/services/send-email-notification.ts b/packages/backend/src/services/send-email-notification.ts
deleted file mode 100644
index 14a9754fe5..0000000000
--- a/packages/backend/src/services/send-email-notification.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import { UserProfiles } from "@/models/index.js";
-import type { User } from "@/models/entities/user.js";
-import { sendEmail } from "./send-email.js";
-import { I18n } from "@/misc/i18n.js";
-import * as Acct from "@/misc/acct.js";
-// TODO
-//const locales = await import('../../../../locales/index.js');
-
-// TODO: locale ファイルをクライアント用とサーバー用で分けたい
-
-async function follow(userId: User["id"], follower: User) {
-	/*
-	const userProfile = await UserProfiles.findOneByOrFail({ userId: userId });
-	if (!userProfile.email || !userProfile.emailNotificationTypes.includes('follow')) return;
-	const locale = locales[userProfile.lang || 'ja-JP'];
-	const i18n = new I18n(locale);
-	// TODO: render user information html
-	sendEmail(userProfile.email, i18n.t('_email._follow.title'), `${follower.name} (@${Acct.toString(follower)})`, `${follower.name} (@${Acct.toString(follower)})`);
-	*/
-}
-
-async function receiveFollowRequest(userId: User["id"], follower: User) {
-	/*
-	const userProfile = await UserProfiles.findOneByOrFail({ userId: userId });
-	if (!userProfile.email || !userProfile.emailNotificationTypes.includes('receiveFollowRequest')) return;
-	const locale = locales[userProfile.lang || 'ja-JP'];
-	const i18n = new I18n(locale);
-	// TODO: render user information html
-	sendEmail(userProfile.email, i18n.t('_email._receiveFollowRequest.title'), `${follower.name} (@${Acct.toString(follower)})`, `${follower.name} (@${Acct.toString(follower)})`);
-	*/
-}
-
-export const sendEmailNotification = {
-	follow,
-	receiveFollowRequest,
-};
diff --git a/packages/backend/src/services/send-email.ts b/packages/backend/src/services/send-email.ts
deleted file mode 100644
index 4c442a168c..0000000000
--- a/packages/backend/src/services/send-email.ts
+++ /dev/null
@@ -1,132 +0,0 @@
-import * as nodemailer from "nodemailer";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-import Logger from "./logger.js";
-import config from "@/config/index.js";
-
-export const logger = new Logger("email");
-
-export async function sendEmail(
-	to: string,
-	subject: string,
-	html: string,
-	text: string,
-) {
-	const meta = await fetchMeta(true);
-
-	const iconUrl = `${config.url}/static-assets/mi-white.png`;
-	const emailSettingUrl = `${config.url}/settings/email`;
-
-	const enableAuth = meta.smtpUser != null && meta.smtpUser !== "";
-
-	const transporter = nodemailer.createTransport({
-		host: meta.smtpHost,
-		port: meta.smtpPort,
-		secure: meta.smtpSecure,
-		ignoreTLS: !enableAuth,
-		proxy: config.proxySmtp,
-		auth: enableAuth
-			? {
-					user: meta.smtpUser,
-					pass: meta.smtpPass,
-			  }
-			: undefined,
-	} as any);
-
-	try {
-		// TODO: htmlサニタイズ
-		const info = await transporter.sendMail({
-			from: meta.email!,
-			to: to,
-			subject: subject,
-			text: text,
-			html: `<!DOCTYPE html>
-<html>
-	<head>
-		<meta charset="utf-8">
-		<title>${subject}</title>
-		<style>
-			html {
-				background: #191724;
-			}
-
-			body {
-				padding: 16px;
-				margin: 0;
-				font-family: sans-serif;
-				font-size: 14px;
-			}
-
-			a {
-				text-decoration: none;
-				color: #31748f;
-			}
-			a:hover {
-				text-decoration: underline;
-			}
-
-			main {
-				max-width: 500px;
-				margin: 0 auto;
-				background: #1f1d2e;
-				color: #e0def4;
-			}
-				main > header {
-					padding: 32px;
-					background: #31748f;
-					display: flex;
-				}
-					main > header > img {
-						max-width: 128px;
-						max-height: 72px;
-						vertical-align: bottom;
-						margin-right: 16px;
-					}
-				main > article {
-					padding: 32px;
-				}
-					main > article > h1 {
-						margin: 0 0 1em 0;
-					}
-				main > footer {
-					padding: 32px;
-					border-top: solid 1px #26233a;
-				}
-
-			nav {
-				box-sizing: border-box;
-				max-width: 500px;
-				margin: 16px auto 0 auto;
-				padding: 0 32px;
-			}
-				nav > a {
-					color: #6e6a86;
-				}
-		</style>
-	</head>
-	<body>
-		<main>
-			<header>
-				<img src="${meta.logoImageUrl || meta.iconUrl || iconUrl}" height="100"/>
-				<h1>${meta.name}</h1>
-			</header>
-			<article>
-				<h1>${subject}</h1>
-				<div>${html}</div>
-			</article>
-			<footer>
-				<a href="${emailSettingUrl}">${"Email setting"}</a>
-			</footer>
-		</main>
-		<nav>
-			<a href="${config.url}">${config.host}</a>
-		</nav>
-	</body>
-</html>`,
-		});
-
-		logger.info(`Message sent: ${info.messageId}`);
-	} catch (err) {
-		logger.error(err as Error);
-		throw err;
-	}
-}
diff --git a/packages/backend/src/services/stream.ts b/packages/backend/src/services/stream.ts
deleted file mode 100644
index f3846feaf1..0000000000
--- a/packages/backend/src/services/stream.ts
+++ /dev/null
@@ -1,226 +0,0 @@
-import { redisClient } from "../db/redis.js";
-import type { User } from "@/models/entities/user.js";
-import type { Note } from "@/models/entities/note.js";
-import type { UserList } from "@/models/entities/user-list.js";
-import type { UserGroup } from "@/models/entities/user-group.js";
-import config from "@/config/index.js";
-import type { Antenna } from "@/models/entities/antenna.js";
-import type { Channel } from "@/models/entities/channel.js";
-import type {
-	StreamChannels,
-	AdminStreamTypes,
-	AntennaStreamTypes,
-	BroadcastTypes,
-	ChannelStreamTypes,
-	DriveStreamTypes,
-	GroupMessagingStreamTypes,
-	InternalStreamTypes,
-	MainStreamTypes,
-	MessagingIndexStreamTypes,
-	MessagingStreamTypes,
-	NoteStreamTypes,
-	UserListStreamTypes,
-	UserStreamTypes,
-} from "@/server/api/stream/types.js";
-
-class Publisher {
-	private publish = (
-		channel: StreamChannels,
-		type: string | null,
-		value?: any,
-	): void => {
-		const message =
-			type == null
-				? value
-				: value == null
-				? { type: type, body: null }
-				: { type: type, body: value };
-
-		redisClient.publish(
-			config.host,
-			JSON.stringify({
-				channel: channel,
-				message: message,
-			}),
-		);
-	};
-
-	public publishInternalEvent = <K extends keyof InternalStreamTypes>(
-		type: K,
-		value?: InternalStreamTypes[K],
-	): void => {
-		this.publish("internal", type, typeof value === "undefined" ? null : value);
-	};
-
-	public publishUserEvent = <K extends keyof UserStreamTypes>(
-		userId: User["id"],
-		type: K,
-		value?: UserStreamTypes[K],
-	): void => {
-		this.publish(
-			`user:${userId}`,
-			type,
-			typeof value === "undefined" ? null : value,
-		);
-	};
-
-	public publishBroadcastStream = <K extends keyof BroadcastTypes>(
-		type: K,
-		value?: BroadcastTypes[K],
-	): void => {
-		this.publish(
-			"broadcast",
-			type,
-			typeof value === "undefined" ? null : value,
-		);
-	};
-
-	public publishMainStream = <K extends keyof MainStreamTypes>(
-		userId: User["id"],
-		type: K,
-		value?: MainStreamTypes[K],
-	): void => {
-		this.publish(
-			`mainStream:${userId}`,
-			type,
-			typeof value === "undefined" ? null : value,
-		);
-	};
-
-	public publishDriveStream = <K extends keyof DriveStreamTypes>(
-		userId: User["id"],
-		type: K,
-		value?: DriveStreamTypes[K],
-	): void => {
-		this.publish(
-			`driveStream:${userId}`,
-			type,
-			typeof value === "undefined" ? null : value,
-		);
-	};
-
-	public publishNoteStream = <K extends keyof NoteStreamTypes>(
-		noteId: Note["id"],
-		type: K,
-		value?: NoteStreamTypes[K],
-	): void => {
-		this.publish(`noteStream:${noteId}`, type, {
-			id: noteId,
-			body: value,
-		});
-	};
-
-	public publishChannelStream = <K extends keyof ChannelStreamTypes>(
-		channelId: Channel["id"],
-		type: K,
-		value?: ChannelStreamTypes[K],
-	): void => {
-		this.publish(
-			`channelStream:${channelId}`,
-			type,
-			typeof value === "undefined" ? null : value,
-		);
-	};
-
-	public publishUserListStream = <K extends keyof UserListStreamTypes>(
-		listId: UserList["id"],
-		type: K,
-		value?: UserListStreamTypes[K],
-	): void => {
-		this.publish(
-			`userListStream:${listId}`,
-			type,
-			typeof value === "undefined" ? null : value,
-		);
-	};
-
-	public publishAntennaStream = <K extends keyof AntennaStreamTypes>(
-		antennaId: Antenna["id"],
-		type: K,
-		value?: AntennaStreamTypes[K],
-	): void => {
-		this.publish(
-			`antennaStream:${antennaId}`,
-			type,
-			typeof value === "undefined" ? null : value,
-		);
-	};
-
-	public publishMessagingStream = <K extends keyof MessagingStreamTypes>(
-		userId: User["id"],
-		otherpartyId: User["id"],
-		type: K,
-		value?: MessagingStreamTypes[K],
-	): void => {
-		this.publish(
-			`messagingStream:${userId}-${otherpartyId}`,
-			type,
-			typeof value === "undefined" ? null : value,
-		);
-	};
-
-	public publishGroupMessagingStream = <
-		K extends keyof GroupMessagingStreamTypes,
-	>(
-		groupId: UserGroup["id"],
-		type: K,
-		value?: GroupMessagingStreamTypes[K],
-	): void => {
-		this.publish(
-			`messagingStream:${groupId}`,
-			type,
-			typeof value === "undefined" ? null : value,
-		);
-	};
-
-	public publishMessagingIndexStream = <
-		K extends keyof MessagingIndexStreamTypes,
-	>(
-		userId: User["id"],
-		type: K,
-		value?: MessagingIndexStreamTypes[K],
-	): void => {
-		this.publish(
-			`messagingIndexStream:${userId}`,
-			type,
-			typeof value === "undefined" ? null : value,
-		);
-	};
-
-	public publishNotesStream = (note: Note): void => {
-		this.publish("notesStream", null, note);
-	};
-
-	public publishAdminStream = <K extends keyof AdminStreamTypes>(
-		userId: User["id"],
-		type: K,
-		value?: AdminStreamTypes[K],
-	): void => {
-		this.publish(
-			`adminStream:${userId}`,
-			type,
-			typeof value === "undefined" ? null : value,
-		);
-	};
-}
-
-const publisher = new Publisher();
-
-export default publisher;
-
-export const publishInternalEvent = publisher.publishInternalEvent;
-export const publishUserEvent = publisher.publishUserEvent;
-export const publishBroadcastStream = publisher.publishBroadcastStream;
-export const publishMainStream = publisher.publishMainStream;
-export const publishDriveStream = publisher.publishDriveStream;
-export const publishNoteStream = publisher.publishNoteStream;
-export const publishNotesStream = publisher.publishNotesStream;
-export const publishChannelStream = publisher.publishChannelStream;
-export const publishUserListStream = publisher.publishUserListStream;
-export const publishAntennaStream = publisher.publishAntennaStream;
-export const publishMessagingStream = publisher.publishMessagingStream;
-export const publishGroupMessagingStream =
-	publisher.publishGroupMessagingStream;
-export const publishMessagingIndexStream =
-	publisher.publishMessagingIndexStream;
-export const publishAdminStream = publisher.publishAdminStream;
diff --git a/packages/backend/src/services/suspend-user.ts b/packages/backend/src/services/suspend-user.ts
deleted file mode 100644
index f72b8ffcb1..0000000000
--- a/packages/backend/src/services/suspend-user.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import renderDelete from "@/remote/activitypub/renderer/delete.js";
-import { renderActivity } from "@/remote/activitypub/renderer/index.js";
-import { deliver } from "@/queue/index.js";
-import config from "@/config/index.js";
-import type { User } from "@/models/entities/user.js";
-import { Users, Followings } from "@/models/index.js";
-import { Not, IsNull } from "typeorm";
-import { publishInternalEvent } from "@/services/stream.js";
-
-export async function doPostSuspend(user: {
-	id: User["id"];
-	host: User["host"];
-}) {
-	publishInternalEvent("userChangeSuspendedState", {
-		id: user.id,
-		isSuspended: true,
-	});
-
-	if (Users.isLocalUser(user)) {
-		// Send Delete to all known SharedInboxes
-		const content = renderActivity(
-			renderDelete(`${config.url}/users/${user.id}`, user),
-		);
-
-		const queue: string[] = [];
-
-		const followings = await Followings.find({
-			where: [
-				{ followerSharedInbox: Not(IsNull()) },
-				{ followeeSharedInbox: Not(IsNull()) },
-			],
-			select: ["followerSharedInbox", "followeeSharedInbox"],
-		});
-
-		const inboxes = followings.map(
-			(x) => x.followerSharedInbox || x.followeeSharedInbox,
-		);
-
-		for (const inbox of inboxes) {
-			if (inbox != null && !queue.includes(inbox)) queue.push(inbox);
-		}
-
-		for (const inbox of queue) {
-			deliver(user, content, inbox);
-		}
-	}
-}
diff --git a/packages/backend/src/services/unsuspend-user.ts b/packages/backend/src/services/unsuspend-user.ts
deleted file mode 100644
index 69447a4a26..0000000000
--- a/packages/backend/src/services/unsuspend-user.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import renderDelete from "@/remote/activitypub/renderer/delete.js";
-import renderUndo from "@/remote/activitypub/renderer/undo.js";
-import { renderActivity } from "@/remote/activitypub/renderer/index.js";
-import { deliver } from "@/queue/index.js";
-import config from "@/config/index.js";
-import type { User } from "@/models/entities/user.js";
-import { Users, Followings } from "@/models/index.js";
-import { Not, IsNull } from "typeorm";
-import { publishInternalEvent } from "@/services/stream.js";
-
-export async function doPostUnsuspend(user: User) {
-	publishInternalEvent("userChangeSuspendedState", {
-		id: user.id,
-		isSuspended: false,
-	});
-
-	if (Users.isLocalUser(user)) {
-		// 知り得る全SharedInboxにUndo Delete配信
-		const content = renderActivity(
-			renderUndo(renderDelete(`${config.url}/users/${user.id}`, user), user),
-		);
-
-		const queue: string[] = [];
-
-		const followings = await Followings.find({
-			where: [
-				{ followerSharedInbox: Not(IsNull()) },
-				{ followeeSharedInbox: Not(IsNull()) },
-			],
-			select: ["followerSharedInbox", "followeeSharedInbox"],
-		});
-
-		const inboxes = followings.map(
-			(x) => x.followerSharedInbox || x.followeeSharedInbox,
-		);
-
-		for (const inbox of inboxes) {
-			if (inbox != null && !queue.includes(inbox)) queue.push(inbox);
-		}
-
-		for (const inbox of queue) {
-			deliver(user as any, content, inbox);
-		}
-	}
-}
diff --git a/packages/backend/src/services/update-hashtag.ts b/packages/backend/src/services/update-hashtag.ts
deleted file mode 100644
index 0c65b08f0a..0000000000
--- a/packages/backend/src/services/update-hashtag.ts
+++ /dev/null
@@ -1,158 +0,0 @@
-import type { User } from "@/models/entities/user.js";
-import { Hashtags, Users } from "@/models/index.js";
-import { hashtagChart } from "@/services/chart/index.js";
-import { genId } from "@/misc/gen-id.js";
-import type { Hashtag } from "@/models/entities/hashtag.js";
-import { normalizeForSearch } from "@/misc/normalize-for-search.js";
-
-export async function updateHashtags(
-	user: { id: User["id"]; host: User["host"] },
-	tags: string[],
-) {
-	for (const tag of tags) {
-		await updateHashtag(user, tag);
-	}
-}
-
-export async function updateUsertags(user: User, tags: string[]) {
-	for (const tag of tags) {
-		await updateHashtag(user, tag, true, true);
-	}
-
-	for (const tag of (user.tags || []).filter((x) => !tags.includes(x))) {
-		await updateHashtag(user, tag, true, false);
-	}
-}
-
-export async function updateHashtag(
-	user: { id: User["id"]; host: User["host"] },
-	tag: string,
-	isUserAttached = false,
-	inc = true,
-) {
-	tag = normalizeForSearch(tag);
-
-	const index = await Hashtags.findOneBy({ name: tag });
-
-	if (index == null && !inc) return;
-
-	if (index != null) {
-		const q = Hashtags.createQueryBuilder("tag")
-			.update()
-			.where("name = :name", { name: tag });
-
-		const set = {} as any;
-
-		if (isUserAttached) {
-			if (inc) {
-				// 自分が初めてこのタグを使ったなら
-				if (!index.attachedUserIds.some((id) => id === user.id)) {
-					set.attachedUserIds = () =>
-						`array_append("attachedUserIds", '${user.id}')`;
-					set.attachedUsersCount = () => `"attachedUsersCount" + 1`;
-				}
-				// 自分が(ローカル内で)初めてこのタグを使ったなら
-				if (
-					Users.isLocalUser(user) &&
-					!index.attachedLocalUserIds.some((id) => id === user.id)
-				) {
-					set.attachedLocalUserIds = () =>
-						`array_append("attachedLocalUserIds", '${user.id}')`;
-					set.attachedLocalUsersCount = () => `"attachedLocalUsersCount" + 1`;
-				}
-				// 自分が(リモートで)初めてこのタグを使ったなら
-				if (
-					Users.isRemoteUser(user) &&
-					!index.attachedRemoteUserIds.some((id) => id === user.id)
-				) {
-					set.attachedRemoteUserIds = () =>
-						`array_append("attachedRemoteUserIds", '${user.id}')`;
-					set.attachedRemoteUsersCount = () => `"attachedRemoteUsersCount" + 1`;
-				}
-			} else {
-				set.attachedUserIds = () =>
-					`array_remove("attachedUserIds", '${user.id}')`;
-				set.attachedUsersCount = () => `"attachedUsersCount" - 1`;
-				if (Users.isLocalUser(user)) {
-					set.attachedLocalUserIds = () =>
-						`array_remove("attachedLocalUserIds", '${user.id}')`;
-					set.attachedLocalUsersCount = () => `"attachedLocalUsersCount" - 1`;
-				} else {
-					set.attachedRemoteUserIds = () =>
-						`array_remove("attachedRemoteUserIds", '${user.id}')`;
-					set.attachedRemoteUsersCount = () => `"attachedRemoteUsersCount" - 1`;
-				}
-			}
-		} else {
-			// 自分が初めてこのタグを使ったなら
-			if (!index.mentionedUserIds.some((id) => id === user.id)) {
-				set.mentionedUserIds = () =>
-					`array_append("mentionedUserIds", '${user.id}')`;
-				set.mentionedUsersCount = () => `"mentionedUsersCount" + 1`;
-			}
-			// 自分が(ローカル内で)初めてこのタグを使ったなら
-			if (
-				Users.isLocalUser(user) &&
-				!index.mentionedLocalUserIds.some((id) => id === user.id)
-			) {
-				set.mentionedLocalUserIds = () =>
-					`array_append("mentionedLocalUserIds", '${user.id}')`;
-				set.mentionedLocalUsersCount = () => `"mentionedLocalUsersCount" + 1`;
-			}
-			// 自分が(リモートで)初めてこのタグを使ったなら
-			if (
-				Users.isRemoteUser(user) &&
-				!index.mentionedRemoteUserIds.some((id) => id === user.id)
-			) {
-				set.mentionedRemoteUserIds = () =>
-					`array_append("mentionedRemoteUserIds", '${user.id}')`;
-				set.mentionedRemoteUsersCount = () => `"mentionedRemoteUsersCount" + 1`;
-			}
-		}
-
-		if (Object.keys(set).length > 0) {
-			q.set(set);
-			q.execute();
-		}
-	} else {
-		if (isUserAttached) {
-			Hashtags.insert({
-				id: genId(),
-				name: tag,
-				mentionedUserIds: [],
-				mentionedUsersCount: 0,
-				mentionedLocalUserIds: [],
-				mentionedLocalUsersCount: 0,
-				mentionedRemoteUserIds: [],
-				mentionedRemoteUsersCount: 0,
-				attachedUserIds: [user.id],
-				attachedUsersCount: 1,
-				attachedLocalUserIds: Users.isLocalUser(user) ? [user.id] : [],
-				attachedLocalUsersCount: Users.isLocalUser(user) ? 1 : 0,
-				attachedRemoteUserIds: Users.isRemoteUser(user) ? [user.id] : [],
-				attachedRemoteUsersCount: Users.isRemoteUser(user) ? 1 : 0,
-			} as Hashtag);
-		} else {
-			Hashtags.insert({
-				id: genId(),
-				name: tag,
-				mentionedUserIds: [user.id],
-				mentionedUsersCount: 1,
-				mentionedLocalUserIds: Users.isLocalUser(user) ? [user.id] : [],
-				mentionedLocalUsersCount: Users.isLocalUser(user) ? 1 : 0,
-				mentionedRemoteUserIds: Users.isRemoteUser(user) ? [user.id] : [],
-				mentionedRemoteUsersCount: Users.isRemoteUser(user) ? 1 : 0,
-				attachedUserIds: [],
-				attachedUsersCount: 0,
-				attachedLocalUserIds: [],
-				attachedLocalUsersCount: 0,
-				attachedRemoteUserIds: [],
-				attachedRemoteUsersCount: 0,
-			} as Hashtag);
-		}
-	}
-
-	if (!isUserAttached) {
-		hashtagChart.update(tag, user);
-	}
-}
diff --git a/packages/backend/src/services/user-cache.ts b/packages/backend/src/services/user-cache.ts
deleted file mode 100644
index 9492448554..0000000000
--- a/packages/backend/src/services/user-cache.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-import type {
-	CacheableLocalUser,
-	CacheableUser,
-	ILocalUser,
-} from "@/models/entities/user.js";
-import { User } from "@/models/entities/user.js";
-import { Users } from "@/models/index.js";
-import { Cache } from "@/misc/cache.js";
-import { subscriber } from "@/db/redis.js";
-
-export const userByIdCache = new Cache<CacheableUser>(Infinity);
-export const localUserByNativeTokenCache = new Cache<CacheableLocalUser | null>(
-	Infinity,
-);
-export const localUserByIdCache = new Cache<CacheableLocalUser>(Infinity);
-export const uriPersonCache = new Cache<CacheableUser | null>(Infinity);
-
-subscriber.on("message", async (_, data) => {
-	const obj = JSON.parse(data);
-
-	if (obj.channel === "internal") {
-		const { type, body } = obj.message;
-		switch (type) {
-			case "localUserUpdated": {
-				userByIdCache.delete(body.id);
-				localUserByIdCache.delete(body.id);
-				localUserByNativeTokenCache.cache.forEach((v, k) => {
-					if (v.value?.id === body.id) {
-						localUserByNativeTokenCache.delete(k);
-					}
-				});
-				break;
-			}
-			case "userChangeSuspendedState":
-			case "userChangeSilencedState":
-			case "userChangeModeratorState":
-			case "remoteUserUpdated": {
-				const user = await Users.findOneByOrFail({ id: body.id });
-				userByIdCache.set(user.id, user);
-				for (const [k, v] of uriPersonCache.cache.entries()) {
-					if (v.value?.id === user.id) {
-						uriPersonCache.set(k, user);
-					}
-				}
-				if (Users.isLocalUser(user)) {
-					localUserByNativeTokenCache.set(user.token, user);
-					localUserByIdCache.set(user.id, user);
-				}
-				break;
-			}
-			case "userTokenRegenerated": {
-				const user = (await Users.findOneByOrFail({
-					id: body.id,
-				})) as ILocalUser;
-				localUserByNativeTokenCache.delete(body.oldToken);
-				localUserByNativeTokenCache.set(body.newToken, user);
-				break;
-			}
-			default:
-				break;
-		}
-	}
-});
diff --git a/packages/backend/src/services/user-list/push.ts b/packages/backend/src/services/user-list/push.ts
deleted file mode 100644
index 01bb066019..0000000000
--- a/packages/backend/src/services/user-list/push.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import { publishUserListStream } from "@/services/stream.js";
-import type { User } from "@/models/entities/user.js";
-import type { UserList } from "@/models/entities/user-list.js";
-import { UserListJoinings, Users } from "@/models/index.js";
-import type { UserListJoining } from "@/models/entities/user-list-joining.js";
-import { genId } from "@/misc/gen-id.js";
-import { fetchProxyAccount } from "@/misc/fetch-proxy-account.js";
-import createFollowing from "../following/create.js";
-
-export async function pushUserToUserList(target: User, list: UserList) {
-	await UserListJoinings.insert({
-		id: genId(),
-		createdAt: new Date(),
-		userId: target.id,
-		userListId: list.id,
-	} as UserListJoining);
-
-	publishUserListStream(list.id, "userAdded", await Users.pack(target));
-
-	// このインスタンス内にこのリモートユーザーをフォローしているユーザーがいなくても投稿を受け取るためにダミーのユーザーがフォローしたということにする
-	if (Users.isRemoteUser(target)) {
-		const proxy = await fetchProxyAccount();
-		if (proxy) {
-			createFollowing(proxy, target);
-		}
-	}
-}
diff --git a/packages/backend/src/services/validate-email-for-account.ts b/packages/backend/src/services/validate-email-for-account.ts
deleted file mode 100644
index 2bb5e93e7e..0000000000
--- a/packages/backend/src/services/validate-email-for-account.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import { validate as validateEmail } from "deep-email-validator";
-import { UserProfiles } from "@/models/index.js";
-import { fetchMeta } from "@/misc/fetch-meta.js";
-
-export async function validateEmailForAccount(emailAddress: string): Promise<{
-	available: boolean;
-	reason: null | "used" | "format" | "disposable" | "mx" | "smtp";
-}> {
-	const meta = await fetchMeta();
-
-	const exist = await UserProfiles.countBy({
-		emailVerified: true,
-		email: emailAddress,
-	});
-
-	const validated = meta.enableActiveEmailValidation
-		? await validateEmail({
-				email: emailAddress,
-				validateRegex: true,
-				validateMx: true,
-				validateTypo: false, // TLDを見ているみたいだけどclubとか弾かれるので
-				validateDisposable: true, // 捨てアドかどうかチェック
-				validateSMTP: false, // 日本だと25ポートが殆どのプロバイダーで塞がれていてタイムアウトになるので
-		  })
-		: { valid: true };
-
-	const available = exist === 0 && validated.valid;
-
-	return {
-		available,
-		reason: available
-			? null
-			: exist !== 0
-			? "used"
-			: validated.reason === "regex"
-			? "format"
-			: validated.reason === "disposable"
-			? "disposable"
-			: validated.reason === "mx"
-			? "mx"
-			: validated.reason === "smtp"
-			? "smtp"
-			: null,
-	};
-}
diff --git a/packages/backend/src/types.ts b/packages/backend/src/types.ts
deleted file mode 100644
index 9e53440a17..0000000000
--- a/packages/backend/src/types.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-export const notificationTypes = [
-	"follow",
-	"mention",
-	"reply",
-	"renote",
-	"quote",
-	"reaction",
-	"pollVote",
-	"pollEnded",
-	"receiveFollowRequest",
-	"followRequestAccepted",
-	"groupInvited",
-	"app",
-] as const;
-
-export const noteVisibilities = [
-	"public",
-	"home",
-	"followers",
-	"specified",
-] as const;
-
-export const mutedNoteReasons = ["word", "manual", "spam", "other"] as const;
-
-export const ffVisibility = ["public", "followers", "private"] as const;
diff --git a/packages/backend/test/activitypub.ts b/packages/backend/test/activitypub.ts
deleted file mode 100644
index 7b6f85f5a1..0000000000
--- a/packages/backend/test/activitypub.ts
+++ /dev/null
@@ -1,102 +0,0 @@
-process.env.NODE_ENV = "test";
-
-import * as assert from "assert";
-import rndstr from "rndstr";
-import { initDb } from "../src/db/postgre.js";
-import { initTestDb } from "./utils.js";
-
-describe("ActivityPub", () => {
-	before(async () => {
-		//await initTestDb();
-		await initDb();
-	});
-
-	describe("Parse minimum object", () => {
-		const host = "https://host1.test";
-		const preferredUsername = `${rndstr("A-Z", 4)}${rndstr("a-z", 4)}`;
-		const actorId = `${host}/users/${preferredUsername.toLowerCase()}`;
-
-		const actor = {
-			"@context": "https://www.w3.org/ns/activitystreams",
-			id: actorId,
-			type: "Person",
-			preferredUsername,
-			inbox: `${actorId}/inbox`,
-			outbox: `${actorId}/outbox`,
-		};
-
-		const post = {
-			"@context": "https://www.w3.org/ns/activitystreams",
-			id: `${host}/users/${rndstr("0-9a-z", 8)}`,
-			type: "Note",
-			attributedTo: actor.id,
-			to: "https://www.w3.org/ns/activitystreams#Public",
-			content: "あ",
-		};
-
-		it("Minimum Actor", async () => {
-			const { MockResolver } = await import("./misc/mock-resolver.js");
-			const { createPerson } = await import(
-				"../src/remote/activitypub/models/person.js"
-			);
-
-			const resolver = new MockResolver();
-			resolver._register(actor.id, actor);
-
-			const user = await createPerson(actor.id, resolver);
-
-			assert.deepStrictEqual(user.uri, actor.id);
-			assert.deepStrictEqual(user.username, actor.preferredUsername);
-			assert.deepStrictEqual(user.inbox, actor.inbox);
-		});
-
-		it("Minimum Note", async () => {
-			const { MockResolver } = await import("./misc/mock-resolver.js");
-			const { createNote } = await import(
-				"../src/remote/activitypub/models/note.js"
-			);
-
-			const resolver = new MockResolver();
-			resolver._register(actor.id, actor);
-			resolver._register(post.id, post);
-
-			const note = await createNote(post.id, resolver, true);
-
-			assert.deepStrictEqual(note?.uri, post.id);
-			assert.deepStrictEqual(note.visibility, "public");
-			assert.deepStrictEqual(note.text, post.content);
-		});
-	});
-
-	describe("Truncate long name", () => {
-		const host = "https://host1.test";
-		const preferredUsername = `${rndstr("A-Z", 4)}${rndstr("a-z", 4)}`;
-		const actorId = `${host}/users/${preferredUsername.toLowerCase()}`;
-
-		const name = rndstr("0-9a-z", 129);
-
-		const actor = {
-			"@context": "https://www.w3.org/ns/activitystreams",
-			id: actorId,
-			type: "Person",
-			preferredUsername,
-			name,
-			inbox: `${actorId}/inbox`,
-			outbox: `${actorId}/outbox`,
-		};
-
-		it("Actor", async () => {
-			const { MockResolver } = await import("./misc/mock-resolver.js");
-			const { createPerson } = await import(
-				"../src/remote/activitypub/models/person.js"
-			);
-
-			const resolver = new MockResolver();
-			resolver._register(actor.id, actor);
-
-			const user = await createPerson(actor.id, resolver);
-
-			assert.deepStrictEqual(user.name, actor.name.substr(0, 128));
-		});
-	});
-});
diff --git a/packages/backend/test/ap-request.ts b/packages/backend/test/ap-request.ts
deleted file mode 100644
index bf77a38532..0000000000
--- a/packages/backend/test/ap-request.ts
+++ /dev/null
@@ -1,75 +0,0 @@
-import * as assert from "assert";
-import httpSignature from "@peertube/http-signature";
-import { genRsaKeyPair } from "../src/misc/gen-key-pair.js";
-import {
-	createSignedPost,
-	createSignedGet,
-} from "../src/remote/activitypub/ap-request.js";
-
-export const buildParsedSignature = (
-	signingString: string,
-	signature: string,
-	algorithm: string,
-) => {
-	return {
-		scheme: "Signature",
-		params: {
-			keyId: "KeyID", // dummy, not used for verify
-			algorithm: algorithm,
-			headers: ["(request-target)", "date", "host", "digest"], // dummy, not used for verify
-			signature: signature,
-		},
-		signingString: signingString,
-		algorithm: algorithm.toUpperCase(),
-		keyId: "KeyID", // dummy, not used for verify
-	};
-};
-
-describe("ap-request", () => {
-	it("createSignedPost with verify", async () => {
-		const keypair = await genRsaKeyPair();
-		const key = { keyId: "x", privateKeyPem: keypair.privateKey };
-		const url = "https://example.com/inbox";
-		const activity = { a: 1 };
-		const body = JSON.stringify(activity);
-		const headers = {
-			"User-Agent": "UA",
-		};
-
-		const req = createSignedPost({
-			key,
-			url,
-			body,
-			additionalHeaders: headers,
-		});
-
-		const parsed = buildParsedSignature(
-			req.signingString,
-			req.signature,
-			"rsa-sha256",
-		);
-
-		const result = httpSignature.verifySignature(parsed, keypair.publicKey);
-		assert.deepStrictEqual(result, true);
-	});
-
-	it("createSignedGet with verify", async () => {
-		const keypair = await genRsaKeyPair();
-		const key = { keyId: "x", privateKeyPem: keypair.privateKey };
-		const url = "https://example.com/outbox";
-		const headers = {
-			"User-Agent": "UA",
-		};
-
-		const req = createSignedGet({ key, url, additionalHeaders: headers });
-
-		const parsed = buildParsedSignature(
-			req.signingString,
-			req.signature,
-			"rsa-sha256",
-		);
-
-		const result = httpSignature.verifySignature(parsed, keypair.publicKey);
-		assert.deepStrictEqual(result, true);
-	});
-});
diff --git a/packages/backend/test/api-visibility.ts b/packages/backend/test/api-visibility.ts
deleted file mode 100644
index 0ee4a4d337..0000000000
--- a/packages/backend/test/api-visibility.ts
+++ /dev/null
@@ -1,535 +0,0 @@
-process.env.NODE_ENV = "test";
-
-import * as assert from "assert";
-import * as childProcess from "child_process";
-import {
-	async,
-	signup,
-	request,
-	post,
-	startServer,
-	shutdownServer,
-} from "./utils.js";
-
-describe("API visibility", () => {
-	let p: childProcess.ChildProcess;
-
-	before(async () => {
-		p = await startServer();
-	});
-
-	after(async () => {
-		await shutdownServer(p);
-	});
-
-	describe("Note visibility", async () => {
-		//#region vars
-		/** ヒロイン */
-		let alice: any;
-		/** フォロワー */
-		let follower: any;
-		/** 非フォロワー */
-		let other: any;
-		/** 非フォロワーでもリプライやメンションをされた人 */
-		let target: any;
-		/** specified mentionでmentionを飛ばされる人 */
-		let target2: any;
-
-		/** public-post */
-		let pub: any;
-		/** home-post */
-		let home: any;
-		/** followers-post */
-		let fol: any;
-		/** specified-post */
-		let spe: any;
-
-		/** public-reply to target's post */
-		let pubR: any;
-		/** home-reply to target's post */
-		let homeR: any;
-		/** followers-reply to target's post */
-		let folR: any;
-		/** specified-reply to target's post */
-		let speR: any;
-
-		/** public-mention to target */
-		let pubM: any;
-		/** home-mention to target */
-		let homeM: any;
-		/** followers-mention to target */
-		let folM: any;
-		/** specified-mention to target */
-		let speM: any;
-
-		/** reply target post */
-		let tgt: any;
-		//#endregion
-
-		const show = async (noteId: any, by: any) => {
-			return await request(
-				"/notes/show",
-				{
-					noteId,
-				},
-				by,
-			);
-		};
-
-		before(async () => {
-			//#region prepare
-			// signup
-			alice = await signup({ username: "alice" });
-			follower = await signup({ username: "follower" });
-			other = await signup({ username: "other" });
-			target = await signup({ username: "target" });
-			target2 = await signup({ username: "target2" });
-
-			// follow alice <= follower
-			await request("/following/create", { userId: alice.id }, follower);
-
-			// normal posts
-			pub = await post(alice, { text: "x", visibility: "public" });
-			home = await post(alice, { text: "x", visibility: "home" });
-			fol = await post(alice, { text: "x", visibility: "followers" });
-			spe = await post(alice, {
-				text: "x",
-				visibility: "specified",
-				visibleUserIds: [target.id],
-			});
-
-			// replies
-			tgt = await post(target, { text: "y", visibility: "public" });
-			pubR = await post(alice, {
-				text: "x",
-				replyId: tgt.id,
-				visibility: "public",
-			});
-			homeR = await post(alice, {
-				text: "x",
-				replyId: tgt.id,
-				visibility: "home",
-			});
-			folR = await post(alice, {
-				text: "x",
-				replyId: tgt.id,
-				visibility: "followers",
-			});
-			speR = await post(alice, {
-				text: "x",
-				replyId: tgt.id,
-				visibility: "specified",
-			});
-
-			// mentions
-			pubM = await post(alice, {
-				text: "@target x",
-				replyId: tgt.id,
-				visibility: "public",
-			});
-			homeM = await post(alice, {
-				text: "@target x",
-				replyId: tgt.id,
-				visibility: "home",
-			});
-			folM = await post(alice, {
-				text: "@target x",
-				replyId: tgt.id,
-				visibility: "followers",
-			});
-			speM = await post(alice, {
-				text: "@target2 x",
-				replyId: tgt.id,
-				visibility: "specified",
-			});
-			//#endregion
-		});
-
-		//#region show post
-		// public
-		it("[show] public-postを自分が見れる", async(async () => {
-			const res = await show(pub.id, alice);
-			assert.strictEqual(res.body.text, "x");
-		}));
-
-		it("[show] public-postをフォロワーが見れる", async(async () => {
-			const res = await show(pub.id, follower);
-			assert.strictEqual(res.body.text, "x");
-		}));
-
-		it("[show] public-postを非フォロワーが見れる", async(async () => {
-			const res = await show(pub.id, other);
-			assert.strictEqual(res.body.text, "x");
-		}));
-
-		it("[show] public-postを未認証が見れる", async(async () => {
-			const res = await show(pub.id, null);
-			assert.strictEqual(res.body.text, "x");
-		}));
-
-		// home
-		it("[show] home-postを自分が見れる", async(async () => {
-			const res = await show(home.id, alice);
-			assert.strictEqual(res.body.text, "x");
-		}));
-
-		it("[show] home-postをフォロワーが見れる", async(async () => {
-			const res = await show(home.id, follower);
-			assert.strictEqual(res.body.text, "x");
-		}));
-
-		it("[show] home-postを非フォロワーが見れる", async(async () => {
-			const res = await show(home.id, other);
-			assert.strictEqual(res.body.text, "x");
-		}));
-
-		it("[show] home-postを未認証が見れる", async(async () => {
-			const res = await show(home.id, null);
-			assert.strictEqual(res.body.text, "x");
-		}));
-
-		// followers
-		it("[show] followers-postを自分が見れる", async(async () => {
-			const res = await show(fol.id, alice);
-			assert.strictEqual(res.body.text, "x");
-		}));
-
-		it("[show] followers-postをフォロワーが見れる", async(async () => {
-			const res = await show(fol.id, follower);
-			assert.strictEqual(res.body.text, "x");
-		}));
-
-		it("[show] followers-postを非フォロワーが見れない", async(async () => {
-			const res = await show(fol.id, other);
-			assert.strictEqual(res.status, 404);
-		}));
-
-		it("[show] followers-postを未認証が見れない", async(async () => {
-			const res = await show(fol.id, null);
-			assert.strictEqual(res.status, 404);
-		}));
-
-		// specified
-		it("[show] specified-postを自分が見れる", async(async () => {
-			const res = await show(spe.id, alice);
-			assert.strictEqual(res.status, 404);
-		}));
-
-		it("[show] specified-postを指定ユーザーが見れる", async(async () => {
-			const res = await show(spe.id, target);
-			assert.strictEqual(res.body.text, "x");
-		}));
-
-		it("[show] specified-postをフォロワーが見れない", async(async () => {
-			const res = await show(spe.id, follower);
-			assert.strictEqual(res.status, 404);
-		}));
-
-		it("[show] specified-postを非フォロワーが見れない", async(async () => {
-			const res = await show(spe.id, other);
-			assert.strictEqual(res.status, 404);
-		}));
-
-		it("[show] specified-postを未認証が見れない", async(async () => {
-			const res = await show(spe.id, null);
-			assert.strictEqual(res.status, 404);
-		}));
-		//#endregion
-
-		//#region show reply
-		// public
-		it("[show] public-replyを自分が見れる", async(async () => {
-			const res = await show(pubR.id, alice);
-			assert.strictEqual(res.body.text, "x");
-		}));
-
-		it("[show] public-replyをされた人が見れる", async(async () => {
-			const res = await show(pubR.id, target);
-			assert.strictEqual(res.body.text, "x");
-		}));
-
-		it("[show] public-replyをフォロワーが見れる", async(async () => {
-			const res = await show(pubR.id, follower);
-			assert.strictEqual(res.body.text, "x");
-		}));
-
-		it("[show] public-replyを非フォロワーが見れる", async(async () => {
-			const res = await show(pubR.id, other);
-			assert.strictEqual(res.body.text, "x");
-		}));
-
-		it("[show] public-replyを未認証が見れる", async(async () => {
-			const res = await show(pubR.id, null);
-			assert.strictEqual(res.body.text, "x");
-		}));
-
-		// home
-		it("[show] home-replyを自分が見れる", async(async () => {
-			const res = await show(homeR.id, alice);
-			assert.strictEqual(res.body.text, "x");
-		}));
-
-		it("[show] home-replyをされた人が見れる", async(async () => {
-			const res = await show(homeR.id, target);
-			assert.strictEqual(res.body.text, "x");
-		}));
-
-		it("[show] home-replyをフォロワーが見れる", async(async () => {
-			const res = await show(homeR.id, follower);
-			assert.strictEqual(res.body.text, "x");
-		}));
-
-		it("[show] home-replyを非フォロワーが見れる", async(async () => {
-			const res = await show(homeR.id, other);
-			assert.strictEqual(res.body.text, "x");
-		}));
-
-		it("[show] home-replyを未認証が見れる", async(async () => {
-			const res = await show(homeR.id, null);
-			assert.strictEqual(res.body.text, "x");
-		}));
-
-		// followers
-		it("[show] followers-replyを自分が見れる", async(async () => {
-			const res = await show(folR.id, alice);
-			assert.strictEqual(res.body.text, "x");
-		}));
-
-		it("[show] followers-replyを非フォロワーでもリプライされていれば見れる", async(async () => {
-			const res = await show(folR.id, target);
-			assert.strictEqual(res.body.text, "x");
-		}));
-
-		it("[show] followers-replyをフォロワーが見れる", async(async () => {
-			const res = await show(folR.id, follower);
-			assert.strictEqual(res.body.text, "x");
-		}));
-
-		it("[show] followers-replyを非フォロワーが見れない", async(async () => {
-			const res = await show(folR.id, other);
-			assert.strictEqual(res.status, 404);
-		}));
-
-		it("[show] followers-replyを未認証が見れない", async(async () => {
-			const res = await show(folR.id, null);
-			assert.strictEqual(res.status, 404);
-		}));
-
-		// specified
-		it("[show] specified-replyを自分が見れる", async(async () => {
-			const res = await show(speR.id, alice);
-			assert.strictEqual(res.body.text, "x");
-		}));
-
-		it("[show] specified-replyを指定ユーザーが見れる", async(async () => {
-			const res = await show(speR.id, target);
-			assert.strictEqual(res.body.text, "x");
-		}));
-
-		it("[show] specified-replyをされた人が指定されてなくても見れる", async(async () => {
-			const res = await show(speR.id, target);
-			assert.strictEqual(res.body.text, "x");
-		}));
-
-		it("[show] specified-replyをフォロワーが見れない", async(async () => {
-			const res = await show(speR.id, follower);
-			assert.strictEqual(res.status, 404);
-		}));
-
-		it("[show] specified-replyを非フォロワーが見れない", async(async () => {
-			const res = await show(speR.id, other);
-			assert.strictEqual(res.status, 404);
-		}));
-
-		it("[show] specified-replyを未認証が見れない", async(async () => {
-			const res = await show(speR.id, null);
-			assert.strictEqual(res.status, 404);
-		}));
-		//#endregion
-
-		//#region show mention
-		// public
-		it("[show] public-mentionを自分が見れる", async(async () => {
-			const res = await show(pubM.id, alice);
-			assert.strictEqual(res.body.text, "@target x");
-		}));
-
-		it("[show] public-mentionをされた人が見れる", async(async () => {
-			const res = await show(pubM.id, target);
-			assert.strictEqual(res.body.text, "@target x");
-		}));
-
-		it("[show] public-mentionをフォロワーが見れる", async(async () => {
-			const res = await show(pubM.id, follower);
-			assert.strictEqual(res.body.text, "@target x");
-		}));
-
-		it("[show] public-mentionを非フォロワーが見れる", async(async () => {
-			const res = await show(pubM.id, other);
-			assert.strictEqual(res.body.text, "@target x");
-		}));
-
-		it("[show] public-mentionを未認証が見れる", async(async () => {
-			const res = await show(pubM.id, null);
-			assert.strictEqual(res.body.text, "@target x");
-		}));
-
-		// home
-		it("[show] home-mentionを自分が見れる", async(async () => {
-			const res = await show(homeM.id, alice);
-			assert.strictEqual(res.body.text, "@target x");
-		}));
-
-		it("[show] home-mentionをされた人が見れる", async(async () => {
-			const res = await show(homeM.id, target);
-			assert.strictEqual(res.body.text, "@target x");
-		}));
-
-		it("[show] home-mentionをフォロワーが見れる", async(async () => {
-			const res = await show(homeM.id, follower);
-			assert.strictEqual(res.body.text, "@target x");
-		}));
-
-		it("[show] home-mentionを非フォロワーが見れる", async(async () => {
-			const res = await show(homeM.id, other);
-			assert.strictEqual(res.body.text, "@target x");
-		}));
-
-		it("[show] home-mentionを未認証が見れる", async(async () => {
-			const res = await show(homeM.id, null);
-			assert.strictEqual(res.body.text, "@target x");
-		}));
-
-		// followers
-		it("[show] followers-mentionを自分が見れる", async(async () => {
-			const res = await show(folM.id, alice);
-			assert.strictEqual(res.body.text, "@target x");
-		}));
-
-		it("[show] followers-mentionをメンションされていれば非フォロワーでも見れる", async(async () => {
-			const res = await show(folM.id, target);
-			assert.strictEqual(res.body.text, "@target x");
-		}));
-
-		it("[show] followers-mentionをフォロワーが見れる", async(async () => {
-			const res = await show(folM.id, follower);
-			assert.strictEqual(res.body.text, "@target x");
-		}));
-
-		it("[show] followers-mentionを非フォロワーが見れない", async(async () => {
-			const res = await show(folM.id, other);
-			assert.strictEqual(res.status, 404);
-		}));
-
-		it("[show] followers-mentionを未認証が見れない", async(async () => {
-			const res = await show(folM.id, null);
-			assert.strictEqual(res.status, 404);
-		}));
-
-		// specified
-		it("[show] specified-mentionを自分が見れる", async(async () => {
-			const res = await show(speM.id, alice);
-			assert.strictEqual(res.body.text, "@target2 x");
-		}));
-
-		it("[show] specified-mentionを指定ユーザーが見れる", async(async () => {
-			const res = await show(speM.id, target);
-			assert.strictEqual(res.body.text, "@target2 x");
-		}));
-
-		it("[show] specified-mentionをされた人が指定されてなかったら見れない", async(async () => {
-			const res = await show(speM.id, target2);
-			assert.strictEqual(res.status, 404);
-		}));
-
-		it("[show] specified-mentionをフォロワーが見れない", async(async () => {
-			const res = await show(speM.id, follower);
-			assert.strictEqual(res.status, 404);
-		}));
-
-		it("[show] specified-mentionを非フォロワーが見れない", async(async () => {
-			const res = await show(speM.id, other);
-			assert.strictEqual(res.status, 404);
-		}));
-
-		it("[show] specified-mentionを未認証が見れない", async(async () => {
-			const res = await show(speM.id, null);
-			assert.strictEqual(res.status, 404);
-		}));
-		//#endregion
-
-		//#region HTL
-		it("[HTL] public-post が 自分が見れる", async(async () => {
-			const res = await request("/notes/timeline", { limit: 100 }, alice);
-			assert.strictEqual(res.status, 200);
-			const notes = res.body.filter((n: any) => n.id == pub.id);
-			assert.strictEqual(notes[0].text, "x");
-		}));
-
-		it("[HTL] public-post が 非フォロワーから見れない", async(async () => {
-			const res = await request("/notes/timeline", { limit: 100 }, other);
-			assert.strictEqual(res.status, 200);
-			const notes = res.body.filter((n: any) => n.id == pub.id);
-			assert.strictEqual(notes.length, 0);
-		}));
-
-		it("[HTL] followers-post が フォロワーから見れる", async(async () => {
-			const res = await request("/notes/timeline", { limit: 100 }, follower);
-			assert.strictEqual(res.status, 200);
-			const notes = res.body.filter((n: any) => n.id == fol.id);
-			assert.strictEqual(notes[0].text, "x");
-		}));
-		//#endregion
-
-		//#region RTL
-		it("[replies] followers-reply が フォロワーから見れる", async(async () => {
-			const res = await request(
-				"/notes/replies",
-				{ noteId: tgt.id, limit: 100 },
-				follower,
-			);
-			assert.strictEqual(res.status, 200);
-			const notes = res.body.filter((n: any) => n.id == folR.id);
-			assert.strictEqual(notes[0].text, "x");
-		}));
-
-		it("[replies] followers-reply が 非フォロワー (リプライ先ではない) から見れない", async(async () => {
-			const res = await request(
-				"/notes/replies",
-				{ noteId: tgt.id, limit: 100 },
-				other,
-			);
-			assert.strictEqual(res.status, 200);
-			const notes = res.body.filter((n: any) => n.id == folR.id);
-			assert.strictEqual(notes.length, 0);
-		}));
-
-		it("[replies] followers-reply が 非フォロワー (リプライ先である) から見れる", async(async () => {
-			const res = await request(
-				"/notes/replies",
-				{ noteId: tgt.id, limit: 100 },
-				target,
-			);
-			assert.strictEqual(res.status, 200);
-			const notes = res.body.filter((n: any) => n.id == folR.id);
-			assert.strictEqual(notes[0].text, "x");
-		}));
-		//#endregion
-
-		//#region MTL
-		it("[mentions] followers-reply が 非フォロワー (リプライ先である) から見れる", async(async () => {
-			const res = await request("/notes/mentions", { limit: 100 }, target);
-			assert.strictEqual(res.status, 200);
-			const notes = res.body.filter((n: any) => n.id == folR.id);
-			assert.strictEqual(notes[0].text, "x");
-		}));
-
-		it("[mentions] followers-mention が 非フォロワー (メンション先である) から見れる", async(async () => {
-			const res = await request("/notes/mentions", { limit: 100 }, target);
-			assert.strictEqual(res.status, 200);
-			const notes = res.body.filter((n: any) => n.id == folM.id);
-			assert.strictEqual(notes[0].text, "@target x");
-		}));
-		//#endregion
-	});
-});
diff --git a/packages/backend/test/api.ts b/packages/backend/test/api.ts
deleted file mode 100644
index 19a754552c..0000000000
--- a/packages/backend/test/api.ts
+++ /dev/null
@@ -1,92 +0,0 @@
-process.env.NODE_ENV = "test";
-
-import * as assert from "assert";
-import * as childProcess from "child_process";
-import {
-	async,
-	signup,
-	request,
-	post,
-	react,
-	uploadFile,
-	startServer,
-	shutdownServer,
-} from "./utils.js";
-
-describe("API", () => {
-	let p: childProcess.ChildProcess;
-	let alice: any;
-	let bob: any;
-	let carol: any;
-
-	before(async () => {
-		p = await startServer();
-		alice = await signup({ username: "alice" });
-		bob = await signup({ username: "bob" });
-		carol = await signup({ username: "carol" });
-	});
-
-	after(async () => {
-		await shutdownServer(p);
-	});
-
-	describe("General validation", () => {
-		it("wrong type", async(async () => {
-			const res = await request("/test", {
-				required: true,
-				string: 42,
-			});
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it("missing require param", async(async () => {
-			const res = await request("/test", {
-				string: "a",
-			});
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it("invalid misskey:id (empty string)", async(async () => {
-			const res = await request("/test", {
-				required: true,
-				id: "",
-			});
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it("valid misskey:id", async(async () => {
-			const res = await request("/test", {
-				required: true,
-				id: "8wvhjghbxu",
-			});
-			assert.strictEqual(res.status, 200);
-		}));
-
-		it("default value", async(async () => {
-			const res = await request("/test", {
-				required: true,
-				string: "a",
-			});
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(res.body.default, "hello");
-		}));
-
-		it("can set null even if it has default value", async(async () => {
-			const res = await request("/test", {
-				required: true,
-				nullableDefault: null,
-			});
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(res.body.nullableDefault, null);
-		}));
-
-		it("cannot set undefined if it has default value", async(async () => {
-			const res = await request("/test", {
-				required: true,
-				nullableDefault: undefined,
-			});
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(res.body.nullableDefault, "hello");
-		}));
-	});
-});
diff --git a/packages/backend/test/block.ts b/packages/backend/test/block.ts
deleted file mode 100644
index 08192e4869..0000000000
--- a/packages/backend/test/block.ts
+++ /dev/null
@@ -1,129 +0,0 @@
-process.env.NODE_ENV = "test";
-
-import * as assert from "assert";
-import * as childProcess from "child_process";
-import {
-	async,
-	signup,
-	request,
-	post,
-	startServer,
-	shutdownServer,
-} from "./utils.js";
-
-describe("Block", () => {
-	let p: childProcess.ChildProcess;
-
-	// alice blocks bob
-	let alice: any;
-	let bob: any;
-	let carol: any;
-
-	before(async () => {
-		p = await startServer();
-		alice = await signup({ username: "alice" });
-		bob = await signup({ username: "bob" });
-		carol = await signup({ username: "carol" });
-	});
-
-	after(async () => {
-		await shutdownServer(p);
-	});
-
-	it("Block作成", async(async () => {
-		const res = await request(
-			"/blocking/create",
-			{
-				userId: bob.id,
-			},
-			alice,
-		);
-
-		assert.strictEqual(res.status, 200);
-	}));
-
-	it("ブロックされているユーザーをフォローできない", async(async () => {
-		const res = await request("/following/create", { userId: alice.id }, bob);
-
-		assert.strictEqual(res.status, 400);
-		assert.strictEqual(
-			res.body.error.id,
-			"c4ab57cc-4e41-45e9-bfd9-584f61e35ce0",
-		);
-	}));
-
-	it("ブロックされているユーザーにリアクションできない", async(async () => {
-		const note = await post(alice, { text: "hello" });
-
-		const res = await request(
-			"/notes/reactions/create",
-			{ noteId: note.id, reaction: "👍" },
-			bob,
-		);
-
-		assert.strictEqual(res.status, 400);
-		assert.strictEqual(
-			res.body.error.id,
-			"20ef5475-9f38-4e4c-bd33-de6d979498ec",
-		);
-	}));
-
-	it("ブロックされているユーザーに返信できない", async(async () => {
-		const note = await post(alice, { text: "hello" });
-
-		const res = await request(
-			"/notes/create",
-			{ replyId: note.id, text: "yo" },
-			bob,
-		);
-
-		assert.strictEqual(res.status, 400);
-		assert.strictEqual(
-			res.body.error.id,
-			"b390d7e1-8a5e-46ed-b625-06271cafd3d3",
-		);
-	}));
-
-	it("ブロックされているユーザーのノートをRenoteできない", async(async () => {
-		const note = await post(alice, { text: "hello" });
-
-		const res = await request(
-			"/notes/create",
-			{ renoteId: note.id, text: "yo" },
-			bob,
-		);
-
-		assert.strictEqual(res.status, 400);
-		assert.strictEqual(
-			res.body.error.id,
-			"b390d7e1-8a5e-46ed-b625-06271cafd3d3",
-		);
-	}));
-
-	// TODO: ユーザーリストに入れられないテスト
-
-	// TODO: ユーザーリストから除外されるテスト
-
-	it("タイムライン(LTL)にブロックされているユーザーの投稿が含まれない", async(async () => {
-		const aliceNote = await post(alice);
-		const bobNote = await post(bob);
-		const carolNote = await post(carol);
-
-		const res = await request("/notes/local-timeline", {}, bob);
-
-		assert.strictEqual(res.status, 200);
-		assert.strictEqual(Array.isArray(res.body), true);
-		assert.strictEqual(
-			res.body.some((note: any) => note.id === aliceNote.id),
-			false,
-		);
-		assert.strictEqual(
-			res.body.some((note: any) => note.id === bobNote.id),
-			true,
-		);
-		assert.strictEqual(
-			res.body.some((note: any) => note.id === carolNote.id),
-			true,
-		);
-	}));
-});
diff --git a/packages/backend/test/chart.ts b/packages/backend/test/chart.ts
deleted file mode 100644
index e194c6c195..0000000000
--- a/packages/backend/test/chart.ts
+++ /dev/null
@@ -1,575 +0,0 @@
-process.env.NODE_ENV = "test";
-
-import * as assert from "assert";
-import * as lolex from "@sinonjs/fake-timers";
-import TestChart from "../src/services/chart/charts/test.js";
-import TestGroupedChart from "../src/services/chart/charts/test-grouped.js";
-import TestUniqueChart from "../src/services/chart/charts/test-unique.js";
-import TestIntersectionChart from "../src/services/chart/charts/test-intersection.js";
-import { initDb } from "../src/db/postgre.js";
-
-describe("Chart", () => {
-	let testChart: TestChart;
-	let testGroupedChart: TestGroupedChart;
-	let testUniqueChart: TestUniqueChart;
-	let testIntersectionChart: TestIntersectionChart;
-	let clock: lolex.InstalledClock;
-
-	beforeEach(async () => {
-		await initDb(true);
-
-		testChart = new TestChart();
-		testGroupedChart = new TestGroupedChart();
-		testUniqueChart = new TestUniqueChart();
-		testIntersectionChart = new TestIntersectionChart();
-
-		clock = lolex.install({
-			now: new Date(Date.UTC(2000, 0, 1, 0, 0, 0)),
-			shouldClearNativeTimers: true,
-		});
-	});
-
-	afterEach(() => {
-		clock.uninstall();
-	});
-
-	it("Can updates", async () => {
-		await testChart.increment();
-		await testChart.save();
-
-		const chartHours = await testChart.getChart("hour", 3, null);
-		const chartDays = await testChart.getChart("day", 3, null);
-
-		assert.deepStrictEqual(chartHours, {
-			foo: {
-				dec: [0, 0, 0],
-				inc: [1, 0, 0],
-				total: [1, 0, 0],
-			},
-		});
-
-		assert.deepStrictEqual(chartDays, {
-			foo: {
-				dec: [0, 0, 0],
-				inc: [1, 0, 0],
-				total: [1, 0, 0],
-			},
-		});
-	});
-
-	it("Can updates (dec)", async () => {
-		await testChart.decrement();
-		await testChart.save();
-
-		const chartHours = await testChart.getChart("hour", 3, null);
-		const chartDays = await testChart.getChart("day", 3, null);
-
-		assert.deepStrictEqual(chartHours, {
-			foo: {
-				dec: [1, 0, 0],
-				inc: [0, 0, 0],
-				total: [-1, 0, 0],
-			},
-		});
-
-		assert.deepStrictEqual(chartDays, {
-			foo: {
-				dec: [1, 0, 0],
-				inc: [0, 0, 0],
-				total: [-1, 0, 0],
-			},
-		});
-	});
-
-	it("Empty chart", async () => {
-		const chartHours = await testChart.getChart("hour", 3, null);
-		const chartDays = await testChart.getChart("day", 3, null);
-
-		assert.deepStrictEqual(chartHours, {
-			foo: {
-				dec: [0, 0, 0],
-				inc: [0, 0, 0],
-				total: [0, 0, 0],
-			},
-		});
-
-		assert.deepStrictEqual(chartDays, {
-			foo: {
-				dec: [0, 0, 0],
-				inc: [0, 0, 0],
-				total: [0, 0, 0],
-			},
-		});
-	});
-
-	it("Can updates at multiple times at same time", async () => {
-		await testChart.increment();
-		await testChart.increment();
-		await testChart.increment();
-		await testChart.save();
-
-		const chartHours = await testChart.getChart("hour", 3, null);
-		const chartDays = await testChart.getChart("day", 3, null);
-
-		assert.deepStrictEqual(chartHours, {
-			foo: {
-				dec: [0, 0, 0],
-				inc: [3, 0, 0],
-				total: [3, 0, 0],
-			},
-		});
-
-		assert.deepStrictEqual(chartDays, {
-			foo: {
-				dec: [0, 0, 0],
-				inc: [3, 0, 0],
-				total: [3, 0, 0],
-			},
-		});
-	});
-
-	it("複数回saveされてもデータの更新は一度だけ", async () => {
-		await testChart.increment();
-		await testChart.save();
-		await testChart.save();
-		await testChart.save();
-
-		const chartHours = await testChart.getChart("hour", 3, null);
-		const chartDays = await testChart.getChart("day", 3, null);
-
-		assert.deepStrictEqual(chartHours, {
-			foo: {
-				dec: [0, 0, 0],
-				inc: [1, 0, 0],
-				total: [1, 0, 0],
-			},
-		});
-
-		assert.deepStrictEqual(chartDays, {
-			foo: {
-				dec: [0, 0, 0],
-				inc: [1, 0, 0],
-				total: [1, 0, 0],
-			},
-		});
-	});
-
-	it("Can updates at different times", async () => {
-		await testChart.increment();
-		await testChart.save();
-
-		clock.tick("01:00:00");
-
-		await testChart.increment();
-		await testChart.save();
-
-		const chartHours = await testChart.getChart("hour", 3, null);
-		const chartDays = await testChart.getChart("day", 3, null);
-
-		assert.deepStrictEqual(chartHours, {
-			foo: {
-				dec: [0, 0, 0],
-				inc: [1, 1, 0],
-				total: [2, 1, 0],
-			},
-		});
-
-		assert.deepStrictEqual(chartDays, {
-			foo: {
-				dec: [0, 0, 0],
-				inc: [2, 0, 0],
-				total: [2, 0, 0],
-			},
-		});
-	});
-
-	// 仕様上はこうなってほしいけど、実装は難しそうなのでskip
-	/*
-	it('Can updates at different times without save', async () => {
-		await testChart.increment();
-
-		clock.tick('01:00:00');
-
-		await testChart.increment();
-		await testChart.save();
-
-		const chartHours = await testChart.getChart('hour', 3, null);
-		const chartDays = await testChart.getChart('day', 3, null);
-
-		assert.deepStrictEqual(chartHours, {
-			foo: {
-				dec: [0, 0, 0],
-				inc: [1, 1, 0],
-				total: [2, 1, 0]
-			},
-		});
-
-		assert.deepStrictEqual(chartDays, {
-			foo: {
-				dec: [0, 0, 0],
-				inc: [2, 0, 0],
-				total: [2, 0, 0]
-			},
-		});
-	});
-	*/
-
-	it("Can padding", async () => {
-		await testChart.increment();
-		await testChart.save();
-
-		clock.tick("02:00:00");
-
-		await testChart.increment();
-		await testChart.save();
-
-		const chartHours = await testChart.getChart("hour", 3, null);
-		const chartDays = await testChart.getChart("day", 3, null);
-
-		assert.deepStrictEqual(chartHours, {
-			foo: {
-				dec: [0, 0, 0],
-				inc: [1, 0, 1],
-				total: [2, 1, 1],
-			},
-		});
-
-		assert.deepStrictEqual(chartDays, {
-			foo: {
-				dec: [0, 0, 0],
-				inc: [2, 0, 0],
-				total: [2, 0, 0],
-			},
-		});
-	});
-
-	// 要求された範囲にログがひとつもない場合でもパディングできる
-	it("Can padding from past range", async () => {
-		await testChart.increment();
-		await testChart.save();
-
-		clock.tick("05:00:00");
-
-		const chartHours = await testChart.getChart("hour", 3, null);
-		const chartDays = await testChart.getChart("day", 3, null);
-
-		assert.deepStrictEqual(chartHours, {
-			foo: {
-				dec: [0, 0, 0],
-				inc: [0, 0, 0],
-				total: [1, 1, 1],
-			},
-		});
-
-		assert.deepStrictEqual(chartDays, {
-			foo: {
-				dec: [0, 0, 0],
-				inc: [1, 0, 0],
-				total: [1, 0, 0],
-			},
-		});
-	});
-
-	// 要求された範囲の最も古い箇所に位置するログが存在しない場合でもパディングできる
-	// Issue #3190
-	it("Can padding from past range 2", async () => {
-		await testChart.increment();
-		await testChart.save();
-
-		clock.tick("05:00:00");
-
-		await testChart.increment();
-		await testChart.save();
-
-		const chartHours = await testChart.getChart("hour", 3, null);
-		const chartDays = await testChart.getChart("day", 3, null);
-
-		assert.deepStrictEqual(chartHours, {
-			foo: {
-				dec: [0, 0, 0],
-				inc: [1, 0, 0],
-				total: [2, 1, 1],
-			},
-		});
-
-		assert.deepStrictEqual(chartDays, {
-			foo: {
-				dec: [0, 0, 0],
-				inc: [2, 0, 0],
-				total: [2, 0, 0],
-			},
-		});
-	});
-
-	it("Can specify offset", async () => {
-		await testChart.increment();
-		await testChart.save();
-
-		clock.tick("01:00:00");
-
-		await testChart.increment();
-		await testChart.save();
-
-		const chartHours = await testChart.getChart(
-			"hour",
-			3,
-			new Date(Date.UTC(2000, 0, 1, 0, 0, 0)),
-		);
-		const chartDays = await testChart.getChart(
-			"day",
-			3,
-			new Date(Date.UTC(2000, 0, 1, 0, 0, 0)),
-		);
-
-		assert.deepStrictEqual(chartHours, {
-			foo: {
-				dec: [0, 0, 0],
-				inc: [1, 0, 0],
-				total: [1, 0, 0],
-			},
-		});
-
-		assert.deepStrictEqual(chartDays, {
-			foo: {
-				dec: [0, 0, 0],
-				inc: [2, 0, 0],
-				total: [2, 0, 0],
-			},
-		});
-	});
-
-	it("Can specify offset (floor time)", async () => {
-		clock.tick("00:30:00");
-
-		await testChart.increment();
-		await testChart.save();
-
-		clock.tick("01:30:00");
-
-		await testChart.increment();
-		await testChart.save();
-
-		const chartHours = await testChart.getChart(
-			"hour",
-			3,
-			new Date(Date.UTC(2000, 0, 1, 0, 0, 0)),
-		);
-		const chartDays = await testChart.getChart(
-			"day",
-			3,
-			new Date(Date.UTC(2000, 0, 1, 0, 0, 0)),
-		);
-
-		assert.deepStrictEqual(chartHours, {
-			foo: {
-				dec: [0, 0, 0],
-				inc: [1, 0, 0],
-				total: [1, 0, 0],
-			},
-		});
-
-		assert.deepStrictEqual(chartDays, {
-			foo: {
-				dec: [0, 0, 0],
-				inc: [2, 0, 0],
-				total: [2, 0, 0],
-			},
-		});
-	});
-
-	describe("Grouped", () => {
-		it("Can updates", async () => {
-			await testGroupedChart.increment("alice");
-			await testGroupedChart.save();
-
-			const aliceChartHours = await testGroupedChart.getChart(
-				"hour",
-				3,
-				null,
-				"alice",
-			);
-			const aliceChartDays = await testGroupedChart.getChart(
-				"day",
-				3,
-				null,
-				"alice",
-			);
-			const bobChartHours = await testGroupedChart.getChart(
-				"hour",
-				3,
-				null,
-				"bob",
-			);
-			const bobChartDays = await testGroupedChart.getChart(
-				"day",
-				3,
-				null,
-				"bob",
-			);
-
-			assert.deepStrictEqual(aliceChartHours, {
-				foo: {
-					dec: [0, 0, 0],
-					inc: [1, 0, 0],
-					total: [1, 0, 0],
-				},
-			});
-
-			assert.deepStrictEqual(aliceChartDays, {
-				foo: {
-					dec: [0, 0, 0],
-					inc: [1, 0, 0],
-					total: [1, 0, 0],
-				},
-			});
-
-			assert.deepStrictEqual(bobChartHours, {
-				foo: {
-					dec: [0, 0, 0],
-					inc: [0, 0, 0],
-					total: [0, 0, 0],
-				},
-			});
-
-			assert.deepStrictEqual(bobChartDays, {
-				foo: {
-					dec: [0, 0, 0],
-					inc: [0, 0, 0],
-					total: [0, 0, 0],
-				},
-			});
-		});
-	});
-
-	describe("Unique increment", () => {
-		it("Can updates", async () => {
-			await testUniqueChart.uniqueIncrement("alice");
-			await testUniqueChart.uniqueIncrement("alice");
-			await testUniqueChart.uniqueIncrement("bob");
-			await testUniqueChart.save();
-
-			const chartHours = await testUniqueChart.getChart("hour", 3, null);
-			const chartDays = await testUniqueChart.getChart("day", 3, null);
-
-			assert.deepStrictEqual(chartHours, {
-				foo: [2, 0, 0],
-			});
-
-			assert.deepStrictEqual(chartDays, {
-				foo: [2, 0, 0],
-			});
-		});
-
-		describe("Intersection", () => {
-			it("条件が満たされていない場合はカウントされない", async () => {
-				await testIntersectionChart.addA("alice");
-				await testIntersectionChart.addA("bob");
-				await testIntersectionChart.addB("carol");
-				await testIntersectionChart.save();
-
-				const chartHours = await testIntersectionChart.getChart(
-					"hour",
-					3,
-					null,
-				);
-				const chartDays = await testIntersectionChart.getChart("day", 3, null);
-
-				assert.deepStrictEqual(chartHours, {
-					a: [2, 0, 0],
-					b: [1, 0, 0],
-					aAndB: [0, 0, 0],
-				});
-
-				assert.deepStrictEqual(chartDays, {
-					a: [2, 0, 0],
-					b: [1, 0, 0],
-					aAndB: [0, 0, 0],
-				});
-			});
-
-			it("条件が満たされている場合にカウントされる", async () => {
-				await testIntersectionChart.addA("alice");
-				await testIntersectionChart.addA("bob");
-				await testIntersectionChart.addB("carol");
-				await testIntersectionChart.addB("alice");
-				await testIntersectionChart.save();
-
-				const chartHours = await testIntersectionChart.getChart(
-					"hour",
-					3,
-					null,
-				);
-				const chartDays = await testIntersectionChart.getChart("day", 3, null);
-
-				assert.deepStrictEqual(chartHours, {
-					a: [2, 0, 0],
-					b: [2, 0, 0],
-					aAndB: [1, 0, 0],
-				});
-
-				assert.deepStrictEqual(chartDays, {
-					a: [2, 0, 0],
-					b: [2, 0, 0],
-					aAndB: [1, 0, 0],
-				});
-			});
-		});
-	});
-
-	describe("Resync", () => {
-		it("Can resync", async () => {
-			testChart.total = 1;
-
-			await testChart.resync();
-
-			const chartHours = await testChart.getChart("hour", 3, null);
-			const chartDays = await testChart.getChart("day", 3, null);
-
-			assert.deepStrictEqual(chartHours, {
-				foo: {
-					dec: [0, 0, 0],
-					inc: [0, 0, 0],
-					total: [1, 0, 0],
-				},
-			});
-
-			assert.deepStrictEqual(chartDays, {
-				foo: {
-					dec: [0, 0, 0],
-					inc: [0, 0, 0],
-					total: [1, 0, 0],
-				},
-			});
-		});
-
-		it("Can resync (2)", async () => {
-			await testChart.increment();
-			await testChart.save();
-
-			clock.tick("01:00:00");
-
-			testChart.total = 100;
-
-			await testChart.resync();
-
-			const chartHours = await testChart.getChart("hour", 3, null);
-			const chartDays = await testChart.getChart("day", 3, null);
-
-			assert.deepStrictEqual(chartHours, {
-				foo: {
-					dec: [0, 0, 0],
-					inc: [0, 1, 0],
-					total: [100, 1, 0],
-				},
-			});
-
-			assert.deepStrictEqual(chartDays, {
-				foo: {
-					dec: [0, 0, 0],
-					inc: [1, 0, 0],
-					total: [100, 0, 0],
-				},
-			});
-		});
-	});
-});
diff --git a/packages/backend/test/docker-compose.yml b/packages/backend/test/docker-compose.yml
deleted file mode 100644
index 5f95bec4c0..0000000000
--- a/packages/backend/test/docker-compose.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-version: "3"
-
-services:
-  redistest:
-    image: redis:6
-    ports:
-      - "127.0.0.1:56312:6379"
-
-  dbtest:
-    image: postgres:13
-    ports:
-      - "127.0.0.1:54312:5432"
-    environment:
-      POSTGRES_DB: "test-misskey"
-      POSTGRES_HOST_AUTH_METHOD: trust
diff --git a/packages/backend/test/endpoints.ts b/packages/backend/test/endpoints.ts
deleted file mode 100644
index 2aedc25f2c..0000000000
--- a/packages/backend/test/endpoints.ts
+++ /dev/null
@@ -1,865 +0,0 @@
-/*
-process.env.NODE_ENV = 'test';
-
-import * as assert from 'assert';
-import * as childProcess from 'child_process';
-import { async, signup, request, post, react, uploadFile, startServer, shutdownServer } from './utils.js';
-
-describe('API: Endpoints', () => {
-	let p: childProcess.ChildProcess;
-	let alice: any;
-	let bob: any;
-	let carol: any;
-
-	before(async () => {
-		p = await startServer();
-		alice = await signup({ username: 'alice' });
-		bob = await signup({ username: 'bob' });
-		carol = await signup({ username: 'carol' });
-	});
-
-	after(async () => {
-		await shutdownServer(p);
-	});
-
-	describe('signup', () => {
-		it('不正なユーザー名でアカウントが作成できない', async(async () => {
-			const res = await request('/signup', {
-				username: 'test.',
-				password: 'test'
-			});
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it('空のパスワードでアカウントが作成できない', async(async () => {
-			const res = await request('/signup', {
-				username: 'test',
-				password: ''
-			});
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it('正しくアカウントが作成できる', async(async () => {
-			const me = {
-				username: 'test1',
-				password: 'test1'
-			};
-
-			const res = await request('/signup', me);
-
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
-			assert.strictEqual(res.body.username, me.username);
-		}));
-
-		it('同じユーザー名のアカウントは作成できない', async(async () => {
-			await signup({
-				username: 'test2'
-			});
-
-			const res = await request('/signup', {
-				username: 'test2',
-				password: 'test2'
-			});
-
-			assert.strictEqual(res.status, 400);
-		}));
-	});
-
-	describe('signin', () => {
-		it('間違ったパスワードでサインインできない', async(async () => {
-			await signup({
-				username: 'test3',
-				password: 'foo'
-			});
-
-			const res = await request('/signin', {
-				username: 'test3',
-				password: 'bar'
-			});
-
-			assert.strictEqual(res.status, 403);
-		}));
-
-		it('クエリをインジェクションできない', async(async () => {
-			await signup({
-				username: 'test4'
-			});
-
-			const res = await request('/signin', {
-				username: 'test4',
-				password: {
-					$gt: ''
-				}
-			});
-
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it('正しい情報でサインインできる', async(async () => {
-			await signup({
-				username: 'test5',
-				password: 'foo'
-			});
-
-			const res = await request('/signin', {
-				username: 'test5',
-				password: 'foo'
-			});
-
-			assert.strictEqual(res.status, 200);
-		}));
-	});
-
-	describe('i/update', () => {
-		it('アカウント設定を更新できる', async(async () => {
-			const myName = '大室櫻子';
-			const myLocation = '七森中';
-			const myBirthday = '2000-09-07';
-
-			const res = await request('/i/update', {
-				name: myName,
-				location: myLocation,
-				birthday: myBirthday
-			}, alice);
-
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
-			assert.strictEqual(res.body.name, myName);
-			assert.strictEqual(res.body.location, myLocation);
-			assert.strictEqual(res.body.birthday, myBirthday);
-		}));
-
-		it('名前を空白にできない', async(async () => {
-			const res = await request('/i/update', {
-				name: ' '
-			}, alice);
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it('誕生日の設定を削除できる', async(async () => {
-			await request('/i/update', {
-				birthday: '2000-09-07'
-			}, alice);
-
-			const res = await request('/i/update', {
-				birthday: null
-			}, alice);
-
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
-			assert.strictEqual(res.body.birthday, null);
-		}));
-
-		it('不正な誕生日の形式で怒られる', async(async () => {
-			const res = await request('/i/update', {
-				birthday: '2000/09/07'
-			}, alice);
-			assert.strictEqual(res.status, 400);
-		}));
-	});
-
-	describe('users/show', () => {
-		it('ユーザーが取得できる', async(async () => {
-			const res = await request('/users/show', {
-				userId: alice.id
-			}, alice);
-
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
-			assert.strictEqual(res.body.id, alice.id);
-		}));
-
-		it('ユーザーが存在しなかったら怒る', async(async () => {
-			const res = await request('/users/show', {
-				userId: '000000000000000000000000'
-			});
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it('間違ったIDで怒られる', async(async () => {
-			const res = await request('/users/show', {
-				userId: 'kyoppie'
-			});
-			assert.strictEqual(res.status, 400);
-		}));
-	});
-
-	describe('notes/show', () => {
-		it('投稿が取得できる', async(async () => {
-			const myPost = await post(alice, {
-				text: 'test'
-			});
-
-			const res = await request('/notes/show', {
-				noteId: myPost.id
-			}, alice);
-
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
-			assert.strictEqual(res.body.id, myPost.id);
-			assert.strictEqual(res.body.text, myPost.text);
-		}));
-
-		it('投稿が存在しなかったら怒る', async(async () => {
-			const res = await request('/notes/show', {
-				noteId: '000000000000000000000000'
-			});
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it('間違ったIDで怒られる', async(async () => {
-			const res = await request('/notes/show', {
-				noteId: 'kyoppie'
-			});
-			assert.strictEqual(res.status, 400);
-		}));
-	});
-
-	describe('notes/reactions/create', () => {
-		it('リアクションできる', async(async () => {
-			const bobPost = await post(bob);
-
-			const alice = await signup({ username: 'alice' });
-			const res = await request('/notes/reactions/create', {
-				noteId: bobPost.id,
-				reaction: '🚀',
-			}, alice);
-
-			assert.strictEqual(res.status, 204);
-
-			const resNote = await request('/notes/show', {
-				noteId: bobPost.id,
-			}, alice);
-
-			assert.strictEqual(resNote.status, 200);
-			assert.strictEqual(resNote.body.reactions['🚀'], [alice.id]);
-		}));
-
-		it('自分の投稿にもリアクションできる', async(async () => {
-			const myPost = await post(alice);
-
-			const res = await request('/notes/reactions/create', {
-				noteId: myPost.id,
-				reaction: '🚀',
-			}, alice);
-
-			assert.strictEqual(res.status, 204);
-		}));
-
-		it('二重にリアクションできない', async(async () => {
-			const bobPost = await post(bob);
-
-			await react(alice, bobPost, 'like');
-
-			const res = await request('/notes/reactions/create', {
-				noteId: bobPost.id,
-				reaction: '🚀',
-			}, alice);
-
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it('存在しない投稿にはリアクションできない', async(async () => {
-			const res = await request('/notes/reactions/create', {
-				noteId: '000000000000000000000000',
-				reaction: '🚀',
-			}, alice);
-
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it('空のパラメータで怒られる', async(async () => {
-			const res = await request('/notes/reactions/create', {}, alice);
-
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it('間違ったIDで怒られる', async(async () => {
-			const res = await request('/notes/reactions/create', {
-				noteId: 'kyoppie',
-				reaction: '🚀',
-			}, alice);
-
-			assert.strictEqual(res.status, 400);
-		}));
-	});
-
-	describe('following/create', () => {
-		it('フォローできる', async(async () => {
-			const res = await request('/following/create', {
-				userId: alice.id
-			}, bob);
-
-			assert.strictEqual(res.status, 200);
-		}));
-
-		it('既にフォローしている場合は怒る', async(async () => {
-			const res = await request('/following/create', {
-				userId: alice.id
-			}, bob);
-
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it('存在しないユーザーはフォローできない', async(async () => {
-			const res = await request('/following/create', {
-				userId: '000000000000000000000000'
-			}, alice);
-
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it('自分自身はフォローできない', async(async () => {
-			const res = await request('/following/create', {
-				userId: alice.id
-			}, alice);
-
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it('空のパラメータで怒られる', async(async () => {
-			const res = await request('/following/create', {}, alice);
-
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it('間違ったIDで怒られる', async(async () => {
-			const res = await request('/following/create', {
-				userId: 'foo'
-			}, alice);
-
-			assert.strictEqual(res.status, 400);
-		}));
-	});
-
-	describe('following/delete', () => {
-		it('フォロー解除できる', async(async () => {
-			await request('/following/create', {
-				userId: alice.id
-			}, bob);
-
-			const res = await request('/following/delete', {
-				userId: alice.id
-			}, bob);
-
-			assert.strictEqual(res.status, 200);
-		}));
-
-		it('フォローしていない場合は怒る', async(async () => {
-			const res = await request('/following/delete', {
-				userId: alice.id
-			}, bob);
-
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it('存在しないユーザーはフォロー解除できない', async(async () => {
-			const res = await request('/following/delete', {
-				userId: '000000000000000000000000'
-			}, alice);
-
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it('自分自身はフォロー解除できない', async(async () => {
-			const res = await request('/following/delete', {
-				userId: alice.id
-			}, alice);
-
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it('空のパラメータで怒られる', async(async () => {
-			const res = await request('/following/delete', {}, alice);
-
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it('間違ったIDで怒られる', async(async () => {
-			const res = await request('/following/delete', {
-				userId: 'kyoppie'
-			}, alice);
-
-			assert.strictEqual(res.status, 400);
-		}));
-	});
-
-	describe('drive', () => {
-		it('ドライブ情報を取得できる', async(async () => {
-			await uploadFile({
-				userId: alice.id,
-				size: 256
-			});
-			await uploadFile({
-				userId: alice.id,
-				size: 512
-			});
-			await uploadFile({
-				userId: alice.id,
-				size: 1024
-			});
-			const res = await request('/drive', {}, alice);
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
-			expect(res.body).have.property('usage').eql(1792);
-		}));
-	});
-
-	describe('drive/files/create', () => {
-		it('ファイルを作成できる', async(async () => {
-			const res = await uploadFile(alice);
-
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
-			assert.strictEqual(res.body.name, 'Lenna.png');
-		}));
-
-		it('ファイルに名前を付けられる', async(async () => {
-			const res = await assert.request(server)
-				.post('/drive/files/create')
-				.field('i', alice.token)
-				.field('name', 'Belmond.png')
-				.attach('file', fs.readFileSync(__dirname + '/resources/Lenna.png'), 'Lenna.png');
-
-			expect(res).have.status(200);
-			expect(res.body).be.a('object');
-			expect(res.body).have.property('name').eql('Belmond.png');
-		}));
-
-		it('ファイル無しで怒られる', async(async () => {
-			const res = await request('/drive/files/create', {}, alice);
-
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it('SVGファイルを作成できる', async(async () => {
-			const res = await uploadFile(alice, __dirname + '/resources/image.svg');
-
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
-			assert.strictEqual(res.body.name, 'image.svg');
-			assert.strictEqual(res.body.type, 'image/svg+xml');
-		}));
-	});
-
-	describe('drive/files/update', () => {
-		it('名前を更新できる', async(async () => {
-			const file = await uploadFile(alice);
-			const newName = 'いちごパスタ.png';
-
-			const res = await request('/drive/files/update', {
-				fileId: file.id,
-				name: newName
-			}, alice);
-
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
-			assert.strictEqual(res.body.name, newName);
-		}));
-
-		it('他人のファイルは更新できない', async(async () => {
-			const file = await uploadFile(bob);
-
-			const res = await request('/drive/files/update', {
-				fileId: file.id,
-				name: 'いちごパスタ.png'
-			}, alice);
-
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it('親フォルダを更新できる', async(async () => {
-			const file = await uploadFile(alice);
-			const folder = (await request('/drive/folders/create', {
-				name: 'test'
-			}, alice)).body;
-
-			const res = await request('/drive/files/update', {
-				fileId: file.id,
-				folderId: folder.id
-			}, alice);
-
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
-			assert.strictEqual(res.body.folderId, folder.id);
-		}));
-
-		it('親フォルダを無しにできる', async(async () => {
-			const file = await uploadFile(alice);
-
-			const folder = (await request('/drive/folders/create', {
-				name: 'test'
-			}, alice)).body;
-
-			await request('/drive/files/update', {
-				fileId: file.id,
-				folderId: folder.id
-			}, alice);
-
-			const res = await request('/drive/files/update', {
-				fileId: file.id,
-				folderId: null
-			}, alice);
-
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
-			assert.strictEqual(res.body.folderId, null);
-		}));
-
-		it('他人のフォルダには入れられない', async(async () => {
-			const file = await uploadFile(alice);
-			const folder = (await request('/drive/folders/create', {
-				name: 'test'
-			}, bob)).body;
-
-			const res = await request('/drive/files/update', {
-				fileId: file.id,
-				folderId: folder.id
-			}, alice);
-
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it('存在しないフォルダで怒られる', async(async () => {
-			const file = await uploadFile(alice);
-
-			const res = await request('/drive/files/update', {
-				fileId: file.id,
-				folderId: '000000000000000000000000'
-			}, alice);
-
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it('不正なフォルダIDで怒られる', async(async () => {
-			const file = await uploadFile(alice);
-
-			const res = await request('/drive/files/update', {
-				fileId: file.id,
-				folderId: 'foo'
-			}, alice);
-
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it('ファイルが存在しなかったら怒る', async(async () => {
-			const res = await request('/drive/files/update', {
-				fileId: '000000000000000000000000',
-				name: 'いちごパスタ.png'
-			}, alice);
-
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it('間違ったIDで怒られる', async(async () => {
-			const res = await request('/drive/files/update', {
-				fileId: 'kyoppie',
-				name: 'いちごパスタ.png'
-			}, alice);
-
-			assert.strictEqual(res.status, 400);
-		}));
-	});
-
-	describe('drive/folders/create', () => {
-		it('フォルダを作成できる', async(async () => {
-			const res = await request('/drive/folders/create', {
-				name: 'test'
-			}, alice);
-
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
-			assert.strictEqual(res.body.name, 'test');
-		}));
-	});
-
-	describe('drive/folders/update', () => {
-		it('名前を更新できる', async(async () => {
-			const folder = (await request('/drive/folders/create', {
-				name: 'test'
-			}, alice)).body;
-
-			const res = await request('/drive/folders/update', {
-				folderId: folder.id,
-				name: 'new name'
-			}, alice);
-
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
-			assert.strictEqual(res.body.name, 'new name');
-		}));
-
-		it('他人のフォルダを更新できない', async(async () => {
-			const folder = (await request('/drive/folders/create', {
-				name: 'test'
-			}, bob)).body;
-
-			const res = await request('/drive/folders/update', {
-				folderId: folder.id,
-				name: 'new name'
-			}, alice);
-
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it('親フォルダを更新できる', async(async () => {
-			const folder = (await request('/drive/folders/create', {
-				name: 'test'
-			}, alice)).body;
-			const parentFolder = (await request('/drive/folders/create', {
-				name: 'parent'
-			}, alice)).body;
-
-			const res = await request('/drive/folders/update', {
-				folderId: folder.id,
-				parentId: parentFolder.id
-			}, alice);
-
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
-			assert.strictEqual(res.body.parentId, parentFolder.id);
-		}));
-
-		it('親フォルダを無しに更新できる', async(async () => {
-			const folder = (await request('/drive/folders/create', {
-				name: 'test'
-			}, alice)).body;
-			const parentFolder = (await request('/drive/folders/create', {
-				name: 'parent'
-			}, alice)).body;
-			await request('/drive/folders/update', {
-				folderId: folder.id,
-				parentId: parentFolder.id
-			}, alice);
-
-			const res = await request('/drive/folders/update', {
-				folderId: folder.id,
-				parentId: null
-			}, alice);
-
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
-			assert.strictEqual(res.body.parentId, null);
-		}));
-
-		it('他人のフォルダを親フォルダに設定できない', async(async () => {
-			const folder = (await request('/drive/folders/create', {
-				name: 'test'
-			}, alice)).body;
-			const parentFolder = (await request('/drive/folders/create', {
-				name: 'parent'
-			}, bob)).body;
-
-			const res = await request('/drive/folders/update', {
-				folderId: folder.id,
-				parentId: parentFolder.id
-			}, alice);
-
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it('フォルダが循環するような構造にできない', async(async () => {
-			const folder = (await request('/drive/folders/create', {
-				name: 'test'
-			}, alice)).body;
-			const parentFolder = (await request('/drive/folders/create', {
-				name: 'parent'
-			}, alice)).body;
-			await request('/drive/folders/update', {
-				folderId: parentFolder.id,
-				parentId: folder.id
-			}, alice);
-
-			const res = await request('/drive/folders/update', {
-				folderId: folder.id,
-				parentId: parentFolder.id
-			}, alice);
-
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it('フォルダが循環するような構造にできない(再帰的)', async(async () => {
-			const folderA = (await request('/drive/folders/create', {
-				name: 'test'
-			}, alice)).body;
-			const folderB = (await request('/drive/folders/create', {
-				name: 'test'
-			}, alice)).body;
-			const folderC = (await request('/drive/folders/create', {
-				name: 'test'
-			}, alice)).body;
-			await request('/drive/folders/update', {
-				folderId: folderB.id,
-				parentId: folderA.id
-			}, alice);
-			await request('/drive/folders/update', {
-				folderId: folderC.id,
-				parentId: folderB.id
-			}, alice);
-
-			const res = await request('/drive/folders/update', {
-				folderId: folderA.id,
-				parentId: folderC.id
-			}, alice);
-
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it('フォルダが循環するような構造にできない(自身)', async(async () => {
-			const folderA = (await request('/drive/folders/create', {
-				name: 'test'
-			}, alice)).body;
-
-			const res = await request('/drive/folders/update', {
-				folderId: folderA.id,
-				parentId: folderA.id
-			}, alice);
-
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it('存在しない親フォルダを設定できない', async(async () => {
-			const folder = (await request('/drive/folders/create', {
-				name: 'test'
-			}, alice)).body;
-
-			const res = await request('/drive/folders/update', {
-				folderId: folder.id,
-				parentId: '000000000000000000000000'
-			}, alice);
-
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it('不正な親フォルダIDで怒られる', async(async () => {
-			const folder = (await request('/drive/folders/create', {
-				name: 'test'
-			}, alice)).body;
-
-			const res = await request('/drive/folders/update', {
-				folderId: folder.id,
-				parentId: 'foo'
-			}, alice);
-
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it('存在しないフォルダを更新できない', async(async () => {
-			const res = await request('/drive/folders/update', {
-				folderId: '000000000000000000000000'
-			}, alice);
-
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it('不正なフォルダIDで怒られる', async(async () => {
-			const res = await request('/drive/folders/update', {
-				folderId: 'foo'
-			}, alice);
-
-			assert.strictEqual(res.status, 400);
-		}));
-	});
-
-	describe('messaging/messages/create', () => {
-		it('メッセージを送信できる', async(async () => {
-			const res = await request('/messaging/messages/create', {
-				userId: bob.id,
-				text: 'test'
-			}, alice);
-
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(typeof res.body === 'object' && !Array.isArray(res.body), true);
-			assert.strictEqual(res.body.text, 'test');
-		}));
-
-		it('自分自身にはメッセージを送信できない', async(async () => {
-			const res = await request('/messaging/messages/create', {
-				userId: alice.id,
-				text: 'Yo'
-			}, alice);
-
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it('存在しないユーザーにはメッセージを送信できない', async(async () => {
-			const res = await request('/messaging/messages/create', {
-				userId: '000000000000000000000000',
-				text: 'test'
-			}, alice);
-
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it('不正なユーザーIDで怒られる', async(async () => {
-			const res = await request('/messaging/messages/create', {
-				userId: 'foo',
-				text: 'test'
-			}, alice);
-
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it('テキストが無くて怒られる', async(async () => {
-			const res = await request('/messaging/messages/create', {
-				userId: bob.id
-			}, alice);
-
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it('文字数オーバーで怒られる', async(async () => {
-			const res = await request('/messaging/messages/create', {
-				userId: bob.id,
-				text: '!'.repeat(1001)
-			}, alice);
-
-			assert.strictEqual(res.status, 400);
-		}));
-	});
-
-	describe('notes/replies', () => {
-		it('自分に閲覧権限のない投稿は含まれない', async(async () => {
-			const alicePost = await post(alice, {
-				text: 'foo'
-			});
-
-			await post(bob, {
-				replyId: alicePost.id,
-				text: 'bar',
-				visibility: 'specified',
-				visibleUserIds: [alice.id]
-			});
-
-			const res = await request('/notes/replies', {
-				noteId: alicePost.id
-			}, carol);
-
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(Array.isArray(res.body), true);
-			assert.strictEqual(res.body.length, 0);
-		}));
-	});
-
-	describe('notes/timeline', () => {
-		it('フォロワー限定投稿が含まれる', async(async () => {
-			await request('/following/create', {
-				userId: alice.id
-			}, bob);
-
-			const alicePost = await post(alice, {
-				text: 'foo',
-				visibility: 'followers'
-			});
-
-			const res = await request('/notes/timeline', {}, bob);
-
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(Array.isArray(res.body), true);
-			assert.strictEqual(res.body.length, 1);
-			assert.strictEqual(res.body[0].id, alicePost.id);
-		}));
-	});
-});
-*/
diff --git a/packages/backend/test/extract-mentions.ts b/packages/backend/test/extract-mentions.ts
deleted file mode 100644
index f400e1e634..0000000000
--- a/packages/backend/test/extract-mentions.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import * as assert from "assert";
-
-import { parse } from "mfm-js";
-import { extractMentions } from "../src/misc/extract-mentions.js";
-
-describe("Extract mentions", () => {
-	it("simple", () => {
-		const ast = parse("@foo @bar @baz")!;
-		const mentions = extractMentions(ast);
-		assert.deepStrictEqual(mentions, [
-			{
-				username: "foo",
-				acct: "@foo",
-				host: null,
-			},
-			{
-				username: "bar",
-				acct: "@bar",
-				host: null,
-			},
-			{
-				username: "baz",
-				acct: "@baz",
-				host: null,
-			},
-		]);
-	});
-
-	it("nested", () => {
-		const ast = parse("@foo **@bar** @baz")!;
-		const mentions = extractMentions(ast);
-		assert.deepStrictEqual(mentions, [
-			{
-				username: "foo",
-				acct: "@foo",
-				host: null,
-			},
-			{
-				username: "bar",
-				acct: "@bar",
-				host: null,
-			},
-			{
-				username: "baz",
-				acct: "@baz",
-				host: null,
-			},
-		]);
-	});
-});
diff --git a/packages/backend/test/fetch-resource.ts b/packages/backend/test/fetch-resource.ts
deleted file mode 100644
index da3116f0e8..0000000000
--- a/packages/backend/test/fetch-resource.ts
+++ /dev/null
@@ -1,213 +0,0 @@
-process.env.NODE_ENV = "test";
-
-import * as assert from "assert";
-import * as childProcess from "child_process";
-import * as openapi from "@redocly/openapi-core";
-import {
-	async,
-	startServer,
-	signup,
-	post,
-	request,
-	simpleGet,
-	port,
-	shutdownServer,
-} from "./utils.js";
-
-// Request Accept
-const ONLY_AP = "application/activity+json";
-const PREFER_AP = "application/activity+json, */*";
-const PREFER_HTML = "text/html, */*";
-const UNSPECIFIED = "*/*";
-
-// Response Contet-Type
-const AP = "application/activity+json; charset=utf-8";
-const JSON = "application/json; charset=utf-8";
-const HTML = "text/html; charset=utf-8";
-
-describe("Fetch resource", () => {
-	let p: childProcess.ChildProcess;
-
-	let alice: any;
-	let alicesPost: any;
-
-	before(async () => {
-		p = await startServer();
-		alice = await signup({ username: "alice" });
-		alicesPost = await post(alice, {
-			text: "test",
-		});
-	});
-
-	after(async () => {
-		await shutdownServer(p);
-	});
-
-	describe("Common", () => {
-		it("meta", async(async () => {
-			const res = await request("/meta", {});
-
-			assert.strictEqual(res.status, 200);
-		}));
-
-		it("GET root", async(async () => {
-			const res = await simpleGet("/");
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(res.type, HTML);
-		}));
-
-		it("GET docs", async(async () => {
-			const res = await simpleGet("/docs/ja-JP/about");
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(res.type, HTML);
-		}));
-
-		it("GET api-doc", async(async () => {
-			const res = await simpleGet("/api-doc");
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(res.type, HTML);
-		}));
-
-		it("GET api.json", async(async () => {
-			const res = await simpleGet("/api.json");
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(res.type, JSON);
-		}));
-
-		it("Validate api.json", async(async () => {
-			const config = await openapi.loadConfig();
-			const result = await openapi.bundle({
-				config,
-				ref: `http://localhost:${port}/api.json`,
-			});
-
-			for (const problem of result.problems) {
-				console.log(`${problem.message} - ${problem.location[0]?.pointer}`);
-			}
-
-			assert.strictEqual(result.problems.length, 0);
-		}));
-
-		it("GET favicon.ico", async(async () => {
-			const res = await simpleGet("/favicon.ico");
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(res.type, "image/x-icon");
-		}));
-
-		it("GET apple-touch-icon.png", async(async () => {
-			const res = await simpleGet("/apple-touch-icon.png");
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(res.type, "image/png");
-		}));
-
-		it("GET twemoji svg", async(async () => {
-			const res = await simpleGet("/twemoji/2764.svg");
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(res.type, "image/svg+xml");
-		}));
-
-		it("GET twemoji svg with hyphen", async(async () => {
-			const res = await simpleGet("/twemoji/2764-fe0f-200d-1f525.svg");
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(res.type, "image/svg+xml");
-		}));
-	});
-
-	describe("/@:username", () => {
-		it("Only AP => AP", async(async () => {
-			const res = await simpleGet(`/@${alice.username}`, ONLY_AP);
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(res.type, AP);
-		}));
-
-		it("Prefer AP => AP", async(async () => {
-			const res = await simpleGet(`/@${alice.username}`, PREFER_AP);
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(res.type, AP);
-		}));
-
-		it("Prefer HTML => HTML", async(async () => {
-			const res = await simpleGet(`/@${alice.username}`, PREFER_HTML);
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(res.type, HTML);
-		}));
-
-		it("Unspecified => HTML", async(async () => {
-			const res = await simpleGet(`/@${alice.username}`, UNSPECIFIED);
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(res.type, HTML);
-		}));
-	});
-
-	describe("/users/:id", () => {
-		it("Only AP => AP", async(async () => {
-			const res = await simpleGet(`/users/${alice.id}`, ONLY_AP);
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(res.type, AP);
-		}));
-
-		it("Prefer AP => AP", async(async () => {
-			const res = await simpleGet(`/users/${alice.id}`, PREFER_AP);
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(res.type, AP);
-		}));
-
-		it("Prefer HTML => Redirect to /@:username", async(async () => {
-			const res = await simpleGet(`/users/${alice.id}`, PREFER_HTML);
-			assert.strictEqual(res.status, 302);
-			assert.strictEqual(res.location, `/@${alice.username}`);
-		}));
-
-		it("Undecided => HTML", async(async () => {
-			const res = await simpleGet(`/users/${alice.id}`, UNSPECIFIED);
-			assert.strictEqual(res.status, 302);
-			assert.strictEqual(res.location, `/@${alice.username}`);
-		}));
-	});
-
-	describe("/notes/:id", () => {
-		it("Only AP => AP", async(async () => {
-			const res = await simpleGet(`/notes/${alicesPost.id}`, ONLY_AP);
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(res.type, AP);
-		}));
-
-		it("Prefer AP => AP", async(async () => {
-			const res = await simpleGet(`/notes/${alicesPost.id}`, PREFER_AP);
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(res.type, AP);
-		}));
-
-		it("Prefer HTML => HTML", async(async () => {
-			const res = await simpleGet(`/notes/${alicesPost.id}`, PREFER_HTML);
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(res.type, HTML);
-		}));
-
-		it("Unspecified => HTML", async(async () => {
-			const res = await simpleGet(`/notes/${alicesPost.id}`, UNSPECIFIED);
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(res.type, HTML);
-		}));
-	});
-
-	describe("Feeds", () => {
-		it("RSS", async(async () => {
-			const res = await simpleGet(`/@${alice.username}.rss`, UNSPECIFIED);
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(res.type, "application/rss+xml; charset=utf-8");
-		}));
-
-		it("ATOM", async(async () => {
-			const res = await simpleGet(`/@${alice.username}.atom`, UNSPECIFIED);
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(res.type, "application/atom+xml; charset=utf-8");
-		}));
-
-		it("JSON", async(async () => {
-			const res = await simpleGet(`/@${alice.username}.json`, UNSPECIFIED);
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(res.type, "application/json; charset=utf-8");
-		}));
-	});
-});
diff --git a/packages/backend/test/ff-visibility.ts b/packages/backend/test/ff-visibility.ts
deleted file mode 100644
index f898926d99..0000000000
--- a/packages/backend/test/ff-visibility.ts
+++ /dev/null
@@ -1,283 +0,0 @@
-process.env.NODE_ENV = "test";
-
-import * as assert from "assert";
-import * as childProcess from "child_process";
-import {
-	async,
-	signup,
-	request,
-	post,
-	react,
-	connectStream,
-	startServer,
-	shutdownServer,
-	simpleGet,
-} from "./utils.js";
-
-describe("FF visibility", () => {
-	let p: childProcess.ChildProcess;
-
-	let alice: any;
-	let bob: any;
-	let carol: any;
-
-	before(async () => {
-		p = await startServer();
-		alice = await signup({ username: "alice" });
-		bob = await signup({ username: "bob" });
-		carol = await signup({ username: "carol" });
-	});
-
-	after(async () => {
-		await shutdownServer(p);
-	});
-
-	it("ffVisibility が public なユーザーのフォロー/フォロワーを誰でも見れる", async(async () => {
-		await request(
-			"/i/update",
-			{
-				ffVisibility: "public",
-			},
-			alice,
-		);
-
-		const followingRes = await request(
-			"/users/following",
-			{
-				userId: alice.id,
-			},
-			bob,
-		);
-		const followersRes = await request(
-			"/users/followers",
-			{
-				userId: alice.id,
-			},
-			bob,
-		);
-
-		assert.strictEqual(followingRes.status, 200);
-		assert.strictEqual(Array.isArray(followingRes.body), true);
-		assert.strictEqual(followersRes.status, 200);
-		assert.strictEqual(Array.isArray(followersRes.body), true);
-	}));
-
-	it("ffVisibility が followers なユーザーのフォロー/フォロワーを自分で見れる", async(async () => {
-		await request(
-			"/i/update",
-			{
-				ffVisibility: "followers",
-			},
-			alice,
-		);
-
-		const followingRes = await request(
-			"/users/following",
-			{
-				userId: alice.id,
-			},
-			alice,
-		);
-		const followersRes = await request(
-			"/users/followers",
-			{
-				userId: alice.id,
-			},
-			alice,
-		);
-
-		assert.strictEqual(followingRes.status, 200);
-		assert.strictEqual(Array.isArray(followingRes.body), true);
-		assert.strictEqual(followersRes.status, 200);
-		assert.strictEqual(Array.isArray(followersRes.body), true);
-	}));
-
-	it("ffVisibility が followers なユーザーのフォロー/フォロワーを非フォロワーが見れない", async(async () => {
-		await request(
-			"/i/update",
-			{
-				ffVisibility: "followers",
-			},
-			alice,
-		);
-
-		const followingRes = await request(
-			"/users/following",
-			{
-				userId: alice.id,
-			},
-			bob,
-		);
-		const followersRes = await request(
-			"/users/followers",
-			{
-				userId: alice.id,
-			},
-			bob,
-		);
-
-		assert.strictEqual(followingRes.status, 400);
-		assert.strictEqual(followersRes.status, 400);
-	}));
-
-	it("ffVisibility が followers なユーザーのフォロー/フォロワーをフォロワーが見れる", async(async () => {
-		await request(
-			"/i/update",
-			{
-				ffVisibility: "followers",
-			},
-			alice,
-		);
-
-		await request(
-			"/following/create",
-			{
-				userId: alice.id,
-			},
-			bob,
-		);
-
-		const followingRes = await request(
-			"/users/following",
-			{
-				userId: alice.id,
-			},
-			bob,
-		);
-		const followersRes = await request(
-			"/users/followers",
-			{
-				userId: alice.id,
-			},
-			bob,
-		);
-
-		assert.strictEqual(followingRes.status, 200);
-		assert.strictEqual(Array.isArray(followingRes.body), true);
-		assert.strictEqual(followersRes.status, 200);
-		assert.strictEqual(Array.isArray(followersRes.body), true);
-	}));
-
-	it("ffVisibility が private なユーザーのフォロー/フォロワーを自分で見れる", async(async () => {
-		await request(
-			"/i/update",
-			{
-				ffVisibility: "private",
-			},
-			alice,
-		);
-
-		const followingRes = await request(
-			"/users/following",
-			{
-				userId: alice.id,
-			},
-			alice,
-		);
-		const followersRes = await request(
-			"/users/followers",
-			{
-				userId: alice.id,
-			},
-			alice,
-		);
-
-		assert.strictEqual(followingRes.status, 200);
-		assert.strictEqual(Array.isArray(followingRes.body), true);
-		assert.strictEqual(followersRes.status, 200);
-		assert.strictEqual(Array.isArray(followersRes.body), true);
-	}));
-
-	it("ffVisibility が private なユーザーのフォロー/フォロワーを他人が見れない", async(async () => {
-		await request(
-			"/i/update",
-			{
-				ffVisibility: "private",
-			},
-			alice,
-		);
-
-		const followingRes = await request(
-			"/users/following",
-			{
-				userId: alice.id,
-			},
-			bob,
-		);
-		const followersRes = await request(
-			"/users/followers",
-			{
-				userId: alice.id,
-			},
-			bob,
-		);
-
-		assert.strictEqual(followingRes.status, 400);
-		assert.strictEqual(followersRes.status, 400);
-	}));
-
-	describe("AP", () => {
-		it("ffVisibility が public 以外ならばAPからは取得できない", async(async () => {
-			{
-				await request(
-					"/i/update",
-					{
-						ffVisibility: "public",
-					},
-					alice,
-				);
-
-				const followingRes = await simpleGet(
-					`/users/${alice.id}/following`,
-					"application/activity+json",
-				);
-				const followersRes = await simpleGet(
-					`/users/${alice.id}/followers`,
-					"application/activity+json",
-				);
-				assert.strictEqual(followingRes.status, 200);
-				assert.strictEqual(followersRes.status, 200);
-			}
-			{
-				await request(
-					"/i/update",
-					{
-						ffVisibility: "followers",
-					},
-					alice,
-				);
-
-				const followingRes = await simpleGet(
-					`/users/${alice.id}/following`,
-					"application/activity+json",
-				).catch((res) => ({ status: res.statusCode }));
-				const followersRes = await simpleGet(
-					`/users/${alice.id}/followers`,
-					"application/activity+json",
-				).catch((res) => ({ status: res.statusCode }));
-				assert.strictEqual(followingRes.status, 403);
-				assert.strictEqual(followersRes.status, 403);
-			}
-			{
-				await request(
-					"/i/update",
-					{
-						ffVisibility: "private",
-					},
-					alice,
-				);
-
-				const followingRes = await simpleGet(
-					`/users/${alice.id}/following`,
-					"application/activity+json",
-				).catch((res) => ({ status: res.statusCode }));
-				const followersRes = await simpleGet(
-					`/users/${alice.id}/followers`,
-					"application/activity+json",
-				).catch((res) => ({ status: res.statusCode }));
-				assert.strictEqual(followingRes.status, 403);
-				assert.strictEqual(followersRes.status, 403);
-			}
-		}));
-	});
-});
diff --git a/packages/backend/test/get-file-info.ts b/packages/backend/test/get-file-info.ts
deleted file mode 100644
index 22dc28c8e0..0000000000
--- a/packages/backend/test/get-file-info.ts
+++ /dev/null
@@ -1,209 +0,0 @@
-import * as assert from "assert";
-import { fileURLToPath } from "node:url";
-import { dirname } from "node:path";
-import { getFileInfo } from "../src/misc/get-file-info.js";
-import { async } from "./utils.js";
-
-const _filename = fileURLToPath(import.meta.url);
-const _dirname = dirname(_filename);
-
-describe("Get file info", () => {
-	it("Empty file", async(async () => {
-		const path = `${_dirname}/resources/emptyfile`;
-		const info = (await getFileInfo(path, {
-			skipSensitiveDetection: true,
-		})) as any;
-		delete info.warnings;
-		delete info.blurhash;
-		delete info.sensitive;
-		delete info.porn;
-		assert.deepStrictEqual(info, {
-			size: 0,
-			md5: "d41d8cd98f00b204e9800998ecf8427e",
-			type: {
-				mime: "application/octet-stream",
-				ext: null,
-			},
-			width: undefined,
-			height: undefined,
-			orientation: undefined,
-		});
-	}));
-
-	it("Generic JPEG", async(async () => {
-		const path = `${_dirname}/resources/Lenna.jpg`;
-		const info = (await getFileInfo(path, {
-			skipSensitiveDetection: true,
-		})) as any;
-		delete info.warnings;
-		delete info.blurhash;
-		delete info.sensitive;
-		delete info.porn;
-		assert.deepStrictEqual(info, {
-			size: 25360,
-			md5: "091b3f259662aa31e2ffef4519951168",
-			type: {
-				mime: "image/jpeg",
-				ext: "jpg",
-			},
-			width: 512,
-			height: 512,
-			orientation: undefined,
-		});
-	}));
-
-	it("Generic APNG", async(async () => {
-		const path = `${_dirname}/resources/anime.png`;
-		const info = (await getFileInfo(path, {
-			skipSensitiveDetection: true,
-		})) as any;
-		delete info.warnings;
-		delete info.blurhash;
-		delete info.sensitive;
-		delete info.porn;
-		assert.deepStrictEqual(info, {
-			size: 1868,
-			md5: "08189c607bea3b952704676bb3c979e0",
-			type: {
-				mime: "image/apng",
-				ext: "apng",
-			},
-			width: 256,
-			height: 256,
-			orientation: undefined,
-		});
-	}));
-
-	it("Generic AGIF", async(async () => {
-		const path = `${_dirname}/resources/anime.gif`;
-		const info = (await getFileInfo(path, {
-			skipSensitiveDetection: true,
-		})) as any;
-		delete info.warnings;
-		delete info.blurhash;
-		delete info.sensitive;
-		delete info.porn;
-		assert.deepStrictEqual(info, {
-			size: 2248,
-			md5: "32c47a11555675d9267aee1a86571e7e",
-			type: {
-				mime: "image/gif",
-				ext: "gif",
-			},
-			width: 256,
-			height: 256,
-			orientation: undefined,
-		});
-	}));
-
-	it("PNG with alpha", async(async () => {
-		const path = `${_dirname}/resources/with-alpha.png`;
-		const info = (await getFileInfo(path, {
-			skipSensitiveDetection: true,
-		})) as any;
-		delete info.warnings;
-		delete info.blurhash;
-		delete info.sensitive;
-		delete info.porn;
-		assert.deepStrictEqual(info, {
-			size: 3772,
-			md5: "f73535c3e1e27508885b69b10cf6e991",
-			type: {
-				mime: "image/png",
-				ext: "png",
-			},
-			width: 256,
-			height: 256,
-			orientation: undefined,
-		});
-	}));
-
-	it("Generic SVG", async(async () => {
-		const path = `${_dirname}/resources/image.svg`;
-		const info = (await getFileInfo(path, {
-			skipSensitiveDetection: true,
-		})) as any;
-		delete info.warnings;
-		delete info.blurhash;
-		delete info.sensitive;
-		delete info.porn;
-		assert.deepStrictEqual(info, {
-			size: 505,
-			md5: "b6f52b4b021e7b92cdd04509c7267965",
-			type: {
-				mime: "image/svg+xml",
-				ext: "svg",
-			},
-			width: 256,
-			height: 256,
-			orientation: undefined,
-		});
-	}));
-
-	it("SVG with XML definition", async(async () => {
-		// https://github.com/misskey-dev/misskey/issues/4413
-		const path = `${_dirname}/resources/with-xml-def.svg`;
-		const info = (await getFileInfo(path, {
-			skipSensitiveDetection: true,
-		})) as any;
-		delete info.warnings;
-		delete info.blurhash;
-		delete info.sensitive;
-		delete info.porn;
-		assert.deepStrictEqual(info, {
-			size: 544,
-			md5: "4b7a346cde9ccbeb267e812567e33397",
-			type: {
-				mime: "image/svg+xml",
-				ext: "svg",
-			},
-			width: 256,
-			height: 256,
-			orientation: undefined,
-		});
-	}));
-
-	it("Dimension limit", async(async () => {
-		const path = `${_dirname}/resources/25000x25000.png`;
-		const info = (await getFileInfo(path, {
-			skipSensitiveDetection: true,
-		})) as any;
-		delete info.warnings;
-		delete info.blurhash;
-		delete info.sensitive;
-		delete info.porn;
-		assert.deepStrictEqual(info, {
-			size: 75933,
-			md5: "268c5dde99e17cf8fe09f1ab3f97df56",
-			type: {
-				mime: "application/octet-stream", // do not treat as image
-				ext: null,
-			},
-			width: 25000,
-			height: 25000,
-			orientation: undefined,
-		});
-	}));
-
-	it("Rotate JPEG", async(async () => {
-		const path = `${_dirname}/resources/rotate.jpg`;
-		const info = (await getFileInfo(path, {
-			skipSensitiveDetection: true,
-		})) as any;
-		delete info.warnings;
-		delete info.blurhash;
-		delete info.sensitive;
-		delete info.porn;
-		assert.deepStrictEqual(info, {
-			size: 12624,
-			md5: "68d5b2d8d1d1acbbce99203e3ec3857e",
-			type: {
-				mime: "image/jpeg",
-				ext: "jpg",
-			},
-			width: 512,
-			height: 256,
-			orientation: 8,
-		});
-	}));
-});
diff --git a/packages/backend/test/loader.js b/packages/backend/test/loader.js
deleted file mode 100644
index 7e1bf379dc..0000000000
--- a/packages/backend/test/loader.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * ts-node/esmローダーに投げる前にpath mappingを解決する
- * 参考
- * - https://github.com/TypeStrong/ts-node/discussions/1450#discussioncomment-1806115
- * - https://nodejs.org/api/esm.html#loaders
- * ※ https://github.com/TypeStrong/ts-node/pull/1585 が取り込まれたらこのカスタムローダーは必要なくなる
- */
-
-import { resolve as resolveTs, load } from "ts-node/esm";
-import { loadConfig, createMatchPath } from "tsconfig-paths";
-import { pathToFileURL } from "url";
-
-const tsconfig = loadConfig();
-const matchPath = createMatchPath(tsconfig.absoluteBaseUrl, tsconfig.paths);
-
-export function resolve(specifier, ctx, defaultResolve) {
-	let resolvedSpecifier;
-	if (specifier.endsWith(".js")) {
-		// maybe transpiled
-		const specifierWithoutExtension = specifier.substring(
-			0,
-			specifier.length - ".js".length,
-		);
-		const matchedSpecifier = matchPath(specifierWithoutExtension);
-		if (matchedSpecifier) {
-			resolvedSpecifier = pathToFileURL(`${matchedSpecifier}.js`).href;
-		}
-	} else {
-		const matchedSpecifier = matchPath(specifier);
-		if (matchedSpecifier) {
-			resolvedSpecifier = pathToFileURL(matchedSpecifier).href;
-		}
-	}
-	return resolveTs(resolvedSpecifier ?? specifier, ctx, defaultResolve);
-}
-
-export { load };
diff --git a/packages/backend/test/mfm.ts b/packages/backend/test/mfm.ts
deleted file mode 100644
index 605daa7107..0000000000
--- a/packages/backend/test/mfm.ts
+++ /dev/null
@@ -1,127 +0,0 @@
-import * as assert from "assert";
-import * as mfm from "mfm-js";
-
-import { toHtml } from "../src/mfm/to-html.js";
-import { fromHtml } from "../src/mfm/from-html.js";
-
-describe("toHtml", () => {
-	it("br", () => {
-		const input = "foo\nbar\nbaz";
-		const output = "<p><span>foo<br>bar<br>baz</span></p>";
-		assert.equal(toHtml(mfm.parse(input)), output);
-	});
-
-	it("br alt", () => {
-		const input = "foo\r\nbar\rbaz";
-		const output = "<p><span>foo<br>bar<br>baz</span></p>";
-		assert.equal(toHtml(mfm.parse(input)), output);
-	});
-});
-
-describe("fromHtml", () => {
-	it("p", () => {
-		assert.deepStrictEqual(fromHtml("<p>a</p><p>b</p>"), "a\n\nb");
-	});
-
-	it("block element", () => {
-		assert.deepStrictEqual(fromHtml("<div>a</div><div>b</div>"), "a\nb");
-	});
-
-	it("inline element", () => {
-		assert.deepStrictEqual(fromHtml("<ul><li>a</li><li>b</li></ul>"), "a\nb");
-	});
-
-	it("block code", () => {
-		assert.deepStrictEqual(
-			fromHtml("<pre><code>a\nb</code></pre>"),
-			"```\na\nb\n```",
-		);
-	});
-
-	it("inline code", () => {
-		assert.deepStrictEqual(fromHtml("<code>a</code>"), "`a`");
-	});
-
-	it("quote", () => {
-		assert.deepStrictEqual(
-			fromHtml("<blockquote>a\nb</blockquote>"),
-			"> a\n> b",
-		);
-	});
-
-	it("br", () => {
-		assert.deepStrictEqual(fromHtml("<p>abc<br><br/>d</p>"), "abc\n\nd");
-	});
-
-	it("link with different text", () => {
-		assert.deepStrictEqual(
-			fromHtml('<p>a <a href="https://example.com/b">c</a> d</p>'),
-			"a [c](https://example.com/b) d",
-		);
-	});
-
-	it("link with different text, but not encoded", () => {
-		assert.deepStrictEqual(
-			fromHtml('<p>a <a href="https://example.com/ä">c</a> d</p>'),
-			"a [c](<https://example.com/ä>) d",
-		);
-	});
-
-	it("link with same text", () => {
-		assert.deepStrictEqual(
-			fromHtml(
-				'<p>a <a href="https://example.com/b">https://example.com/b</a> d</p>',
-			),
-			"a https://example.com/b d",
-		);
-	});
-
-	it("link with same text, but not encoded", () => {
-		assert.deepStrictEqual(
-			fromHtml(
-				'<p>a <a href="https://example.com/ä">https://example.com/ä</a> d</p>',
-			),
-			"a <https://example.com/ä> d",
-		);
-	});
-
-	it("link with no url", () => {
-		assert.deepStrictEqual(
-			fromHtml('<p>a <a href="b">c</a> d</p>'),
-			"a [c](b) d",
-		);
-	});
-
-	it("link without href", () => {
-		assert.deepStrictEqual(fromHtml("<p>a <a>c</a> d</p>"), "a c d");
-	});
-
-	it("link without text", () => {
-		assert.deepStrictEqual(
-			fromHtml('<p>a <a href="https://example.com/b"></a> d</p>'),
-			"a https://example.com/b d",
-		);
-	});
-
-	it("link without both", () => {
-		assert.deepStrictEqual(fromHtml("<p>a <a></a> d</p>"), "a  d");
-	});
-
-	it("mention", () => {
-		assert.deepStrictEqual(
-			fromHtml(
-				'<p>a <a href="https://example.com/@user" class="u-url mention">@user</a> d</p>',
-			),
-			"a @user@example.com d",
-		);
-	});
-
-	it("hashtag", () => {
-		assert.deepStrictEqual(
-			fromHtml('<p>a <a href="https://example.com/tags/a">#a</a> d</p>', [
-				"#a",
-			]),
-			"a #a d",
-		);
-	});
-});
diff --git a/packages/backend/test/misc/mock-resolver.ts b/packages/backend/test/misc/mock-resolver.ts
deleted file mode 100644
index 74c67e3d3f..0000000000
--- a/packages/backend/test/misc/mock-resolver.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-import Resolver from "../../src/remote/activitypub/resolver.js";
-import { IObject } from "../../src/remote/activitypub/type.js";
-
-type MockResponse = {
-	type: string;
-	content: string;
-};
-
-export class MockResolver extends Resolver {
-	private _rs = new Map<string, MockResponse>();
-	public async _register(
-		uri: string,
-		content: string | Record<string, any>,
-		type = "application/activity+json",
-	) {
-		this._rs.set(uri, {
-			type,
-			content: typeof content === "string" ? content : JSON.stringify(content),
-		});
-	}
-
-	public async resolve(value: string | IObject): Promise<IObject> {
-		if (typeof value !== "string") return value;
-
-		const r = this._rs.get(value);
-
-		if (!r) {
-			throw {
-				name: "StatusError",
-				statusCode: 404,
-				message: "Not registed for mock",
-			};
-		}
-
-		const object = JSON.parse(r.content);
-
-		return object;
-	}
-}
diff --git a/packages/backend/test/mute.ts b/packages/backend/test/mute.ts
deleted file mode 100644
index c511628342..0000000000
--- a/packages/backend/test/mute.ts
+++ /dev/null
@@ -1,176 +0,0 @@
-process.env.NODE_ENV = "test";
-
-import * as assert from "assert";
-import * as childProcess from "child_process";
-import {
-	async,
-	signup,
-	request,
-	post,
-	react,
-	startServer,
-	shutdownServer,
-	waitFire,
-} from "./utils.js";
-
-describe("Mute", () => {
-	let p: childProcess.ChildProcess;
-
-	// alice mutes carol
-	let alice: any;
-	let bob: any;
-	let carol: any;
-
-	before(async () => {
-		p = await startServer();
-		alice = await signup({ username: "alice" });
-		bob = await signup({ username: "bob" });
-		carol = await signup({ username: "carol" });
-	});
-
-	after(async () => {
-		await shutdownServer(p);
-	});
-
-	it("ミュート作成", async(async () => {
-		const res = await request(
-			"/mute/create",
-			{
-				userId: carol.id,
-			},
-			alice,
-		);
-
-		assert.strictEqual(res.status, 204);
-	}));
-
-	it("「自分宛ての投稿」にミュートしているユーザーの投稿が含まれない", async(async () => {
-		const bobNote = await post(bob, { text: "@alice hi" });
-		const carolNote = await post(carol, { text: "@alice hi" });
-
-		const res = await request("/notes/mentions", {}, alice);
-
-		assert.strictEqual(res.status, 200);
-		assert.strictEqual(Array.isArray(res.body), true);
-		assert.strictEqual(
-			res.body.some((note: any) => note.id === bobNote.id),
-			true,
-		);
-		assert.strictEqual(
-			res.body.some((note: any) => note.id === carolNote.id),
-			false,
-		);
-	}));
-
-	it("ミュートしているユーザーからメンションされても、hasUnreadMentions が true にならない", async(async () => {
-		// 状態リセット
-		await request("/i/read-all-unread-notes", {}, alice);
-
-		await post(carol, { text: "@alice hi" });
-
-		const res = await request("/i", {}, alice);
-
-		assert.strictEqual(res.status, 200);
-		assert.strictEqual(res.body.hasUnreadMentions, false);
-	}));
-
-	it("ミュートしているユーザーからメンションされても、ストリームに unreadMention イベントが流れてこない", async () => {
-		// 状態リセット
-		await request("/i/read-all-unread-notes", {}, alice);
-
-		const fired = await waitFire(
-			alice,
-			"main",
-			() => post(carol, { text: "@alice hi" }),
-			(msg) => msg.type === "unreadMention",
-		);
-
-		assert.strictEqual(fired, false);
-	});
-
-	it("ミュートしているユーザーからメンションされても、ストリームに unreadNotification イベントが流れてこない", async () => {
-		// 状態リセット
-		await request("/i/read-all-unread-notes", {}, alice);
-		await request("/notifications/mark-all-as-read", {}, alice);
-
-		const fired = await waitFire(
-			alice,
-			"main",
-			() => post(carol, { text: "@alice hi" }),
-			(msg) => msg.type === "unreadNotification",
-		);
-
-		assert.strictEqual(fired, false);
-	});
-
-	describe("Timeline", () => {
-		it("タイムラインにミュートしているユーザーの投稿が含まれない", async(async () => {
-			const aliceNote = await post(alice);
-			const bobNote = await post(bob);
-			const carolNote = await post(carol);
-
-			const res = await request("/notes/local-timeline", {}, alice);
-
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(Array.isArray(res.body), true);
-			assert.strictEqual(
-				res.body.some((note: any) => note.id === aliceNote.id),
-				true,
-			);
-			assert.strictEqual(
-				res.body.some((note: any) => note.id === bobNote.id),
-				true,
-			);
-			assert.strictEqual(
-				res.body.some((note: any) => note.id === carolNote.id),
-				false,
-			);
-		}));
-
-		it("タイムラインにミュートしているユーザーの投稿のRenoteが含まれない", async(async () => {
-			const aliceNote = await post(alice);
-			const carolNote = await post(carol);
-			const bobNote = await post(bob, {
-				renoteId: carolNote.id,
-			});
-
-			const res = await request("/notes/local-timeline", {}, alice);
-
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(Array.isArray(res.body), true);
-			assert.strictEqual(
-				res.body.some((note: any) => note.id === aliceNote.id),
-				true,
-			);
-			assert.strictEqual(
-				res.body.some((note: any) => note.id === bobNote.id),
-				false,
-			);
-			assert.strictEqual(
-				res.body.some((note: any) => note.id === carolNote.id),
-				false,
-			);
-		}));
-	});
-
-	describe("Notification", () => {
-		it("通知にミュートしているユーザーの通知が含まれない(リアクション)", async(async () => {
-			const aliceNote = await post(alice);
-			await react(bob, aliceNote, "like");
-			await react(carol, aliceNote, "like");
-
-			const res = await request("/i/notifications", {}, alice);
-
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(Array.isArray(res.body), true);
-			assert.strictEqual(
-				res.body.some((notification: any) => notification.userId === bob.id),
-				true,
-			);
-			assert.strictEqual(
-				res.body.some((notification: any) => notification.userId === carol.id),
-				false,
-			);
-		}));
-	});
-});
diff --git a/packages/backend/test/note.ts b/packages/backend/test/note.ts
deleted file mode 100644
index 3af4b88d87..0000000000
--- a/packages/backend/test/note.ts
+++ /dev/null
@@ -1,517 +0,0 @@
-process.env.NODE_ENV = "test";
-
-import * as assert from "assert";
-import * as childProcess from "child_process";
-import { Note } from "../src/models/entities/note.js";
-import {
-	async,
-	signup,
-	request,
-	post,
-	uploadUrl,
-	startServer,
-	shutdownServer,
-	initTestDb,
-	api,
-} from "./utils.js";
-
-describe("Note", () => {
-	let p: childProcess.ChildProcess;
-	let Notes: any;
-
-	let alice: any;
-	let bob: any;
-
-	before(async () => {
-		p = await startServer();
-		const connection = await initTestDb(true);
-		Notes = connection.getRepository(Note);
-		alice = await signup({ username: "alice" });
-		bob = await signup({ username: "bob" });
-	});
-
-	after(async () => {
-		await shutdownServer(p);
-	});
-
-	it("投稿できる", async(async () => {
-		const post = {
-			text: "test",
-		};
-
-		const res = await request("/notes/create", post, alice);
-
-		assert.strictEqual(res.status, 200);
-		assert.strictEqual(
-			typeof res.body === "object" && !Array.isArray(res.body),
-			true,
-		);
-		assert.strictEqual(res.body.createdNote.text, post.text);
-	}));
-
-	it("ファイルを添付できる", async(async () => {
-		const file = await uploadUrl(
-			alice,
-			"https://raw.githubusercontent.com/misskey-dev/misskey/develop/packages/backend/test/resources/Lenna.jpg",
-		);
-
-		const res = await request(
-			"/notes/create",
-			{
-				fileIds: [file.id],
-			},
-			alice,
-		);
-
-		assert.strictEqual(res.status, 200);
-		assert.strictEqual(
-			typeof res.body === "object" && !Array.isArray(res.body),
-			true,
-		);
-		assert.deepStrictEqual(res.body.createdNote.fileIds, [file.id]);
-	}));
-
-	it("他人のファイルは無視", async(async () => {
-		const file = await uploadUrl(
-			bob,
-			"https://raw.githubusercontent.com/misskey-dev/misskey/develop/packages/backend/test/resources/Lenna.jpg",
-		);
-
-		const res = await request(
-			"/notes/create",
-			{
-				text: "test",
-				fileIds: [file.id],
-			},
-			alice,
-		);
-
-		assert.strictEqual(res.status, 200);
-		assert.strictEqual(
-			typeof res.body === "object" && !Array.isArray(res.body),
-			true,
-		);
-		assert.deepStrictEqual(res.body.createdNote.fileIds, []);
-	}));
-
-	it("存在しないファイルは無視", async(async () => {
-		const res = await request(
-			"/notes/create",
-			{
-				text: "test",
-				fileIds: ["000000000000000000000000"],
-			},
-			alice,
-		);
-
-		assert.strictEqual(res.status, 200);
-		assert.strictEqual(
-			typeof res.body === "object" && !Array.isArray(res.body),
-			true,
-		);
-		assert.deepStrictEqual(res.body.createdNote.fileIds, []);
-	}));
-
-	it("不正なファイルIDは無視", async(async () => {
-		const res = await request(
-			"/notes/create",
-			{
-				fileIds: ["kyoppie"],
-			},
-			alice,
-		);
-		assert.strictEqual(res.status, 200);
-		assert.strictEqual(
-			typeof res.body === "object" && !Array.isArray(res.body),
-			true,
-		);
-		assert.deepStrictEqual(res.body.createdNote.fileIds, []);
-	}));
-
-	it("返信できる", async(async () => {
-		const bobPost = await post(bob, {
-			text: "foo",
-		});
-
-		const alicePost = {
-			text: "bar",
-			replyId: bobPost.id,
-		};
-
-		const res = await request("/notes/create", alicePost, alice);
-
-		assert.strictEqual(res.status, 200);
-		assert.strictEqual(
-			typeof res.body === "object" && !Array.isArray(res.body),
-			true,
-		);
-		assert.strictEqual(res.body.createdNote.text, alicePost.text);
-		assert.strictEqual(res.body.createdNote.replyId, alicePost.replyId);
-		assert.strictEqual(res.body.createdNote.reply.text, bobPost.text);
-	}));
-
-	it("renoteできる", async(async () => {
-		const bobPost = await post(bob, {
-			text: "test",
-		});
-
-		const alicePost = {
-			renoteId: bobPost.id,
-		};
-
-		const res = await request("/notes/create", alicePost, alice);
-
-		assert.strictEqual(res.status, 200);
-		assert.strictEqual(
-			typeof res.body === "object" && !Array.isArray(res.body),
-			true,
-		);
-		assert.strictEqual(res.body.createdNote.renoteId, alicePost.renoteId);
-		assert.strictEqual(res.body.createdNote.renote.text, bobPost.text);
-	}));
-
-	it("引用renoteできる", async(async () => {
-		const bobPost = await post(bob, {
-			text: "test",
-		});
-
-		const alicePost = {
-			text: "test",
-			renoteId: bobPost.id,
-		};
-
-		const res = await request("/notes/create", alicePost, alice);
-
-		assert.strictEqual(res.status, 200);
-		assert.strictEqual(
-			typeof res.body === "object" && !Array.isArray(res.body),
-			true,
-		);
-		assert.strictEqual(res.body.createdNote.text, alicePost.text);
-		assert.strictEqual(res.body.createdNote.renoteId, alicePost.renoteId);
-		assert.strictEqual(res.body.createdNote.renote.text, bobPost.text);
-	}));
-
-	it("文字数ぎりぎりで怒られない", async(async () => {
-		const post = {
-			text: "!".repeat(3000),
-		};
-		const res = await request("/notes/create", post, alice);
-		assert.strictEqual(res.status, 200);
-	}));
-
-	it("文字数オーバーで怒られる", async(async () => {
-		const post = {
-			text: "!".repeat(3001),
-		};
-		const res = await request("/notes/create", post, alice);
-		assert.strictEqual(res.status, 400);
-	}));
-
-	it("存在しないリプライ先で怒られる", async(async () => {
-		const post = {
-			text: "test",
-			replyId: "000000000000000000000000",
-		};
-		const res = await request("/notes/create", post, alice);
-		assert.strictEqual(res.status, 400);
-	}));
-
-	it("存在しないrenote対象で怒られる", async(async () => {
-		const post = {
-			renoteId: "000000000000000000000000",
-		};
-		const res = await request("/notes/create", post, alice);
-		assert.strictEqual(res.status, 400);
-	}));
-
-	it("不正なリプライ先IDで怒られる", async(async () => {
-		const post = {
-			text: "test",
-			replyId: "foo",
-		};
-		const res = await request("/notes/create", post, alice);
-		assert.strictEqual(res.status, 400);
-	}));
-
-	it("不正なrenote対象IDで怒られる", async(async () => {
-		const post = {
-			renoteId: "foo",
-		};
-		const res = await request("/notes/create", post, alice);
-		assert.strictEqual(res.status, 400);
-	}));
-
-	it("存在しないユーザーにメンションできる", async(async () => {
-		const post = {
-			text: "@ghost yo",
-		};
-
-		const res = await request("/notes/create", post, alice);
-
-		assert.strictEqual(res.status, 200);
-		assert.strictEqual(
-			typeof res.body === "object" && !Array.isArray(res.body),
-			true,
-		);
-		assert.strictEqual(res.body.createdNote.text, post.text);
-	}));
-
-	it("同じユーザーに複数メンションしても内部的にまとめられる", async(async () => {
-		const post = {
-			text: "@bob @bob @bob yo",
-		};
-
-		const res = await request("/notes/create", post, alice);
-
-		assert.strictEqual(res.status, 200);
-		assert.strictEqual(
-			typeof res.body === "object" && !Array.isArray(res.body),
-			true,
-		);
-		assert.strictEqual(res.body.createdNote.text, post.text);
-
-		const noteDoc = await Notes.findOneBy({ id: res.body.createdNote.id });
-		assert.deepStrictEqual(noteDoc.mentions, [bob.id]);
-	}));
-
-	describe("notes/create", () => {
-		it("投票を添付できる", async(async () => {
-			const res = await request(
-				"/notes/create",
-				{
-					text: "test",
-					poll: {
-						choices: ["foo", "bar"],
-					},
-				},
-				alice,
-			);
-
-			assert.strictEqual(res.status, 200);
-			assert.strictEqual(
-				typeof res.body === "object" && !Array.isArray(res.body),
-				true,
-			);
-			assert.strictEqual(res.body.createdNote.poll != null, true);
-		}));
-
-		it("投票の選択肢が無くて怒られる", async(async () => {
-			const res = await request(
-				"/notes/create",
-				{
-					poll: {},
-				},
-				alice,
-			);
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it("投票の選択肢が無くて怒られる (空の配列)", async(async () => {
-			const res = await request(
-				"/notes/create",
-				{
-					poll: {
-						choices: [],
-					},
-				},
-				alice,
-			);
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it("投票の選択肢が1つで怒られる", async(async () => {
-			const res = await request(
-				"/notes/create",
-				{
-					poll: {
-						choices: ["Strawberry Pasta"],
-					},
-				},
-				alice,
-			);
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it("投票できる", async(async () => {
-			const { body } = await request(
-				"/notes/create",
-				{
-					text: "test",
-					poll: {
-						choices: ["sakura", "izumi", "ako"],
-					},
-				},
-				alice,
-			);
-
-			const res = await request(
-				"/notes/polls/vote",
-				{
-					noteId: body.createdNote.id,
-					choice: 1,
-				},
-				alice,
-			);
-
-			assert.strictEqual(res.status, 204);
-		}));
-
-		it("複数投票できない", async(async () => {
-			const { body } = await request(
-				"/notes/create",
-				{
-					text: "test",
-					poll: {
-						choices: ["sakura", "izumi", "ako"],
-					},
-				},
-				alice,
-			);
-
-			await request(
-				"/notes/polls/vote",
-				{
-					noteId: body.createdNote.id,
-					choice: 0,
-				},
-				alice,
-			);
-
-			const res = await request(
-				"/notes/polls/vote",
-				{
-					noteId: body.createdNote.id,
-					choice: 2,
-				},
-				alice,
-			);
-
-			assert.strictEqual(res.status, 400);
-		}));
-
-		it("許可されている場合は複数投票できる", async(async () => {
-			const { body } = await request(
-				"/notes/create",
-				{
-					text: "test",
-					poll: {
-						choices: ["sakura", "izumi", "ako"],
-						multiple: true,
-					},
-				},
-				alice,
-			);
-
-			await request(
-				"/notes/polls/vote",
-				{
-					noteId: body.createdNote.id,
-					choice: 0,
-				},
-				alice,
-			);
-
-			await request(
-				"/notes/polls/vote",
-				{
-					noteId: body.createdNote.id,
-					choice: 1,
-				},
-				alice,
-			);
-
-			const res = await request(
-				"/notes/polls/vote",
-				{
-					noteId: body.createdNote.id,
-					choice: 2,
-				},
-				alice,
-			);
-
-			assert.strictEqual(res.status, 204);
-		}));
-
-		it("締め切られている場合は投票できない", async(async () => {
-			const { body } = await request(
-				"/notes/create",
-				{
-					text: "test",
-					poll: {
-						choices: ["sakura", "izumi", "ako"],
-						expiredAfter: 1,
-					},
-				},
-				alice,
-			);
-
-			await new Promise((x) => setTimeout(x, 2));
-
-			const res = await request(
-				"/notes/polls/vote",
-				{
-					noteId: body.createdNote.id,
-					choice: 1,
-				},
-				alice,
-			);
-
-			assert.strictEqual(res.status, 400);
-		}));
-	});
-
-	describe("notes/delete", () => {
-		it("delete a reply", async(async () => {
-			const mainNoteRes = await api(
-				"notes/create",
-				{
-					text: "main post",
-				},
-				alice,
-			);
-			const replyOneRes = await api(
-				"notes/create",
-				{
-					text: "reply one",
-					replyId: mainNoteRes.body.createdNote.id,
-				},
-				alice,
-			);
-			const replyTwoRes = await api(
-				"notes/create",
-				{
-					text: "reply two",
-					replyId: mainNoteRes.body.createdNote.id,
-				},
-				alice,
-			);
-
-			const deleteOneRes = await api(
-				"notes/delete",
-				{
-					noteId: replyOneRes.body.createdNote.id,
-				},
-				alice,
-			);
-
-			assert.strictEqual(deleteOneRes.status, 204);
-			let mainNote = await Notes.findOneBy({
-				id: mainNoteRes.body.createdNote.id,
-			});
-			assert.strictEqual(mainNote.repliesCount, 1);
-
-			const deleteTwoRes = await api(
-				"notes/delete",
-				{
-					noteId: replyTwoRes.body.createdNote.id,
-				},
-				alice,
-			);
-
-			assert.strictEqual(deleteTwoRes.status, 204);
-			mainNote = await Notes.findOneBy({ id: mainNoteRes.body.createdNote.id });
-			assert.strictEqual(mainNote.repliesCount, 0);
-		}));
-	});
-});
diff --git a/packages/backend/test/prelude/maybe.ts b/packages/backend/test/prelude/maybe.ts
deleted file mode 100644
index df589981c3..0000000000
--- a/packages/backend/test/prelude/maybe.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import * as assert from "assert";
-import { just, nothing } from "../../src/prelude/maybe.js";
-
-describe("just", () => {
-	it("has a value", () => {
-		assert.deepStrictEqual(just(3).isJust(), true);
-	});
-
-	it("has the inverse called get", () => {
-		assert.deepStrictEqual(just(3).get(), 3);
-	});
-});
-
-describe("nothing", () => {
-	it("has no value", () => {
-		assert.deepStrictEqual(nothing().isJust(), false);
-	});
-});
diff --git a/packages/backend/test/prelude/url.ts b/packages/backend/test/prelude/url.ts
deleted file mode 100644
index 5d08ff8924..0000000000
--- a/packages/backend/test/prelude/url.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import * as assert from "assert";
-import { query } from "../../src/prelude/url.js";
-
-describe("url", () => {
-	it("query", () => {
-		const s = query({
-			foo: "ふぅ",
-			bar: "b a r",
-			baz: undefined,
-		});
-		assert.deepStrictEqual(s, "foo=%E3%81%B5%E3%81%85&bar=b%20a%20r");
-	});
-});
diff --git a/packages/backend/test/reaction-lib.ts b/packages/backend/test/reaction-lib.ts
deleted file mode 100644
index 7c61dc76c2..0000000000
--- a/packages/backend/test/reaction-lib.ts
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
-import * as assert from 'assert';
-
-import { toDbReaction } from '../src/misc/reaction-lib.js';
-
-describe('toDbReaction', async () => {
-	it('既存の文字列リアクションはそのまま', async () => {
-		assert.strictEqual(await toDbReaction('like'), 'like');
-	});
-
-	it('Unicodeプリンは寿司化不能とするため文字列化しない', async () => {
-		assert.strictEqual(await toDbReaction('🍮'), '🍮');
-	});
-
-	it('プリン以外の既存のリアクションは文字列化する like', async () => {
-		assert.strictEqual(await toDbReaction('👍'), 'like');
-	});
-
-	it('プリン以外の既存のリアクションは文字列化する love', async () => {
-		assert.strictEqual(await toDbReaction('❤️'), 'love');
-	});
-
-	it('プリン以外の既存のリアクションは文字列化する love 異体字セレクタなし', async () => {
-		assert.strictEqual(await toDbReaction('❤'), 'love');
-	});
-
-	it('プリン以外の既存のリアクションは文字列化する laugh', async () => {
-		assert.strictEqual(await toDbReaction('😆'), 'laugh');
-	});
-
-	it('プリン以外の既存のリアクションは文字列化する hmm', async () => {
-		assert.strictEqual(await toDbReaction('🤔'), 'hmm');
-	});
-
-	it('プリン以外の既存のリアクションは文字列化する surprise', async () => {
-		assert.strictEqual(await toDbReaction('😮'), 'surprise');
-	});
-
-	it('プリン以外の既存のリアクションは文字列化する congrats', async () => {
-		assert.strictEqual(await toDbReaction('🎉'), 'congrats');
-	});
-
-	it('プリン以外の既存のリアクションは文字列化する angry', async () => {
-		assert.strictEqual(await toDbReaction('💢'), 'angry');
-	});
-
-	it('プリン以外の既存のリアクションは文字列化する confused', async () => {
-		assert.strictEqual(await toDbReaction('😥'), 'confused');
-	});
-
-	it('プリン以外の既存のリアクションは文字列化する rip', async () => {
-		assert.strictEqual(await toDbReaction('😇'), 'rip');
-	});
-
-	it('それ以外はUnicodeのまま', async () => {
-		assert.strictEqual(await toDbReaction('🍅'), '🍅');
-	});
-
-	it('異体字セレクタ除去', async () => {
-		assert.strictEqual(await toDbReaction('㊗️'), '㊗');
-	});
-
-	it('異体字セレクタ除去 必要なし', async () => {
-		assert.strictEqual(await toDbReaction('㊗'), '㊗');
-	});
-
-	it('fallback - undefined', async () => {
-		assert.strictEqual(await toDbReaction(undefined), 'like');
-	});
-
-	it('fallback - null', async () => {
-		assert.strictEqual(await toDbReaction(null), 'like');
-	});
-
-	it('fallback - empty', async () => {
-		assert.strictEqual(await toDbReaction(''), 'like');
-	});
-
-	it('fallback - unknown', async () => {
-		assert.strictEqual(await toDbReaction('unknown'), 'like');
-	});
-});
-*/
diff --git a/packages/backend/test/resources/25000x25000.png b/packages/backend/test/resources/25000x25000.png
deleted file mode 100644
index 0ed4666925f715eca6fdd9831206ec478b304047..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 75933
zcmeI&y-HhQ0LS6?cp^w3Q3pW{loTAi19gy^5<dbWp(JZ#F2HLr7#s>6yo);7$+;8+
za|eD*p>uJ_kV$%)H+S*EbKrb%&T{_G{QK5EJFb*B%OQkH>!kT5g#K+jvwZeu@?r1m
z?3TArJBLM4{CKF1Lbly)H5;AvjlaLMZ1!<*^Y7=|(!%V?L4W`O0t5&UAV7cs0RjXF
z5FkK+009C72oNAZfB*pk1PCN8FnAf}F$M_r;_0Z}br2vxfB*pk1PBlyK!5-N0t5&U
zAV7cs0RjXF5FkK+009E23-p((rPu-t-g~u1>SO#r0RjXF5FkK+009C72oNAZfB*pk
z1PBlyK!5-N0t5&UAke+u-(86<K$u)!lz0#zK!5-N0t5&UAV7cs0RjXF5FkK+009C7
z2oNAZfB*pk$qTGa#|QHkU{u_%c9NfC009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs
z0RjXF5Fqe8%(EB+)QhL1HVy&=2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkJx
zd4c|NwG>-`!F#XPNPdk01PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfWY<s
z?n-O{!sPOzgo6M90t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBmFUSMrHKA5)v
zqvC$Gll&Y52oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+0D;$Gz7S)8k40~1
lYhDGo5FkK+009DN3w&SvbrQ12Pmh1%j@IE>^X~Kc)qni7KGgsK

diff --git a/packages/backend/test/resources/Lenna.jpg b/packages/backend/test/resources/Lenna.jpg
deleted file mode 100644
index 6b5b32281c1ffd5893d23392169cc368d72e0823..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 25360
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
Ho3H=b#ca3`

diff --git a/packages/backend/test/resources/Lenna.png b/packages/backend/test/resources/Lenna.png
deleted file mode 100644
index 59ef68aabd033341028ccd2b1f6c5871c02b9d7b..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 473831
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%0DQ2q
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%0D|;N;<J*lwi4yXsNUNdt*xTB-@gNS3&V
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
B<?sLi

diff --git a/packages/backend/test/resources/anime.gif b/packages/backend/test/resources/anime.gif
deleted file mode 100644
index 256ba495ce11b5f1ec7649c739feb750844eb4df..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 2248
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
W2~9|w)0}XH4ipRvSICP30028Jj!=I9

diff --git a/packages/backend/test/resources/anime.png b/packages/backend/test/resources/anime.png
deleted file mode 100644
index f13600f7a49951d0bd67cd0c8c34c06379b6a4cf..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 1868
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
MpCIp+qtr{k0MoP{oB#j-

diff --git a/packages/backend/test/resources/emptyfile b/packages/backend/test/resources/emptyfile
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/packages/backend/test/resources/image.svg b/packages/backend/test/resources/image.svg
deleted file mode 100644
index 1e2bf5b5bb..0000000000
--- a/packages/backend/test/resources/image.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256"><path fill="#FF40A4" d="M128 80c-16 4-20 24-20 48v16c0 8-8 16-20.3 8 4.3 20 24.3 28 40.3 24s20-24 20-48v-16c0-8 8-16 20.3-8C164 84 144 76 128 80"/><path fill="#FFBF40" d="M192 80c-16 4-20 24-20 48v16c0 8-8 16-20.3 8 4.3 20 24.3 28 40.3 24s20-24 20-48v-16c0-8 8-16 20.3-8C228 84 208 76 192 80"/><path fill="#408EFF" d="M64 80c-16 4-20 24-20 48v16c0 8-8 16-20.3 8C28 172 48 180 64 176s20-24 20-48v-16c0-8 8-16 20.3-8C100 84 80 76 64 80"/></svg>
diff --git a/packages/backend/test/resources/rotate.jpg b/packages/backend/test/resources/rotate.jpg
deleted file mode 100644
index 477c2baf5bbd0039dc08fa36e3d4b3cd5d39ecb9..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 12624
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

diff --git a/packages/backend/test/resources/with-alpha.png b/packages/backend/test/resources/with-alpha.png
deleted file mode 100644
index adc8d01805dbcf1bf38f506096b99bc157f25de5..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 3772
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
Gh5idy2NOjA

diff --git a/packages/backend/test/resources/with-xml-def.svg b/packages/backend/test/resources/with-xml-def.svg
deleted file mode 100644
index 90971215a6..0000000000
--- a/packages/backend/test/resources/with-xml-def.svg
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256"><path fill="#FF40A4" d="M128 80c-16 4-20 24-20 48v16c0 8-8 16-20.3 8 4.3 20 24.3 28 40.3 24s20-24 20-48v-16c0-8 8-16 20.3-8C164 84 144 76 128 80"/><path fill="#FFBF40" d="M192 80c-16 4-20 24-20 48v16c0 8-8 16-20.3 8 4.3 20 24.3 28 40.3 24s20-24 20-48v-16c0-8 8-16 20.3-8C228 84 208 76 192 80"/><path fill="#408EFF" d="M64 80c-16 4-20 24-20 48v16c0 8-8 16-20.3 8C28 172 48 180 64 176s20-24 20-48v-16c0-8 8-16 20.3-8C100 84 80 76 64 80"/></svg>
diff --git a/packages/backend/test/streaming.ts b/packages/backend/test/streaming.ts
deleted file mode 100644
index 3292c66e17..0000000000
--- a/packages/backend/test/streaming.ts
+++ /dev/null
@@ -1,766 +0,0 @@
-process.env.NODE_ENV = "test";
-
-import * as assert from "assert";
-import * as childProcess from "child_process";
-import { Following } from "../src/models/entities/following.js";
-import {
-	connectStream,
-	signup,
-	api,
-	post,
-	startServer,
-	shutdownServer,
-	initTestDb,
-	waitFire,
-} from "./utils.js";
-
-describe("Streaming", () => {
-	let p: childProcess.ChildProcess;
-	let Followings: any;
-
-	const follow = async (follower: any, followee: any) => {
-		await Followings.save({
-			id: "a",
-			createdAt: new Date(),
-			followerId: follower.id,
-			followeeId: followee.id,
-			followerHost: follower.host,
-			followerInbox: null,
-			followerSharedInbox: null,
-			followeeHost: followee.host,
-			followeeInbox: null,
-			followeeSharedInbox: null,
-		});
-	};
-
-	describe("Streaming", () => {
-		// Local users
-		let ayano: any;
-		let kyoko: any;
-		let chitose: any;
-
-		// Remote users
-		let akari: any;
-		let chinatsu: any;
-
-		let kyokoNote: any;
-		let list: any;
-
-		before(async () => {
-			p = await startServer();
-			const connection = await initTestDb(true);
-			Followings = connection.getRepository(Following);
-
-			ayano = await signup({ username: "ayano" });
-			kyoko = await signup({ username: "kyoko" });
-			chitose = await signup({ username: "chitose" });
-
-			akari = await signup({ username: "akari", host: "example.com" });
-			chinatsu = await signup({ username: "chinatsu", host: "example.com" });
-
-			kyokoNote = await post(kyoko, { text: "foo" });
-
-			// Follow: ayano => kyoko
-			await api("following/create", { userId: kyoko.id }, ayano);
-
-			// Follow: ayano => akari
-			await follow(ayano, akari);
-
-			// List: chitose => ayano, kyoko
-			list = await api(
-				"users/lists/create",
-				{
-					name: "my list",
-				},
-				chitose,
-			).then((x) => x.body);
-
-			await api(
-				"users/lists/push",
-				{
-					listId: list.id,
-					userId: ayano.id,
-				},
-				chitose,
-			);
-
-			await api(
-				"users/lists/push",
-				{
-					listId: list.id,
-					userId: kyoko.id,
-				},
-				chitose,
-			);
-		});
-
-		after(async () => {
-			await shutdownServer(p);
-		});
-
-		describe("Events", () => {
-			it("mention event", async () => {
-				const fired = await waitFire(
-					kyoko,
-					"main", // kyoko:main
-					() => post(ayano, { text: "foo @kyoko bar" }), // ayano mention => kyoko
-					(msg) => msg.type === "mention" && msg.body.userId === ayano.id, // wait ayano
-				);
-
-				assert.strictEqual(fired, true);
-			});
-
-			it("renote event", async () => {
-				const fired = await waitFire(
-					kyoko,
-					"main", // kyoko:main
-					() => post(ayano, { renoteId: kyokoNote.id }), // ayano renote
-					(msg) => msg.type === "renote" && msg.body.renoteId === kyokoNote.id, // wait renote
-				);
-
-				assert.strictEqual(fired, true);
-			});
-		});
-
-		describe("Home Timeline", () => {
-			it("自分の投稿が流れる", async () => {
-				const fired = await waitFire(
-					ayano,
-					"homeTimeline", // ayano:Home
-					() => api("notes/create", { text: "foo" }, ayano), // ayano posts
-					(msg) => msg.type === "note" && msg.body.text === "foo",
-				);
-
-				assert.strictEqual(fired, true);
-			});
-
-			it("フォローしているユーザーの投稿が流れる", async () => {
-				const fired = await waitFire(
-					ayano,
-					"homeTimeline", // ayano:home
-					() => api("notes/create", { text: "foo" }, kyoko), // kyoko posts
-					(msg) => msg.type === "note" && msg.body.userId === kyoko.id, // wait kyoko
-				);
-
-				assert.strictEqual(fired, true);
-			});
-
-			it("フォローしていないユーザーの投稿は流れない", async () => {
-				const fired = await waitFire(
-					kyoko,
-					"homeTimeline", // kyoko:home
-					() => api("notes/create", { text: "foo" }, ayano), // ayano posts
-					(msg) => msg.type === "note" && msg.body.userId === ayano.id, // wait ayano
-				);
-
-				assert.strictEqual(fired, false);
-			});
-
-			it("フォローしているユーザーのダイレクト投稿が流れる", async () => {
-				const fired = await waitFire(
-					ayano,
-					"homeTimeline", // ayano:home
-					() =>
-						api(
-							"notes/create",
-							{
-								text: "foo",
-								visibility: "specified",
-								visibleUserIds: [ayano.id],
-							},
-							kyoko,
-						), // kyoko dm => ayano
-					(msg) => msg.type === "note" && msg.body.userId === kyoko.id, // wait kyoko
-				);
-
-				assert.strictEqual(fired, true);
-			});
-
-			it("フォローしているユーザーでも自分が指定されていないダイレクト投稿は流れない", async () => {
-				const fired = await waitFire(
-					ayano,
-					"homeTimeline", // ayano:home
-					() =>
-						api(
-							"notes/create",
-							{
-								text: "foo",
-								visibility: "specified",
-								visibleUserIds: [chitose.id],
-							},
-							kyoko,
-						), // kyoko dm => chitose
-					(msg) => msg.type === "note" && msg.body.userId === kyoko.id, // wait kyoko
-				);
-
-				assert.strictEqual(fired, false);
-			});
-		}); // Home
-
-		describe("Local Timeline", () => {
-			it("自分の投稿が流れる", async () => {
-				const fired = await waitFire(
-					ayano,
-					"localTimeline", // ayano:Local
-					() => api("notes/create", { text: "foo" }, ayano), // ayano posts
-					(msg) => msg.type === "note" && msg.body.text === "foo",
-				);
-
-				assert.strictEqual(fired, true);
-			});
-
-			it("フォローしていないローカルユーザーの投稿が流れる", async () => {
-				const fired = await waitFire(
-					ayano,
-					"localTimeline", // ayano:Local
-					() => api("notes/create", { text: "foo" }, chitose), // chitose posts
-					(msg) => msg.type === "note" && msg.body.userId === chitose.id, // wait chitose
-				);
-
-				assert.strictEqual(fired, true);
-			});
-
-			it("リモートユーザーの投稿は流れない", async () => {
-				const fired = await waitFire(
-					ayano,
-					"localTimeline", // ayano:Local
-					() => api("notes/create", { text: "foo" }, chinatsu), // chinatsu posts
-					(msg) => msg.type === "note" && msg.body.userId === chinatsu.id, // wait chinatsu
-				);
-
-				assert.strictEqual(fired, false);
-			});
-
-			it("フォローしてたとしてもリモートユーザーの投稿は流れない", async () => {
-				const fired = await waitFire(
-					ayano,
-					"localTimeline", // ayano:Local
-					() => api("notes/create", { text: "foo" }, akari), // akari posts
-					(msg) => msg.type === "note" && msg.body.userId === akari.id, // wait akari
-				);
-
-				assert.strictEqual(fired, false);
-			});
-
-			it("ホーム指定の投稿は流れない", async () => {
-				const fired = await waitFire(
-					ayano,
-					"localTimeline", // ayano:Local
-					() => api("notes/create", { text: "foo", visibility: "home" }, kyoko), // kyoko home posts
-					(msg) => msg.type === "note" && msg.body.userId === kyoko.id, // wait kyoko
-				);
-
-				assert.strictEqual(fired, false);
-			});
-
-			it("フォローしているローカルユーザーのダイレクト投稿は流れない", async () => {
-				const fired = await waitFire(
-					ayano,
-					"localTimeline", // ayano:Local
-					() =>
-						api(
-							"notes/create",
-							{
-								text: "foo",
-								visibility: "specified",
-								visibleUserIds: [ayano.id],
-							},
-							kyoko,
-						), // kyoko DM => ayano
-					(msg) => msg.type === "note" && msg.body.userId === kyoko.id, // wait kyoko
-				);
-
-				assert.strictEqual(fired, false);
-			});
-
-			it("フォローしていないローカルユーザーのフォロワー宛て投稿は流れない", async () => {
-				const fired = await waitFire(
-					ayano,
-					"localTimeline", // ayano:Local
-					() =>
-						api(
-							"notes/create",
-							{ text: "foo", visibility: "followers" },
-							chitose,
-						),
-					(msg) => msg.type === "note" && msg.body.userId === chitose.id, // wait chitose
-				);
-
-				assert.strictEqual(fired, false);
-			});
-		});
-
-		describe("Recommended Timeline", () => {
-			it("自分の投稿が流れる", async () => {
-				const fired = await waitFire(
-					ayano,
-					"recommendedTimeline", // ayano:Local
-					() => api("notes/create", { text: "foo" }, ayano), // ayano posts
-					(msg) => msg.type === "note" && msg.body.text === "foo",
-				);
-
-				assert.strictEqual(fired, true);
-			});
-
-			it("フォローしていないローカルユーザーの投稿が流れる", async () => {
-				const fired = await waitFire(
-					ayano,
-					"recommendedTimeline", // ayano:Local
-					() => api("notes/create", { text: "foo" }, chitose), // chitose posts
-					(msg) => msg.type === "note" && msg.body.userId === chitose.id, // wait chitose
-				);
-
-				assert.strictEqual(fired, true);
-			});
-
-			it("リモートユーザーの投稿は流れない", async () => {
-				const fired = await waitFire(
-					ayano,
-					"recommendedTimeline", // ayano:Local
-					() => api("notes/create", { text: "foo" }, chinatsu), // chinatsu posts
-					(msg) => msg.type === "note" && msg.body.userId === chinatsu.id, // wait chinatsu
-				);
-
-				assert.strictEqual(fired, false);
-			});
-
-			it("フォローしてたとしてもリモートユーザーの投稿は流れない", async () => {
-				const fired = await waitFire(
-					ayano,
-					"recommendedTimeline", // ayano:Local
-					() => api("notes/create", { text: "foo" }, akari), // akari posts
-					(msg) => msg.type === "note" && msg.body.userId === akari.id, // wait akari
-				);
-
-				assert.strictEqual(fired, false);
-			});
-
-			it("ホーム指定の投稿は流れない", async () => {
-				const fired = await waitFire(
-					ayano,
-					"recommendedTimeline", // ayano:Local
-					() => api("notes/create", { text: "foo", visibility: "home" }, kyoko), // kyoko home posts
-					(msg) => msg.type === "note" && msg.body.userId === kyoko.id, // wait kyoko
-				);
-
-				assert.strictEqual(fired, false);
-			});
-
-			it("フォローしているローカルユーザーのダイレクト投稿は流れない", async () => {
-				const fired = await waitFire(
-					ayano,
-					"recommendedTimeline", // ayano:Local
-					() =>
-						api(
-							"notes/create",
-							{
-								text: "foo",
-								visibility: "specified",
-								visibleUserIds: [ayano.id],
-							},
-							kyoko,
-						), // kyoko DM => ayano
-					(msg) => msg.type === "note" && msg.body.userId === kyoko.id, // wait kyoko
-				);
-
-				assert.strictEqual(fired, false);
-			});
-
-			it("フォローしていないローカルユーザーのフォロワー宛て投稿は流れない", async () => {
-				const fired = await waitFire(
-					ayano,
-					"recommendedTimeline", // ayano:Local
-					() =>
-						api(
-							"notes/create",
-							{ text: "foo", visibility: "followers" },
-							chitose,
-						),
-					(msg) => msg.type === "note" && msg.body.userId === chitose.id, // wait chitose
-				);
-
-				assert.strictEqual(fired, false);
-			});
-		});
-
-		describe("Hybrid Timeline", () => {
-			it("自分の投稿が流れる", async () => {
-				const fired = await waitFire(
-					ayano,
-					"hybridTimeline", // ayano:Hybrid
-					() => api("notes/create", { text: "foo" }, ayano), // ayano posts
-					(msg) => msg.type === "note" && msg.body.text === "foo",
-				);
-
-				assert.strictEqual(fired, true);
-			});
-
-			it("フォローしていないローカルユーザーの投稿が流れる", async () => {
-				const fired = await waitFire(
-					ayano,
-					"hybridTimeline", // ayano:Hybrid
-					() => api("notes/create", { text: "foo" }, chitose), // chitose posts
-					(msg) => msg.type === "note" && msg.body.userId === chitose.id, // wait chitose
-				);
-
-				assert.strictEqual(fired, true);
-			});
-
-			it("フォローしているリモートユーザーの投稿が流れる", async () => {
-				const fired = await waitFire(
-					ayano,
-					"hybridTimeline", // ayano:Hybrid
-					() => api("notes/create", { text: "foo" }, akari), // akari posts
-					(msg) => msg.type === "note" && msg.body.userId === akari.id, // wait akari
-				);
-
-				assert.strictEqual(fired, true);
-			});
-
-			it("フォローしていないリモートユーザーの投稿は流れない", async () => {
-				const fired = await waitFire(
-					ayano,
-					"hybridTimeline", // ayano:Hybrid
-					() => api("notes/create", { text: "foo" }, chinatsu), // chinatsu posts
-					(msg) => msg.type === "note" && msg.body.userId === chinatsu.id, // wait chinatsu
-				);
-
-				assert.strictEqual(fired, false);
-			});
-
-			it("フォローしているユーザーのダイレクト投稿が流れる", async () => {
-				const fired = await waitFire(
-					ayano,
-					"hybridTimeline", // ayano:Hybrid
-					() =>
-						api(
-							"notes/create",
-							{
-								text: "foo",
-								visibility: "specified",
-								visibleUserIds: [ayano.id],
-							},
-							kyoko,
-						),
-					(msg) => msg.type === "note" && msg.body.userId === kyoko.id, // wait kyoko
-				);
-
-				assert.strictEqual(fired, true);
-			});
-
-			it("フォローしているユーザーのホーム投稿が流れる", async () => {
-				const fired = await waitFire(
-					ayano,
-					"hybridTimeline", // ayano:Hybrid
-					() => api("notes/create", { text: "foo", visibility: "home" }, kyoko),
-					(msg) => msg.type === "note" && msg.body.userId === kyoko.id, // wait kyoko
-				);
-
-				assert.strictEqual(fired, true);
-			});
-
-			it("フォローしていないローカルユーザーのホーム投稿は流れない", async () => {
-				const fired = await waitFire(
-					ayano,
-					"hybridTimeline", // ayano:Hybrid
-					() =>
-						api("notes/create", { text: "foo", visibility: "home" }, chitose),
-					(msg) => msg.type === "note" && msg.body.userId === chitose.id,
-				);
-
-				assert.strictEqual(fired, false);
-			});
-
-			it("フォローしていないローカルユーザーのフォロワー宛て投稿は流れない", () =>
-				async () => {
-					const fired = await waitFire(
-						ayano,
-						"hybridTimeline", // ayano:Hybrid
-						() =>
-							api(
-								"notes/create",
-								{ text: "foo", visibility: "followers" },
-								chitose,
-							),
-						(msg) => msg.type === "note" && msg.body.userId === chitose.id,
-					);
-
-					assert.strictEqual(fired, false);
-				});
-		});
-
-		describe("Global Timeline", () => {
-			it("フォローしていないローカルユーザーの投稿が流れる", () => async () => {
-				const fired = await waitFire(
-					ayano,
-					"globalTimeline", // ayano:Global
-					() => api("notes/create", { text: "foo" }, chitose), // chitose posts
-					(msg) => msg.type === "note" && msg.body.userId === chitose.id, // wait chitose
-				);
-
-				assert.strictEqual(fired, true);
-			});
-
-			it("フォローしていないリモートユーザーの投稿が流れる", () => async () => {
-				const fired = await waitFire(
-					ayano,
-					"globalTimeline", // ayano:Global
-					() => api("notes/create", { text: "foo" }, chinatsu), // chinatsu posts
-					(msg) => msg.type === "note" && msg.body.userId === chinatsu.id, // wait chinatsu
-				);
-
-				assert.strictEqual(fired, true);
-			});
-
-			it("ホーム投稿は流れない", () => async () => {
-				const fired = await waitFire(
-					ayano,
-					"globalTimeline", // ayano:Global
-					() => api("notes/create", { text: "foo", visibility: "home" }, kyoko), // kyoko posts
-					(msg) => msg.type === "note" && msg.body.userId === kyoko.id, // wait kyoko
-				);
-
-				assert.strictEqual(fired, false);
-			});
-		});
-
-		describe("UserList Timeline", () => {
-			it("リストに入れているユーザーの投稿が流れる", () => async () => {
-				const fired = await waitFire(
-					chitose,
-					"userList",
-					() => api("notes/create", { text: "foo" }, ayano),
-					(msg) => msg.type === "note" && msg.body.userId === ayano.id,
-					{ listId: list.id },
-				);
-
-				assert.strictEqual(fired, true);
-			});
-
-			it("リストに入れていないユーザーの投稿は流れない", () => async () => {
-				const fired = await waitFire(
-					chitose,
-					"userList",
-					() => api("notes/create", { text: "foo" }, chinatsu),
-					(msg) => msg.type === "note" && msg.body.userId === chinatsu.id,
-					{ listId: list.id },
-				);
-
-				assert.strictEqual(fired, false);
-			});
-
-			// #4471
-			it("リストに入れているユーザーのダイレクト投稿が流れる", () =>
-				async () => {
-					const fired = await waitFire(
-						chitose,
-						"userList",
-						() =>
-							api(
-								"notes/create",
-								{
-									text: "foo",
-									visibility: "specified",
-									visibleUserIds: [chitose.id],
-								},
-								ayano,
-							),
-						(msg) => msg.type === "note" && msg.body.userId === ayano.id,
-						{ listId: list.id },
-					);
-
-					assert.strictEqual(fired, true);
-				});
-
-			// #4335
-			it("リストに入れているがフォローはしてないユーザーのフォロワー宛て投稿は流れない", () =>
-				async () => {
-					const fired = await waitFire(
-						chitose,
-						"userList",
-						() =>
-							api(
-								"notes/create",
-								{ text: "foo", visibility: "followers" },
-								kyoko,
-							),
-						(msg) => msg.type === "note" && msg.body.userId === kyoko.id,
-						{ listId: list.id },
-					);
-
-					assert.strictEqual(fired, false);
-				});
-		});
-
-		describe("Hashtag Timeline", () => {
-			it("指定したハッシュタグの投稿が流れる", () =>
-				new Promise<void>(async (done) => {
-					const ws = await connectStream(
-						chitose,
-						"hashtag",
-						({ type, body }) => {
-							if (type == "note") {
-								assert.deepStrictEqual(body.text, "#foo");
-								ws.close();
-								done();
-							}
-						},
-						{
-							q: [["foo"]],
-						},
-					);
-
-					post(chitose, {
-						text: "#foo",
-					});
-				}));
-
-			it("指定したハッシュタグの投稿が流れる (AND)", () =>
-				new Promise<void>(async (done) => {
-					let fooCount = 0;
-					let barCount = 0;
-					let fooBarCount = 0;
-
-					const ws = await connectStream(
-						chitose,
-						"hashtag",
-						({ type, body }) => {
-							if (type == "note") {
-								if (body.text === "#foo") fooCount++;
-								if (body.text === "#bar") barCount++;
-								if (body.text === "#foo #bar") fooBarCount++;
-							}
-						},
-						{
-							q: [["foo", "bar"]],
-						},
-					);
-
-					post(chitose, {
-						text: "#foo",
-					});
-
-					post(chitose, {
-						text: "#bar",
-					});
-
-					post(chitose, {
-						text: "#foo #bar",
-					});
-
-					setTimeout(() => {
-						assert.strictEqual(fooCount, 0);
-						assert.strictEqual(barCount, 0);
-						assert.strictEqual(fooBarCount, 1);
-						ws.close();
-						done();
-					}, 3000);
-				}));
-
-			it("指定したハッシュタグの投稿が流れる (OR)", () =>
-				new Promise<void>(async (done) => {
-					let fooCount = 0;
-					let barCount = 0;
-					let fooBarCount = 0;
-					let piyoCount = 0;
-
-					const ws = await connectStream(
-						chitose,
-						"hashtag",
-						({ type, body }) => {
-							if (type == "note") {
-								if (body.text === "#foo") fooCount++;
-								if (body.text === "#bar") barCount++;
-								if (body.text === "#foo #bar") fooBarCount++;
-								if (body.text === "#piyo") piyoCount++;
-							}
-						},
-						{
-							q: [["foo"], ["bar"]],
-						},
-					);
-
-					post(chitose, {
-						text: "#foo",
-					});
-
-					post(chitose, {
-						text: "#bar",
-					});
-
-					post(chitose, {
-						text: "#foo #bar",
-					});
-
-					post(chitose, {
-						text: "#piyo",
-					});
-
-					setTimeout(() => {
-						assert.strictEqual(fooCount, 1);
-						assert.strictEqual(barCount, 1);
-						assert.strictEqual(fooBarCount, 1);
-						assert.strictEqual(piyoCount, 0);
-						ws.close();
-						done();
-					}, 3000);
-				}));
-
-			it("指定したハッシュタグの投稿が流れる (AND + OR)", () =>
-				new Promise<void>(async (done) => {
-					let fooCount = 0;
-					let barCount = 0;
-					let fooBarCount = 0;
-					let piyoCount = 0;
-					let waaaCount = 0;
-
-					const ws = await connectStream(
-						chitose,
-						"hashtag",
-						({ type, body }) => {
-							if (type == "note") {
-								if (body.text === "#foo") fooCount++;
-								if (body.text === "#bar") barCount++;
-								if (body.text === "#foo #bar") fooBarCount++;
-								if (body.text === "#piyo") piyoCount++;
-								if (body.text === "#waaa") waaaCount++;
-							}
-						},
-						{
-							q: [["foo", "bar"], ["piyo"]],
-						},
-					);
-
-					post(chitose, {
-						text: "#foo",
-					});
-
-					post(chitose, {
-						text: "#bar",
-					});
-
-					post(chitose, {
-						text: "#foo #bar",
-					});
-
-					post(chitose, {
-						text: "#piyo",
-					});
-
-					post(chitose, {
-						text: "#waaa",
-					});
-
-					setTimeout(() => {
-						assert.strictEqual(fooCount, 0);
-						assert.strictEqual(barCount, 0);
-						assert.strictEqual(fooBarCount, 1);
-						assert.strictEqual(piyoCount, 1);
-						assert.strictEqual(waaaCount, 0);
-						ws.close();
-						done();
-					}, 3000);
-				}));
-		});
-	});
-});
diff --git a/packages/backend/test/thread-mute.ts b/packages/backend/test/thread-mute.ts
deleted file mode 100644
index 9b3bb8dfe4..0000000000
--- a/packages/backend/test/thread-mute.ts
+++ /dev/null
@@ -1,161 +0,0 @@
-process.env.NODE_ENV = "test";
-
-import * as assert from "assert";
-import * as childProcess from "child_process";
-import {
-	async,
-	signup,
-	request,
-	post,
-	react,
-	connectStream,
-	startServer,
-	shutdownServer,
-} from "./utils.js";
-
-describe("Note thread mute", () => {
-	let p: childProcess.ChildProcess;
-
-	let alice: any;
-	let bob: any;
-	let carol: any;
-
-	before(async () => {
-		p = await startServer();
-		alice = await signup({ username: "alice" });
-		bob = await signup({ username: "bob" });
-		carol = await signup({ username: "carol" });
-	});
-
-	after(async () => {
-		await shutdownServer(p);
-	});
-
-	it("notes/mentions にミュートしているスレッドの投稿が含まれない", async(async () => {
-		const bobNote = await post(bob, { text: "@alice @carol root note" });
-		const aliceReply = await post(alice, {
-			replyId: bobNote.id,
-			text: "@bob @carol child note",
-		});
-
-		await request("/notes/thread-muting/create", { noteId: bobNote.id }, alice);
-
-		const carolReply = await post(carol, {
-			replyId: bobNote.id,
-			text: "@bob @alice child note",
-		});
-		const carolReplyWithoutMention = await post(carol, {
-			replyId: aliceReply.id,
-			text: "child note",
-		});
-
-		const res = await request("/notes/mentions", {}, alice);
-
-		assert.strictEqual(res.status, 200);
-		assert.strictEqual(Array.isArray(res.body), true);
-		assert.strictEqual(
-			res.body.some((note: any) => note.id === bobNote.id),
-			false,
-		);
-		assert.strictEqual(
-			res.body.some((note: any) => note.id === carolReply.id),
-			false,
-		);
-		assert.strictEqual(
-			res.body.some((note: any) => note.id === carolReplyWithoutMention.id),
-			false,
-		);
-	}));
-
-	it("ミュートしているスレッドからメンションされても、hasUnreadMentions が true にならない", async(async () => {
-		// 状態リセット
-		await request("/i/read-all-unread-notes", {}, alice);
-
-		const bobNote = await post(bob, { text: "@alice @carol root note" });
-
-		await request("/notes/thread-muting/create", { noteId: bobNote.id }, alice);
-
-		const carolReply = await post(carol, {
-			replyId: bobNote.id,
-			text: "@bob @alice child note",
-		});
-
-		const res = await request("/i", {}, alice);
-
-		assert.strictEqual(res.status, 200);
-		assert.strictEqual(res.body.hasUnreadMentions, false);
-	}));
-
-	it("ミュートしているスレッドからメンションされても、ストリームに unreadMention イベントが流れてこない", () =>
-		new Promise(async (done) => {
-			// 状態リセット
-			await request("/i/read-all-unread-notes", {}, alice);
-
-			const bobNote = await post(bob, { text: "@alice @carol root note" });
-
-			await request(
-				"/notes/thread-muting/create",
-				{ noteId: bobNote.id },
-				alice,
-			);
-
-			let fired = false;
-
-			const ws = await connectStream(alice, "main", async ({ type, body }) => {
-				if (type === "unreadMention") {
-					if (body === bobNote.id) return;
-					fired = true;
-				}
-			});
-
-			const carolReply = await post(carol, {
-				replyId: bobNote.id,
-				text: "@bob @alice child note",
-			});
-
-			setTimeout(() => {
-				assert.strictEqual(fired, false);
-				ws.close();
-				done();
-			}, 5000);
-		}));
-
-	it("i/notifications にミュートしているスレッドの通知が含まれない", async(async () => {
-		const bobNote = await post(bob, { text: "@alice @carol root note" });
-		const aliceReply = await post(alice, {
-			replyId: bobNote.id,
-			text: "@bob @carol child note",
-		});
-
-		await request("/notes/thread-muting/create", { noteId: bobNote.id }, alice);
-
-		const carolReply = await post(carol, {
-			replyId: bobNote.id,
-			text: "@bob @alice child note",
-		});
-		const carolReplyWithoutMention = await post(carol, {
-			replyId: aliceReply.id,
-			text: "child note",
-		});
-
-		const res = await request("/i/notifications", {}, alice);
-
-		assert.strictEqual(res.status, 200);
-		assert.strictEqual(Array.isArray(res.body), true);
-		assert.strictEqual(
-			res.body.some(
-				(notification: any) => notification.note.id === carolReply.id,
-			),
-			false,
-		);
-		assert.strictEqual(
-			res.body.some(
-				(notification: any) =>
-					notification.note.id === carolReplyWithoutMention.id,
-			),
-			false,
-		);
-
-		// NOTE: bobの投稿はスレッドミュート前に行われたため通知に含まれていてもよい
-	}));
-});
diff --git a/packages/backend/test/tsconfig.json b/packages/backend/test/tsconfig.json
deleted file mode 100644
index bc7a9968b5..0000000000
--- a/packages/backend/test/tsconfig.json
+++ /dev/null
@@ -1,41 +0,0 @@
-{
-	"compilerOptions": {
-		"allowJs": true,
-		"noEmitOnError": false,
-		"noImplicitAny": true,
-		"noImplicitReturns": true,
-		"noUnusedParameters": false,
-		"noUnusedLocals": true,
-		"noFallthroughCasesInSwitch": true,
-		"declaration": false,
-		"sourceMap": true,
-		"target": "es2021",
-		"module": "es2020",
-		"moduleResolution": "node",
-		"allowSyntheticDefaultImports": true,
-		"removeComments": false,
-		"noLib": false,
-		"strict": true,
-		"strictNullChecks": true,
-		"strictPropertyInitialization": false,
-		"experimentalDecorators": true,
-		"emitDecoratorMetadata": true,
-		"resolveJsonModule": true,
-		"isolatedModules": true,
-		"baseUrl": "./",
-		"paths": {
-			"@/*": ["../src/*"]
-		},
-		"typeRoots": [
-			"../node_modules/@types",
-			"../src/@types"
-		],
-		"lib": [
-			"esnext"
-		]
-	},
-	"compileOnSave": false,
-	"include": [
-		"./**/*.ts"
-	]
-}
diff --git a/packages/backend/test/user-notes.ts b/packages/backend/test/user-notes.ts
deleted file mode 100644
index 86a541c101..0000000000
--- a/packages/backend/test/user-notes.ts
+++ /dev/null
@@ -1,98 +0,0 @@
-process.env.NODE_ENV = "test";
-
-import * as assert from "assert";
-import * as childProcess from "child_process";
-import {
-	async,
-	signup,
-	request,
-	post,
-	uploadUrl,
-	startServer,
-	shutdownServer,
-} from "./utils.js";
-
-describe("users/notes", () => {
-	let p: childProcess.ChildProcess;
-
-	let alice: any;
-	let jpgNote: any;
-	let pngNote: any;
-	let jpgPngNote: any;
-
-	before(async () => {
-		p = await startServer();
-		alice = await signup({ username: "alice" });
-		const jpg = await uploadUrl(
-			alice,
-			"https://raw.githubusercontent.com/misskey-dev/misskey/develop/packages/backend/test/resources/Lenna.jpg",
-		);
-		const png = await uploadUrl(
-			alice,
-			"https://raw.githubusercontent.com/misskey-dev/misskey/develop/packages/backend/test/resources/Lenna.png",
-		);
-		jpgNote = await post(alice, {
-			fileIds: [jpg.id],
-		});
-		pngNote = await post(alice, {
-			fileIds: [png.id],
-		});
-		jpgPngNote = await post(alice, {
-			fileIds: [jpg.id, png.id],
-		});
-	});
-
-	after(async () => {
-		await shutdownServer(p);
-	});
-
-	it("ファイルタイプ指定 (jpg)", async(async () => {
-		const res = await request(
-			"/users/notes",
-			{
-				userId: alice.id,
-				fileType: ["image/jpeg"],
-			},
-			alice,
-		);
-
-		assert.strictEqual(res.status, 200);
-		assert.strictEqual(Array.isArray(res.body), true);
-		assert.strictEqual(res.body.length, 2);
-		assert.strictEqual(
-			res.body.some((note: any) => note.id === jpgNote.id),
-			true,
-		);
-		assert.strictEqual(
-			res.body.some((note: any) => note.id === jpgPngNote.id),
-			true,
-		);
-	}));
-
-	it("ファイルタイプ指定 (jpg or png)", async(async () => {
-		const res = await request(
-			"/users/notes",
-			{
-				userId: alice.id,
-				fileType: ["image/jpeg", "image/png"],
-			},
-			alice,
-		);
-
-		assert.strictEqual(res.status, 200);
-		assert.strictEqual(Array.isArray(res.body), true);
-		assert.strictEqual(res.body.length, 3);
-		assert.strictEqual(
-			res.body.some((note: any) => note.id === jpgNote.id),
-			true,
-		);
-		assert.strictEqual(
-			res.body.some((note: any) => note.id === pngNote.id),
-			true,
-		);
-		assert.strictEqual(
-			res.body.some((note: any) => note.id === jpgPngNote.id),
-			true,
-		);
-	}));
-});
diff --git a/packages/backend/test/utils.ts b/packages/backend/test/utils.ts
deleted file mode 100644
index f3f68b2609..0000000000
--- a/packages/backend/test/utils.ts
+++ /dev/null
@@ -1,403 +0,0 @@
-import * as fs from "node:fs";
-import * as path from "node:path";
-import { fileURLToPath } from "node:url";
-import { dirname } from "node:path";
-import * as childProcess from "child_process";
-import * as http from "node:http";
-import { SIGKILL } from "constants";
-import WebSocket from "ws";
-import * as misskey from "calckey-js";
-import fetch from "node-fetch";
-import FormData from "form-data";
-import { DataSource } from "typeorm";
-import loadConfig from "../src/config/load.js";
-import { entities } from "../src/db/postgre.js";
-import got from "got";
-
-const _filename = fileURLToPath(import.meta.url);
-const _dirname = dirname(_filename);
-
-const config = loadConfig();
-export const port = config.port;
-
-export const async = (fn: Function) => (done: Function) => {
-	fn().then(
-		() => {
-			done();
-		},
-		(err: Error) => {
-			done(err);
-		},
-	);
-};
-
-export const api = async (endpoint: string, params: any, me?: any) => {
-	endpoint = endpoint.replace(/^\//, "");
-
-	const auth = me
-		? {
-				i: me.token,
-		  }
-		: {};
-
-	const res = await got<string>(`http://localhost:${port}/api/${endpoint}`, {
-		method: "POST",
-		headers: {
-			"Content-Type": "application/json",
-		},
-		body: JSON.stringify(Object.assign(auth, params)),
-		retry: {
-			limit: 0,
-		},
-		hooks: {
-			beforeError: [
-				(error) => {
-					const { response } = error;
-					if (response && response.body) console.warn(response.body);
-					return error;
-				},
-			],
-		},
-	});
-
-	const status = res.statusCode;
-	const body = res.statusCode !== 204 ? await JSON.parse(res.body) : null;
-
-	return {
-		status,
-		body,
-	};
-};
-
-export const request = async (
-	endpoint: string,
-	params: any,
-	me?: any,
-): Promise<{ body: any; status: number }> => {
-	const auth = me
-		? {
-				i: me.token,
-		  }
-		: {};
-
-	const res = await fetch(`http://localhost:${port}/api${endpoint}`, {
-		method: "POST",
-		headers: {
-			"Content-Type": "application/json",
-		},
-		body: JSON.stringify(Object.assign(auth, params)),
-	});
-
-	const status = res.status;
-	const body = res.status !== 204 ? await res.json().catch() : null;
-
-	return {
-		body,
-		status,
-	};
-};
-
-export const signup = async (params?: any): Promise<any> => {
-	const q = Object.assign(
-		{
-			username: "test",
-			password: "test",
-		},
-		params,
-	);
-
-	const res = await api("signup", q);
-
-	return res.body;
-};
-
-export const post = async (
-	user: any,
-	params?: misskey.Endpoints["notes/create"]["req"],
-): Promise<misskey.entities.Note> => {
-	const q = Object.assign(
-		{
-			text: "test",
-		},
-		params,
-	);
-
-	const res = await api("notes/create", q, user);
-
-	return res.body ? res.body.createdNote : null;
-};
-
-export const react = async (
-	user: any,
-	note: any,
-	reaction: string,
-): Promise<any> => {
-	await api(
-		"notes/reactions/create",
-		{
-			noteId: note.id,
-			reaction: reaction,
-		},
-		user,
-	);
-};
-
-/**
- * Upload file
- * @param user User
- * @param _path Optional, absolute path or relative from ./resources/
- */
-export const uploadFile = async (user: any, _path?: string): Promise<any> => {
-	const absPath =
-		_path == null
-			? `${_dirname}/resources/Lenna.jpg`
-			: path.isAbsolute(_path)
-			? _path
-			: `${_dirname}/resources/${_path}`;
-
-	const formData = new FormData() as any;
-	formData.append("i", user.token);
-	formData.append("file", fs.createReadStream(absPath));
-	formData.append("force", "true");
-
-	const res = await got<string>(
-		`http://localhost:${port}/api/drive/files/create`,
-		{
-			method: "POST",
-			body: formData,
-			retry: {
-				limit: 0,
-			},
-		},
-	);
-
-	const body = res.statusCode !== 204 ? await JSON.parse(res.body) : null;
-
-	return body;
-};
-
-export const uploadUrl = async (user: any, url: string) => {
-	let file: any;
-
-	const ws = await connectStream(user, "main", (msg) => {
-		if (msg.type === "driveFileCreated") {
-			file = msg.body;
-		}
-	});
-
-	await api(
-		"drive/files/upload-from-url",
-		{
-			url,
-			force: true,
-		},
-		user,
-	);
-
-	await sleep(5000);
-	ws.close();
-
-	return file;
-};
-
-export function connectStream(
-	user: any,
-	channel: string,
-	listener: (message: Record<string, any>) => any,
-	params?: any,
-): Promise<WebSocket> {
-	return new Promise((res, rej) => {
-		const ws = new WebSocket(
-			`ws://localhost:${port}/streaming?i=${user.token}`,
-		);
-
-		ws.on("open", () => {
-			ws.on("message", (data) => {
-				const msg = JSON.parse(data.toString());
-				if (msg.type === "channel" && msg.body.id === "a") {
-					listener(msg.body);
-				} else if (msg.type === "connected" && msg.body.id === "a") {
-					res(ws);
-				}
-			});
-
-			ws.send(
-				JSON.stringify({
-					type: "connect",
-					body: {
-						channel: channel,
-						id: "a",
-						pong: true,
-						params: params,
-					},
-				}),
-			);
-		});
-	});
-}
-
-export const waitFire = async (
-	user: any,
-	channel: string,
-	trgr: () => any,
-	cond: (msg: Record<string, any>) => boolean,
-	params?: any,
-) => {
-	return new Promise<boolean>(async (res, rej) => {
-		let timer: NodeJS.Timeout;
-
-		let ws: WebSocket;
-		try {
-			ws = await connectStream(
-				user,
-				channel,
-				(msg) => {
-					if (cond(msg)) {
-						ws.close();
-						if (timer) clearTimeout(timer);
-						res(true);
-					}
-				},
-				params,
-			);
-		} catch (e) {
-			rej(e);
-		}
-
-		if (!ws!) return;
-
-		timer = setTimeout(() => {
-			ws.close();
-			res(false);
-		}, 3000);
-
-		try {
-			await trgr();
-		} catch (e) {
-			ws.close();
-			if (timer) clearTimeout(timer);
-			rej(e);
-		}
-	});
-};
-
-export const simpleGet = async (
-	path: string,
-	accept = "*/*",
-): Promise<{ status?: number; type?: string; location?: string }> => {
-	// node-fetchだと3xxを取れない
-	return await new Promise((resolve, reject) => {
-		const req = http.request(
-			`http://localhost:${port}${path}`,
-			{
-				headers: {
-					Accept: accept,
-				},
-			},
-			(res) => {
-				if (res.statusCode! >= 400) {
-					reject(res);
-				} else {
-					resolve({
-						status: res.statusCode,
-						type: res.headers["content-type"],
-						location: res.headers.location,
-					});
-				}
-			},
-		);
-
-		req.end();
-	});
-};
-
-export function launchServer(
-	callbackSpawnedProcess: (p: childProcess.ChildProcess) => void,
-	moreProcess: () => Promise<void> = async () => {},
-) {
-	return (done: (err?: Error) => any) => {
-		const p = childProcess.spawn("node", [_dirname + "/../index.js"], {
-			stdio: ["inherit", "inherit", "inherit", "ipc"],
-			env: { NODE_ENV: "test", PATH: process.env.PATH },
-		});
-		callbackSpawnedProcess(p);
-		p.on("message", (message) => {
-			if (message === "ok")
-				moreProcess()
-					.then(() => done())
-					.catch((e) => done(e));
-		});
-	};
-}
-
-export async function initTestDb(justBorrow = false, initEntities?: any[]) {
-	if (process.env.NODE_ENV !== "test") throw "NODE_ENV is not a test";
-
-	const db = new DataSource({
-		type: "postgres",
-		host: config.db.host,
-		port: config.db.port,
-		username: config.db.user,
-		password: config.db.pass,
-		database: config.db.db,
-		synchronize: true && !justBorrow,
-		dropSchema: true && !justBorrow,
-		entities: initEntities || entities,
-	});
-
-	await db.initialize();
-
-	return db;
-}
-
-export function startServer(
-	timeout = 60 * 1000,
-): Promise<childProcess.ChildProcess> {
-	return new Promise((res, rej) => {
-		const t = setTimeout(() => {
-			p.kill(SIGKILL);
-			rej("timeout to start");
-		}, timeout);
-
-		const p = childProcess.spawn("node", [_dirname + "/../built/index.js"], {
-			stdio: ["inherit", "inherit", "inherit", "ipc"],
-			env: { NODE_ENV: "test", PATH: process.env.PATH },
-		});
-
-		p.on("error", (e) => rej(e));
-
-		p.on("message", (message) => {
-			if (message === "ok") {
-				clearTimeout(t);
-				res(p);
-			}
-		});
-	});
-}
-
-export function shutdownServer(
-	p: childProcess.ChildProcess,
-	timeout = 20 * 1000,
-) {
-	return new Promise((res, rej) => {
-		const t = setTimeout(() => {
-			p.kill(SIGKILL);
-			res("force exit");
-		}, timeout);
-
-		p.once("exit", () => {
-			clearTimeout(t);
-			res("exited");
-		});
-
-		p.kill();
-	});
-}
-
-export function sleep(msec: number) {
-	return new Promise<void>((res) => {
-		setTimeout(() => {
-			res();
-		}, msec);
-	});
-}
diff --git a/packages/backend/tsconfig.json b/packages/backend/tsconfig.json
deleted file mode 100644
index 692d7b95b7..0000000000
--- a/packages/backend/tsconfig.json
+++ /dev/null
@@ -1,48 +0,0 @@
-{
-	"compilerOptions": {
-		"allowJs": true,
-		"noEmitOnError": false,
-		"noImplicitAny": true,
-		"noImplicitReturns": true,
-		"noUnusedParameters": false,
-		"noUnusedLocals": false,
-		"noFallthroughCasesInSwitch": true,
-		"declaration": false,
-		"sourceMap": false,
-		"target": "es2021",
-		"module": "es2020",
-		"moduleResolution": "node",
-		"allowSyntheticDefaultImports": true,
-		"removeComments": false,
-		"noLib": false,
-		"strict": true,
-		"strictNullChecks": true,
-		"strictPropertyInitialization": false,
-		"experimentalDecorators": true,
-		"emitDecoratorMetadata": true,
-		"resolveJsonModule": true,
-		"isolatedModules": false,
-		"rootDir": "./src",
-		"baseUrl": "./",
-		"paths": {
-			"@/*": [
-				"./src/*"
-			]
-		},
-		"outDir": "./built",
-		"types": [
-			"node"
-		],
-		"typeRoots": [
-			"./node_modules/@types",
-			"./src/@types"
-		],
-		"lib": [
-			"esnext"
-		]
-	},
-	"compileOnSave": false,
-	"include": [
-		"./src/**/*.ts"
-	],
-}