From 90f8fe7e538bb7e52d2558152a0390e693f39b11 Mon Sep 17 00:00:00 2001
From: Akihiko Odaki <nekomanma@pixiv.co.jp>
Date: Thu, 29 Mar 2018 01:20:40 +0900
Subject: [PATCH 1/2] Introduce processor

---
 gulpfile.ts                                   |  28 ++++++-------
 package.json                                  |   2 +
 src/{common => }/build/fa.ts                  |   0
 src/{common => }/build/i18n.ts                |   2 +-
 src/{common => }/build/license.ts             |   2 +-
 src/index.ts                                  |  38 +++++++++++++-----
 src/parse-opt.ts                              |  17 ++++++++
 src/processor/index.ts                        |   4 ++
 src/processor/report-github-failure.ts        |  29 +++++++++++++
 src/queue.ts                                  |  10 +++++
 src/{ => server}/api/api-handler.ts           |   0
 src/{ => server}/api/authenticate.ts          |   0
 src/{ => server}/api/bot/core.ts              |   0
 src/{ => server}/api/bot/interfaces/line.ts   |   4 +-
 src/{ => server}/api/common/drive/add-file.ts |   2 +-
 .../api/common/drive/upload_from_url.ts       |   0
 .../api/common/generate-native-user-token.ts  |   0
 src/{ => server}/api/common/get-friends.ts    |   0
 src/{ => server}/api/common/get-host-lower.ts |   0
 .../api/common/is-native-token.ts             |   0
 src/{ => server}/api/common/notify.ts         |   0
 src/{ => server}/api/common/push-sw.ts        |   2 +-
 .../api/common/read-messaging-message.ts      |   0
 .../api/common/read-notification.ts           |   0
 src/{ => server}/api/common/signin.ts         |   2 +-
 .../common/text/core/syntax-highlighter.ts    |   0
 .../api/common/text/elements/bold.ts          |   0
 .../api/common/text/elements/code.ts          |   0
 .../api/common/text/elements/emoji.ts         |   0
 .../api/common/text/elements/hashtag.ts       |   0
 .../api/common/text/elements/inline-code.ts   |   0
 .../api/common/text/elements/link.ts          |   0
 .../api/common/text/elements/mention.ts       |   0
 .../api/common/text/elements/quote.ts         |   0
 .../api/common/text/elements/url.ts           |   0
 src/{ => server}/api/common/text/index.ts     |   0
 src/{ => server}/api/common/watch-post.ts     |   0
 src/{ => server}/api/endpoints.ts             |   0
 .../api/endpoints/aggregation/posts.ts        |   0
 .../endpoints/aggregation/posts/reaction.ts   |   0
 .../endpoints/aggregation/posts/reactions.ts  |   0
 .../api/endpoints/aggregation/posts/reply.ts  |   0
 .../api/endpoints/aggregation/posts/repost.ts |   0
 .../api/endpoints/aggregation/users.ts        |   0
 .../endpoints/aggregation/users/activity.ts   |   0
 .../endpoints/aggregation/users/followers.ts  |   0
 .../endpoints/aggregation/users/following.ts  |   0
 .../api/endpoints/aggregation/users/post.ts   |   0
 .../endpoints/aggregation/users/reaction.ts   |   0
 src/{ => server}/api/endpoints/app/create.ts  |   0
 .../api/endpoints/app/name_id/available.ts    |   0
 src/{ => server}/api/endpoints/app/show.ts    |   0
 src/{ => server}/api/endpoints/auth/accept.ts |   0
 .../api/endpoints/auth/session/generate.ts    |   2 +-
 .../api/endpoints/auth/session/show.ts        |   0
 .../api/endpoints/auth/session/userkey.ts     |   0
 src/{ => server}/api/endpoints/channels.ts    |   0
 .../api/endpoints/channels/create.ts          |   0
 .../api/endpoints/channels/posts.ts           |   0
 .../api/endpoints/channels/show.ts            |   0
 .../api/endpoints/channels/unwatch.ts         |   0
 .../api/endpoints/channels/watch.ts           |   0
 src/{ => server}/api/endpoints/drive.ts       |   0
 src/{ => server}/api/endpoints/drive/files.ts |   0
 .../api/endpoints/drive/files/create.ts       |   0
 .../api/endpoints/drive/files/find.ts         |   0
 .../api/endpoints/drive/files/show.ts         |   0
 .../api/endpoints/drive/files/update.ts       |   0
 .../endpoints/drive/files/upload_from_url.ts  |   0
 .../api/endpoints/drive/folders.ts            |   0
 .../api/endpoints/drive/folders/create.ts     |   0
 .../api/endpoints/drive/folders/find.ts       |   0
 .../api/endpoints/drive/folders/show.ts       |   0
 .../api/endpoints/drive/folders/update.ts     |   0
 .../api/endpoints/drive/stream.ts             |   0
 .../api/endpoints/following/create.ts         |   0
 .../api/endpoints/following/delete.ts         |   0
 src/{ => server}/api/endpoints/i.ts           |   0
 src/{ => server}/api/endpoints/i/2fa/done.ts  |   0
 .../api/endpoints/i/2fa/register.ts           |   2 +-
 .../api/endpoints/i/2fa/unregister.ts         |   0
 .../api/endpoints/i/appdata/get.ts            |   0
 .../api/endpoints/i/appdata/set.ts            |   0
 .../api/endpoints/i/authorized_apps.ts        |   0
 .../api/endpoints/i/change_password.ts        |   0
 src/{ => server}/api/endpoints/i/favorites.ts |   0
 .../api/endpoints/i/notifications.ts          |   0
 src/{ => server}/api/endpoints/i/pin.ts       |   0
 .../api/endpoints/i/regenerate_token.ts       |   0
 .../api/endpoints/i/signin_history.ts         |   0
 src/{ => server}/api/endpoints/i/update.ts    |   2 +-
 .../api/endpoints/i/update_client_setting.ts  |   0
 .../api/endpoints/i/update_home.ts            |   0
 .../api/endpoints/i/update_mobile_home.ts     |   0
 .../api/endpoints/messaging/history.ts        |   0
 .../api/endpoints/messaging/messages.ts       |   0
 .../endpoints/messaging/messages/create.ts    |   2 +-
 .../api/endpoints/messaging/unread.ts         |   0
 src/{ => server}/api/endpoints/meta.ts        |   4 +-
 src/{ => server}/api/endpoints/mute/create.ts |   0
 src/{ => server}/api/endpoints/mute/delete.ts |   0
 src/{ => server}/api/endpoints/mute/list.ts   |   0
 src/{ => server}/api/endpoints/my/apps.ts     |   0
 .../notifications/get_unread_count.ts         |   0
 .../notifications/mark_as_read_all.ts         |   0
 .../api/endpoints/othello/games.ts            |   0
 .../api/endpoints/othello/games/show.ts       |   0
 .../api/endpoints/othello/invitations.ts      |   0
 .../api/endpoints/othello/match.ts            |   0
 .../api/endpoints/othello/match/cancel.ts     |   0
 src/{ => server}/api/endpoints/posts.ts       |   0
 .../api/endpoints/posts/categorize.ts         |   0
 .../api/endpoints/posts/context.ts            |   0
 .../api/endpoints/posts/create.ts             |   2 +-
 .../api/endpoints/posts/favorites/create.ts   |   0
 .../api/endpoints/posts/favorites/delete.ts   |   0
 .../api/endpoints/posts/mentions.ts           |   0
 .../endpoints/posts/polls/recommendation.ts   |   0
 .../api/endpoints/posts/polls/vote.ts         |   0
 .../api/endpoints/posts/reactions.ts          |   0
 .../api/endpoints/posts/reactions/create.ts   |   0
 .../api/endpoints/posts/reactions/delete.ts   |   0
 .../api/endpoints/posts/replies.ts            |   0
 .../api/endpoints/posts/reposts.ts            |   0
 .../api/endpoints/posts/search.ts             |   0
 src/{ => server}/api/endpoints/posts/show.ts  |   0
 .../api/endpoints/posts/timeline.ts           |   0
 src/{ => server}/api/endpoints/posts/trend.ts |   0
 src/{ => server}/api/endpoints/stats.ts       |   0
 src/{ => server}/api/endpoints/sw/register.ts |   0
 .../api/endpoints/username/available.ts       |   0
 src/{ => server}/api/endpoints/users.ts       |   0
 .../api/endpoints/users/followers.ts          |   0
 .../api/endpoints/users/following.ts          |   0
 .../users/get_frequently_replied_users.ts     |   0
 src/{ => server}/api/endpoints/users/posts.ts |   0
 .../api/endpoints/users/recommendation.ts     |   0
 .../api/endpoints/users/search.ts             |   2 +-
 .../api/endpoints/users/search_by_username.ts |   0
 src/{ => server}/api/endpoints/users/show.ts  |   0
 src/{ => server}/api/event.ts                 |   2 +-
 src/{ => server}/api/limitter.ts              |   2 +-
 src/{ => server}/api/models/access-token.ts   |   2 +-
 src/{ => server}/api/models/app.ts            |   4 +-
 src/{ => server}/api/models/appdata.ts        |   2 +-
 src/{ => server}/api/models/auth-session.ts   |   2 +-
 .../api/models/channel-watching.ts            |   2 +-
 src/{ => server}/api/models/channel.ts        |   2 +-
 src/{ => server}/api/models/drive-file.ts     |   4 +-
 src/{ => server}/api/models/drive-folder.ts   |   2 +-
 src/{ => server}/api/models/drive-tag.ts      |   2 +-
 src/{ => server}/api/models/favorite.ts       |   2 +-
 src/{ => server}/api/models/following.ts      |   2 +-
 .../api/models/messaging-history.ts           |   2 +-
 .../api/models/messaging-message.ts           |   2 +-
 src/{ => server}/api/models/meta.ts           |   2 +-
 src/{ => server}/api/models/mute.ts           |   2 +-
 src/{ => server}/api/models/notification.ts   |   2 +-
 src/{ => server}/api/models/othello-game.ts   |   2 +-
 .../api/models/othello-matching.ts            |   2 +-
 src/{ => server}/api/models/poll-vote.ts      |   2 +-
 src/{ => server}/api/models/post-reaction.ts  |   2 +-
 src/{ => server}/api/models/post-watching.ts  |   2 +-
 src/{ => server}/api/models/post.ts           |   2 +-
 src/{ => server}/api/models/signin.ts         |   2 +-
 .../api/models/sw-subscription.ts             |   2 +-
 src/{ => server}/api/models/user.ts           |   4 +-
 src/{ => server}/api/private/signin.ts        |   2 +-
 src/{ => server}/api/private/signup.ts        |   4 +-
 src/{ => server}/api/reply.ts                 |   0
 src/{ => server}/api/server.ts                |   0
 src/{ => server}/api/service/github.ts        |  38 ++++++------------
 src/{ => server}/api/service/twitter.ts       |   4 +-
 src/{ => server}/api/stream/channel.ts        |   0
 src/{ => server}/api/stream/drive.ts          |   0
 src/{ => server}/api/stream/home.ts           |   0
 .../api/stream/messaging-index.ts             |   0
 src/{ => server}/api/stream/messaging.ts      |   0
 src/{ => server}/api/stream/othello-game.ts   |   0
 src/{ => server}/api/stream/othello.ts        |   0
 src/{ => server}/api/stream/requests.ts       |   0
 src/{ => server}/api/stream/server.ts         |   0
 src/{ => server}/api/streaming.ts             |   2 +-
 .../common/get-notification-summary.ts        |   0
 src/{ => server}/common/get-post-summary.ts   |   0
 src/{ => server}/common/get-reaction-emoji.ts |   0
 src/{ => server}/common/othello/ai/back.ts    |   2 +-
 src/{ => server}/common/othello/ai/front.ts   |   2 +-
 src/{ => server}/common/othello/ai/index.ts   |   0
 src/{ => server}/common/othello/core.ts       |   0
 src/{ => server}/common/othello/maps.ts       |   0
 src/{ => server}/common/user/get-acct.ts      |   0
 src/{ => server}/common/user/get-summary.ts   |   0
 src/{ => server}/common/user/parse-acct.ts    |   0
 src/{ => server}/file/assets/avatar.jpg       | Bin
 src/{ => server}/file/assets/bad-egg.png      | Bin
 src/{ => server}/file/assets/dummy.png        | Bin
 src/{ => server}/file/assets/not-an-image.png | Bin
 .../file/assets/thumbnail-not-available.png   | Bin
 src/{ => server}/file/server.ts               |   0
 src/{server.ts => server/index.ts}            |  38 +++++++-----------
 src/{ => server}/log-request.ts               |   0
 src/{ => server}/web/app/animation.styl       |   0
 src/{ => server}/web/app/app.styl             |   0
 src/{ => server}/web/app/app.vue              |   0
 src/{ => server}/web/app/auth/assets/logo.svg |   0
 src/{ => server}/web/app/auth/script.ts       |   0
 src/{ => server}/web/app/auth/style.styl      |   0
 src/{ => server}/web/app/auth/views/form.vue  |   0
 src/{ => server}/web/app/auth/views/index.vue |   0
 src/{ => server}/web/app/base.pug             |   6 +--
 src/{ => server}/web/app/boot.js              |   0
 src/{ => server}/web/app/ch/script.ts         |   0
 src/{ => server}/web/app/ch/style.styl        |   0
 src/{ => server}/web/app/ch/tags/channel.tag  |   0
 src/{ => server}/web/app/ch/tags/header.tag   |   0
 src/{ => server}/web/app/ch/tags/index.tag    |   0
 src/{ => server}/web/app/ch/tags/index.ts     |   0
 .../web/app/common/define-widget.ts           |   0
 src/{ => server}/web/app/common/mios.ts       |   0
 .../app/common/scripts/check-for-update.ts    |   0
 .../common/scripts/compose-notification.ts    |   0
 .../web/app/common/scripts/contains.ts        |   0
 .../app/common/scripts/copy-to-clipboard.ts   |   0
 .../web/app/common/scripts/date-stringify.ts  |   0
 .../web/app/common/scripts/fuck-ad-block.ts   |   0
 .../web/app/common/scripts/gcd.ts             |   0
 .../web/app/common/scripts/get-kao.ts         |   0
 .../web/app/common/scripts/get-median.ts      |   0
 .../web/app/common/scripts/loading.ts         |   0
 .../app/common/scripts/parse-search-query.ts  |   0
 .../app/common/scripts/streaming/channel.ts   |   0
 .../web/app/common/scripts/streaming/drive.ts |   0
 .../web/app/common/scripts/streaming/home.ts  |   0
 .../scripts/streaming/messaging-index.ts      |   0
 .../app/common/scripts/streaming/messaging.ts |   0
 .../common/scripts/streaming/othello-game.ts  |   0
 .../app/common/scripts/streaming/othello.ts   |   0
 .../app/common/scripts/streaming/requests.ts  |   0
 .../app/common/scripts/streaming/server.ts    |   0
 .../scripts/streaming/stream-manager.ts       |   0
 .../app/common/scripts/streaming/stream.ts    |   0
 .../common/views/components/autocomplete.vue  |   0
 .../connect-failed.troubleshooter.vue         |   0
 .../views/components/connect-failed.vue       |   0
 .../app/common/views/components/ellipsis.vue  |   0
 .../views/components/file-type-icon.vue       |   0
 .../app/common/views/components/forkit.vue    |   0
 .../web/app/common/views/components/index.ts  |   0
 .../common/views/components/media-list.vue    |   0
 .../views/components/messaging-room.form.vue  |   0
 .../components/messaging-room.message.vue     |   0
 .../views/components/messaging-room.vue       |   0
 .../app/common/views/components/messaging.vue |   0
 .../web/app/common/views/components/nav.vue   |   0
 .../common/views/components/othello.game.vue  |   0
 .../views/components/othello.gameroom.vue     |   0
 .../common/views/components/othello.room.vue  |   0
 .../app/common/views/components/othello.vue   |   0
 .../common/views/components/poll-editor.vue   |   0
 .../web/app/common/views/components/poll.vue  |   0
 .../app/common/views/components/post-html.ts  |   0
 .../app/common/views/components/post-menu.vue |   0
 .../common/views/components/reaction-icon.vue |   0
 .../views/components/reaction-picker.vue      |   0
 .../views/components/reactions-viewer.vue     |   0
 .../app/common/views/components/signin.vue    |   0
 .../app/common/views/components/signup.vue    |   0
 .../views/components/special-message.vue      |   0
 .../views/components/stream-indicator.vue     |   0
 .../app/common/views/components/switch.vue    |   0
 .../web/app/common/views/components/time.vue  |   0
 .../web/app/common/views/components/timer.vue |   0
 .../views/components/twitter-setting.vue      |   0
 .../app/common/views/components/uploader.vue  |   0
 .../common/views/components/url-preview.vue   |   0
 .../web/app/common/views/components/url.vue   |   0
 .../views/components/welcome-timeline.vue     |   0
 .../common/views/directives/autocomplete.ts   |   0
 .../web/app/common/views/directives/index.ts  |   0
 .../web/app/common/views/filters/bytes.ts     |   0
 .../web/app/common/views/filters/index.ts     |   0
 .../web/app/common/views/filters/number.ts    |   0
 .../app/common/views/widgets/access-log.vue   |   0
 .../app/common/views/widgets/broadcast.vue    |   0
 .../web/app/common/views/widgets/calendar.vue |   0
 .../web/app/common/views/widgets/donation.vue |   0
 .../web/app/common/views/widgets/index.ts     |   0
 .../web/app/common/views/widgets/nav.vue      |   0
 .../app/common/views/widgets/photo-stream.vue |   0
 .../web/app/common/views/widgets/rss.vue      |   0
 .../views/widgets/server.cpu-memory.vue       |   0
 .../app/common/views/widgets/server.cpu.vue   |   0
 .../app/common/views/widgets/server.disk.vue  |   0
 .../app/common/views/widgets/server.info.vue  |   0
 .../common/views/widgets/server.memory.vue    |   0
 .../app/common/views/widgets/server.pie.vue   |   0
 .../common/views/widgets/server.uptimes.vue   |   0
 .../web/app/common/views/widgets/server.vue   |   0
 .../app/common/views/widgets/slideshow.vue    |   0
 .../web/app/common/views/widgets/tips.vue     |   0
 .../web/app/common/views/widgets/version.vue  |   0
 src/{ => server}/web/app/config.ts            |   0
 .../web/app/desktop/api/choose-drive-file.ts  |   0
 .../app/desktop/api/choose-drive-folder.ts    |   0
 .../web/app/desktop/api/contextmenu.ts        |   0
 .../web/app/desktop/api/dialog.ts             |   0
 src/{ => server}/web/app/desktop/api/input.ts |   0
 .../web/app/desktop/api/notify.ts             |   0
 src/{ => server}/web/app/desktop/api/post.ts  |   0
 .../web/app/desktop/api/update-avatar.ts      |   0
 .../web/app/desktop/api/update-banner.ts      |   0
 .../web/app/desktop/assets/grid.svg           |   0
 .../app/desktop/assets/header-logo-white.svg  |   0
 .../web/app/desktop/assets/header-logo.svg    |   0
 .../web/app/desktop/assets/index.jpg          | Bin
 .../web/app/desktop/assets/remove.png         | Bin
 src/{ => server}/web/app/desktop/script.ts    |   0
 src/{ => server}/web/app/desktop/style.styl   |   0
 src/{ => server}/web/app/desktop/ui.styl      |   0
 .../views/components/activity.calendar.vue    |   0
 .../views/components/activity.chart.vue       |   0
 .../app/desktop/views/components/activity.vue |   0
 .../desktop/views/components/analog-clock.vue |   0
 .../app/desktop/views/components/calendar.vue |   0
 .../choose-file-from-drive-window.vue         |   0
 .../choose-folder-from-drive-window.vue       |   0
 .../views/components/context-menu.menu.vue    |   0
 .../desktop/views/components/context-menu.vue |   0
 .../desktop/views/components/crop-window.vue  |   0
 .../app/desktop/views/components/dialog.vue   |   0
 .../desktop/views/components/drive-window.vue |   0
 .../desktop/views/components/drive.file.vue   |   0
 .../desktop/views/components/drive.folder.vue |   0
 .../views/components/drive.nav-folder.vue     |   0
 .../app/desktop/views/components/drive.vue    |   0
 .../views/components/ellipsis-icon.vue        |   0
 .../views/components/follow-button.vue        |   0
 .../views/components/followers-window.vue     |   0
 .../desktop/views/components/followers.vue    |   0
 .../views/components/following-window.vue     |   0
 .../desktop/views/components/following.vue    |   0
 .../views/components/friends-maker.vue        |   0
 .../desktop/views/components/game-window.vue  |   0
 .../web/app/desktop/views/components/home.vue |   0
 .../web/app/desktop/views/components/index.ts |   0
 .../desktop/views/components/input-dialog.vue |   0
 .../views/components/media-image-dialog.vue   |   0
 .../desktop/views/components/media-image.vue  |   0
 .../views/components/media-video-dialog.vue   |   0
 .../desktop/views/components/media-video.vue  |   0
 .../app/desktop/views/components/mentions.vue |   0
 .../components/messaging-room-window.vue      |   0
 .../views/components/messaging-window.vue     |   0
 .../views/components/notifications.vue        |   0
 .../views/components/post-detail.sub.vue      |   0
 .../desktop/views/components/post-detail.vue  |   0
 .../views/components/post-form-window.vue     |   0
 .../desktop/views/components/post-form.vue    |   0
 .../desktop/views/components/post-preview.vue |   0
 .../views/components/posts.post.sub.vue       |   0
 .../desktop/views/components/posts.post.vue   |   0
 .../app/desktop/views/components/posts.vue    |   0
 .../views/components/progress-dialog.vue      |   0
 .../views/components/repost-form-window.vue   |   0
 .../desktop/views/components/repost-form.vue  |   0
 .../views/components/settings-window.vue      |   0
 .../desktop/views/components/settings.2fa.vue |   0
 .../desktop/views/components/settings.api.vue |   0
 .../views/components/settings.apps.vue        |   0
 .../views/components/settings.drive.vue       |   0
 .../views/components/settings.mute.vue        |   0
 .../views/components/settings.password.vue    |   0
 .../views/components/settings.profile.vue     |   0
 .../views/components/settings.signins.vue     |   0
 .../app/desktop/views/components/settings.vue |   0
 .../views/components/sub-post-content.vue     |   0
 .../desktop/views/components/taskmanager.vue  |   0
 .../app/desktop/views/components/timeline.vue |   0
 .../views/components/ui-notification.vue      |   0
 .../views/components/ui.header.account.vue    |   0
 .../views/components/ui.header.clock.vue      |   0
 .../views/components/ui.header.nav.vue        |   0
 .../components/ui.header.notifications.vue    |   0
 .../views/components/ui.header.post.vue       |   0
 .../views/components/ui.header.search.vue     |   0
 .../desktop/views/components/ui.header.vue    |   0
 .../web/app/desktop/views/components/ui.vue   |   0
 .../desktop/views/components/user-preview.vue |   0
 .../views/components/users-list.item.vue      |   0
 .../desktop/views/components/users-list.vue   |   0
 .../views/components/widget-container.vue     |   0
 .../app/desktop/views/components/window.vue   |   0
 .../web/app/desktop/views/directives/index.ts |   0
 .../desktop/views/directives/user-preview.ts  |   0
 .../web/app/desktop/views/pages/drive.vue     |   0
 .../desktop/views/pages/home-customize.vue    |   0
 .../web/app/desktop/views/pages/home.vue      |   0
 .../web/app/desktop/views/pages/index.vue     |   0
 .../desktop/views/pages/messaging-room.vue    |   0
 .../web/app/desktop/views/pages/othello.vue   |   0
 .../web/app/desktop/views/pages/post.vue      |   0
 .../web/app/desktop/views/pages/search.vue    |   0
 .../app/desktop/views/pages/selectdrive.vue   |   0
 .../pages/user/user.followers-you-know.vue    |   0
 .../desktop/views/pages/user/user.friends.vue |   0
 .../desktop/views/pages/user/user.header.vue  |   0
 .../desktop/views/pages/user/user.home.vue    |   0
 .../desktop/views/pages/user/user.photos.vue  |   0
 .../desktop/views/pages/user/user.profile.vue |   0
 .../views/pages/user/user.timeline.vue        |   0
 .../web/app/desktop/views/pages/user/user.vue |   0
 .../web/app/desktop/views/pages/welcome.vue   |   0
 .../app/desktop/views/widgets/activity.vue    |   0
 .../views/widgets/channel.channel.form.vue    |   0
 .../views/widgets/channel.channel.post.vue    |   0
 .../desktop/views/widgets/channel.channel.vue |   0
 .../web/app/desktop/views/widgets/channel.vue |   0
 .../web/app/desktop/views/widgets/index.ts    |   0
 .../app/desktop/views/widgets/messaging.vue   |   0
 .../desktop/views/widgets/notifications.vue   |   0
 .../web/app/desktop/views/widgets/polls.vue   |   0
 .../app/desktop/views/widgets/post-form.vue   |   0
 .../web/app/desktop/views/widgets/profile.vue |   0
 .../app/desktop/views/widgets/timemachine.vue |   0
 .../web/app/desktop/views/widgets/trends.vue  |   0
 .../web/app/desktop/views/widgets/users.vue   |   0
 src/{ => server}/web/app/dev/script.ts        |   0
 src/{ => server}/web/app/dev/style.styl       |   0
 src/{ => server}/web/app/dev/views/app.vue    |   0
 src/{ => server}/web/app/dev/views/apps.vue   |   0
 src/{ => server}/web/app/dev/views/index.vue  |   0
 .../web/app/dev/views/new-app.vue             |   0
 src/{ => server}/web/app/dev/views/ui.vue     |   0
 src/{ => server}/web/app/init.css             |   0
 src/{ => server}/web/app/init.ts              |   0
 .../web/app/mobile/api/choose-drive-file.ts   |   0
 .../web/app/mobile/api/choose-drive-folder.ts |   0
 src/{ => server}/web/app/mobile/api/dialog.ts |   0
 src/{ => server}/web/app/mobile/api/input.ts  |   0
 src/{ => server}/web/app/mobile/api/notify.ts |   0
 src/{ => server}/web/app/mobile/api/post.ts   |   0
 src/{ => server}/web/app/mobile/script.ts     |   0
 src/{ => server}/web/app/mobile/style.styl    |   0
 .../app/mobile/views/components/activity.vue  |   0
 .../views/components/drive-file-chooser.vue   |   0
 .../views/components/drive-folder-chooser.vue |   0
 .../views/components/drive.file-detail.vue    |   0
 .../mobile/views/components/drive.file.vue    |   0
 .../mobile/views/components/drive.folder.vue  |   0
 .../web/app/mobile/views/components/drive.vue |   0
 .../mobile/views/components/follow-button.vue |   0
 .../mobile/views/components/friends-maker.vue |   0
 .../web/app/mobile/views/components/index.ts  |   0
 .../mobile/views/components/media-image.vue   |   0
 .../mobile/views/components/media-video.vue   |   0
 .../views/components/notification-preview.vue |   0
 .../mobile/views/components/notification.vue  |   0
 .../mobile/views/components/notifications.vue |   0
 .../app/mobile/views/components/notify.vue    |   0
 .../app/mobile/views/components/post-card.vue |   0
 .../views/components/post-detail.sub.vue      |   0
 .../mobile/views/components/post-detail.vue   |   0
 .../app/mobile/views/components/post-form.vue |   0
 .../mobile/views/components/post-preview.vue  |   0
 .../app/mobile/views/components/post.sub.vue  |   0
 .../web/app/mobile/views/components/post.vue  |   0
 .../web/app/mobile/views/components/posts.vue |   0
 .../views/components/sub-post-content.vue     |   0
 .../app/mobile/views/components/timeline.vue  |   0
 .../app/mobile/views/components/ui.header.vue |   0
 .../app/mobile/views/components/ui.nav.vue    |   0
 .../web/app/mobile/views/components/ui.vue    |   0
 .../app/mobile/views/components/user-card.vue |   0
 .../mobile/views/components/user-preview.vue  |   0
 .../mobile/views/components/user-timeline.vue |   0
 .../mobile/views/components/users-list.vue    |   0
 .../views/components/widget-container.vue     |   0
 .../web/app/mobile/views/directives/index.ts  |   0
 .../mobile/views/directives/user-preview.ts   |   0
 .../web/app/mobile/views/pages/drive.vue      |   0
 .../web/app/mobile/views/pages/followers.vue  |   0
 .../web/app/mobile/views/pages/following.vue  |   0
 .../web/app/mobile/views/pages/home.vue       |   0
 .../web/app/mobile/views/pages/index.vue      |   0
 .../app/mobile/views/pages/messaging-room.vue |   0
 .../web/app/mobile/views/pages/messaging.vue  |   0
 .../app/mobile/views/pages/notifications.vue  |   0
 .../web/app/mobile/views/pages/othello.vue    |   0
 .../web/app/mobile/views/pages/post.vue       |   0
 .../mobile/views/pages/profile-setting.vue    |   0
 .../web/app/mobile/views/pages/search.vue     |   0
 .../app/mobile/views/pages/selectdrive.vue    |   0
 .../web/app/mobile/views/pages/settings.vue   |   0
 .../web/app/mobile/views/pages/signup.vue     |   0
 .../web/app/mobile/views/pages/user.vue       |   0
 .../pages/user/home.followers-you-know.vue    |   0
 .../mobile/views/pages/user/home.friends.vue  |   0
 .../mobile/views/pages/user/home.photos.vue   |   0
 .../mobile/views/pages/user/home.posts.vue    |   0
 .../web/app/mobile/views/pages/user/home.vue  |   0
 .../web/app/mobile/views/pages/welcome.vue    |   0
 .../web/app/mobile/views/widgets/activity.vue |   0
 .../web/app/mobile/views/widgets/index.ts     |   0
 .../web/app/mobile/views/widgets/profile.vue  |   0
 src/{ => server}/web/app/reset.styl           |   0
 src/{ => server}/web/app/safe.js              |   0
 src/{ => server}/web/app/stats/style.styl     |   0
 src/{ => server}/web/app/stats/tags/index.tag |   0
 src/{ => server}/web/app/stats/tags/index.ts  |   0
 src/{ => server}/web/app/status/style.styl    |   0
 .../web/app/status/tags/index.tag             |   0
 src/{ => server}/web/app/status/tags/index.ts |   0
 src/{ => server}/web/app/sw.js                |   0
 src/{ => server}/web/app/tsconfig.json        |   0
 src/{ => server}/web/app/v.d.ts               |   0
 src/{ => server}/web/assets/404.js            |   0
 .../web/assets/code-highlight.css             |   0
 src/{ => server}/web/assets/error.jpg         | Bin
 src/{ => server}/web/assets/favicon.ico       | Bin
 src/{ => server}/web/assets/label.svg         |   0
 src/{ => server}/web/assets/manifest.json     |   0
 src/{ => server}/web/assets/message.mp3       | Bin
 .../web/assets/othello-put-me.mp3             | Bin
 .../web/assets/othello-put-you.mp3            | Bin
 src/{ => server}/web/assets/post.mp3          | Bin
 .../web/assets/reactions/angry.png            | Bin
 .../web/assets/reactions/confused.png         | Bin
 .../web/assets/reactions/congrats.png         | Bin
 src/{ => server}/web/assets/reactions/hmm.png | Bin
 .../web/assets/reactions/laugh.png            | Bin
 .../web/assets/reactions/like.png             | Bin
 .../web/assets/reactions/love.png             | Bin
 .../web/assets/reactions/pudding.png          | Bin
 .../web/assets/reactions/surprise.png         | Bin
 src/{ => server}/web/assets/recover.html      |   0
 src/{ => server}/web/assets/title.svg         |   0
 src/{ => server}/web/assets/unread.svg        |   0
 src/{ => server}/web/assets/welcome-bg.svg    |   0
 src/{ => server}/web/assets/welcome-fg.svg    |   0
 src/{ => server}/web/const.styl               |   2 +-
 src/{ => server}/web/docs/about.en.pug        |   0
 src/{ => server}/web/docs/about.ja.pug        |   0
 src/{ => server}/web/docs/api.ja.pug          |   0
 .../web/docs/api/endpoints/posts/create.yaml  |   0
 .../docs/api/endpoints/posts/timeline.yaml    |   0
 .../web/docs/api/endpoints/style.styl         |   0
 .../web/docs/api/endpoints/view.pug           |   0
 .../web/docs/api/entities/drive-file.yaml     |   0
 .../web/docs/api/entities/post.yaml           |   0
 .../web/docs/api/entities/style.styl          |   0
 .../web/docs/api/entities/user.yaml           |   0
 .../web/docs/api/entities/view.pug            |   0
 src/{ => server}/web/docs/api/gulpfile.ts     |  24 +++++------
 src/{ => server}/web/docs/api/mixins.pug      |   0
 src/{ => server}/web/docs/api/style.styl      |   0
 src/{ => server}/web/docs/gulpfile.ts         |  16 ++++----
 src/{ => server}/web/docs/index.en.pug        |   0
 src/{ => server}/web/docs/index.ja.pug        |   0
 src/{ => server}/web/docs/layout.pug          |   0
 src/{ => server}/web/docs/license.en.pug      |   0
 src/{ => server}/web/docs/license.ja.pug      |   0
 src/{ => server}/web/docs/mute.ja.pug         |   0
 src/{ => server}/web/docs/search.ja.pug       |   0
 src/{ => server}/web/docs/server.ts           |   0
 src/{ => server}/web/docs/style.styl          |   0
 src/{ => server}/web/docs/tou.ja.pug          |   0
 src/{ => server}/web/docs/ui.styl             |   0
 src/{ => server}/web/docs/vars.ts             |  16 ++++----
 src/{ => server}/web/element.scss             |   2 +-
 src/{ => server}/web/server.ts                |   0
 src/{ => server}/web/service/url-preview.ts   |   0
 src/{ => server}/web/style.styl               |   0
 src/tools/analysis/core.ts                    |   2 +-
 src/tools/analysis/extract-user-domains.ts    |   6 +--
 src/tools/analysis/extract-user-keywords.ts   |   6 +--
 .../analysis/predict-all-post-category.ts     |   2 +-
 src/tools/analysis/predict-user-interst.ts    |   4 +-
 test/api.js                                   |   2 +-
 test/text.js                                  |   4 +-
 tsconfig.json                                 |   2 +-
 webpack.config.ts                             |  30 +++++++-------
 582 files changed, 246 insertions(+), 188 deletions(-)
 rename src/{common => }/build/fa.ts (100%)
 rename src/{common => }/build/i18n.ts (96%)
 rename src/{common => }/build/license.ts (72%)
 create mode 100644 src/parse-opt.ts
 create mode 100644 src/processor/index.ts
 create mode 100644 src/processor/report-github-failure.ts
 create mode 100644 src/queue.ts
 rename src/{ => server}/api/api-handler.ts (100%)
 rename src/{ => server}/api/authenticate.ts (100%)
 rename src/{ => server}/api/bot/core.ts (100%)
 rename src/{ => server}/api/bot/interfaces/line.ts (98%)
 rename src/{ => server}/api/common/drive/add-file.ts (99%)
 rename src/{ => server}/api/common/drive/upload_from_url.ts (100%)
 rename src/{ => server}/api/common/generate-native-user-token.ts (100%)
 rename src/{ => server}/api/common/get-friends.ts (100%)
 rename src/{ => server}/api/common/get-host-lower.ts (100%)
 rename src/{ => server}/api/common/is-native-token.ts (100%)
 rename src/{ => server}/api/common/notify.ts (100%)
 rename src/{ => server}/api/common/push-sw.ts (97%)
 rename src/{ => server}/api/common/read-messaging-message.ts (100%)
 rename src/{ => server}/api/common/read-notification.ts (100%)
 rename src/{ => server}/api/common/signin.ts (92%)
 rename src/{ => server}/api/common/text/core/syntax-highlighter.ts (100%)
 rename src/{ => server}/api/common/text/elements/bold.ts (100%)
 rename src/{ => server}/api/common/text/elements/code.ts (100%)
 rename src/{ => server}/api/common/text/elements/emoji.ts (100%)
 rename src/{ => server}/api/common/text/elements/hashtag.ts (100%)
 rename src/{ => server}/api/common/text/elements/inline-code.ts (100%)
 rename src/{ => server}/api/common/text/elements/link.ts (100%)
 rename src/{ => server}/api/common/text/elements/mention.ts (100%)
 rename src/{ => server}/api/common/text/elements/quote.ts (100%)
 rename src/{ => server}/api/common/text/elements/url.ts (100%)
 rename src/{ => server}/api/common/text/index.ts (100%)
 rename src/{ => server}/api/common/watch-post.ts (100%)
 rename src/{ => server}/api/endpoints.ts (100%)
 rename src/{ => server}/api/endpoints/aggregation/posts.ts (100%)
 rename src/{ => server}/api/endpoints/aggregation/posts/reaction.ts (100%)
 rename src/{ => server}/api/endpoints/aggregation/posts/reactions.ts (100%)
 rename src/{ => server}/api/endpoints/aggregation/posts/reply.ts (100%)
 rename src/{ => server}/api/endpoints/aggregation/posts/repost.ts (100%)
 rename src/{ => server}/api/endpoints/aggregation/users.ts (100%)
 rename src/{ => server}/api/endpoints/aggregation/users/activity.ts (100%)
 rename src/{ => server}/api/endpoints/aggregation/users/followers.ts (100%)
 rename src/{ => server}/api/endpoints/aggregation/users/following.ts (100%)
 rename src/{ => server}/api/endpoints/aggregation/users/post.ts (100%)
 rename src/{ => server}/api/endpoints/aggregation/users/reaction.ts (100%)
 rename src/{ => server}/api/endpoints/app/create.ts (100%)
 rename src/{ => server}/api/endpoints/app/name_id/available.ts (100%)
 rename src/{ => server}/api/endpoints/app/show.ts (100%)
 rename src/{ => server}/api/endpoints/auth/accept.ts (100%)
 rename src/{ => server}/api/endpoints/auth/session/generate.ts (97%)
 rename src/{ => server}/api/endpoints/auth/session/show.ts (100%)
 rename src/{ => server}/api/endpoints/auth/session/userkey.ts (100%)
 rename src/{ => server}/api/endpoints/channels.ts (100%)
 rename src/{ => server}/api/endpoints/channels/create.ts (100%)
 rename src/{ => server}/api/endpoints/channels/posts.ts (100%)
 rename src/{ => server}/api/endpoints/channels/show.ts (100%)
 rename src/{ => server}/api/endpoints/channels/unwatch.ts (100%)
 rename src/{ => server}/api/endpoints/channels/watch.ts (100%)
 rename src/{ => server}/api/endpoints/drive.ts (100%)
 rename src/{ => server}/api/endpoints/drive/files.ts (100%)
 rename src/{ => server}/api/endpoints/drive/files/create.ts (100%)
 rename src/{ => server}/api/endpoints/drive/files/find.ts (100%)
 rename src/{ => server}/api/endpoints/drive/files/show.ts (100%)
 rename src/{ => server}/api/endpoints/drive/files/update.ts (100%)
 rename src/{ => server}/api/endpoints/drive/files/upload_from_url.ts (100%)
 rename src/{ => server}/api/endpoints/drive/folders.ts (100%)
 rename src/{ => server}/api/endpoints/drive/folders/create.ts (100%)
 rename src/{ => server}/api/endpoints/drive/folders/find.ts (100%)
 rename src/{ => server}/api/endpoints/drive/folders/show.ts (100%)
 rename src/{ => server}/api/endpoints/drive/folders/update.ts (100%)
 rename src/{ => server}/api/endpoints/drive/stream.ts (100%)
 rename src/{ => server}/api/endpoints/following/create.ts (100%)
 rename src/{ => server}/api/endpoints/following/delete.ts (100%)
 rename src/{ => server}/api/endpoints/i.ts (100%)
 rename src/{ => server}/api/endpoints/i/2fa/done.ts (100%)
 rename src/{ => server}/api/endpoints/i/2fa/register.ts (96%)
 rename src/{ => server}/api/endpoints/i/2fa/unregister.ts (100%)
 rename src/{ => server}/api/endpoints/i/appdata/get.ts (100%)
 rename src/{ => server}/api/endpoints/i/appdata/set.ts (100%)
 rename src/{ => server}/api/endpoints/i/authorized_apps.ts (100%)
 rename src/{ => server}/api/endpoints/i/change_password.ts (100%)
 rename src/{ => server}/api/endpoints/i/favorites.ts (100%)
 rename src/{ => server}/api/endpoints/i/notifications.ts (100%)
 rename src/{ => server}/api/endpoints/i/pin.ts (100%)
 rename src/{ => server}/api/endpoints/i/regenerate_token.ts (100%)
 rename src/{ => server}/api/endpoints/i/signin_history.ts (100%)
 rename src/{ => server}/api/endpoints/i/update.ts (98%)
 rename src/{ => server}/api/endpoints/i/update_client_setting.ts (100%)
 rename src/{ => server}/api/endpoints/i/update_home.ts (100%)
 rename src/{ => server}/api/endpoints/i/update_mobile_home.ts (100%)
 rename src/{ => server}/api/endpoints/messaging/history.ts (100%)
 rename src/{ => server}/api/endpoints/messaging/messages.ts (100%)
 rename src/{ => server}/api/endpoints/messaging/messages/create.ts (99%)
 rename src/{ => server}/api/endpoints/messaging/unread.ts (100%)
 rename src/{ => server}/api/endpoints/meta.ts (94%)
 rename src/{ => server}/api/endpoints/mute/create.ts (100%)
 rename src/{ => server}/api/endpoints/mute/delete.ts (100%)
 rename src/{ => server}/api/endpoints/mute/list.ts (100%)
 rename src/{ => server}/api/endpoints/my/apps.ts (100%)
 rename src/{ => server}/api/endpoints/notifications/get_unread_count.ts (100%)
 rename src/{ => server}/api/endpoints/notifications/mark_as_read_all.ts (100%)
 rename src/{ => server}/api/endpoints/othello/games.ts (100%)
 rename src/{ => server}/api/endpoints/othello/games/show.ts (100%)
 rename src/{ => server}/api/endpoints/othello/invitations.ts (100%)
 rename src/{ => server}/api/endpoints/othello/match.ts (100%)
 rename src/{ => server}/api/endpoints/othello/match/cancel.ts (100%)
 rename src/{ => server}/api/endpoints/posts.ts (100%)
 rename src/{ => server}/api/endpoints/posts/categorize.ts (100%)
 rename src/{ => server}/api/endpoints/posts/context.ts (100%)
 rename src/{ => server}/api/endpoints/posts/create.ts (99%)
 rename src/{ => server}/api/endpoints/posts/favorites/create.ts (100%)
 rename src/{ => server}/api/endpoints/posts/favorites/delete.ts (100%)
 rename src/{ => server}/api/endpoints/posts/mentions.ts (100%)
 rename src/{ => server}/api/endpoints/posts/polls/recommendation.ts (100%)
 rename src/{ => server}/api/endpoints/posts/polls/vote.ts (100%)
 rename src/{ => server}/api/endpoints/posts/reactions.ts (100%)
 rename src/{ => server}/api/endpoints/posts/reactions/create.ts (100%)
 rename src/{ => server}/api/endpoints/posts/reactions/delete.ts (100%)
 rename src/{ => server}/api/endpoints/posts/replies.ts (100%)
 rename src/{ => server}/api/endpoints/posts/reposts.ts (100%)
 rename src/{ => server}/api/endpoints/posts/search.ts (100%)
 rename src/{ => server}/api/endpoints/posts/show.ts (100%)
 rename src/{ => server}/api/endpoints/posts/timeline.ts (100%)
 rename src/{ => server}/api/endpoints/posts/trend.ts (100%)
 rename src/{ => server}/api/endpoints/stats.ts (100%)
 rename src/{ => server}/api/endpoints/sw/register.ts (100%)
 rename src/{ => server}/api/endpoints/username/available.ts (100%)
 rename src/{ => server}/api/endpoints/users.ts (100%)
 rename src/{ => server}/api/endpoints/users/followers.ts (100%)
 rename src/{ => server}/api/endpoints/users/following.ts (100%)
 rename src/{ => server}/api/endpoints/users/get_frequently_replied_users.ts (100%)
 rename src/{ => server}/api/endpoints/users/posts.ts (100%)
 rename src/{ => server}/api/endpoints/users/recommendation.ts (100%)
 rename src/{ => server}/api/endpoints/users/search.ts (98%)
 rename src/{ => server}/api/endpoints/users/search_by_username.ts (100%)
 rename src/{ => server}/api/endpoints/users/show.ts (100%)
 rename src/{ => server}/api/event.ts (98%)
 rename src/{ => server}/api/limitter.ts (97%)
 rename src/{ => server}/api/models/access-token.ts (86%)
 rename src/{ => server}/api/models/app.ts (96%)
 rename src/{ => server}/api/models/appdata.ts (63%)
 rename src/{ => server}/api/models/auth-session.ts (95%)
 rename src/{ => server}/api/models/channel-watching.ts (66%)
 rename src/{ => server}/api/models/channel.ts (97%)
 rename src/{ => server}/api/models/drive-file.ts (96%)
 rename src/{ => server}/api/models/drive-folder.ts (97%)
 rename src/{ => server}/api/models/drive-tag.ts (64%)
 rename src/{ => server}/api/models/favorite.ts (64%)
 rename src/{ => server}/api/models/following.ts (64%)
 rename src/{ => server}/api/models/messaging-history.ts (67%)
 rename src/{ => server}/api/models/messaging-message.ts (97%)
 rename src/{ => server}/api/models/meta.ts (74%)
 rename src/{ => server}/api/models/mute.ts (62%)
 rename src/{ => server}/api/models/notification.ts (98%)
 rename src/{ => server}/api/models/othello-game.ts (98%)
 rename src/{ => server}/api/models/othello-matching.ts (96%)
 rename src/{ => server}/api/models/poll-vote.ts (64%)
 rename src/{ => server}/api/models/post-reaction.ts (96%)
 rename src/{ => server}/api/models/post-watching.ts (65%)
 rename src/{ => server}/api/models/post.ts (99%)
 rename src/{ => server}/api/models/signin.ts (93%)
 rename src/{ => server}/api/models/sw-subscription.ts (66%)
 rename src/{ => server}/api/models/user.ts (99%)
 rename src/{ => server}/api/private/signin.ts (98%)
 rename src/{ => server}/api/private/signup.ts (96%)
 rename src/{ => server}/api/reply.ts (100%)
 rename src/{ => server}/api/server.ts (100%)
 rename src/{ => server}/api/service/github.ts (77%)
 rename src/{ => server}/api/service/twitter.ts (98%)
 rename src/{ => server}/api/stream/channel.ts (100%)
 rename src/{ => server}/api/stream/drive.ts (100%)
 rename src/{ => server}/api/stream/home.ts (100%)
 rename src/{ => server}/api/stream/messaging-index.ts (100%)
 rename src/{ => server}/api/stream/messaging.ts (100%)
 rename src/{ => server}/api/stream/othello-game.ts (100%)
 rename src/{ => server}/api/stream/othello.ts (100%)
 rename src/{ => server}/api/stream/requests.ts (100%)
 rename src/{ => server}/api/stream/server.ts (100%)
 rename src/{ => server}/api/streaming.ts (98%)
 rename src/{ => server}/common/get-notification-summary.ts (100%)
 rename src/{ => server}/common/get-post-summary.ts (100%)
 rename src/{ => server}/common/get-reaction-emoji.ts (100%)
 rename src/{ => server}/common/othello/ai/back.ts (99%)
 rename src/{ => server}/common/othello/ai/front.ts (99%)
 rename src/{ => server}/common/othello/ai/index.ts (100%)
 rename src/{ => server}/common/othello/core.ts (100%)
 rename src/{ => server}/common/othello/maps.ts (100%)
 rename src/{ => server}/common/user/get-acct.ts (100%)
 rename src/{ => server}/common/user/get-summary.ts (100%)
 rename src/{ => server}/common/user/parse-acct.ts (100%)
 rename src/{ => server}/file/assets/avatar.jpg (100%)
 rename src/{ => server}/file/assets/bad-egg.png (100%)
 rename src/{ => server}/file/assets/dummy.png (100%)
 rename src/{ => server}/file/assets/not-an-image.png (100%)
 rename src/{ => server}/file/assets/thumbnail-not-available.png (100%)
 rename src/{ => server}/file/server.ts (100%)
 rename src/{server.ts => server/index.ts} (77%)
 rename src/{ => server}/log-request.ts (100%)
 rename src/{ => server}/web/app/animation.styl (100%)
 rename src/{ => server}/web/app/app.styl (100%)
 rename src/{ => server}/web/app/app.vue (100%)
 rename src/{ => server}/web/app/auth/assets/logo.svg (100%)
 rename src/{ => server}/web/app/auth/script.ts (100%)
 rename src/{ => server}/web/app/auth/style.styl (100%)
 rename src/{ => server}/web/app/auth/views/form.vue (100%)
 rename src/{ => server}/web/app/auth/views/index.vue (100%)
 rename src/{ => server}/web/app/base.pug (76%)
 rename src/{ => server}/web/app/boot.js (100%)
 rename src/{ => server}/web/app/ch/script.ts (100%)
 rename src/{ => server}/web/app/ch/style.styl (100%)
 rename src/{ => server}/web/app/ch/tags/channel.tag (100%)
 rename src/{ => server}/web/app/ch/tags/header.tag (100%)
 rename src/{ => server}/web/app/ch/tags/index.tag (100%)
 rename src/{ => server}/web/app/ch/tags/index.ts (100%)
 rename src/{ => server}/web/app/common/define-widget.ts (100%)
 rename src/{ => server}/web/app/common/mios.ts (100%)
 rename src/{ => server}/web/app/common/scripts/check-for-update.ts (100%)
 rename src/{ => server}/web/app/common/scripts/compose-notification.ts (100%)
 rename src/{ => server}/web/app/common/scripts/contains.ts (100%)
 rename src/{ => server}/web/app/common/scripts/copy-to-clipboard.ts (100%)
 rename src/{ => server}/web/app/common/scripts/date-stringify.ts (100%)
 rename src/{ => server}/web/app/common/scripts/fuck-ad-block.ts (100%)
 rename src/{ => server}/web/app/common/scripts/gcd.ts (100%)
 rename src/{ => server}/web/app/common/scripts/get-kao.ts (100%)
 rename src/{ => server}/web/app/common/scripts/get-median.ts (100%)
 rename src/{ => server}/web/app/common/scripts/loading.ts (100%)
 rename src/{ => server}/web/app/common/scripts/parse-search-query.ts (100%)
 rename src/{ => server}/web/app/common/scripts/streaming/channel.ts (100%)
 rename src/{ => server}/web/app/common/scripts/streaming/drive.ts (100%)
 rename src/{ => server}/web/app/common/scripts/streaming/home.ts (100%)
 rename src/{ => server}/web/app/common/scripts/streaming/messaging-index.ts (100%)
 rename src/{ => server}/web/app/common/scripts/streaming/messaging.ts (100%)
 rename src/{ => server}/web/app/common/scripts/streaming/othello-game.ts (100%)
 rename src/{ => server}/web/app/common/scripts/streaming/othello.ts (100%)
 rename src/{ => server}/web/app/common/scripts/streaming/requests.ts (100%)
 rename src/{ => server}/web/app/common/scripts/streaming/server.ts (100%)
 rename src/{ => server}/web/app/common/scripts/streaming/stream-manager.ts (100%)
 rename src/{ => server}/web/app/common/scripts/streaming/stream.ts (100%)
 rename src/{ => server}/web/app/common/views/components/autocomplete.vue (100%)
 rename src/{ => server}/web/app/common/views/components/connect-failed.troubleshooter.vue (100%)
 rename src/{ => server}/web/app/common/views/components/connect-failed.vue (100%)
 rename src/{ => server}/web/app/common/views/components/ellipsis.vue (100%)
 rename src/{ => server}/web/app/common/views/components/file-type-icon.vue (100%)
 rename src/{ => server}/web/app/common/views/components/forkit.vue (100%)
 rename src/{ => server}/web/app/common/views/components/index.ts (100%)
 rename src/{ => server}/web/app/common/views/components/media-list.vue (100%)
 rename src/{ => server}/web/app/common/views/components/messaging-room.form.vue (100%)
 rename src/{ => server}/web/app/common/views/components/messaging-room.message.vue (100%)
 rename src/{ => server}/web/app/common/views/components/messaging-room.vue (100%)
 rename src/{ => server}/web/app/common/views/components/messaging.vue (100%)
 rename src/{ => server}/web/app/common/views/components/nav.vue (100%)
 rename src/{ => server}/web/app/common/views/components/othello.game.vue (100%)
 rename src/{ => server}/web/app/common/views/components/othello.gameroom.vue (100%)
 rename src/{ => server}/web/app/common/views/components/othello.room.vue (100%)
 rename src/{ => server}/web/app/common/views/components/othello.vue (100%)
 rename src/{ => server}/web/app/common/views/components/poll-editor.vue (100%)
 rename src/{ => server}/web/app/common/views/components/poll.vue (100%)
 rename src/{ => server}/web/app/common/views/components/post-html.ts (100%)
 rename src/{ => server}/web/app/common/views/components/post-menu.vue (100%)
 rename src/{ => server}/web/app/common/views/components/reaction-icon.vue (100%)
 rename src/{ => server}/web/app/common/views/components/reaction-picker.vue (100%)
 rename src/{ => server}/web/app/common/views/components/reactions-viewer.vue (100%)
 rename src/{ => server}/web/app/common/views/components/signin.vue (100%)
 rename src/{ => server}/web/app/common/views/components/signup.vue (100%)
 rename src/{ => server}/web/app/common/views/components/special-message.vue (100%)
 rename src/{ => server}/web/app/common/views/components/stream-indicator.vue (100%)
 rename src/{ => server}/web/app/common/views/components/switch.vue (100%)
 rename src/{ => server}/web/app/common/views/components/time.vue (100%)
 rename src/{ => server}/web/app/common/views/components/timer.vue (100%)
 rename src/{ => server}/web/app/common/views/components/twitter-setting.vue (100%)
 rename src/{ => server}/web/app/common/views/components/uploader.vue (100%)
 rename src/{ => server}/web/app/common/views/components/url-preview.vue (100%)
 rename src/{ => server}/web/app/common/views/components/url.vue (100%)
 rename src/{ => server}/web/app/common/views/components/welcome-timeline.vue (100%)
 rename src/{ => server}/web/app/common/views/directives/autocomplete.ts (100%)
 rename src/{ => server}/web/app/common/views/directives/index.ts (100%)
 rename src/{ => server}/web/app/common/views/filters/bytes.ts (100%)
 rename src/{ => server}/web/app/common/views/filters/index.ts (100%)
 rename src/{ => server}/web/app/common/views/filters/number.ts (100%)
 rename src/{ => server}/web/app/common/views/widgets/access-log.vue (100%)
 rename src/{ => server}/web/app/common/views/widgets/broadcast.vue (100%)
 rename src/{ => server}/web/app/common/views/widgets/calendar.vue (100%)
 rename src/{ => server}/web/app/common/views/widgets/donation.vue (100%)
 rename src/{ => server}/web/app/common/views/widgets/index.ts (100%)
 rename src/{ => server}/web/app/common/views/widgets/nav.vue (100%)
 rename src/{ => server}/web/app/common/views/widgets/photo-stream.vue (100%)
 rename src/{ => server}/web/app/common/views/widgets/rss.vue (100%)
 rename src/{ => server}/web/app/common/views/widgets/server.cpu-memory.vue (100%)
 rename src/{ => server}/web/app/common/views/widgets/server.cpu.vue (100%)
 rename src/{ => server}/web/app/common/views/widgets/server.disk.vue (100%)
 rename src/{ => server}/web/app/common/views/widgets/server.info.vue (100%)
 rename src/{ => server}/web/app/common/views/widgets/server.memory.vue (100%)
 rename src/{ => server}/web/app/common/views/widgets/server.pie.vue (100%)
 rename src/{ => server}/web/app/common/views/widgets/server.uptimes.vue (100%)
 rename src/{ => server}/web/app/common/views/widgets/server.vue (100%)
 rename src/{ => server}/web/app/common/views/widgets/slideshow.vue (100%)
 rename src/{ => server}/web/app/common/views/widgets/tips.vue (100%)
 rename src/{ => server}/web/app/common/views/widgets/version.vue (100%)
 rename src/{ => server}/web/app/config.ts (100%)
 rename src/{ => server}/web/app/desktop/api/choose-drive-file.ts (100%)
 rename src/{ => server}/web/app/desktop/api/choose-drive-folder.ts (100%)
 rename src/{ => server}/web/app/desktop/api/contextmenu.ts (100%)
 rename src/{ => server}/web/app/desktop/api/dialog.ts (100%)
 rename src/{ => server}/web/app/desktop/api/input.ts (100%)
 rename src/{ => server}/web/app/desktop/api/notify.ts (100%)
 rename src/{ => server}/web/app/desktop/api/post.ts (100%)
 rename src/{ => server}/web/app/desktop/api/update-avatar.ts (100%)
 rename src/{ => server}/web/app/desktop/api/update-banner.ts (100%)
 rename src/{ => server}/web/app/desktop/assets/grid.svg (100%)
 rename src/{ => server}/web/app/desktop/assets/header-logo-white.svg (100%)
 rename src/{ => server}/web/app/desktop/assets/header-logo.svg (100%)
 rename src/{ => server}/web/app/desktop/assets/index.jpg (100%)
 rename src/{ => server}/web/app/desktop/assets/remove.png (100%)
 rename src/{ => server}/web/app/desktop/script.ts (100%)
 rename src/{ => server}/web/app/desktop/style.styl (100%)
 rename src/{ => server}/web/app/desktop/ui.styl (100%)
 rename src/{ => server}/web/app/desktop/views/components/activity.calendar.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/activity.chart.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/activity.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/analog-clock.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/calendar.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/choose-file-from-drive-window.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/choose-folder-from-drive-window.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/context-menu.menu.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/context-menu.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/crop-window.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/dialog.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/drive-window.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/drive.file.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/drive.folder.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/drive.nav-folder.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/drive.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/ellipsis-icon.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/follow-button.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/followers-window.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/followers.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/following-window.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/following.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/friends-maker.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/game-window.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/home.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/index.ts (100%)
 rename src/{ => server}/web/app/desktop/views/components/input-dialog.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/media-image-dialog.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/media-image.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/media-video-dialog.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/media-video.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/mentions.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/messaging-room-window.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/messaging-window.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/notifications.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/post-detail.sub.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/post-detail.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/post-form-window.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/post-form.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/post-preview.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/posts.post.sub.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/posts.post.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/posts.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/progress-dialog.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/repost-form-window.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/repost-form.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/settings-window.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/settings.2fa.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/settings.api.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/settings.apps.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/settings.drive.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/settings.mute.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/settings.password.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/settings.profile.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/settings.signins.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/settings.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/sub-post-content.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/taskmanager.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/timeline.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/ui-notification.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/ui.header.account.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/ui.header.clock.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/ui.header.nav.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/ui.header.notifications.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/ui.header.post.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/ui.header.search.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/ui.header.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/ui.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/user-preview.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/users-list.item.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/users-list.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/widget-container.vue (100%)
 rename src/{ => server}/web/app/desktop/views/components/window.vue (100%)
 rename src/{ => server}/web/app/desktop/views/directives/index.ts (100%)
 rename src/{ => server}/web/app/desktop/views/directives/user-preview.ts (100%)
 rename src/{ => server}/web/app/desktop/views/pages/drive.vue (100%)
 rename src/{ => server}/web/app/desktop/views/pages/home-customize.vue (100%)
 rename src/{ => server}/web/app/desktop/views/pages/home.vue (100%)
 rename src/{ => server}/web/app/desktop/views/pages/index.vue (100%)
 rename src/{ => server}/web/app/desktop/views/pages/messaging-room.vue (100%)
 rename src/{ => server}/web/app/desktop/views/pages/othello.vue (100%)
 rename src/{ => server}/web/app/desktop/views/pages/post.vue (100%)
 rename src/{ => server}/web/app/desktop/views/pages/search.vue (100%)
 rename src/{ => server}/web/app/desktop/views/pages/selectdrive.vue (100%)
 rename src/{ => server}/web/app/desktop/views/pages/user/user.followers-you-know.vue (100%)
 rename src/{ => server}/web/app/desktop/views/pages/user/user.friends.vue (100%)
 rename src/{ => server}/web/app/desktop/views/pages/user/user.header.vue (100%)
 rename src/{ => server}/web/app/desktop/views/pages/user/user.home.vue (100%)
 rename src/{ => server}/web/app/desktop/views/pages/user/user.photos.vue (100%)
 rename src/{ => server}/web/app/desktop/views/pages/user/user.profile.vue (100%)
 rename src/{ => server}/web/app/desktop/views/pages/user/user.timeline.vue (100%)
 rename src/{ => server}/web/app/desktop/views/pages/user/user.vue (100%)
 rename src/{ => server}/web/app/desktop/views/pages/welcome.vue (100%)
 rename src/{ => server}/web/app/desktop/views/widgets/activity.vue (100%)
 rename src/{ => server}/web/app/desktop/views/widgets/channel.channel.form.vue (100%)
 rename src/{ => server}/web/app/desktop/views/widgets/channel.channel.post.vue (100%)
 rename src/{ => server}/web/app/desktop/views/widgets/channel.channel.vue (100%)
 rename src/{ => server}/web/app/desktop/views/widgets/channel.vue (100%)
 rename src/{ => server}/web/app/desktop/views/widgets/index.ts (100%)
 rename src/{ => server}/web/app/desktop/views/widgets/messaging.vue (100%)
 rename src/{ => server}/web/app/desktop/views/widgets/notifications.vue (100%)
 rename src/{ => server}/web/app/desktop/views/widgets/polls.vue (100%)
 rename src/{ => server}/web/app/desktop/views/widgets/post-form.vue (100%)
 rename src/{ => server}/web/app/desktop/views/widgets/profile.vue (100%)
 rename src/{ => server}/web/app/desktop/views/widgets/timemachine.vue (100%)
 rename src/{ => server}/web/app/desktop/views/widgets/trends.vue (100%)
 rename src/{ => server}/web/app/desktop/views/widgets/users.vue (100%)
 rename src/{ => server}/web/app/dev/script.ts (100%)
 rename src/{ => server}/web/app/dev/style.styl (100%)
 rename src/{ => server}/web/app/dev/views/app.vue (100%)
 rename src/{ => server}/web/app/dev/views/apps.vue (100%)
 rename src/{ => server}/web/app/dev/views/index.vue (100%)
 rename src/{ => server}/web/app/dev/views/new-app.vue (100%)
 rename src/{ => server}/web/app/dev/views/ui.vue (100%)
 rename src/{ => server}/web/app/init.css (100%)
 rename src/{ => server}/web/app/init.ts (100%)
 rename src/{ => server}/web/app/mobile/api/choose-drive-file.ts (100%)
 rename src/{ => server}/web/app/mobile/api/choose-drive-folder.ts (100%)
 rename src/{ => server}/web/app/mobile/api/dialog.ts (100%)
 rename src/{ => server}/web/app/mobile/api/input.ts (100%)
 rename src/{ => server}/web/app/mobile/api/notify.ts (100%)
 rename src/{ => server}/web/app/mobile/api/post.ts (100%)
 rename src/{ => server}/web/app/mobile/script.ts (100%)
 rename src/{ => server}/web/app/mobile/style.styl (100%)
 rename src/{ => server}/web/app/mobile/views/components/activity.vue (100%)
 rename src/{ => server}/web/app/mobile/views/components/drive-file-chooser.vue (100%)
 rename src/{ => server}/web/app/mobile/views/components/drive-folder-chooser.vue (100%)
 rename src/{ => server}/web/app/mobile/views/components/drive.file-detail.vue (100%)
 rename src/{ => server}/web/app/mobile/views/components/drive.file.vue (100%)
 rename src/{ => server}/web/app/mobile/views/components/drive.folder.vue (100%)
 rename src/{ => server}/web/app/mobile/views/components/drive.vue (100%)
 rename src/{ => server}/web/app/mobile/views/components/follow-button.vue (100%)
 rename src/{ => server}/web/app/mobile/views/components/friends-maker.vue (100%)
 rename src/{ => server}/web/app/mobile/views/components/index.ts (100%)
 rename src/{ => server}/web/app/mobile/views/components/media-image.vue (100%)
 rename src/{ => server}/web/app/mobile/views/components/media-video.vue (100%)
 rename src/{ => server}/web/app/mobile/views/components/notification-preview.vue (100%)
 rename src/{ => server}/web/app/mobile/views/components/notification.vue (100%)
 rename src/{ => server}/web/app/mobile/views/components/notifications.vue (100%)
 rename src/{ => server}/web/app/mobile/views/components/notify.vue (100%)
 rename src/{ => server}/web/app/mobile/views/components/post-card.vue (100%)
 rename src/{ => server}/web/app/mobile/views/components/post-detail.sub.vue (100%)
 rename src/{ => server}/web/app/mobile/views/components/post-detail.vue (100%)
 rename src/{ => server}/web/app/mobile/views/components/post-form.vue (100%)
 rename src/{ => server}/web/app/mobile/views/components/post-preview.vue (100%)
 rename src/{ => server}/web/app/mobile/views/components/post.sub.vue (100%)
 rename src/{ => server}/web/app/mobile/views/components/post.vue (100%)
 rename src/{ => server}/web/app/mobile/views/components/posts.vue (100%)
 rename src/{ => server}/web/app/mobile/views/components/sub-post-content.vue (100%)
 rename src/{ => server}/web/app/mobile/views/components/timeline.vue (100%)
 rename src/{ => server}/web/app/mobile/views/components/ui.header.vue (100%)
 rename src/{ => server}/web/app/mobile/views/components/ui.nav.vue (100%)
 rename src/{ => server}/web/app/mobile/views/components/ui.vue (100%)
 rename src/{ => server}/web/app/mobile/views/components/user-card.vue (100%)
 rename src/{ => server}/web/app/mobile/views/components/user-preview.vue (100%)
 rename src/{ => server}/web/app/mobile/views/components/user-timeline.vue (100%)
 rename src/{ => server}/web/app/mobile/views/components/users-list.vue (100%)
 rename src/{ => server}/web/app/mobile/views/components/widget-container.vue (100%)
 rename src/{ => server}/web/app/mobile/views/directives/index.ts (100%)
 rename src/{ => server}/web/app/mobile/views/directives/user-preview.ts (100%)
 rename src/{ => server}/web/app/mobile/views/pages/drive.vue (100%)
 rename src/{ => server}/web/app/mobile/views/pages/followers.vue (100%)
 rename src/{ => server}/web/app/mobile/views/pages/following.vue (100%)
 rename src/{ => server}/web/app/mobile/views/pages/home.vue (100%)
 rename src/{ => server}/web/app/mobile/views/pages/index.vue (100%)
 rename src/{ => server}/web/app/mobile/views/pages/messaging-room.vue (100%)
 rename src/{ => server}/web/app/mobile/views/pages/messaging.vue (100%)
 rename src/{ => server}/web/app/mobile/views/pages/notifications.vue (100%)
 rename src/{ => server}/web/app/mobile/views/pages/othello.vue (100%)
 rename src/{ => server}/web/app/mobile/views/pages/post.vue (100%)
 rename src/{ => server}/web/app/mobile/views/pages/profile-setting.vue (100%)
 rename src/{ => server}/web/app/mobile/views/pages/search.vue (100%)
 rename src/{ => server}/web/app/mobile/views/pages/selectdrive.vue (100%)
 rename src/{ => server}/web/app/mobile/views/pages/settings.vue (100%)
 rename src/{ => server}/web/app/mobile/views/pages/signup.vue (100%)
 rename src/{ => server}/web/app/mobile/views/pages/user.vue (100%)
 rename src/{ => server}/web/app/mobile/views/pages/user/home.followers-you-know.vue (100%)
 rename src/{ => server}/web/app/mobile/views/pages/user/home.friends.vue (100%)
 rename src/{ => server}/web/app/mobile/views/pages/user/home.photos.vue (100%)
 rename src/{ => server}/web/app/mobile/views/pages/user/home.posts.vue (100%)
 rename src/{ => server}/web/app/mobile/views/pages/user/home.vue (100%)
 rename src/{ => server}/web/app/mobile/views/pages/welcome.vue (100%)
 rename src/{ => server}/web/app/mobile/views/widgets/activity.vue (100%)
 rename src/{ => server}/web/app/mobile/views/widgets/index.ts (100%)
 rename src/{ => server}/web/app/mobile/views/widgets/profile.vue (100%)
 rename src/{ => server}/web/app/reset.styl (100%)
 rename src/{ => server}/web/app/safe.js (100%)
 rename src/{ => server}/web/app/stats/style.styl (100%)
 rename src/{ => server}/web/app/stats/tags/index.tag (100%)
 rename src/{ => server}/web/app/stats/tags/index.ts (100%)
 rename src/{ => server}/web/app/status/style.styl (100%)
 rename src/{ => server}/web/app/status/tags/index.tag (100%)
 rename src/{ => server}/web/app/status/tags/index.ts (100%)
 rename src/{ => server}/web/app/sw.js (100%)
 rename src/{ => server}/web/app/tsconfig.json (100%)
 rename src/{ => server}/web/app/v.d.ts (100%)
 rename src/{ => server}/web/assets/404.js (100%)
 rename src/{ => server}/web/assets/code-highlight.css (100%)
 rename src/{ => server}/web/assets/error.jpg (100%)
 rename src/{ => server}/web/assets/favicon.ico (100%)
 rename src/{ => server}/web/assets/label.svg (100%)
 rename src/{ => server}/web/assets/manifest.json (100%)
 rename src/{ => server}/web/assets/message.mp3 (100%)
 rename src/{ => server}/web/assets/othello-put-me.mp3 (100%)
 rename src/{ => server}/web/assets/othello-put-you.mp3 (100%)
 rename src/{ => server}/web/assets/post.mp3 (100%)
 rename src/{ => server}/web/assets/reactions/angry.png (100%)
 rename src/{ => server}/web/assets/reactions/confused.png (100%)
 rename src/{ => server}/web/assets/reactions/congrats.png (100%)
 rename src/{ => server}/web/assets/reactions/hmm.png (100%)
 rename src/{ => server}/web/assets/reactions/laugh.png (100%)
 rename src/{ => server}/web/assets/reactions/like.png (100%)
 rename src/{ => server}/web/assets/reactions/love.png (100%)
 rename src/{ => server}/web/assets/reactions/pudding.png (100%)
 rename src/{ => server}/web/assets/reactions/surprise.png (100%)
 rename src/{ => server}/web/assets/recover.html (100%)
 rename src/{ => server}/web/assets/title.svg (100%)
 rename src/{ => server}/web/assets/unread.svg (100%)
 rename src/{ => server}/web/assets/welcome-bg.svg (100%)
 rename src/{ => server}/web/assets/welcome-fg.svg (100%)
 rename src/{ => server}/web/const.styl (74%)
 rename src/{ => server}/web/docs/about.en.pug (100%)
 rename src/{ => server}/web/docs/about.ja.pug (100%)
 rename src/{ => server}/web/docs/api.ja.pug (100%)
 rename src/{ => server}/web/docs/api/endpoints/posts/create.yaml (100%)
 rename src/{ => server}/web/docs/api/endpoints/posts/timeline.yaml (100%)
 rename src/{ => server}/web/docs/api/endpoints/style.styl (100%)
 rename src/{ => server}/web/docs/api/endpoints/view.pug (100%)
 rename src/{ => server}/web/docs/api/entities/drive-file.yaml (100%)
 rename src/{ => server}/web/docs/api/entities/post.yaml (100%)
 rename src/{ => server}/web/docs/api/entities/style.styl (100%)
 rename src/{ => server}/web/docs/api/entities/user.yaml (100%)
 rename src/{ => server}/web/docs/api/entities/view.pug (100%)
 rename src/{ => server}/web/docs/api/gulpfile.ts (80%)
 rename src/{ => server}/web/docs/api/mixins.pug (100%)
 rename src/{ => server}/web/docs/api/style.styl (100%)
 rename src/{ => server}/web/docs/gulpfile.ts (74%)
 rename src/{ => server}/web/docs/index.en.pug (100%)
 rename src/{ => server}/web/docs/index.ja.pug (100%)
 rename src/{ => server}/web/docs/layout.pug (100%)
 rename src/{ => server}/web/docs/license.en.pug (100%)
 rename src/{ => server}/web/docs/license.ja.pug (100%)
 rename src/{ => server}/web/docs/mute.ja.pug (100%)
 rename src/{ => server}/web/docs/search.ja.pug (100%)
 rename src/{ => server}/web/docs/server.ts (100%)
 rename src/{ => server}/web/docs/style.styl (100%)
 rename src/{ => server}/web/docs/tou.ja.pug (100%)
 rename src/{ => server}/web/docs/ui.styl (100%)
 rename src/{ => server}/web/docs/vars.ts (76%)
 rename src/{ => server}/web/element.scss (91%)
 rename src/{ => server}/web/server.ts (100%)
 rename src/{ => server}/web/service/url-preview.ts (100%)
 rename src/{ => server}/web/style.styl (100%)

diff --git a/gulpfile.ts b/gulpfile.ts
index 9c61e3a1c..11f34c962 100644
--- a/gulpfile.ts
+++ b/gulpfile.ts
@@ -22,7 +22,7 @@ import * as replace from 'gulp-replace';
 import * as htmlmin from 'gulp-htmlmin';
 const uglifyes = require('uglify-es');
 
-import { fa } from './src/common/build/fa';
+import { fa } from './src/build/fa';
 import version from './src/version';
 import config from './src/conf';
 
@@ -39,7 +39,7 @@ if (isDebug) {
 
 const constants = require('./src/const.json');
 
-require('./src/web/docs/gulpfile.ts');
+require('./src/server/web/docs/gulpfile.ts');
 
 gulp.task('build', [
 	'build:js',
@@ -52,7 +52,7 @@ gulp.task('build', [
 gulp.task('rebuild', ['clean', 'build']);
 
 gulp.task('build:js', () =>
-	gulp.src(['./src/**/*.js', '!./src/web/**/*.js'])
+	gulp.src(['./src/**/*.js', '!./src/server/web/**/*.js'])
 		.pipe(gulp.dest('./built/'))
 );
 
@@ -71,7 +71,7 @@ gulp.task('build:copy', () =>
 	gulp.src([
 		'./build/Release/crypto_key.node',
 		'./src/**/assets/**/*',
-		'!./src/web/app/**/assets/**/*'
+		'!./src/server/web/app/**/assets/**/*'
 	]).pipe(gulp.dest('./built/'))
 );
 
@@ -121,7 +121,7 @@ gulp.task('build:client', [
 ]);
 
 gulp.task('build:client:script', () =>
-	gulp.src(['./src/web/app/boot.js', './src/web/app/safe.js'])
+	gulp.src(['./src/server/web/app/boot.js', './src/server/web/app/safe.js'])
 		.pipe(replace('VERSION', JSON.stringify(version)))
 		.pipe(replace('API', JSON.stringify(config.api_url)))
 		.pipe(replace('ENV', JSON.stringify(env)))
@@ -129,15 +129,15 @@ gulp.task('build:client:script', () =>
 		.pipe(isProduction ? uglify({
 			toplevel: true
 		} as any) : gutil.noop())
-		.pipe(gulp.dest('./built/web/assets/')) as any
+		.pipe(gulp.dest('./built/server/web/assets/')) as any
 );
 
 gulp.task('build:client:styles', () =>
-	gulp.src('./src/web/app/init.css')
+	gulp.src('./src/server/web/app/init.css')
 		.pipe(isProduction
 			? (cssnano as any)()
 			: gutil.noop())
-		.pipe(gulp.dest('./built/web/assets/'))
+		.pipe(gulp.dest('./built/server/web/assets/'))
 );
 
 gulp.task('copy:client', [
@@ -145,14 +145,14 @@ gulp.task('copy:client', [
 ], () =>
 		gulp.src([
 			'./assets/**/*',
-			'./src/web/assets/**/*',
-			'./src/web/app/*/assets/**/*'
+			'./src/server/web/assets/**/*',
+			'./src/server/web/app/*/assets/**/*'
 		])
 			.pipe(isProduction ? (imagemin as any)() : gutil.noop())
 			.pipe(rename(path => {
 				path.dirname = path.dirname.replace('assets', '.');
 			}))
-			.pipe(gulp.dest('./built/web/assets/'))
+			.pipe(gulp.dest('./built/server/web/assets/'))
 );
 
 gulp.task('build:client:pug', [
@@ -160,13 +160,13 @@ gulp.task('build:client:pug', [
 	'build:client:script',
 	'build:client:styles'
 ], () =>
-		gulp.src('./src/web/app/base.pug')
+		gulp.src('./src/server/web/app/base.pug')
 			.pipe(pug({
 				locals: {
 					themeColor: constants.themeColor,
 					facss: fa.dom.css(),
 					//hljscss: fs.readFileSync('./node_modules/highlight.js/styles/default.css', 'utf8')
-					hljscss: fs.readFileSync('./src/web/assets/code-highlight.css', 'utf8')
+					hljscss: fs.readFileSync('./src/server/web/assets/code-highlight.css', 'utf8')
 				}
 			}))
 			.pipe(htmlmin({
@@ -201,5 +201,5 @@ gulp.task('build:client:pug', [
 				// CSSも圧縮する
 				minifyCSS: true
 			}))
-			.pipe(gulp.dest('./built/web/app/'))
+			.pipe(gulp.dest('./built/server/web/app/'))
 );
diff --git a/package.json b/package.json
index d9ed80b47..290fb00d7 100644
--- a/package.json
+++ b/package.json
@@ -135,6 +135,7 @@
 		"is-url": "1.2.3",
 		"js-yaml": "3.11.0",
 		"jsdom": "^11.6.2",
+		"kue": "^0.11.6",
 		"license-checker": "18.0.0",
 		"loader-utils": "1.1.0",
 		"mecab-async": "0.1.2",
@@ -149,6 +150,7 @@
 		"nan": "^2.10.0",
 		"node-sass": "4.7.2",
 		"node-sass-json-importer": "3.1.5",
+		"nopt": "^4.0.1",
 		"nprogress": "0.2.0",
 		"object-assign-deep": "0.3.1",
 		"on-build-webpack": "0.1.0",
diff --git a/src/common/build/fa.ts b/src/build/fa.ts
similarity index 100%
rename from src/common/build/fa.ts
rename to src/build/fa.ts
diff --git a/src/common/build/i18n.ts b/src/build/i18n.ts
similarity index 96%
rename from src/common/build/i18n.ts
rename to src/build/i18n.ts
index 5e3c0381a..b9b740321 100644
--- a/src/common/build/i18n.ts
+++ b/src/build/i18n.ts
@@ -2,7 +2,7 @@
  * Replace i18n texts
  */
 
-import locale from '../../../locales';
+import locale from '../../locales';
 
 export default class Replacer {
 	private lang: string;
diff --git a/src/common/build/license.ts b/src/build/license.ts
similarity index 72%
rename from src/common/build/license.ts
rename to src/build/license.ts
index e5c264df8..d36af665c 100644
--- a/src/common/build/license.ts
+++ b/src/build/license.ts
@@ -1,6 +1,6 @@
 import * as fs from 'fs';
 
-const license = fs.readFileSync(__dirname + '/../../../LICENSE', 'utf-8');
+const license = fs.readFileSync(__dirname + '/../../LICENSE', 'utf-8');
 
 const licenseHtml = license
 	.replace(/\r\n/g, '\n')
diff --git a/src/index.ts b/src/index.ts
index 218455d6f..bd9b094d9 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -24,6 +24,8 @@ import stats from './utils/stats';
 import { Config, path as configPath } from './config';
 import loadConfig from './config';
 
+import parseOpt from './parse-opt';
+
 const clusterLog = debug('misskey:cluster');
 const ev = new Xev();
 
@@ -36,20 +38,22 @@ main();
  * Init process
  */
 function main() {
+	const opt = parseOpt(process.argv, 2);
+
 	if (cluster.isMaster) {
-		masterMain();
+		masterMain(opt);
 
 		ev.mount();
 		stats();
 	} else {
-		workerMain();
+		workerMain(opt);
 	}
 }
 
 /**
  * Init master process
  */
-async function masterMain() {
+async function masterMain(opt) {
 	let config: Config;
 
 	try {
@@ -69,19 +73,35 @@ async function masterMain() {
 	}
 
 	spawnWorkers(() => {
-		Logger.info(chalk.bold.green(
-			`Now listening on port ${chalk.underline(config.port.toString())}`));
+		if (!opt['only-processor']) {
+			Logger.info(chalk.bold.green(
+				`Now listening on port ${chalk.underline(config.port.toString())}`));
 
-		Logger.info(chalk.bold.green(config.url));
+			Logger.info(chalk.bold.green(config.url));
+		}
+
+		if (!opt['only-server']) {
+			Logger.info(chalk.bold.green('Now processing jobs'));
+		}
 	});
 }
 
 /**
  * Init worker process
  */
-function workerMain() {
-	// start server
-	require('./server');
+async function workerMain(opt) {
+	if (!opt['only-processor']) {
+		// start server
+		await require('./server').default();
+	}
+
+	if (!opt['only-server']) {
+		// start processor
+		require('./processor').default();
+	}
+
+	// Send a 'ready' message to parent process
+	process.send('ready');
 }
 
 /**
diff --git a/src/parse-opt.ts b/src/parse-opt.ts
new file mode 100644
index 000000000..61dc60c6c
--- /dev/null
+++ b/src/parse-opt.ts
@@ -0,0 +1,17 @@
+const nopt = require('nopt');
+
+export default (vector, index) => {
+	const parsed = nopt({
+		'only-processor': Boolean,
+		'only-server': Boolean
+	}, {
+		p: ['--only-processor'],
+		s: ['--only-server']
+	}, vector, index);
+
+	if (parsed['only-processor'] && parsed['only-server']) {
+		throw 'only-processor option and only-server option cannot be set at the same time';
+	}
+
+	return parsed;
+};
diff --git a/src/processor/index.ts b/src/processor/index.ts
new file mode 100644
index 000000000..f06cf24e8
--- /dev/null
+++ b/src/processor/index.ts
@@ -0,0 +1,4 @@
+import queue from '../queue';
+import reportGitHubFailure from './report-github-failure';
+
+export default () => queue.process('gitHubFailureReport', reportGitHubFailure);
diff --git a/src/processor/report-github-failure.ts b/src/processor/report-github-failure.ts
new file mode 100644
index 000000000..f42071142
--- /dev/null
+++ b/src/processor/report-github-failure.ts
@@ -0,0 +1,29 @@
+import * as request from 'request';
+import User from '../server/api/models/user';
+const createPost = require('../server/api/endpoints/posts/create');
+
+export default ({ data }, done) => {
+	const asyncBot = User.findOne({ _id: data.userId });
+
+	// Fetch parent status
+	request({
+		url: `${data.parentUrl}/statuses`,
+		headers: {
+			'User-Agent': 'misskey'
+		}
+	}, async (err, res, body) => {
+		if (err) {
+			console.error(err);
+			return;
+		}
+		const parentStatuses = JSON.parse(body);
+		const parentState = parentStatuses[0].state;
+		const stillFailed = parentState == 'failure' || parentState == 'error';
+		const text = stillFailed ?
+			`**⚠️BUILD STILL FAILED⚠️**: ?[${data.message}](${data.htmlUrl})` :
+			`**🚨BUILD FAILED🚨**: →→→?[${data.message}](${data.htmlUrl})←←←`;
+
+		createPost({ text }, await asyncBot);
+		done();
+	});
+};
diff --git a/src/queue.ts b/src/queue.ts
new file mode 100644
index 000000000..6089e0a7f
--- /dev/null
+++ b/src/queue.ts
@@ -0,0 +1,10 @@
+import { createQueue } from 'kue';
+import config from './conf';
+
+export default createQueue({
+	redis: {
+		port: config.redis.port,
+		host: config.redis.host,
+		auth: config.redis.pass
+	}
+});
diff --git a/src/api/api-handler.ts b/src/server/api/api-handler.ts
similarity index 100%
rename from src/api/api-handler.ts
rename to src/server/api/api-handler.ts
diff --git a/src/api/authenticate.ts b/src/server/api/authenticate.ts
similarity index 100%
rename from src/api/authenticate.ts
rename to src/server/api/authenticate.ts
diff --git a/src/api/bot/core.ts b/src/server/api/bot/core.ts
similarity index 100%
rename from src/api/bot/core.ts
rename to src/server/api/bot/core.ts
diff --git a/src/api/bot/interfaces/line.ts b/src/server/api/bot/interfaces/line.ts
similarity index 98%
rename from src/api/bot/interfaces/line.ts
rename to src/server/api/bot/interfaces/line.ts
index 8036b2fde..5b3e9107f 100644
--- a/src/api/bot/interfaces/line.ts
+++ b/src/server/api/bot/interfaces/line.ts
@@ -3,9 +3,9 @@ import * as express from 'express';
 import * as request from 'request';
 import * as crypto from 'crypto';
 import User from '../../models/user';
-import config from '../../../conf';
+import config from '../../../../conf';
 import BotCore from '../core';
-import _redis from '../../../db/redis';
+import _redis from '../../../../db/redis';
 import prominence = require('prominence');
 import getAcct from '../../../common/user/get-acct';
 import parseAcct from '../../../common/user/parse-acct';
diff --git a/src/api/common/drive/add-file.ts b/src/server/api/common/drive/add-file.ts
similarity index 99%
rename from src/api/common/drive/add-file.ts
rename to src/server/api/common/drive/add-file.ts
index c4f2f212a..5f3c69c15 100644
--- a/src/api/common/drive/add-file.ts
+++ b/src/server/api/common/drive/add-file.ts
@@ -15,7 +15,7 @@ import DriveFolder from '../../models/drive-folder';
 import { pack } from '../../models/drive-file';
 import event, { publishDriveStream } from '../../event';
 import getAcct from '../../../common/user/get-acct';
-import config from '../../../conf';
+import config from '../../../../conf';
 
 const gm = _gm.subClass({
 	imageMagick: true
diff --git a/src/api/common/drive/upload_from_url.ts b/src/server/api/common/drive/upload_from_url.ts
similarity index 100%
rename from src/api/common/drive/upload_from_url.ts
rename to src/server/api/common/drive/upload_from_url.ts
diff --git a/src/api/common/generate-native-user-token.ts b/src/server/api/common/generate-native-user-token.ts
similarity index 100%
rename from src/api/common/generate-native-user-token.ts
rename to src/server/api/common/generate-native-user-token.ts
diff --git a/src/api/common/get-friends.ts b/src/server/api/common/get-friends.ts
similarity index 100%
rename from src/api/common/get-friends.ts
rename to src/server/api/common/get-friends.ts
diff --git a/src/api/common/get-host-lower.ts b/src/server/api/common/get-host-lower.ts
similarity index 100%
rename from src/api/common/get-host-lower.ts
rename to src/server/api/common/get-host-lower.ts
diff --git a/src/api/common/is-native-token.ts b/src/server/api/common/is-native-token.ts
similarity index 100%
rename from src/api/common/is-native-token.ts
rename to src/server/api/common/is-native-token.ts
diff --git a/src/api/common/notify.ts b/src/server/api/common/notify.ts
similarity index 100%
rename from src/api/common/notify.ts
rename to src/server/api/common/notify.ts
diff --git a/src/api/common/push-sw.ts b/src/server/api/common/push-sw.ts
similarity index 97%
rename from src/api/common/push-sw.ts
rename to src/server/api/common/push-sw.ts
index 2993c760e..b33715eb1 100644
--- a/src/api/common/push-sw.ts
+++ b/src/server/api/common/push-sw.ts
@@ -1,7 +1,7 @@
 const push = require('web-push');
 import * as mongo from 'mongodb';
 import Subscription from '../models/sw-subscription';
-import config from '../../conf';
+import config from '../../../conf';
 
 if (config.sw) {
 	// アプリケーションの連絡先と、サーバーサイドの鍵ペアの情報を登録
diff --git a/src/api/common/read-messaging-message.ts b/src/server/api/common/read-messaging-message.ts
similarity index 100%
rename from src/api/common/read-messaging-message.ts
rename to src/server/api/common/read-messaging-message.ts
diff --git a/src/api/common/read-notification.ts b/src/server/api/common/read-notification.ts
similarity index 100%
rename from src/api/common/read-notification.ts
rename to src/server/api/common/read-notification.ts
diff --git a/src/api/common/signin.ts b/src/server/api/common/signin.ts
similarity index 92%
rename from src/api/common/signin.ts
rename to src/server/api/common/signin.ts
index 04c2cdac8..a11ea56c0 100644
--- a/src/api/common/signin.ts
+++ b/src/server/api/common/signin.ts
@@ -1,4 +1,4 @@
-import config from '../../conf';
+import config from '../../../conf';
 
 export default function(res, user, redirect: boolean) {
 	const expires = 1000 * 60 * 60 * 24 * 365; // One Year
diff --git a/src/api/common/text/core/syntax-highlighter.ts b/src/server/api/common/text/core/syntax-highlighter.ts
similarity index 100%
rename from src/api/common/text/core/syntax-highlighter.ts
rename to src/server/api/common/text/core/syntax-highlighter.ts
diff --git a/src/api/common/text/elements/bold.ts b/src/server/api/common/text/elements/bold.ts
similarity index 100%
rename from src/api/common/text/elements/bold.ts
rename to src/server/api/common/text/elements/bold.ts
diff --git a/src/api/common/text/elements/code.ts b/src/server/api/common/text/elements/code.ts
similarity index 100%
rename from src/api/common/text/elements/code.ts
rename to src/server/api/common/text/elements/code.ts
diff --git a/src/api/common/text/elements/emoji.ts b/src/server/api/common/text/elements/emoji.ts
similarity index 100%
rename from src/api/common/text/elements/emoji.ts
rename to src/server/api/common/text/elements/emoji.ts
diff --git a/src/api/common/text/elements/hashtag.ts b/src/server/api/common/text/elements/hashtag.ts
similarity index 100%
rename from src/api/common/text/elements/hashtag.ts
rename to src/server/api/common/text/elements/hashtag.ts
diff --git a/src/api/common/text/elements/inline-code.ts b/src/server/api/common/text/elements/inline-code.ts
similarity index 100%
rename from src/api/common/text/elements/inline-code.ts
rename to src/server/api/common/text/elements/inline-code.ts
diff --git a/src/api/common/text/elements/link.ts b/src/server/api/common/text/elements/link.ts
similarity index 100%
rename from src/api/common/text/elements/link.ts
rename to src/server/api/common/text/elements/link.ts
diff --git a/src/api/common/text/elements/mention.ts b/src/server/api/common/text/elements/mention.ts
similarity index 100%
rename from src/api/common/text/elements/mention.ts
rename to src/server/api/common/text/elements/mention.ts
diff --git a/src/api/common/text/elements/quote.ts b/src/server/api/common/text/elements/quote.ts
similarity index 100%
rename from src/api/common/text/elements/quote.ts
rename to src/server/api/common/text/elements/quote.ts
diff --git a/src/api/common/text/elements/url.ts b/src/server/api/common/text/elements/url.ts
similarity index 100%
rename from src/api/common/text/elements/url.ts
rename to src/server/api/common/text/elements/url.ts
diff --git a/src/api/common/text/index.ts b/src/server/api/common/text/index.ts
similarity index 100%
rename from src/api/common/text/index.ts
rename to src/server/api/common/text/index.ts
diff --git a/src/api/common/watch-post.ts b/src/server/api/common/watch-post.ts
similarity index 100%
rename from src/api/common/watch-post.ts
rename to src/server/api/common/watch-post.ts
diff --git a/src/api/endpoints.ts b/src/server/api/endpoints.ts
similarity index 100%
rename from src/api/endpoints.ts
rename to src/server/api/endpoints.ts
diff --git a/src/api/endpoints/aggregation/posts.ts b/src/server/api/endpoints/aggregation/posts.ts
similarity index 100%
rename from src/api/endpoints/aggregation/posts.ts
rename to src/server/api/endpoints/aggregation/posts.ts
diff --git a/src/api/endpoints/aggregation/posts/reaction.ts b/src/server/api/endpoints/aggregation/posts/reaction.ts
similarity index 100%
rename from src/api/endpoints/aggregation/posts/reaction.ts
rename to src/server/api/endpoints/aggregation/posts/reaction.ts
diff --git a/src/api/endpoints/aggregation/posts/reactions.ts b/src/server/api/endpoints/aggregation/posts/reactions.ts
similarity index 100%
rename from src/api/endpoints/aggregation/posts/reactions.ts
rename to src/server/api/endpoints/aggregation/posts/reactions.ts
diff --git a/src/api/endpoints/aggregation/posts/reply.ts b/src/server/api/endpoints/aggregation/posts/reply.ts
similarity index 100%
rename from src/api/endpoints/aggregation/posts/reply.ts
rename to src/server/api/endpoints/aggregation/posts/reply.ts
diff --git a/src/api/endpoints/aggregation/posts/repost.ts b/src/server/api/endpoints/aggregation/posts/repost.ts
similarity index 100%
rename from src/api/endpoints/aggregation/posts/repost.ts
rename to src/server/api/endpoints/aggregation/posts/repost.ts
diff --git a/src/api/endpoints/aggregation/users.ts b/src/server/api/endpoints/aggregation/users.ts
similarity index 100%
rename from src/api/endpoints/aggregation/users.ts
rename to src/server/api/endpoints/aggregation/users.ts
diff --git a/src/api/endpoints/aggregation/users/activity.ts b/src/server/api/endpoints/aggregation/users/activity.ts
similarity index 100%
rename from src/api/endpoints/aggregation/users/activity.ts
rename to src/server/api/endpoints/aggregation/users/activity.ts
diff --git a/src/api/endpoints/aggregation/users/followers.ts b/src/server/api/endpoints/aggregation/users/followers.ts
similarity index 100%
rename from src/api/endpoints/aggregation/users/followers.ts
rename to src/server/api/endpoints/aggregation/users/followers.ts
diff --git a/src/api/endpoints/aggregation/users/following.ts b/src/server/api/endpoints/aggregation/users/following.ts
similarity index 100%
rename from src/api/endpoints/aggregation/users/following.ts
rename to src/server/api/endpoints/aggregation/users/following.ts
diff --git a/src/api/endpoints/aggregation/users/post.ts b/src/server/api/endpoints/aggregation/users/post.ts
similarity index 100%
rename from src/api/endpoints/aggregation/users/post.ts
rename to src/server/api/endpoints/aggregation/users/post.ts
diff --git a/src/api/endpoints/aggregation/users/reaction.ts b/src/server/api/endpoints/aggregation/users/reaction.ts
similarity index 100%
rename from src/api/endpoints/aggregation/users/reaction.ts
rename to src/server/api/endpoints/aggregation/users/reaction.ts
diff --git a/src/api/endpoints/app/create.ts b/src/server/api/endpoints/app/create.ts
similarity index 100%
rename from src/api/endpoints/app/create.ts
rename to src/server/api/endpoints/app/create.ts
diff --git a/src/api/endpoints/app/name_id/available.ts b/src/server/api/endpoints/app/name_id/available.ts
similarity index 100%
rename from src/api/endpoints/app/name_id/available.ts
rename to src/server/api/endpoints/app/name_id/available.ts
diff --git a/src/api/endpoints/app/show.ts b/src/server/api/endpoints/app/show.ts
similarity index 100%
rename from src/api/endpoints/app/show.ts
rename to src/server/api/endpoints/app/show.ts
diff --git a/src/api/endpoints/auth/accept.ts b/src/server/api/endpoints/auth/accept.ts
similarity index 100%
rename from src/api/endpoints/auth/accept.ts
rename to src/server/api/endpoints/auth/accept.ts
diff --git a/src/api/endpoints/auth/session/generate.ts b/src/server/api/endpoints/auth/session/generate.ts
similarity index 97%
rename from src/api/endpoints/auth/session/generate.ts
rename to src/server/api/endpoints/auth/session/generate.ts
index 510382247..dc6a045b6 100644
--- a/src/api/endpoints/auth/session/generate.ts
+++ b/src/server/api/endpoints/auth/session/generate.ts
@@ -5,7 +5,7 @@ import * as uuid from 'uuid';
 import $ from 'cafy';
 import App from '../../../models/app';
 import AuthSess from '../../../models/auth-session';
-import config from '../../../../conf';
+import config from '../../../../../conf';
 
 /**
  * @swagger
diff --git a/src/api/endpoints/auth/session/show.ts b/src/server/api/endpoints/auth/session/show.ts
similarity index 100%
rename from src/api/endpoints/auth/session/show.ts
rename to src/server/api/endpoints/auth/session/show.ts
diff --git a/src/api/endpoints/auth/session/userkey.ts b/src/server/api/endpoints/auth/session/userkey.ts
similarity index 100%
rename from src/api/endpoints/auth/session/userkey.ts
rename to src/server/api/endpoints/auth/session/userkey.ts
diff --git a/src/api/endpoints/channels.ts b/src/server/api/endpoints/channels.ts
similarity index 100%
rename from src/api/endpoints/channels.ts
rename to src/server/api/endpoints/channels.ts
diff --git a/src/api/endpoints/channels/create.ts b/src/server/api/endpoints/channels/create.ts
similarity index 100%
rename from src/api/endpoints/channels/create.ts
rename to src/server/api/endpoints/channels/create.ts
diff --git a/src/api/endpoints/channels/posts.ts b/src/server/api/endpoints/channels/posts.ts
similarity index 100%
rename from src/api/endpoints/channels/posts.ts
rename to src/server/api/endpoints/channels/posts.ts
diff --git a/src/api/endpoints/channels/show.ts b/src/server/api/endpoints/channels/show.ts
similarity index 100%
rename from src/api/endpoints/channels/show.ts
rename to src/server/api/endpoints/channels/show.ts
diff --git a/src/api/endpoints/channels/unwatch.ts b/src/server/api/endpoints/channels/unwatch.ts
similarity index 100%
rename from src/api/endpoints/channels/unwatch.ts
rename to src/server/api/endpoints/channels/unwatch.ts
diff --git a/src/api/endpoints/channels/watch.ts b/src/server/api/endpoints/channels/watch.ts
similarity index 100%
rename from src/api/endpoints/channels/watch.ts
rename to src/server/api/endpoints/channels/watch.ts
diff --git a/src/api/endpoints/drive.ts b/src/server/api/endpoints/drive.ts
similarity index 100%
rename from src/api/endpoints/drive.ts
rename to src/server/api/endpoints/drive.ts
diff --git a/src/api/endpoints/drive/files.ts b/src/server/api/endpoints/drive/files.ts
similarity index 100%
rename from src/api/endpoints/drive/files.ts
rename to src/server/api/endpoints/drive/files.ts
diff --git a/src/api/endpoints/drive/files/create.ts b/src/server/api/endpoints/drive/files/create.ts
similarity index 100%
rename from src/api/endpoints/drive/files/create.ts
rename to src/server/api/endpoints/drive/files/create.ts
diff --git a/src/api/endpoints/drive/files/find.ts b/src/server/api/endpoints/drive/files/find.ts
similarity index 100%
rename from src/api/endpoints/drive/files/find.ts
rename to src/server/api/endpoints/drive/files/find.ts
diff --git a/src/api/endpoints/drive/files/show.ts b/src/server/api/endpoints/drive/files/show.ts
similarity index 100%
rename from src/api/endpoints/drive/files/show.ts
rename to src/server/api/endpoints/drive/files/show.ts
diff --git a/src/api/endpoints/drive/files/update.ts b/src/server/api/endpoints/drive/files/update.ts
similarity index 100%
rename from src/api/endpoints/drive/files/update.ts
rename to src/server/api/endpoints/drive/files/update.ts
diff --git a/src/api/endpoints/drive/files/upload_from_url.ts b/src/server/api/endpoints/drive/files/upload_from_url.ts
similarity index 100%
rename from src/api/endpoints/drive/files/upload_from_url.ts
rename to src/server/api/endpoints/drive/files/upload_from_url.ts
diff --git a/src/api/endpoints/drive/folders.ts b/src/server/api/endpoints/drive/folders.ts
similarity index 100%
rename from src/api/endpoints/drive/folders.ts
rename to src/server/api/endpoints/drive/folders.ts
diff --git a/src/api/endpoints/drive/folders/create.ts b/src/server/api/endpoints/drive/folders/create.ts
similarity index 100%
rename from src/api/endpoints/drive/folders/create.ts
rename to src/server/api/endpoints/drive/folders/create.ts
diff --git a/src/api/endpoints/drive/folders/find.ts b/src/server/api/endpoints/drive/folders/find.ts
similarity index 100%
rename from src/api/endpoints/drive/folders/find.ts
rename to src/server/api/endpoints/drive/folders/find.ts
diff --git a/src/api/endpoints/drive/folders/show.ts b/src/server/api/endpoints/drive/folders/show.ts
similarity index 100%
rename from src/api/endpoints/drive/folders/show.ts
rename to src/server/api/endpoints/drive/folders/show.ts
diff --git a/src/api/endpoints/drive/folders/update.ts b/src/server/api/endpoints/drive/folders/update.ts
similarity index 100%
rename from src/api/endpoints/drive/folders/update.ts
rename to src/server/api/endpoints/drive/folders/update.ts
diff --git a/src/api/endpoints/drive/stream.ts b/src/server/api/endpoints/drive/stream.ts
similarity index 100%
rename from src/api/endpoints/drive/stream.ts
rename to src/server/api/endpoints/drive/stream.ts
diff --git a/src/api/endpoints/following/create.ts b/src/server/api/endpoints/following/create.ts
similarity index 100%
rename from src/api/endpoints/following/create.ts
rename to src/server/api/endpoints/following/create.ts
diff --git a/src/api/endpoints/following/delete.ts b/src/server/api/endpoints/following/delete.ts
similarity index 100%
rename from src/api/endpoints/following/delete.ts
rename to src/server/api/endpoints/following/delete.ts
diff --git a/src/api/endpoints/i.ts b/src/server/api/endpoints/i.ts
similarity index 100%
rename from src/api/endpoints/i.ts
rename to src/server/api/endpoints/i.ts
diff --git a/src/api/endpoints/i/2fa/done.ts b/src/server/api/endpoints/i/2fa/done.ts
similarity index 100%
rename from src/api/endpoints/i/2fa/done.ts
rename to src/server/api/endpoints/i/2fa/done.ts
diff --git a/src/api/endpoints/i/2fa/register.ts b/src/server/api/endpoints/i/2fa/register.ts
similarity index 96%
rename from src/api/endpoints/i/2fa/register.ts
rename to src/server/api/endpoints/i/2fa/register.ts
index 24abfcdfc..e2cc1487b 100644
--- a/src/api/endpoints/i/2fa/register.ts
+++ b/src/server/api/endpoints/i/2fa/register.ts
@@ -6,7 +6,7 @@ import * as bcrypt from 'bcryptjs';
 import * as speakeasy from 'speakeasy';
 import * as QRCode from 'qrcode';
 import User from '../../../models/user';
-import config from '../../../../conf';
+import config from '../../../../../conf';
 
 module.exports = async (params, user) => new Promise(async (res, rej) => {
 	// Get 'password' parameter
diff --git a/src/api/endpoints/i/2fa/unregister.ts b/src/server/api/endpoints/i/2fa/unregister.ts
similarity index 100%
rename from src/api/endpoints/i/2fa/unregister.ts
rename to src/server/api/endpoints/i/2fa/unregister.ts
diff --git a/src/api/endpoints/i/appdata/get.ts b/src/server/api/endpoints/i/appdata/get.ts
similarity index 100%
rename from src/api/endpoints/i/appdata/get.ts
rename to src/server/api/endpoints/i/appdata/get.ts
diff --git a/src/api/endpoints/i/appdata/set.ts b/src/server/api/endpoints/i/appdata/set.ts
similarity index 100%
rename from src/api/endpoints/i/appdata/set.ts
rename to src/server/api/endpoints/i/appdata/set.ts
diff --git a/src/api/endpoints/i/authorized_apps.ts b/src/server/api/endpoints/i/authorized_apps.ts
similarity index 100%
rename from src/api/endpoints/i/authorized_apps.ts
rename to src/server/api/endpoints/i/authorized_apps.ts
diff --git a/src/api/endpoints/i/change_password.ts b/src/server/api/endpoints/i/change_password.ts
similarity index 100%
rename from src/api/endpoints/i/change_password.ts
rename to src/server/api/endpoints/i/change_password.ts
diff --git a/src/api/endpoints/i/favorites.ts b/src/server/api/endpoints/i/favorites.ts
similarity index 100%
rename from src/api/endpoints/i/favorites.ts
rename to src/server/api/endpoints/i/favorites.ts
diff --git a/src/api/endpoints/i/notifications.ts b/src/server/api/endpoints/i/notifications.ts
similarity index 100%
rename from src/api/endpoints/i/notifications.ts
rename to src/server/api/endpoints/i/notifications.ts
diff --git a/src/api/endpoints/i/pin.ts b/src/server/api/endpoints/i/pin.ts
similarity index 100%
rename from src/api/endpoints/i/pin.ts
rename to src/server/api/endpoints/i/pin.ts
diff --git a/src/api/endpoints/i/regenerate_token.ts b/src/server/api/endpoints/i/regenerate_token.ts
similarity index 100%
rename from src/api/endpoints/i/regenerate_token.ts
rename to src/server/api/endpoints/i/regenerate_token.ts
diff --git a/src/api/endpoints/i/signin_history.ts b/src/server/api/endpoints/i/signin_history.ts
similarity index 100%
rename from src/api/endpoints/i/signin_history.ts
rename to src/server/api/endpoints/i/signin_history.ts
diff --git a/src/api/endpoints/i/update.ts b/src/server/api/endpoints/i/update.ts
similarity index 98%
rename from src/api/endpoints/i/update.ts
rename to src/server/api/endpoints/i/update.ts
index db8a3f25b..3d52de2cc 100644
--- a/src/api/endpoints/i/update.ts
+++ b/src/server/api/endpoints/i/update.ts
@@ -4,7 +4,7 @@
 import $ from 'cafy';
 import User, { isValidName, isValidDescription, isValidLocation, isValidBirthday, pack } from '../../models/user';
 import event from '../../event';
-import config from '../../../conf';
+import config from '../../../../conf';
 
 /**
  * Update myself
diff --git a/src/api/endpoints/i/update_client_setting.ts b/src/server/api/endpoints/i/update_client_setting.ts
similarity index 100%
rename from src/api/endpoints/i/update_client_setting.ts
rename to src/server/api/endpoints/i/update_client_setting.ts
diff --git a/src/api/endpoints/i/update_home.ts b/src/server/api/endpoints/i/update_home.ts
similarity index 100%
rename from src/api/endpoints/i/update_home.ts
rename to src/server/api/endpoints/i/update_home.ts
diff --git a/src/api/endpoints/i/update_mobile_home.ts b/src/server/api/endpoints/i/update_mobile_home.ts
similarity index 100%
rename from src/api/endpoints/i/update_mobile_home.ts
rename to src/server/api/endpoints/i/update_mobile_home.ts
diff --git a/src/api/endpoints/messaging/history.ts b/src/server/api/endpoints/messaging/history.ts
similarity index 100%
rename from src/api/endpoints/messaging/history.ts
rename to src/server/api/endpoints/messaging/history.ts
diff --git a/src/api/endpoints/messaging/messages.ts b/src/server/api/endpoints/messaging/messages.ts
similarity index 100%
rename from src/api/endpoints/messaging/messages.ts
rename to src/server/api/endpoints/messaging/messages.ts
diff --git a/src/api/endpoints/messaging/messages/create.ts b/src/server/api/endpoints/messaging/messages/create.ts
similarity index 99%
rename from src/api/endpoints/messaging/messages/create.ts
rename to src/server/api/endpoints/messaging/messages/create.ts
index 1b8a5f59e..5184b2bd3 100644
--- a/src/api/endpoints/messaging/messages/create.ts
+++ b/src/server/api/endpoints/messaging/messages/create.ts
@@ -11,7 +11,7 @@ import DriveFile from '../../../models/drive-file';
 import { pack } from '../../../models/messaging-message';
 import publishUserStream from '../../../event';
 import { publishMessagingStream, publishMessagingIndexStream, pushSw } from '../../../event';
-import config from '../../../../conf';
+import config from '../../../../../conf';
 
 /**
  * Create a message
diff --git a/src/api/endpoints/messaging/unread.ts b/src/server/api/endpoints/messaging/unread.ts
similarity index 100%
rename from src/api/endpoints/messaging/unread.ts
rename to src/server/api/endpoints/messaging/unread.ts
diff --git a/src/api/endpoints/meta.ts b/src/server/api/endpoints/meta.ts
similarity index 94%
rename from src/api/endpoints/meta.ts
rename to src/server/api/endpoints/meta.ts
index 1370ead3c..10625ec66 100644
--- a/src/api/endpoints/meta.ts
+++ b/src/server/api/endpoints/meta.ts
@@ -2,8 +2,8 @@
  * Module dependencies
  */
 import * as os from 'os';
-import version from '../../version';
-import config from '../../conf';
+import version from '../../../version';
+import config from '../../../conf';
 import Meta from '../models/meta';
 
 /**
diff --git a/src/api/endpoints/mute/create.ts b/src/server/api/endpoints/mute/create.ts
similarity index 100%
rename from src/api/endpoints/mute/create.ts
rename to src/server/api/endpoints/mute/create.ts
diff --git a/src/api/endpoints/mute/delete.ts b/src/server/api/endpoints/mute/delete.ts
similarity index 100%
rename from src/api/endpoints/mute/delete.ts
rename to src/server/api/endpoints/mute/delete.ts
diff --git a/src/api/endpoints/mute/list.ts b/src/server/api/endpoints/mute/list.ts
similarity index 100%
rename from src/api/endpoints/mute/list.ts
rename to src/server/api/endpoints/mute/list.ts
diff --git a/src/api/endpoints/my/apps.ts b/src/server/api/endpoints/my/apps.ts
similarity index 100%
rename from src/api/endpoints/my/apps.ts
rename to src/server/api/endpoints/my/apps.ts
diff --git a/src/api/endpoints/notifications/get_unread_count.ts b/src/server/api/endpoints/notifications/get_unread_count.ts
similarity index 100%
rename from src/api/endpoints/notifications/get_unread_count.ts
rename to src/server/api/endpoints/notifications/get_unread_count.ts
diff --git a/src/api/endpoints/notifications/mark_as_read_all.ts b/src/server/api/endpoints/notifications/mark_as_read_all.ts
similarity index 100%
rename from src/api/endpoints/notifications/mark_as_read_all.ts
rename to src/server/api/endpoints/notifications/mark_as_read_all.ts
diff --git a/src/api/endpoints/othello/games.ts b/src/server/api/endpoints/othello/games.ts
similarity index 100%
rename from src/api/endpoints/othello/games.ts
rename to src/server/api/endpoints/othello/games.ts
diff --git a/src/api/endpoints/othello/games/show.ts b/src/server/api/endpoints/othello/games/show.ts
similarity index 100%
rename from src/api/endpoints/othello/games/show.ts
rename to src/server/api/endpoints/othello/games/show.ts
diff --git a/src/api/endpoints/othello/invitations.ts b/src/server/api/endpoints/othello/invitations.ts
similarity index 100%
rename from src/api/endpoints/othello/invitations.ts
rename to src/server/api/endpoints/othello/invitations.ts
diff --git a/src/api/endpoints/othello/match.ts b/src/server/api/endpoints/othello/match.ts
similarity index 100%
rename from src/api/endpoints/othello/match.ts
rename to src/server/api/endpoints/othello/match.ts
diff --git a/src/api/endpoints/othello/match/cancel.ts b/src/server/api/endpoints/othello/match/cancel.ts
similarity index 100%
rename from src/api/endpoints/othello/match/cancel.ts
rename to src/server/api/endpoints/othello/match/cancel.ts
diff --git a/src/api/endpoints/posts.ts b/src/server/api/endpoints/posts.ts
similarity index 100%
rename from src/api/endpoints/posts.ts
rename to src/server/api/endpoints/posts.ts
diff --git a/src/api/endpoints/posts/categorize.ts b/src/server/api/endpoints/posts/categorize.ts
similarity index 100%
rename from src/api/endpoints/posts/categorize.ts
rename to src/server/api/endpoints/posts/categorize.ts
diff --git a/src/api/endpoints/posts/context.ts b/src/server/api/endpoints/posts/context.ts
similarity index 100%
rename from src/api/endpoints/posts/context.ts
rename to src/server/api/endpoints/posts/context.ts
diff --git a/src/api/endpoints/posts/create.ts b/src/server/api/endpoints/posts/create.ts
similarity index 99%
rename from src/api/endpoints/posts/create.ts
rename to src/server/api/endpoints/posts/create.ts
index 286e18bb7..bc9af843b 100644
--- a/src/api/endpoints/posts/create.ts
+++ b/src/server/api/endpoints/posts/create.ts
@@ -18,7 +18,7 @@ import watch from '../../common/watch-post';
 import event, { pushSw, publishChannelStream } from '../../event';
 import getAcct from '../../../common/user/get-acct';
 import parseAcct from '../../../common/user/parse-acct';
-import config from '../../../conf';
+import config from '../../../../conf';
 
 /**
  * Create a post
diff --git a/src/api/endpoints/posts/favorites/create.ts b/src/server/api/endpoints/posts/favorites/create.ts
similarity index 100%
rename from src/api/endpoints/posts/favorites/create.ts
rename to src/server/api/endpoints/posts/favorites/create.ts
diff --git a/src/api/endpoints/posts/favorites/delete.ts b/src/server/api/endpoints/posts/favorites/delete.ts
similarity index 100%
rename from src/api/endpoints/posts/favorites/delete.ts
rename to src/server/api/endpoints/posts/favorites/delete.ts
diff --git a/src/api/endpoints/posts/mentions.ts b/src/server/api/endpoints/posts/mentions.ts
similarity index 100%
rename from src/api/endpoints/posts/mentions.ts
rename to src/server/api/endpoints/posts/mentions.ts
diff --git a/src/api/endpoints/posts/polls/recommendation.ts b/src/server/api/endpoints/posts/polls/recommendation.ts
similarity index 100%
rename from src/api/endpoints/posts/polls/recommendation.ts
rename to src/server/api/endpoints/posts/polls/recommendation.ts
diff --git a/src/api/endpoints/posts/polls/vote.ts b/src/server/api/endpoints/posts/polls/vote.ts
similarity index 100%
rename from src/api/endpoints/posts/polls/vote.ts
rename to src/server/api/endpoints/posts/polls/vote.ts
diff --git a/src/api/endpoints/posts/reactions.ts b/src/server/api/endpoints/posts/reactions.ts
similarity index 100%
rename from src/api/endpoints/posts/reactions.ts
rename to src/server/api/endpoints/posts/reactions.ts
diff --git a/src/api/endpoints/posts/reactions/create.ts b/src/server/api/endpoints/posts/reactions/create.ts
similarity index 100%
rename from src/api/endpoints/posts/reactions/create.ts
rename to src/server/api/endpoints/posts/reactions/create.ts
diff --git a/src/api/endpoints/posts/reactions/delete.ts b/src/server/api/endpoints/posts/reactions/delete.ts
similarity index 100%
rename from src/api/endpoints/posts/reactions/delete.ts
rename to src/server/api/endpoints/posts/reactions/delete.ts
diff --git a/src/api/endpoints/posts/replies.ts b/src/server/api/endpoints/posts/replies.ts
similarity index 100%
rename from src/api/endpoints/posts/replies.ts
rename to src/server/api/endpoints/posts/replies.ts
diff --git a/src/api/endpoints/posts/reposts.ts b/src/server/api/endpoints/posts/reposts.ts
similarity index 100%
rename from src/api/endpoints/posts/reposts.ts
rename to src/server/api/endpoints/posts/reposts.ts
diff --git a/src/api/endpoints/posts/search.ts b/src/server/api/endpoints/posts/search.ts
similarity index 100%
rename from src/api/endpoints/posts/search.ts
rename to src/server/api/endpoints/posts/search.ts
diff --git a/src/api/endpoints/posts/show.ts b/src/server/api/endpoints/posts/show.ts
similarity index 100%
rename from src/api/endpoints/posts/show.ts
rename to src/server/api/endpoints/posts/show.ts
diff --git a/src/api/endpoints/posts/timeline.ts b/src/server/api/endpoints/posts/timeline.ts
similarity index 100%
rename from src/api/endpoints/posts/timeline.ts
rename to src/server/api/endpoints/posts/timeline.ts
diff --git a/src/api/endpoints/posts/trend.ts b/src/server/api/endpoints/posts/trend.ts
similarity index 100%
rename from src/api/endpoints/posts/trend.ts
rename to src/server/api/endpoints/posts/trend.ts
diff --git a/src/api/endpoints/stats.ts b/src/server/api/endpoints/stats.ts
similarity index 100%
rename from src/api/endpoints/stats.ts
rename to src/server/api/endpoints/stats.ts
diff --git a/src/api/endpoints/sw/register.ts b/src/server/api/endpoints/sw/register.ts
similarity index 100%
rename from src/api/endpoints/sw/register.ts
rename to src/server/api/endpoints/sw/register.ts
diff --git a/src/api/endpoints/username/available.ts b/src/server/api/endpoints/username/available.ts
similarity index 100%
rename from src/api/endpoints/username/available.ts
rename to src/server/api/endpoints/username/available.ts
diff --git a/src/api/endpoints/users.ts b/src/server/api/endpoints/users.ts
similarity index 100%
rename from src/api/endpoints/users.ts
rename to src/server/api/endpoints/users.ts
diff --git a/src/api/endpoints/users/followers.ts b/src/server/api/endpoints/users/followers.ts
similarity index 100%
rename from src/api/endpoints/users/followers.ts
rename to src/server/api/endpoints/users/followers.ts
diff --git a/src/api/endpoints/users/following.ts b/src/server/api/endpoints/users/following.ts
similarity index 100%
rename from src/api/endpoints/users/following.ts
rename to src/server/api/endpoints/users/following.ts
diff --git a/src/api/endpoints/users/get_frequently_replied_users.ts b/src/server/api/endpoints/users/get_frequently_replied_users.ts
similarity index 100%
rename from src/api/endpoints/users/get_frequently_replied_users.ts
rename to src/server/api/endpoints/users/get_frequently_replied_users.ts
diff --git a/src/api/endpoints/users/posts.ts b/src/server/api/endpoints/users/posts.ts
similarity index 100%
rename from src/api/endpoints/users/posts.ts
rename to src/server/api/endpoints/users/posts.ts
diff --git a/src/api/endpoints/users/recommendation.ts b/src/server/api/endpoints/users/recommendation.ts
similarity index 100%
rename from src/api/endpoints/users/recommendation.ts
rename to src/server/api/endpoints/users/recommendation.ts
diff --git a/src/api/endpoints/users/search.ts b/src/server/api/endpoints/users/search.ts
similarity index 98%
rename from src/api/endpoints/users/search.ts
rename to src/server/api/endpoints/users/search.ts
index 39e2ff989..3c8157644 100644
--- a/src/api/endpoints/users/search.ts
+++ b/src/server/api/endpoints/users/search.ts
@@ -4,7 +4,7 @@
 import * as mongo from 'mongodb';
 import $ from 'cafy';
 import User, { pack } from '../../models/user';
-import config from '../../../conf';
+import config from '../../../../conf';
 const escapeRegexp = require('escape-regexp');
 
 /**
diff --git a/src/api/endpoints/users/search_by_username.ts b/src/server/api/endpoints/users/search_by_username.ts
similarity index 100%
rename from src/api/endpoints/users/search_by_username.ts
rename to src/server/api/endpoints/users/search_by_username.ts
diff --git a/src/api/endpoints/users/show.ts b/src/server/api/endpoints/users/show.ts
similarity index 100%
rename from src/api/endpoints/users/show.ts
rename to src/server/api/endpoints/users/show.ts
diff --git a/src/api/event.ts b/src/server/api/event.ts
similarity index 98%
rename from src/api/event.ts
rename to src/server/api/event.ts
index 4c9cc18e4..98bf16113 100644
--- a/src/api/event.ts
+++ b/src/server/api/event.ts
@@ -1,7 +1,7 @@
 import * as mongo from 'mongodb';
 import * as redis from 'redis';
 import swPush from './common/push-sw';
-import config from '../conf';
+import config from '../../conf';
 
 type ID = string | mongo.ObjectID;
 
diff --git a/src/api/limitter.ts b/src/server/api/limitter.ts
similarity index 97%
rename from src/api/limitter.ts
rename to src/server/api/limitter.ts
index 9d2c42d33..33337fbb1 100644
--- a/src/api/limitter.ts
+++ b/src/server/api/limitter.ts
@@ -1,6 +1,6 @@
 import * as Limiter from 'ratelimiter';
 import * as debug from 'debug';
-import limiterDB from '../db/redis';
+import limiterDB from '../../db/redis';
 import { Endpoint } from './endpoints';
 import { IAuthContext } from './authenticate';
 import getAcct from '../common/user/get-acct';
diff --git a/src/api/models/access-token.ts b/src/server/api/models/access-token.ts
similarity index 86%
rename from src/api/models/access-token.ts
rename to src/server/api/models/access-token.ts
index 9985be501..2bf91f309 100644
--- a/src/api/models/access-token.ts
+++ b/src/server/api/models/access-token.ts
@@ -1,4 +1,4 @@
-import db from '../../db/mongodb';
+import db from '../../../db/mongodb';
 
 const collection = db.get('access_tokens');
 
diff --git a/src/api/models/app.ts b/src/server/api/models/app.ts
similarity index 96%
rename from src/api/models/app.ts
rename to src/server/api/models/app.ts
index 34e9867db..17db82eca 100644
--- a/src/api/models/app.ts
+++ b/src/server/api/models/app.ts
@@ -1,8 +1,8 @@
 import * as mongo from 'mongodb';
 import deepcopy = require('deepcopy');
 import AccessToken from './access-token';
-import db from '../../db/mongodb';
-import config from '../../conf';
+import db from '../../../db/mongodb';
+import config from '../../../conf';
 
 const App = db.get<IApp>('apps');
 App.createIndex('name_id');
diff --git a/src/api/models/appdata.ts b/src/server/api/models/appdata.ts
similarity index 63%
rename from src/api/models/appdata.ts
rename to src/server/api/models/appdata.ts
index 3e68354fa..dda3c9893 100644
--- a/src/api/models/appdata.ts
+++ b/src/server/api/models/appdata.ts
@@ -1,3 +1,3 @@
-import db from '../../db/mongodb';
+import db from '../../../db/mongodb';
 
 export default db.get('appdata') as any; // fuck type definition
diff --git a/src/api/models/auth-session.ts b/src/server/api/models/auth-session.ts
similarity index 95%
rename from src/api/models/auth-session.ts
rename to src/server/api/models/auth-session.ts
index 997ec61c2..a79d901df 100644
--- a/src/api/models/auth-session.ts
+++ b/src/server/api/models/auth-session.ts
@@ -1,6 +1,6 @@
 import * as mongo from 'mongodb';
 import deepcopy = require('deepcopy');
-import db from '../../db/mongodb';
+import db from '../../../db/mongodb';
 import { pack as packApp } from './app';
 
 const AuthSession = db.get('auth_sessions');
diff --git a/src/api/models/channel-watching.ts b/src/server/api/models/channel-watching.ts
similarity index 66%
rename from src/api/models/channel-watching.ts
rename to src/server/api/models/channel-watching.ts
index 6184ae408..4c6fae28d 100644
--- a/src/api/models/channel-watching.ts
+++ b/src/server/api/models/channel-watching.ts
@@ -1,3 +1,3 @@
-import db from '../../db/mongodb';
+import db from '../../../db/mongodb';
 
 export default db.get('channel_watching') as any; // fuck type definition
diff --git a/src/api/models/channel.ts b/src/server/api/models/channel.ts
similarity index 97%
rename from src/api/models/channel.ts
rename to src/server/api/models/channel.ts
index 815d53593..97999bd9e 100644
--- a/src/api/models/channel.ts
+++ b/src/server/api/models/channel.ts
@@ -2,7 +2,7 @@ import * as mongo from 'mongodb';
 import deepcopy = require('deepcopy');
 import { IUser } from './user';
 import Watching from './channel-watching';
-import db from '../../db/mongodb';
+import db from '../../../db/mongodb';
 
 const Channel = db.get<IChannel>('channels');
 export default Channel;
diff --git a/src/api/models/drive-file.ts b/src/server/api/models/drive-file.ts
similarity index 96%
rename from src/api/models/drive-file.ts
rename to src/server/api/models/drive-file.ts
index 2a46d8dc4..851a79a0e 100644
--- a/src/api/models/drive-file.ts
+++ b/src/server/api/models/drive-file.ts
@@ -1,8 +1,8 @@
 import * as mongodb from 'mongodb';
 import deepcopy = require('deepcopy');
 import { pack as packFolder } from './drive-folder';
-import config from '../../conf';
-import monkDb, { nativeDbConn } from '../../db/mongodb';
+import config from '../../../conf';
+import monkDb, { nativeDbConn } from '../../../db/mongodb';
 
 const DriveFile = monkDb.get<IDriveFile>('drive_files.files');
 
diff --git a/src/api/models/drive-folder.ts b/src/server/api/models/drive-folder.ts
similarity index 97%
rename from src/api/models/drive-folder.ts
rename to src/server/api/models/drive-folder.ts
index 54b45049b..505556376 100644
--- a/src/api/models/drive-folder.ts
+++ b/src/server/api/models/drive-folder.ts
@@ -1,6 +1,6 @@
 import * as mongo from 'mongodb';
 import deepcopy = require('deepcopy');
-import db from '../../db/mongodb';
+import db from '../../../db/mongodb';
 import DriveFile from './drive-file';
 
 const DriveFolder = db.get<IDriveFolder>('drive_folders');
diff --git a/src/api/models/drive-tag.ts b/src/server/api/models/drive-tag.ts
similarity index 64%
rename from src/api/models/drive-tag.ts
rename to src/server/api/models/drive-tag.ts
index 991c935e8..d1c68365a 100644
--- a/src/api/models/drive-tag.ts
+++ b/src/server/api/models/drive-tag.ts
@@ -1,3 +1,3 @@
-import db from '../../db/mongodb';
+import db from '../../../db/mongodb';
 
 export default db.get('drive_tags') as any; // fuck type definition
diff --git a/src/api/models/favorite.ts b/src/server/api/models/favorite.ts
similarity index 64%
rename from src/api/models/favorite.ts
rename to src/server/api/models/favorite.ts
index e01d9e343..314261764 100644
--- a/src/api/models/favorite.ts
+++ b/src/server/api/models/favorite.ts
@@ -1,3 +1,3 @@
-import db from '../../db/mongodb';
+import db from '../../../db/mongodb';
 
 export default db.get('favorites') as any; // fuck type definition
diff --git a/src/api/models/following.ts b/src/server/api/models/following.ts
similarity index 64%
rename from src/api/models/following.ts
rename to src/server/api/models/following.ts
index cb3db9b53..92d7b6d31 100644
--- a/src/api/models/following.ts
+++ b/src/server/api/models/following.ts
@@ -1,3 +1,3 @@
-import db from '../../db/mongodb';
+import db from '../../../db/mongodb';
 
 export default db.get('following') as any; // fuck type definition
diff --git a/src/api/models/messaging-history.ts b/src/server/api/models/messaging-history.ts
similarity index 67%
rename from src/api/models/messaging-history.ts
rename to src/server/api/models/messaging-history.ts
index c06987e45..ea9f317ee 100644
--- a/src/api/models/messaging-history.ts
+++ b/src/server/api/models/messaging-history.ts
@@ -1,3 +1,3 @@
-import db from '../../db/mongodb';
+import db from '../../../db/mongodb';
 
 export default db.get('messaging_histories') as any; // fuck type definition
diff --git a/src/api/models/messaging-message.ts b/src/server/api/models/messaging-message.ts
similarity index 97%
rename from src/api/models/messaging-message.ts
rename to src/server/api/models/messaging-message.ts
index fcb356c5c..be484d635 100644
--- a/src/api/models/messaging-message.ts
+++ b/src/server/api/models/messaging-message.ts
@@ -2,7 +2,7 @@ import * as mongo from 'mongodb';
 import deepcopy = require('deepcopy');
 import { pack as packUser } from './user';
 import { pack as packFile } from './drive-file';
-import db from '../../db/mongodb';
+import db from '../../../db/mongodb';
 import parse from '../common/text';
 
 const MessagingMessage = db.get<IMessagingMessage>('messaging_messages');
diff --git a/src/api/models/meta.ts b/src/server/api/models/meta.ts
similarity index 74%
rename from src/api/models/meta.ts
rename to src/server/api/models/meta.ts
index c7dba8fcb..ee1ada18f 100644
--- a/src/api/models/meta.ts
+++ b/src/server/api/models/meta.ts
@@ -1,4 +1,4 @@
-import db from '../../db/mongodb';
+import db from '../../../db/mongodb';
 
 export default db.get('meta') as any; // fuck type definition
 
diff --git a/src/api/models/mute.ts b/src/server/api/models/mute.ts
similarity index 62%
rename from src/api/models/mute.ts
rename to src/server/api/models/mute.ts
index 16018b82f..02f652c30 100644
--- a/src/api/models/mute.ts
+++ b/src/server/api/models/mute.ts
@@ -1,3 +1,3 @@
-import db from '../../db/mongodb';
+import db from '../../../db/mongodb';
 
 export default db.get('mute') as any; // fuck type definition
diff --git a/src/api/models/notification.ts b/src/server/api/models/notification.ts
similarity index 98%
rename from src/api/models/notification.ts
rename to src/server/api/models/notification.ts
index fa7049d31..bcb25534d 100644
--- a/src/api/models/notification.ts
+++ b/src/server/api/models/notification.ts
@@ -1,6 +1,6 @@
 import * as mongo from 'mongodb';
 import deepcopy = require('deepcopy');
-import db from '../../db/mongodb';
+import db from '../../../db/mongodb';
 import { IUser, pack as packUser } from './user';
 import { pack as packPost } from './post';
 
diff --git a/src/api/models/othello-game.ts b/src/server/api/models/othello-game.ts
similarity index 98%
rename from src/api/models/othello-game.ts
rename to src/server/api/models/othello-game.ts
index 01c6ca6c0..97508e46d 100644
--- a/src/api/models/othello-game.ts
+++ b/src/server/api/models/othello-game.ts
@@ -1,6 +1,6 @@
 import * as mongo from 'mongodb';
 import deepcopy = require('deepcopy');
-import db from '../../db/mongodb';
+import db from '../../../db/mongodb';
 import { IUser, pack as packUser } from './user';
 
 const Game = db.get<IGame>('othello_games');
diff --git a/src/api/models/othello-matching.ts b/src/server/api/models/othello-matching.ts
similarity index 96%
rename from src/api/models/othello-matching.ts
rename to src/server/api/models/othello-matching.ts
index 5cc39cae1..3c29e6a00 100644
--- a/src/api/models/othello-matching.ts
+++ b/src/server/api/models/othello-matching.ts
@@ -1,6 +1,6 @@
 import * as mongo from 'mongodb';
 import deepcopy = require('deepcopy');
-import db from '../../db/mongodb';
+import db from '../../../db/mongodb';
 import { IUser, pack as packUser } from './user';
 
 const Matching = db.get<IMatching>('othello_matchings');
diff --git a/src/api/models/poll-vote.ts b/src/server/api/models/poll-vote.ts
similarity index 64%
rename from src/api/models/poll-vote.ts
rename to src/server/api/models/poll-vote.ts
index af77a2643..c6638ccf1 100644
--- a/src/api/models/poll-vote.ts
+++ b/src/server/api/models/poll-vote.ts
@@ -1,3 +1,3 @@
-import db from '../../db/mongodb';
+import db from '../../../db/mongodb';
 
 export default db.get('poll_votes') as any; // fuck type definition
diff --git a/src/api/models/post-reaction.ts b/src/server/api/models/post-reaction.ts
similarity index 96%
rename from src/api/models/post-reaction.ts
rename to src/server/api/models/post-reaction.ts
index 639a70e00..5cd122d76 100644
--- a/src/api/models/post-reaction.ts
+++ b/src/server/api/models/post-reaction.ts
@@ -1,6 +1,6 @@
 import * as mongo from 'mongodb';
 import deepcopy = require('deepcopy');
-import db from '../../db/mongodb';
+import db from '../../../db/mongodb';
 import Reaction from './post-reaction';
 import { pack as packUser } from './user';
 
diff --git a/src/api/models/post-watching.ts b/src/server/api/models/post-watching.ts
similarity index 65%
rename from src/api/models/post-watching.ts
rename to src/server/api/models/post-watching.ts
index 41d37e270..9a4163c8d 100644
--- a/src/api/models/post-watching.ts
+++ b/src/server/api/models/post-watching.ts
@@ -1,3 +1,3 @@
-import db from '../../db/mongodb';
+import db from '../../../db/mongodb';
 
 export default db.get('post_watching') as any; // fuck type definition
diff --git a/src/api/models/post.ts b/src/server/api/models/post.ts
similarity index 99%
rename from src/api/models/post.ts
rename to src/server/api/models/post.ts
index c37c8371c..3f648e08c 100644
--- a/src/api/models/post.ts
+++ b/src/server/api/models/post.ts
@@ -1,7 +1,7 @@
 import * as mongo from 'mongodb';
 import deepcopy = require('deepcopy');
 import rap from '@prezzemolo/rap';
-import db from '../../db/mongodb';
+import db from '../../../db/mongodb';
 import { IUser, pack as packUser } from './user';
 import { pack as packApp } from './app';
 import { pack as packChannel } from './channel';
diff --git a/src/api/models/signin.ts b/src/server/api/models/signin.ts
similarity index 93%
rename from src/api/models/signin.ts
rename to src/server/api/models/signin.ts
index 262c8707e..5cffb3c31 100644
--- a/src/api/models/signin.ts
+++ b/src/server/api/models/signin.ts
@@ -1,6 +1,6 @@
 import * as mongo from 'mongodb';
 import deepcopy = require('deepcopy');
-import db from '../../db/mongodb';
+import db from '../../../db/mongodb';
 
 const Signin = db.get<ISignin>('signin');
 export default Signin;
diff --git a/src/api/models/sw-subscription.ts b/src/server/api/models/sw-subscription.ts
similarity index 66%
rename from src/api/models/sw-subscription.ts
rename to src/server/api/models/sw-subscription.ts
index ecca04cb9..4506a982f 100644
--- a/src/api/models/sw-subscription.ts
+++ b/src/server/api/models/sw-subscription.ts
@@ -1,3 +1,3 @@
-import db from '../../db/mongodb';
+import db from '../../../db/mongodb';
 
 export default db.get('sw_subscriptions') as any; // fuck type definition
diff --git a/src/api/models/user.ts b/src/server/api/models/user.ts
similarity index 99%
rename from src/api/models/user.ts
rename to src/server/api/models/user.ts
index e73c95faf..8e7d50baa 100644
--- a/src/api/models/user.ts
+++ b/src/server/api/models/user.ts
@@ -1,12 +1,12 @@
 import * as mongo from 'mongodb';
 import deepcopy = require('deepcopy');
 import rap from '@prezzemolo/rap';
-import db from '../../db/mongodb';
+import db from '../../../db/mongodb';
 import { IPost, pack as packPost } from './post';
 import Following from './following';
 import Mute from './mute';
 import getFriends from '../common/get-friends';
-import config from '../../conf';
+import config from '../../../conf';
 
 const User = db.get<IUser>('users');
 
diff --git a/src/api/private/signin.ts b/src/server/api/private/signin.ts
similarity index 98%
rename from src/api/private/signin.ts
rename to src/server/api/private/signin.ts
index 00dcb8afc..bbc990899 100644
--- a/src/api/private/signin.ts
+++ b/src/server/api/private/signin.ts
@@ -5,7 +5,7 @@ import { default as User, ILocalAccount, IUser } from '../models/user';
 import Signin, { pack } from '../models/signin';
 import event from '../event';
 import signin from '../common/signin';
-import config from '../../conf';
+import config from '../../../conf';
 
 export default async (req: express.Request, res: express.Response) => {
 	res.header('Access-Control-Allow-Origin', config.url);
diff --git a/src/api/private/signup.ts b/src/server/api/private/signup.ts
similarity index 96%
rename from src/api/private/signup.ts
rename to src/server/api/private/signup.ts
index 96e049570..9f5539331 100644
--- a/src/api/private/signup.ts
+++ b/src/server/api/private/signup.ts
@@ -1,11 +1,11 @@
 import * as uuid from 'uuid';
 import * as express from 'express';
 import * as bcrypt from 'bcryptjs';
-import { generate as generateKeypair } from '../../crypto_key';
+import { generate as generateKeypair } from '../../../crypto_key';
 import recaptcha = require('recaptcha-promise');
 import User, { IUser, validateUsername, validatePassword, pack } from '../models/user';
 import generateUserToken from '../common/generate-native-user-token';
-import config from '../../conf';
+import config from '../../../conf';
 
 recaptcha.init({
 	secret_key: config.recaptcha.secret_key
diff --git a/src/api/reply.ts b/src/server/api/reply.ts
similarity index 100%
rename from src/api/reply.ts
rename to src/server/api/reply.ts
diff --git a/src/api/server.ts b/src/server/api/server.ts
similarity index 100%
rename from src/api/server.ts
rename to src/server/api/server.ts
diff --git a/src/api/service/github.ts b/src/server/api/service/github.ts
similarity index 77%
rename from src/api/service/github.ts
rename to src/server/api/service/github.ts
index 1c78267c0..a33d35975 100644
--- a/src/api/service/github.ts
+++ b/src/server/api/service/github.ts
@@ -1,9 +1,9 @@
 import * as EventEmitter from 'events';
 import * as express from 'express';
-import * as request from 'request';
 const crypto = require('crypto');
 import User from '../models/user';
-import config from '../../conf';
+import config from '../../../conf';
+import queue from '../../../queue';
 
 module.exports = async (app: express.Application) => {
 	if (config.github_bot == null) return;
@@ -25,12 +25,12 @@ module.exports = async (app: express.Application) => {
 		// req.headers['x-hub-signature'] および
 		// req.headers['x-github-event'] は常に string ですが、型定義の都合上
 		// string | string[] になっているので string を明示しています
-		if ((new Buffer(req.headers['x-hub-signature'] as string)).equals(new Buffer(`sha1=${crypto.createHmac('sha1', config.github_bot.hook_secret).update(JSON.stringify(req.body)).digest('hex')}`))) {
+//		if ((new Buffer(req.headers['x-hub-signature'] as string)).equals(new Buffer(`sha1=${crypto.createHmac('sha1', config.github_bot.hook_secret).update(JSON.stringify(req.body)).digest('hex')}`))) {
 			handler.emit(req.headers['x-github-event'] as string, req.body);
 			res.sendStatus(200);
-		} else {
-			res.sendStatus(400);
-		}
+//		} else {
+//			res.sendStatus(400);
+//		}
 	});
 
 	handler.on('status', event => {
@@ -41,26 +41,12 @@ module.exports = async (app: express.Application) => {
 				const commit = event.commit;
 				const parent = commit.parents[0];
 
-				// Fetch parent status
-				request({
-					url: `${parent.url}/statuses`,
-					headers: {
-						'User-Agent': 'misskey'
-					}
-				}, (err, res, body) => {
-					if (err) {
-						console.error(err);
-						return;
-					}
-					const parentStatuses = JSON.parse(body);
-					const parentState = parentStatuses[0].state;
-					const stillFailed = parentState == 'failure' || parentState == 'error';
-					if (stillFailed) {
-						post(`**⚠️BUILD STILL FAILED⚠️**: ?[${commit.commit.message}](${commit.html_url})`);
-					} else {
-						post(`**🚨BUILD FAILED🚨**: →→→?[${commit.commit.message}](${commit.html_url})←←←`);
-					}
-				});
+				queue.create('gitHubFailureReport', {
+					userId: bot._id,
+					parentUrl: parent.url,
+					htmlUrl: commit.html_url,
+					message: commit.commit.message,
+				}).save();
 				break;
 		}
 	});
diff --git a/src/api/service/twitter.ts b/src/server/api/service/twitter.ts
similarity index 98%
rename from src/api/service/twitter.ts
rename to src/server/api/service/twitter.ts
index c1f2e48a6..861f63ed6 100644
--- a/src/api/service/twitter.ts
+++ b/src/server/api/service/twitter.ts
@@ -4,10 +4,10 @@ import * as uuid from 'uuid';
 // import * as Twitter from 'twitter';
 // const Twitter = require('twitter');
 import autwh from 'autwh';
-import redis from '../../db/redis';
+import redis from '../../../db/redis';
 import User, { pack } from '../models/user';
 import event from '../event';
-import config from '../../conf';
+import config from '../../../conf';
 import signin from '../common/signin';
 
 module.exports = (app: express.Application) => {
diff --git a/src/api/stream/channel.ts b/src/server/api/stream/channel.ts
similarity index 100%
rename from src/api/stream/channel.ts
rename to src/server/api/stream/channel.ts
diff --git a/src/api/stream/drive.ts b/src/server/api/stream/drive.ts
similarity index 100%
rename from src/api/stream/drive.ts
rename to src/server/api/stream/drive.ts
diff --git a/src/api/stream/home.ts b/src/server/api/stream/home.ts
similarity index 100%
rename from src/api/stream/home.ts
rename to src/server/api/stream/home.ts
diff --git a/src/api/stream/messaging-index.ts b/src/server/api/stream/messaging-index.ts
similarity index 100%
rename from src/api/stream/messaging-index.ts
rename to src/server/api/stream/messaging-index.ts
diff --git a/src/api/stream/messaging.ts b/src/server/api/stream/messaging.ts
similarity index 100%
rename from src/api/stream/messaging.ts
rename to src/server/api/stream/messaging.ts
diff --git a/src/api/stream/othello-game.ts b/src/server/api/stream/othello-game.ts
similarity index 100%
rename from src/api/stream/othello-game.ts
rename to src/server/api/stream/othello-game.ts
diff --git a/src/api/stream/othello.ts b/src/server/api/stream/othello.ts
similarity index 100%
rename from src/api/stream/othello.ts
rename to src/server/api/stream/othello.ts
diff --git a/src/api/stream/requests.ts b/src/server/api/stream/requests.ts
similarity index 100%
rename from src/api/stream/requests.ts
rename to src/server/api/stream/requests.ts
diff --git a/src/api/stream/server.ts b/src/server/api/stream/server.ts
similarity index 100%
rename from src/api/stream/server.ts
rename to src/server/api/stream/server.ts
diff --git a/src/api/streaming.ts b/src/server/api/streaming.ts
similarity index 98%
rename from src/api/streaming.ts
rename to src/server/api/streaming.ts
index a6759e414..95f444e00 100644
--- a/src/api/streaming.ts
+++ b/src/server/api/streaming.ts
@@ -1,7 +1,7 @@
 import * as http from 'http';
 import * as websocket from 'websocket';
 import * as redis from 'redis';
-import config from '../conf';
+import config from '../../conf';
 import { default as User, IUser } from './models/user';
 import AccessToken from './models/access-token';
 import isNativeToken from './common/is-native-token';
diff --git a/src/common/get-notification-summary.ts b/src/server/common/get-notification-summary.ts
similarity index 100%
rename from src/common/get-notification-summary.ts
rename to src/server/common/get-notification-summary.ts
diff --git a/src/common/get-post-summary.ts b/src/server/common/get-post-summary.ts
similarity index 100%
rename from src/common/get-post-summary.ts
rename to src/server/common/get-post-summary.ts
diff --git a/src/common/get-reaction-emoji.ts b/src/server/common/get-reaction-emoji.ts
similarity index 100%
rename from src/common/get-reaction-emoji.ts
rename to src/server/common/get-reaction-emoji.ts
diff --git a/src/common/othello/ai/back.ts b/src/server/common/othello/ai/back.ts
similarity index 99%
rename from src/common/othello/ai/back.ts
rename to src/server/common/othello/ai/back.ts
index 27dbc3952..c20c6fed2 100644
--- a/src/common/othello/ai/back.ts
+++ b/src/server/common/othello/ai/back.ts
@@ -8,7 +8,7 @@
 
 import * as request from 'request-promise-native';
 import Othello, { Color } from '../core';
-import conf from '../../../conf';
+import conf from '../../../../conf';
 
 let game;
 let form;
diff --git a/src/common/othello/ai/front.ts b/src/server/common/othello/ai/front.ts
similarity index 99%
rename from src/common/othello/ai/front.ts
rename to src/server/common/othello/ai/front.ts
index d892afbed..af0b748fc 100644
--- a/src/common/othello/ai/front.ts
+++ b/src/server/common/othello/ai/front.ts
@@ -10,7 +10,7 @@ import * as childProcess from 'child_process';
 const WebSocket = require('ws');
 import * as ReconnectingWebSocket from 'reconnecting-websocket';
 import * as request from 'request-promise-native';
-import conf from '../../../conf';
+import conf from '../../../../conf';
 
 // 設定 ////////////////////////////////////////////////////////
 
diff --git a/src/common/othello/ai/index.ts b/src/server/common/othello/ai/index.ts
similarity index 100%
rename from src/common/othello/ai/index.ts
rename to src/server/common/othello/ai/index.ts
diff --git a/src/common/othello/core.ts b/src/server/common/othello/core.ts
similarity index 100%
rename from src/common/othello/core.ts
rename to src/server/common/othello/core.ts
diff --git a/src/common/othello/maps.ts b/src/server/common/othello/maps.ts
similarity index 100%
rename from src/common/othello/maps.ts
rename to src/server/common/othello/maps.ts
diff --git a/src/common/user/get-acct.ts b/src/server/common/user/get-acct.ts
similarity index 100%
rename from src/common/user/get-acct.ts
rename to src/server/common/user/get-acct.ts
diff --git a/src/common/user/get-summary.ts b/src/server/common/user/get-summary.ts
similarity index 100%
rename from src/common/user/get-summary.ts
rename to src/server/common/user/get-summary.ts
diff --git a/src/common/user/parse-acct.ts b/src/server/common/user/parse-acct.ts
similarity index 100%
rename from src/common/user/parse-acct.ts
rename to src/server/common/user/parse-acct.ts
diff --git a/src/file/assets/avatar.jpg b/src/server/file/assets/avatar.jpg
similarity index 100%
rename from src/file/assets/avatar.jpg
rename to src/server/file/assets/avatar.jpg
diff --git a/src/file/assets/bad-egg.png b/src/server/file/assets/bad-egg.png
similarity index 100%
rename from src/file/assets/bad-egg.png
rename to src/server/file/assets/bad-egg.png
diff --git a/src/file/assets/dummy.png b/src/server/file/assets/dummy.png
similarity index 100%
rename from src/file/assets/dummy.png
rename to src/server/file/assets/dummy.png
diff --git a/src/file/assets/not-an-image.png b/src/server/file/assets/not-an-image.png
similarity index 100%
rename from src/file/assets/not-an-image.png
rename to src/server/file/assets/not-an-image.png
diff --git a/src/file/assets/thumbnail-not-available.png b/src/server/file/assets/thumbnail-not-available.png
similarity index 100%
rename from src/file/assets/thumbnail-not-available.png
rename to src/server/file/assets/thumbnail-not-available.png
diff --git a/src/file/server.ts b/src/server/file/server.ts
similarity index 100%
rename from src/file/server.ts
rename to src/server/file/server.ts
diff --git a/src/server.ts b/src/server/index.ts
similarity index 77%
rename from src/server.ts
rename to src/server/index.ts
index 0e030002a..3908b8a52 100644
--- a/src/server.ts
+++ b/src/server/index.ts
@@ -5,13 +5,12 @@
 import * as fs from 'fs';
 import * as http from 'http';
 import * as https from 'https';
-import * as cluster from 'cluster';
 import * as express from 'express';
 import * as morgan from 'morgan';
 import Accesses from 'accesses';
 
 import log from './log-request';
-import config from './conf';
+import config from '../conf';
 
 /**
  * Init app
@@ -56,10 +55,7 @@ app.use('/api', require('./api/server'));
 app.use('/files', require('./file/server'));
 app.use(require('./web/server'));
 
-/**
- * Create server
- */
-const server = (() => {
+function createServer() {
 	if (config.https) {
 		const certs = {};
 		Object.keys(config.https).forEach(k => {
@@ -69,24 +65,18 @@ const server = (() => {
 	} else {
 		return http.createServer(app);
 	}
-})();
+}
 
-/**
- * Steaming
- */
-require('./api/streaming')(server);
+export default () => new Promise(resolve => {
+	const server = createServer();
 
-/**
- * Server listen
- */
-server.listen(config.port, () => {
-	if (cluster.isWorker) {
-		// Send a 'ready' message to parent process
-		process.send('ready');
-	}
+	/**
+	 * Steaming
+	 */
+	require('./api/streaming')(server);
+
+	/**
+	 * Server listen
+	 */
+	server.listen(config.port, resolve);
 });
-
-/**
- * Export app for testing
- */
-module.exports = app;
diff --git a/src/log-request.ts b/src/server/log-request.ts
similarity index 100%
rename from src/log-request.ts
rename to src/server/log-request.ts
diff --git a/src/web/app/animation.styl b/src/server/web/app/animation.styl
similarity index 100%
rename from src/web/app/animation.styl
rename to src/server/web/app/animation.styl
diff --git a/src/web/app/app.styl b/src/server/web/app/app.styl
similarity index 100%
rename from src/web/app/app.styl
rename to src/server/web/app/app.styl
diff --git a/src/web/app/app.vue b/src/server/web/app/app.vue
similarity index 100%
rename from src/web/app/app.vue
rename to src/server/web/app/app.vue
diff --git a/src/web/app/auth/assets/logo.svg b/src/server/web/app/auth/assets/logo.svg
similarity index 100%
rename from src/web/app/auth/assets/logo.svg
rename to src/server/web/app/auth/assets/logo.svg
diff --git a/src/web/app/auth/script.ts b/src/server/web/app/auth/script.ts
similarity index 100%
rename from src/web/app/auth/script.ts
rename to src/server/web/app/auth/script.ts
diff --git a/src/web/app/auth/style.styl b/src/server/web/app/auth/style.styl
similarity index 100%
rename from src/web/app/auth/style.styl
rename to src/server/web/app/auth/style.styl
diff --git a/src/web/app/auth/views/form.vue b/src/server/web/app/auth/views/form.vue
similarity index 100%
rename from src/web/app/auth/views/form.vue
rename to src/server/web/app/auth/views/form.vue
diff --git a/src/web/app/auth/views/index.vue b/src/server/web/app/auth/views/index.vue
similarity index 100%
rename from src/web/app/auth/views/index.vue
rename to src/server/web/app/auth/views/index.vue
diff --git a/src/web/app/base.pug b/src/server/web/app/base.pug
similarity index 76%
rename from src/web/app/base.pug
rename to src/server/web/app/base.pug
index d7c7f0aed..60eb1539e 100644
--- a/src/web/app/base.pug
+++ b/src/server/web/app/base.pug
@@ -14,12 +14,12 @@ html
 		title Misskey
 
 		style
-			include ./../../../built/web/assets/init.css
+			include ./../../../../built/server/web/assets/init.css
 		script
-			include ./../../../built/web/assets/boot.js
+			include ./../../../../built/server/web/assets/boot.js
 
 		script
-			include ./../../../built/web/assets/safe.js
+			include ./../../../../built/server/web/assets/safe.js
 
 		//- FontAwesome style
 		style #{facss}
diff --git a/src/web/app/boot.js b/src/server/web/app/boot.js
similarity index 100%
rename from src/web/app/boot.js
rename to src/server/web/app/boot.js
diff --git a/src/web/app/ch/script.ts b/src/server/web/app/ch/script.ts
similarity index 100%
rename from src/web/app/ch/script.ts
rename to src/server/web/app/ch/script.ts
diff --git a/src/web/app/ch/style.styl b/src/server/web/app/ch/style.styl
similarity index 100%
rename from src/web/app/ch/style.styl
rename to src/server/web/app/ch/style.styl
diff --git a/src/web/app/ch/tags/channel.tag b/src/server/web/app/ch/tags/channel.tag
similarity index 100%
rename from src/web/app/ch/tags/channel.tag
rename to src/server/web/app/ch/tags/channel.tag
diff --git a/src/web/app/ch/tags/header.tag b/src/server/web/app/ch/tags/header.tag
similarity index 100%
rename from src/web/app/ch/tags/header.tag
rename to src/server/web/app/ch/tags/header.tag
diff --git a/src/web/app/ch/tags/index.tag b/src/server/web/app/ch/tags/index.tag
similarity index 100%
rename from src/web/app/ch/tags/index.tag
rename to src/server/web/app/ch/tags/index.tag
diff --git a/src/web/app/ch/tags/index.ts b/src/server/web/app/ch/tags/index.ts
similarity index 100%
rename from src/web/app/ch/tags/index.ts
rename to src/server/web/app/ch/tags/index.ts
diff --git a/src/web/app/common/define-widget.ts b/src/server/web/app/common/define-widget.ts
similarity index 100%
rename from src/web/app/common/define-widget.ts
rename to src/server/web/app/common/define-widget.ts
diff --git a/src/web/app/common/mios.ts b/src/server/web/app/common/mios.ts
similarity index 100%
rename from src/web/app/common/mios.ts
rename to src/server/web/app/common/mios.ts
diff --git a/src/web/app/common/scripts/check-for-update.ts b/src/server/web/app/common/scripts/check-for-update.ts
similarity index 100%
rename from src/web/app/common/scripts/check-for-update.ts
rename to src/server/web/app/common/scripts/check-for-update.ts
diff --git a/src/web/app/common/scripts/compose-notification.ts b/src/server/web/app/common/scripts/compose-notification.ts
similarity index 100%
rename from src/web/app/common/scripts/compose-notification.ts
rename to src/server/web/app/common/scripts/compose-notification.ts
diff --git a/src/web/app/common/scripts/contains.ts b/src/server/web/app/common/scripts/contains.ts
similarity index 100%
rename from src/web/app/common/scripts/contains.ts
rename to src/server/web/app/common/scripts/contains.ts
diff --git a/src/web/app/common/scripts/copy-to-clipboard.ts b/src/server/web/app/common/scripts/copy-to-clipboard.ts
similarity index 100%
rename from src/web/app/common/scripts/copy-to-clipboard.ts
rename to src/server/web/app/common/scripts/copy-to-clipboard.ts
diff --git a/src/web/app/common/scripts/date-stringify.ts b/src/server/web/app/common/scripts/date-stringify.ts
similarity index 100%
rename from src/web/app/common/scripts/date-stringify.ts
rename to src/server/web/app/common/scripts/date-stringify.ts
diff --git a/src/web/app/common/scripts/fuck-ad-block.ts b/src/server/web/app/common/scripts/fuck-ad-block.ts
similarity index 100%
rename from src/web/app/common/scripts/fuck-ad-block.ts
rename to src/server/web/app/common/scripts/fuck-ad-block.ts
diff --git a/src/web/app/common/scripts/gcd.ts b/src/server/web/app/common/scripts/gcd.ts
similarity index 100%
rename from src/web/app/common/scripts/gcd.ts
rename to src/server/web/app/common/scripts/gcd.ts
diff --git a/src/web/app/common/scripts/get-kao.ts b/src/server/web/app/common/scripts/get-kao.ts
similarity index 100%
rename from src/web/app/common/scripts/get-kao.ts
rename to src/server/web/app/common/scripts/get-kao.ts
diff --git a/src/web/app/common/scripts/get-median.ts b/src/server/web/app/common/scripts/get-median.ts
similarity index 100%
rename from src/web/app/common/scripts/get-median.ts
rename to src/server/web/app/common/scripts/get-median.ts
diff --git a/src/web/app/common/scripts/loading.ts b/src/server/web/app/common/scripts/loading.ts
similarity index 100%
rename from src/web/app/common/scripts/loading.ts
rename to src/server/web/app/common/scripts/loading.ts
diff --git a/src/web/app/common/scripts/parse-search-query.ts b/src/server/web/app/common/scripts/parse-search-query.ts
similarity index 100%
rename from src/web/app/common/scripts/parse-search-query.ts
rename to src/server/web/app/common/scripts/parse-search-query.ts
diff --git a/src/web/app/common/scripts/streaming/channel.ts b/src/server/web/app/common/scripts/streaming/channel.ts
similarity index 100%
rename from src/web/app/common/scripts/streaming/channel.ts
rename to src/server/web/app/common/scripts/streaming/channel.ts
diff --git a/src/web/app/common/scripts/streaming/drive.ts b/src/server/web/app/common/scripts/streaming/drive.ts
similarity index 100%
rename from src/web/app/common/scripts/streaming/drive.ts
rename to src/server/web/app/common/scripts/streaming/drive.ts
diff --git a/src/web/app/common/scripts/streaming/home.ts b/src/server/web/app/common/scripts/streaming/home.ts
similarity index 100%
rename from src/web/app/common/scripts/streaming/home.ts
rename to src/server/web/app/common/scripts/streaming/home.ts
diff --git a/src/web/app/common/scripts/streaming/messaging-index.ts b/src/server/web/app/common/scripts/streaming/messaging-index.ts
similarity index 100%
rename from src/web/app/common/scripts/streaming/messaging-index.ts
rename to src/server/web/app/common/scripts/streaming/messaging-index.ts
diff --git a/src/web/app/common/scripts/streaming/messaging.ts b/src/server/web/app/common/scripts/streaming/messaging.ts
similarity index 100%
rename from src/web/app/common/scripts/streaming/messaging.ts
rename to src/server/web/app/common/scripts/streaming/messaging.ts
diff --git a/src/web/app/common/scripts/streaming/othello-game.ts b/src/server/web/app/common/scripts/streaming/othello-game.ts
similarity index 100%
rename from src/web/app/common/scripts/streaming/othello-game.ts
rename to src/server/web/app/common/scripts/streaming/othello-game.ts
diff --git a/src/web/app/common/scripts/streaming/othello.ts b/src/server/web/app/common/scripts/streaming/othello.ts
similarity index 100%
rename from src/web/app/common/scripts/streaming/othello.ts
rename to src/server/web/app/common/scripts/streaming/othello.ts
diff --git a/src/web/app/common/scripts/streaming/requests.ts b/src/server/web/app/common/scripts/streaming/requests.ts
similarity index 100%
rename from src/web/app/common/scripts/streaming/requests.ts
rename to src/server/web/app/common/scripts/streaming/requests.ts
diff --git a/src/web/app/common/scripts/streaming/server.ts b/src/server/web/app/common/scripts/streaming/server.ts
similarity index 100%
rename from src/web/app/common/scripts/streaming/server.ts
rename to src/server/web/app/common/scripts/streaming/server.ts
diff --git a/src/web/app/common/scripts/streaming/stream-manager.ts b/src/server/web/app/common/scripts/streaming/stream-manager.ts
similarity index 100%
rename from src/web/app/common/scripts/streaming/stream-manager.ts
rename to src/server/web/app/common/scripts/streaming/stream-manager.ts
diff --git a/src/web/app/common/scripts/streaming/stream.ts b/src/server/web/app/common/scripts/streaming/stream.ts
similarity index 100%
rename from src/web/app/common/scripts/streaming/stream.ts
rename to src/server/web/app/common/scripts/streaming/stream.ts
diff --git a/src/web/app/common/views/components/autocomplete.vue b/src/server/web/app/common/views/components/autocomplete.vue
similarity index 100%
rename from src/web/app/common/views/components/autocomplete.vue
rename to src/server/web/app/common/views/components/autocomplete.vue
diff --git a/src/web/app/common/views/components/connect-failed.troubleshooter.vue b/src/server/web/app/common/views/components/connect-failed.troubleshooter.vue
similarity index 100%
rename from src/web/app/common/views/components/connect-failed.troubleshooter.vue
rename to src/server/web/app/common/views/components/connect-failed.troubleshooter.vue
diff --git a/src/web/app/common/views/components/connect-failed.vue b/src/server/web/app/common/views/components/connect-failed.vue
similarity index 100%
rename from src/web/app/common/views/components/connect-failed.vue
rename to src/server/web/app/common/views/components/connect-failed.vue
diff --git a/src/web/app/common/views/components/ellipsis.vue b/src/server/web/app/common/views/components/ellipsis.vue
similarity index 100%
rename from src/web/app/common/views/components/ellipsis.vue
rename to src/server/web/app/common/views/components/ellipsis.vue
diff --git a/src/web/app/common/views/components/file-type-icon.vue b/src/server/web/app/common/views/components/file-type-icon.vue
similarity index 100%
rename from src/web/app/common/views/components/file-type-icon.vue
rename to src/server/web/app/common/views/components/file-type-icon.vue
diff --git a/src/web/app/common/views/components/forkit.vue b/src/server/web/app/common/views/components/forkit.vue
similarity index 100%
rename from src/web/app/common/views/components/forkit.vue
rename to src/server/web/app/common/views/components/forkit.vue
diff --git a/src/web/app/common/views/components/index.ts b/src/server/web/app/common/views/components/index.ts
similarity index 100%
rename from src/web/app/common/views/components/index.ts
rename to src/server/web/app/common/views/components/index.ts
diff --git a/src/web/app/common/views/components/media-list.vue b/src/server/web/app/common/views/components/media-list.vue
similarity index 100%
rename from src/web/app/common/views/components/media-list.vue
rename to src/server/web/app/common/views/components/media-list.vue
diff --git a/src/web/app/common/views/components/messaging-room.form.vue b/src/server/web/app/common/views/components/messaging-room.form.vue
similarity index 100%
rename from src/web/app/common/views/components/messaging-room.form.vue
rename to src/server/web/app/common/views/components/messaging-room.form.vue
diff --git a/src/web/app/common/views/components/messaging-room.message.vue b/src/server/web/app/common/views/components/messaging-room.message.vue
similarity index 100%
rename from src/web/app/common/views/components/messaging-room.message.vue
rename to src/server/web/app/common/views/components/messaging-room.message.vue
diff --git a/src/web/app/common/views/components/messaging-room.vue b/src/server/web/app/common/views/components/messaging-room.vue
similarity index 100%
rename from src/web/app/common/views/components/messaging-room.vue
rename to src/server/web/app/common/views/components/messaging-room.vue
diff --git a/src/web/app/common/views/components/messaging.vue b/src/server/web/app/common/views/components/messaging.vue
similarity index 100%
rename from src/web/app/common/views/components/messaging.vue
rename to src/server/web/app/common/views/components/messaging.vue
diff --git a/src/web/app/common/views/components/nav.vue b/src/server/web/app/common/views/components/nav.vue
similarity index 100%
rename from src/web/app/common/views/components/nav.vue
rename to src/server/web/app/common/views/components/nav.vue
diff --git a/src/web/app/common/views/components/othello.game.vue b/src/server/web/app/common/views/components/othello.game.vue
similarity index 100%
rename from src/web/app/common/views/components/othello.game.vue
rename to src/server/web/app/common/views/components/othello.game.vue
diff --git a/src/web/app/common/views/components/othello.gameroom.vue b/src/server/web/app/common/views/components/othello.gameroom.vue
similarity index 100%
rename from src/web/app/common/views/components/othello.gameroom.vue
rename to src/server/web/app/common/views/components/othello.gameroom.vue
diff --git a/src/web/app/common/views/components/othello.room.vue b/src/server/web/app/common/views/components/othello.room.vue
similarity index 100%
rename from src/web/app/common/views/components/othello.room.vue
rename to src/server/web/app/common/views/components/othello.room.vue
diff --git a/src/web/app/common/views/components/othello.vue b/src/server/web/app/common/views/components/othello.vue
similarity index 100%
rename from src/web/app/common/views/components/othello.vue
rename to src/server/web/app/common/views/components/othello.vue
diff --git a/src/web/app/common/views/components/poll-editor.vue b/src/server/web/app/common/views/components/poll-editor.vue
similarity index 100%
rename from src/web/app/common/views/components/poll-editor.vue
rename to src/server/web/app/common/views/components/poll-editor.vue
diff --git a/src/web/app/common/views/components/poll.vue b/src/server/web/app/common/views/components/poll.vue
similarity index 100%
rename from src/web/app/common/views/components/poll.vue
rename to src/server/web/app/common/views/components/poll.vue
diff --git a/src/web/app/common/views/components/post-html.ts b/src/server/web/app/common/views/components/post-html.ts
similarity index 100%
rename from src/web/app/common/views/components/post-html.ts
rename to src/server/web/app/common/views/components/post-html.ts
diff --git a/src/web/app/common/views/components/post-menu.vue b/src/server/web/app/common/views/components/post-menu.vue
similarity index 100%
rename from src/web/app/common/views/components/post-menu.vue
rename to src/server/web/app/common/views/components/post-menu.vue
diff --git a/src/web/app/common/views/components/reaction-icon.vue b/src/server/web/app/common/views/components/reaction-icon.vue
similarity index 100%
rename from src/web/app/common/views/components/reaction-icon.vue
rename to src/server/web/app/common/views/components/reaction-icon.vue
diff --git a/src/web/app/common/views/components/reaction-picker.vue b/src/server/web/app/common/views/components/reaction-picker.vue
similarity index 100%
rename from src/web/app/common/views/components/reaction-picker.vue
rename to src/server/web/app/common/views/components/reaction-picker.vue
diff --git a/src/web/app/common/views/components/reactions-viewer.vue b/src/server/web/app/common/views/components/reactions-viewer.vue
similarity index 100%
rename from src/web/app/common/views/components/reactions-viewer.vue
rename to src/server/web/app/common/views/components/reactions-viewer.vue
diff --git a/src/web/app/common/views/components/signin.vue b/src/server/web/app/common/views/components/signin.vue
similarity index 100%
rename from src/web/app/common/views/components/signin.vue
rename to src/server/web/app/common/views/components/signin.vue
diff --git a/src/web/app/common/views/components/signup.vue b/src/server/web/app/common/views/components/signup.vue
similarity index 100%
rename from src/web/app/common/views/components/signup.vue
rename to src/server/web/app/common/views/components/signup.vue
diff --git a/src/web/app/common/views/components/special-message.vue b/src/server/web/app/common/views/components/special-message.vue
similarity index 100%
rename from src/web/app/common/views/components/special-message.vue
rename to src/server/web/app/common/views/components/special-message.vue
diff --git a/src/web/app/common/views/components/stream-indicator.vue b/src/server/web/app/common/views/components/stream-indicator.vue
similarity index 100%
rename from src/web/app/common/views/components/stream-indicator.vue
rename to src/server/web/app/common/views/components/stream-indicator.vue
diff --git a/src/web/app/common/views/components/switch.vue b/src/server/web/app/common/views/components/switch.vue
similarity index 100%
rename from src/web/app/common/views/components/switch.vue
rename to src/server/web/app/common/views/components/switch.vue
diff --git a/src/web/app/common/views/components/time.vue b/src/server/web/app/common/views/components/time.vue
similarity index 100%
rename from src/web/app/common/views/components/time.vue
rename to src/server/web/app/common/views/components/time.vue
diff --git a/src/web/app/common/views/components/timer.vue b/src/server/web/app/common/views/components/timer.vue
similarity index 100%
rename from src/web/app/common/views/components/timer.vue
rename to src/server/web/app/common/views/components/timer.vue
diff --git a/src/web/app/common/views/components/twitter-setting.vue b/src/server/web/app/common/views/components/twitter-setting.vue
similarity index 100%
rename from src/web/app/common/views/components/twitter-setting.vue
rename to src/server/web/app/common/views/components/twitter-setting.vue
diff --git a/src/web/app/common/views/components/uploader.vue b/src/server/web/app/common/views/components/uploader.vue
similarity index 100%
rename from src/web/app/common/views/components/uploader.vue
rename to src/server/web/app/common/views/components/uploader.vue
diff --git a/src/web/app/common/views/components/url-preview.vue b/src/server/web/app/common/views/components/url-preview.vue
similarity index 100%
rename from src/web/app/common/views/components/url-preview.vue
rename to src/server/web/app/common/views/components/url-preview.vue
diff --git a/src/web/app/common/views/components/url.vue b/src/server/web/app/common/views/components/url.vue
similarity index 100%
rename from src/web/app/common/views/components/url.vue
rename to src/server/web/app/common/views/components/url.vue
diff --git a/src/web/app/common/views/components/welcome-timeline.vue b/src/server/web/app/common/views/components/welcome-timeline.vue
similarity index 100%
rename from src/web/app/common/views/components/welcome-timeline.vue
rename to src/server/web/app/common/views/components/welcome-timeline.vue
diff --git a/src/web/app/common/views/directives/autocomplete.ts b/src/server/web/app/common/views/directives/autocomplete.ts
similarity index 100%
rename from src/web/app/common/views/directives/autocomplete.ts
rename to src/server/web/app/common/views/directives/autocomplete.ts
diff --git a/src/web/app/common/views/directives/index.ts b/src/server/web/app/common/views/directives/index.ts
similarity index 100%
rename from src/web/app/common/views/directives/index.ts
rename to src/server/web/app/common/views/directives/index.ts
diff --git a/src/web/app/common/views/filters/bytes.ts b/src/server/web/app/common/views/filters/bytes.ts
similarity index 100%
rename from src/web/app/common/views/filters/bytes.ts
rename to src/server/web/app/common/views/filters/bytes.ts
diff --git a/src/web/app/common/views/filters/index.ts b/src/server/web/app/common/views/filters/index.ts
similarity index 100%
rename from src/web/app/common/views/filters/index.ts
rename to src/server/web/app/common/views/filters/index.ts
diff --git a/src/web/app/common/views/filters/number.ts b/src/server/web/app/common/views/filters/number.ts
similarity index 100%
rename from src/web/app/common/views/filters/number.ts
rename to src/server/web/app/common/views/filters/number.ts
diff --git a/src/web/app/common/views/widgets/access-log.vue b/src/server/web/app/common/views/widgets/access-log.vue
similarity index 100%
rename from src/web/app/common/views/widgets/access-log.vue
rename to src/server/web/app/common/views/widgets/access-log.vue
diff --git a/src/web/app/common/views/widgets/broadcast.vue b/src/server/web/app/common/views/widgets/broadcast.vue
similarity index 100%
rename from src/web/app/common/views/widgets/broadcast.vue
rename to src/server/web/app/common/views/widgets/broadcast.vue
diff --git a/src/web/app/common/views/widgets/calendar.vue b/src/server/web/app/common/views/widgets/calendar.vue
similarity index 100%
rename from src/web/app/common/views/widgets/calendar.vue
rename to src/server/web/app/common/views/widgets/calendar.vue
diff --git a/src/web/app/common/views/widgets/donation.vue b/src/server/web/app/common/views/widgets/donation.vue
similarity index 100%
rename from src/web/app/common/views/widgets/donation.vue
rename to src/server/web/app/common/views/widgets/donation.vue
diff --git a/src/web/app/common/views/widgets/index.ts b/src/server/web/app/common/views/widgets/index.ts
similarity index 100%
rename from src/web/app/common/views/widgets/index.ts
rename to src/server/web/app/common/views/widgets/index.ts
diff --git a/src/web/app/common/views/widgets/nav.vue b/src/server/web/app/common/views/widgets/nav.vue
similarity index 100%
rename from src/web/app/common/views/widgets/nav.vue
rename to src/server/web/app/common/views/widgets/nav.vue
diff --git a/src/web/app/common/views/widgets/photo-stream.vue b/src/server/web/app/common/views/widgets/photo-stream.vue
similarity index 100%
rename from src/web/app/common/views/widgets/photo-stream.vue
rename to src/server/web/app/common/views/widgets/photo-stream.vue
diff --git a/src/web/app/common/views/widgets/rss.vue b/src/server/web/app/common/views/widgets/rss.vue
similarity index 100%
rename from src/web/app/common/views/widgets/rss.vue
rename to src/server/web/app/common/views/widgets/rss.vue
diff --git a/src/web/app/common/views/widgets/server.cpu-memory.vue b/src/server/web/app/common/views/widgets/server.cpu-memory.vue
similarity index 100%
rename from src/web/app/common/views/widgets/server.cpu-memory.vue
rename to src/server/web/app/common/views/widgets/server.cpu-memory.vue
diff --git a/src/web/app/common/views/widgets/server.cpu.vue b/src/server/web/app/common/views/widgets/server.cpu.vue
similarity index 100%
rename from src/web/app/common/views/widgets/server.cpu.vue
rename to src/server/web/app/common/views/widgets/server.cpu.vue
diff --git a/src/web/app/common/views/widgets/server.disk.vue b/src/server/web/app/common/views/widgets/server.disk.vue
similarity index 100%
rename from src/web/app/common/views/widgets/server.disk.vue
rename to src/server/web/app/common/views/widgets/server.disk.vue
diff --git a/src/web/app/common/views/widgets/server.info.vue b/src/server/web/app/common/views/widgets/server.info.vue
similarity index 100%
rename from src/web/app/common/views/widgets/server.info.vue
rename to src/server/web/app/common/views/widgets/server.info.vue
diff --git a/src/web/app/common/views/widgets/server.memory.vue b/src/server/web/app/common/views/widgets/server.memory.vue
similarity index 100%
rename from src/web/app/common/views/widgets/server.memory.vue
rename to src/server/web/app/common/views/widgets/server.memory.vue
diff --git a/src/web/app/common/views/widgets/server.pie.vue b/src/server/web/app/common/views/widgets/server.pie.vue
similarity index 100%
rename from src/web/app/common/views/widgets/server.pie.vue
rename to src/server/web/app/common/views/widgets/server.pie.vue
diff --git a/src/web/app/common/views/widgets/server.uptimes.vue b/src/server/web/app/common/views/widgets/server.uptimes.vue
similarity index 100%
rename from src/web/app/common/views/widgets/server.uptimes.vue
rename to src/server/web/app/common/views/widgets/server.uptimes.vue
diff --git a/src/web/app/common/views/widgets/server.vue b/src/server/web/app/common/views/widgets/server.vue
similarity index 100%
rename from src/web/app/common/views/widgets/server.vue
rename to src/server/web/app/common/views/widgets/server.vue
diff --git a/src/web/app/common/views/widgets/slideshow.vue b/src/server/web/app/common/views/widgets/slideshow.vue
similarity index 100%
rename from src/web/app/common/views/widgets/slideshow.vue
rename to src/server/web/app/common/views/widgets/slideshow.vue
diff --git a/src/web/app/common/views/widgets/tips.vue b/src/server/web/app/common/views/widgets/tips.vue
similarity index 100%
rename from src/web/app/common/views/widgets/tips.vue
rename to src/server/web/app/common/views/widgets/tips.vue
diff --git a/src/web/app/common/views/widgets/version.vue b/src/server/web/app/common/views/widgets/version.vue
similarity index 100%
rename from src/web/app/common/views/widgets/version.vue
rename to src/server/web/app/common/views/widgets/version.vue
diff --git a/src/web/app/config.ts b/src/server/web/app/config.ts
similarity index 100%
rename from src/web/app/config.ts
rename to src/server/web/app/config.ts
diff --git a/src/web/app/desktop/api/choose-drive-file.ts b/src/server/web/app/desktop/api/choose-drive-file.ts
similarity index 100%
rename from src/web/app/desktop/api/choose-drive-file.ts
rename to src/server/web/app/desktop/api/choose-drive-file.ts
diff --git a/src/web/app/desktop/api/choose-drive-folder.ts b/src/server/web/app/desktop/api/choose-drive-folder.ts
similarity index 100%
rename from src/web/app/desktop/api/choose-drive-folder.ts
rename to src/server/web/app/desktop/api/choose-drive-folder.ts
diff --git a/src/web/app/desktop/api/contextmenu.ts b/src/server/web/app/desktop/api/contextmenu.ts
similarity index 100%
rename from src/web/app/desktop/api/contextmenu.ts
rename to src/server/web/app/desktop/api/contextmenu.ts
diff --git a/src/web/app/desktop/api/dialog.ts b/src/server/web/app/desktop/api/dialog.ts
similarity index 100%
rename from src/web/app/desktop/api/dialog.ts
rename to src/server/web/app/desktop/api/dialog.ts
diff --git a/src/web/app/desktop/api/input.ts b/src/server/web/app/desktop/api/input.ts
similarity index 100%
rename from src/web/app/desktop/api/input.ts
rename to src/server/web/app/desktop/api/input.ts
diff --git a/src/web/app/desktop/api/notify.ts b/src/server/web/app/desktop/api/notify.ts
similarity index 100%
rename from src/web/app/desktop/api/notify.ts
rename to src/server/web/app/desktop/api/notify.ts
diff --git a/src/web/app/desktop/api/post.ts b/src/server/web/app/desktop/api/post.ts
similarity index 100%
rename from src/web/app/desktop/api/post.ts
rename to src/server/web/app/desktop/api/post.ts
diff --git a/src/web/app/desktop/api/update-avatar.ts b/src/server/web/app/desktop/api/update-avatar.ts
similarity index 100%
rename from src/web/app/desktop/api/update-avatar.ts
rename to src/server/web/app/desktop/api/update-avatar.ts
diff --git a/src/web/app/desktop/api/update-banner.ts b/src/server/web/app/desktop/api/update-banner.ts
similarity index 100%
rename from src/web/app/desktop/api/update-banner.ts
rename to src/server/web/app/desktop/api/update-banner.ts
diff --git a/src/web/app/desktop/assets/grid.svg b/src/server/web/app/desktop/assets/grid.svg
similarity index 100%
rename from src/web/app/desktop/assets/grid.svg
rename to src/server/web/app/desktop/assets/grid.svg
diff --git a/src/web/app/desktop/assets/header-logo-white.svg b/src/server/web/app/desktop/assets/header-logo-white.svg
similarity index 100%
rename from src/web/app/desktop/assets/header-logo-white.svg
rename to src/server/web/app/desktop/assets/header-logo-white.svg
diff --git a/src/web/app/desktop/assets/header-logo.svg b/src/server/web/app/desktop/assets/header-logo.svg
similarity index 100%
rename from src/web/app/desktop/assets/header-logo.svg
rename to src/server/web/app/desktop/assets/header-logo.svg
diff --git a/src/web/app/desktop/assets/index.jpg b/src/server/web/app/desktop/assets/index.jpg
similarity index 100%
rename from src/web/app/desktop/assets/index.jpg
rename to src/server/web/app/desktop/assets/index.jpg
diff --git a/src/web/app/desktop/assets/remove.png b/src/server/web/app/desktop/assets/remove.png
similarity index 100%
rename from src/web/app/desktop/assets/remove.png
rename to src/server/web/app/desktop/assets/remove.png
diff --git a/src/web/app/desktop/script.ts b/src/server/web/app/desktop/script.ts
similarity index 100%
rename from src/web/app/desktop/script.ts
rename to src/server/web/app/desktop/script.ts
diff --git a/src/web/app/desktop/style.styl b/src/server/web/app/desktop/style.styl
similarity index 100%
rename from src/web/app/desktop/style.styl
rename to src/server/web/app/desktop/style.styl
diff --git a/src/web/app/desktop/ui.styl b/src/server/web/app/desktop/ui.styl
similarity index 100%
rename from src/web/app/desktop/ui.styl
rename to src/server/web/app/desktop/ui.styl
diff --git a/src/web/app/desktop/views/components/activity.calendar.vue b/src/server/web/app/desktop/views/components/activity.calendar.vue
similarity index 100%
rename from src/web/app/desktop/views/components/activity.calendar.vue
rename to src/server/web/app/desktop/views/components/activity.calendar.vue
diff --git a/src/web/app/desktop/views/components/activity.chart.vue b/src/server/web/app/desktop/views/components/activity.chart.vue
similarity index 100%
rename from src/web/app/desktop/views/components/activity.chart.vue
rename to src/server/web/app/desktop/views/components/activity.chart.vue
diff --git a/src/web/app/desktop/views/components/activity.vue b/src/server/web/app/desktop/views/components/activity.vue
similarity index 100%
rename from src/web/app/desktop/views/components/activity.vue
rename to src/server/web/app/desktop/views/components/activity.vue
diff --git a/src/web/app/desktop/views/components/analog-clock.vue b/src/server/web/app/desktop/views/components/analog-clock.vue
similarity index 100%
rename from src/web/app/desktop/views/components/analog-clock.vue
rename to src/server/web/app/desktop/views/components/analog-clock.vue
diff --git a/src/web/app/desktop/views/components/calendar.vue b/src/server/web/app/desktop/views/components/calendar.vue
similarity index 100%
rename from src/web/app/desktop/views/components/calendar.vue
rename to src/server/web/app/desktop/views/components/calendar.vue
diff --git a/src/web/app/desktop/views/components/choose-file-from-drive-window.vue b/src/server/web/app/desktop/views/components/choose-file-from-drive-window.vue
similarity index 100%
rename from src/web/app/desktop/views/components/choose-file-from-drive-window.vue
rename to src/server/web/app/desktop/views/components/choose-file-from-drive-window.vue
diff --git a/src/web/app/desktop/views/components/choose-folder-from-drive-window.vue b/src/server/web/app/desktop/views/components/choose-folder-from-drive-window.vue
similarity index 100%
rename from src/web/app/desktop/views/components/choose-folder-from-drive-window.vue
rename to src/server/web/app/desktop/views/components/choose-folder-from-drive-window.vue
diff --git a/src/web/app/desktop/views/components/context-menu.menu.vue b/src/server/web/app/desktop/views/components/context-menu.menu.vue
similarity index 100%
rename from src/web/app/desktop/views/components/context-menu.menu.vue
rename to src/server/web/app/desktop/views/components/context-menu.menu.vue
diff --git a/src/web/app/desktop/views/components/context-menu.vue b/src/server/web/app/desktop/views/components/context-menu.vue
similarity index 100%
rename from src/web/app/desktop/views/components/context-menu.vue
rename to src/server/web/app/desktop/views/components/context-menu.vue
diff --git a/src/web/app/desktop/views/components/crop-window.vue b/src/server/web/app/desktop/views/components/crop-window.vue
similarity index 100%
rename from src/web/app/desktop/views/components/crop-window.vue
rename to src/server/web/app/desktop/views/components/crop-window.vue
diff --git a/src/web/app/desktop/views/components/dialog.vue b/src/server/web/app/desktop/views/components/dialog.vue
similarity index 100%
rename from src/web/app/desktop/views/components/dialog.vue
rename to src/server/web/app/desktop/views/components/dialog.vue
diff --git a/src/web/app/desktop/views/components/drive-window.vue b/src/server/web/app/desktop/views/components/drive-window.vue
similarity index 100%
rename from src/web/app/desktop/views/components/drive-window.vue
rename to src/server/web/app/desktop/views/components/drive-window.vue
diff --git a/src/web/app/desktop/views/components/drive.file.vue b/src/server/web/app/desktop/views/components/drive.file.vue
similarity index 100%
rename from src/web/app/desktop/views/components/drive.file.vue
rename to src/server/web/app/desktop/views/components/drive.file.vue
diff --git a/src/web/app/desktop/views/components/drive.folder.vue b/src/server/web/app/desktop/views/components/drive.folder.vue
similarity index 100%
rename from src/web/app/desktop/views/components/drive.folder.vue
rename to src/server/web/app/desktop/views/components/drive.folder.vue
diff --git a/src/web/app/desktop/views/components/drive.nav-folder.vue b/src/server/web/app/desktop/views/components/drive.nav-folder.vue
similarity index 100%
rename from src/web/app/desktop/views/components/drive.nav-folder.vue
rename to src/server/web/app/desktop/views/components/drive.nav-folder.vue
diff --git a/src/web/app/desktop/views/components/drive.vue b/src/server/web/app/desktop/views/components/drive.vue
similarity index 100%
rename from src/web/app/desktop/views/components/drive.vue
rename to src/server/web/app/desktop/views/components/drive.vue
diff --git a/src/web/app/desktop/views/components/ellipsis-icon.vue b/src/server/web/app/desktop/views/components/ellipsis-icon.vue
similarity index 100%
rename from src/web/app/desktop/views/components/ellipsis-icon.vue
rename to src/server/web/app/desktop/views/components/ellipsis-icon.vue
diff --git a/src/web/app/desktop/views/components/follow-button.vue b/src/server/web/app/desktop/views/components/follow-button.vue
similarity index 100%
rename from src/web/app/desktop/views/components/follow-button.vue
rename to src/server/web/app/desktop/views/components/follow-button.vue
diff --git a/src/web/app/desktop/views/components/followers-window.vue b/src/server/web/app/desktop/views/components/followers-window.vue
similarity index 100%
rename from src/web/app/desktop/views/components/followers-window.vue
rename to src/server/web/app/desktop/views/components/followers-window.vue
diff --git a/src/web/app/desktop/views/components/followers.vue b/src/server/web/app/desktop/views/components/followers.vue
similarity index 100%
rename from src/web/app/desktop/views/components/followers.vue
rename to src/server/web/app/desktop/views/components/followers.vue
diff --git a/src/web/app/desktop/views/components/following-window.vue b/src/server/web/app/desktop/views/components/following-window.vue
similarity index 100%
rename from src/web/app/desktop/views/components/following-window.vue
rename to src/server/web/app/desktop/views/components/following-window.vue
diff --git a/src/web/app/desktop/views/components/following.vue b/src/server/web/app/desktop/views/components/following.vue
similarity index 100%
rename from src/web/app/desktop/views/components/following.vue
rename to src/server/web/app/desktop/views/components/following.vue
diff --git a/src/web/app/desktop/views/components/friends-maker.vue b/src/server/web/app/desktop/views/components/friends-maker.vue
similarity index 100%
rename from src/web/app/desktop/views/components/friends-maker.vue
rename to src/server/web/app/desktop/views/components/friends-maker.vue
diff --git a/src/web/app/desktop/views/components/game-window.vue b/src/server/web/app/desktop/views/components/game-window.vue
similarity index 100%
rename from src/web/app/desktop/views/components/game-window.vue
rename to src/server/web/app/desktop/views/components/game-window.vue
diff --git a/src/web/app/desktop/views/components/home.vue b/src/server/web/app/desktop/views/components/home.vue
similarity index 100%
rename from src/web/app/desktop/views/components/home.vue
rename to src/server/web/app/desktop/views/components/home.vue
diff --git a/src/web/app/desktop/views/components/index.ts b/src/server/web/app/desktop/views/components/index.ts
similarity index 100%
rename from src/web/app/desktop/views/components/index.ts
rename to src/server/web/app/desktop/views/components/index.ts
diff --git a/src/web/app/desktop/views/components/input-dialog.vue b/src/server/web/app/desktop/views/components/input-dialog.vue
similarity index 100%
rename from src/web/app/desktop/views/components/input-dialog.vue
rename to src/server/web/app/desktop/views/components/input-dialog.vue
diff --git a/src/web/app/desktop/views/components/media-image-dialog.vue b/src/server/web/app/desktop/views/components/media-image-dialog.vue
similarity index 100%
rename from src/web/app/desktop/views/components/media-image-dialog.vue
rename to src/server/web/app/desktop/views/components/media-image-dialog.vue
diff --git a/src/web/app/desktop/views/components/media-image.vue b/src/server/web/app/desktop/views/components/media-image.vue
similarity index 100%
rename from src/web/app/desktop/views/components/media-image.vue
rename to src/server/web/app/desktop/views/components/media-image.vue
diff --git a/src/web/app/desktop/views/components/media-video-dialog.vue b/src/server/web/app/desktop/views/components/media-video-dialog.vue
similarity index 100%
rename from src/web/app/desktop/views/components/media-video-dialog.vue
rename to src/server/web/app/desktop/views/components/media-video-dialog.vue
diff --git a/src/web/app/desktop/views/components/media-video.vue b/src/server/web/app/desktop/views/components/media-video.vue
similarity index 100%
rename from src/web/app/desktop/views/components/media-video.vue
rename to src/server/web/app/desktop/views/components/media-video.vue
diff --git a/src/web/app/desktop/views/components/mentions.vue b/src/server/web/app/desktop/views/components/mentions.vue
similarity index 100%
rename from src/web/app/desktop/views/components/mentions.vue
rename to src/server/web/app/desktop/views/components/mentions.vue
diff --git a/src/web/app/desktop/views/components/messaging-room-window.vue b/src/server/web/app/desktop/views/components/messaging-room-window.vue
similarity index 100%
rename from src/web/app/desktop/views/components/messaging-room-window.vue
rename to src/server/web/app/desktop/views/components/messaging-room-window.vue
diff --git a/src/web/app/desktop/views/components/messaging-window.vue b/src/server/web/app/desktop/views/components/messaging-window.vue
similarity index 100%
rename from src/web/app/desktop/views/components/messaging-window.vue
rename to src/server/web/app/desktop/views/components/messaging-window.vue
diff --git a/src/web/app/desktop/views/components/notifications.vue b/src/server/web/app/desktop/views/components/notifications.vue
similarity index 100%
rename from src/web/app/desktop/views/components/notifications.vue
rename to src/server/web/app/desktop/views/components/notifications.vue
diff --git a/src/web/app/desktop/views/components/post-detail.sub.vue b/src/server/web/app/desktop/views/components/post-detail.sub.vue
similarity index 100%
rename from src/web/app/desktop/views/components/post-detail.sub.vue
rename to src/server/web/app/desktop/views/components/post-detail.sub.vue
diff --git a/src/web/app/desktop/views/components/post-detail.vue b/src/server/web/app/desktop/views/components/post-detail.vue
similarity index 100%
rename from src/web/app/desktop/views/components/post-detail.vue
rename to src/server/web/app/desktop/views/components/post-detail.vue
diff --git a/src/web/app/desktop/views/components/post-form-window.vue b/src/server/web/app/desktop/views/components/post-form-window.vue
similarity index 100%
rename from src/web/app/desktop/views/components/post-form-window.vue
rename to src/server/web/app/desktop/views/components/post-form-window.vue
diff --git a/src/web/app/desktop/views/components/post-form.vue b/src/server/web/app/desktop/views/components/post-form.vue
similarity index 100%
rename from src/web/app/desktop/views/components/post-form.vue
rename to src/server/web/app/desktop/views/components/post-form.vue
diff --git a/src/web/app/desktop/views/components/post-preview.vue b/src/server/web/app/desktop/views/components/post-preview.vue
similarity index 100%
rename from src/web/app/desktop/views/components/post-preview.vue
rename to src/server/web/app/desktop/views/components/post-preview.vue
diff --git a/src/web/app/desktop/views/components/posts.post.sub.vue b/src/server/web/app/desktop/views/components/posts.post.sub.vue
similarity index 100%
rename from src/web/app/desktop/views/components/posts.post.sub.vue
rename to src/server/web/app/desktop/views/components/posts.post.sub.vue
diff --git a/src/web/app/desktop/views/components/posts.post.vue b/src/server/web/app/desktop/views/components/posts.post.vue
similarity index 100%
rename from src/web/app/desktop/views/components/posts.post.vue
rename to src/server/web/app/desktop/views/components/posts.post.vue
diff --git a/src/web/app/desktop/views/components/posts.vue b/src/server/web/app/desktop/views/components/posts.vue
similarity index 100%
rename from src/web/app/desktop/views/components/posts.vue
rename to src/server/web/app/desktop/views/components/posts.vue
diff --git a/src/web/app/desktop/views/components/progress-dialog.vue b/src/server/web/app/desktop/views/components/progress-dialog.vue
similarity index 100%
rename from src/web/app/desktop/views/components/progress-dialog.vue
rename to src/server/web/app/desktop/views/components/progress-dialog.vue
diff --git a/src/web/app/desktop/views/components/repost-form-window.vue b/src/server/web/app/desktop/views/components/repost-form-window.vue
similarity index 100%
rename from src/web/app/desktop/views/components/repost-form-window.vue
rename to src/server/web/app/desktop/views/components/repost-form-window.vue
diff --git a/src/web/app/desktop/views/components/repost-form.vue b/src/server/web/app/desktop/views/components/repost-form.vue
similarity index 100%
rename from src/web/app/desktop/views/components/repost-form.vue
rename to src/server/web/app/desktop/views/components/repost-form.vue
diff --git a/src/web/app/desktop/views/components/settings-window.vue b/src/server/web/app/desktop/views/components/settings-window.vue
similarity index 100%
rename from src/web/app/desktop/views/components/settings-window.vue
rename to src/server/web/app/desktop/views/components/settings-window.vue
diff --git a/src/web/app/desktop/views/components/settings.2fa.vue b/src/server/web/app/desktop/views/components/settings.2fa.vue
similarity index 100%
rename from src/web/app/desktop/views/components/settings.2fa.vue
rename to src/server/web/app/desktop/views/components/settings.2fa.vue
diff --git a/src/web/app/desktop/views/components/settings.api.vue b/src/server/web/app/desktop/views/components/settings.api.vue
similarity index 100%
rename from src/web/app/desktop/views/components/settings.api.vue
rename to src/server/web/app/desktop/views/components/settings.api.vue
diff --git a/src/web/app/desktop/views/components/settings.apps.vue b/src/server/web/app/desktop/views/components/settings.apps.vue
similarity index 100%
rename from src/web/app/desktop/views/components/settings.apps.vue
rename to src/server/web/app/desktop/views/components/settings.apps.vue
diff --git a/src/web/app/desktop/views/components/settings.drive.vue b/src/server/web/app/desktop/views/components/settings.drive.vue
similarity index 100%
rename from src/web/app/desktop/views/components/settings.drive.vue
rename to src/server/web/app/desktop/views/components/settings.drive.vue
diff --git a/src/web/app/desktop/views/components/settings.mute.vue b/src/server/web/app/desktop/views/components/settings.mute.vue
similarity index 100%
rename from src/web/app/desktop/views/components/settings.mute.vue
rename to src/server/web/app/desktop/views/components/settings.mute.vue
diff --git a/src/web/app/desktop/views/components/settings.password.vue b/src/server/web/app/desktop/views/components/settings.password.vue
similarity index 100%
rename from src/web/app/desktop/views/components/settings.password.vue
rename to src/server/web/app/desktop/views/components/settings.password.vue
diff --git a/src/web/app/desktop/views/components/settings.profile.vue b/src/server/web/app/desktop/views/components/settings.profile.vue
similarity index 100%
rename from src/web/app/desktop/views/components/settings.profile.vue
rename to src/server/web/app/desktop/views/components/settings.profile.vue
diff --git a/src/web/app/desktop/views/components/settings.signins.vue b/src/server/web/app/desktop/views/components/settings.signins.vue
similarity index 100%
rename from src/web/app/desktop/views/components/settings.signins.vue
rename to src/server/web/app/desktop/views/components/settings.signins.vue
diff --git a/src/web/app/desktop/views/components/settings.vue b/src/server/web/app/desktop/views/components/settings.vue
similarity index 100%
rename from src/web/app/desktop/views/components/settings.vue
rename to src/server/web/app/desktop/views/components/settings.vue
diff --git a/src/web/app/desktop/views/components/sub-post-content.vue b/src/server/web/app/desktop/views/components/sub-post-content.vue
similarity index 100%
rename from src/web/app/desktop/views/components/sub-post-content.vue
rename to src/server/web/app/desktop/views/components/sub-post-content.vue
diff --git a/src/web/app/desktop/views/components/taskmanager.vue b/src/server/web/app/desktop/views/components/taskmanager.vue
similarity index 100%
rename from src/web/app/desktop/views/components/taskmanager.vue
rename to src/server/web/app/desktop/views/components/taskmanager.vue
diff --git a/src/web/app/desktop/views/components/timeline.vue b/src/server/web/app/desktop/views/components/timeline.vue
similarity index 100%
rename from src/web/app/desktop/views/components/timeline.vue
rename to src/server/web/app/desktop/views/components/timeline.vue
diff --git a/src/web/app/desktop/views/components/ui-notification.vue b/src/server/web/app/desktop/views/components/ui-notification.vue
similarity index 100%
rename from src/web/app/desktop/views/components/ui-notification.vue
rename to src/server/web/app/desktop/views/components/ui-notification.vue
diff --git a/src/web/app/desktop/views/components/ui.header.account.vue b/src/server/web/app/desktop/views/components/ui.header.account.vue
similarity index 100%
rename from src/web/app/desktop/views/components/ui.header.account.vue
rename to src/server/web/app/desktop/views/components/ui.header.account.vue
diff --git a/src/web/app/desktop/views/components/ui.header.clock.vue b/src/server/web/app/desktop/views/components/ui.header.clock.vue
similarity index 100%
rename from src/web/app/desktop/views/components/ui.header.clock.vue
rename to src/server/web/app/desktop/views/components/ui.header.clock.vue
diff --git a/src/web/app/desktop/views/components/ui.header.nav.vue b/src/server/web/app/desktop/views/components/ui.header.nav.vue
similarity index 100%
rename from src/web/app/desktop/views/components/ui.header.nav.vue
rename to src/server/web/app/desktop/views/components/ui.header.nav.vue
diff --git a/src/web/app/desktop/views/components/ui.header.notifications.vue b/src/server/web/app/desktop/views/components/ui.header.notifications.vue
similarity index 100%
rename from src/web/app/desktop/views/components/ui.header.notifications.vue
rename to src/server/web/app/desktop/views/components/ui.header.notifications.vue
diff --git a/src/web/app/desktop/views/components/ui.header.post.vue b/src/server/web/app/desktop/views/components/ui.header.post.vue
similarity index 100%
rename from src/web/app/desktop/views/components/ui.header.post.vue
rename to src/server/web/app/desktop/views/components/ui.header.post.vue
diff --git a/src/web/app/desktop/views/components/ui.header.search.vue b/src/server/web/app/desktop/views/components/ui.header.search.vue
similarity index 100%
rename from src/web/app/desktop/views/components/ui.header.search.vue
rename to src/server/web/app/desktop/views/components/ui.header.search.vue
diff --git a/src/web/app/desktop/views/components/ui.header.vue b/src/server/web/app/desktop/views/components/ui.header.vue
similarity index 100%
rename from src/web/app/desktop/views/components/ui.header.vue
rename to src/server/web/app/desktop/views/components/ui.header.vue
diff --git a/src/web/app/desktop/views/components/ui.vue b/src/server/web/app/desktop/views/components/ui.vue
similarity index 100%
rename from src/web/app/desktop/views/components/ui.vue
rename to src/server/web/app/desktop/views/components/ui.vue
diff --git a/src/web/app/desktop/views/components/user-preview.vue b/src/server/web/app/desktop/views/components/user-preview.vue
similarity index 100%
rename from src/web/app/desktop/views/components/user-preview.vue
rename to src/server/web/app/desktop/views/components/user-preview.vue
diff --git a/src/web/app/desktop/views/components/users-list.item.vue b/src/server/web/app/desktop/views/components/users-list.item.vue
similarity index 100%
rename from src/web/app/desktop/views/components/users-list.item.vue
rename to src/server/web/app/desktop/views/components/users-list.item.vue
diff --git a/src/web/app/desktop/views/components/users-list.vue b/src/server/web/app/desktop/views/components/users-list.vue
similarity index 100%
rename from src/web/app/desktop/views/components/users-list.vue
rename to src/server/web/app/desktop/views/components/users-list.vue
diff --git a/src/web/app/desktop/views/components/widget-container.vue b/src/server/web/app/desktop/views/components/widget-container.vue
similarity index 100%
rename from src/web/app/desktop/views/components/widget-container.vue
rename to src/server/web/app/desktop/views/components/widget-container.vue
diff --git a/src/web/app/desktop/views/components/window.vue b/src/server/web/app/desktop/views/components/window.vue
similarity index 100%
rename from src/web/app/desktop/views/components/window.vue
rename to src/server/web/app/desktop/views/components/window.vue
diff --git a/src/web/app/desktop/views/directives/index.ts b/src/server/web/app/desktop/views/directives/index.ts
similarity index 100%
rename from src/web/app/desktop/views/directives/index.ts
rename to src/server/web/app/desktop/views/directives/index.ts
diff --git a/src/web/app/desktop/views/directives/user-preview.ts b/src/server/web/app/desktop/views/directives/user-preview.ts
similarity index 100%
rename from src/web/app/desktop/views/directives/user-preview.ts
rename to src/server/web/app/desktop/views/directives/user-preview.ts
diff --git a/src/web/app/desktop/views/pages/drive.vue b/src/server/web/app/desktop/views/pages/drive.vue
similarity index 100%
rename from src/web/app/desktop/views/pages/drive.vue
rename to src/server/web/app/desktop/views/pages/drive.vue
diff --git a/src/web/app/desktop/views/pages/home-customize.vue b/src/server/web/app/desktop/views/pages/home-customize.vue
similarity index 100%
rename from src/web/app/desktop/views/pages/home-customize.vue
rename to src/server/web/app/desktop/views/pages/home-customize.vue
diff --git a/src/web/app/desktop/views/pages/home.vue b/src/server/web/app/desktop/views/pages/home.vue
similarity index 100%
rename from src/web/app/desktop/views/pages/home.vue
rename to src/server/web/app/desktop/views/pages/home.vue
diff --git a/src/web/app/desktop/views/pages/index.vue b/src/server/web/app/desktop/views/pages/index.vue
similarity index 100%
rename from src/web/app/desktop/views/pages/index.vue
rename to src/server/web/app/desktop/views/pages/index.vue
diff --git a/src/web/app/desktop/views/pages/messaging-room.vue b/src/server/web/app/desktop/views/pages/messaging-room.vue
similarity index 100%
rename from src/web/app/desktop/views/pages/messaging-room.vue
rename to src/server/web/app/desktop/views/pages/messaging-room.vue
diff --git a/src/web/app/desktop/views/pages/othello.vue b/src/server/web/app/desktop/views/pages/othello.vue
similarity index 100%
rename from src/web/app/desktop/views/pages/othello.vue
rename to src/server/web/app/desktop/views/pages/othello.vue
diff --git a/src/web/app/desktop/views/pages/post.vue b/src/server/web/app/desktop/views/pages/post.vue
similarity index 100%
rename from src/web/app/desktop/views/pages/post.vue
rename to src/server/web/app/desktop/views/pages/post.vue
diff --git a/src/web/app/desktop/views/pages/search.vue b/src/server/web/app/desktop/views/pages/search.vue
similarity index 100%
rename from src/web/app/desktop/views/pages/search.vue
rename to src/server/web/app/desktop/views/pages/search.vue
diff --git a/src/web/app/desktop/views/pages/selectdrive.vue b/src/server/web/app/desktop/views/pages/selectdrive.vue
similarity index 100%
rename from src/web/app/desktop/views/pages/selectdrive.vue
rename to src/server/web/app/desktop/views/pages/selectdrive.vue
diff --git a/src/web/app/desktop/views/pages/user/user.followers-you-know.vue b/src/server/web/app/desktop/views/pages/user/user.followers-you-know.vue
similarity index 100%
rename from src/web/app/desktop/views/pages/user/user.followers-you-know.vue
rename to src/server/web/app/desktop/views/pages/user/user.followers-you-know.vue
diff --git a/src/web/app/desktop/views/pages/user/user.friends.vue b/src/server/web/app/desktop/views/pages/user/user.friends.vue
similarity index 100%
rename from src/web/app/desktop/views/pages/user/user.friends.vue
rename to src/server/web/app/desktop/views/pages/user/user.friends.vue
diff --git a/src/web/app/desktop/views/pages/user/user.header.vue b/src/server/web/app/desktop/views/pages/user/user.header.vue
similarity index 100%
rename from src/web/app/desktop/views/pages/user/user.header.vue
rename to src/server/web/app/desktop/views/pages/user/user.header.vue
diff --git a/src/web/app/desktop/views/pages/user/user.home.vue b/src/server/web/app/desktop/views/pages/user/user.home.vue
similarity index 100%
rename from src/web/app/desktop/views/pages/user/user.home.vue
rename to src/server/web/app/desktop/views/pages/user/user.home.vue
diff --git a/src/web/app/desktop/views/pages/user/user.photos.vue b/src/server/web/app/desktop/views/pages/user/user.photos.vue
similarity index 100%
rename from src/web/app/desktop/views/pages/user/user.photos.vue
rename to src/server/web/app/desktop/views/pages/user/user.photos.vue
diff --git a/src/web/app/desktop/views/pages/user/user.profile.vue b/src/server/web/app/desktop/views/pages/user/user.profile.vue
similarity index 100%
rename from src/web/app/desktop/views/pages/user/user.profile.vue
rename to src/server/web/app/desktop/views/pages/user/user.profile.vue
diff --git a/src/web/app/desktop/views/pages/user/user.timeline.vue b/src/server/web/app/desktop/views/pages/user/user.timeline.vue
similarity index 100%
rename from src/web/app/desktop/views/pages/user/user.timeline.vue
rename to src/server/web/app/desktop/views/pages/user/user.timeline.vue
diff --git a/src/web/app/desktop/views/pages/user/user.vue b/src/server/web/app/desktop/views/pages/user/user.vue
similarity index 100%
rename from src/web/app/desktop/views/pages/user/user.vue
rename to src/server/web/app/desktop/views/pages/user/user.vue
diff --git a/src/web/app/desktop/views/pages/welcome.vue b/src/server/web/app/desktop/views/pages/welcome.vue
similarity index 100%
rename from src/web/app/desktop/views/pages/welcome.vue
rename to src/server/web/app/desktop/views/pages/welcome.vue
diff --git a/src/web/app/desktop/views/widgets/activity.vue b/src/server/web/app/desktop/views/widgets/activity.vue
similarity index 100%
rename from src/web/app/desktop/views/widgets/activity.vue
rename to src/server/web/app/desktop/views/widgets/activity.vue
diff --git a/src/web/app/desktop/views/widgets/channel.channel.form.vue b/src/server/web/app/desktop/views/widgets/channel.channel.form.vue
similarity index 100%
rename from src/web/app/desktop/views/widgets/channel.channel.form.vue
rename to src/server/web/app/desktop/views/widgets/channel.channel.form.vue
diff --git a/src/web/app/desktop/views/widgets/channel.channel.post.vue b/src/server/web/app/desktop/views/widgets/channel.channel.post.vue
similarity index 100%
rename from src/web/app/desktop/views/widgets/channel.channel.post.vue
rename to src/server/web/app/desktop/views/widgets/channel.channel.post.vue
diff --git a/src/web/app/desktop/views/widgets/channel.channel.vue b/src/server/web/app/desktop/views/widgets/channel.channel.vue
similarity index 100%
rename from src/web/app/desktop/views/widgets/channel.channel.vue
rename to src/server/web/app/desktop/views/widgets/channel.channel.vue
diff --git a/src/web/app/desktop/views/widgets/channel.vue b/src/server/web/app/desktop/views/widgets/channel.vue
similarity index 100%
rename from src/web/app/desktop/views/widgets/channel.vue
rename to src/server/web/app/desktop/views/widgets/channel.vue
diff --git a/src/web/app/desktop/views/widgets/index.ts b/src/server/web/app/desktop/views/widgets/index.ts
similarity index 100%
rename from src/web/app/desktop/views/widgets/index.ts
rename to src/server/web/app/desktop/views/widgets/index.ts
diff --git a/src/web/app/desktop/views/widgets/messaging.vue b/src/server/web/app/desktop/views/widgets/messaging.vue
similarity index 100%
rename from src/web/app/desktop/views/widgets/messaging.vue
rename to src/server/web/app/desktop/views/widgets/messaging.vue
diff --git a/src/web/app/desktop/views/widgets/notifications.vue b/src/server/web/app/desktop/views/widgets/notifications.vue
similarity index 100%
rename from src/web/app/desktop/views/widgets/notifications.vue
rename to src/server/web/app/desktop/views/widgets/notifications.vue
diff --git a/src/web/app/desktop/views/widgets/polls.vue b/src/server/web/app/desktop/views/widgets/polls.vue
similarity index 100%
rename from src/web/app/desktop/views/widgets/polls.vue
rename to src/server/web/app/desktop/views/widgets/polls.vue
diff --git a/src/web/app/desktop/views/widgets/post-form.vue b/src/server/web/app/desktop/views/widgets/post-form.vue
similarity index 100%
rename from src/web/app/desktop/views/widgets/post-form.vue
rename to src/server/web/app/desktop/views/widgets/post-form.vue
diff --git a/src/web/app/desktop/views/widgets/profile.vue b/src/server/web/app/desktop/views/widgets/profile.vue
similarity index 100%
rename from src/web/app/desktop/views/widgets/profile.vue
rename to src/server/web/app/desktop/views/widgets/profile.vue
diff --git a/src/web/app/desktop/views/widgets/timemachine.vue b/src/server/web/app/desktop/views/widgets/timemachine.vue
similarity index 100%
rename from src/web/app/desktop/views/widgets/timemachine.vue
rename to src/server/web/app/desktop/views/widgets/timemachine.vue
diff --git a/src/web/app/desktop/views/widgets/trends.vue b/src/server/web/app/desktop/views/widgets/trends.vue
similarity index 100%
rename from src/web/app/desktop/views/widgets/trends.vue
rename to src/server/web/app/desktop/views/widgets/trends.vue
diff --git a/src/web/app/desktop/views/widgets/users.vue b/src/server/web/app/desktop/views/widgets/users.vue
similarity index 100%
rename from src/web/app/desktop/views/widgets/users.vue
rename to src/server/web/app/desktop/views/widgets/users.vue
diff --git a/src/web/app/dev/script.ts b/src/server/web/app/dev/script.ts
similarity index 100%
rename from src/web/app/dev/script.ts
rename to src/server/web/app/dev/script.ts
diff --git a/src/web/app/dev/style.styl b/src/server/web/app/dev/style.styl
similarity index 100%
rename from src/web/app/dev/style.styl
rename to src/server/web/app/dev/style.styl
diff --git a/src/web/app/dev/views/app.vue b/src/server/web/app/dev/views/app.vue
similarity index 100%
rename from src/web/app/dev/views/app.vue
rename to src/server/web/app/dev/views/app.vue
diff --git a/src/web/app/dev/views/apps.vue b/src/server/web/app/dev/views/apps.vue
similarity index 100%
rename from src/web/app/dev/views/apps.vue
rename to src/server/web/app/dev/views/apps.vue
diff --git a/src/web/app/dev/views/index.vue b/src/server/web/app/dev/views/index.vue
similarity index 100%
rename from src/web/app/dev/views/index.vue
rename to src/server/web/app/dev/views/index.vue
diff --git a/src/web/app/dev/views/new-app.vue b/src/server/web/app/dev/views/new-app.vue
similarity index 100%
rename from src/web/app/dev/views/new-app.vue
rename to src/server/web/app/dev/views/new-app.vue
diff --git a/src/web/app/dev/views/ui.vue b/src/server/web/app/dev/views/ui.vue
similarity index 100%
rename from src/web/app/dev/views/ui.vue
rename to src/server/web/app/dev/views/ui.vue
diff --git a/src/web/app/init.css b/src/server/web/app/init.css
similarity index 100%
rename from src/web/app/init.css
rename to src/server/web/app/init.css
diff --git a/src/web/app/init.ts b/src/server/web/app/init.ts
similarity index 100%
rename from src/web/app/init.ts
rename to src/server/web/app/init.ts
diff --git a/src/web/app/mobile/api/choose-drive-file.ts b/src/server/web/app/mobile/api/choose-drive-file.ts
similarity index 100%
rename from src/web/app/mobile/api/choose-drive-file.ts
rename to src/server/web/app/mobile/api/choose-drive-file.ts
diff --git a/src/web/app/mobile/api/choose-drive-folder.ts b/src/server/web/app/mobile/api/choose-drive-folder.ts
similarity index 100%
rename from src/web/app/mobile/api/choose-drive-folder.ts
rename to src/server/web/app/mobile/api/choose-drive-folder.ts
diff --git a/src/web/app/mobile/api/dialog.ts b/src/server/web/app/mobile/api/dialog.ts
similarity index 100%
rename from src/web/app/mobile/api/dialog.ts
rename to src/server/web/app/mobile/api/dialog.ts
diff --git a/src/web/app/mobile/api/input.ts b/src/server/web/app/mobile/api/input.ts
similarity index 100%
rename from src/web/app/mobile/api/input.ts
rename to src/server/web/app/mobile/api/input.ts
diff --git a/src/web/app/mobile/api/notify.ts b/src/server/web/app/mobile/api/notify.ts
similarity index 100%
rename from src/web/app/mobile/api/notify.ts
rename to src/server/web/app/mobile/api/notify.ts
diff --git a/src/web/app/mobile/api/post.ts b/src/server/web/app/mobile/api/post.ts
similarity index 100%
rename from src/web/app/mobile/api/post.ts
rename to src/server/web/app/mobile/api/post.ts
diff --git a/src/web/app/mobile/script.ts b/src/server/web/app/mobile/script.ts
similarity index 100%
rename from src/web/app/mobile/script.ts
rename to src/server/web/app/mobile/script.ts
diff --git a/src/web/app/mobile/style.styl b/src/server/web/app/mobile/style.styl
similarity index 100%
rename from src/web/app/mobile/style.styl
rename to src/server/web/app/mobile/style.styl
diff --git a/src/web/app/mobile/views/components/activity.vue b/src/server/web/app/mobile/views/components/activity.vue
similarity index 100%
rename from src/web/app/mobile/views/components/activity.vue
rename to src/server/web/app/mobile/views/components/activity.vue
diff --git a/src/web/app/mobile/views/components/drive-file-chooser.vue b/src/server/web/app/mobile/views/components/drive-file-chooser.vue
similarity index 100%
rename from src/web/app/mobile/views/components/drive-file-chooser.vue
rename to src/server/web/app/mobile/views/components/drive-file-chooser.vue
diff --git a/src/web/app/mobile/views/components/drive-folder-chooser.vue b/src/server/web/app/mobile/views/components/drive-folder-chooser.vue
similarity index 100%
rename from src/web/app/mobile/views/components/drive-folder-chooser.vue
rename to src/server/web/app/mobile/views/components/drive-folder-chooser.vue
diff --git a/src/web/app/mobile/views/components/drive.file-detail.vue b/src/server/web/app/mobile/views/components/drive.file-detail.vue
similarity index 100%
rename from src/web/app/mobile/views/components/drive.file-detail.vue
rename to src/server/web/app/mobile/views/components/drive.file-detail.vue
diff --git a/src/web/app/mobile/views/components/drive.file.vue b/src/server/web/app/mobile/views/components/drive.file.vue
similarity index 100%
rename from src/web/app/mobile/views/components/drive.file.vue
rename to src/server/web/app/mobile/views/components/drive.file.vue
diff --git a/src/web/app/mobile/views/components/drive.folder.vue b/src/server/web/app/mobile/views/components/drive.folder.vue
similarity index 100%
rename from src/web/app/mobile/views/components/drive.folder.vue
rename to src/server/web/app/mobile/views/components/drive.folder.vue
diff --git a/src/web/app/mobile/views/components/drive.vue b/src/server/web/app/mobile/views/components/drive.vue
similarity index 100%
rename from src/web/app/mobile/views/components/drive.vue
rename to src/server/web/app/mobile/views/components/drive.vue
diff --git a/src/web/app/mobile/views/components/follow-button.vue b/src/server/web/app/mobile/views/components/follow-button.vue
similarity index 100%
rename from src/web/app/mobile/views/components/follow-button.vue
rename to src/server/web/app/mobile/views/components/follow-button.vue
diff --git a/src/web/app/mobile/views/components/friends-maker.vue b/src/server/web/app/mobile/views/components/friends-maker.vue
similarity index 100%
rename from src/web/app/mobile/views/components/friends-maker.vue
rename to src/server/web/app/mobile/views/components/friends-maker.vue
diff --git a/src/web/app/mobile/views/components/index.ts b/src/server/web/app/mobile/views/components/index.ts
similarity index 100%
rename from src/web/app/mobile/views/components/index.ts
rename to src/server/web/app/mobile/views/components/index.ts
diff --git a/src/web/app/mobile/views/components/media-image.vue b/src/server/web/app/mobile/views/components/media-image.vue
similarity index 100%
rename from src/web/app/mobile/views/components/media-image.vue
rename to src/server/web/app/mobile/views/components/media-image.vue
diff --git a/src/web/app/mobile/views/components/media-video.vue b/src/server/web/app/mobile/views/components/media-video.vue
similarity index 100%
rename from src/web/app/mobile/views/components/media-video.vue
rename to src/server/web/app/mobile/views/components/media-video.vue
diff --git a/src/web/app/mobile/views/components/notification-preview.vue b/src/server/web/app/mobile/views/components/notification-preview.vue
similarity index 100%
rename from src/web/app/mobile/views/components/notification-preview.vue
rename to src/server/web/app/mobile/views/components/notification-preview.vue
diff --git a/src/web/app/mobile/views/components/notification.vue b/src/server/web/app/mobile/views/components/notification.vue
similarity index 100%
rename from src/web/app/mobile/views/components/notification.vue
rename to src/server/web/app/mobile/views/components/notification.vue
diff --git a/src/web/app/mobile/views/components/notifications.vue b/src/server/web/app/mobile/views/components/notifications.vue
similarity index 100%
rename from src/web/app/mobile/views/components/notifications.vue
rename to src/server/web/app/mobile/views/components/notifications.vue
diff --git a/src/web/app/mobile/views/components/notify.vue b/src/server/web/app/mobile/views/components/notify.vue
similarity index 100%
rename from src/web/app/mobile/views/components/notify.vue
rename to src/server/web/app/mobile/views/components/notify.vue
diff --git a/src/web/app/mobile/views/components/post-card.vue b/src/server/web/app/mobile/views/components/post-card.vue
similarity index 100%
rename from src/web/app/mobile/views/components/post-card.vue
rename to src/server/web/app/mobile/views/components/post-card.vue
diff --git a/src/web/app/mobile/views/components/post-detail.sub.vue b/src/server/web/app/mobile/views/components/post-detail.sub.vue
similarity index 100%
rename from src/web/app/mobile/views/components/post-detail.sub.vue
rename to src/server/web/app/mobile/views/components/post-detail.sub.vue
diff --git a/src/web/app/mobile/views/components/post-detail.vue b/src/server/web/app/mobile/views/components/post-detail.vue
similarity index 100%
rename from src/web/app/mobile/views/components/post-detail.vue
rename to src/server/web/app/mobile/views/components/post-detail.vue
diff --git a/src/web/app/mobile/views/components/post-form.vue b/src/server/web/app/mobile/views/components/post-form.vue
similarity index 100%
rename from src/web/app/mobile/views/components/post-form.vue
rename to src/server/web/app/mobile/views/components/post-form.vue
diff --git a/src/web/app/mobile/views/components/post-preview.vue b/src/server/web/app/mobile/views/components/post-preview.vue
similarity index 100%
rename from src/web/app/mobile/views/components/post-preview.vue
rename to src/server/web/app/mobile/views/components/post-preview.vue
diff --git a/src/web/app/mobile/views/components/post.sub.vue b/src/server/web/app/mobile/views/components/post.sub.vue
similarity index 100%
rename from src/web/app/mobile/views/components/post.sub.vue
rename to src/server/web/app/mobile/views/components/post.sub.vue
diff --git a/src/web/app/mobile/views/components/post.vue b/src/server/web/app/mobile/views/components/post.vue
similarity index 100%
rename from src/web/app/mobile/views/components/post.vue
rename to src/server/web/app/mobile/views/components/post.vue
diff --git a/src/web/app/mobile/views/components/posts.vue b/src/server/web/app/mobile/views/components/posts.vue
similarity index 100%
rename from src/web/app/mobile/views/components/posts.vue
rename to src/server/web/app/mobile/views/components/posts.vue
diff --git a/src/web/app/mobile/views/components/sub-post-content.vue b/src/server/web/app/mobile/views/components/sub-post-content.vue
similarity index 100%
rename from src/web/app/mobile/views/components/sub-post-content.vue
rename to src/server/web/app/mobile/views/components/sub-post-content.vue
diff --git a/src/web/app/mobile/views/components/timeline.vue b/src/server/web/app/mobile/views/components/timeline.vue
similarity index 100%
rename from src/web/app/mobile/views/components/timeline.vue
rename to src/server/web/app/mobile/views/components/timeline.vue
diff --git a/src/web/app/mobile/views/components/ui.header.vue b/src/server/web/app/mobile/views/components/ui.header.vue
similarity index 100%
rename from src/web/app/mobile/views/components/ui.header.vue
rename to src/server/web/app/mobile/views/components/ui.header.vue
diff --git a/src/web/app/mobile/views/components/ui.nav.vue b/src/server/web/app/mobile/views/components/ui.nav.vue
similarity index 100%
rename from src/web/app/mobile/views/components/ui.nav.vue
rename to src/server/web/app/mobile/views/components/ui.nav.vue
diff --git a/src/web/app/mobile/views/components/ui.vue b/src/server/web/app/mobile/views/components/ui.vue
similarity index 100%
rename from src/web/app/mobile/views/components/ui.vue
rename to src/server/web/app/mobile/views/components/ui.vue
diff --git a/src/web/app/mobile/views/components/user-card.vue b/src/server/web/app/mobile/views/components/user-card.vue
similarity index 100%
rename from src/web/app/mobile/views/components/user-card.vue
rename to src/server/web/app/mobile/views/components/user-card.vue
diff --git a/src/web/app/mobile/views/components/user-preview.vue b/src/server/web/app/mobile/views/components/user-preview.vue
similarity index 100%
rename from src/web/app/mobile/views/components/user-preview.vue
rename to src/server/web/app/mobile/views/components/user-preview.vue
diff --git a/src/web/app/mobile/views/components/user-timeline.vue b/src/server/web/app/mobile/views/components/user-timeline.vue
similarity index 100%
rename from src/web/app/mobile/views/components/user-timeline.vue
rename to src/server/web/app/mobile/views/components/user-timeline.vue
diff --git a/src/web/app/mobile/views/components/users-list.vue b/src/server/web/app/mobile/views/components/users-list.vue
similarity index 100%
rename from src/web/app/mobile/views/components/users-list.vue
rename to src/server/web/app/mobile/views/components/users-list.vue
diff --git a/src/web/app/mobile/views/components/widget-container.vue b/src/server/web/app/mobile/views/components/widget-container.vue
similarity index 100%
rename from src/web/app/mobile/views/components/widget-container.vue
rename to src/server/web/app/mobile/views/components/widget-container.vue
diff --git a/src/web/app/mobile/views/directives/index.ts b/src/server/web/app/mobile/views/directives/index.ts
similarity index 100%
rename from src/web/app/mobile/views/directives/index.ts
rename to src/server/web/app/mobile/views/directives/index.ts
diff --git a/src/web/app/mobile/views/directives/user-preview.ts b/src/server/web/app/mobile/views/directives/user-preview.ts
similarity index 100%
rename from src/web/app/mobile/views/directives/user-preview.ts
rename to src/server/web/app/mobile/views/directives/user-preview.ts
diff --git a/src/web/app/mobile/views/pages/drive.vue b/src/server/web/app/mobile/views/pages/drive.vue
similarity index 100%
rename from src/web/app/mobile/views/pages/drive.vue
rename to src/server/web/app/mobile/views/pages/drive.vue
diff --git a/src/web/app/mobile/views/pages/followers.vue b/src/server/web/app/mobile/views/pages/followers.vue
similarity index 100%
rename from src/web/app/mobile/views/pages/followers.vue
rename to src/server/web/app/mobile/views/pages/followers.vue
diff --git a/src/web/app/mobile/views/pages/following.vue b/src/server/web/app/mobile/views/pages/following.vue
similarity index 100%
rename from src/web/app/mobile/views/pages/following.vue
rename to src/server/web/app/mobile/views/pages/following.vue
diff --git a/src/web/app/mobile/views/pages/home.vue b/src/server/web/app/mobile/views/pages/home.vue
similarity index 100%
rename from src/web/app/mobile/views/pages/home.vue
rename to src/server/web/app/mobile/views/pages/home.vue
diff --git a/src/web/app/mobile/views/pages/index.vue b/src/server/web/app/mobile/views/pages/index.vue
similarity index 100%
rename from src/web/app/mobile/views/pages/index.vue
rename to src/server/web/app/mobile/views/pages/index.vue
diff --git a/src/web/app/mobile/views/pages/messaging-room.vue b/src/server/web/app/mobile/views/pages/messaging-room.vue
similarity index 100%
rename from src/web/app/mobile/views/pages/messaging-room.vue
rename to src/server/web/app/mobile/views/pages/messaging-room.vue
diff --git a/src/web/app/mobile/views/pages/messaging.vue b/src/server/web/app/mobile/views/pages/messaging.vue
similarity index 100%
rename from src/web/app/mobile/views/pages/messaging.vue
rename to src/server/web/app/mobile/views/pages/messaging.vue
diff --git a/src/web/app/mobile/views/pages/notifications.vue b/src/server/web/app/mobile/views/pages/notifications.vue
similarity index 100%
rename from src/web/app/mobile/views/pages/notifications.vue
rename to src/server/web/app/mobile/views/pages/notifications.vue
diff --git a/src/web/app/mobile/views/pages/othello.vue b/src/server/web/app/mobile/views/pages/othello.vue
similarity index 100%
rename from src/web/app/mobile/views/pages/othello.vue
rename to src/server/web/app/mobile/views/pages/othello.vue
diff --git a/src/web/app/mobile/views/pages/post.vue b/src/server/web/app/mobile/views/pages/post.vue
similarity index 100%
rename from src/web/app/mobile/views/pages/post.vue
rename to src/server/web/app/mobile/views/pages/post.vue
diff --git a/src/web/app/mobile/views/pages/profile-setting.vue b/src/server/web/app/mobile/views/pages/profile-setting.vue
similarity index 100%
rename from src/web/app/mobile/views/pages/profile-setting.vue
rename to src/server/web/app/mobile/views/pages/profile-setting.vue
diff --git a/src/web/app/mobile/views/pages/search.vue b/src/server/web/app/mobile/views/pages/search.vue
similarity index 100%
rename from src/web/app/mobile/views/pages/search.vue
rename to src/server/web/app/mobile/views/pages/search.vue
diff --git a/src/web/app/mobile/views/pages/selectdrive.vue b/src/server/web/app/mobile/views/pages/selectdrive.vue
similarity index 100%
rename from src/web/app/mobile/views/pages/selectdrive.vue
rename to src/server/web/app/mobile/views/pages/selectdrive.vue
diff --git a/src/web/app/mobile/views/pages/settings.vue b/src/server/web/app/mobile/views/pages/settings.vue
similarity index 100%
rename from src/web/app/mobile/views/pages/settings.vue
rename to src/server/web/app/mobile/views/pages/settings.vue
diff --git a/src/web/app/mobile/views/pages/signup.vue b/src/server/web/app/mobile/views/pages/signup.vue
similarity index 100%
rename from src/web/app/mobile/views/pages/signup.vue
rename to src/server/web/app/mobile/views/pages/signup.vue
diff --git a/src/web/app/mobile/views/pages/user.vue b/src/server/web/app/mobile/views/pages/user.vue
similarity index 100%
rename from src/web/app/mobile/views/pages/user.vue
rename to src/server/web/app/mobile/views/pages/user.vue
diff --git a/src/web/app/mobile/views/pages/user/home.followers-you-know.vue b/src/server/web/app/mobile/views/pages/user/home.followers-you-know.vue
similarity index 100%
rename from src/web/app/mobile/views/pages/user/home.followers-you-know.vue
rename to src/server/web/app/mobile/views/pages/user/home.followers-you-know.vue
diff --git a/src/web/app/mobile/views/pages/user/home.friends.vue b/src/server/web/app/mobile/views/pages/user/home.friends.vue
similarity index 100%
rename from src/web/app/mobile/views/pages/user/home.friends.vue
rename to src/server/web/app/mobile/views/pages/user/home.friends.vue
diff --git a/src/web/app/mobile/views/pages/user/home.photos.vue b/src/server/web/app/mobile/views/pages/user/home.photos.vue
similarity index 100%
rename from src/web/app/mobile/views/pages/user/home.photos.vue
rename to src/server/web/app/mobile/views/pages/user/home.photos.vue
diff --git a/src/web/app/mobile/views/pages/user/home.posts.vue b/src/server/web/app/mobile/views/pages/user/home.posts.vue
similarity index 100%
rename from src/web/app/mobile/views/pages/user/home.posts.vue
rename to src/server/web/app/mobile/views/pages/user/home.posts.vue
diff --git a/src/web/app/mobile/views/pages/user/home.vue b/src/server/web/app/mobile/views/pages/user/home.vue
similarity index 100%
rename from src/web/app/mobile/views/pages/user/home.vue
rename to src/server/web/app/mobile/views/pages/user/home.vue
diff --git a/src/web/app/mobile/views/pages/welcome.vue b/src/server/web/app/mobile/views/pages/welcome.vue
similarity index 100%
rename from src/web/app/mobile/views/pages/welcome.vue
rename to src/server/web/app/mobile/views/pages/welcome.vue
diff --git a/src/web/app/mobile/views/widgets/activity.vue b/src/server/web/app/mobile/views/widgets/activity.vue
similarity index 100%
rename from src/web/app/mobile/views/widgets/activity.vue
rename to src/server/web/app/mobile/views/widgets/activity.vue
diff --git a/src/web/app/mobile/views/widgets/index.ts b/src/server/web/app/mobile/views/widgets/index.ts
similarity index 100%
rename from src/web/app/mobile/views/widgets/index.ts
rename to src/server/web/app/mobile/views/widgets/index.ts
diff --git a/src/web/app/mobile/views/widgets/profile.vue b/src/server/web/app/mobile/views/widgets/profile.vue
similarity index 100%
rename from src/web/app/mobile/views/widgets/profile.vue
rename to src/server/web/app/mobile/views/widgets/profile.vue
diff --git a/src/web/app/reset.styl b/src/server/web/app/reset.styl
similarity index 100%
rename from src/web/app/reset.styl
rename to src/server/web/app/reset.styl
diff --git a/src/web/app/safe.js b/src/server/web/app/safe.js
similarity index 100%
rename from src/web/app/safe.js
rename to src/server/web/app/safe.js
diff --git a/src/web/app/stats/style.styl b/src/server/web/app/stats/style.styl
similarity index 100%
rename from src/web/app/stats/style.styl
rename to src/server/web/app/stats/style.styl
diff --git a/src/web/app/stats/tags/index.tag b/src/server/web/app/stats/tags/index.tag
similarity index 100%
rename from src/web/app/stats/tags/index.tag
rename to src/server/web/app/stats/tags/index.tag
diff --git a/src/web/app/stats/tags/index.ts b/src/server/web/app/stats/tags/index.ts
similarity index 100%
rename from src/web/app/stats/tags/index.ts
rename to src/server/web/app/stats/tags/index.ts
diff --git a/src/web/app/status/style.styl b/src/server/web/app/status/style.styl
similarity index 100%
rename from src/web/app/status/style.styl
rename to src/server/web/app/status/style.styl
diff --git a/src/web/app/status/tags/index.tag b/src/server/web/app/status/tags/index.tag
similarity index 100%
rename from src/web/app/status/tags/index.tag
rename to src/server/web/app/status/tags/index.tag
diff --git a/src/web/app/status/tags/index.ts b/src/server/web/app/status/tags/index.ts
similarity index 100%
rename from src/web/app/status/tags/index.ts
rename to src/server/web/app/status/tags/index.ts
diff --git a/src/web/app/sw.js b/src/server/web/app/sw.js
similarity index 100%
rename from src/web/app/sw.js
rename to src/server/web/app/sw.js
diff --git a/src/web/app/tsconfig.json b/src/server/web/app/tsconfig.json
similarity index 100%
rename from src/web/app/tsconfig.json
rename to src/server/web/app/tsconfig.json
diff --git a/src/web/app/v.d.ts b/src/server/web/app/v.d.ts
similarity index 100%
rename from src/web/app/v.d.ts
rename to src/server/web/app/v.d.ts
diff --git a/src/web/assets/404.js b/src/server/web/assets/404.js
similarity index 100%
rename from src/web/assets/404.js
rename to src/server/web/assets/404.js
diff --git a/src/web/assets/code-highlight.css b/src/server/web/assets/code-highlight.css
similarity index 100%
rename from src/web/assets/code-highlight.css
rename to src/server/web/assets/code-highlight.css
diff --git a/src/web/assets/error.jpg b/src/server/web/assets/error.jpg
similarity index 100%
rename from src/web/assets/error.jpg
rename to src/server/web/assets/error.jpg
diff --git a/src/web/assets/favicon.ico b/src/server/web/assets/favicon.ico
similarity index 100%
rename from src/web/assets/favicon.ico
rename to src/server/web/assets/favicon.ico
diff --git a/src/web/assets/label.svg b/src/server/web/assets/label.svg
similarity index 100%
rename from src/web/assets/label.svg
rename to src/server/web/assets/label.svg
diff --git a/src/web/assets/manifest.json b/src/server/web/assets/manifest.json
similarity index 100%
rename from src/web/assets/manifest.json
rename to src/server/web/assets/manifest.json
diff --git a/src/web/assets/message.mp3 b/src/server/web/assets/message.mp3
similarity index 100%
rename from src/web/assets/message.mp3
rename to src/server/web/assets/message.mp3
diff --git a/src/web/assets/othello-put-me.mp3 b/src/server/web/assets/othello-put-me.mp3
similarity index 100%
rename from src/web/assets/othello-put-me.mp3
rename to src/server/web/assets/othello-put-me.mp3
diff --git a/src/web/assets/othello-put-you.mp3 b/src/server/web/assets/othello-put-you.mp3
similarity index 100%
rename from src/web/assets/othello-put-you.mp3
rename to src/server/web/assets/othello-put-you.mp3
diff --git a/src/web/assets/post.mp3 b/src/server/web/assets/post.mp3
similarity index 100%
rename from src/web/assets/post.mp3
rename to src/server/web/assets/post.mp3
diff --git a/src/web/assets/reactions/angry.png b/src/server/web/assets/reactions/angry.png
similarity index 100%
rename from src/web/assets/reactions/angry.png
rename to src/server/web/assets/reactions/angry.png
diff --git a/src/web/assets/reactions/confused.png b/src/server/web/assets/reactions/confused.png
similarity index 100%
rename from src/web/assets/reactions/confused.png
rename to src/server/web/assets/reactions/confused.png
diff --git a/src/web/assets/reactions/congrats.png b/src/server/web/assets/reactions/congrats.png
similarity index 100%
rename from src/web/assets/reactions/congrats.png
rename to src/server/web/assets/reactions/congrats.png
diff --git a/src/web/assets/reactions/hmm.png b/src/server/web/assets/reactions/hmm.png
similarity index 100%
rename from src/web/assets/reactions/hmm.png
rename to src/server/web/assets/reactions/hmm.png
diff --git a/src/web/assets/reactions/laugh.png b/src/server/web/assets/reactions/laugh.png
similarity index 100%
rename from src/web/assets/reactions/laugh.png
rename to src/server/web/assets/reactions/laugh.png
diff --git a/src/web/assets/reactions/like.png b/src/server/web/assets/reactions/like.png
similarity index 100%
rename from src/web/assets/reactions/like.png
rename to src/server/web/assets/reactions/like.png
diff --git a/src/web/assets/reactions/love.png b/src/server/web/assets/reactions/love.png
similarity index 100%
rename from src/web/assets/reactions/love.png
rename to src/server/web/assets/reactions/love.png
diff --git a/src/web/assets/reactions/pudding.png b/src/server/web/assets/reactions/pudding.png
similarity index 100%
rename from src/web/assets/reactions/pudding.png
rename to src/server/web/assets/reactions/pudding.png
diff --git a/src/web/assets/reactions/surprise.png b/src/server/web/assets/reactions/surprise.png
similarity index 100%
rename from src/web/assets/reactions/surprise.png
rename to src/server/web/assets/reactions/surprise.png
diff --git a/src/web/assets/recover.html b/src/server/web/assets/recover.html
similarity index 100%
rename from src/web/assets/recover.html
rename to src/server/web/assets/recover.html
diff --git a/src/web/assets/title.svg b/src/server/web/assets/title.svg
similarity index 100%
rename from src/web/assets/title.svg
rename to src/server/web/assets/title.svg
diff --git a/src/web/assets/unread.svg b/src/server/web/assets/unread.svg
similarity index 100%
rename from src/web/assets/unread.svg
rename to src/server/web/assets/unread.svg
diff --git a/src/web/assets/welcome-bg.svg b/src/server/web/assets/welcome-bg.svg
similarity index 100%
rename from src/web/assets/welcome-bg.svg
rename to src/server/web/assets/welcome-bg.svg
diff --git a/src/web/assets/welcome-fg.svg b/src/server/web/assets/welcome-fg.svg
similarity index 100%
rename from src/web/assets/welcome-fg.svg
rename to src/server/web/assets/welcome-fg.svg
diff --git a/src/web/const.styl b/src/server/web/const.styl
similarity index 74%
rename from src/web/const.styl
rename to src/server/web/const.styl
index b6560701d..f16e07782 100644
--- a/src/web/const.styl
+++ b/src/server/web/const.styl
@@ -1,4 +1,4 @@
-json('../const.json')
+json('../../const.json')
 
 $theme-color = themeColor
 $theme-color-foreground = themeColorForeground
diff --git a/src/web/docs/about.en.pug b/src/server/web/docs/about.en.pug
similarity index 100%
rename from src/web/docs/about.en.pug
rename to src/server/web/docs/about.en.pug
diff --git a/src/web/docs/about.ja.pug b/src/server/web/docs/about.ja.pug
similarity index 100%
rename from src/web/docs/about.ja.pug
rename to src/server/web/docs/about.ja.pug
diff --git a/src/web/docs/api.ja.pug b/src/server/web/docs/api.ja.pug
similarity index 100%
rename from src/web/docs/api.ja.pug
rename to src/server/web/docs/api.ja.pug
diff --git a/src/web/docs/api/endpoints/posts/create.yaml b/src/server/web/docs/api/endpoints/posts/create.yaml
similarity index 100%
rename from src/web/docs/api/endpoints/posts/create.yaml
rename to src/server/web/docs/api/endpoints/posts/create.yaml
diff --git a/src/web/docs/api/endpoints/posts/timeline.yaml b/src/server/web/docs/api/endpoints/posts/timeline.yaml
similarity index 100%
rename from src/web/docs/api/endpoints/posts/timeline.yaml
rename to src/server/web/docs/api/endpoints/posts/timeline.yaml
diff --git a/src/web/docs/api/endpoints/style.styl b/src/server/web/docs/api/endpoints/style.styl
similarity index 100%
rename from src/web/docs/api/endpoints/style.styl
rename to src/server/web/docs/api/endpoints/style.styl
diff --git a/src/web/docs/api/endpoints/view.pug b/src/server/web/docs/api/endpoints/view.pug
similarity index 100%
rename from src/web/docs/api/endpoints/view.pug
rename to src/server/web/docs/api/endpoints/view.pug
diff --git a/src/web/docs/api/entities/drive-file.yaml b/src/server/web/docs/api/entities/drive-file.yaml
similarity index 100%
rename from src/web/docs/api/entities/drive-file.yaml
rename to src/server/web/docs/api/entities/drive-file.yaml
diff --git a/src/web/docs/api/entities/post.yaml b/src/server/web/docs/api/entities/post.yaml
similarity index 100%
rename from src/web/docs/api/entities/post.yaml
rename to src/server/web/docs/api/entities/post.yaml
diff --git a/src/web/docs/api/entities/style.styl b/src/server/web/docs/api/entities/style.styl
similarity index 100%
rename from src/web/docs/api/entities/style.styl
rename to src/server/web/docs/api/entities/style.styl
diff --git a/src/web/docs/api/entities/user.yaml b/src/server/web/docs/api/entities/user.yaml
similarity index 100%
rename from src/web/docs/api/entities/user.yaml
rename to src/server/web/docs/api/entities/user.yaml
diff --git a/src/web/docs/api/entities/view.pug b/src/server/web/docs/api/entities/view.pug
similarity index 100%
rename from src/web/docs/api/entities/view.pug
rename to src/server/web/docs/api/entities/view.pug
diff --git a/src/web/docs/api/gulpfile.ts b/src/server/web/docs/api/gulpfile.ts
similarity index 80%
rename from src/web/docs/api/gulpfile.ts
rename to src/server/web/docs/api/gulpfile.ts
index cd1bf1530..37935413d 100644
--- a/src/web/docs/api/gulpfile.ts
+++ b/src/server/web/docs/api/gulpfile.ts
@@ -10,10 +10,10 @@ import * as pug from 'pug';
 import * as yaml from 'js-yaml';
 import * as mkdirp from 'mkdirp';
 
-import locales from '../../../../locales';
-import I18nReplacer from '../../../common/build/i18n';
-import fa from '../../../common/build/fa';
-import config from './../../../conf';
+import locales from '../../../../../locales';
+import I18nReplacer from '../../../../build/i18n';
+import fa from '../../../../build/fa';
+import config from './../../../../conf';
 
 import generateVars from '../vars';
 
@@ -94,7 +94,7 @@ gulp.task('doc:api', [
 
 gulp.task('doc:api:endpoints', async () => {
 	const commonVars = await generateVars();
-	glob('./src/web/docs/api/endpoints/**/*.yaml', (globErr, files) => {
+	glob('./src/server/web/docs/api/endpoints/**/*.yaml', (globErr, files) => {
 		if (globErr) {
 			console.error(globErr);
 			return;
@@ -115,10 +115,10 @@ gulp.task('doc:api:endpoints', async () => {
 				resDefs: ep.res ? extractDefs(ep.res) : null,
 			};
 			langs.forEach(lang => {
-				pug.renderFile('./src/web/docs/api/endpoints/view.pug', Object.assign({}, vars, {
+				pug.renderFile('./src/server/web/docs/api/endpoints/view.pug', Object.assign({}, vars, {
 					lang,
 					title: ep.endpoint,
-					src: `https://github.com/syuilo/misskey/tree/master/src/web/docs/api/endpoints/${ep.endpoint}.yaml`,
+					src: `https://github.com/syuilo/misskey/tree/master/src/server/web/docs/api/endpoints/${ep.endpoint}.yaml`,
 					kebab,
 					common: commonVars
 				}), (renderErr, html) => {
@@ -129,7 +129,7 @@ gulp.task('doc:api:endpoints', async () => {
 					const i18n = new I18nReplacer(lang);
 					html = html.replace(i18n.pattern, i18n.replacement);
 					html = fa(html);
-					const htmlPath = `./built/web/docs/${lang}/api/endpoints/${ep.endpoint}.html`;
+					const htmlPath = `./built/server/web/docs/${lang}/api/endpoints/${ep.endpoint}.html`;
 					mkdirp(path.dirname(htmlPath), (mkdirErr) => {
 						if (mkdirErr) {
 							console.error(mkdirErr);
@@ -145,7 +145,7 @@ gulp.task('doc:api:endpoints', async () => {
 
 gulp.task('doc:api:entities', async () => {
 	const commonVars = await generateVars();
-	glob('./src/web/docs/api/entities/**/*.yaml', (globErr, files) => {
+	glob('./src/server/web/docs/api/entities/**/*.yaml', (globErr, files) => {
 		if (globErr) {
 			console.error(globErr);
 			return;
@@ -159,10 +159,10 @@ gulp.task('doc:api:entities', async () => {
 				propDefs: extractDefs(entity.props),
 			};
 			langs.forEach(lang => {
-				pug.renderFile('./src/web/docs/api/entities/view.pug', Object.assign({}, vars, {
+				pug.renderFile('./src/server/web/docs/api/entities/view.pug', Object.assign({}, vars, {
 					lang,
 					title: entity.name,
-					src: `https://github.com/syuilo/misskey/tree/master/src/web/docs/api/entities/${kebab(entity.name)}.yaml`,
+					src: `https://github.com/syuilo/misskey/tree/master/src/server/web/docs/api/entities/${kebab(entity.name)}.yaml`,
 					kebab,
 					common: commonVars
 				}), (renderErr, html) => {
@@ -173,7 +173,7 @@ gulp.task('doc:api:entities', async () => {
 					const i18n = new I18nReplacer(lang);
 					html = html.replace(i18n.pattern, i18n.replacement);
 					html = fa(html);
-					const htmlPath = `./built/web/docs/${lang}/api/entities/${kebab(entity.name)}.html`;
+					const htmlPath = `./built/server/web/docs/${lang}/api/entities/${kebab(entity.name)}.html`;
 					mkdirp(path.dirname(htmlPath), (mkdirErr) => {
 						if (mkdirErr) {
 							console.error(mkdirErr);
diff --git a/src/web/docs/api/mixins.pug b/src/server/web/docs/api/mixins.pug
similarity index 100%
rename from src/web/docs/api/mixins.pug
rename to src/server/web/docs/api/mixins.pug
diff --git a/src/web/docs/api/style.styl b/src/server/web/docs/api/style.styl
similarity index 100%
rename from src/web/docs/api/style.styl
rename to src/server/web/docs/api/style.styl
diff --git a/src/web/docs/gulpfile.ts b/src/server/web/docs/gulpfile.ts
similarity index 74%
rename from src/web/docs/gulpfile.ts
rename to src/server/web/docs/gulpfile.ts
index d5ddda108..7b36cf667 100644
--- a/src/web/docs/gulpfile.ts
+++ b/src/server/web/docs/gulpfile.ts
@@ -11,8 +11,8 @@ import * as mkdirp from 'mkdirp';
 import stylus = require('gulp-stylus');
 import cssnano = require('gulp-cssnano');
 
-import I18nReplacer from '../../common/build/i18n';
-import fa from '../../common/build/fa';
+import I18nReplacer from '../../../build/i18n';
+import fa from '../../../build/fa';
 import generateVars from './vars';
 
 require('./api/gulpfile.ts');
@@ -26,7 +26,7 @@ gulp.task('doc', [
 gulp.task('doc:docs', async () => {
 	const commonVars = await generateVars();
 
-	glob('./src/web/docs/**/*.*.pug', (globErr, files) => {
+	glob('./src/server/web/docs/**/*.*.pug', (globErr, files) => {
 		if (globErr) {
 			console.error(globErr);
 			return;
@@ -37,7 +37,7 @@ gulp.task('doc:docs', async () => {
 				common: commonVars,
 				lang: lang,
 				title: fs.readFileSync(file, 'utf-8').match(/^h1 (.+?)\r?\n/)[1],
-				src: `https://github.com/syuilo/misskey/tree/master/src/web/docs/${name}.${lang}.pug`,
+				src: `https://github.com/syuilo/misskey/tree/master/src/server/web/docs/${name}.${lang}.pug`,
 			};
 			pug.renderFile(file, vars, (renderErr, content) => {
 				if (renderErr) {
@@ -45,7 +45,7 @@ gulp.task('doc:docs', async () => {
 					return;
 				}
 
-				pug.renderFile('./src/web/docs/layout.pug', Object.assign({}, vars, {
+				pug.renderFile('./src/server/web/docs/layout.pug', Object.assign({}, vars, {
 					content
 				}), (renderErr2, html) => {
 					if (renderErr2) {
@@ -55,7 +55,7 @@ gulp.task('doc:docs', async () => {
 					const i18n = new I18nReplacer(lang);
 					html = html.replace(i18n.pattern, i18n.replacement);
 					html = fa(html);
-					const htmlPath = `./built/web/docs/${lang}/${name}.html`;
+					const htmlPath = `./built/server/web/docs/${lang}/${name}.html`;
 					mkdirp(path.dirname(htmlPath), (mkdirErr) => {
 						if (mkdirErr) {
 							console.error(mkdirErr);
@@ -70,8 +70,8 @@ gulp.task('doc:docs', async () => {
 });
 
 gulp.task('doc:styles', () =>
-	gulp.src('./src/web/docs/**/*.styl')
+	gulp.src('./src/server/web/docs/**/*.styl')
 		.pipe(stylus())
 		.pipe((cssnano as any)())
-		.pipe(gulp.dest('./built/web/docs/assets/'))
+		.pipe(gulp.dest('./built/server/web/docs/assets/'))
 );
diff --git a/src/web/docs/index.en.pug b/src/server/web/docs/index.en.pug
similarity index 100%
rename from src/web/docs/index.en.pug
rename to src/server/web/docs/index.en.pug
diff --git a/src/web/docs/index.ja.pug b/src/server/web/docs/index.ja.pug
similarity index 100%
rename from src/web/docs/index.ja.pug
rename to src/server/web/docs/index.ja.pug
diff --git a/src/web/docs/layout.pug b/src/server/web/docs/layout.pug
similarity index 100%
rename from src/web/docs/layout.pug
rename to src/server/web/docs/layout.pug
diff --git a/src/web/docs/license.en.pug b/src/server/web/docs/license.en.pug
similarity index 100%
rename from src/web/docs/license.en.pug
rename to src/server/web/docs/license.en.pug
diff --git a/src/web/docs/license.ja.pug b/src/server/web/docs/license.ja.pug
similarity index 100%
rename from src/web/docs/license.ja.pug
rename to src/server/web/docs/license.ja.pug
diff --git a/src/web/docs/mute.ja.pug b/src/server/web/docs/mute.ja.pug
similarity index 100%
rename from src/web/docs/mute.ja.pug
rename to src/server/web/docs/mute.ja.pug
diff --git a/src/web/docs/search.ja.pug b/src/server/web/docs/search.ja.pug
similarity index 100%
rename from src/web/docs/search.ja.pug
rename to src/server/web/docs/search.ja.pug
diff --git a/src/web/docs/server.ts b/src/server/web/docs/server.ts
similarity index 100%
rename from src/web/docs/server.ts
rename to src/server/web/docs/server.ts
diff --git a/src/web/docs/style.styl b/src/server/web/docs/style.styl
similarity index 100%
rename from src/web/docs/style.styl
rename to src/server/web/docs/style.styl
diff --git a/src/web/docs/tou.ja.pug b/src/server/web/docs/tou.ja.pug
similarity index 100%
rename from src/web/docs/tou.ja.pug
rename to src/server/web/docs/tou.ja.pug
diff --git a/src/web/docs/ui.styl b/src/server/web/docs/ui.styl
similarity index 100%
rename from src/web/docs/ui.styl
rename to src/server/web/docs/ui.styl
diff --git a/src/web/docs/vars.ts b/src/server/web/docs/vars.ts
similarity index 76%
rename from src/web/docs/vars.ts
rename to src/server/web/docs/vars.ts
index 6f713f21d..5096a39c9 100644
--- a/src/web/docs/vars.ts
+++ b/src/server/web/docs/vars.ts
@@ -5,27 +5,27 @@ import * as yaml from 'js-yaml';
 import * as licenseChecker from 'license-checker';
 import * as tmp from 'tmp';
 
-import { fa } from '../../common/build/fa';
-import config from '../../conf';
-import { licenseHtml } from '../../common/build/license';
-const constants = require('../../const.json');
+import { fa } from '../../../build/fa';
+import config from '../../../conf';
+import { licenseHtml } from '../../../build/license';
+const constants = require('../../../const.json');
 
 export default async function(): Promise<{ [key: string]: any }> {
 	const vars = {} as { [key: string]: any };
 
-	const endpoints = glob.sync('./src/web/docs/api/endpoints/**/*.yaml');
+	const endpoints = glob.sync('./src/server/web/docs/api/endpoints/**/*.yaml');
 	vars['endpoints'] = endpoints.map(ep => {
 		const _ep = yaml.safeLoad(fs.readFileSync(ep, 'utf-8'));
 		return _ep.endpoint;
 	});
 
-	const entities = glob.sync('./src/web/docs/api/entities/**/*.yaml');
+	const entities = glob.sync('./src/server/web/docs/api/entities/**/*.yaml');
 	vars['entities'] = entities.map(x => {
 		const _x = yaml.safeLoad(fs.readFileSync(x, 'utf-8'));
 		return _x.name;
 	});
 
-	const docs = glob.sync('./src/web/docs/**/*.*.pug');
+	const docs = glob.sync('./src/server/web/docs/**/*.*.pug');
 	vars['docs'] = {};
 	docs.forEach(x => {
 		const [, name, lang] = x.match(/docs\/(.+?)\.(.+?)\.pug$/);
@@ -53,7 +53,7 @@ export default async function(): Promise<{ [key: string]: any }> {
 		licenseText: ''
 	}), 'utf-8');
 	const dependencies = await util.promisify(licenseChecker.init).bind(licenseChecker)({
-		start: __dirname + '/../../../',
+		start: __dirname + '/../../../../',
 		customPath: tmpObj.name
 	});
 	tmpObj.removeCallback();
diff --git a/src/web/element.scss b/src/server/web/element.scss
similarity index 91%
rename from src/web/element.scss
rename to src/server/web/element.scss
index 917198e02..7e6d0e709 100644
--- a/src/web/element.scss
+++ b/src/server/web/element.scss
@@ -1,7 +1,7 @@
 /* Element variable definitons */
 /* SEE: http://element.eleme.io/#/en-US/component/custom-theme */
 
-@import '../const.json';
+@import '../../const.json';
 
 /* theme color */
 $--color-primary: $themeColor;
diff --git a/src/web/server.ts b/src/server/web/server.ts
similarity index 100%
rename from src/web/server.ts
rename to src/server/web/server.ts
diff --git a/src/web/service/url-preview.ts b/src/server/web/service/url-preview.ts
similarity index 100%
rename from src/web/service/url-preview.ts
rename to src/server/web/service/url-preview.ts
diff --git a/src/web/style.styl b/src/server/web/style.styl
similarity index 100%
rename from src/web/style.styl
rename to src/server/web/style.styl
diff --git a/src/tools/analysis/core.ts b/src/tools/analysis/core.ts
index 20e5fa6c5..839fffd3c 100644
--- a/src/tools/analysis/core.ts
+++ b/src/tools/analysis/core.ts
@@ -1,7 +1,7 @@
 const bayes = require('./naive-bayes.js');
 
 const MeCab = require('./mecab');
-import Post from '../../api/models/post';
+import Post from '../../server/api/models/post';
 
 /**
  * 投稿を学習したり与えられた投稿のカテゴリを予測します
diff --git a/src/tools/analysis/extract-user-domains.ts b/src/tools/analysis/extract-user-domains.ts
index bc120f5c1..ba472b89a 100644
--- a/src/tools/analysis/extract-user-domains.ts
+++ b/src/tools/analysis/extract-user-domains.ts
@@ -1,8 +1,8 @@
 import * as URL from 'url';
 
-import Post from '../../api/models/post';
-import User from '../../api/models/user';
-import parse from '../../api/common/text';
+import Post from '../../server/api/models/post';
+import User from '../../server/api/models/user';
+import parse from '../../server/api/common/text';
 
 process.on('unhandledRejection', console.dir);
 
diff --git a/src/tools/analysis/extract-user-keywords.ts b/src/tools/analysis/extract-user-keywords.ts
index b99ca9321..4fa9b384e 100644
--- a/src/tools/analysis/extract-user-keywords.ts
+++ b/src/tools/analysis/extract-user-keywords.ts
@@ -1,9 +1,9 @@
 const moji = require('moji');
 
 const MeCab = require('./mecab');
-import Post from '../../api/models/post';
-import User from '../../api/models/user';
-import parse from '../../api/common/text';
+import Post from '../../server/api/models/post';
+import User from '../../server/api/models/user';
+import parse from '../../server/api/common/text';
 
 process.on('unhandledRejection', console.dir);
 
diff --git a/src/tools/analysis/predict-all-post-category.ts b/src/tools/analysis/predict-all-post-category.ts
index 058c4f99e..8564fd1b1 100644
--- a/src/tools/analysis/predict-all-post-category.ts
+++ b/src/tools/analysis/predict-all-post-category.ts
@@ -1,4 +1,4 @@
-import Post from '../../api/models/post';
+import Post from '../../server/api/models/post';
 import Core from './core';
 
 const c = new Core();
diff --git a/src/tools/analysis/predict-user-interst.ts b/src/tools/analysis/predict-user-interst.ts
index 99bdfa420..6599fb220 100644
--- a/src/tools/analysis/predict-user-interst.ts
+++ b/src/tools/analysis/predict-user-interst.ts
@@ -1,5 +1,5 @@
-import Post from '../../api/models/post';
-import User from '../../api/models/user';
+import Post from '../../server/api/models/post';
+import User from '../../server/api/models/user';
 
 export async function predictOne(id) {
 	console.log(`predict interest of ${id} ...`);
diff --git a/test/api.js b/test/api.js
index b8b2aecc9..c2c08dd95 100644
--- a/test/api.js
+++ b/test/api.js
@@ -17,7 +17,7 @@ const should = _chai.should();
 
 _chai.use(chaiHttp);
 
-const server = require('../built/api/server');
+const server = require('../built/server/api/server');
 const db = require('../built/db/mongodb').default;
 
 const async = fn => (done) => {
diff --git a/test/text.js b/test/text.js
index 3b27aa23d..4f739cc1b 100644
--- a/test/text.js
+++ b/test/text.js
@@ -4,8 +4,8 @@
 
 const assert = require('assert');
 
-const analyze = require('../built/api/common/text').default;
-const syntaxhighlighter = require('../built/api/common/text/core/syntax-highlighter').default;
+const analyze = require('../built/server/api/common/text').default;
+const syntaxhighlighter = require('../built/server/api/common/text/core/syntax-highlighter').default;
 
 describe('Text', () => {
 	it('can be analyzed', () => {
diff --git a/tsconfig.json b/tsconfig.json
index 47aa521bf..574c11bac 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -21,6 +21,6 @@
     "./src/**/*.ts"
   ],
   "exclude": [
-    "./src/web/app/**/*.ts"
+    "./src/server/web/app/**/*.ts"
   ]
 }
diff --git a/webpack.config.ts b/webpack.config.ts
index 9a952c8ef..6f16fcbfa 100644
--- a/webpack.config.ts
+++ b/webpack.config.ts
@@ -11,11 +11,11 @@ const WebpackOnBuildPlugin = require('on-build-webpack');
 //const HardSourceWebpackPlugin = require('hard-source-webpack-plugin');
 const ProgressBarPlugin = require('progress-bar-webpack-plugin');
 
-import I18nReplacer from './src/common/build/i18n';
-import { pattern as faPattern, replacement as faReplacement } from './src/common/build/fa';
+import I18nReplacer from './src/build/i18n';
+import { pattern as faPattern, replacement as faReplacement } from './src/build/fa';
 const constants = require('./src/const.json');
 import config from './src/conf';
-import { licenseHtml } from './src/common/build/license';
+import { licenseHtml } from './src/build/license';
 
 import locales from './locales';
 const meta = require('./package.json');
@@ -33,7 +33,7 @@ global['collapseSpacesReplacement'] = html => {
 };
 
 global['base64replacement'] = (_, key) => {
-	return fs.readFileSync(__dirname + '/src/web/' + key, 'base64');
+	return fs.readFileSync(__dirname + '/src/server/web/' + key, 'base64');
 };
 //#endregion
 
@@ -51,18 +51,18 @@ module.exports = entries.map(x => {
 
 	// Entries
 	const entry = {
-		desktop: './src/web/app/desktop/script.ts',
-		mobile: './src/web/app/mobile/script.ts',
-		//ch: './src/web/app/ch/script.ts',
-		//stats: './src/web/app/stats/script.ts',
-		//status: './src/web/app/status/script.ts',
-		dev: './src/web/app/dev/script.ts',
-		auth: './src/web/app/auth/script.ts',
-		sw: './src/web/app/sw.js'
+		desktop: './src/server/web/app/desktop/script.ts',
+		mobile: './src/server/web/app/mobile/script.ts',
+		//ch: './src/server/web/app/ch/script.ts',
+		//stats: './src/server/web/app/stats/script.ts',
+		//status: './src/server/web/app/status/script.ts',
+		dev: './src/server/web/app/dev/script.ts',
+		auth: './src/server/web/app/auth/script.ts',
+		sw: './src/server/web/app/sw.js'
 	};
 
 	const output = {
-		path: __dirname + '/built/web/assets',
+		path: __dirname + '/built/server/web/assets',
 		filename: `[name].${version}.${lang}.${isProduction ? 'min' : 'raw'}.js`
 	};
 
@@ -206,7 +206,7 @@ module.exports = entries.map(x => {
 					loader: 'ts-loader',
 					options: {
 						happyPackMode: true,
-						configFile: __dirname + '/../src/web/app/tsconfig.json',
+						configFile: __dirname + '/../src/server/web/app/tsconfig.json',
 						appendTsSuffixTo: [/\.vue$/]
 					}
 				}, {
@@ -231,7 +231,7 @@ module.exports = entries.map(x => {
 				'.js', '.ts', '.json'
 			],
 			alias: {
-				'const.styl': __dirname + '/src/web/const.styl'
+				'const.styl': __dirname + '/src/server/web/const.styl'
 			}
 		},
 		resolveLoader: {

From bfc193d8cd9aecdb82d585e8b4e101deac60a5bb Mon Sep 17 00:00:00 2001
From: syuilo <syuilotan@yahoo.co.jp>
Date: Thu, 29 Mar 2018 14:48:47 +0900
Subject: [PATCH 2/2] Resolve conflicts

---
 docs/config.md => .config/example.yml         |   3 -
 .gitignore                                    |   3 +-
 CHANGELOG.md                                  | 532 --------------
 LICENSE                                       | 674 +++++++++++++++++-
 LICENSE_AGPL-3.0                              | 661 -----------------
 README.md                                     |  55 +-
 docker/Dockerfile                             |   2 +-
 docs/setup.en.md                              |   6 +-
 docs/setup.ja.md                              |   6 +-
 gulpfile.ts                                   |   1 -
 locales/ja.yml                                |   2 +-
 src/index.ts                                  |   1 -
 src/server/api/authenticate.ts                |   4 +-
 src/server/api/bot/core.ts                    |   8 +-
 src/server/api/bot/interfaces/line.ts         |  12 +-
 src/server/api/common/drive/add-file.ts       |  16 +-
 src/server/api/common/get-friends.ts          |   8 +-
 src/server/api/common/notify.ts               |  18 +-
 src/server/api/common/push-sw.ts              |   4 +-
 .../api/common/read-messaging-message.ts      |  12 +-
 src/server/api/common/read-notification.ts    |   8 +-
 src/server/api/common/watch-post.ts           |  14 +-
 src/server/api/endpoints.ts                   |   2 +-
 src/server/api/endpoints/aggregation/posts.ts |  16 +-
 .../endpoints/aggregation/posts/reaction.ts   |  16 +-
 .../endpoints/aggregation/posts/reactions.ts  |  16 +-
 .../api/endpoints/aggregation/posts/reply.ts  |  14 +-
 .../api/endpoints/aggregation/posts/repost.ts |  16 +-
 src/server/api/endpoints/aggregation/users.ts |   8 +-
 .../endpoints/aggregation/users/activity.ts   |  24 +-
 .../endpoints/aggregation/users/followers.ts  |  20 +-
 .../endpoints/aggregation/users/following.ts  |  20 +-
 .../api/endpoints/aggregation/users/post.ts   |  24 +-
 .../endpoints/aggregation/users/reaction.ts   |  16 +-
 src/server/api/endpoints/app/create.ts        |  26 +-
 .../api/endpoints/app/name_id/available.ts    |  18 +-
 src/server/api/endpoints/app/show.ts          |  24 +-
 src/server/api/endpoints/auth/accept.ts       |  14 +-
 .../api/endpoints/auth/session/generate.ts    |  12 +-
 src/server/api/endpoints/auth/session/show.ts |   6 +-
 .../api/endpoints/auth/session/userkey.ts     |  20 +-
 src/server/api/endpoints/channels.ts          |  16 +-
 src/server/api/endpoints/channels/create.ts   |  12 +-
 src/server/api/endpoints/channels/posts.ts    |  24 +-
 src/server/api/endpoints/channels/show.ts     |   6 +-
 src/server/api/endpoints/channels/unwatch.ts  |  16 +-
 src/server/api/endpoints/channels/watch.ts    |  20 +-
 src/server/api/endpoints/drive.ts             |   4 +-
 src/server/api/endpoints/drive/files.ts       |  26 +-
 .../api/endpoints/drive/files/create.ts       |   6 +-
 src/server/api/endpoints/drive/files/find.ts  |  10 +-
 src/server/api/endpoints/drive/files/show.ts  |   8 +-
 .../api/endpoints/drive/files/update.ts       |  22 +-
 .../endpoints/drive/files/upload_from_url.ts  |   6 +-
 src/server/api/endpoints/drive/folders.ts     |  26 +-
 .../api/endpoints/drive/folders/create.ts     |  14 +-
 .../api/endpoints/drive/folders/find.ts       |  10 +-
 .../api/endpoints/drive/folders/show.ts       |   8 +-
 .../api/endpoints/drive/folders/update.ts     |  32 +-
 src/server/api/endpoints/drive/stream.ts      |  18 +-
 src/server/api/endpoints/following/create.ts  |  22 +-
 src/server/api/endpoints/following/delete.ts  |  18 +-
 src/server/api/endpoints/i.ts                 |   2 +-
 src/server/api/endpoints/i/2fa/done.ts        |   8 +-
 src/server/api/endpoints/i/2fa/register.ts    |   2 +-
 src/server/api/endpoints/i/2fa/unregister.ts  |   4 +-
 src/server/api/endpoints/i/appdata/get.ts     |   4 +-
 src/server/api/endpoints/i/appdata/set.ts     |   8 +-
 src/server/api/endpoints/i/authorized_apps.ts |   4 +-
 src/server/api/endpoints/i/change_password.ts |  12 +-
 src/server/api/endpoints/i/favorites.ts       |   4 +-
 src/server/api/endpoints/i/notifications.ts   |  34 +-
 src/server/api/endpoints/i/pin.ts             |  10 +-
 src/server/api/endpoints/i/signin_history.ts  |  18 +-
 src/server/api/endpoints/i/update.ts          |  38 +-
 .../api/endpoints/i/update_client_setting.ts  |   4 +-
 src/server/api/endpoints/i/update_home.ts     |   6 +-
 .../api/endpoints/i/update_mobile_home.ts     |   6 +-
 src/server/api/endpoints/messaging/history.ts |  14 +-
 .../api/endpoints/messaging/messages.ts       |  36 +-
 .../endpoints/messaging/messages/create.ts    |  74 +-
 src/server/api/endpoints/messaging/unread.ts  |  12 +-
 src/server/api/endpoints/meta.ts              |   1 -
 src/server/api/endpoints/mute/create.ts       |  18 +-
 src/server/api/endpoints/mute/delete.ts       |  14 +-
 src/server/api/endpoints/mute/list.ts         |   8 +-
 src/server/api/endpoints/my/apps.ts           |   2 +-
 .../notifications/get_unread_count.ts         |  12 +-
 .../notifications/mark_as_read_all.ts         |   6 +-
 src/server/api/endpoints/othello/games.ts     |  28 +-
 .../api/endpoints/othello/games/show.ts       |  16 +-
 .../api/endpoints/othello/invitations.ts      |   2 +-
 src/server/api/endpoints/othello/match.ts     |  44 +-
 .../api/endpoints/othello/match/cancel.ts     |   2 +-
 src/server/api/endpoints/posts.ts             |  24 +-
 src/server/api/endpoints/posts/categorize.ts  |   8 +-
 src/server/api/endpoints/posts/context.ts     |  14 +-
 src/server/api/endpoints/posts/create.ts      | 166 ++---
 .../api/endpoints/posts/favorites/create.ts   |  16 +-
 .../api/endpoints/posts/favorites/delete.ts   |  12 +-
 src/server/api/endpoints/posts/mentions.ts    |  18 +-
 .../endpoints/posts/polls/recommendation.ts   |   8 +-
 src/server/api/endpoints/posts/polls/vote.ts  |  34 +-
 src/server/api/endpoints/posts/reactions.ts   |  10 +-
 .../api/endpoints/posts/reactions/create.ts   |  46 +-
 .../api/endpoints/posts/reactions/delete.ts   |  16 +-
 src/server/api/endpoints/posts/replies.ts     |   8 +-
 src/server/api/endpoints/posts/reposts.ts     |  24 +-
 src/server/api/endpoints/posts/search.ts      |  98 +--
 src/server/api/endpoints/posts/show.ts        |   6 +-
 src/server/api/endpoints/posts/timeline.ts    |  58 +-
 src/server/api/endpoints/posts/trend.ts       |  12 +-
 src/server/api/endpoints/stats.ts             |   8 +-
 src/server/api/endpoints/sw/register.ts       |   6 +-
 .../api/endpoints/username/available.ts       |   2 +-
 src/server/api/endpoints/users.ts             |   4 +-
 src/server/api/endpoints/users/followers.ts   |  14 +-
 src/server/api/endpoints/users/following.ts   |  14 +-
 .../users/get_frequently_replied_users.ts     |  20 +-
 src/server/api/endpoints/users/posts.ts       |  62 +-
 .../api/endpoints/users/recommendation.ts     |   4 +-
 src/server/api/endpoints/users/search.ts      |   2 +-
 .../api/endpoints/users/search_by_username.ts |   2 +-
 src/server/api/endpoints/users/show.ts        |  56 +-
 src/server/api/models/access-token.ts         |  18 +-
 src/server/api/models/app.ts                  |  24 +-
 src/server/api/models/appdata.ts              |   3 -
 src/server/api/models/auth-session.ts         |   9 +-
 src/server/api/models/channel-watching.ts     |  12 +-
 src/server/api/models/channel.ts              |  15 +-
 src/server/api/models/drive-file.ts           |  14 +-
 src/server/api/models/drive-folder.ts         |  18 +-
 src/server/api/models/drive-tag.ts            |   3 -
 src/server/api/models/favorite.ts             |  11 +-
 src/server/api/models/following.ts            |  12 +-
 src/server/api/models/messaging-history.ts    |  12 +-
 src/server/api/models/messaging-message.ts    |  19 +-
 src/server/api/models/meta.ts                 |   5 +-
 src/server/api/models/mute.ts                 |  12 +-
 src/server/api/models/notification.ts         |  22 +-
 src/server/api/models/othello-game.ts         |  42 +-
 src/server/api/models/othello-matching.ts     |  12 +-
 src/server/api/models/poll-vote.ts            |  16 +-
 src/server/api/models/post-reaction.ts        |  10 +-
 src/server/api/models/post-watching.ts        |  11 +-
 src/server/api/models/post.ts                 |  62 +-
 src/server/api/models/signin.ts               |   5 +
 src/server/api/models/sw-subscription.ts      |  12 +-
 src/server/api/models/user.ts                 | 133 ++--
 src/server/api/private/signin.ts              |  10 +-
 src/server/api/private/signup.ts              |  26 +-
 src/server/api/service/github.ts              |   2 +-
 src/server/api/service/twitter.ts             |  10 +-
 src/server/api/stream/home.ts                 |  16 +-
 src/server/api/stream/othello-game.ts         | 128 ++--
 src/server/api/stream/othello.ts              |   6 +-
 src/server/api/streaming.ts                   |   2 +-
 src/server/common/get-post-summary.ts         |   4 +-
 src/server/common/othello/ai/back.ts          |  30 +-
 src/server/common/othello/ai/front.ts         |  16 +-
 src/server/common/user/get-summary.ts         |   2 +-
 src/server/web/app/auth/views/form.vue        |   2 +-
 src/server/web/app/auth/views/index.vue       |  12 +-
 src/server/web/app/ch/tags/channel.tag        |  28 +-
 src/server/web/app/common/define-widget.ts    |   4 +-
 src/server/web/app/common/mios.ts             |   4 +-
 .../common/scripts/compose-notification.ts    |  12 +-
 .../app/common/scripts/parse-search-query.ts  |   4 +-
 .../web/app/common/scripts/streaming/home.ts  |   2 +-
 .../common/views/components/autocomplete.vue  |   2 +-
 .../views/components/messaging-room.form.vue  |   6 +-
 .../components/messaging-room.message.vue     |  12 +-
 .../views/components/messaging-room.vue       |  16 +-
 .../app/common/views/components/messaging.vue |  16 +-
 .../common/views/components/othello.game.vue  |  58 +-
 .../views/components/othello.gameroom.vue     |   2 +-
 .../common/views/components/othello.room.vue  |  26 +-
 .../app/common/views/components/othello.vue   |  22 +-
 .../web/app/common/views/components/poll.vue  |  10 +-
 .../app/common/views/components/post-menu.vue |   4 +-
 .../views/components/reaction-picker.vue      |   2 +-
 .../views/components/reactions-viewer.vue     |   2 +-
 .../app/common/views/components/signin.vue    |   6 +-
 .../app/common/views/components/signup.vue    |   2 +-
 .../views/components/twitter-setting.vue      |   4 +-
 .../app/common/views/components/uploader.vue  |   2 +-
 .../views/components/welcome-timeline.vue     |   4 +-
 .../common/views/directives/autocomplete.ts   |   2 +-
 .../app/common/views/widgets/slideshow.vue    |   2 +-
 .../web/app/common/views/widgets/version.vue  |   7 +-
 src/server/web/app/config.ts                  |   4 +-
 .../web/app/desktop/api/update-avatar.ts      |   8 +-
 .../web/app/desktop/api/update-banner.ts      |   8 +-
 .../app/desktop/views/components/activity.vue |   2 +-
 .../desktop/views/components/drive.file.vue   |  14 +-
 .../desktop/views/components/drive.folder.vue |  10 +-
 .../views/components/drive.nav-folder.vue     |   8 +-
 .../app/desktop/views/components/drive.vue    |  28 +-
 .../views/components/follow-button.vue        |  22 +-
 .../views/components/followers-window.vue     |   2 +-
 .../desktop/views/components/followers.vue    |   6 +-
 .../views/components/following-window.vue     |   2 +-
 .../desktop/views/components/following.vue    |   6 +-
 .../views/components/friends-maker.vue        |   2 +-
 .../web/app/desktop/views/components/home.vue |  20 +-
 .../desktop/views/components/media-image.vue  |   2 +-
 .../app/desktop/views/components/mentions.vue |   2 +-
 .../views/components/notifications.vue        |  38 +-
 .../views/components/post-detail.sub.vue      |   8 +-
 .../desktop/views/components/post-detail.vue  |  32 +-
 .../desktop/views/components/post-form.vue    |   8 +-
 .../desktop/views/components/post-preview.vue |   8 +-
 .../views/components/posts.post.sub.vue       |   8 +-
 .../desktop/views/components/posts.post.vue   |  36 +-
 .../app/desktop/views/components/posts.vue    |   4 +-
 .../desktop/views/components/repost-form.vue  |   2 +-
 .../desktop/views/components/settings.2fa.vue |   8 +-
 .../views/components/settings.password.vue    |   4 +-
 .../views/components/settings.profile.vue     |   6 +-
 .../views/components/settings.signins.vue     |   2 +-
 .../app/desktop/views/components/settings.vue |  14 +-
 .../views/components/sub-post-content.vue     |   4 +-
 .../app/desktop/views/components/timeline.vue |   8 +-
 .../views/components/ui.header.account.vue    |   2 +-
 .../desktop/views/components/ui.header.vue    |   4 +-
 .../desktop/views/components/user-preview.vue |  12 +-
 .../views/components/users-list.item.vue      |   4 +-
 .../views/components/widget-container.vue     |   4 +-
 .../app/desktop/views/components/window.vue   |   4 +-
 .../web/app/desktop/views/pages/home.vue      |   2 +-
 .../web/app/desktop/views/pages/othello.vue   |   2 +-
 .../web/app/desktop/views/pages/post.vue      |   2 +-
 .../pages/user/user.followers-you-know.vue    |   4 +-
 .../desktop/views/pages/user/user.friends.vue |   4 +-
 .../desktop/views/pages/user/user.header.vue  |  10 +-
 .../desktop/views/pages/user/user.home.vue    |   6 +-
 .../desktop/views/pages/user/user.photos.vue  |   4 +-
 .../desktop/views/pages/user/user.profile.vue |  22 +-
 .../views/pages/user/user.timeline.vue        |   8 +-
 .../web/app/desktop/views/pages/welcome.vue   |   2 +-
 .../views/widgets/channel.channel.form.vue    |   4 +-
 .../desktop/views/widgets/channel.channel.vue |   2 +-
 .../web/app/desktop/views/widgets/channel.vue |   2 +-
 .../web/app/desktop/views/widgets/profile.vue |   4 +-
 .../web/app/desktop/views/widgets/users.vue   |   2 +-
 src/server/web/app/dev/views/app.vue          |   2 +-
 src/server/web/app/dev/views/new-app.vue      |  12 +-
 src/server/web/app/init.ts                    |   4 +-
 src/server/web/app/mobile/api/post.ts         |   2 +-
 .../app/mobile/views/components/activity.vue  |   2 +-
 .../views/components/drive.file-detail.vue    |  14 +-
 .../mobile/views/components/drive.file.vue    |   4 +-
 .../web/app/mobile/views/components/drive.vue |  38 +-
 .../mobile/views/components/follow-button.vue |  22 +-
 .../mobile/views/components/media-image.vue   |   2 +-
 .../views/components/notification-preview.vue |  14 +-
 .../mobile/views/components/notification.vue  |  16 +-
 .../mobile/views/components/notifications.vue |   6 +-
 .../app/mobile/views/components/post-card.vue |   2 +-
 .../views/components/post-detail.sub.vue      |   4 +-
 .../mobile/views/components/post-detail.vue   |  28 +-
 .../app/mobile/views/components/post-form.vue |   8 +-
 .../mobile/views/components/post-preview.vue  |   4 +-
 .../app/mobile/views/components/post.sub.vue  |   4 +-
 .../web/app/mobile/views/components/post.vue  |  30 +-
 .../web/app/mobile/views/components/posts.vue |   4 +-
 .../views/components/sub-post-content.vue     |   4 +-
 .../app/mobile/views/components/timeline.vue  |   6 +-
 .../app/mobile/views/components/ui.header.vue |   4 +-
 .../app/mobile/views/components/ui.nav.vue    |   2 +-
 .../app/mobile/views/components/user-card.vue |   4 +-
 .../mobile/views/components/user-preview.vue  |   2 +-
 .../mobile/views/components/user-timeline.vue |  10 +-
 .../web/app/mobile/views/pages/followers.vue  |   8 +-
 .../web/app/mobile/views/pages/following.vue  |   8 +-
 .../web/app/mobile/views/pages/home.vue       |  22 +-
 .../app/mobile/views/pages/notifications.vue  |   2 +-
 .../web/app/mobile/views/pages/othello.vue    |   2 +-
 .../web/app/mobile/views/pages/post.vue       |   2 +-
 .../mobile/views/pages/profile-setting.vue    |   8 +-
 .../web/app/mobile/views/pages/settings.vue   |   7 +-
 .../web/app/mobile/views/pages/user.vue       |  12 +-
 .../pages/user/home.followers-you-know.vue    |   4 +-
 .../mobile/views/pages/user/home.friends.vue  |   2 +-
 .../mobile/views/pages/user/home.photos.vue   |   4 +-
 .../mobile/views/pages/user/home.posts.vue    |   2 +-
 .../web/app/mobile/views/pages/user/home.vue  |   4 +-
 .../web/app/mobile/views/pages/welcome.vue    |   8 +-
 .../web/app/mobile/views/widgets/profile.vue  |   4 +-
 src/server/web/app/stats/tags/index.tag       |   4 +-
 src/server/web/docs/api.ja.pug                |   4 +-
 .../web/docs/api/endpoints/posts/create.yaml  |   8 +-
 .../docs/api/endpoints/posts/timeline.yaml    |   8 +-
 .../web/docs/api/entities/drive-file.yaml     |   6 +-
 src/server/web/docs/api/entities/post.yaml    |  18 +-
 src/server/web/docs/api/entities/user.yaml    |  36 +-
 src/tools/analysis/extract-user-domains.ts    |   2 +-
 src/tools/analysis/extract-user-keywords.ts   |   2 +-
 src/tools/analysis/predict-user-interst.ts    |   2 +-
 swagger.js                                    |  10 +-
 .../1.js}                                     |   6 +-
 tools/migration/nighthike/2.js                |  39 +
 tools/migration/nighthike/3.js                |  73 ++
 tools/migration/nighthike/4.js                | 232 ++++++
 .../shell.1522038492.user-account.js          |  41 --
 tools/migration/shell.1522116709.user-host.js |   1 -
 .../shell.1522116710.user-host_lower.js       |   1 -
 webpack.config.ts                             |   3 +-
 308 files changed, 3045 insertions(+), 3200 deletions(-)
 rename docs/config.md => .config/example.yml (98%)
 delete mode 100644 CHANGELOG.md
 delete mode 100644 LICENSE_AGPL-3.0
 delete mode 100644 src/server/api/models/appdata.ts
 delete mode 100644 src/server/api/models/drive-tag.ts
 rename tools/migration/{node.1522066477.user-account-keypair.js => nighthike/1.js} (79%)
 create mode 100644 tools/migration/nighthike/2.js
 create mode 100644 tools/migration/nighthike/3.js
 create mode 100644 tools/migration/nighthike/4.js
 delete mode 100644 tools/migration/shell.1522038492.user-account.js
 delete mode 100644 tools/migration/shell.1522116709.user-host.js
 delete mode 100644 tools/migration/shell.1522116710.user-host_lower.js

diff --git a/docs/config.md b/.config/example.yml
similarity index 98%
rename from docs/config.md
rename to .config/example.yml
index c4a54c0be..0e167ccb7 100644
--- a/docs/config.md
+++ b/.config/example.yml
@@ -1,4 +1,3 @@
-``` yaml
 # サーバーのメンテナ情報
 maintainer:
   # メンテナの名前
@@ -56,5 +55,3 @@ twitter:
 
   # インテグレーション用アプリのコンシューマーシークレット
   consumer_secret:
-
-```
diff --git a/.gitignore b/.gitignore
index d0ae0b808..be8689e2e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
-/.config
+/.config/*
+!/.config/example.yml
 /.vscode
 /node_modules
 /build
diff --git a/CHANGELOG.md b/CHANGELOG.md
deleted file mode 100644
index 6e69a7319..000000000
--- a/CHANGELOG.md
+++ /dev/null
@@ -1,532 +0,0 @@
-ChangeLog (Release Notes)
-=========================
-主に notable な changes を書いていきます
-
-3493 (2018/01/01)
------------------
-* なんか
-
-3460 (2017/12/23)
------------------
-* 検索で複数のユーザーを指定できるように
-* 検索でユーザーを除外できるように
-* など
-
-3451 (2017/12/22)
------------------
-* ミュート機能
-
-3430 (2017/12/21)
------------------
-* oops
-
-3428 (2017/12/21)
------------------
-* バグ修正
-
-3426 (2017/12/21)
------------------
-* 検索にpoll追加
-
-3424 (2017/12/21)
------------------
-* 検索にrepost追加
-* など
-
-3422 (2017/12/21)
------------------
-* 検索にfollow追加 #1023
-
-3420 (2017/12/21)
------------------
-* 検索機能を大幅に強化
-
-3415 (2017/12/19)
------------------
-* デザインの調整
-
-3404 (2017/12/17)
------------------
-* なんか
-
-3400 (2017/12/17)
------------------
-* なんか
-
-3392 (2017/12/17)
------------------
-* ドキュメントなど
-
-3390 (2017/12/16)
------------------
-* ドキュメントなど
-
-3347 (2017/12/11)
------------------
-* バグ修正
-
-3342 (2017/12/11)
------------------
-* なんか
-
-3339 (2017/12/11)
------------------
-* なんか
-
-3334 (2017/12/10)
------------------
-* いい感じにした
-
-3322 (2017/12/10)
------------------
-* :art:
-
-3320 (2017/12/10)
------------------
-* なんか
-
-3310 (2017/12/09)
------------------
-* i18nなど
-
-3308 (2017/12/09)
------------------
-* :art:
-
-3294 (2017/12/09)
------------------
-* バグ修正
-
-3292 (2017/12/09)
------------------
-* ユーザビリティの向上
-
-3281 (2017/12/08)
------------------
-* 二段階認証の実装 (#967)
-
-3278 (2017/12/08)
------------------
-* :v:
-
-3272 (2017/12/08)
------------------
-* Fix bug
-
-3268 (2017/12/08)
------------------
-* :v:
-
-3263 (2017/12/08)
------------------
-* FontAwesome5に移行
-
-3230 (2017/11/28)
------------------
-* :v:
-
-3219 (2017/11/28)
------------------
-* なんか
-
-3212 (2017/11/27)
------------------
-* なんか
-
-3201 (2017/11/23)
------------------
-* Twitterログインを実装 (#939)
-
-3196 (2017/11/23)
------------------
-* バグ修正
-
-3194 (2017/11/23)
------------------
-* バグ修正
-
-3191 (2017/11/23)
------------------
-* :v:
-
-3188 (2017/11/22)
------------------
-* バグ修正
-
-3180 (2017/11/21)
------------------
-* バグ修正
-
-3177 (2017/11/21)
------------------
-* ServiceWorker support
-  * Misskeyを開いていないときでも通知を受け取れるように(Chromeのみ)
-
-3165 (2017/11/20)
------------------
-* デスクトップ版でも通知バッジを表示 (#918)
-* デザインの調整
-* バグ修正
-
-3155 (2017/11/20)
------------------
-* デスクトップ版でユーザーの投稿グラフを見れるように
-
-3142 (2017/11/18)
------------------
-* バグ修正
-
-3140 (2017/11/18)
------------------
-* ウィジェットをスクロールに追従させるように
-
-3136 (2017/11/17)
------------------
-* バグ修正
-* 通信の最適化
-
-3131 (2017/11/17)
------------------
-* バグ修正
-* 通信の最適化
-
-3124 (2017/11/16)
------------------
-* バグ修正
-
-3121 (2017/11/16)
------------------
-* ブロードキャストウィジェットの強化
-* デザインのグリッチの修正
-* 通信の最適化
-
-3113 (2017/11/15)
------------------
-* アクティビティのレンダリングの問題の修正など
-
-3110 (2017/11/15)
------------------
-* デザインの調整など
-
-3107 (2017/11/14)
------------------
-* デザインの調整
-
-3104 (2017/11/14)
------------------
-* デスクトップ版ユーザーページのデザインの改良
-* バグ修正
-
-3099 (2017/11/14)
------------------
-* デスクトップ版ユーザーページの強化
-* バグ修正
-
-3093 (2017/11/14)
------------------
-* やった
-
-3089 (2017/11/14)
------------------
-* なんか
-
-3069 (2017/11/14)
------------------
-* ドライブウィンドウもポップアウトできるように
-* デザインの調整
-
-3066 (2017/11/14)
------------------
-* メッセージウィジェット追加
-* アクセスログウィジェット追加
-
-3057 (2017/11/13)
------------------
-* グリッチ修正
-
-3055 (2017/11/13)
------------------
-* メッセージのウィンドウのポップアウト (#911)
-
-3050 (2017/11/13)
------------------
-* 通信の最適化
-  * これで例えばサーバー情報ウィジェットを5000兆個設置しても利用するコネクションは一つだけになりウィジェットを1つ設置したときと(ネットワーク的な)負荷は変わらなくなる
-* デザインの調整
-* ユーザビリティの向上
-
-3040 (2017/11/12)
------------------
-* バグ修正
-
-3038 (2017/11/12)
------------------
-* 投稿フォームウィジェットの追加
-* タイムライン上部にもウィジェットを配置できるように
-
-3035 (2017/11/12)
------------------
-* ウィジェットの強化
-
-3033 (2017/11/12)
------------------
-* デザインの調整
-
-3031 (2017/11/12)
------------------
-* ウィジェットの強化
-
-3028 (2017/11/12)
------------------
-* ウィジェットの表示をコンパクトにできるように
-
-3026 (2017/11/12)
------------------
-* バグ修正
-
-3024 (2017/11/12)
------------------
-* いい感じにするなど
-
-3020 (2017/11/12)
------------------
-* 通信の最適化
-
-3017 (2017/11/11)
------------------
-* 誤字修正など
-
-3012 (2017/11/11)
------------------
-* デザインの調整
-
-3010 (2017/11/11)
------------------
-* デザインの調整
-
-3008 (2017/11/11)
------------------
-* カレンダー(タイムマシン)ウィジェットの追加
-
-3006 (2017/11/11)
------------------
-* デザインの調整
-* など
-
-2996 (2017/11/10)
------------------
-* デザインの調整
-* など
-
-2991 (2017/11/09)
------------------
-* デザインの調整
-
-2988 (2017/11/09)
------------------
-* チャンネルウィジェットを追加
-
-2984 (2017/11/09)
------------------
-* スライドショーウィジェットを追加
-
-2974 (2017/11/08)
------------------
-* ホームのカスタマイズを実装するなど
-
-2971 (2017/11/08)
------------------
-* バグ修正
-* デザインの調整
-* i18n
-
-2944 (2017/11/07)
------------------
-* パフォーマンスの向上
-  * GirdFSになるなどした
-* 依存関係の更新
-
-2807 (2017/11/02)
------------------
-* いい感じに
-
-2805 (2017/11/02)
------------------
-* いい感じに
-
-2801 (2017/11/01)
------------------
-* チャンネルのWatch実装
-
-2799 (2017/11/01)
------------------
-* いい感じに
-
-2795 (2017/11/01)
------------------
-* いい感じに
-
-2793 (2017/11/01)
------------------
-* なんか
-
-2783 (2017/11/01)
------------------
-* なんか
-
-2777 (2017/11/01)
------------------
-* 細かいブラッシュアップ
-
-2775 (2017/11/01)
------------------
-* Fix: バグ修正
-
-2769 (2017/11/01)
------------------
-* New: チャンネルシステム
-
-2752 (2017/10/30)
------------------
-* New: 未読の通知がある場合アイコンを表示するように
-
-2747 (2017/10/25)
------------------
-* Fix: 非ログイン状態ですべてのページが致命的な問題を発生させる (#89)
-
-2742 (2017/10/25)
------------------
-* New: トラブルシューティングを実装するなど
-
-2735 (2017/10/22)
------------------
-* New: モバイル版からでもクライアントバージョンを確認できるように
-
-2732 (2017/10/22)
------------------
-* 依存関係の更新など
-
-2584 (2017/09/08)
------------------
-* New: ユーザーページによく使うドメインを表示 (#771)
-* New: よくリプライするユーザーをユーザーページに表示 (#770)
-
-2566 (2017/09/07)
------------------
-* New: 投稿することの多いキーワードをユーザーページに表示する (#768)
-* l10n
-* デザインの修正
-
-2544 (2017/09/06)
------------------
-* 投稿のカテゴリに関する実験的な実装
-* l10n
-* ユーザビリティの向上
-
-2520 (2017/08/30)
------------------
-* デザインの調整
-
-2518 (2017/08/30)
------------------
-* Fix: モバイル版のタイムラインからリアクションやメニューを開けない
-* デザインの調整
-
-2515 (2017/08/30)
------------------
-* New: 投稿のピン留め (#746)
-* New: モバイル版のユーザーページに知り合いのフォロワーを表示するように
-* New: ホームストリームにメッセージを流すことでlast_used_atを更新できるようにする (#745)
-* その他細かな修正
-
-2508 (2017/08/30)
------------------
-* New: モバイル版のユーザーページのアクティビティチャートを変更
-* New: モバイル版のユーザーページに最終ログイン日時を表示するように
-* デザインの調整
-
-2503 (2017/08/30)
------------------
-* デザインの調整
-
-2502 (2017/08/30)
------------------
-* デザインの修正・調整
-
-2501 (2017/08/30)
------------------
-* New: モバイルのユーザーページを刷新
-
-2498 (2017/08/29)
------------------
-* Fix: repostのborder-radiusが効いていない (#743)
-* テーマカラーを赤に戻してみた
-* ユーザビリティの向上
-* デザインの調整
-
-2493-2 (2017/08/29)
--------------------
-* デザインの修正
-
-2493 (2017/08/29)
------------------
-* デザインの変更など
-
-2491 (2017/08/29)
------------------
-* デザインの修正と調整
-
-2489 (2017/08/29)
------------------
-* ユーザビリティの向上
-* デザインの調整
-
-2487 (2017/08/29)
------------------
-* New: パスワードを変更する際に新しいパスワードを二度入力させる (#739)
-* New: ドナーを表示する (#738)
-* Fix: 投稿のリンクが機能していない問題を修正
-* Fix: アカウント作成フォームのユーザーページURLプレビューが正しく機能していなかった問題を修正
-* l10n
-* デザインの調整
-
-2470 (2017/08/29)
------------------
-* New: トークンを再生成できるように (#497)
-* New: パスワードを変更する機能 (#364)
-
-2461 (2017/08/28)
------------------
-* Fix: モバイル版からアバターとバナーの設定を行えなかった問題を修正
-* デザインの修正
-
-2458 (2017/08/28)
------------------
-* New: モバイル版からプロフィールを設定できるように
-* New: モバイル版からサインアウトを行えるように
-* New: 投稿ページに次の投稿/前の投稿リンクを作成 (#734)
-* New: タイムラインの投稿をダブルクリックすることで詳細な情報が見れるように
-* Fix: モバイル版でおすすめユーザーをフォローしてもタイムラインが更新されない (#736)
-* Fix: モバイル版で設定にアクセスできない
-* デザインの調整
-* 依存関係の更新
-
-2380
-----
-アプリケーションが作れない問題を修正
-
-2367
-----
-Statsのユーザー数グラフに「アカウントが作成された**回数**」(その日時点での「アカウント数」**ではなく**)グラフも併記するようにした
-
-2364
-----
-デザインの微調整
-
-2361
-----
-Statsを実装するなど
-
-2357
-----
-Statusを実装するなど
diff --git a/LICENSE b/LICENSE
index 0b6e30e45..dba13ed2d 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,21 +1,661 @@
-The MIT License (MIT)
+                    GNU AFFERO GENERAL PUBLIC LICENSE
+                       Version 3, 19 November 2007
 
-Copyright (c) 2014-2018 syuilo
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
 
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+                            Preamble
 
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+  The GNU Affero General Public License is a free, copyleft license for
+software and other kinds of works, specifically designed to ensure
+cooperation with the community in the case of network server software.
 
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+our General Public Licenses are intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  Developers that use our General Public Licenses protect your rights
+with two steps: (1) assert copyright on the software, and (2) offer
+you this License which gives you legal permission to copy, distribute
+and/or modify the software.
+
+  A secondary benefit of defending all users' freedom is that
+improvements made in alternate versions of the program, if they
+receive widespread use, become available for other developers to
+incorporate.  Many developers of free software are heartened and
+encouraged by the resulting cooperation.  However, in the case of
+software used on network servers, this result may fail to come about.
+The GNU General Public License permits making a modified version and
+letting the public access it on a server without ever releasing its
+source code to the public.
+
+  The GNU Affero General Public License is designed specifically to
+ensure that, in such cases, the modified source code becomes available
+to the community.  It requires the operator of a network server to
+provide the source code of the modified version running there to the
+users of that server.  Therefore, public use of a modified version, on
+a publicly accessible server, gives the public access to the source
+code of the modified version.
+
+  An older license, called the Affero General Public License and
+published by Affero, was designed to accomplish similar goals.  This is
+a different license, not a version of the Affero GPL, but Affero has
+released a new version of the Affero GPL which permits relicensing under
+this license.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU Affero General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Remote Network Interaction; Use with the GNU General Public License.
+
+  Notwithstanding any other provision of this License, if you modify the
+Program, your modified version must prominently offer all users
+interacting with it remotely through a computer network (if your version
+supports such interaction) an opportunity to receive the Corresponding
+Source of your version by providing access to the Corresponding Source
+from a network server at no charge, through some standard or customary
+means of facilitating copying of software.  This Corresponding Source
+shall include the Corresponding Source for any work covered by version 3
+of the GNU General Public License that is incorporated pursuant to the
+following paragraph.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the work with which it is combined will remain governed by version
+3 of the GNU General Public License.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU Affero General Public License from time to time.  Such new versions
+will be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU Affero General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU Affero General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU Affero General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Affero General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Affero General Public License for more details.
+
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If your software can interact with users remotely through a computer
+network, you should also make sure that it provides a way for users to
+get its source.  For example, if your program is a web application, its
+interface could display a "Source" link that leads users to an archive
+of the code.  There are many ways you could offer source, and different
+solutions will be better for different programs; see section 13 for the
+specific requirements.
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU AGPL, see
+<http://www.gnu.org/licenses/>.
diff --git a/LICENSE_AGPL-3.0 b/LICENSE_AGPL-3.0
deleted file mode 100644
index dba13ed2d..000000000
--- a/LICENSE_AGPL-3.0
+++ /dev/null
@@ -1,661 +0,0 @@
-                    GNU AFFERO GENERAL PUBLIC LICENSE
-                       Version 3, 19 November 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-                            Preamble
-
-  The GNU Affero General Public License is a free, copyleft license for
-software and other kinds of works, specifically designed to ensure
-cooperation with the community in the case of network server software.
-
-  The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works.  By contrast,
-our General Public Licenses are intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
-  Developers that use our General Public Licenses protect your rights
-with two steps: (1) assert copyright on the software, and (2) offer
-you this License which gives you legal permission to copy, distribute
-and/or modify the software.
-
-  A secondary benefit of defending all users' freedom is that
-improvements made in alternate versions of the program, if they
-receive widespread use, become available for other developers to
-incorporate.  Many developers of free software are heartened and
-encouraged by the resulting cooperation.  However, in the case of
-software used on network servers, this result may fail to come about.
-The GNU General Public License permits making a modified version and
-letting the public access it on a server without ever releasing its
-source code to the public.
-
-  The GNU Affero General Public License is designed specifically to
-ensure that, in such cases, the modified source code becomes available
-to the community.  It requires the operator of a network server to
-provide the source code of the modified version running there to the
-users of that server.  Therefore, public use of a modified version, on
-a publicly accessible server, gives the public access to the source
-code of the modified version.
-
-  An older license, called the Affero General Public License and
-published by Affero, was designed to accomplish similar goals.  This is
-a different license, not a version of the Affero GPL, but Affero has
-released a new version of the Affero GPL which permits relicensing under
-this license.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-                       TERMS AND CONDITIONS
-
-  0. Definitions.
-
-  "This License" refers to version 3 of the GNU Affero General Public License.
-
-  "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
-  "The Program" refers to any copyrightable work licensed under this
-License.  Each licensee is addressed as "you".  "Licensees" and
-"recipients" may be individuals or organizations.
-
-  To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy.  The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
-  A "covered work" means either the unmodified Program or a work based
-on the Program.
-
-  To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy.  Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
-  To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies.  Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
-  An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License.  If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
-  1. Source Code.
-
-  The "source code" for a work means the preferred form of the work
-for making modifications to it.  "Object code" means any non-source
-form of a work.
-
-  A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
-  The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form.  A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
-  The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities.  However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work.  For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
-  The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
-  The Corresponding Source for a work in source code form is that
-same work.
-
-  2. Basic Permissions.
-
-  All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met.  This License explicitly affirms your unlimited
-permission to run the unmodified Program.  The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work.  This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
-  You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force.  You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright.  Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
-  Conveying under any other circumstances is permitted solely under
-the conditions stated below.  Sublicensing is not allowed; section 10
-makes it unnecessary.
-
-  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
-  No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
-  When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
-  4. Conveying Verbatim Copies.
-
-  You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
-  You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
-  5. Conveying Modified Source Versions.
-
-  You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
-    a) The work must carry prominent notices stating that you modified
-    it, and giving a relevant date.
-
-    b) The work must carry prominent notices stating that it is
-    released under this License and any conditions added under section
-    7.  This requirement modifies the requirement in section 4 to
-    "keep intact all notices".
-
-    c) You must license the entire work, as a whole, under this
-    License to anyone who comes into possession of a copy.  This
-    License will therefore apply, along with any applicable section 7
-    additional terms, to the whole of the work, and all its parts,
-    regardless of how they are packaged.  This License gives no
-    permission to license the work in any other way, but it does not
-    invalidate such permission if you have separately received it.
-
-    d) If the work has interactive user interfaces, each must display
-    Appropriate Legal Notices; however, if the Program has interactive
-    interfaces that do not display Appropriate Legal Notices, your
-    work need not make them do so.
-
-  A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit.  Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
-  6. Conveying Non-Source Forms.
-
-  You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
-    a) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by the
-    Corresponding Source fixed on a durable physical medium
-    customarily used for software interchange.
-
-    b) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by a
-    written offer, valid for at least three years and valid for as
-    long as you offer spare parts or customer support for that product
-    model, to give anyone who possesses the object code either (1) a
-    copy of the Corresponding Source for all the software in the
-    product that is covered by this License, on a durable physical
-    medium customarily used for software interchange, for a price no
-    more than your reasonable cost of physically performing this
-    conveying of source, or (2) access to copy the
-    Corresponding Source from a network server at no charge.
-
-    c) Convey individual copies of the object code with a copy of the
-    written offer to provide the Corresponding Source.  This
-    alternative is allowed only occasionally and noncommercially, and
-    only if you received the object code with such an offer, in accord
-    with subsection 6b.
-
-    d) Convey the object code by offering access from a designated
-    place (gratis or for a charge), and offer equivalent access to the
-    Corresponding Source in the same way through the same place at no
-    further charge.  You need not require recipients to copy the
-    Corresponding Source along with the object code.  If the place to
-    copy the object code is a network server, the Corresponding Source
-    may be on a different server (operated by you or a third party)
-    that supports equivalent copying facilities, provided you maintain
-    clear directions next to the object code saying where to find the
-    Corresponding Source.  Regardless of what server hosts the
-    Corresponding Source, you remain obligated to ensure that it is
-    available for as long as needed to satisfy these requirements.
-
-    e) Convey the object code using peer-to-peer transmission, provided
-    you inform other peers where the object code and Corresponding
-    Source of the work are being offered to the general public at no
-    charge under subsection 6d.
-
-  A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
-  A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling.  In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage.  For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product.  A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
-  "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source.  The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
-  If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information.  But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
-  The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed.  Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
-  Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
-  7. Additional Terms.
-
-  "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law.  If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
-  When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it.  (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.)  You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
-  Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
-    a) Disclaiming warranty or limiting liability differently from the
-    terms of sections 15 and 16 of this License; or
-
-    b) Requiring preservation of specified reasonable legal notices or
-    author attributions in that material or in the Appropriate Legal
-    Notices displayed by works containing it; or
-
-    c) Prohibiting misrepresentation of the origin of that material, or
-    requiring that modified versions of such material be marked in
-    reasonable ways as different from the original version; or
-
-    d) Limiting the use for publicity purposes of names of licensors or
-    authors of the material; or
-
-    e) Declining to grant rights under trademark law for use of some
-    trade names, trademarks, or service marks; or
-
-    f) Requiring indemnification of licensors and authors of that
-    material by anyone who conveys the material (or modified versions of
-    it) with contractual assumptions of liability to the recipient, for
-    any liability that these contractual assumptions directly impose on
-    those licensors and authors.
-
-  All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10.  If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term.  If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
-  If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
-  Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
-  8. Termination.
-
-  You may not propagate or modify a covered work except as expressly
-provided under this License.  Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
-  However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
-  Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
-  Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License.  If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
-  9. Acceptance Not Required for Having Copies.
-
-  You are not required to accept this License in order to receive or
-run a copy of the Program.  Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance.  However,
-nothing other than this License grants you permission to propagate or
-modify any covered work.  These actions infringe copyright if you do
-not accept this License.  Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
-  10. Automatic Licensing of Downstream Recipients.
-
-  Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License.  You are not responsible
-for enforcing compliance by third parties with this License.
-
-  An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations.  If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
-  You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License.  For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
-  11. Patents.
-
-  A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based.  The
-work thus licensed is called the contributor's "contributor version".
-
-  A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version.  For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
-  Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
-  In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement).  To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
-  If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients.  "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
-  If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
-  A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License.  You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
-  Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
-  12. No Surrender of Others' Freedom.
-
-  If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all.  For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
-  13. Remote Network Interaction; Use with the GNU General Public License.
-
-  Notwithstanding any other provision of this License, if you modify the
-Program, your modified version must prominently offer all users
-interacting with it remotely through a computer network (if your version
-supports such interaction) an opportunity to receive the Corresponding
-Source of your version by providing access to the Corresponding Source
-from a network server at no charge, through some standard or customary
-means of facilitating copying of software.  This Corresponding Source
-shall include the Corresponding Source for any work covered by version 3
-of the GNU General Public License that is incorporated pursuant to the
-following paragraph.
-
-  Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU General Public License into a single
-combined work, and to convey the resulting work.  The terms of this
-License will continue to apply to the part which is the covered work,
-but the work with which it is combined will remain governed by version
-3 of the GNU General Public License.
-
-  14. Revised Versions of this License.
-
-  The Free Software Foundation may publish revised and/or new versions of
-the GNU Affero General Public License from time to time.  Such new versions
-will be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-  Each version is given a distinguishing version number.  If the
-Program specifies that a certain numbered version of the GNU Affero General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation.  If the Program does not specify a version number of the
-GNU Affero General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
-  If the Program specifies that a proxy can decide which future
-versions of the GNU Affero General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
-  Later license versions may give you additional or different
-permissions.  However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
-  15. Disclaimer of Warranty.
-
-  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. Limitation of Liability.
-
-  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
-  17. Interpretation of Sections 15 and 16.
-
-  If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
-                     END OF TERMS AND CONDITIONS
-
-            How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU Affero General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU Affero General Public License for more details.
-
-    You should have received a copy of the GNU Affero General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-Also add information on how to contact you by electronic and paper mail.
-
-  If your software can interact with users remotely through a computer
-network, you should also make sure that it provides a way for users to
-get its source.  For example, if your program is a web application, its
-interface could display a "Source" link that leads users to an archive
-of the code.  There are many ways you could offer source, and different
-solutions will be better for different programs; see section 13 for the
-specific requirements.
-
-  You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU AGPL, see
-<http://www.gnu.org/licenses/>.
diff --git a/README.md b/README.md
index c50566cc9..ef12958c2 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,6 @@
-![Misskey](./assets/title.png)
+<img src="https://github.com/syuilo/misskey/blob/b3f42e62af698a67c2250533c437569559f1fdf9/src/himasaku/resources/himasaku.png?raw=true" align="right" width="320px"/>
+
+Misskey
 ================================================================
 
 [![][travis-badge]][travis-link]
@@ -7,57 +9,46 @@
 [![][sakurako-badge]][himasaku]
 [![][agpl-3.0-badge]][AGPL-3.0]
 
-[Misskey](https://misskey.xyz) is a completely open source,
+> Lead Maintainer: [syuilo][syuilo-link]
+
+**[Misskey](https://misskey.xyz)** is a completely open source,
 ultimately sophisticated new type of mini-blog based SNS.
 
-![ss](./assets/ss.jpg)
-
-Key features
+:sparkles: Features
 ----------------------------------------------------------------
 * Automatically updated timeline
 * Private messages
 * Two-Factor Authentication support
 * ServiceWorker support
 * Web API for third-party applications
-* No ads
+* ActivityPub compatible
 
 and more! You can touch with your own eyes at https://misskey.xyz/.
 
-Setup and Installation
+:package: Setup and Installation
 ----------------------------------------------------------------
 If you want to run your own instance of Misskey,
 please see [Setup and installation guide](./docs/setup.en.md).
 
-Contribution
+:yen: Donation
 ----------------------------------------------------------------
-Please see [Contribution guide](./CONTRIBUTING.md).
+If you want to donate to Misskey, please see [this](./docs/donate.ja.md).
 
-Release Notes
+[List of all donors](./DONORS.md)
+
+:mortar_board: Notable contributors
 ----------------------------------------------------------------
-Please see [ChangeLog](./CHANGELOG.md).
-
-Sponsors & Backers
-----------------------------------------------------------------
-Misskey has no 100+ GitHub stars currently. However, a donation is always welcome!
-If you want to donate to Misskey, please get in touch with [@syuilo][syuilo-link].
-
-**Note:** When you donate to Misskey, your name will be listed in [donors](./DONORS.md).
-
-Collaborators
-----------------------------------------------------------------
-| ![syuilo][syuilo-icon] | ![Morisawa Aya][ayamorisawa-icon] | ![otofune][otofune-icon]        |
-|------------------------|-----------------------------------|---------------------------------|
-| [syuilo][syuilo-link]  | [Aya Morisawa][ayamorisawa-link]  | [otofune][otofune-link] |
+| ![syuilo][syuilo-icon] | ![Morisawa Aya][ayamorisawa-icon] | ![otofune][otofune-icon] | ![akihikodaki][akihikodaki-icon] | ![rinsuki][rinsuki-icon] |
+|:-:|:-:|:-:|:-:|:-:|
+| [syuilo][syuilo-link]<br>Owner | [Aya Morisawa][ayamorisawa-link]<br>Collaborator | [otofune][otofune-link]<br>Collaborator | [akihikodaki][akihikodaki-link] | [rinsuki][rinsuki-link] |
 
 [List of all contributors](https://github.com/syuilo/misskey/graphs/contributors)
 
-Copyright
+:four_leaf_clover: Copyright
 ----------------------------------------------------------------
-Misskey is an open-source software licensed under [The MIT License](LICENSE).
+> Copyright (c) 2014-2018 syuilo
 
-The portions of Misskey contributed by Akihiko Odaki <nekomanma@pixiv.co.jp> is
-licensed under GNU Affero General Public License (only version 3.0 of the
-license is applied.) See Git log to identify them.
+Misskey is an open-source software licensed under [GNU AGPLv3](LICENSE).
 
 [agpl-3.0]:           https://www.gnu.org/licenses/agpl-3.0.en.html
 [agpl-3.0-badge]:     https://img.shields.io/badge/license-AGPL--3.0-444444.svg?style=flat-square
@@ -69,10 +60,14 @@ license is applied.) See Git log to identify them.
 [himawari-badge]:     https://img.shields.io/badge/%E5%8F%A4%E8%B0%B7-%E5%90%91%E6%97%A5%E8%91%B5-1684c5.svg?style=flat-square
 [sakurako-badge]:     https://img.shields.io/badge/%E5%A4%A7%E5%AE%A4-%E6%AB%BB%E5%AD%90-efb02a.svg?style=flat-square
 
-<!-- Collaborators Info -->
+<!-- Contributors Info -->
 [syuilo-link]:      https://syuilo.com
 [syuilo-icon]:      https://avatars2.githubusercontent.com/u/4439005?v=3&s=70
 [ayamorisawa-link]: https://github.com/ayamorisawa
 [ayamorisawa-icon]: https://avatars0.githubusercontent.com/u/10798641?v=3&s=70
 [otofune-link]:     https://github.com/otofune
 [otofune-icon]:     https://avatars0.githubusercontent.com/u/15062473?v=3&s=70
+[akihikodaki-link]: https://github.com/akihikodaki
+[akihikodaki-icon]: https://avatars2.githubusercontent.com/u/17036990?s=70&v=4
+[rinsuki-link]:     https://github.com/rinsuki
+[rinsuki-icon]:     https://avatars0.githubusercontent.com/u/6533808?s=70&v=4
diff --git a/docker/Dockerfile b/docker/Dockerfile
index ef04fc9e2..7cee650de 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -14,7 +14,7 @@ RUN pacman -S --noconfirm pacman
 RUN pacman-db-upgrade
 RUN pacman -S --noconfirm archlinux-keyring
 RUN pacman -Syyu --noconfirm
-RUN pacman -S --noconfirm git nodejs npm mongodb redis graphicsmagick
+RUN pacman -S --noconfirm git nodejs npm mongodb redis imagemagick
 
 COPY misskey.sh /root/misskey.sh
 RUN chmod u+x /root/misskey.sh
diff --git a/docs/setup.en.md b/docs/setup.en.md
index 08cd16857..a436d751c 100644
--- a/docs/setup.en.md
+++ b/docs/setup.en.md
@@ -37,9 +37,9 @@ Please install and setup these softwares:
 
 *3.* Prepare configuration
 ----------------------------------------------------------------
-First, you need to create a `.config` directory in the directory that
-Misskey installed. And then you need to create a `default.yml` file in
-the directory. The template of configuration is available [here](./config.md).
+1. Copy `example.yml` of `.config` directory
+2. Rename it to `default.yml`
+3. Edit it
 
 *4.* Install and build Misskey
 ----------------------------------------------------------------
diff --git a/docs/setup.ja.md b/docs/setup.ja.md
index 9fa56acb2..6605461d9 100644
--- a/docs/setup.ja.md
+++ b/docs/setup.ja.md
@@ -37,9 +37,9 @@ web-push generate-vapid-keys
 
 *3.* 設定ファイルを用意する
 ----------------------------------------------------------------
-Misskeyをインストールしたディレクトリに、`.config`というディレクトリを作成し、
-その中に`default.yml`という名前で設定ファイルを作ってください。
-設定ファイルの下書きは[ここ](./config.md)にありますので、コピペしてご利用ください。
+1. `.config`ディレクトリ内の`example.yml`をコピー
+2. `default.yml`にリネーム
+3. 編集する
 
 *4.* Misskeyのインストール(とビルド)
 ----------------------------------------------------------------
diff --git a/gulpfile.ts b/gulpfile.ts
index 11f34c962..46727126c 100644
--- a/gulpfile.ts
+++ b/gulpfile.ts
@@ -125,7 +125,6 @@ gulp.task('build:client:script', () =>
 		.pipe(replace('VERSION', JSON.stringify(version)))
 		.pipe(replace('API', JSON.stringify(config.api_url)))
 		.pipe(replace('ENV', JSON.stringify(env)))
-		.pipe(replace('HOST', JSON.stringify(config.host)))
 		.pipe(isProduction ? uglify({
 			toplevel: true
 		} as any) : gutil.noop())
diff --git a/locales/ja.yml b/locales/ja.yml
index f826b1b6c..fd140ecc3 100644
--- a/locales/ja.yml
+++ b/locales/ja.yml
@@ -147,7 +147,7 @@ common:
       available: "利用できます"
       unavailable: "既に利用されています"
       error: "通信エラー"
-      invalid-format: "a~z、A~Z、0~9、-(ハイフン)が使えます"
+      invalid-format: "a~z、A~Z、0~9、_が使えます"
       too-short: "3文字以上でお願いします!"
       too-long: "20文字以内でお願いします"
       password: "パスワード"
diff --git a/src/index.ts b/src/index.ts
index bd9b094d9..f86c768fd 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -109,7 +109,6 @@ async function workerMain(opt) {
  */
 async function init(): Promise<Config> {
 	Logger.info('Welcome to Misskey!');
-	Logger.info(chalk.bold('Misskey <aoi>'));
 	Logger.info('Initializing...');
 
 	EnvironmentInfo.show();
diff --git a/src/server/api/authenticate.ts b/src/server/api/authenticate.ts
index 537c3d1e1..7b3983a83 100644
--- a/src/server/api/authenticate.ts
+++ b/src/server/api/authenticate.ts
@@ -55,10 +55,10 @@ export default (req: express.Request) => new Promise<IAuthContext>(async (resolv
 		}
 
 		const app = await App
-			.findOne({ _id: accessToken.app_id });
+			.findOne({ _id: accessToken.appId });
 
 		const user = await User
-			.findOne({ _id: accessToken.user_id });
+			.findOne({ _id: accessToken.userId });
 
 		return resolve({
 			app: app,
diff --git a/src/server/api/bot/core.ts b/src/server/api/bot/core.ts
index 77a68aaee..ec7c935f9 100644
--- a/src/server/api/bot/core.ts
+++ b/src/server/api/bot/core.ts
@@ -67,7 +67,7 @@ export default class BotCore extends EventEmitter {
 			return await this.context.q(query);
 		}
 
-		if (/^@[a-zA-Z0-9-]+$/.test(query)) {
+		if (/^@[a-zA-Z0-9_]+$/.test(query)) {
 			return await this.showUserCommand(query);
 		}
 
@@ -208,7 +208,7 @@ class SigninContext extends Context {
 		if (this.temporaryUser == null) {
 			// Fetch user
 			const user: IUser = await User.findOne({
-				username_lower: query.toLowerCase(),
+				usernameLower: query.toLowerCase(),
 				host: null
 			}, {
 				fields: {
@@ -297,7 +297,7 @@ class TlContext extends Context {
 	private async getTl() {
 		const tl = await require('../endpoints/posts/timeline')({
 			limit: 5,
-			until_id: this.next ? this.next : undefined
+			untilId: this.next ? this.next : undefined
 		}, this.bot.user);
 
 		if (tl.length > 0) {
@@ -349,7 +349,7 @@ class NotificationsContext extends Context {
 	private async getNotifications() {
 		const notifications = await require('../endpoints/i/notifications')({
 			limit: 5,
-			until_id: this.next ? this.next : undefined
+			untilId: this.next ? this.next : undefined
 		}, this.bot.user);
 
 		if (notifications.length > 0) {
diff --git a/src/server/api/bot/interfaces/line.ts b/src/server/api/bot/interfaces/line.ts
index 5b3e9107f..1340ac992 100644
--- a/src/server/api/bot/interfaces/line.ts
+++ b/src/server/api/bot/interfaces/line.ts
@@ -115,7 +115,7 @@ class LineBot extends BotCore {
 			actions.push({
 				type: 'uri',
 				label: 'Twitterアカウントを見る',
-				uri: `https://twitter.com/${user.account.twitter.screen_name}`
+				uri: `https://twitter.com/${user.account.twitter.screenName}`
 			});
 		}
 
@@ -130,7 +130,7 @@ class LineBot extends BotCore {
 			altText: await super.showUserCommand(q),
 			template: {
 				type: 'buttons',
-				thumbnailImageUrl: `${user.avatar_url}?thumbnail&size=1024`,
+				thumbnailImageUrl: `${user.avatarUrl}?thumbnail&size=1024`,
 				title: `${user.name} (@${acct})`,
 				text: user.description || '(no description)',
 				actions: actions
@@ -142,7 +142,7 @@ class LineBot extends BotCore {
 
 	public async showUserTimelinePostback(userId: string) {
 		const tl = await require('../../endpoints/users/posts')({
-			user_id: userId,
+			userId: userId,
 			limit: 5
 		}, this.user);
 
@@ -174,7 +174,7 @@ module.exports = async (app: express.Application) => {
 			const user = await User.findOne({
 				host: null,
 				'account.line': {
-					user_id: sourceId
+					userId: sourceId
 				}
 			});
 
@@ -184,7 +184,7 @@ module.exports = async (app: express.Application) => {
 				User.update(user._id, {
 					$set: {
 						'account.line': {
-							user_id: sourceId
+							userId: sourceId
 						}
 					}
 				});
@@ -194,7 +194,7 @@ module.exports = async (app: express.Application) => {
 				User.update(user._id, {
 					$set: {
 						'account.line': {
-							user_id: null
+							userId: null
 						}
 					}
 				});
diff --git a/src/server/api/common/drive/add-file.ts b/src/server/api/common/drive/add-file.ts
index 5f3c69c15..21ddd1aae 100644
--- a/src/server/api/common/drive/add-file.ts
+++ b/src/server/api/common/drive/add-file.ts
@@ -100,7 +100,7 @@ const addFile = async (
 		// Check if there is a file with the same hash
 		const much = await DriveFile.findOne({
 			md5: hash,
-			'metadata.user_id': user._id
+			'metadata.userId': user._id
 		});
 
 		if (much !== null) {
@@ -172,7 +172,7 @@ const addFile = async (
 			}
 			const driveFolder = await DriveFolder.findOne({
 				_id: folderId,
-				user_id: user._id
+				userId: user._id
 			});
 			if (!driveFolder) {
 				throw 'folder-not-found';
@@ -184,7 +184,7 @@ const addFile = async (
 			// Calculate drive usage
 			const usage = await DriveFile
 				.aggregate([{
-					$match: { 'metadata.user_id': user._id }
+					$match: { 'metadata.userId': user._id }
 				}, {
 					$project: {
 						length: true
@@ -205,7 +205,7 @@ const addFile = async (
 			log(`drive usage is ${usage}`);
 
 			// If usage limit exceeded
-			if (usage + size > user.drive_capacity) {
+			if (usage + size > user.driveCapacity) {
 				throw 'no-free-space';
 			}
 		})()
@@ -221,12 +221,12 @@ const addFile = async (
 	}
 
 	if (averageColor) {
-		properties['average_color'] = averageColor;
+		properties['avgColor'] = averageColor;
 	}
 
 	return addToGridFS(detectedName, readable, mime, {
-		user_id: user._id,
-		folder_id: folder !== null ? folder._id : null,
+		userId: user._id,
+		folderId: folder !== null ? folder._id : null,
 		comment: comment,
 		properties: properties
 	});
@@ -297,7 +297,7 @@ export default (user: any, file: string | stream.Readable, ...args) => new Promi
 					id: file._id.toString(),
 					body: {
 						name: file.name,
-						user_id: user._id.toString()
+						userId: user._id.toString()
 					}
 				});
 			}
diff --git a/src/server/api/common/get-friends.ts b/src/server/api/common/get-friends.ts
index db6313816..7f548b3bb 100644
--- a/src/server/api/common/get-friends.ts
+++ b/src/server/api/common/get-friends.ts
@@ -6,17 +6,17 @@ export default async (me: mongodb.ObjectID, includeMe: boolean = true) => {
 	// SELECT followee
 	const myfollowing = await Following
 		.find({
-			follower_id: me,
+			followerId: me,
 			// 削除されたドキュメントは除く
-			deleted_at: { $exists: false }
+			deletedAt: { $exists: false }
 		}, {
 			fields: {
-				followee_id: true
+				followeeId: true
 			}
 		});
 
 	// ID list of other users who the I follows
-	const myfollowingIds = myfollowing.map(follow => follow.followee_id);
+	const myfollowingIds = myfollowing.map(follow => follow.followeeId);
 
 	if (includeMe) {
 		myfollowingIds.push(me);
diff --git a/src/server/api/common/notify.ts b/src/server/api/common/notify.ts
index ae5669b84..c4df17f88 100644
--- a/src/server/api/common/notify.ts
+++ b/src/server/api/common/notify.ts
@@ -16,11 +16,11 @@ export default (
 
 	// Create notification
 	const notification = await Notification.insert(Object.assign({
-		created_at: new Date(),
-		notifiee_id: notifiee,
-		notifier_id: notifier,
+		createdAt: new Date(),
+		notifieeId: notifiee,
+		notifierId: notifier,
 		type: type,
-		is_read: false
+		isRead: false
 	}, content));
 
 	resolve(notification);
@@ -31,14 +31,14 @@ export default (
 
 	// 3秒経っても(今回作成した)通知が既読にならなかったら「未読の通知がありますよ」イベントを発行する
 	setTimeout(async () => {
-		const fresh = await Notification.findOne({ _id: notification._id }, { is_read: true });
-		if (!fresh.is_read) {
+		const fresh = await Notification.findOne({ _id: notification._id }, { isRead: true });
+		if (!fresh.isRead) {
 			//#region ただしミュートしているユーザーからの通知なら無視
 			const mute = await Mute.find({
-				muter_id: notifiee,
-				deleted_at: { $exists: false }
+				muterId: notifiee,
+				deletedAt: { $exists: false }
 			});
-			const mutedUserIds = mute.map(m => m.mutee_id.toString());
+			const mutedUserIds = mute.map(m => m.muteeId.toString());
 			if (mutedUserIds.indexOf(notifier.toString()) != -1) {
 				return;
 			}
diff --git a/src/server/api/common/push-sw.ts b/src/server/api/common/push-sw.ts
index b33715eb1..e5fbec10e 100644
--- a/src/server/api/common/push-sw.ts
+++ b/src/server/api/common/push-sw.ts
@@ -20,7 +20,7 @@ export default async function(userId: mongo.ObjectID | string, type, body?) {
 
 	// Fetch
 	const subscriptions = await Subscription.find({
-		user_id: userId
+		userId: userId
 	});
 
 	subscriptions.forEach(subscription => {
@@ -41,7 +41,7 @@ export default async function(userId: mongo.ObjectID | string, type, body?) {
 
 			if (err.statusCode == 410) {
 				Subscription.remove({
-					user_id: userId,
+					userId: userId,
 					endpoint: subscription.endpoint,
 					auth: subscription.auth,
 					publickey: subscription.publickey
diff --git a/src/server/api/common/read-messaging-message.ts b/src/server/api/common/read-messaging-message.ts
index 8e5e5b2b6..9047edec8 100644
--- a/src/server/api/common/read-messaging-message.ts
+++ b/src/server/api/common/read-messaging-message.ts
@@ -37,12 +37,12 @@ export default (
 	// Update documents
 	await Message.update({
 		_id: { $in: ids },
-		user_id: otherpartyId,
-		recipient_id: userId,
-		is_read: false
+		userId: otherpartyId,
+		recipientId: userId,
+		isRead: false
 	}, {
 		$set: {
-			is_read: true
+			isRead: true
 		}
 	}, {
 		multi: true
@@ -55,8 +55,8 @@ export default (
 	// Calc count of my unread messages
 	const count = await Message
 		.count({
-			recipient_id: userId,
-			is_read: false
+			recipientId: userId,
+			isRead: false
 		});
 
 	if (count == 0) {
diff --git a/src/server/api/common/read-notification.ts b/src/server/api/common/read-notification.ts
index 3009cc5d0..5bbf13632 100644
--- a/src/server/api/common/read-notification.ts
+++ b/src/server/api/common/read-notification.ts
@@ -29,10 +29,10 @@ export default (
 	// Update documents
 	await Notification.update({
 		_id: { $in: ids },
-		is_read: false
+		isRead: false
 	}, {
 		$set: {
-			is_read: true
+			isRead: true
 		}
 	}, {
 		multi: true
@@ -41,8 +41,8 @@ export default (
 	// Calc count of my unread notifications
 	const count = await Notification
 		.count({
-			notifiee_id: userId,
-			is_read: false
+			notifieeId: userId,
+			isRead: false
 		});
 
 	if (count == 0) {
diff --git a/src/server/api/common/watch-post.ts b/src/server/api/common/watch-post.ts
index 1a50f0eda..61ea44443 100644
--- a/src/server/api/common/watch-post.ts
+++ b/src/server/api/common/watch-post.ts
@@ -3,15 +3,15 @@ import Watching from '../models/post-watching';
 
 export default async (me: mongodb.ObjectID, post: object) => {
 	// 自分の投稿はwatchできない
-	if (me.equals((post as any).user_id)) {
+	if (me.equals((post as any).userId)) {
 		return;
 	}
 
 	// if watching now
 	const exist = await Watching.findOne({
-		post_id: (post as any)._id,
-		user_id: me,
-		deleted_at: { $exists: false }
+		postId: (post as any)._id,
+		userId: me,
+		deletedAt: { $exists: false }
 	});
 
 	if (exist !== null) {
@@ -19,8 +19,8 @@ export default async (me: mongodb.ObjectID, post: object) => {
 	}
 
 	await Watching.insert({
-		created_at: new Date(),
-		post_id: (post as any)._id,
-		user_id: me
+		createdAt: new Date(),
+		postId: (post as any)._id,
+		userId: me
 	});
 };
diff --git a/src/server/api/endpoints.ts b/src/server/api/endpoints.ts
index c7100bd03..979d8ac29 100644
--- a/src/server/api/endpoints.ts
+++ b/src/server/api/endpoints.ts
@@ -289,7 +289,7 @@ const endpoints: Endpoint[] = [
 		kind: 'notification-write'
 	},
 	{
-		name: 'notifications/mark_as_read_all',
+		name: 'notifications/markAsRead_all',
 		withCredential: true,
 		kind: 'notification-write'
 	},
diff --git a/src/server/api/endpoints/aggregation/posts.ts b/src/server/api/endpoints/aggregation/posts.ts
index 9d8bccbdb..67d261964 100644
--- a/src/server/api/endpoints/aggregation/posts.ts
+++ b/src/server/api/endpoints/aggregation/posts.ts
@@ -18,23 +18,23 @@ module.exports = params => new Promise(async (res, rej) => {
 	const datas = await Post
 		.aggregate([
 			{ $project: {
-				repost_id: '$repost_id',
-				reply_id: '$reply_id',
-				created_at: { $add: ['$created_at', 9 * 60 * 60 * 1000] } // Convert into JST
+				repostId: '$repostId',
+				replyId: '$replyId',
+				createdAt: { $add: ['$createdAt', 9 * 60 * 60 * 1000] } // Convert into JST
 			}},
 			{ $project: {
 				date: {
-					year: { $year: '$created_at' },
-					month: { $month: '$created_at' },
-					day: { $dayOfMonth: '$created_at' }
+					year: { $year: '$createdAt' },
+					month: { $month: '$createdAt' },
+					day: { $dayOfMonth: '$createdAt' }
 				},
 				type: {
 					$cond: {
-						if: { $ne: ['$repost_id', null] },
+						if: { $ne: ['$repostId', null] },
 						then: 'repost',
 						else: {
 							$cond: {
-								if: { $ne: ['$reply_id', null] },
+								if: { $ne: ['$replyId', null] },
 								then: 'reply',
 								else: 'post'
 							}
diff --git a/src/server/api/endpoints/aggregation/posts/reaction.ts b/src/server/api/endpoints/aggregation/posts/reaction.ts
index eb99b9d08..9f9a4f37e 100644
--- a/src/server/api/endpoints/aggregation/posts/reaction.ts
+++ b/src/server/api/endpoints/aggregation/posts/reaction.ts
@@ -12,9 +12,9 @@ import Reaction from '../../../models/post-reaction';
  * @return {Promise<any>}
  */
 module.exports = (params) => new Promise(async (res, rej) => {
-	// Get 'post_id' parameter
-	const [postId, postIdErr] = $(params.post_id).id().$;
-	if (postIdErr) return rej('invalid post_id param');
+	// Get 'postId' parameter
+	const [postId, postIdErr] = $(params.postId).id().$;
+	if (postIdErr) return rej('invalid postId param');
 
 	// Lookup post
 	const post = await Post.findOne({
@@ -27,15 +27,15 @@ module.exports = (params) => new Promise(async (res, rej) => {
 
 	const datas = await Reaction
 		.aggregate([
-			{ $match: { post_id: post._id } },
+			{ $match: { postId: post._id } },
 			{ $project: {
-				created_at: { $add: ['$created_at', 9 * 60 * 60 * 1000] } // Convert into JST
+				createdAt: { $add: ['$createdAt', 9 * 60 * 60 * 1000] } // Convert into JST
 			}},
 			{ $project: {
 				date: {
-					year: { $year: '$created_at' },
-					month: { $month: '$created_at' },
-					day: { $dayOfMonth: '$created_at' }
+					year: { $year: '$createdAt' },
+					month: { $month: '$createdAt' },
+					day: { $dayOfMonth: '$createdAt' }
 				}
 			}},
 			{ $group: {
diff --git a/src/server/api/endpoints/aggregation/posts/reactions.ts b/src/server/api/endpoints/aggregation/posts/reactions.ts
index 790b523be..2dc989281 100644
--- a/src/server/api/endpoints/aggregation/posts/reactions.ts
+++ b/src/server/api/endpoints/aggregation/posts/reactions.ts
@@ -12,9 +12,9 @@ import Reaction from '../../../models/post-reaction';
  * @return {Promise<any>}
  */
 module.exports = (params) => new Promise(async (res, rej) => {
-	// Get 'post_id' parameter
-	const [postId, postIdErr] = $(params.post_id).id().$;
-	if (postIdErr) return rej('invalid post_id param');
+	// Get 'postId' parameter
+	const [postId, postIdErr] = $(params.postId).id().$;
+	if (postIdErr) return rej('invalid postId param');
 
 	// Lookup post
 	const post = await Post.findOne({
@@ -29,10 +29,10 @@ module.exports = (params) => new Promise(async (res, rej) => {
 
 	const reactions = await Reaction
 		.find({
-			post_id: post._id,
+			postId: post._id,
 			$or: [
-				{ deleted_at: { $exists: false } },
-				{ deleted_at: { $gt: startTime } }
+				{ deletedAt: { $exists: false } },
+				{ deletedAt: { $gt: startTime } }
 			]
 		}, {
 			sort: {
@@ -40,7 +40,7 @@ module.exports = (params) => new Promise(async (res, rej) => {
 			},
 			fields: {
 				_id: false,
-				post_id: false
+				postId: false
 			}
 		});
 
@@ -55,7 +55,7 @@ module.exports = (params) => new Promise(async (res, rej) => {
 		// day = day.getTime();
 
 		const count = reactions.filter(r =>
-			r.created_at < day && (r.deleted_at == null || r.deleted_at > day)
+			r.createdAt < day && (r.deletedAt == null || r.deletedAt > day)
 		).length;
 
 		graph.push({
diff --git a/src/server/api/endpoints/aggregation/posts/reply.ts b/src/server/api/endpoints/aggregation/posts/reply.ts
index b114c34e1..3b050582a 100644
--- a/src/server/api/endpoints/aggregation/posts/reply.ts
+++ b/src/server/api/endpoints/aggregation/posts/reply.ts
@@ -11,9 +11,9 @@ import Post from '../../../models/post';
  * @return {Promise<any>}
  */
 module.exports = (params) => new Promise(async (res, rej) => {
-	// Get 'post_id' parameter
-	const [postId, postIdErr] = $(params.post_id).id().$;
-	if (postIdErr) return rej('invalid post_id param');
+	// Get 'postId' parameter
+	const [postId, postIdErr] = $(params.postId).id().$;
+	if (postIdErr) return rej('invalid postId param');
 
 	// Lookup post
 	const post = await Post.findOne({
@@ -28,13 +28,13 @@ module.exports = (params) => new Promise(async (res, rej) => {
 		.aggregate([
 			{ $match: { reply: post._id } },
 			{ $project: {
-				created_at: { $add: ['$created_at', 9 * 60 * 60 * 1000] } // Convert into JST
+				createdAt: { $add: ['$createdAt', 9 * 60 * 60 * 1000] } // Convert into JST
 			}},
 			{ $project: {
 				date: {
-					year: { $year: '$created_at' },
-					month: { $month: '$created_at' },
-					day: { $dayOfMonth: '$created_at' }
+					year: { $year: '$createdAt' },
+					month: { $month: '$createdAt' },
+					day: { $dayOfMonth: '$createdAt' }
 				}
 			}},
 			{ $group: {
diff --git a/src/server/api/endpoints/aggregation/posts/repost.ts b/src/server/api/endpoints/aggregation/posts/repost.ts
index 217159caa..d9f3e36a0 100644
--- a/src/server/api/endpoints/aggregation/posts/repost.ts
+++ b/src/server/api/endpoints/aggregation/posts/repost.ts
@@ -11,9 +11,9 @@ import Post from '../../../models/post';
  * @return {Promise<any>}
  */
 module.exports = (params) => new Promise(async (res, rej) => {
-	// Get 'post_id' parameter
-	const [postId, postIdErr] = $(params.post_id).id().$;
-	if (postIdErr) return rej('invalid post_id param');
+	// Get 'postId' parameter
+	const [postId, postIdErr] = $(params.postId).id().$;
+	if (postIdErr) return rej('invalid postId param');
 
 	// Lookup post
 	const post = await Post.findOne({
@@ -26,15 +26,15 @@ module.exports = (params) => new Promise(async (res, rej) => {
 
 	const datas = await Post
 		.aggregate([
-			{ $match: { repost_id: post._id } },
+			{ $match: { repostId: post._id } },
 			{ $project: {
-				created_at: { $add: ['$created_at', 9 * 60 * 60 * 1000] } // Convert into JST
+				createdAt: { $add: ['$createdAt', 9 * 60 * 60 * 1000] } // Convert into JST
 			}},
 			{ $project: {
 				date: {
-					year: { $year: '$created_at' },
-					month: { $month: '$created_at' },
-					day: { $dayOfMonth: '$created_at' }
+					year: { $year: '$createdAt' },
+					month: { $month: '$createdAt' },
+					day: { $dayOfMonth: '$createdAt' }
 				}
 			}},
 			{ $group: {
diff --git a/src/server/api/endpoints/aggregation/users.ts b/src/server/api/endpoints/aggregation/users.ts
index e38ce92ff..a4e91a228 100644
--- a/src/server/api/endpoints/aggregation/users.ts
+++ b/src/server/api/endpoints/aggregation/users.ts
@@ -22,8 +22,8 @@ module.exports = params => new Promise(async (res, rej) => {
 			},
 			fields: {
 				_id: false,
-				created_at: true,
-				deleted_at: true
+				createdAt: true,
+				deletedAt: true
 			}
 		});
 
@@ -44,11 +44,11 @@ module.exports = params => new Promise(async (res, rej) => {
 		// day = day.getTime();
 
 		const total = users.filter(u =>
-			u.created_at < dayEnd && (u.deleted_at == null || u.deleted_at > dayEnd)
+			u.createdAt < dayEnd && (u.deletedAt == null || u.deletedAt > dayEnd)
 		).length;
 
 		const created = users.filter(u =>
-			u.created_at < dayEnd && u.created_at > dayStart
+			u.createdAt < dayEnd && u.createdAt > dayStart
 		).length;
 
 		graph.push({
diff --git a/src/server/api/endpoints/aggregation/users/activity.ts b/src/server/api/endpoints/aggregation/users/activity.ts
index 102a71d7c..d47761657 100644
--- a/src/server/api/endpoints/aggregation/users/activity.ts
+++ b/src/server/api/endpoints/aggregation/users/activity.ts
@@ -18,9 +18,9 @@ module.exports = (params) => new Promise(async (res, rej) => {
 	const [limit = 365, limitErr] = $(params.limit).optional.number().range(1, 365).$;
 	if (limitErr) return rej('invalid limit param');
 
-	// Get 'user_id' parameter
-	const [userId, userIdErr] = $(params.user_id).id().$;
-	if (userIdErr) return rej('invalid user_id param');
+	// Get 'userId' parameter
+	const [userId, userIdErr] = $(params.userId).id().$;
+	if (userIdErr) return rej('invalid userId param');
 
 	// Lookup user
 	const user = await User.findOne({
@@ -37,25 +37,25 @@ module.exports = (params) => new Promise(async (res, rej) => {
 
 	const datas = await Post
 		.aggregate([
-			{ $match: { user_id: user._id } },
+			{ $match: { userId: user._id } },
 			{ $project: {
-				repost_id: '$repost_id',
-				reply_id: '$reply_id',
-				created_at: { $add: ['$created_at', 9 * 60 * 60 * 1000] } // Convert into JST
+				repostId: '$repostId',
+				replyId: '$replyId',
+				createdAt: { $add: ['$createdAt', 9 * 60 * 60 * 1000] } // Convert into JST
 			}},
 			{ $project: {
 				date: {
-					year: { $year: '$created_at' },
-					month: { $month: '$created_at' },
-					day: { $dayOfMonth: '$created_at' }
+					year: { $year: '$createdAt' },
+					month: { $month: '$createdAt' },
+					day: { $dayOfMonth: '$createdAt' }
 				},
 				type: {
 					$cond: {
-						if: { $ne: ['$repost_id', null] },
+						if: { $ne: ['$repostId', null] },
 						then: 'repost',
 						else: {
 							$cond: {
-								if: { $ne: ['$reply_id', null] },
+								if: { $ne: ['$replyId', null] },
 								then: 'reply',
 								else: 'post'
 							}
diff --git a/src/server/api/endpoints/aggregation/users/followers.ts b/src/server/api/endpoints/aggregation/users/followers.ts
index 3022b2b00..73a30281b 100644
--- a/src/server/api/endpoints/aggregation/users/followers.ts
+++ b/src/server/api/endpoints/aggregation/users/followers.ts
@@ -12,9 +12,9 @@ import Following from '../../../models/following';
  * @return {Promise<any>}
  */
 module.exports = (params) => new Promise(async (res, rej) => {
-	// Get 'user_id' parameter
-	const [userId, userIdErr] = $(params.user_id).id().$;
-	if (userIdErr) return rej('invalid user_id param');
+	// Get 'userId' parameter
+	const [userId, userIdErr] = $(params.userId).id().$;
+	if (userIdErr) return rej('invalid userId param');
 
 	// Lookup user
 	const user = await User.findOne({
@@ -33,17 +33,17 @@ module.exports = (params) => new Promise(async (res, rej) => {
 
 	const following = await Following
 		.find({
-			followee_id: user._id,
+			followeeId: user._id,
 			$or: [
-				{ deleted_at: { $exists: false } },
-				{ deleted_at: { $gt: startTime } }
+				{ deletedAt: { $exists: false } },
+				{ deletedAt: { $gt: startTime } }
 			]
 		}, {
 			_id: false,
-			follower_id: false,
-			followee_id: false
+			followerId: false,
+			followeeId: false
 		}, {
-			sort: { created_at: -1 }
+			sort: { createdAt: -1 }
 		});
 
 	const graph = [];
@@ -57,7 +57,7 @@ module.exports = (params) => new Promise(async (res, rej) => {
 		// day = day.getTime();
 
 		const count = following.filter(f =>
-			f.created_at < day && (f.deleted_at == null || f.deleted_at > day)
+			f.createdAt < day && (f.deletedAt == null || f.deletedAt > day)
 		).length;
 
 		graph.push({
diff --git a/src/server/api/endpoints/aggregation/users/following.ts b/src/server/api/endpoints/aggregation/users/following.ts
index 92da7e692..16fc568d5 100644
--- a/src/server/api/endpoints/aggregation/users/following.ts
+++ b/src/server/api/endpoints/aggregation/users/following.ts
@@ -12,9 +12,9 @@ import Following from '../../../models/following';
  * @return {Promise<any>}
  */
 module.exports = (params) => new Promise(async (res, rej) => {
-	// Get 'user_id' parameter
-	const [userId, userIdErr] = $(params.user_id).id().$;
-	if (userIdErr) return rej('invalid user_id param');
+	// Get 'userId' parameter
+	const [userId, userIdErr] = $(params.userId).id().$;
+	if (userIdErr) return rej('invalid userId param');
 
 	// Lookup user
 	const user = await User.findOne({
@@ -33,17 +33,17 @@ module.exports = (params) => new Promise(async (res, rej) => {
 
 	const following = await Following
 		.find({
-			follower_id: user._id,
+			followerId: user._id,
 			$or: [
-				{ deleted_at: { $exists: false } },
-				{ deleted_at: { $gt: startTime } }
+				{ deletedAt: { $exists: false } },
+				{ deletedAt: { $gt: startTime } }
 			]
 		}, {
 			_id: false,
-			follower_id: false,
-			followee_id: false
+			followerId: false,
+			followeeId: false
 		}, {
-			sort: { created_at: -1 }
+			sort: { createdAt: -1 }
 		});
 
 	const graph = [];
@@ -56,7 +56,7 @@ module.exports = (params) => new Promise(async (res, rej) => {
 		day = new Date(day.setHours(23));
 
 		const count = following.filter(f =>
-			f.created_at < day && (f.deleted_at == null || f.deleted_at > day)
+			f.createdAt < day && (f.deletedAt == null || f.deletedAt > day)
 		).length;
 
 		graph.push({
diff --git a/src/server/api/endpoints/aggregation/users/post.ts b/src/server/api/endpoints/aggregation/users/post.ts
index c6a75eee3..c98874859 100644
--- a/src/server/api/endpoints/aggregation/users/post.ts
+++ b/src/server/api/endpoints/aggregation/users/post.ts
@@ -12,9 +12,9 @@ import Post from '../../../models/post';
  * @return {Promise<any>}
  */
 module.exports = (params) => new Promise(async (res, rej) => {
-	// Get 'user_id' parameter
-	const [userId, userIdErr] = $(params.user_id).id().$;
-	if (userIdErr) return rej('invalid user_id param');
+	// Get 'userId' parameter
+	const [userId, userIdErr] = $(params.userId).id().$;
+	if (userIdErr) return rej('invalid userId param');
 
 	// Lookup user
 	const user = await User.findOne({
@@ -31,25 +31,25 @@ module.exports = (params) => new Promise(async (res, rej) => {
 
 	const datas = await Post
 		.aggregate([
-			{ $match: { user_id: user._id } },
+			{ $match: { userId: user._id } },
 			{ $project: {
-				repost_id: '$repost_id',
-				reply_id: '$reply_id',
-				created_at: { $add: ['$created_at', 9 * 60 * 60 * 1000] } // Convert into JST
+				repostId: '$repostId',
+				replyId: '$replyId',
+				createdAt: { $add: ['$createdAt', 9 * 60 * 60 * 1000] } // Convert into JST
 			}},
 			{ $project: {
 				date: {
-					year: { $year: '$created_at' },
-					month: { $month: '$created_at' },
-					day: { $dayOfMonth: '$created_at' }
+					year: { $year: '$createdAt' },
+					month: { $month: '$createdAt' },
+					day: { $dayOfMonth: '$createdAt' }
 				},
 				type: {
 					$cond: {
-						if: { $ne: ['$repost_id', null] },
+						if: { $ne: ['$repostId', null] },
 						then: 'repost',
 						else: {
 							$cond: {
-								if: { $ne: ['$reply_id', null] },
+								if: { $ne: ['$replyId', null] },
 								then: 'reply',
 								else: 'post'
 							}
diff --git a/src/server/api/endpoints/aggregation/users/reaction.ts b/src/server/api/endpoints/aggregation/users/reaction.ts
index 0a082ed1b..60b33e9d1 100644
--- a/src/server/api/endpoints/aggregation/users/reaction.ts
+++ b/src/server/api/endpoints/aggregation/users/reaction.ts
@@ -12,9 +12,9 @@ import Reaction from '../../../models/post-reaction';
  * @return {Promise<any>}
  */
 module.exports = (params) => new Promise(async (res, rej) => {
-	// Get 'user_id' parameter
-	const [userId, userIdErr] = $(params.user_id).id().$;
-	if (userIdErr) return rej('invalid user_id param');
+	// Get 'userId' parameter
+	const [userId, userIdErr] = $(params.userId).id().$;
+	if (userIdErr) return rej('invalid userId param');
 
 	// Lookup user
 	const user = await User.findOne({
@@ -31,15 +31,15 @@ module.exports = (params) => new Promise(async (res, rej) => {
 
 	const datas = await Reaction
 		.aggregate([
-			{ $match: { user_id: user._id } },
+			{ $match: { userId: user._id } },
 			{ $project: {
-				created_at: { $add: ['$created_at', 9 * 60 * 60 * 1000] } // Convert into JST
+				createdAt: { $add: ['$createdAt', 9 * 60 * 60 * 1000] } // Convert into JST
 			}},
 			{ $project: {
 				date: {
-					year: { $year: '$created_at' },
-					month: { $month: '$created_at' },
-					day: { $dayOfMonth: '$created_at' }
+					year: { $year: '$createdAt' },
+					month: { $month: '$createdAt' },
+					day: { $dayOfMonth: '$createdAt' }
 				}
 			}},
 			{ $group: {
diff --git a/src/server/api/endpoints/app/create.ts b/src/server/api/endpoints/app/create.ts
index 0f688792a..713078463 100644
--- a/src/server/api/endpoints/app/create.ts
+++ b/src/server/api/endpoints/app/create.ts
@@ -13,7 +13,7 @@ import App, { isValidNameId, pack } from '../../models/app';
  *     parameters:
  *       - $ref: "#/parameters/AccessToken"
  *       -
- *         name: name_id
+ *         name: nameId
  *         description: Application unique name
  *         in: formData
  *         required: true
@@ -40,7 +40,7 @@ import App, { isValidNameId, pack } from '../../models/app';
  *           type: string
  *           collectionFormat: csv
  *       -
- *         name: callback_url
+ *         name: callbackUrl
  *         description: URL called back after authentication
  *         in: formData
  *         required: false
@@ -66,9 +66,9 @@ import App, { isValidNameId, pack } from '../../models/app';
  * @return {Promise<any>}
  */
 module.exports = async (params, user) => new Promise(async (res, rej) => {
-	// Get 'name_id' parameter
-	const [nameId, nameIdErr] = $(params.name_id).string().pipe(isValidNameId).$;
-	if (nameIdErr) return rej('invalid name_id param');
+	// Get 'nameId' parameter
+	const [nameId, nameIdErr] = $(params.nameId).string().pipe(isValidNameId).$;
+	if (nameIdErr) return rej('invalid nameId param');
 
 	// Get 'name' parameter
 	const [name, nameErr] = $(params.name).string().$;
@@ -82,24 +82,24 @@ module.exports = async (params, user) => new Promise(async (res, rej) => {
 	const [permission, permissionErr] = $(params.permission).array('string').unique().$;
 	if (permissionErr) return rej('invalid permission param');
 
-	// Get 'callback_url' parameter
+	// Get 'callbackUrl' parameter
 	// TODO: Check it is valid url
-	const [callbackUrl = null, callbackUrlErr] = $(params.callback_url).optional.nullable.string().$;
-	if (callbackUrlErr) return rej('invalid callback_url param');
+	const [callbackUrl = null, callbackUrlErr] = $(params.callbackUrl).optional.nullable.string().$;
+	if (callbackUrlErr) return rej('invalid callbackUrl param');
 
 	// Generate secret
 	const secret = rndstr('a-zA-Z0-9', 32);
 
 	// Create account
 	const app = await App.insert({
-		created_at: new Date(),
-		user_id: user._id,
+		createdAt: new Date(),
+		userId: user._id,
 		name: name,
-		name_id: nameId,
-		name_id_lower: nameId.toLowerCase(),
+		nameId: nameId,
+		nameIdLower: nameId.toLowerCase(),
 		description: description,
 		permission: permission,
-		callback_url: callbackUrl,
+		callbackUrl: callbackUrl,
 		secret: secret
 	});
 
diff --git a/src/server/api/endpoints/app/name_id/available.ts b/src/server/api/endpoints/app/name_id/available.ts
index 3d2c71032..6d02b26d2 100644
--- a/src/server/api/endpoints/app/name_id/available.ts
+++ b/src/server/api/endpoints/app/name_id/available.ts
@@ -7,12 +7,12 @@ import { isValidNameId } from '../../../models/app';
 
 /**
  * @swagger
- * /app/name_id/available:
+ * /app/nameId/available:
  *   post:
- *     summary: Check available name_id on creation an application
+ *     summary: Check available nameId on creation an application
  *     parameters:
  *       -
- *         name: name_id
+ *         name: nameId
  *         description: Application unique name
  *         in: formData
  *         required: true
@@ -25,7 +25,7 @@ import { isValidNameId } from '../../../models/app';
  *           type: object
  *           properties:
  *             available:
- *               description: Whether name_id is available
+ *               description: Whether nameId is available
  *               type: boolean
  *
  *       default:
@@ -35,20 +35,20 @@ import { isValidNameId } from '../../../models/app';
  */
 
 /**
- * Check available name_id of app
+ * Check available nameId of app
  *
  * @param {any} params
  * @return {Promise<any>}
  */
 module.exports = async (params) => new Promise(async (res, rej) => {
-	// Get 'name_id' parameter
-	const [nameId, nameIdErr] = $(params.name_id).string().pipe(isValidNameId).$;
-	if (nameIdErr) return rej('invalid name_id param');
+	// Get 'nameId' parameter
+	const [nameId, nameIdErr] = $(params.nameId).string().pipe(isValidNameId).$;
+	if (nameIdErr) return rej('invalid nameId param');
 
 	// Get exist
 	const exist = await App
 		.count({
-			name_id_lower: nameId.toLowerCase()
+			nameIdLower: nameId.toLowerCase()
 		}, {
 			limit: 1
 		});
diff --git a/src/server/api/endpoints/app/show.ts b/src/server/api/endpoints/app/show.ts
index 8bc3dda42..34bb958ee 100644
--- a/src/server/api/endpoints/app/show.ts
+++ b/src/server/api/endpoints/app/show.ts
@@ -9,15 +9,15 @@ import App, { pack } from '../../models/app';
  * /app/show:
  *   post:
  *     summary: Show an application's information
- *     description: Require app_id or name_id
+ *     description: Require appId or nameId
  *     parameters:
  *       -
- *         name: app_id
+ *         name: appId
  *         description: Application ID
  *         in: formData
  *         type: string
  *       -
- *         name: name_id
+ *         name: nameId
  *         description: Application unique name
  *         in: formData
  *         type: string
@@ -44,22 +44,22 @@ import App, { pack } from '../../models/app';
  * @return {Promise<any>}
  */
 module.exports = (params, user, _, isSecure) => new Promise(async (res, rej) => {
-	// Get 'app_id' parameter
-	const [appId, appIdErr] = $(params.app_id).optional.id().$;
-	if (appIdErr) return rej('invalid app_id param');
+	// Get 'appId' parameter
+	const [appId, appIdErr] = $(params.appId).optional.id().$;
+	if (appIdErr) return rej('invalid appId param');
 
-	// Get 'name_id' parameter
-	const [nameId, nameIdErr] = $(params.name_id).optional.string().$;
-	if (nameIdErr) return rej('invalid name_id param');
+	// Get 'nameId' parameter
+	const [nameId, nameIdErr] = $(params.nameId).optional.string().$;
+	if (nameIdErr) return rej('invalid nameId param');
 
 	if (appId === undefined && nameId === undefined) {
-		return rej('app_id or name_id is required');
+		return rej('appId or nameId is required');
 	}
 
 	// Lookup app
 	const app = appId !== undefined
 		? await App.findOne({ _id: appId })
-		: await App.findOne({ name_id_lower: nameId.toLowerCase() });
+		: await App.findOne({ nameIdLower: nameId.toLowerCase() });
 
 	if (app === null) {
 		return rej('app not found');
@@ -67,6 +67,6 @@ module.exports = (params, user, _, isSecure) => new Promise(async (res, rej) =>
 
 	// Send response
 	res(await pack(app, user, {
-		includeSecret: isSecure && app.user_id.equals(user._id)
+		includeSecret: isSecure && app.userId.equals(user._id)
 	}));
 });
diff --git a/src/server/api/endpoints/auth/accept.ts b/src/server/api/endpoints/auth/accept.ts
index 4ee20a6d2..5a1925144 100644
--- a/src/server/api/endpoints/auth/accept.ts
+++ b/src/server/api/endpoints/auth/accept.ts
@@ -56,14 +56,14 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 
 	// Fetch exist access token
 	const exist = await AccessToken.findOne({
-		app_id: session.app_id,
-		user_id: user._id,
+		appId: session.appId,
+		userId: user._id,
 	});
 
 	if (exist === null) {
 		// Lookup app
 		const app = await App.findOne({
-			_id: session.app_id
+			_id: session.appId
 		});
 
 		// Generate Hash
@@ -73,9 +73,9 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 
 		// Insert access token doc
 		await AccessToken.insert({
-			created_at: new Date(),
-			app_id: session.app_id,
-			user_id: user._id,
+			createdAt: new Date(),
+			appId: session.appId,
+			userId: user._id,
 			token: accessToken,
 			hash: hash
 		});
@@ -84,7 +84,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Update session
 	await AuthSess.update(session._id, {
 		$set: {
-			user_id: user._id
+			userId: user._id
 		}
 	});
 
diff --git a/src/server/api/endpoints/auth/session/generate.ts b/src/server/api/endpoints/auth/session/generate.ts
index dc6a045b6..180ad83cc 100644
--- a/src/server/api/endpoints/auth/session/generate.ts
+++ b/src/server/api/endpoints/auth/session/generate.ts
@@ -14,7 +14,7 @@ import config from '../../../../../conf';
  *     summary: Generate a session
  *     parameters:
  *       -
- *         name: app_secret
+ *         name: appSecret
  *         description: App Secret
  *         in: formData
  *         required: true
@@ -45,9 +45,9 @@ import config from '../../../../../conf';
  * @return {Promise<any>}
  */
 module.exports = (params) => new Promise(async (res, rej) => {
-	// Get 'app_secret' parameter
-	const [appSecret, appSecretErr] = $(params.app_secret).string().$;
-	if (appSecretErr) return rej('invalid app_secret param');
+	// Get 'appSecret' parameter
+	const [appSecret, appSecretErr] = $(params.appSecret).string().$;
+	if (appSecretErr) return rej('invalid appSecret param');
 
 	// Lookup app
 	const app = await App.findOne({
@@ -63,8 +63,8 @@ module.exports = (params) => new Promise(async (res, rej) => {
 
 	// Create session token document
 	const doc = await AuthSess.insert({
-		created_at: new Date(),
-		app_id: app._id,
+		createdAt: new Date(),
+		appId: app._id,
 		token: token
 	});
 
diff --git a/src/server/api/endpoints/auth/session/show.ts b/src/server/api/endpoints/auth/session/show.ts
index 73ac3185f..869b714e7 100644
--- a/src/server/api/endpoints/auth/session/show.ts
+++ b/src/server/api/endpoints/auth/session/show.ts
@@ -23,17 +23,17 @@ import AuthSess, { pack } from '../../../models/auth-session';
  *         schema:
  *           type: object
  *           properties:
- *             created_at:
+ *             createdAt:
  *               type: string
  *               format: date-time
  *               description: Date and time of the session creation
- *             app_id:
+ *             appId:
  *               type: string
  *               description: Application ID
  *             token:
  *               type: string
  *               description: Session Token
- *             user_id:
+ *             userId:
  *               type: string
  *               description: ID of user who create the session
  *             app:
diff --git a/src/server/api/endpoints/auth/session/userkey.ts b/src/server/api/endpoints/auth/session/userkey.ts
index fc989bf8c..5d9983af6 100644
--- a/src/server/api/endpoints/auth/session/userkey.ts
+++ b/src/server/api/endpoints/auth/session/userkey.ts
@@ -14,7 +14,7 @@ import { pack } from '../../../models/user';
  *     summary: Get an access token(userkey)
  *     parameters:
  *       -
- *         name: app_secret
+ *         name: appSecret
  *         description: App Secret
  *         in: formData
  *         required: true
@@ -50,9 +50,9 @@ import { pack } from '../../../models/user';
  * @return {Promise<any>}
  */
 module.exports = (params) => new Promise(async (res, rej) => {
-	// Get 'app_secret' parameter
-	const [appSecret, appSecretErr] = $(params.app_secret).string().$;
-	if (appSecretErr) return rej('invalid app_secret param');
+	// Get 'appSecret' parameter
+	const [appSecret, appSecretErr] = $(params.appSecret).string().$;
+	if (appSecretErr) return rej('invalid appSecret param');
 
 	// Lookup app
 	const app = await App.findOne({
@@ -71,21 +71,21 @@ module.exports = (params) => new Promise(async (res, rej) => {
 	const session = await AuthSess
 		.findOne({
 			token: token,
-			app_id: app._id
+			appId: app._id
 		});
 
 	if (session === null) {
 		return rej('session not found');
 	}
 
-	if (session.user_id == null) {
+	if (session.userId == null) {
 		return rej('this session is not allowed yet');
 	}
 
 	// Lookup access token
 	const accessToken = await AccessToken.findOne({
-		app_id: app._id,
-		user_id: session.user_id
+		appId: app._id,
+		userId: session.userId
 	});
 
 	// Delete session
@@ -101,8 +101,8 @@ module.exports = (params) => new Promise(async (res, rej) => {
 
 	// Response
 	res({
-		access_token: accessToken.token,
-		user: await pack(session.user_id, null, {
+		accessToken: accessToken.token,
+		user: await pack(session.userId, null, {
 			detail: true
 		})
 	});
diff --git a/src/server/api/endpoints/channels.ts b/src/server/api/endpoints/channels.ts
index b9a7d1b78..a4acc0660 100644
--- a/src/server/api/endpoints/channels.ts
+++ b/src/server/api/endpoints/channels.ts
@@ -16,17 +16,17 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
 	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
 	if (limitErr) return rej('invalid limit param');
 
-	// Get 'since_id' parameter
-	const [sinceId, sinceIdErr] = $(params.since_id).optional.id().$;
-	if (sinceIdErr) return rej('invalid since_id param');
+	// Get 'sinceId' parameter
+	const [sinceId, sinceIdErr] = $(params.sinceId).optional.id().$;
+	if (sinceIdErr) return rej('invalid sinceId param');
 
-	// Get 'until_id' parameter
-	const [untilId, untilIdErr] = $(params.until_id).optional.id().$;
-	if (untilIdErr) return rej('invalid until_id param');
+	// Get 'untilId' parameter
+	const [untilId, untilIdErr] = $(params.untilId).optional.id().$;
+	if (untilIdErr) return rej('invalid untilId param');
 
-	// Check if both of since_id and until_id is specified
+	// Check if both of sinceId and untilId is specified
 	if (sinceId && untilId) {
-		return rej('cannot set since_id and until_id');
+		return rej('cannot set sinceId and untilId');
 	}
 
 	// Construct query
diff --git a/src/server/api/endpoints/channels/create.ts b/src/server/api/endpoints/channels/create.ts
index 695b4515b..1dc453c4a 100644
--- a/src/server/api/endpoints/channels/create.ts
+++ b/src/server/api/endpoints/channels/create.ts
@@ -20,11 +20,11 @@ module.exports = async (params, user) => new Promise(async (res, rej) => {
 
 	// Create a channel
 	const channel = await Channel.insert({
-		created_at: new Date(),
-		user_id: user._id,
+		createdAt: new Date(),
+		userId: user._id,
 		title: title,
 		index: 0,
-		watching_count: 1
+		watchingCount: 1
 	});
 
 	// Response
@@ -32,8 +32,8 @@ module.exports = async (params, user) => new Promise(async (res, rej) => {
 
 	// Create Watching
 	await Watching.insert({
-		created_at: new Date(),
-		user_id: user._id,
-		channel_id: channel._id
+		createdAt: new Date(),
+		userId: user._id,
+		channelId: channel._id
 	});
 });
diff --git a/src/server/api/endpoints/channels/posts.ts b/src/server/api/endpoints/channels/posts.ts
index d722589c2..348dbb108 100644
--- a/src/server/api/endpoints/channels/posts.ts
+++ b/src/server/api/endpoints/channels/posts.ts
@@ -17,22 +17,22 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	const [limit = 1000, limitErr] = $(params.limit).optional.number().range(1, 1000).$;
 	if (limitErr) return rej('invalid limit param');
 
-	// Get 'since_id' parameter
-	const [sinceId, sinceIdErr] = $(params.since_id).optional.id().$;
-	if (sinceIdErr) return rej('invalid since_id param');
+	// Get 'sinceId' parameter
+	const [sinceId, sinceIdErr] = $(params.sinceId).optional.id().$;
+	if (sinceIdErr) return rej('invalid sinceId param');
 
-	// Get 'until_id' parameter
-	const [untilId, untilIdErr] = $(params.until_id).optional.id().$;
-	if (untilIdErr) return rej('invalid until_id param');
+	// Get 'untilId' parameter
+	const [untilId, untilIdErr] = $(params.untilId).optional.id().$;
+	if (untilIdErr) return rej('invalid untilId param');
 
-	// Check if both of since_id and until_id is specified
+	// Check if both of sinceId and untilId is specified
 	if (sinceId && untilId) {
-		return rej('cannot set since_id and until_id');
+		return rej('cannot set sinceId and untilId');
 	}
 
-	// Get 'channel_id' parameter
-	const [channelId, channelIdErr] = $(params.channel_id).id().$;
-	if (channelIdErr) return rej('invalid channel_id param');
+	// Get 'channelId' parameter
+	const [channelId, channelIdErr] = $(params.channelId).id().$;
+	if (channelIdErr) return rej('invalid channelId param');
 
 	// Fetch channel
 	const channel: IChannel = await Channel.findOne({
@@ -49,7 +49,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	};
 
 	const query = {
-		channel_id: channel._id
+		channelId: channel._id
 	} as any;
 
 	if (sinceId) {
diff --git a/src/server/api/endpoints/channels/show.ts b/src/server/api/endpoints/channels/show.ts
index 332da6467..5874ed18a 100644
--- a/src/server/api/endpoints/channels/show.ts
+++ b/src/server/api/endpoints/channels/show.ts
@@ -12,9 +12,9 @@ import Channel, { IChannel, pack } from '../../models/channel';
  * @return {Promise<any>}
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
-	// Get 'channel_id' parameter
-	const [channelId, channelIdErr] = $(params.channel_id).id().$;
-	if (channelIdErr) return rej('invalid channel_id param');
+	// Get 'channelId' parameter
+	const [channelId, channelIdErr] = $(params.channelId).id().$;
+	if (channelIdErr) return rej('invalid channelId param');
 
 	// Fetch channel
 	const channel: IChannel = await Channel.findOne({
diff --git a/src/server/api/endpoints/channels/unwatch.ts b/src/server/api/endpoints/channels/unwatch.ts
index 19d3be118..709313bc6 100644
--- a/src/server/api/endpoints/channels/unwatch.ts
+++ b/src/server/api/endpoints/channels/unwatch.ts
@@ -13,9 +13,9 @@ import Watching from '../../models/channel-watching';
  * @return {Promise<any>}
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
-	// Get 'channel_id' parameter
-	const [channelId, channelIdErr] = $(params.channel_id).id().$;
-	if (channelIdErr) return rej('invalid channel_id param');
+	// Get 'channelId' parameter
+	const [channelId, channelIdErr] = $(params.channelId).id().$;
+	if (channelIdErr) return rej('invalid channelId param');
 
 	//#region Fetch channel
 	const channel = await Channel.findOne({
@@ -29,9 +29,9 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 
 	//#region Check whether not watching
 	const exist = await Watching.findOne({
-		user_id: user._id,
-		channel_id: channel._id,
-		deleted_at: { $exists: false }
+		userId: user._id,
+		channelId: channel._id,
+		deletedAt: { $exists: false }
 	});
 
 	if (exist === null) {
@@ -44,7 +44,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 		_id: exist._id
 	}, {
 		$set: {
-			deleted_at: new Date()
+			deletedAt: new Date()
 		}
 	});
 
@@ -54,7 +54,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Decrement watching count
 	Channel.update(channel._id, {
 		$inc: {
-			watching_count: -1
+			watchingCount: -1
 		}
 	});
 });
diff --git a/src/server/api/endpoints/channels/watch.ts b/src/server/api/endpoints/channels/watch.ts
index 030e0dd41..df9e70d5c 100644
--- a/src/server/api/endpoints/channels/watch.ts
+++ b/src/server/api/endpoints/channels/watch.ts
@@ -13,9 +13,9 @@ import Watching from '../../models/channel-watching';
  * @return {Promise<any>}
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
-	// Get 'channel_id' parameter
-	const [channelId, channelIdErr] = $(params.channel_id).id().$;
-	if (channelIdErr) return rej('invalid channel_id param');
+	// Get 'channelId' parameter
+	const [channelId, channelIdErr] = $(params.channelId).id().$;
+	if (channelIdErr) return rej('invalid channelId param');
 
 	//#region Fetch channel
 	const channel = await Channel.findOne({
@@ -29,9 +29,9 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 
 	//#region Check whether already watching
 	const exist = await Watching.findOne({
-		user_id: user._id,
-		channel_id: channel._id,
-		deleted_at: { $exists: false }
+		userId: user._id,
+		channelId: channel._id,
+		deletedAt: { $exists: false }
 	});
 
 	if (exist !== null) {
@@ -41,9 +41,9 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 
 	// Create Watching
 	await Watching.insert({
-		created_at: new Date(),
-		user_id: user._id,
-		channel_id: channel._id
+		createdAt: new Date(),
+		userId: user._id,
+		channelId: channel._id
 	});
 
 	// Send response
@@ -52,7 +52,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Increment watching count
 	Channel.update(channel._id, {
 		$inc: {
-			watching_count: 1
+			watchingCount: 1
 		}
 	});
 });
diff --git a/src/server/api/endpoints/drive.ts b/src/server/api/endpoints/drive.ts
index d92473633..eb2185391 100644
--- a/src/server/api/endpoints/drive.ts
+++ b/src/server/api/endpoints/drive.ts
@@ -14,7 +14,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Calculate drive usage
 	const usage = ((await DriveFile
 		.aggregate([
-			{ $match: { 'metadata.user_id': user._id } },
+			{ $match: { 'metadata.userId': user._id } },
 			{
 				$project: {
 					length: true
@@ -31,7 +31,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 		}).usage;
 
 	res({
-		capacity: user.drive_capacity,
+		capacity: user.driveCapacity,
 		usage: usage
 	});
 });
diff --git a/src/server/api/endpoints/drive/files.ts b/src/server/api/endpoints/drive/files.ts
index 89915331e..f982ef62e 100644
--- a/src/server/api/endpoints/drive/files.ts
+++ b/src/server/api/endpoints/drive/files.ts
@@ -17,22 +17,22 @@ module.exports = async (params, user, app) => {
 	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
 	if (limitErr) throw 'invalid limit param';
 
-	// Get 'since_id' parameter
-	const [sinceId, sinceIdErr] = $(params.since_id).optional.id().$;
-	if (sinceIdErr) throw 'invalid since_id param';
+	// Get 'sinceId' parameter
+	const [sinceId, sinceIdErr] = $(params.sinceId).optional.id().$;
+	if (sinceIdErr) throw 'invalid sinceId param';
 
-	// Get 'until_id' parameter
-	const [untilId, untilIdErr] = $(params.until_id).optional.id().$;
-	if (untilIdErr) throw 'invalid until_id param';
+	// Get 'untilId' parameter
+	const [untilId, untilIdErr] = $(params.untilId).optional.id().$;
+	if (untilIdErr) throw 'invalid untilId param';
 
-	// Check if both of since_id and until_id is specified
+	// Check if both of sinceId and untilId is specified
 	if (sinceId && untilId) {
-		throw 'cannot set since_id and until_id';
+		throw 'cannot set sinceId and untilId';
 	}
 
-	// Get 'folder_id' parameter
-	const [folderId = null, folderIdErr] = $(params.folder_id).optional.nullable.id().$;
-	if (folderIdErr) throw 'invalid folder_id param';
+	// Get 'folderId' parameter
+	const [folderId = null, folderIdErr] = $(params.folderId).optional.nullable.id().$;
+	if (folderIdErr) throw 'invalid folderId param';
 
 	// Get 'type' parameter
 	const [type, typeErr] = $(params.type).optional.string().match(/^[a-zA-Z\/\-\*]+$/).$;
@@ -43,8 +43,8 @@ module.exports = async (params, user, app) => {
 		_id: -1
 	};
 	const query = {
-		'metadata.user_id': user._id,
-		'metadata.folder_id': folderId
+		'metadata.userId': user._id,
+		'metadata.folderId': folderId
 	} as any;
 	if (sinceId) {
 		sort._id = 1;
diff --git a/src/server/api/endpoints/drive/files/create.ts b/src/server/api/endpoints/drive/files/create.ts
index db801b61f..2cd89a8fa 100644
--- a/src/server/api/endpoints/drive/files/create.ts
+++ b/src/server/api/endpoints/drive/files/create.ts
@@ -33,9 +33,9 @@ module.exports = async (file, params, user): Promise<any> => {
 		name = null;
 	}
 
-	// Get 'folder_id' parameter
-	const [folderId = null, folderIdErr] = $(params.folder_id).optional.nullable.id().$;
-	if (folderIdErr) throw 'invalid folder_id param';
+	// Get 'folderId' parameter
+	const [folderId = null, folderIdErr] = $(params.folderId).optional.nullable.id().$;
+	if (folderIdErr) throw 'invalid folderId param';
 
 	try {
 		// Create file
diff --git a/src/server/api/endpoints/drive/files/find.ts b/src/server/api/endpoints/drive/files/find.ts
index e026afe93..47ce89130 100644
--- a/src/server/api/endpoints/drive/files/find.ts
+++ b/src/server/api/endpoints/drive/files/find.ts
@@ -16,16 +16,16 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	const [name, nameErr] = $(params.name).string().$;
 	if (nameErr) return rej('invalid name param');
 
-	// Get 'folder_id' parameter
-	const [folderId = null, folderIdErr] = $(params.folder_id).optional.nullable.id().$;
-	if (folderIdErr) return rej('invalid folder_id param');
+	// Get 'folderId' parameter
+	const [folderId = null, folderIdErr] = $(params.folderId).optional.nullable.id().$;
+	if (folderIdErr) return rej('invalid folderId param');
 
 	// Issue query
 	const files = await DriveFile
 		.find({
 			filename: name,
-			'metadata.user_id': user._id,
-			'metadata.folder_id': folderId
+			'metadata.userId': user._id,
+			'metadata.folderId': folderId
 		});
 
 	// Serialize
diff --git a/src/server/api/endpoints/drive/files/show.ts b/src/server/api/endpoints/drive/files/show.ts
index 21664f7ba..63920db7f 100644
--- a/src/server/api/endpoints/drive/files/show.ts
+++ b/src/server/api/endpoints/drive/files/show.ts
@@ -12,15 +12,15 @@ import DriveFile, { pack } from '../../../models/drive-file';
  * @return {Promise<any>}
  */
 module.exports = async (params, user) => {
-	// Get 'file_id' parameter
-	const [fileId, fileIdErr] = $(params.file_id).id().$;
-	if (fileIdErr) throw 'invalid file_id param';
+	// Get 'fileId' parameter
+	const [fileId, fileIdErr] = $(params.fileId).id().$;
+	if (fileIdErr) throw 'invalid fileId param';
 
 	// Fetch file
 	const file = await DriveFile
 		.findOne({
 			_id: fileId,
-			'metadata.user_id': user._id
+			'metadata.userId': user._id
 		});
 
 	if (file === null) {
diff --git a/src/server/api/endpoints/drive/files/update.ts b/src/server/api/endpoints/drive/files/update.ts
index 83da46211..bfad45b0a 100644
--- a/src/server/api/endpoints/drive/files/update.ts
+++ b/src/server/api/endpoints/drive/files/update.ts
@@ -14,15 +14,15 @@ import { publishDriveStream } from '../../../event';
  * @return {Promise<any>}
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
-	// Get 'file_id' parameter
-	const [fileId, fileIdErr] = $(params.file_id).id().$;
-	if (fileIdErr) return rej('invalid file_id param');
+	// Get 'fileId' parameter
+	const [fileId, fileIdErr] = $(params.fileId).id().$;
+	if (fileIdErr) return rej('invalid fileId param');
 
 	// Fetch file
 	const file = await DriveFile
 		.findOne({
 			_id: fileId,
-			'metadata.user_id': user._id
+			'metadata.userId': user._id
 		});
 
 	if (file === null) {
@@ -34,33 +34,33 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	if (nameErr) return rej('invalid name param');
 	if (name) file.filename = name;
 
-	// Get 'folder_id' parameter
-	const [folderId, folderIdErr] = $(params.folder_id).optional.nullable.id().$;
-	if (folderIdErr) return rej('invalid folder_id param');
+	// Get 'folderId' parameter
+	const [folderId, folderIdErr] = $(params.folderId).optional.nullable.id().$;
+	if (folderIdErr) return rej('invalid folderId param');
 
 	if (folderId !== undefined) {
 		if (folderId === null) {
-			file.metadata.folder_id = null;
+			file.metadata.folderId = null;
 		} else {
 			// Fetch folder
 			const folder = await DriveFolder
 				.findOne({
 					_id: folderId,
-					user_id: user._id
+					userId: user._id
 				});
 
 			if (folder === null) {
 				return rej('folder-not-found');
 			}
 
-			file.metadata.folder_id = folder._id;
+			file.metadata.folderId = folder._id;
 		}
 	}
 
 	await DriveFile.update(file._id, {
 		$set: {
 			filename: file.filename,
-			'metadata.folder_id': file.metadata.folder_id
+			'metadata.folderId': file.metadata.folderId
 		}
 	});
 
diff --git a/src/server/api/endpoints/drive/files/upload_from_url.ts b/src/server/api/endpoints/drive/files/upload_from_url.ts
index 346633c61..1a4ce0bf0 100644
--- a/src/server/api/endpoints/drive/files/upload_from_url.ts
+++ b/src/server/api/endpoints/drive/files/upload_from_url.ts
@@ -18,9 +18,9 @@ module.exports = async (params, user): Promise<any> => {
 	const [url, urlErr] = $(params.url).string().$;
 	if (urlErr) throw 'invalid url param';
 
-	// Get 'folder_id' parameter
-	const [folderId = null, folderIdErr] = $(params.folder_id).optional.nullable.id().$;
-	if (folderIdErr) throw 'invalid folder_id param';
+	// Get 'folderId' parameter
+	const [folderId = null, folderIdErr] = $(params.folderId).optional.nullable.id().$;
+	if (folderIdErr) throw 'invalid folderId param';
 
 	return pack(await uploadFromUrl(url, user, folderId));
 };
diff --git a/src/server/api/endpoints/drive/folders.ts b/src/server/api/endpoints/drive/folders.ts
index 428bde350..c314837f7 100644
--- a/src/server/api/endpoints/drive/folders.ts
+++ b/src/server/api/endpoints/drive/folders.ts
@@ -17,30 +17,30 @@ module.exports = (params, user, app) => new Promise(async (res, rej) => {
 	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
 	if (limitErr) return rej('invalid limit param');
 
-	// Get 'since_id' parameter
-	const [sinceId, sinceIdErr] = $(params.since_id).optional.id().$;
-	if (sinceIdErr) return rej('invalid since_id param');
+	// Get 'sinceId' parameter
+	const [sinceId, sinceIdErr] = $(params.sinceId).optional.id().$;
+	if (sinceIdErr) return rej('invalid sinceId param');
 
-	// Get 'until_id' parameter
-	const [untilId, untilIdErr] = $(params.until_id).optional.id().$;
-	if (untilIdErr) return rej('invalid until_id param');
+	// Get 'untilId' parameter
+	const [untilId, untilIdErr] = $(params.untilId).optional.id().$;
+	if (untilIdErr) return rej('invalid untilId param');
 
-	// Check if both of since_id and until_id is specified
+	// Check if both of sinceId and untilId is specified
 	if (sinceId && untilId) {
-		return rej('cannot set since_id and until_id');
+		return rej('cannot set sinceId and untilId');
 	}
 
-	// Get 'folder_id' parameter
-	const [folderId = null, folderIdErr] = $(params.folder_id).optional.nullable.id().$;
-	if (folderIdErr) return rej('invalid folder_id param');
+	// Get 'folderId' parameter
+	const [folderId = null, folderIdErr] = $(params.folderId).optional.nullable.id().$;
+	if (folderIdErr) return rej('invalid folderId param');
 
 	// Construct query
 	const sort = {
 		_id: -1
 	};
 	const query = {
-		user_id: user._id,
-		parent_id: folderId
+		userId: user._id,
+		parentId: folderId
 	} as any;
 	if (sinceId) {
 		sort._id = 1;
diff --git a/src/server/api/endpoints/drive/folders/create.ts b/src/server/api/endpoints/drive/folders/create.ts
index 03f396ddc..564558606 100644
--- a/src/server/api/endpoints/drive/folders/create.ts
+++ b/src/server/api/endpoints/drive/folders/create.ts
@@ -17,9 +17,9 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	const [name = '無題のフォルダー', nameErr] = $(params.name).optional.string().pipe(isValidFolderName).$;
 	if (nameErr) return rej('invalid name param');
 
-	// Get 'parent_id' parameter
-	const [parentId = null, parentIdErr] = $(params.parent_id).optional.nullable.id().$;
-	if (parentIdErr) return rej('invalid parent_id param');
+	// Get 'parentId' parameter
+	const [parentId = null, parentIdErr] = $(params.parentId).optional.nullable.id().$;
+	if (parentIdErr) return rej('invalid parentId param');
 
 	// If the parent folder is specified
 	let parent = null;
@@ -28,7 +28,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 		parent = await DriveFolder
 			.findOne({
 				_id: parentId,
-				user_id: user._id
+				userId: user._id
 			});
 
 		if (parent === null) {
@@ -38,10 +38,10 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 
 	// Create folder
 	const folder = await DriveFolder.insert({
-		created_at: new Date(),
+		createdAt: new Date(),
 		name: name,
-		parent_id: parent !== null ? parent._id : null,
-		user_id: user._id
+		parentId: parent !== null ? parent._id : null,
+		userId: user._id
 	});
 
 	// Serialize
diff --git a/src/server/api/endpoints/drive/folders/find.ts b/src/server/api/endpoints/drive/folders/find.ts
index fc84766bc..f46aaedd3 100644
--- a/src/server/api/endpoints/drive/folders/find.ts
+++ b/src/server/api/endpoints/drive/folders/find.ts
@@ -16,16 +16,16 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	const [name, nameErr] = $(params.name).string().$;
 	if (nameErr) return rej('invalid name param');
 
-	// Get 'parent_id' parameter
-	const [parentId = null, parentIdErr] = $(params.parent_id).optional.nullable.id().$;
-	if (parentIdErr) return rej('invalid parent_id param');
+	// Get 'parentId' parameter
+	const [parentId = null, parentIdErr] = $(params.parentId).optional.nullable.id().$;
+	if (parentIdErr) return rej('invalid parentId param');
 
 	// Issue query
 	const folders = await DriveFolder
 		.find({
 			name: name,
-			user_id: user._id,
-			parent_id: parentId
+			userId: user._id,
+			parentId: parentId
 		});
 
 	// Serialize
diff --git a/src/server/api/endpoints/drive/folders/show.ts b/src/server/api/endpoints/drive/folders/show.ts
index e07d14d20..a6d7e86df 100644
--- a/src/server/api/endpoints/drive/folders/show.ts
+++ b/src/server/api/endpoints/drive/folders/show.ts
@@ -12,15 +12,15 @@ import DriveFolder, { pack } from '../../../models/drive-folder';
  * @return {Promise<any>}
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
-	// Get 'folder_id' parameter
-	const [folderId, folderIdErr] = $(params.folder_id).id().$;
-	if (folderIdErr) return rej('invalid folder_id param');
+	// Get 'folderId' parameter
+	const [folderId, folderIdErr] = $(params.folderId).id().$;
+	if (folderIdErr) return rej('invalid folderId param');
 
 	// Get folder
 	const folder = await DriveFolder
 		.findOne({
 			_id: folderId,
-			user_id: user._id
+			userId: user._id
 		});
 
 	if (folder === null) {
diff --git a/src/server/api/endpoints/drive/folders/update.ts b/src/server/api/endpoints/drive/folders/update.ts
index d3df8bdae..fcfd24124 100644
--- a/src/server/api/endpoints/drive/folders/update.ts
+++ b/src/server/api/endpoints/drive/folders/update.ts
@@ -13,15 +13,15 @@ import { publishDriveStream } from '../../../event';
  * @return {Promise<any>}
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
-	// Get 'folder_id' parameter
-	const [folderId, folderIdErr] = $(params.folder_id).id().$;
-	if (folderIdErr) return rej('invalid folder_id param');
+	// Get 'folderId' parameter
+	const [folderId, folderIdErr] = $(params.folderId).id().$;
+	if (folderIdErr) return rej('invalid folderId param');
 
 	// Fetch folder
 	const folder = await DriveFolder
 		.findOne({
 			_id: folderId,
-			user_id: user._id
+			userId: user._id
 		});
 
 	if (folder === null) {
@@ -33,18 +33,18 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	if (nameErr) return rej('invalid name param');
 	if (name) folder.name = name;
 
-	// Get 'parent_id' parameter
-	const [parentId, parentIdErr] = $(params.parent_id).optional.nullable.id().$;
-	if (parentIdErr) return rej('invalid parent_id param');
+	// Get 'parentId' parameter
+	const [parentId, parentIdErr] = $(params.parentId).optional.nullable.id().$;
+	if (parentIdErr) return rej('invalid parentId param');
 	if (parentId !== undefined) {
 		if (parentId === null) {
-			folder.parent_id = null;
+			folder.parentId = null;
 		} else {
 			// Get parent folder
 			const parent = await DriveFolder
 				.findOne({
 					_id: parentId,
-					user_id: user._id
+					userId: user._id
 				});
 
 			if (parent === null) {
@@ -58,25 +58,25 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 					_id: folderId
 				}, {
 					_id: true,
-					parent_id: true
+					parentId: true
 				});
 
 				if (folder2._id.equals(folder._id)) {
 					return true;
-				} else if (folder2.parent_id) {
-					return await checkCircle(folder2.parent_id);
+				} else if (folder2.parentId) {
+					return await checkCircle(folder2.parentId);
 				} else {
 					return false;
 				}
 			}
 
-			if (parent.parent_id !== null) {
-				if (await checkCircle(parent.parent_id)) {
+			if (parent.parentId !== null) {
+				if (await checkCircle(parent.parentId)) {
 					return rej('detected-circular-definition');
 				}
 			}
 
-			folder.parent_id = parent._id;
+			folder.parentId = parent._id;
 		}
 	}
 
@@ -84,7 +84,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	DriveFolder.update(folder._id, {
 		$set: {
 			name: folder.name,
-			parent_id: folder.parent_id
+			parentId: folder.parentId
 		}
 	});
 
diff --git a/src/server/api/endpoints/drive/stream.ts b/src/server/api/endpoints/drive/stream.ts
index 8352c7dd4..71db38f3b 100644
--- a/src/server/api/endpoints/drive/stream.ts
+++ b/src/server/api/endpoints/drive/stream.ts
@@ -16,17 +16,17 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
 	if (limitErr) return rej('invalid limit param');
 
-	// Get 'since_id' parameter
-	const [sinceId, sinceIdErr] = $(params.since_id).optional.id().$;
-	if (sinceIdErr) return rej('invalid since_id param');
+	// Get 'sinceId' parameter
+	const [sinceId, sinceIdErr] = $(params.sinceId).optional.id().$;
+	if (sinceIdErr) return rej('invalid sinceId param');
 
-	// Get 'until_id' parameter
-	const [untilId, untilIdErr] = $(params.until_id).optional.id().$;
-	if (untilIdErr) return rej('invalid until_id param');
+	// Get 'untilId' parameter
+	const [untilId, untilIdErr] = $(params.untilId).optional.id().$;
+	if (untilIdErr) return rej('invalid untilId param');
 
-	// Check if both of since_id and until_id is specified
+	// Check if both of sinceId and untilId is specified
 	if (sinceId && untilId) {
-		return rej('cannot set since_id and until_id');
+		return rej('cannot set sinceId and untilId');
 	}
 
 	// Get 'type' parameter
@@ -38,7 +38,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 		_id: -1
 	};
 	const query = {
-		'metadata.user_id': user._id
+		'metadata.userId': user._id
 	} as any;
 	if (sinceId) {
 		sort._id = 1;
diff --git a/src/server/api/endpoints/following/create.ts b/src/server/api/endpoints/following/create.ts
index 767b837b3..983d8040f 100644
--- a/src/server/api/endpoints/following/create.ts
+++ b/src/server/api/endpoints/following/create.ts
@@ -17,9 +17,9 @@ import event from '../../event';
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	const follower = user;
 
-	// Get 'user_id' parameter
-	const [userId, userIdErr] = $(params.user_id).id().$;
-	if (userIdErr) return rej('invalid user_id param');
+	// Get 'userId' parameter
+	const [userId, userIdErr] = $(params.userId).id().$;
+	if (userIdErr) return rej('invalid userId param');
 
 	// 自分自身
 	if (user._id.equals(userId)) {
@@ -42,9 +42,9 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 
 	// Check if already following
 	const exist = await Following.findOne({
-		follower_id: follower._id,
-		followee_id: followee._id,
-		deleted_at: { $exists: false }
+		followerId: follower._id,
+		followeeId: followee._id,
+		deletedAt: { $exists: false }
 	});
 
 	if (exist !== null) {
@@ -53,9 +53,9 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 
 	// Create following
 	await Following.insert({
-		created_at: new Date(),
-		follower_id: follower._id,
-		followee_id: followee._id
+		createdAt: new Date(),
+		followerId: follower._id,
+		followeeId: followee._id
 	});
 
 	// Send response
@@ -64,14 +64,14 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Increment following count
 	User.update(follower._id, {
 		$inc: {
-			following_count: 1
+			followingCount: 1
 		}
 	});
 
 	// Increment followers count
 	User.update({ _id: followee._id }, {
 		$inc: {
-			followers_count: 1
+			followersCount: 1
 		}
 	});
 
diff --git a/src/server/api/endpoints/following/delete.ts b/src/server/api/endpoints/following/delete.ts
index 64b9a8cec..25eba8b26 100644
--- a/src/server/api/endpoints/following/delete.ts
+++ b/src/server/api/endpoints/following/delete.ts
@@ -16,9 +16,9 @@ import event from '../../event';
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	const follower = user;
 
-	// Get 'user_id' parameter
-	const [userId, userIdErr] = $(params.user_id).id().$;
-	if (userIdErr) return rej('invalid user_id param');
+	// Get 'userId' parameter
+	const [userId, userIdErr] = $(params.userId).id().$;
+	if (userIdErr) return rej('invalid userId param');
 
 	// Check if the followee is yourself
 	if (user._id.equals(userId)) {
@@ -41,9 +41,9 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 
 	// Check not following
 	const exist = await Following.findOne({
-		follower_id: follower._id,
-		followee_id: followee._id,
-		deleted_at: { $exists: false }
+		followerId: follower._id,
+		followeeId: followee._id,
+		deletedAt: { $exists: false }
 	});
 
 	if (exist === null) {
@@ -55,7 +55,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 		_id: exist._id
 	}, {
 		$set: {
-			deleted_at: new Date()
+			deletedAt: new Date()
 		}
 	});
 
@@ -65,14 +65,14 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Decrement following count
 	User.update({ _id: follower._id }, {
 		$inc: {
-			following_count: -1
+			followingCount: -1
 		}
 	});
 
 	// Decrement followers count
 	User.update({ _id: followee._id }, {
 		$inc: {
-			followers_count: -1
+			followersCount: -1
 		}
 	});
 
diff --git a/src/server/api/endpoints/i.ts b/src/server/api/endpoints/i.ts
index 32b0382fa..f5e92b4de 100644
--- a/src/server/api/endpoints/i.ts
+++ b/src/server/api/endpoints/i.ts
@@ -22,7 +22,7 @@ module.exports = (params, user, _, isSecure) => new Promise(async (res, rej) =>
 	// Update lastUsedAt
 	User.update({ _id: user._id }, {
 		$set: {
-			'account.last_used_at': new Date()
+			'account.lastUsedAt': new Date()
 		}
 	});
 });
diff --git a/src/server/api/endpoints/i/2fa/done.ts b/src/server/api/endpoints/i/2fa/done.ts
index 0f1db7382..d61ebbe6f 100644
--- a/src/server/api/endpoints/i/2fa/done.ts
+++ b/src/server/api/endpoints/i/2fa/done.ts
@@ -12,12 +12,12 @@ module.exports = async (params, user) => new Promise(async (res, rej) => {
 
 	const _token = token.replace(/\s/g, '');
 
-	if (user.two_factor_temp_secret == null) {
+	if (user.twoFactorTempSecret == null) {
 		return rej('二段階認証の設定が開始されていません');
 	}
 
 	const verified = (speakeasy as any).totp.verify({
-		secret: user.two_factor_temp_secret,
+		secret: user.twoFactorTempSecret,
 		encoding: 'base32',
 		token: _token
 	});
@@ -28,8 +28,8 @@ module.exports = async (params, user) => new Promise(async (res, rej) => {
 
 	await User.update(user._id, {
 		$set: {
-			'account.two_factor_secret': user.two_factor_temp_secret,
-			'account.two_factor_enabled': true
+			'account.twoFactorSecret': user.twoFactorTempSecret,
+			'account.twoFactorEnabled': true
 		}
 	});
 
diff --git a/src/server/api/endpoints/i/2fa/register.ts b/src/server/api/endpoints/i/2fa/register.ts
index e2cc1487b..0b49ad882 100644
--- a/src/server/api/endpoints/i/2fa/register.ts
+++ b/src/server/api/endpoints/i/2fa/register.ts
@@ -27,7 +27,7 @@ module.exports = async (params, user) => new Promise(async (res, rej) => {
 
 	await User.update(user._id, {
 		$set: {
-			two_factor_temp_secret: secret.base32
+			twoFactorTempSecret: secret.base32
 		}
 	});
 
diff --git a/src/server/api/endpoints/i/2fa/unregister.ts b/src/server/api/endpoints/i/2fa/unregister.ts
index c43f9ccc4..0221ecb96 100644
--- a/src/server/api/endpoints/i/2fa/unregister.ts
+++ b/src/server/api/endpoints/i/2fa/unregister.ts
@@ -19,8 +19,8 @@ module.exports = async (params, user) => new Promise(async (res, rej) => {
 
 	await User.update(user._id, {
 		$set: {
-			'account.two_factor_secret': null,
-			'account.two_factor_enabled': false
+			'account.twoFactorSecret': null,
+			'account.twoFactorEnabled': false
 		}
 	});
 
diff --git a/src/server/api/endpoints/i/appdata/get.ts b/src/server/api/endpoints/i/appdata/get.ts
index 571208d46..0b34643f7 100644
--- a/src/server/api/endpoints/i/appdata/get.ts
+++ b/src/server/api/endpoints/i/appdata/get.ts
@@ -25,8 +25,8 @@ module.exports = (params, user, app) => new Promise(async (res, rej) => {
 		select[`data.${key}`] = true;
 	}
 	const appdata = await Appdata.findOne({
-		app_id: app._id,
-		user_id: user._id
+		appId: app._id,
+		userId: user._id
 	}, {
 		fields: select
 	});
diff --git a/src/server/api/endpoints/i/appdata/set.ts b/src/server/api/endpoints/i/appdata/set.ts
index 2804a14cb..1e3232ce3 100644
--- a/src/server/api/endpoints/i/appdata/set.ts
+++ b/src/server/api/endpoints/i/appdata/set.ts
@@ -43,11 +43,11 @@ module.exports = (params, user, app) => new Promise(async (res, rej) => {
 	}
 
 	await Appdata.update({
-		app_id: app._id,
-		user_id: user._id
+		appId: app._id,
+		userId: user._id
 	}, Object.assign({
-		app_id: app._id,
-		user_id: user._id
+		appId: app._id,
+		userId: user._id
 	}, {
 			$set: set
 		}), {
diff --git a/src/server/api/endpoints/i/authorized_apps.ts b/src/server/api/endpoints/i/authorized_apps.ts
index 40ce7a68c..5a38d7c18 100644
--- a/src/server/api/endpoints/i/authorized_apps.ts
+++ b/src/server/api/endpoints/i/authorized_apps.ts
@@ -28,7 +28,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Get tokens
 	const tokens = await AccessToken
 		.find({
-			user_id: user._id
+			userId: user._id
 		}, {
 			limit: limit,
 			skip: offset,
@@ -39,5 +39,5 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 
 	// Serialize
 	res(await Promise.all(tokens.map(async token =>
-		await pack(token.app_id))));
+		await pack(token.appId))));
 });
diff --git a/src/server/api/endpoints/i/change_password.ts b/src/server/api/endpoints/i/change_password.ts
index 88fb36b1f..e3b0127e7 100644
--- a/src/server/api/endpoints/i/change_password.ts
+++ b/src/server/api/endpoints/i/change_password.ts
@@ -13,13 +13,13 @@ import User from '../../models/user';
  * @return {Promise<any>}
  */
 module.exports = async (params, user) => new Promise(async (res, rej) => {
-	// Get 'current_password' parameter
-	const [currentPassword, currentPasswordErr] = $(params.current_password).string().$;
-	if (currentPasswordErr) return rej('invalid current_password param');
+	// Get 'currentPasword' parameter
+	const [currentPassword, currentPasswordErr] = $(params.currentPasword).string().$;
+	if (currentPasswordErr) return rej('invalid currentPasword param');
 
-	// Get 'new_password' parameter
-	const [newPassword, newPasswordErr] = $(params.new_password).string().$;
-	if (newPasswordErr) return rej('invalid new_password param');
+	// Get 'newPassword' parameter
+	const [newPassword, newPasswordErr] = $(params.newPassword).string().$;
+	if (newPasswordErr) return rej('invalid newPassword param');
 
 	// Compare password
 	const same = await bcrypt.compare(currentPassword, user.account.password);
diff --git a/src/server/api/endpoints/i/favorites.ts b/src/server/api/endpoints/i/favorites.ts
index eb464cf0f..9f8becf21 100644
--- a/src/server/api/endpoints/i/favorites.ts
+++ b/src/server/api/endpoints/i/favorites.ts
@@ -28,7 +28,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Get favorites
 	const favorites = await Favorite
 		.find({
-			user_id: user._id
+			userId: user._id
 		}, {
 			limit: limit,
 			skip: offset,
@@ -39,6 +39,6 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 
 	// Serialize
 	res(await Promise.all(favorites.map(async favorite =>
-		await pack(favorite.post)
+		await pack(favorite.postId)
 	)));
 });
diff --git a/src/server/api/endpoints/i/notifications.ts b/src/server/api/endpoints/i/notifications.ts
index 688039a0d..7119bf6ea 100644
--- a/src/server/api/endpoints/i/notifications.ts
+++ b/src/server/api/endpoints/i/notifications.ts
@@ -21,9 +21,9 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 		$(params.following).optional.boolean().$;
 	if (followingError) return rej('invalid following param');
 
-	// Get 'mark_as_read' parameter
-	const [markAsRead = true, markAsReadErr] = $(params.mark_as_read).optional.boolean().$;
-	if (markAsReadErr) return rej('invalid mark_as_read param');
+	// Get 'markAsRead' parameter
+	const [markAsRead = true, markAsReadErr] = $(params.markAsRead).optional.boolean().$;
+	if (markAsReadErr) return rej('invalid markAsRead param');
 
 	// Get 'type' parameter
 	const [type, typeErr] = $(params.type).optional.array('string').unique().$;
@@ -33,29 +33,29 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
 	if (limitErr) return rej('invalid limit param');
 
-	// Get 'since_id' parameter
-	const [sinceId, sinceIdErr] = $(params.since_id).optional.id().$;
-	if (sinceIdErr) return rej('invalid since_id param');
+	// Get 'sinceId' parameter
+	const [sinceId, sinceIdErr] = $(params.sinceId).optional.id().$;
+	if (sinceIdErr) return rej('invalid sinceId param');
 
-	// Get 'until_id' parameter
-	const [untilId, untilIdErr] = $(params.until_id).optional.id().$;
-	if (untilIdErr) return rej('invalid until_id param');
+	// Get 'untilId' parameter
+	const [untilId, untilIdErr] = $(params.untilId).optional.id().$;
+	if (untilIdErr) return rej('invalid untilId param');
 
-	// Check if both of since_id and until_id is specified
+	// Check if both of sinceId and untilId is specified
 	if (sinceId && untilId) {
-		return rej('cannot set since_id and until_id');
+		return rej('cannot set sinceId and untilId');
 	}
 
 	const mute = await Mute.find({
-		muter_id: user._id,
-		deleted_at: { $exists: false }
+		muterId: user._id,
+		deletedAt: { $exists: false }
 	});
 
 	const query = {
-		notifiee_id: user._id,
+		notifieeId: user._id,
 		$and: [{
-			notifier_id: {
-				$nin: mute.map(m => m.mutee_id)
+			notifierId: {
+				$nin: mute.map(m => m.muteeId)
 			}
 		}]
 	} as any;
@@ -69,7 +69,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 		const followingIds = await getFriends(user._id);
 
 		query.$and.push({
-			notifier_id: {
+			notifierId: {
 				$in: followingIds
 			}
 		});
diff --git a/src/server/api/endpoints/i/pin.ts b/src/server/api/endpoints/i/pin.ts
index ff546fc2b..886a3edeb 100644
--- a/src/server/api/endpoints/i/pin.ts
+++ b/src/server/api/endpoints/i/pin.ts
@@ -14,14 +14,14 @@ import { pack } from '../../models/user';
  * @return {Promise<any>}
  */
 module.exports = async (params, user) => new Promise(async (res, rej) => {
-	// Get 'post_id' parameter
-	const [postId, postIdErr] = $(params.post_id).id().$;
-	if (postIdErr) return rej('invalid post_id param');
+	// Get 'postId' parameter
+	const [postId, postIdErr] = $(params.postId).id().$;
+	if (postIdErr) return rej('invalid postId param');
 
 	// Fetch pinee
 	const post = await Post.findOne({
 		_id: postId,
-		user_id: user._id
+		userId: user._id
 	});
 
 	if (post === null) {
@@ -30,7 +30,7 @@ module.exports = async (params, user) => new Promise(async (res, rej) => {
 
 	await User.update(user._id, {
 		$set: {
-			pinned_post_id: post._id
+			pinnedPostId: post._id
 		}
 	});
 
diff --git a/src/server/api/endpoints/i/signin_history.ts b/src/server/api/endpoints/i/signin_history.ts
index 859e81653..a4ba22790 100644
--- a/src/server/api/endpoints/i/signin_history.ts
+++ b/src/server/api/endpoints/i/signin_history.ts
@@ -16,21 +16,21 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
 	if (limitErr) return rej('invalid limit param');
 
-	// Get 'since_id' parameter
-	const [sinceId, sinceIdErr] = $(params.since_id).optional.id().$;
-	if (sinceIdErr) return rej('invalid since_id param');
+	// Get 'sinceId' parameter
+	const [sinceId, sinceIdErr] = $(params.sinceId).optional.id().$;
+	if (sinceIdErr) return rej('invalid sinceId param');
 
-	// Get 'until_id' parameter
-	const [untilId, untilIdErr] = $(params.until_id).optional.id().$;
-	if (untilIdErr) return rej('invalid until_id param');
+	// Get 'untilId' parameter
+	const [untilId, untilIdErr] = $(params.untilId).optional.id().$;
+	if (untilIdErr) return rej('invalid untilId param');
 
-	// Check if both of since_id and until_id is specified
+	// Check if both of sinceId and untilId is specified
 	if (sinceId && untilId) {
-		return rej('cannot set since_id and until_id');
+		return rej('cannot set sinceId and untilId');
 	}
 
 	const query = {
-		user_id: user._id
+		userId: user._id
 	} as any;
 
 	const sort = {
diff --git a/src/server/api/endpoints/i/update.ts b/src/server/api/endpoints/i/update.ts
index 3d52de2cc..8147b1bba 100644
--- a/src/server/api/endpoints/i/update.ts
+++ b/src/server/api/endpoints/i/update.ts
@@ -36,34 +36,34 @@ module.exports = async (params, user, _, isSecure) => new Promise(async (res, re
 	if (birthdayErr) return rej('invalid birthday param');
 	if (birthday !== undefined) user.account.profile.birthday = birthday;
 
-	// Get 'avatar_id' parameter
-	const [avatarId, avatarIdErr] = $(params.avatar_id).optional.id().$;
-	if (avatarIdErr) return rej('invalid avatar_id param');
-	if (avatarId) user.avatar_id = avatarId;
+	// Get 'avatarId' parameter
+	const [avatarId, avatarIdErr] = $(params.avatarId).optional.id().$;
+	if (avatarIdErr) return rej('invalid avatarId param');
+	if (avatarId) user.avatarId = avatarId;
 
-	// Get 'banner_id' parameter
-	const [bannerId, bannerIdErr] = $(params.banner_id).optional.id().$;
-	if (bannerIdErr) return rej('invalid banner_id param');
-	if (bannerId) user.banner_id = bannerId;
+	// Get 'bannerId' parameter
+	const [bannerId, bannerIdErr] = $(params.bannerId).optional.id().$;
+	if (bannerIdErr) return rej('invalid bannerId param');
+	if (bannerId) user.bannerId = bannerId;
 
-	// Get 'is_bot' parameter
-	const [isBot, isBotErr] = $(params.is_bot).optional.boolean().$;
-	if (isBotErr) return rej('invalid is_bot param');
-	if (isBot != null) user.account.is_bot = isBot;
+	// Get 'isBot' parameter
+	const [isBot, isBotErr] = $(params.isBot).optional.boolean().$;
+	if (isBotErr) return rej('invalid isBot param');
+	if (isBot != null) user.account.isBot = isBot;
 
-	// Get 'auto_watch' parameter
-	const [autoWatch, autoWatchErr] = $(params.auto_watch).optional.boolean().$;
-	if (autoWatchErr) return rej('invalid auto_watch param');
-	if (autoWatch != null) user.account.settings.auto_watch = autoWatch;
+	// Get 'autoWatch' parameter
+	const [autoWatch, autoWatchErr] = $(params.autoWatch).optional.boolean().$;
+	if (autoWatchErr) return rej('invalid autoWatch param');
+	if (autoWatch != null) user.account.settings.autoWatch = autoWatch;
 
 	await User.update(user._id, {
 		$set: {
 			name: user.name,
 			description: user.description,
-			avatar_id: user.avatar_id,
-			banner_id: user.banner_id,
+			avatarId: user.avatarId,
+			bannerId: user.bannerId,
 			'account.profile': user.account.profile,
-			'account.is_bot': user.account.is_bot,
+			'account.isBot': user.account.isBot,
 			'account.settings': user.account.settings
 		}
 	});
diff --git a/src/server/api/endpoints/i/update_client_setting.ts b/src/server/api/endpoints/i/update_client_setting.ts
index c772ed5dc..a0bef5e59 100644
--- a/src/server/api/endpoints/i/update_client_setting.ts
+++ b/src/server/api/endpoints/i/update_client_setting.ts
@@ -22,14 +22,14 @@ module.exports = async (params, user) => new Promise(async (res, rej) => {
 	if (valueErr) return rej('invalid value param');
 
 	const x = {};
-	x[`account.client_settings.${name}`] = value;
+	x[`account.clientSettings.${name}`] = value;
 
 	await User.update(user._id, {
 		$set: x
 	});
 
 	// Serialize
-	user.account.client_settings[name] = value;
+	user.account.clientSettings[name] = value;
 	const iObj = await pack(user, user, {
 		detail: true,
 		includeSecrets: true
diff --git a/src/server/api/endpoints/i/update_home.ts b/src/server/api/endpoints/i/update_home.ts
index 9ce44e25e..151c3e205 100644
--- a/src/server/api/endpoints/i/update_home.ts
+++ b/src/server/api/endpoints/i/update_home.ts
@@ -26,7 +26,7 @@ module.exports = async (params, user) => new Promise(async (res, rej) => {
 	if (home) {
 		await User.update(user._id, {
 			$set: {
-				'account.client_settings.home': home
+				'account.clientSettings.home': home
 			}
 		});
 
@@ -38,7 +38,7 @@ module.exports = async (params, user) => new Promise(async (res, rej) => {
 	} else {
 		if (id == null && data == null) return rej('you need to set id and data params if home param unset');
 
-		const _home = user.account.client_settings.home;
+		const _home = user.account.clientSettings.home;
 		const widget = _home.find(w => w.id == id);
 
 		if (widget == null) return rej('widget not found');
@@ -47,7 +47,7 @@ module.exports = async (params, user) => new Promise(async (res, rej) => {
 
 		await User.update(user._id, {
 			$set: {
-				'account.client_settings.home': _home
+				'account.clientSettings.home': _home
 			}
 		});
 
diff --git a/src/server/api/endpoints/i/update_mobile_home.ts b/src/server/api/endpoints/i/update_mobile_home.ts
index 1daddf42b..a8436b940 100644
--- a/src/server/api/endpoints/i/update_mobile_home.ts
+++ b/src/server/api/endpoints/i/update_mobile_home.ts
@@ -25,7 +25,7 @@ module.exports = async (params, user) => new Promise(async (res, rej) => {
 	if (home) {
 		await User.update(user._id, {
 			$set: {
-				'account.client_settings.mobile_home': home
+				'account.clientSettings.mobile_home': home
 			}
 		});
 
@@ -37,7 +37,7 @@ module.exports = async (params, user) => new Promise(async (res, rej) => {
 	} else {
 		if (id == null && data == null) return rej('you need to set id and data params if home param unset');
 
-		const _home = user.account.client_settings.mobile_home || [];
+		const _home = user.account.clientSettings.mobile_home || [];
 		const widget = _home.find(w => w.id == id);
 
 		if (widget == null) return rej('widget not found');
@@ -46,7 +46,7 @@ module.exports = async (params, user) => new Promise(async (res, rej) => {
 
 		await User.update(user._id, {
 			$set: {
-				'account.client_settings.mobile_home': _home
+				'account.clientSettings.mobile_home': _home
 			}
 		});
 
diff --git a/src/server/api/endpoints/messaging/history.ts b/src/server/api/endpoints/messaging/history.ts
index 1683ca7a8..2bf3ed996 100644
--- a/src/server/api/endpoints/messaging/history.ts
+++ b/src/server/api/endpoints/messaging/history.ts
@@ -19,25 +19,25 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	if (limitErr) return rej('invalid limit param');
 
 	const mute = await Mute.find({
-		muter_id: user._id,
-		deleted_at: { $exists: false }
+		muterId: user._id,
+		deletedAt: { $exists: false }
 	});
 
 	// Get history
 	const history = await History
 		.find({
-			user_id: user._id,
-			partner: {
-				$nin: mute.map(m => m.mutee_id)
+			userId: user._id,
+			partnerId: {
+				$nin: mute.map(m => m.muteeId)
 			}
 		}, {
 			limit: limit,
 			sort: {
-				updated_at: -1
+				updatedAt: -1
 			}
 		});
 
 	// Serialize
 	res(await Promise.all(history.map(async h =>
-		await pack(h.message, user))));
+		await pack(h.messageId, user))));
 });
diff --git a/src/server/api/endpoints/messaging/messages.ts b/src/server/api/endpoints/messaging/messages.ts
index 67ba5e9d6..dd80e41d0 100644
--- a/src/server/api/endpoints/messaging/messages.ts
+++ b/src/server/api/endpoints/messaging/messages.ts
@@ -15,9 +15,9 @@ import read from '../../common/read-messaging-message';
  * @return {Promise<any>}
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
-	// Get 'user_id' parameter
-	const [recipientId, recipientIdErr] = $(params.user_id).id().$;
-	if (recipientIdErr) return rej('invalid user_id param');
+	// Get 'userId' parameter
+	const [recipientId, recipientIdErr] = $(params.userId).id().$;
+	if (recipientIdErr) return rej('invalid userId param');
 
 	// Fetch recipient
 	const recipient = await User.findOne({
@@ -32,34 +32,34 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 		return rej('user not found');
 	}
 
-	// Get 'mark_as_read' parameter
-	const [markAsRead = true, markAsReadErr] = $(params.mark_as_read).optional.boolean().$;
-	if (markAsReadErr) return rej('invalid mark_as_read param');
+	// Get 'markAsRead' parameter
+	const [markAsRead = true, markAsReadErr] = $(params.markAsRead).optional.boolean().$;
+	if (markAsReadErr) return rej('invalid markAsRead param');
 
 	// Get 'limit' parameter
 	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
 	if (limitErr) return rej('invalid limit param');
 
-	// Get 'since_id' parameter
-	const [sinceId, sinceIdErr] = $(params.since_id).optional.id().$;
-	if (sinceIdErr) return rej('invalid since_id param');
+	// Get 'sinceId' parameter
+	const [sinceId, sinceIdErr] = $(params.sinceId).optional.id().$;
+	if (sinceIdErr) return rej('invalid sinceId param');
 
-	// Get 'until_id' parameter
-	const [untilId, untilIdErr] = $(params.until_id).optional.id().$;
-	if (untilIdErr) return rej('invalid until_id param');
+	// Get 'untilId' parameter
+	const [untilId, untilIdErr] = $(params.untilId).optional.id().$;
+	if (untilIdErr) return rej('invalid untilId param');
 
-	// Check if both of since_id and until_id is specified
+	// Check if both of sinceId and untilId is specified
 	if (sinceId && untilId) {
-		return rej('cannot set since_id and until_id');
+		return rej('cannot set sinceId and untilId');
 	}
 
 	const query = {
 		$or: [{
-			user_id: user._id,
-			recipient_id: recipient._id
+			userId: user._id,
+			recipientId: recipient._id
 		}, {
-			user_id: recipient._id,
-			recipient_id: user._id
+			userId: recipient._id,
+			recipientId: user._id
 		}]
 	} as any;
 
diff --git a/src/server/api/endpoints/messaging/messages/create.ts b/src/server/api/endpoints/messaging/messages/create.ts
index 5184b2bd3..4edd72655 100644
--- a/src/server/api/endpoints/messaging/messages/create.ts
+++ b/src/server/api/endpoints/messaging/messages/create.ts
@@ -21,9 +21,9 @@ import config from '../../../../../conf';
  * @return {Promise<any>}
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
-	// Get 'user_id' parameter
-	const [recipientId, recipientIdErr] = $(params.user_id).id().$;
-	if (recipientIdErr) return rej('invalid user_id param');
+	// Get 'userId' parameter
+	const [recipientId, recipientIdErr] = $(params.userId).id().$;
+	if (recipientIdErr) return rej('invalid userId param');
 
 	// Myself
 	if (recipientId.equals(user._id)) {
@@ -47,15 +47,15 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	const [text, textErr] = $(params.text).optional.string().pipe(isValidText).$;
 	if (textErr) return rej('invalid text');
 
-	// Get 'file_id' parameter
-	const [fileId, fileIdErr] = $(params.file_id).optional.id().$;
-	if (fileIdErr) return rej('invalid file_id param');
+	// Get 'fileId' parameter
+	const [fileId, fileIdErr] = $(params.fileId).optional.id().$;
+	if (fileIdErr) return rej('invalid fileId param');
 
 	let file = null;
 	if (fileId !== undefined) {
 		file = await DriveFile.findOne({
 			_id: fileId,
-			'metadata.user_id': user._id
+			'metadata.userId': user._id
 		});
 
 		if (file === null) {
@@ -70,12 +70,12 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 
 	// メッセージを作成
 	const message = await Message.insert({
-		created_at: new Date(),
-		file_id: file ? file._id : undefined,
-		recipient_id: recipient._id,
+		createdAt: new Date(),
+		fileId: file ? file._id : undefined,
+		recipientId: recipient._id,
 		text: text ? text : undefined,
-		user_id: user._id,
-		is_read: false
+		userId: user._id,
+		isRead: false
 	});
 
 	// Serialize
@@ -85,32 +85,32 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	res(messageObj);
 
 	// 自分のストリーム
-	publishMessagingStream(message.user_id, message.recipient_id, 'message', messageObj);
-	publishMessagingIndexStream(message.user_id, 'message', messageObj);
-	publishUserStream(message.user_id, 'messaging_message', messageObj);
+	publishMessagingStream(message.userId, message.recipientId, 'message', messageObj);
+	publishMessagingIndexStream(message.userId, 'message', messageObj);
+	publishUserStream(message.userId, 'messaging_message', messageObj);
 
 	// 相手のストリーム
-	publishMessagingStream(message.recipient_id, message.user_id, 'message', messageObj);
-	publishMessagingIndexStream(message.recipient_id, 'message', messageObj);
-	publishUserStream(message.recipient_id, 'messaging_message', messageObj);
+	publishMessagingStream(message.recipientId, message.userId, 'message', messageObj);
+	publishMessagingIndexStream(message.recipientId, 'message', messageObj);
+	publishUserStream(message.recipientId, 'messaging_message', messageObj);
 
 	// 3秒経っても(今回作成した)メッセージが既読にならなかったら「未読のメッセージがありますよ」イベントを発行する
 	setTimeout(async () => {
-		const freshMessage = await Message.findOne({ _id: message._id }, { is_read: true });
-		if (!freshMessage.is_read) {
+		const freshMessage = await Message.findOne({ _id: message._id }, { isRead: true });
+		if (!freshMessage.isRead) {
 			//#region ただしミュートされているなら発行しない
 			const mute = await Mute.find({
-				muter_id: recipient._id,
-				deleted_at: { $exists: false }
+				muterId: recipient._id,
+				deletedAt: { $exists: false }
 			});
-			const mutedUserIds = mute.map(m => m.mutee_id.toString());
+			const mutedUserIds = mute.map(m => m.muteeId.toString());
 			if (mutedUserIds.indexOf(user._id.toString()) != -1) {
 				return;
 			}
 			//#endregion
 
-			publishUserStream(message.recipient_id, 'unread_messaging_message', messageObj);
-			pushSw(message.recipient_id, 'unread_messaging_message', messageObj);
+			publishUserStream(message.recipientId, 'unread_messaging_message', messageObj);
+			pushSw(message.recipientId, 'unread_messaging_message', messageObj);
 		}
 	}, 3000);
 
@@ -130,26 +130,26 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 
 	// 履歴作成(自分)
 	History.update({
-		user_id: user._id,
-		partner: recipient._id
+		userId: user._id,
+		partnerId: recipient._id
 	}, {
-		updated_at: new Date(),
-		user_id: user._id,
-		partner: recipient._id,
-		message: message._id
+		updatedAt: new Date(),
+		userId: user._id,
+		partnerId: recipient._id,
+		messageId: message._id
 	}, {
 		upsert: true
 	});
 
 	// 履歴作成(相手)
 	History.update({
-		user_id: recipient._id,
-		partner: user._id
+		userId: recipient._id,
+		partnerId: user._id
 	}, {
-		updated_at: new Date(),
-		user_id: recipient._id,
-		partner: user._id,
-		message: message._id
+		updatedAt: new Date(),
+		userId: recipient._id,
+		partnerId: user._id,
+		messageId: message._id
 	}, {
 		upsert: true
 	});
diff --git a/src/server/api/endpoints/messaging/unread.ts b/src/server/api/endpoints/messaging/unread.ts
index c4326e1d2..f7f4047b6 100644
--- a/src/server/api/endpoints/messaging/unread.ts
+++ b/src/server/api/endpoints/messaging/unread.ts
@@ -13,18 +13,18 @@ import Mute from '../../models/mute';
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	const mute = await Mute.find({
-		muter_id: user._id,
-		deleted_at: { $exists: false }
+		muterId: user._id,
+		deletedAt: { $exists: false }
 	});
-	const mutedUserIds = mute.map(m => m.mutee_id);
+	const mutedUserIds = mute.map(m => m.muteeId);
 
 	const count = await Message
 		.count({
-			user_id: {
+			userId: {
 				$nin: mutedUserIds
 			},
-			recipient_id: user._id,
-			is_read: false
+			recipientId: user._id,
+			isRead: false
 		});
 
 	res({
diff --git a/src/server/api/endpoints/meta.ts b/src/server/api/endpoints/meta.ts
index 10625ec66..cb47ede57 100644
--- a/src/server/api/endpoints/meta.ts
+++ b/src/server/api/endpoints/meta.ts
@@ -53,7 +53,6 @@ module.exports = (params) => new Promise(async (res, rej) => {
 			model: os.cpus()[0].model,
 			cores: os.cpus().length
 		},
-		top_image: meta.top_image,
 		broadcasts: meta.broadcasts
 	});
 });
diff --git a/src/server/api/endpoints/mute/create.ts b/src/server/api/endpoints/mute/create.ts
index f99b40d32..e86023508 100644
--- a/src/server/api/endpoints/mute/create.ts
+++ b/src/server/api/endpoints/mute/create.ts
@@ -15,9 +15,9 @@ import Mute from '../../models/mute';
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	const muter = user;
 
-	// Get 'user_id' parameter
-	const [userId, userIdErr] = $(params.user_id).id().$;
-	if (userIdErr) return rej('invalid user_id param');
+	// Get 'userId' parameter
+	const [userId, userIdErr] = $(params.userId).id().$;
+	if (userIdErr) return rej('invalid userId param');
 
 	// 自分自身
 	if (user._id.equals(userId)) {
@@ -40,9 +40,9 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 
 	// Check if already muting
 	const exist = await Mute.findOne({
-		muter_id: muter._id,
-		mutee_id: mutee._id,
-		deleted_at: { $exists: false }
+		muterId: muter._id,
+		muteeId: mutee._id,
+		deletedAt: { $exists: false }
 	});
 
 	if (exist !== null) {
@@ -51,9 +51,9 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 
 	// Create mute
 	await Mute.insert({
-		created_at: new Date(),
-		muter_id: muter._id,
-		mutee_id: mutee._id,
+		createdAt: new Date(),
+		muterId: muter._id,
+		muteeId: mutee._id,
 	});
 
 	// Send response
diff --git a/src/server/api/endpoints/mute/delete.ts b/src/server/api/endpoints/mute/delete.ts
index 36e2fd101..7e361b479 100644
--- a/src/server/api/endpoints/mute/delete.ts
+++ b/src/server/api/endpoints/mute/delete.ts
@@ -15,9 +15,9 @@ import Mute from '../../models/mute';
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	const muter = user;
 
-	// Get 'user_id' parameter
-	const [userId, userIdErr] = $(params.user_id).id().$;
-	if (userIdErr) return rej('invalid user_id param');
+	// Get 'userId' parameter
+	const [userId, userIdErr] = $(params.userId).id().$;
+	if (userIdErr) return rej('invalid userId param');
 
 	// Check if the mutee is yourself
 	if (user._id.equals(userId)) {
@@ -40,9 +40,9 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 
 	// Check not muting
 	const exist = await Mute.findOne({
-		muter_id: muter._id,
-		mutee_id: mutee._id,
-		deleted_at: { $exists: false }
+		muterId: muter._id,
+		muteeId: mutee._id,
+		deletedAt: { $exists: false }
 	});
 
 	if (exist === null) {
@@ -54,7 +54,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 		_id: exist._id
 	}, {
 		$set: {
-			deleted_at: new Date()
+			deletedAt: new Date()
 		}
 	});
 
diff --git a/src/server/api/endpoints/mute/list.ts b/src/server/api/endpoints/mute/list.ts
index 19e3b157e..3401fba64 100644
--- a/src/server/api/endpoints/mute/list.ts
+++ b/src/server/api/endpoints/mute/list.ts
@@ -28,15 +28,15 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
 
 	// Construct query
 	const query = {
-		muter_id: me._id,
-		deleted_at: { $exists: false }
+		muterId: me._id,
+		deletedAt: { $exists: false }
 	} as any;
 
 	if (iknow) {
 		// Get my friends
 		const myFriends = await getFriends(me._id);
 
-		query.mutee_id = {
+		query.muteeId = {
 			$in: myFriends
 		};
 	}
@@ -63,7 +63,7 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
 
 	// Serialize
 	const users = await Promise.all(mutes.map(async m =>
-		await pack(m.mutee_id, me, { detail: true })));
+		await pack(m.muteeId, me, { detail: true })));
 
 	// Response
 	res({
diff --git a/src/server/api/endpoints/my/apps.ts b/src/server/api/endpoints/my/apps.ts
index b23619050..bc1290cac 100644
--- a/src/server/api/endpoints/my/apps.ts
+++ b/src/server/api/endpoints/my/apps.ts
@@ -21,7 +21,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	if (offsetErr) return rej('invalid offset param');
 
 	const query = {
-		user_id: user._id
+		userId: user._id
 	};
 
 	// Execute query
diff --git a/src/server/api/endpoints/notifications/get_unread_count.ts b/src/server/api/endpoints/notifications/get_unread_count.ts
index 845d6b29c..8f9719fff 100644
--- a/src/server/api/endpoints/notifications/get_unread_count.ts
+++ b/src/server/api/endpoints/notifications/get_unread_count.ts
@@ -13,18 +13,18 @@ import Mute from '../../models/mute';
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	const mute = await Mute.find({
-		muter_id: user._id,
-		deleted_at: { $exists: false }
+		muterId: user._id,
+		deletedAt: { $exists: false }
 	});
-	const mutedUserIds = mute.map(m => m.mutee_id);
+	const mutedUserIds = mute.map(m => m.muteeId);
 
 	const count = await Notification
 		.count({
-			notifiee_id: user._id,
-			notifier_id: {
+			notifieeId: user._id,
+			notifierId: {
 				$nin: mutedUserIds
 			},
-			is_read: false
+			isRead: false
 		});
 
 	res({
diff --git a/src/server/api/endpoints/notifications/mark_as_read_all.ts b/src/server/api/endpoints/notifications/mark_as_read_all.ts
index 3550e344c..693de3d0e 100644
--- a/src/server/api/endpoints/notifications/mark_as_read_all.ts
+++ b/src/server/api/endpoints/notifications/mark_as_read_all.ts
@@ -14,11 +14,11 @@ import event from '../../event';
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Update documents
 	await Notification.update({
-		notifiee_id: user._id,
-		is_read: false
+		notifieeId: user._id,
+		isRead: false
 	}, {
 		$set: {
-			is_read: true
+			isRead: true
 		}
 	}, {
 		multi: true
diff --git a/src/server/api/endpoints/othello/games.ts b/src/server/api/endpoints/othello/games.ts
index 2a6bbb404..37fa38418 100644
--- a/src/server/api/endpoints/othello/games.ts
+++ b/src/server/api/endpoints/othello/games.ts
@@ -1,5 +1,5 @@
 import $ from 'cafy';
-import Game, { pack } from '../../models/othello-game';
+import OthelloGame, { pack } from '../../models/othello-game';
 
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Get 'my' parameter
@@ -10,28 +10,28 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
 	if (limitErr) return rej('invalid limit param');
 
-	// Get 'since_id' parameter
-	const [sinceId, sinceIdErr] = $(params.since_id).optional.id().$;
-	if (sinceIdErr) return rej('invalid since_id param');
+	// Get 'sinceId' parameter
+	const [sinceId, sinceIdErr] = $(params.sinceId).optional.id().$;
+	if (sinceIdErr) return rej('invalid sinceId param');
 
-	// Get 'until_id' parameter
-	const [untilId, untilIdErr] = $(params.until_id).optional.id().$;
-	if (untilIdErr) return rej('invalid until_id param');
+	// Get 'untilId' parameter
+	const [untilId, untilIdErr] = $(params.untilId).optional.id().$;
+	if (untilIdErr) return rej('invalid untilId param');
 
-	// Check if both of since_id and until_id is specified
+	// Check if both of sinceId and untilId is specified
 	if (sinceId && untilId) {
-		return rej('cannot set since_id and until_id');
+		return rej('cannot set sinceId and untilId');
 	}
 
 	const q: any = my ? {
-		is_started: true,
+		isStarted: true,
 		$or: [{
-			user1_id: user._id
+			user1Id: user._id
 		}, {
-			user2_id: user._id
+			user2Id: user._id
 		}]
 	} : {
-		is_started: true
+		isStarted: true
 	};
 
 	const sort = {
@@ -50,7 +50,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	}
 
 	// Fetch games
-	const games = await Game.find(q, {
+	const games = await OthelloGame.find(q, {
 		sort,
 		limit
 	});
diff --git a/src/server/api/endpoints/othello/games/show.ts b/src/server/api/endpoints/othello/games/show.ts
index 2b0db4dd0..f9084682f 100644
--- a/src/server/api/endpoints/othello/games/show.ts
+++ b/src/server/api/endpoints/othello/games/show.ts
@@ -1,22 +1,22 @@
 import $ from 'cafy';
-import Game, { pack } from '../../../models/othello-game';
+import OthelloGame, { pack } from '../../../models/othello-game';
 import Othello from '../../../../common/othello/core';
 
 module.exports = (params, user) => new Promise(async (res, rej) => {
-	// Get 'game_id' parameter
-	const [gameId, gameIdErr] = $(params.game_id).id().$;
-	if (gameIdErr) return rej('invalid game_id param');
+	// Get 'gameId' parameter
+	const [gameId, gameIdErr] = $(params.gameId).id().$;
+	if (gameIdErr) return rej('invalid gameId param');
 
-	const game = await Game.findOne({ _id: gameId });
+	const game = await OthelloGame.findOne({ _id: gameId });
 
 	if (game == null) {
 		return rej('game not found');
 	}
 
 	const o = new Othello(game.settings.map, {
-		isLlotheo: game.settings.is_llotheo,
-		canPutEverywhere: game.settings.can_put_everywhere,
-		loopedBoard: game.settings.looped_board
+		isLlotheo: game.settings.isLlotheo,
+		canPutEverywhere: game.settings.canPutEverywhere,
+		loopedBoard: game.settings.loopedBoard
 	});
 
 	game.logs.forEach(log => {
diff --git a/src/server/api/endpoints/othello/invitations.ts b/src/server/api/endpoints/othello/invitations.ts
index 02fb421fb..f6e0071a6 100644
--- a/src/server/api/endpoints/othello/invitations.ts
+++ b/src/server/api/endpoints/othello/invitations.ts
@@ -3,7 +3,7 @@ import Matching, { pack as packMatching } from '../../models/othello-matching';
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Find session
 	const invitations = await Matching.find({
-		child_id: user._id
+		childId: user._id
 	}, {
 		sort: {
 			_id: -1
diff --git a/src/server/api/endpoints/othello/match.ts b/src/server/api/endpoints/othello/match.ts
index b73e105ef..f503c5834 100644
--- a/src/server/api/endpoints/othello/match.ts
+++ b/src/server/api/endpoints/othello/match.ts
@@ -1,24 +1,24 @@
 import $ from 'cafy';
 import Matching, { pack as packMatching } from '../../models/othello-matching';
-import Game, { pack as packGame } from '../../models/othello-game';
+import OthelloGame, { pack as packGame } from '../../models/othello-game';
 import User from '../../models/user';
 import publishUserStream, { publishOthelloStream } from '../../event';
 import { eighteight } from '../../../common/othello/maps';
 
 module.exports = (params, user) => new Promise(async (res, rej) => {
-	// Get 'user_id' parameter
-	const [childId, childIdErr] = $(params.user_id).id().$;
-	if (childIdErr) return rej('invalid user_id param');
+	// Get 'userId' parameter
+	const [childId, childIdErr] = $(params.userId).id().$;
+	if (childIdErr) return rej('invalid userId param');
 
 	// Myself
 	if (childId.equals(user._id)) {
-		return rej('invalid user_id param');
+		return rej('invalid userId param');
 	}
 
 	// Find session
 	const exist = await Matching.findOne({
-		parent_id: childId,
-		child_id: user._id
+		parentId: childId,
+		childId: user._id
 	});
 
 	if (exist) {
@@ -28,29 +28,29 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 		});
 
 		// Create game
-		const game = await Game.insert({
-			created_at: new Date(),
-			user1_id: exist.parent_id,
-			user2_id: user._id,
-			user1_accepted: false,
-			user2_accepted: false,
-			is_started: false,
-			is_ended: false,
+		const game = await OthelloGame.insert({
+			createdAt: new Date(),
+			user1Id: exist.parentId,
+			user2Id: user._id,
+			user1Accepted: false,
+			user2Accepted: false,
+			isStarted: false,
+			isEnded: false,
 			logs: [],
 			settings: {
 				map: eighteight.data,
 				bw: 'random',
-				is_llotheo: false
+				isLlotheo: false
 			}
 		});
 
 		// Reponse
 		res(await packGame(game, user));
 
-		publishOthelloStream(exist.parent_id, 'matched', await packGame(game, exist.parent_id));
+		publishOthelloStream(exist.parentId, 'matched', await packGame(game, exist.parentId));
 
 		const other = await Matching.count({
-			child_id: user._id
+			childId: user._id
 		});
 
 		if (other == 0) {
@@ -72,14 +72,14 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 
 		// 以前のセッションはすべて削除しておく
 		await Matching.remove({
-			parent_id: user._id
+			parentId: user._id
 		});
 
 		// セッションを作成
 		const matching = await Matching.insert({
-			created_at: new Date(),
-			parent_id: user._id,
-			child_id: child._id
+			createdAt: new Date(),
+			parentId: user._id,
+			childId: child._id
 		});
 
 		// Reponse
diff --git a/src/server/api/endpoints/othello/match/cancel.ts b/src/server/api/endpoints/othello/match/cancel.ts
index 6f751ef83..ee0f82a61 100644
--- a/src/server/api/endpoints/othello/match/cancel.ts
+++ b/src/server/api/endpoints/othello/match/cancel.ts
@@ -2,7 +2,7 @@ import Matching from '../../../models/othello-matching';
 
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	await Matching.remove({
-		parent_id: user._id
+		parentId: user._id
 	});
 
 	res();
diff --git a/src/server/api/endpoints/posts.ts b/src/server/api/endpoints/posts.ts
index 7df744d2a..bee1de02d 100644
--- a/src/server/api/endpoints/posts.ts
+++ b/src/server/api/endpoints/posts.ts
@@ -35,17 +35,17 @@ module.exports = (params) => new Promise(async (res, rej) => {
 	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
 	if (limitErr) return rej('invalid limit param');
 
-	// Get 'since_id' parameter
-	const [sinceId, sinceIdErr] = $(params.since_id).optional.id().$;
-	if (sinceIdErr) return rej('invalid since_id param');
+	// Get 'sinceId' parameter
+	const [sinceId, sinceIdErr] = $(params.sinceId).optional.id().$;
+	if (sinceIdErr) return rej('invalid sinceId param');
 
-	// Get 'until_id' parameter
-	const [untilId, untilIdErr] = $(params.until_id).optional.id().$;
-	if (untilIdErr) return rej('invalid until_id param');
+	// Get 'untilId' parameter
+	const [untilId, untilIdErr] = $(params.untilId).optional.id().$;
+	if (untilIdErr) return rej('invalid untilId param');
 
-	// Check if both of since_id and until_id is specified
+	// Check if both of sinceId and untilId is specified
 	if (sinceId && untilId) {
-		return rej('cannot set since_id and until_id');
+		return rej('cannot set sinceId and untilId');
 	}
 
 	// Construct query
@@ -65,15 +65,15 @@ module.exports = (params) => new Promise(async (res, rej) => {
 	}
 
 	if (reply != undefined) {
-		query.reply_id = reply ? { $exists: true, $ne: null } : null;
+		query.replyId = reply ? { $exists: true, $ne: null } : null;
 	}
 
 	if (repost != undefined) {
-		query.repost_id = repost ? { $exists: true, $ne: null } : null;
+		query.repostId = repost ? { $exists: true, $ne: null } : null;
 	}
 
 	if (media != undefined) {
-		query.media_ids = media ? { $exists: true, $ne: null } : null;
+		query.mediaIds = media ? { $exists: true, $ne: null } : null;
 	}
 
 	if (poll != undefined) {
@@ -82,7 +82,7 @@ module.exports = (params) => new Promise(async (res, rej) => {
 
 	// TODO
 	//if (bot != undefined) {
-	//	query.is_bot = bot;
+	//	query.isBot = bot;
 	//}
 
 	// Issue query
diff --git a/src/server/api/endpoints/posts/categorize.ts b/src/server/api/endpoints/posts/categorize.ts
index 0c85c2b4e..0436c8e69 100644
--- a/src/server/api/endpoints/posts/categorize.ts
+++ b/src/server/api/endpoints/posts/categorize.ts
@@ -12,13 +12,13 @@ import Post from '../../models/post';
  * @return {Promise<any>}
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
-	if (!user.account.is_pro) {
+	if (!user.account.isPro) {
 		return rej('This endpoint is available only from a Pro account');
 	}
 
-	// Get 'post_id' parameter
-	const [postId, postIdErr] = $(params.post_id).id().$;
-	if (postIdErr) return rej('invalid post_id param');
+	// Get 'postId' parameter
+	const [postId, postIdErr] = $(params.postId).id().$;
+	if (postIdErr) return rej('invalid postId param');
 
 	// Get categorizee
 	const post = await Post.findOne({
diff --git a/src/server/api/endpoints/posts/context.ts b/src/server/api/endpoints/posts/context.ts
index 5ba375897..44a77d102 100644
--- a/src/server/api/endpoints/posts/context.ts
+++ b/src/server/api/endpoints/posts/context.ts
@@ -12,9 +12,9 @@ import Post, { pack } from '../../models/post';
  * @return {Promise<any>}
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
-	// Get 'post_id' parameter
-	const [postId, postIdErr] = $(params.post_id).id().$;
-	if (postIdErr) return rej('invalid post_id param');
+	// Get 'postId' parameter
+	const [postId, postIdErr] = $(params.postId).id().$;
+	if (postIdErr) return rej('invalid postId param');
 
 	// Get 'limit' parameter
 	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
@@ -48,13 +48,13 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 			return;
 		}
 
-		if (p.reply_id) {
-			await get(p.reply_id);
+		if (p.replyId) {
+			await get(p.replyId);
 		}
 	}
 
-	if (post.reply_id) {
-		await get(post.reply_id);
+	if (post.replyId) {
+		await get(post.replyId);
 	}
 
 	// Serialize
diff --git a/src/server/api/endpoints/posts/create.ts b/src/server/api/endpoints/posts/create.ts
index bc9af843b..390370ad4 100644
--- a/src/server/api/endpoints/posts/create.ts
+++ b/src/server/api/endpoints/posts/create.ts
@@ -33,9 +33,9 @@ module.exports = (params, user: IUser, app) => new Promise(async (res, rej) => {
 	const [text, textErr] = $(params.text).optional.string().pipe(isValidText).$;
 	if (textErr) return rej('invalid text');
 
-	// Get 'via_mobile' parameter
-	const [viaMobile = false, viaMobileErr] = $(params.via_mobile).optional.boolean().$;
-	if (viaMobileErr) return rej('invalid via_mobile');
+	// Get 'viaMobile' parameter
+	const [viaMobile = false, viaMobileErr] = $(params.viaMobile).optional.boolean().$;
+	if (viaMobileErr) return rej('invalid viaMobile');
 
 	// Get 'tags' parameter
 	const [tags = [], tagsErr] = $(params.tags).optional.array('string').unique().eachQ(t => t.range(1, 32)).$;
@@ -53,9 +53,9 @@ module.exports = (params, user: IUser, app) => new Promise(async (res, rej) => {
 		.$;
 	if (geoErr) return rej('invalid geo');
 
-	// Get 'media_ids' parameter
-	const [mediaIds, mediaIdsErr] = $(params.media_ids).optional.array('id').unique().range(1, 4).$;
-	if (mediaIdsErr) return rej('invalid media_ids');
+	// Get 'mediaIds' parameter
+	const [mediaIds, mediaIdsErr] = $(params.mediaIds).optional.array('id').unique().range(1, 4).$;
+	if (mediaIdsErr) return rej('invalid mediaIds');
 
 	let files = [];
 	if (mediaIds !== undefined) {
@@ -67,7 +67,7 @@ module.exports = (params, user: IUser, app) => new Promise(async (res, rej) => {
 			// SELECT _id
 			const entity = await DriveFile.findOne({
 				_id: mediaId,
-				'metadata.user_id': user._id
+				'metadata.userId': user._id
 			});
 
 			if (entity === null) {
@@ -80,9 +80,9 @@ module.exports = (params, user: IUser, app) => new Promise(async (res, rej) => {
 		files = null;
 	}
 
-	// Get 'repost_id' parameter
-	const [repostId, repostIdErr] = $(params.repost_id).optional.id().$;
-	if (repostIdErr) return rej('invalid repost_id');
+	// Get 'repostId' parameter
+	const [repostId, repostIdErr] = $(params.repostId).optional.id().$;
+	if (repostIdErr) return rej('invalid repostId');
 
 	let repost: IPost = null;
 	let isQuote = false;
@@ -94,13 +94,13 @@ module.exports = (params, user: IUser, app) => new Promise(async (res, rej) => {
 
 		if (repost == null) {
 			return rej('repostee is not found');
-		} else if (repost.repost_id && !repost.text && !repost.media_ids) {
+		} else if (repost.repostId && !repost.text && !repost.mediaIds) {
 			return rej('cannot repost to repost');
 		}
 
 		// Fetch recently post
 		const latestPost = await Post.findOne({
-			user_id: user._id
+			userId: user._id
 		}, {
 			sort: {
 				_id: -1
@@ -111,8 +111,8 @@ module.exports = (params, user: IUser, app) => new Promise(async (res, rej) => {
 
 		// 直近と同じRepost対象かつ引用じゃなかったらエラー
 		if (latestPost &&
-			latestPost.repost_id &&
-			latestPost.repost_id.equals(repost._id) &&
+			latestPost.repostId &&
+			latestPost.repostId.equals(repost._id) &&
 			!isQuote) {
 			return rej('cannot repost same post that already reposted in your latest post');
 		}
@@ -125,9 +125,9 @@ module.exports = (params, user: IUser, app) => new Promise(async (res, rej) => {
 		}
 	}
 
-	// Get 'reply_id' parameter
-	const [replyId, replyIdErr] = $(params.reply_id).optional.id().$;
-	if (replyIdErr) return rej('invalid reply_id');
+	// Get 'replyId' parameter
+	const [replyId, replyIdErr] = $(params.replyId).optional.id().$;
+	if (replyIdErr) return rej('invalid replyId');
 
 	let reply: IPost = null;
 	if (replyId !== undefined) {
@@ -141,14 +141,14 @@ module.exports = (params, user: IUser, app) => new Promise(async (res, rej) => {
 		}
 
 		// 返信対象が引用でないRepostだったらエラー
-		if (reply.repost_id && !reply.text && !reply.media_ids) {
+		if (reply.repostId && !reply.text && !reply.mediaIds) {
 			return rej('cannot reply to repost');
 		}
 	}
 
-	// Get 'channel_id' parameter
-	const [channelId, channelIdErr] = $(params.channel_id).optional.id().$;
-	if (channelIdErr) return rej('invalid channel_id');
+	// Get 'channelId' parameter
+	const [channelId, channelIdErr] = $(params.channelId).optional.id().$;
+	if (channelIdErr) return rej('invalid channelId');
 
 	let channel: IChannel = null;
 	if (channelId !== undefined) {
@@ -162,12 +162,12 @@ module.exports = (params, user: IUser, app) => new Promise(async (res, rej) => {
 		}
 
 		// 返信対象の投稿がこのチャンネルじゃなかったらダメ
-		if (reply && !channelId.equals(reply.channel_id)) {
+		if (reply && !channelId.equals(reply.channelId)) {
 			return rej('チャンネル内部からチャンネル外部の投稿に返信することはできません');
 		}
 
 		// Repost対象の投稿がこのチャンネルじゃなかったらダメ
-		if (repost && !channelId.equals(repost.channel_id)) {
+		if (repost && !channelId.equals(repost.channelId)) {
 			return rej('チャンネル内部からチャンネル外部の投稿をRepostすることはできません');
 		}
 
@@ -177,12 +177,12 @@ module.exports = (params, user: IUser, app) => new Promise(async (res, rej) => {
 		}
 	} else {
 		// 返信対象の投稿がチャンネルへの投稿だったらダメ
-		if (reply && reply.channel_id != null) {
+		if (reply && reply.channelId != null) {
 			return rej('チャンネル外部からチャンネル内部の投稿に返信することはできません');
 		}
 
 		// Repost対象の投稿がチャンネルへの投稿だったらダメ
-		if (repost && repost.channel_id != null) {
+		if (repost && repost.channelId != null) {
 			return rej('チャンネル外部からチャンネル内部の投稿をRepostすることはできません');
 		}
 	}
@@ -206,22 +206,22 @@ module.exports = (params, user: IUser, app) => new Promise(async (res, rej) => {
 
 	// テキストが無いかつ添付ファイルが無いかつRepostも無いかつ投票も無かったらエラー
 	if (text === undefined && files === null && repost === null && poll === undefined) {
-		return rej('text, media_ids, repost_id or poll is required');
+		return rej('text, mediaIds, repostId or poll is required');
 	}
 
 	// 直近の投稿と重複してたらエラー
 	// TODO: 直近の投稿が一日前くらいなら重複とは見なさない
-	if (user.latest_post) {
+	if (user.latestPost) {
 		if (deepEqual({
-			text: user.latest_post.text,
-			reply: user.latest_post.reply_id ? user.latest_post.reply_id.toString() : null,
-			repost: user.latest_post.repost_id ? user.latest_post.repost_id.toString() : null,
-			media_ids: (user.latest_post.media_ids || []).map(id => id.toString())
+			text: user.latestPost.text,
+			reply: user.latestPost.replyId ? user.latestPost.replyId.toString() : null,
+			repost: user.latestPost.repostId ? user.latestPost.repostId.toString() : null,
+			mediaIds: (user.latestPost.mediaIds || []).map(id => id.toString())
 		}, {
 			text: text,
 			reply: reply ? reply._id.toString() : null,
 			repost: repost ? repost._id.toString() : null,
-			media_ids: (files || []).map(file => file._id.toString())
+			mediaIds: (files || []).map(file => file._id.toString())
 		})) {
 			return rej('duplicate');
 		}
@@ -246,23 +246,23 @@ module.exports = (params, user: IUser, app) => new Promise(async (res, rej) => {
 
 	// 投稿を作成
 	const post = await Post.insert({
-		created_at: new Date(),
-		channel_id: channel ? channel._id : undefined,
+		createdAt: new Date(),
+		channelId: channel ? channel._id : undefined,
 		index: channel ? channel.index + 1 : undefined,
-		media_ids: files ? files.map(file => file._id) : undefined,
-		reply_id: reply ? reply._id : undefined,
-		repost_id: repost ? repost._id : undefined,
+		mediaIds: files ? files.map(file => file._id) : undefined,
+		replyId: reply ? reply._id : undefined,
+		repostId: repost ? repost._id : undefined,
 		poll: poll,
 		text: text,
 		tags: tags,
-		user_id: user._id,
-		app_id: app ? app._id : null,
-		via_mobile: viaMobile,
+		userId: user._id,
+		appId: app ? app._id : null,
+		viaMobile: viaMobile,
 		geo,
 
 		// 以下非正規化データ
-		_reply: reply ? { user_id: reply.user_id } : undefined,
-		_repost: repost ? { user_id: repost.user_id } : undefined,
+		_reply: reply ? { userId: reply.userId } : undefined,
+		_repost: repost ? { userId: repost.userId } : undefined,
 	});
 
 	// Serialize
@@ -270,14 +270,14 @@ module.exports = (params, user: IUser, app) => new Promise(async (res, rej) => {
 
 	// Reponse
 	res({
-		created_post: postObj
+		createdPost: postObj
 	});
 
 	//#region Post processes
 
 	User.update({ _id: user._id }, {
 		$set: {
-			latest_post: post
+			latestPost: post
 		}
 	});
 
@@ -293,10 +293,10 @@ module.exports = (params, user: IUser, app) => new Promise(async (res, rej) => {
 		// Publish event
 		if (!user._id.equals(mentionee)) {
 			const mentioneeMutes = await Mute.find({
-				muter_id: mentionee,
-				deleted_at: { $exists: false }
+				muterId: mentionee,
+				deletedAt: { $exists: false }
 			});
-			const mentioneesMutedUserIds = mentioneeMutes.map(m => m.mutee_id.toString());
+			const mentioneesMutedUserIds = mentioneeMutes.map(m => m.muteeId.toString());
 			if (mentioneesMutedUserIds.indexOf(user._id.toString()) == -1) {
 				event(mentionee, reason, postObj);
 				pushSw(mentionee, reason, postObj);
@@ -312,17 +312,17 @@ module.exports = (params, user: IUser, app) => new Promise(async (res, rej) => {
 		// Fetch all followers
 		const followers = await Following
 			.find({
-				followee_id: user._id,
+				followeeId: user._id,
 				// 削除されたドキュメントは除く
-				deleted_at: { $exists: false }
+				deletedAt: { $exists: false }
 			}, {
-				follower_id: true,
+				followerId: true,
 				_id: false
 			});
 
 		// Publish event to followers stream
 		followers.forEach(following =>
-			event(following.follower_id, 'post', postObj));
+			event(following.followerId, 'post', postObj));
 	}
 
 	// チャンネルへの投稿
@@ -339,21 +339,21 @@ module.exports = (params, user: IUser, app) => new Promise(async (res, rej) => {
 
 		// Get channel watchers
 		const watches = await ChannelWatching.find({
-			channel_id: channel._id,
+			channelId: channel._id,
 			// 削除されたドキュメントは除く
-			deleted_at: { $exists: false }
+			deletedAt: { $exists: false }
 		});
 
 		// チャンネルの視聴者(のタイムライン)に配信
 		watches.forEach(w => {
-			event(w.user_id, 'post', postObj);
+			event(w.userId, 'post', postObj);
 		});
 	}
 
 	// Increment my posts count
 	User.update({ _id: user._id }, {
 		$inc: {
-			posts_count: 1
+			postsCount: 1
 		}
 	});
 
@@ -362,68 +362,68 @@ module.exports = (params, user: IUser, app) => new Promise(async (res, rej) => {
 		// Increment replies count
 		Post.update({ _id: reply._id }, {
 			$inc: {
-				replies_count: 1
+				repliesCount: 1
 			}
 		});
 
 		// 自分自身へのリプライでない限りは通知を作成
-		notify(reply.user_id, user._id, 'reply', {
-			post_id: post._id
+		notify(reply.userId, user._id, 'reply', {
+			postId: post._id
 		});
 
 		// Fetch watchers
 		Watching
 			.find({
-				post_id: reply._id,
-				user_id: { $ne: user._id },
+				postId: reply._id,
+				userId: { $ne: user._id },
 				// 削除されたドキュメントは除く
-				deleted_at: { $exists: false }
+				deletedAt: { $exists: false }
 			}, {
 				fields: {
-					user_id: true
+					userId: true
 				}
 			})
 			.then(watchers => {
 				watchers.forEach(watcher => {
-					notify(watcher.user_id, user._id, 'reply', {
-						post_id: post._id
+					notify(watcher.userId, user._id, 'reply', {
+						postId: post._id
 					});
 				});
 			});
 
 		// この投稿をWatchする
-		if ((user.account as ILocalAccount).settings.auto_watch !== false) {
+		if ((user.account as ILocalAccount).settings.autoWatch !== false) {
 			watch(user._id, reply);
 		}
 
 		// Add mention
-		addMention(reply.user_id, 'reply');
+		addMention(reply.userId, 'reply');
 	}
 
 	// If it is repost
 	if (repost) {
 		// Notify
 		const type = text ? 'quote' : 'repost';
-		notify(repost.user_id, user._id, type, {
-			post_id: post._id
+		notify(repost.userId, user._id, type, {
+			postId: post._id
 		});
 
 		// Fetch watchers
 		Watching
 			.find({
-				post_id: repost._id,
-				user_id: { $ne: user._id },
+				postId: repost._id,
+				userId: { $ne: user._id },
 				// 削除されたドキュメントは除く
-				deleted_at: { $exists: false }
+				deletedAt: { $exists: false }
 			}, {
 				fields: {
-					user_id: true
+					userId: true
 				}
 			})
 			.then(watchers => {
 				watchers.forEach(watcher => {
-					notify(watcher.user_id, user._id, type, {
-						post_id: post._id
+					notify(watcher.userId, user._id, type, {
+						postId: post._id
 					});
 				});
 			});
@@ -436,18 +436,18 @@ module.exports = (params, user: IUser, app) => new Promise(async (res, rej) => {
 		// If it is quote repost
 		if (text) {
 			// Add mention
-			addMention(repost.user_id, 'quote');
+			addMention(repost.userId, 'quote');
 		} else {
 			// Publish event
-			if (!user._id.equals(repost.user_id)) {
-				event(repost.user_id, 'repost', postObj);
+			if (!user._id.equals(repost.userId)) {
+				event(repost.userId, 'repost', postObj);
 			}
 		}
 
 		// 今までで同じ投稿をRepostしているか
 		const existRepost = await Post.findOne({
-			user_id: user._id,
-			repost_id: repost._id,
+			userId: user._id,
+			repostId: repost._id,
 			_id: {
 				$ne: post._id
 			}
@@ -457,7 +457,7 @@ module.exports = (params, user: IUser, app) => new Promise(async (res, rej) => {
 			// Update repostee status
 			Post.update({ _id: repost._id }, {
 				$inc: {
-					repost_count: 1
+					repostCount: 1
 				}
 			});
 		}
@@ -494,15 +494,15 @@ module.exports = (params, user: IUser, app) => new Promise(async (res, rej) => {
 			if (mentionee == null) return;
 
 			// 既に言及されたユーザーに対する返信や引用repostの場合も無視
-			if (reply && reply.user_id.equals(mentionee._id)) return;
-			if (repost && repost.user_id.equals(mentionee._id)) return;
+			if (reply && reply.userId.equals(mentionee._id)) return;
+			if (repost && repost.userId.equals(mentionee._id)) return;
 
 			// Add mention
 			addMention(mentionee._id, 'mention');
 
 			// Create notification
 			notify(mentionee._id, user._id, 'mention', {
-				post_id: post._id
+				postId: post._id
 			});
 
 			return;
diff --git a/src/server/api/endpoints/posts/favorites/create.ts b/src/server/api/endpoints/posts/favorites/create.ts
index f9dee271b..6100e10b2 100644
--- a/src/server/api/endpoints/posts/favorites/create.ts
+++ b/src/server/api/endpoints/posts/favorites/create.ts
@@ -13,9 +13,9 @@ import Post from '../../../models/post';
  * @return {Promise<any>}
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
-	// Get 'post_id' parameter
-	const [postId, postIdErr] = $(params.post_id).id().$;
-	if (postIdErr) return rej('invalid post_id param');
+	// Get 'postId' parameter
+	const [postId, postIdErr] = $(params.postId).id().$;
+	if (postIdErr) return rej('invalid postId param');
 
 	// Get favoritee
 	const post = await Post.findOne({
@@ -28,8 +28,8 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 
 	// if already favorited
 	const exist = await Favorite.findOne({
-		post_id: post._id,
-		user_id: user._id
+		postId: post._id,
+		userId: user._id
 	});
 
 	if (exist !== null) {
@@ -38,9 +38,9 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 
 	// Create favorite
 	await Favorite.insert({
-		created_at: new Date(),
-		post_id: post._id,
-		user_id: user._id
+		createdAt: new Date(),
+		postId: post._id,
+		userId: user._id
 	});
 
 	// Send response
diff --git a/src/server/api/endpoints/posts/favorites/delete.ts b/src/server/api/endpoints/posts/favorites/delete.ts
index c4fe7d323..db52036ec 100644
--- a/src/server/api/endpoints/posts/favorites/delete.ts
+++ b/src/server/api/endpoints/posts/favorites/delete.ts
@@ -13,9 +13,9 @@ import Post from '../../../models/post';
  * @return {Promise<any>}
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
-	// Get 'post_id' parameter
-	const [postId, postIdErr] = $(params.post_id).id().$;
-	if (postIdErr) return rej('invalid post_id param');
+	// Get 'postId' parameter
+	const [postId, postIdErr] = $(params.postId).id().$;
+	if (postIdErr) return rej('invalid postId param');
 
 	// Get favoritee
 	const post = await Post.findOne({
@@ -28,8 +28,8 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 
 	// if already favorited
 	const exist = await Favorite.findOne({
-		post_id: post._id,
-		user_id: user._id
+		postId: post._id,
+		userId: user._id
 	});
 
 	if (exist === null) {
@@ -37,7 +37,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	}
 
 	// Delete favorite
-	await Favorite.deleteOne({
+	await Favorite.remove({
 		_id: exist._id
 	});
 
diff --git a/src/server/api/endpoints/posts/mentions.ts b/src/server/api/endpoints/posts/mentions.ts
index 7127db0ad..1b342e8de 100644
--- a/src/server/api/endpoints/posts/mentions.ts
+++ b/src/server/api/endpoints/posts/mentions.ts
@@ -23,17 +23,17 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
 	if (limitErr) return rej('invalid limit param');
 
-	// Get 'since_id' parameter
-	const [sinceId, sinceIdErr] = $(params.since_id).optional.id().$;
-	if (sinceIdErr) return rej('invalid since_id param');
+	// Get 'sinceId' parameter
+	const [sinceId, sinceIdErr] = $(params.sinceId).optional.id().$;
+	if (sinceIdErr) return rej('invalid sinceId param');
 
-	// Get 'until_id' parameter
-	const [untilId, untilIdErr] = $(params.until_id).optional.id().$;
-	if (untilIdErr) return rej('invalid until_id param');
+	// Get 'untilId' parameter
+	const [untilId, untilIdErr] = $(params.untilId).optional.id().$;
+	if (untilIdErr) return rej('invalid untilId param');
 
-	// Check if both of since_id and until_id is specified
+	// Check if both of sinceId and untilId is specified
 	if (sinceId && untilId) {
-		return rej('cannot set since_id and until_id');
+		return rej('cannot set sinceId and untilId');
 	}
 
 	// Construct query
@@ -48,7 +48,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	if (following) {
 		const followingIds = await getFriends(user._id);
 
-		query.user_id = {
+		query.userId = {
 			$in: followingIds
 		};
 	}
diff --git a/src/server/api/endpoints/posts/polls/recommendation.ts b/src/server/api/endpoints/posts/polls/recommendation.ts
index 4a3fa3f55..19ef0975f 100644
--- a/src/server/api/endpoints/posts/polls/recommendation.ts
+++ b/src/server/api/endpoints/posts/polls/recommendation.ts
@@ -23,22 +23,22 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 
 	// Get votes
 	const votes = await Vote.find({
-		user_id: user._id
+		userId: user._id
 	}, {
 		fields: {
 			_id: false,
-			post_id: true
+			postId: true
 		}
 	});
 
-	const nin = votes && votes.length != 0 ? votes.map(v => v.post_id) : [];
+	const nin = votes && votes.length != 0 ? votes.map(v => v.postId) : [];
 
 	const posts = await Post
 		.find({
 			_id: {
 				$nin: nin
 			},
-			user_id: {
+			userId: {
 				$ne: user._id
 			},
 			poll: {
diff --git a/src/server/api/endpoints/posts/polls/vote.ts b/src/server/api/endpoints/posts/polls/vote.ts
index 16ce76a6f..734a3a3c4 100644
--- a/src/server/api/endpoints/posts/polls/vote.ts
+++ b/src/server/api/endpoints/posts/polls/vote.ts
@@ -17,9 +17,9 @@ import { publishPostStream } from '../../../event';
  * @return {Promise<any>}
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
-	// Get 'post_id' parameter
-	const [postId, postIdErr] = $(params.post_id).id().$;
-	if (postIdErr) return rej('invalid post_id param');
+	// Get 'postId' parameter
+	const [postId, postIdErr] = $(params.postId).id().$;
+	if (postIdErr) return rej('invalid postId param');
 
 	// Get votee
 	const post = await Post.findOne({
@@ -43,8 +43,8 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 
 	// if already voted
 	const exist = await Vote.findOne({
-		post_id: post._id,
-		user_id: user._id
+		postId: post._id,
+		userId: user._id
 	});
 
 	if (exist !== null) {
@@ -53,9 +53,9 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 
 	// Create vote
 	await Vote.insert({
-		created_at: new Date(),
-		post_id: post._id,
-		user_id: user._id,
+		createdAt: new Date(),
+		postId: post._id,
+		userId: user._id,
 		choice: choice
 	});
 
@@ -73,34 +73,34 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	publishPostStream(post._id, 'poll_voted');
 
 	// Notify
-	notify(post.user_id, user._id, 'poll_vote', {
-		post_id: post._id,
+	notify(post.userId, user._id, 'poll_vote', {
+		postId: post._id,
 		choice: choice
 	});
 
 	// Fetch watchers
 	Watching
 		.find({
-			post_id: post._id,
-			user_id: { $ne: user._id },
+			postId: post._id,
+			userId: { $ne: user._id },
 			// 削除されたドキュメントは除く
-			deleted_at: { $exists: false }
+			deletedAt: { $exists: false }
 		}, {
 			fields: {
-				user_id: true
+				userId: true
 			}
 		})
 		.then(watchers => {
 			watchers.forEach(watcher => {
-				notify(watcher.user_id, user._id, 'poll_vote', {
-					post_id: post._id,
+				notify(watcher.userId, user._id, 'poll_vote', {
+					postId: post._id,
 					choice: choice
 				});
 			});
 		});
 
 	// この投稿をWatchする
-	if (user.account.settings.auto_watch !== false) {
+	if (user.account.settings.autoWatch !== false) {
 		watch(user._id, post);
 	}
 });
diff --git a/src/server/api/endpoints/posts/reactions.ts b/src/server/api/endpoints/posts/reactions.ts
index feb140ab4..f753ba7c2 100644
--- a/src/server/api/endpoints/posts/reactions.ts
+++ b/src/server/api/endpoints/posts/reactions.ts
@@ -13,9 +13,9 @@ import Reaction, { pack } from '../../models/post-reaction';
  * @return {Promise<any>}
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
-	// Get 'post_id' parameter
-	const [postId, postIdErr] = $(params.post_id).id().$;
-	if (postIdErr) return rej('invalid post_id param');
+	// Get 'postId' parameter
+	const [postId, postIdErr] = $(params.postId).id().$;
+	if (postIdErr) return rej('invalid postId param');
 
 	// Get 'limit' parameter
 	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
@@ -41,8 +41,8 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Issue query
 	const reactions = await Reaction
 		.find({
-			post_id: post._id,
-			deleted_at: { $exists: false }
+			postId: post._id,
+			deletedAt: { $exists: false }
 		}, {
 			limit: limit,
 			skip: offset,
diff --git a/src/server/api/endpoints/posts/reactions/create.ts b/src/server/api/endpoints/posts/reactions/create.ts
index f77afed40..a1e677980 100644
--- a/src/server/api/endpoints/posts/reactions/create.ts
+++ b/src/server/api/endpoints/posts/reactions/create.ts
@@ -18,9 +18,9 @@ import { publishPostStream, pushSw } from '../../../event';
  * @return {Promise<any>}
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
-	// Get 'post_id' parameter
-	const [postId, postIdErr] = $(params.post_id).id().$;
-	if (postIdErr) return rej('invalid post_id param');
+	// Get 'postId' parameter
+	const [postId, postIdErr] = $(params.postId).id().$;
+	if (postIdErr) return rej('invalid postId param');
 
 	// Get 'reaction' parameter
 	const [reaction, reactionErr] = $(params.reaction).string().or([
@@ -46,15 +46,15 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	}
 
 	// Myself
-	if (post.user_id.equals(user._id)) {
+	if (post.userId.equals(user._id)) {
 		return rej('cannot react to my post');
 	}
 
 	// if already reacted
 	const exist = await Reaction.findOne({
-		post_id: post._id,
-		user_id: user._id,
-		deleted_at: { $exists: false }
+		postId: post._id,
+		userId: user._id,
+		deletedAt: { $exists: false }
 	});
 
 	if (exist !== null) {
@@ -63,9 +63,9 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 
 	// Create reaction
 	await Reaction.insert({
-		created_at: new Date(),
-		post_id: post._id,
-		user_id: user._id,
+		createdAt: new Date(),
+		postId: post._id,
+		userId: user._id,
 		reaction: reaction
 	});
 
@@ -73,7 +73,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	res();
 
 	const inc = {};
-	inc[`reaction_counts.${reaction}`] = 1;
+	inc[`reactionCounts.${reaction}`] = 1;
 
 	// Increment reactions count
 	await Post.update({ _id: post._id }, {
@@ -83,40 +83,40 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	publishPostStream(post._id, 'reacted');
 
 	// Notify
-	notify(post.user_id, user._id, 'reaction', {
-		post_id: post._id,
+	notify(post.userId, user._id, 'reaction', {
+		postId: post._id,
 		reaction: reaction
 	});
 
-	pushSw(post.user_id, 'reaction', {
-		user: await packUser(user, post.user_id),
-		post: await packPost(post, post.user_id),
+	pushSw(post.userId, 'reaction', {
+		user: await packUser(user, post.userId),
+		post: await packPost(post, post.userId),
 		reaction: reaction
 	});
 
 	// Fetch watchers
 	Watching
 		.find({
-			post_id: post._id,
-			user_id: { $ne: user._id },
+			postId: post._id,
+			userId: { $ne: user._id },
 			// 削除されたドキュメントは除く
-			deleted_at: { $exists: false }
+			deletedAt: { $exists: false }
 		}, {
 			fields: {
-				user_id: true
+				userId: true
 			}
 		})
 		.then(watchers => {
 			watchers.forEach(watcher => {
-				notify(watcher.user_id, user._id, 'reaction', {
-					post_id: post._id,
+				notify(watcher.userId, user._id, 'reaction', {
+					postId: post._id,
 					reaction: reaction
 				});
 			});
 		});
 
 	// この投稿をWatchする
-	if (user.account.settings.auto_watch !== false) {
+	if (user.account.settings.autoWatch !== false) {
 		watch(user._id, post);
 	}
 });
diff --git a/src/server/api/endpoints/posts/reactions/delete.ts b/src/server/api/endpoints/posts/reactions/delete.ts
index 922c57ab1..b09bcbb4b 100644
--- a/src/server/api/endpoints/posts/reactions/delete.ts
+++ b/src/server/api/endpoints/posts/reactions/delete.ts
@@ -14,9 +14,9 @@ import Post from '../../../models/post';
  * @return {Promise<any>}
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
-	// Get 'post_id' parameter
-	const [postId, postIdErr] = $(params.post_id).id().$;
-	if (postIdErr) return rej('invalid post_id param');
+	// Get 'postId' parameter
+	const [postId, postIdErr] = $(params.postId).id().$;
+	if (postIdErr) return rej('invalid postId param');
 
 	// Fetch unreactee
 	const post = await Post.findOne({
@@ -29,9 +29,9 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 
 	// if already unreacted
 	const exist = await Reaction.findOne({
-		post_id: post._id,
-		user_id: user._id,
-		deleted_at: { $exists: false }
+		postId: post._id,
+		userId: user._id,
+		deletedAt: { $exists: false }
 	});
 
 	if (exist === null) {
@@ -43,7 +43,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 		_id: exist._id
 	}, {
 			$set: {
-				deleted_at: new Date()
+				deletedAt: new Date()
 			}
 		});
 
@@ -51,7 +51,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	res();
 
 	const dec = {};
-	dec[`reaction_counts.${exist.reaction}`] = -1;
+	dec[`reactionCounts.${exist.reaction}`] = -1;
 
 	// Decrement reactions count
 	Post.update({ _id: post._id }, {
diff --git a/src/server/api/endpoints/posts/replies.ts b/src/server/api/endpoints/posts/replies.ts
index 613c4fa24..db021505f 100644
--- a/src/server/api/endpoints/posts/replies.ts
+++ b/src/server/api/endpoints/posts/replies.ts
@@ -12,9 +12,9 @@ import Post, { pack } from '../../models/post';
  * @return {Promise<any>}
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
-	// Get 'post_id' parameter
-	const [postId, postIdErr] = $(params.post_id).id().$;
-	if (postIdErr) return rej('invalid post_id param');
+	// Get 'postId' parameter
+	const [postId, postIdErr] = $(params.postId).id().$;
+	if (postIdErr) return rej('invalid postId param');
 
 	// Get 'limit' parameter
 	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
@@ -39,7 +39,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 
 	// Issue query
 	const replies = await Post
-		.find({ reply_id: post._id }, {
+		.find({ replyId: post._id }, {
 			limit: limit,
 			skip: offset,
 			sort: {
diff --git a/src/server/api/endpoints/posts/reposts.ts b/src/server/api/endpoints/posts/reposts.ts
index 89ab0e3d5..51af41f52 100644
--- a/src/server/api/endpoints/posts/reposts.ts
+++ b/src/server/api/endpoints/posts/reposts.ts
@@ -12,25 +12,25 @@ import Post, { pack } from '../../models/post';
  * @return {Promise<any>}
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
-	// Get 'post_id' parameter
-	const [postId, postIdErr] = $(params.post_id).id().$;
-	if (postIdErr) return rej('invalid post_id param');
+	// Get 'postId' parameter
+	const [postId, postIdErr] = $(params.postId).id().$;
+	if (postIdErr) return rej('invalid postId param');
 
 	// Get 'limit' parameter
 	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
 	if (limitErr) return rej('invalid limit param');
 
-	// Get 'since_id' parameter
-	const [sinceId, sinceIdErr] = $(params.since_id).optional.id().$;
-	if (sinceIdErr) return rej('invalid since_id param');
+	// Get 'sinceId' parameter
+	const [sinceId, sinceIdErr] = $(params.sinceId).optional.id().$;
+	if (sinceIdErr) return rej('invalid sinceId param');
 
-	// Get 'until_id' parameter
-	const [untilId, untilIdErr] = $(params.until_id).optional.id().$;
-	if (untilIdErr) return rej('invalid until_id param');
+	// Get 'untilId' parameter
+	const [untilId, untilIdErr] = $(params.untilId).optional.id().$;
+	if (untilIdErr) return rej('invalid untilId param');
 
-	// Check if both of since_id and until_id is specified
+	// Check if both of sinceId and untilId is specified
 	if (sinceId && untilId) {
-		return rej('cannot set since_id and until_id');
+		return rej('cannot set sinceId and untilId');
 	}
 
 	// Lookup post
@@ -47,7 +47,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 		_id: -1
 	};
 	const query = {
-		repost_id: post._id
+		repostId: post._id
 	} as any;
 	if (sinceId) {
 		sort._id = 1;
diff --git a/src/server/api/endpoints/posts/search.ts b/src/server/api/endpoints/posts/search.ts
index a36d1178a..bb5c43892 100644
--- a/src/server/api/endpoints/posts/search.ts
+++ b/src/server/api/endpoints/posts/search.ts
@@ -21,21 +21,21 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
 	const [text, textError] = $(params.text).optional.string().$;
 	if (textError) return rej('invalid text param');
 
-	// Get 'include_user_ids' parameter
-	const [includeUserIds = [], includeUserIdsErr] = $(params.include_user_ids).optional.array('id').$;
-	if (includeUserIdsErr) return rej('invalid include_user_ids param');
+	// Get 'includeUserIds' parameter
+	const [includeUserIds = [], includeUserIdsErr] = $(params.includeUserIds).optional.array('id').$;
+	if (includeUserIdsErr) return rej('invalid includeUserIds param');
 
-	// Get 'exclude_user_ids' parameter
-	const [excludeUserIds = [], excludeUserIdsErr] = $(params.exclude_user_ids).optional.array('id').$;
-	if (excludeUserIdsErr) return rej('invalid exclude_user_ids param');
+	// Get 'excludeUserIds' parameter
+	const [excludeUserIds = [], excludeUserIdsErr] = $(params.excludeUserIds).optional.array('id').$;
+	if (excludeUserIdsErr) return rej('invalid excludeUserIds param');
 
-	// Get 'include_user_usernames' parameter
-	const [includeUserUsernames = [], includeUserUsernamesErr] = $(params.include_user_usernames).optional.array('string').$;
-	if (includeUserUsernamesErr) return rej('invalid include_user_usernames param');
+	// Get 'includeUserUsernames' parameter
+	const [includeUserUsernames = [], includeUserUsernamesErr] = $(params.includeUserUsernames).optional.array('string').$;
+	if (includeUserUsernamesErr) return rej('invalid includeUserUsernames param');
 
-	// Get 'exclude_user_usernames' parameter
-	const [excludeUserUsernames = [], excludeUserUsernamesErr] = $(params.exclude_user_usernames).optional.array('string').$;
-	if (excludeUserUsernamesErr) return rej('invalid exclude_user_usernames param');
+	// Get 'excludeUserUsernames' parameter
+	const [excludeUserUsernames = [], excludeUserUsernamesErr] = $(params.excludeUserUsernames).optional.array('string').$;
+	if (excludeUserUsernamesErr) return rej('invalid excludeUserUsernames param');
 
 	// Get 'following' parameter
 	const [following = null, followingErr] = $(params.following).optional.nullable.boolean().$;
@@ -61,13 +61,13 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
 	const [poll = null, pollErr] = $(params.poll).optional.nullable.boolean().$;
 	if (pollErr) return rej('invalid poll param');
 
-	// Get 'since_date' parameter
-	const [sinceDate, sinceDateErr] = $(params.since_date).optional.number().$;
-	if (sinceDateErr) throw 'invalid since_date param';
+	// Get 'sinceDate' parameter
+	const [sinceDate, sinceDateErr] = $(params.sinceDate).optional.number().$;
+	if (sinceDateErr) throw 'invalid sinceDate param';
 
-	// Get 'until_date' parameter
-	const [untilDate, untilDateErr] = $(params.until_date).optional.number().$;
-	if (untilDateErr) throw 'invalid until_date param';
+	// Get 'untilDate' parameter
+	const [untilDate, untilDateErr] = $(params.untilDate).optional.number().$;
+	if (untilDateErr) throw 'invalid untilDate param';
 
 	// Get 'offset' parameter
 	const [offset = 0, offsetErr] = $(params.offset).optional.number().min(0).$;
@@ -81,7 +81,7 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
 	if (includeUserUsernames != null) {
 		const ids = (await Promise.all(includeUserUsernames.map(async (username) => {
 			const _user = await User.findOne({
-				username_lower: username.toLowerCase()
+				usernameLower: username.toLowerCase()
 			});
 			return _user ? _user._id : null;
 		}))).filter(id => id != null);
@@ -92,7 +92,7 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
 	if (excludeUserUsernames != null) {
 		const ids = (await Promise.all(excludeUserUsernames.map(async (username) => {
 			const _user = await User.findOne({
-				username_lower: username.toLowerCase()
+				usernameLower: username.toLowerCase()
 			});
 			return _user ? _user._id : null;
 		}))).filter(id => id != null);
@@ -143,13 +143,13 @@ async function search(
 
 	if (includeUserIds && includeUserIds.length != 0) {
 		push({
-			user_id: {
+			userId: {
 				$in: includeUserIds
 			}
 		});
 	} else if (excludeUserIds && excludeUserIds.length != 0) {
 		push({
-			user_id: {
+			userId: {
 				$nin: excludeUserIds
 			}
 		});
@@ -158,7 +158,7 @@ async function search(
 	if (following != null && me != null) {
 		const ids = await getFriends(me._id, false);
 		push({
-			user_id: following ? {
+			userId: following ? {
 				$in: ids
 			} : {
 				$nin: ids.concat(me._id)
@@ -168,45 +168,45 @@ async function search(
 
 	if (me != null) {
 		const mutes = await Mute.find({
-			muter_id: me._id,
-			deleted_at: { $exists: false }
+			muterId: me._id,
+			deletedAt: { $exists: false }
 		});
-		const mutedUserIds = mutes.map(m => m.mutee_id);
+		const mutedUserIds = mutes.map(m => m.muteeId);
 
 		switch (mute) {
 			case 'mute_all':
 				push({
-					user_id: {
+					userId: {
 						$nin: mutedUserIds
 					},
-					'_reply.user_id': {
+					'_reply.userId': {
 						$nin: mutedUserIds
 					},
-					'_repost.user_id': {
+					'_repost.userId': {
 						$nin: mutedUserIds
 					}
 				});
 				break;
 			case 'mute_related':
 				push({
-					'_reply.user_id': {
+					'_reply.userId': {
 						$nin: mutedUserIds
 					},
-					'_repost.user_id': {
+					'_repost.userId': {
 						$nin: mutedUserIds
 					}
 				});
 				break;
 			case 'mute_direct':
 				push({
-					user_id: {
+					userId: {
 						$nin: mutedUserIds
 					}
 				});
 				break;
 			case 'direct_only':
 				push({
-					user_id: {
+					userId: {
 						$in: mutedUserIds
 					}
 				});
@@ -214,11 +214,11 @@ async function search(
 			case 'related_only':
 				push({
 					$or: [{
-						'_reply.user_id': {
+						'_reply.userId': {
 							$in: mutedUserIds
 						}
 					}, {
-						'_repost.user_id': {
+						'_repost.userId': {
 							$in: mutedUserIds
 						}
 					}]
@@ -227,15 +227,15 @@ async function search(
 			case 'all_only':
 				push({
 					$or: [{
-						user_id: {
+						userId: {
 							$in: mutedUserIds
 						}
 					}, {
-						'_reply.user_id': {
+						'_reply.userId': {
 							$in: mutedUserIds
 						}
 					}, {
-						'_repost.user_id': {
+						'_repost.userId': {
 							$in: mutedUserIds
 						}
 					}]
@@ -247,7 +247,7 @@ async function search(
 	if (reply != null) {
 		if (reply) {
 			push({
-				reply_id: {
+				replyId: {
 					$exists: true,
 					$ne: null
 				}
@@ -255,11 +255,11 @@ async function search(
 		} else {
 			push({
 				$or: [{
-					reply_id: {
+					replyId: {
 						$exists: false
 					}
 				}, {
-					reply_id: null
+					replyId: null
 				}]
 			});
 		}
@@ -268,7 +268,7 @@ async function search(
 	if (repost != null) {
 		if (repost) {
 			push({
-				repost_id: {
+				repostId: {
 					$exists: true,
 					$ne: null
 				}
@@ -276,11 +276,11 @@ async function search(
 		} else {
 			push({
 				$or: [{
-					repost_id: {
+					repostId: {
 						$exists: false
 					}
 				}, {
-					repost_id: null
+					repostId: null
 				}]
 			});
 		}
@@ -289,7 +289,7 @@ async function search(
 	if (media != null) {
 		if (media) {
 			push({
-				media_ids: {
+				mediaIds: {
 					$exists: true,
 					$ne: null
 				}
@@ -297,11 +297,11 @@ async function search(
 		} else {
 			push({
 				$or: [{
-					media_ids: {
+					mediaIds: {
 						$exists: false
 					}
 				}, {
-					media_ids: null
+					mediaIds: null
 				}]
 			});
 		}
@@ -330,7 +330,7 @@ async function search(
 
 	if (sinceDate) {
 		push({
-			created_at: {
+			createdAt: {
 				$gt: new Date(sinceDate)
 			}
 		});
@@ -338,7 +338,7 @@ async function search(
 
 	if (untilDate) {
 		push({
-			created_at: {
+			createdAt: {
 				$lt: new Date(untilDate)
 			}
 		});
diff --git a/src/server/api/endpoints/posts/show.ts b/src/server/api/endpoints/posts/show.ts
index 383949059..bb4bcdb79 100644
--- a/src/server/api/endpoints/posts/show.ts
+++ b/src/server/api/endpoints/posts/show.ts
@@ -12,9 +12,9 @@ import Post, { pack } from '../../models/post';
  * @return {Promise<any>}
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
-	// Get 'post_id' parameter
-	const [postId, postIdErr] = $(params.post_id).id().$;
-	if (postIdErr) return rej('invalid post_id param');
+	// Get 'postId' parameter
+	const [postId, postIdErr] = $(params.postId).id().$;
+	if (postIdErr) return rej('invalid postId param');
 
 	// Get post
 	const post = await Post.findOne({
diff --git a/src/server/api/endpoints/posts/timeline.ts b/src/server/api/endpoints/posts/timeline.ts
index c41cfdb8b..a3e915f16 100644
--- a/src/server/api/endpoints/posts/timeline.ts
+++ b/src/server/api/endpoints/posts/timeline.ts
@@ -22,25 +22,25 @@ module.exports = async (params, user, app) => {
 	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
 	if (limitErr) throw 'invalid limit param';
 
-	// Get 'since_id' parameter
-	const [sinceId, sinceIdErr] = $(params.since_id).optional.id().$;
-	if (sinceIdErr) throw 'invalid since_id param';
+	// Get 'sinceId' parameter
+	const [sinceId, sinceIdErr] = $(params.sinceId).optional.id().$;
+	if (sinceIdErr) throw 'invalid sinceId param';
 
-	// Get 'until_id' parameter
-	const [untilId, untilIdErr] = $(params.until_id).optional.id().$;
-	if (untilIdErr) throw 'invalid until_id param';
+	// Get 'untilId' parameter
+	const [untilId, untilIdErr] = $(params.untilId).optional.id().$;
+	if (untilIdErr) throw 'invalid untilId param';
 
-	// Get 'since_date' parameter
-	const [sinceDate, sinceDateErr] = $(params.since_date).optional.number().$;
-	if (sinceDateErr) throw 'invalid since_date param';
+	// Get 'sinceDate' parameter
+	const [sinceDate, sinceDateErr] = $(params.sinceDate).optional.number().$;
+	if (sinceDateErr) throw 'invalid sinceDate param';
 
-	// Get 'until_date' parameter
-	const [untilDate, untilDateErr] = $(params.until_date).optional.number().$;
-	if (untilDateErr) throw 'invalid until_date param';
+	// Get 'untilDate' parameter
+	const [untilDate, untilDateErr] = $(params.untilDate).optional.number().$;
+	if (untilDateErr) throw 'invalid untilDate param';
 
-	// Check if only one of since_id, until_id, since_date, until_date specified
+	// Check if only one of sinceId, untilId, sinceDate, untilDate specified
 	if ([sinceId, untilId, sinceDate, untilDate].filter(x => x != null).length > 1) {
-		throw 'only one of since_id, until_id, since_date, until_date can be specified';
+		throw 'only one of sinceId, untilId, sinceDate, untilDate can be specified';
 	}
 
 	const { followingIds, watchingChannelIds, mutedUserIds } = await rap({
@@ -49,17 +49,17 @@ module.exports = async (params, user, app) => {
 
 		// Watchしているチャンネルを取得
 		watchingChannelIds: ChannelWatching.find({
-			user_id: user._id,
+			userId: user._id,
 			// 削除されたドキュメントは除く
-			deleted_at: { $exists: false }
-		}).then(watches => watches.map(w => w.channel_id)),
+			deletedAt: { $exists: false }
+		}).then(watches => watches.map(w => w.channelId)),
 
 		// ミュートしているユーザーを取得
 		mutedUserIds: Mute.find({
-			muter_id: user._id,
+			muterId: user._id,
 			// 削除されたドキュメントは除く
-			deleted_at: { $exists: false }
-		}).then(ms => ms.map(m => m.mutee_id))
+			deletedAt: { $exists: false }
+		}).then(ms => ms.map(m => m.muteeId))
 	});
 
 	//#region Construct query
@@ -70,31 +70,31 @@ module.exports = async (params, user, app) => {
 	const query = {
 		$or: [{
 			// フォローしている人のタイムラインへの投稿
-			user_id: {
+			userId: {
 				$in: followingIds
 			},
 			// 「タイムラインへの」投稿に限定するためにチャンネルが指定されていないもののみに限る
 			$or: [{
-				channel_id: {
+				channelId: {
 					$exists: false
 				}
 			}, {
-				channel_id: null
+				channelId: null
 			}]
 		}, {
 			// Watchしているチャンネルへの投稿
-			channel_id: {
+			channelId: {
 				$in: watchingChannelIds
 			}
 		}],
 		// mute
-		user_id: {
+		userId: {
 			$nin: mutedUserIds
 		},
-		'_reply.user_id': {
+		'_reply.userId': {
 			$nin: mutedUserIds
 		},
-		'_repost.user_id': {
+		'_repost.userId': {
 			$nin: mutedUserIds
 		},
 	} as any;
@@ -110,11 +110,11 @@ module.exports = async (params, user, app) => {
 		};
 	} else if (sinceDate) {
 		sort._id = 1;
-		query.created_at = {
+		query.createdAt = {
 			$gt: new Date(sinceDate)
 		};
 	} else if (untilDate) {
-		query.created_at = {
+		query.createdAt = {
 			$lt: new Date(untilDate)
 		};
 	}
diff --git a/src/server/api/endpoints/posts/trend.ts b/src/server/api/endpoints/posts/trend.ts
index caded92bf..bc0c47fbc 100644
--- a/src/server/api/endpoints/posts/trend.ts
+++ b/src/server/api/endpoints/posts/trend.ts
@@ -38,24 +38,24 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	if (pollErr) return rej('invalid poll param');
 
 	const query = {
-		created_at: {
+		createdAt: {
 			$gte: new Date(Date.now() - ms('1days'))
 		},
-		repost_count: {
+		repostCount: {
 			$gt: 0
 		}
 	} as any;
 
 	if (reply != undefined) {
-		query.reply_id = reply ? { $exists: true, $ne: null } : null;
+		query.replyId = reply ? { $exists: true, $ne: null } : null;
 	}
 
 	if (repost != undefined) {
-		query.repost_id = repost ? { $exists: true, $ne: null } : null;
+		query.repostId = repost ? { $exists: true, $ne: null } : null;
 	}
 
 	if (media != undefined) {
-		query.media_ids = media ? { $exists: true, $ne: null } : null;
+		query.mediaIds = media ? { $exists: true, $ne: null } : null;
 	}
 
 	if (poll != undefined) {
@@ -68,7 +68,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 			limit: limit,
 			skip: offset,
 			sort: {
-				repost_count: -1,
+				repostCount: -1,
 				_id: -1
 			}
 		});
diff --git a/src/server/api/endpoints/stats.ts b/src/server/api/endpoints/stats.ts
index a6084cd17..719792d40 100644
--- a/src/server/api/endpoints/stats.ts
+++ b/src/server/api/endpoints/stats.ts
@@ -15,10 +15,10 @@ import User from '../models/user';
  *         schema:
  *           type: object
  *           properties:
- *             posts_count:
+ *             postsCount:
  *               description: count of all posts of misskey
  *               type: number
- *             users_count:
+ *             usersCount:
  *               description: count of all users of misskey
  *               type: number
  *
@@ -42,7 +42,7 @@ module.exports = params => new Promise(async (res, rej) => {
 		.count();
 
 	res({
-		posts_count: postsCount,
-		users_count: usersCount
+		postsCount: postsCount,
+		usersCount: usersCount
 	});
 });
diff --git a/src/server/api/endpoints/sw/register.ts b/src/server/api/endpoints/sw/register.ts
index 99406138d..1542e1dbe 100644
--- a/src/server/api/endpoints/sw/register.ts
+++ b/src/server/api/endpoints/sw/register.ts
@@ -28,11 +28,11 @@ module.exports = async (params, user, _, isSecure) => new Promise(async (res, re
 
 	// if already subscribed
 	const exist = await Subscription.findOne({
-		user_id: user._id,
+		userId: user._id,
 		endpoint: endpoint,
 		auth: auth,
 		publickey: publickey,
-		deleted_at: { $exists: false }
+		deletedAt: { $exists: false }
 	});
 
 	if (exist !== null) {
@@ -40,7 +40,7 @@ module.exports = async (params, user, _, isSecure) => new Promise(async (res, re
 	}
 
 	await Subscription.insert({
-		user_id: user._id,
+		userId: user._id,
 		endpoint: endpoint,
 		auth: auth,
 		publickey: publickey
diff --git a/src/server/api/endpoints/username/available.ts b/src/server/api/endpoints/username/available.ts
index aac7fadf5..f23cdbd85 100644
--- a/src/server/api/endpoints/username/available.ts
+++ b/src/server/api/endpoints/username/available.ts
@@ -20,7 +20,7 @@ module.exports = async (params) => new Promise(async (res, rej) => {
 	const exist = await User
 		.count({
 			host: null,
-			username_lower: username.toLowerCase()
+			usernameLower: username.toLowerCase()
 		}, {
 			limit: 1
 		});
diff --git a/src/server/api/endpoints/users.ts b/src/server/api/endpoints/users.ts
index 4acc13c28..393c3479c 100644
--- a/src/server/api/endpoints/users.ts
+++ b/src/server/api/endpoints/users.ts
@@ -29,11 +29,11 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
 	if (sort) {
 		if (sort == '+follower') {
 			_sort = {
-				followers_count: -1
+				followersCount: -1
 			};
 		} else if (sort == '-follower') {
 			_sort = {
-				followers_count: 1
+				followersCount: 1
 			};
 		}
 	} else {
diff --git a/src/server/api/endpoints/users/followers.ts b/src/server/api/endpoints/users/followers.ts
index b0fb83c68..fc09cfa2c 100644
--- a/src/server/api/endpoints/users/followers.ts
+++ b/src/server/api/endpoints/users/followers.ts
@@ -15,9 +15,9 @@ import getFriends from '../../common/get-friends';
  * @return {Promise<any>}
  */
 module.exports = (params, me) => new Promise(async (res, rej) => {
-	// Get 'user_id' parameter
-	const [userId, userIdErr] = $(params.user_id).id().$;
-	if (userIdErr) return rej('invalid user_id param');
+	// Get 'userId' parameter
+	const [userId, userIdErr] = $(params.userId).id().$;
+	if (userIdErr) return rej('invalid userId param');
 
 	// Get 'iknow' parameter
 	const [iknow = false, iknowErr] = $(params.iknow).optional.boolean().$;
@@ -46,8 +46,8 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
 
 	// Construct query
 	const query = {
-		followee_id: user._id,
-		deleted_at: { $exists: false }
+		followeeId: user._id,
+		deletedAt: { $exists: false }
 	} as any;
 
 	// ログインしていてかつ iknow フラグがあるとき
@@ -55,7 +55,7 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
 		// Get my friends
 		const myFriends = await getFriends(me._id);
 
-		query.follower_id = {
+		query.followerId = {
 			$in: myFriends
 		};
 	}
@@ -82,7 +82,7 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
 
 	// Serialize
 	const users = await Promise.all(following.map(async f =>
-		await pack(f.follower_id, me, { detail: true })));
+		await pack(f.followerId, me, { detail: true })));
 
 	// Response
 	res({
diff --git a/src/server/api/endpoints/users/following.ts b/src/server/api/endpoints/users/following.ts
index 8e88431e9..3387dab36 100644
--- a/src/server/api/endpoints/users/following.ts
+++ b/src/server/api/endpoints/users/following.ts
@@ -15,9 +15,9 @@ import getFriends from '../../common/get-friends';
  * @return {Promise<any>}
  */
 module.exports = (params, me) => new Promise(async (res, rej) => {
-	// Get 'user_id' parameter
-	const [userId, userIdErr] = $(params.user_id).id().$;
-	if (userIdErr) return rej('invalid user_id param');
+	// Get 'userId' parameter
+	const [userId, userIdErr] = $(params.userId).id().$;
+	if (userIdErr) return rej('invalid userId param');
 
 	// Get 'iknow' parameter
 	const [iknow = false, iknowErr] = $(params.iknow).optional.boolean().$;
@@ -46,8 +46,8 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
 
 	// Construct query
 	const query = {
-		follower_id: user._id,
-		deleted_at: { $exists: false }
+		followerId: user._id,
+		deletedAt: { $exists: false }
 	} as any;
 
 	// ログインしていてかつ iknow フラグがあるとき
@@ -55,7 +55,7 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
 		// Get my friends
 		const myFriends = await getFriends(me._id);
 
-		query.followee_id = {
+		query.followeeId = {
 			$in: myFriends
 		};
 	}
@@ -82,7 +82,7 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
 
 	// Serialize
 	const users = await Promise.all(following.map(async f =>
-		await pack(f.followee_id, me, { detail: true })));
+		await pack(f.followeeId, me, { detail: true })));
 
 	// Response
 	res({
diff --git a/src/server/api/endpoints/users/get_frequently_replied_users.ts b/src/server/api/endpoints/users/get_frequently_replied_users.ts
index 87f4f77a5..991c5555b 100644
--- a/src/server/api/endpoints/users/get_frequently_replied_users.ts
+++ b/src/server/api/endpoints/users/get_frequently_replied_users.ts
@@ -6,9 +6,9 @@ import Post from '../../models/post';
 import User, { pack } from '../../models/user';
 
 module.exports = (params, me) => new Promise(async (res, rej) => {
-	// Get 'user_id' parameter
-	const [userId, userIdErr] = $(params.user_id).id().$;
-	if (userIdErr) return rej('invalid user_id param');
+	// Get 'userId' parameter
+	const [userId, userIdErr] = $(params.userId).id().$;
+	if (userIdErr) return rej('invalid userId param');
 
 	// Get 'limit' parameter
 	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
@@ -29,8 +29,8 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
 
 	// Fetch recent posts
 	const recentPosts = await Post.find({
-		user_id: user._id,
-		reply_id: {
+		userId: user._id,
+		replyId: {
 			$exists: true,
 			$ne: null
 		}
@@ -41,7 +41,7 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
 		limit: 1000,
 		fields: {
 			_id: false,
-			reply_id: true
+			replyId: true
 		}
 	});
 
@@ -52,15 +52,15 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
 
 	const replyTargetPosts = await Post.find({
 		_id: {
-			$in: recentPosts.map(p => p.reply_id)
+			$in: recentPosts.map(p => p.replyId)
 		},
-		user_id: {
+		userId: {
 			$ne: user._id
 		}
 	}, {
 		fields: {
 			_id: false,
-			user_id: true
+			userId: true
 		}
 	});
 
@@ -68,7 +68,7 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
 
 	// Extract replies from recent posts
 	replyTargetPosts.forEach(post => {
-		const userId = post.user_id.toString();
+		const userId = post.userId.toString();
 		if (repliedUsers[userId]) {
 			repliedUsers[userId]++;
 		} else {
diff --git a/src/server/api/endpoints/users/posts.ts b/src/server/api/endpoints/users/posts.ts
index 3c84bf0d8..934690749 100644
--- a/src/server/api/endpoints/users/posts.ts
+++ b/src/server/api/endpoints/users/posts.ts
@@ -14,16 +14,16 @@ import User from '../../models/user';
  * @return {Promise<any>}
  */
 module.exports = (params, me) => new Promise(async (res, rej) => {
-	// Get 'user_id' parameter
-	const [userId, userIdErr] = $(params.user_id).optional.id().$;
-	if (userIdErr) return rej('invalid user_id param');
+	// Get 'userId' parameter
+	const [userId, userIdErr] = $(params.userId).optional.id().$;
+	if (userIdErr) return rej('invalid userId param');
 
 	// Get 'username' parameter
 	const [username, usernameErr] = $(params.username).optional.string().$;
 	if (usernameErr) return rej('invalid username param');
 
 	if (userId === undefined && username === undefined) {
-		return rej('user_id or pair of username and host is required');
+		return rej('userId or pair of username and host is required');
 	}
 
 	// Get 'host' parameter
@@ -31,45 +31,45 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
 	if (hostErr) return rej('invalid host param');
 
 	if (userId === undefined && host === undefined) {
-		return rej('user_id or pair of username and host is required');
+		return rej('userId or pair of username and host is required');
 	}
 
-	// Get 'include_replies' parameter
-	const [includeReplies = true, includeRepliesErr] = $(params.include_replies).optional.boolean().$;
-	if (includeRepliesErr) return rej('invalid include_replies param');
+	// Get 'includeReplies' parameter
+	const [includeReplies = true, includeRepliesErr] = $(params.includeReplies).optional.boolean().$;
+	if (includeRepliesErr) return rej('invalid includeReplies param');
 
-	// Get 'with_media' parameter
-	const [withMedia = false, withMediaErr] = $(params.with_media).optional.boolean().$;
-	if (withMediaErr) return rej('invalid with_media param');
+	// Get 'withMedia' parameter
+	const [withMedia = false, withMediaErr] = $(params.withMedia).optional.boolean().$;
+	if (withMediaErr) return rej('invalid withMedia param');
 
 	// Get 'limit' parameter
 	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
 	if (limitErr) return rej('invalid limit param');
 
-	// Get 'since_id' parameter
-	const [sinceId, sinceIdErr] = $(params.since_id).optional.id().$;
-	if (sinceIdErr) return rej('invalid since_id param');
+	// Get 'sinceId' parameter
+	const [sinceId, sinceIdErr] = $(params.sinceId).optional.id().$;
+	if (sinceIdErr) return rej('invalid sinceId param');
 
-	// Get 'until_id' parameter
-	const [untilId, untilIdErr] = $(params.until_id).optional.id().$;
-	if (untilIdErr) return rej('invalid until_id param');
+	// Get 'untilId' parameter
+	const [untilId, untilIdErr] = $(params.untilId).optional.id().$;
+	if (untilIdErr) return rej('invalid untilId param');
 
-	// Get 'since_date' parameter
-	const [sinceDate, sinceDateErr] = $(params.since_date).optional.number().$;
-	if (sinceDateErr) throw 'invalid since_date param';
+	// Get 'sinceDate' parameter
+	const [sinceDate, sinceDateErr] = $(params.sinceDate).optional.number().$;
+	if (sinceDateErr) throw 'invalid sinceDate param';
 
-	// Get 'until_date' parameter
-	const [untilDate, untilDateErr] = $(params.until_date).optional.number().$;
-	if (untilDateErr) throw 'invalid until_date param';
+	// Get 'untilDate' parameter
+	const [untilDate, untilDateErr] = $(params.untilDate).optional.number().$;
+	if (untilDateErr) throw 'invalid untilDate param';
 
-	// Check if only one of since_id, until_id, since_date, until_date specified
+	// Check if only one of sinceId, untilId, sinceDate, untilDate specified
 	if ([sinceId, untilId, sinceDate, untilDate].filter(x => x != null).length > 1) {
-		throw 'only one of since_id, until_id, since_date, until_date can be specified';
+		throw 'only one of sinceId, untilId, sinceDate, untilDate can be specified';
 	}
 
 	const q = userId !== undefined
 		? { _id: userId }
-		: { username_lower: username.toLowerCase(), host_lower: getHostLower(host) } ;
+		: { usernameLower: username.toLowerCase(), hostLower: getHostLower(host) } ;
 
 	// Lookup user
 	const user = await User.findOne(q, {
@@ -88,7 +88,7 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
 	};
 
 	const query = {
-		user_id: user._id
+		userId: user._id
 	} as any;
 
 	if (sinceId) {
@@ -102,21 +102,21 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
 		};
 	} else if (sinceDate) {
 		sort._id = 1;
-		query.created_at = {
+		query.createdAt = {
 			$gt: new Date(sinceDate)
 		};
 	} else if (untilDate) {
-		query.created_at = {
+		query.createdAt = {
 			$lt: new Date(untilDate)
 		};
 	}
 
 	if (!includeReplies) {
-		query.reply_id = null;
+		query.replyId = null;
 	}
 
 	if (withMedia) {
-		query.media_ids = {
+		query.mediaIds = {
 			$exists: true,
 			$ne: null
 		};
diff --git a/src/server/api/endpoints/users/recommendation.ts b/src/server/api/endpoints/users/recommendation.ts
index 45d90f422..c5297cdc5 100644
--- a/src/server/api/endpoints/users/recommendation.ts
+++ b/src/server/api/endpoints/users/recommendation.ts
@@ -32,7 +32,7 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
 			},
 			$or: [
 				{
-					'account.last_used_at': {
+					'account.lastUsedAt': {
 						$gte: new Date(Date.now() - ms('7days'))
 					}
 				}, {
@@ -43,7 +43,7 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
 			limit: limit,
 			skip: offset,
 			sort: {
-				followers_count: -1
+				followersCount: -1
 			}
 		});
 
diff --git a/src/server/api/endpoints/users/search.ts b/src/server/api/endpoints/users/search.ts
index 3c8157644..b03ed2f2f 100644
--- a/src/server/api/endpoints/users/search.ts
+++ b/src/server/api/endpoints/users/search.ts
@@ -41,7 +41,7 @@ async function byNative(res, rej, me, query, offset, max) {
 	const users = await User
 		.find({
 			$or: [{
-				username_lower: new RegExp(escapedQuery.replace('@', '').toLowerCase())
+				usernameLower: new RegExp(escapedQuery.replace('@', '').toLowerCase())
 			}, {
 				name: new RegExp(escapedQuery)
 			}]
diff --git a/src/server/api/endpoints/users/search_by_username.ts b/src/server/api/endpoints/users/search_by_username.ts
index 9c5e1905a..24e9c98e7 100644
--- a/src/server/api/endpoints/users/search_by_username.ts
+++ b/src/server/api/endpoints/users/search_by_username.ts
@@ -26,7 +26,7 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
 
 	const users = await User
 		.find({
-			username_lower: new RegExp(query.toLowerCase())
+			usernameLower: new RegExp(query.toLowerCase())
 		}, {
 			limit: limit,
 			skip: offset
diff --git a/src/server/api/endpoints/users/show.ts b/src/server/api/endpoints/users/show.ts
index 78df23f33..16411dddc 100644
--- a/src/server/api/endpoints/users/show.ts
+++ b/src/server/api/endpoints/users/show.ts
@@ -56,9 +56,9 @@ function webFingerAndVerify(query, verifier) {
 module.exports = (params, me) => new Promise(async (res, rej) => {
 	let user;
 
-	// Get 'user_id' parameter
-	const [userId, userIdErr] = $(params.user_id).optional.id().$;
-	if (userIdErr) return rej('invalid user_id param');
+	// Get 'userId' parameter
+	const [userId, userIdErr] = $(params.userId).optional.id().$;
+	if (userIdErr) return rej('invalid userId param');
 
 	// Get 'username' parameter
 	const [username, usernameErr] = $(params.username).optional.string().$;
@@ -69,25 +69,25 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
 	if (hostErr) return rej('invalid username param');
 
 	if (userId === undefined && typeof username !== 'string') {
-		return rej('user_id or pair of username and host is required');
+		return rej('userId or pair of username and host is required');
 	}
 
 	// Lookup user
 	if (typeof host === 'string') {
-		const username_lower = username.toLowerCase();
-		const host_lower_ascii = toASCII(host).toLowerCase();
-		const host_lower = toUnicode(host_lower_ascii);
+		const usernameLower = username.toLowerCase();
+		const hostLower_ascii = toASCII(host).toLowerCase();
+		const hostLower = toUnicode(hostLower_ascii);
 
-		user = await findUser({ username_lower, host_lower });
+		user = await findUser({ usernameLower, hostLower });
 
 		if (user === null) {
-			const acct_lower = `${username_lower}@${host_lower_ascii}`;
+			const acct_lower = `${usernameLower}@${hostLower_ascii}`;
 			let activityStreams;
 			let finger;
-			let followers_count;
-			let following_count;
+			let followersCount;
+			let followingCount;
 			let likes_count;
-			let posts_count;
+			let postsCount;
 
 			if (!validateUsername(username)) {
 				return rej('username validation failed');
@@ -122,7 +122,7 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
 					activityStreams['@context'] === 'https://www.w3.org/ns/activitystreams') &&
 				activityStreams.type === 'Person' &&
 				typeof activityStreams.preferredUsername === 'string' &&
-				activityStreams.preferredUsername.toLowerCase() === username_lower &&
+				activityStreams.preferredUsername.toLowerCase() === usernameLower &&
 				isValidName(activityStreams.name) &&
 				isValidDescription(activityStreams.summary)
 			)) {
@@ -130,7 +130,7 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
 			}
 
 			try {
-				[followers_count, following_count, likes_count, posts_count] = await Promise.all([
+				[followersCount, followingCount, likes_count, postsCount] = await Promise.all([
 					getCollectionCount(activityStreams.followers),
 					getCollectionCount(activityStreams.following),
 					getCollectionCount(activityStreams.liked),
@@ -145,21 +145,21 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
 
 			// Create user
 			user = await User.insert({
-				avatar_id: null,
-				banner_id: null,
-				created_at: new Date(),
+				avatarId: null,
+				bannerId: null,
+				createdAt: new Date(),
 				description: summaryDOM.textContent,
-				followers_count,
-				following_count,
+				followersCount,
+				followingCount,
 				name: activityStreams.name,
-				posts_count,
+				postsCount,
 				likes_count,
 				liked_count: 0,
-				drive_capacity: 1073741824, // 1GB
+				driveCapacity: 1073741824, // 1GB
 				username: username,
-				username_lower,
+				usernameLower,
 				host: toUnicode(finger.subject.replace(/^.*?@/, '')),
-				host_lower,
+				hostLower,
 				account: {
 					uri: activityStreams.id,
 				},
@@ -182,18 +182,18 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
 
 			User.update({ _id: user._id }, {
 				$set: {
-					avatar_id: icon._id,
-					banner_id: image._id,
+					avatarId: icon._id,
+					bannerId: image._id,
 				},
 			});
 
-			user.avatar_id = icon._id;
-			user.banner_id = icon._id;
+			user.avatarId = icon._id;
+			user.bannerId = icon._id;
 		}
 	} else {
 		const q = userId !== undefined
 			? { _id: userId }
-			: { username_lower: username.toLowerCase(), host: null };
+			: { usernameLower: username.toLowerCase(), host: null };
 
 		user = await findUser(q);
 
diff --git a/src/server/api/models/access-token.ts b/src/server/api/models/access-token.ts
index 2bf91f309..59bb09426 100644
--- a/src/server/api/models/access-token.ts
+++ b/src/server/api/models/access-token.ts
@@ -1,8 +1,16 @@
+import * as mongo from 'mongodb';
 import db from '../../../db/mongodb';
 
-const collection = db.get('access_tokens');
+const AccessToken = db.get<IAccessTokens>('accessTokens');
+AccessToken.createIndex('token');
+AccessToken.createIndex('hash');
+export default AccessToken;
 
-(collection as any).createIndex('token'); // fuck type definition
-(collection as any).createIndex('hash'); // fuck type definition
-
-export default collection as any; // fuck type definition
+export type IAccessTokens = {
+	_id: mongo.ObjectID;
+	createdAt: Date;
+	appId: mongo.ObjectID;
+	userId: mongo.ObjectID;
+	token: string;
+	hash: string;
+};
diff --git a/src/server/api/models/app.ts b/src/server/api/models/app.ts
index 17db82eca..3c17c50fd 100644
--- a/src/server/api/models/app.ts
+++ b/src/server/api/models/app.ts
@@ -5,16 +5,22 @@ import db from '../../../db/mongodb';
 import config from '../../../conf';
 
 const App = db.get<IApp>('apps');
-App.createIndex('name_id');
-App.createIndex('name_id_lower');
+App.createIndex('nameId');
+App.createIndex('nameIdLower');
 App.createIndex('secret');
 export default App;
 
 export type IApp = {
 	_id: mongo.ObjectID;
-	created_at: Date;
-	user_id: mongo.ObjectID;
+	createdAt: Date;
+	userId: mongo.ObjectID;
 	secret: string;
+	name: string;
+	nameId: string;
+	nameIdLower: string;
+	description: string;
+	permission: string;
+	callbackUrl: string;
 };
 
 export function isValidNameId(nameId: string): boolean {
@@ -70,27 +76,27 @@ export const pack = (
 	_app.id = _app._id;
 	delete _app._id;
 
-	delete _app.name_id_lower;
+	delete _app.nameIdLower;
 
 	// Visible by only owner
 	if (!opts.includeSecret) {
 		delete _app.secret;
 	}
 
-	_app.icon_url = _app.icon != null
+	_app.iconUrl = _app.icon != null
 		? `${config.drive_url}/${_app.icon}`
 		: `${config.drive_url}/app-default.jpg`;
 
 	if (me) {
 		// 既に連携しているか
 		const exist = await AccessToken.count({
-			app_id: _app.id,
-			user_id: me,
+			appId: _app.id,
+			userId: me,
 		}, {
 				limit: 1
 			});
 
-		_app.is_authorized = exist === 1;
+		_app.isAuthorized = exist === 1;
 	}
 
 	resolve(_app);
diff --git a/src/server/api/models/appdata.ts b/src/server/api/models/appdata.ts
deleted file mode 100644
index dda3c9893..000000000
--- a/src/server/api/models/appdata.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import db from '../../../db/mongodb';
-
-export default db.get('appdata') as any; // fuck type definition
diff --git a/src/server/api/models/auth-session.ts b/src/server/api/models/auth-session.ts
index a79d901df..2da40b1ea 100644
--- a/src/server/api/models/auth-session.ts
+++ b/src/server/api/models/auth-session.ts
@@ -3,11 +3,15 @@ import deepcopy = require('deepcopy');
 import db from '../../../db/mongodb';
 import { pack as packApp } from './app';
 
-const AuthSession = db.get('auth_sessions');
+const AuthSession = db.get<IAuthSession>('authSessions');
 export default AuthSession;
 
 export interface IAuthSession {
 	_id: mongo.ObjectID;
+	createdAt: Date;
+	appId: mongo.ObjectID;
+	userId: mongo.ObjectID;
+	token: string;
 }
 
 /**
@@ -24,7 +28,6 @@ export const pack = (
 	let _session: any;
 
 	// TODO: Populate session if it ID
-
 	_session = deepcopy(session);
 
 	// Me
@@ -39,7 +42,7 @@ export const pack = (
 	delete _session._id;
 
 	// Populate app
-	_session.app = await packApp(_session.app_id, me);
+	_session.app = await packApp(_session.appId, me);
 
 	resolve(_session);
 });
diff --git a/src/server/api/models/channel-watching.ts b/src/server/api/models/channel-watching.ts
index 4c6fae28d..a26b7edb9 100644
--- a/src/server/api/models/channel-watching.ts
+++ b/src/server/api/models/channel-watching.ts
@@ -1,3 +1,13 @@
+import * as mongo from 'mongodb';
 import db from '../../../db/mongodb';
 
-export default db.get('channel_watching') as any; // fuck type definition
+const ChannelWatching = db.get<IChannelWatching>('channelWatching');
+export default ChannelWatching;
+
+export interface IChannelWatching {
+	_id: mongo.ObjectID;
+	createdAt: Date;
+	deletedAt: Date;
+	channelId: mongo.ObjectID;
+	userId: mongo.ObjectID;
+}
diff --git a/src/server/api/models/channel.ts b/src/server/api/models/channel.ts
index 97999bd9e..9f94c5a8d 100644
--- a/src/server/api/models/channel.ts
+++ b/src/server/api/models/channel.ts
@@ -9,10 +9,11 @@ export default Channel;
 
 export type IChannel = {
 	_id: mongo.ObjectID;
-	created_at: Date;
+	createdAt: Date;
 	title: string;
-	user_id: mongo.ObjectID;
+	userId: mongo.ObjectID;
 	index: number;
+	watchingCount: number;
 };
 
 /**
@@ -47,7 +48,7 @@ export const pack = (
 	delete _channel._id;
 
 	// Remove needless properties
-	delete _channel.user_id;
+	delete _channel.userId;
 
 	// Me
 	const meId: mongo.ObjectID = me
@@ -61,12 +62,12 @@ export const pack = (
 	if (me) {
 		//#region Watchしているかどうか
 		const watch = await Watching.findOne({
-			user_id: meId,
-			channel_id: _channel.id,
-			deleted_at: { $exists: false }
+			userId: meId,
+			channelId: _channel.id,
+			deletedAt: { $exists: false }
 		});
 
-		_channel.is_watching = watch !== null;
+		_channel.isWatching = watch !== null;
 		//#endregion
 	}
 
diff --git a/src/server/api/models/drive-file.ts b/src/server/api/models/drive-file.ts
index 851a79a0e..04c9c54bd 100644
--- a/src/server/api/models/drive-file.ts
+++ b/src/server/api/models/drive-file.ts
@@ -4,14 +4,14 @@ import { pack as packFolder } from './drive-folder';
 import config from '../../../conf';
 import monkDb, { nativeDbConn } from '../../../db/mongodb';
 
-const DriveFile = monkDb.get<IDriveFile>('drive_files.files');
+const DriveFile = monkDb.get<IDriveFile>('driveFiles.files');
 
 export default DriveFile;
 
 const getGridFSBucket = async (): Promise<mongodb.GridFSBucket> => {
 	const db = await nativeDbConn();
 	const bucket = new mongodb.GridFSBucket(db, {
-		bucketName: 'drive_files'
+		bucketName: 'driveFiles'
 	});
 	return bucket;
 };
@@ -26,8 +26,8 @@ export type IDriveFile = {
 	contentType: string;
 	metadata: {
 		properties: any;
-		user_id: mongodb.ObjectID;
-		folder_id: mongodb.ObjectID;
+		userId: mongodb.ObjectID;
+		folderId: mongodb.ObjectID;
 	}
 };
 
@@ -79,7 +79,7 @@ export const pack = (
 	let _target: any = {};
 
 	_target.id = _file._id;
-	_target.created_at = _file.uploadDate;
+	_target.createdAt = _file.uploadDate;
 	_target.name = _file.filename;
 	_target.type = _file.contentType;
 	_target.datasize = _file.length;
@@ -92,9 +92,9 @@ export const pack = (
 	if (_target.properties == null) _target.properties = {};
 
 	if (opts.detail) {
-		if (_target.folder_id) {
+		if (_target.folderId) {
 			// Populate folder
-			_target.folder = await packFolder(_target.folder_id, {
+			_target.folder = await packFolder(_target.folderId, {
 				detail: true
 			});
 		}
diff --git a/src/server/api/models/drive-folder.ts b/src/server/api/models/drive-folder.ts
index 505556376..4ecafaa15 100644
--- a/src/server/api/models/drive-folder.ts
+++ b/src/server/api/models/drive-folder.ts
@@ -8,10 +8,10 @@ export default DriveFolder;
 
 export type IDriveFolder = {
 	_id: mongo.ObjectID;
-	created_at: Date;
+	createdAt: Date;
 	name: string;
-	user_id: mongo.ObjectID;
-	parent_id: mongo.ObjectID;
+	userId: mongo.ObjectID;
+	parentId: mongo.ObjectID;
 };
 
 export function isValidFolderName(name: string): boolean {
@@ -55,20 +55,20 @@ export const pack = (
 
 	if (opts.detail) {
 		const childFoldersCount = await DriveFolder.count({
-			parent_id: _folder.id
+			parentId: _folder.id
 		});
 
 		const childFilesCount = await DriveFile.count({
-			'metadata.folder_id': _folder.id
+			'metadata.folderId': _folder.id
 		});
 
-		_folder.folders_count = childFoldersCount;
-		_folder.files_count = childFilesCount;
+		_folder.foldersCount = childFoldersCount;
+		_folder.filesCount = childFilesCount;
 	}
 
-	if (opts.detail && _folder.parent_id) {
+	if (opts.detail && _folder.parentId) {
 		// Populate parent folder
-		_folder.parent = await pack(_folder.parent_id, {
+		_folder.parent = await pack(_folder.parentId, {
 			detail: true
 		});
 	}
diff --git a/src/server/api/models/drive-tag.ts b/src/server/api/models/drive-tag.ts
deleted file mode 100644
index d1c68365a..000000000
--- a/src/server/api/models/drive-tag.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import db from '../../../db/mongodb';
-
-export default db.get('drive_tags') as any; // fuck type definition
diff --git a/src/server/api/models/favorite.ts b/src/server/api/models/favorite.ts
index 314261764..5fb4db95a 100644
--- a/src/server/api/models/favorite.ts
+++ b/src/server/api/models/favorite.ts
@@ -1,3 +1,12 @@
+import * as mongo from 'mongodb';
 import db from '../../../db/mongodb';
 
-export default db.get('favorites') as any; // fuck type definition
+const Favorites = db.get<IFavorite>('favorites');
+export default Favorites;
+
+export type IFavorite = {
+	_id: mongo.ObjectID;
+	createdAt: Date;
+	userId: mongo.ObjectID;
+	postId: mongo.ObjectID;
+};
diff --git a/src/server/api/models/following.ts b/src/server/api/models/following.ts
index 92d7b6d31..552e94604 100644
--- a/src/server/api/models/following.ts
+++ b/src/server/api/models/following.ts
@@ -1,3 +1,13 @@
+import * as mongo from 'mongodb';
 import db from '../../../db/mongodb';
 
-export default db.get('following') as any; // fuck type definition
+const Following = db.get<IFollowing>('following');
+export default Following;
+
+export type IFollowing = {
+	_id: mongo.ObjectID;
+	createdAt: Date;
+	deletedAt: Date;
+	followeeId: mongo.ObjectID;
+	followerId: mongo.ObjectID;
+};
diff --git a/src/server/api/models/messaging-history.ts b/src/server/api/models/messaging-history.ts
index ea9f317ee..44a2adc31 100644
--- a/src/server/api/models/messaging-history.ts
+++ b/src/server/api/models/messaging-history.ts
@@ -1,3 +1,13 @@
+import * as mongo from 'mongodb';
 import db from '../../../db/mongodb';
 
-export default db.get('messaging_histories') as any; // fuck type definition
+const MessagingHistory = db.get<IMessagingHistory>('messagingHistories');
+export default MessagingHistory;
+
+export type IMessagingHistory = {
+	_id: mongo.ObjectID;
+	updatedAt: Date;
+	userId: mongo.ObjectID;
+	partnerId: mongo.ObjectID;
+	messageId: mongo.ObjectID;
+};
diff --git a/src/server/api/models/messaging-message.ts b/src/server/api/models/messaging-message.ts
index be484d635..d3a418c9a 100644
--- a/src/server/api/models/messaging-message.ts
+++ b/src/server/api/models/messaging-message.ts
@@ -5,16 +5,17 @@ import { pack as packFile } from './drive-file';
 import db from '../../../db/mongodb';
 import parse from '../common/text';
 
-const MessagingMessage = db.get<IMessagingMessage>('messaging_messages');
+const MessagingMessage = db.get<IMessagingMessage>('messagingMessages');
 export default MessagingMessage;
 
 export interface IMessagingMessage {
 	_id: mongo.ObjectID;
-	created_at: Date;
+	createdAt: Date;
 	text: string;
-	user_id: mongo.ObjectID;
-	recipient_id: mongo.ObjectID;
-	is_read: boolean;
+	userId: mongo.ObjectID;
+	recipientId: mongo.ObjectID;
+	isRead: boolean;
+	fileId: mongo.ObjectID;
 }
 
 export function isValidText(text: string): boolean {
@@ -65,16 +66,16 @@ export const pack = (
 	}
 
 	// Populate user
-	_message.user = await packUser(_message.user_id, me);
+	_message.user = await packUser(_message.userId, me);
 
-	if (_message.file_id) {
+	if (_message.fileId) {
 		// Populate file
-		_message.file = await packFile(_message.file_id);
+		_message.file = await packFile(_message.fileId);
 	}
 
 	if (opts.populateRecipient) {
 		// Populate recipient
-		_message.recipient = await packUser(_message.recipient_id, me);
+		_message.recipient = await packUser(_message.recipientId, me);
 	}
 
 	resolve(_message);
diff --git a/src/server/api/models/meta.ts b/src/server/api/models/meta.ts
index ee1ada18f..cad7f5096 100644
--- a/src/server/api/models/meta.ts
+++ b/src/server/api/models/meta.ts
@@ -1,7 +1,8 @@
 import db from '../../../db/mongodb';
 
-export default db.get('meta') as any; // fuck type definition
+const Meta = db.get<IMeta>('meta');
+export default Meta;
 
 export type IMeta = {
-	top_image: string;
+	broadcasts: any[];
 };
diff --git a/src/server/api/models/mute.ts b/src/server/api/models/mute.ts
index 02f652c30..e5385ade3 100644
--- a/src/server/api/models/mute.ts
+++ b/src/server/api/models/mute.ts
@@ -1,3 +1,13 @@
+import * as mongo from 'mongodb';
 import db from '../../../db/mongodb';
 
-export default db.get('mute') as any; // fuck type definition
+const Mute = db.get<IMute>('mute');
+export default Mute;
+
+export interface IMute {
+	_id: mongo.ObjectID;
+	createdAt: Date;
+	deletedAt: Date;
+	muterId: mongo.ObjectID;
+	muteeId: mongo.ObjectID;
+}
diff --git a/src/server/api/models/notification.ts b/src/server/api/models/notification.ts
index bcb25534d..237e2663f 100644
--- a/src/server/api/models/notification.ts
+++ b/src/server/api/models/notification.ts
@@ -9,7 +9,7 @@ export default Notification;
 
 export interface INotification {
 	_id: mongo.ObjectID;
-	created_at: Date;
+	createdAt: Date;
 
 	/**
 	 * 通知の受信者
@@ -19,7 +19,7 @@ export interface INotification {
 	/**
 	 * 通知の受信者
 	 */
-	notifiee_id: mongo.ObjectID;
+	notifieeId: mongo.ObjectID;
 
 	/**
 	 * イニシエータ(initiator)、Origin。通知を行う原因となったユーザー
@@ -29,7 +29,7 @@ export interface INotification {
 	/**
 	 * イニシエータ(initiator)、Origin。通知を行う原因となったユーザー
 	 */
-	notifier_id: mongo.ObjectID;
+	notifierId: mongo.ObjectID;
 
 	/**
 	 * 通知の種類。
@@ -46,7 +46,7 @@ export interface INotification {
 	/**
 	 * 通知が読まれたかどうか
 	 */
-	is_read: Boolean;
+	isRead: Boolean;
 }
 
 /**
@@ -75,15 +75,15 @@ export const pack = (notification: any) => new Promise<any>(async (resolve, reje
 	_notification.id = _notification._id;
 	delete _notification._id;
 
-	// Rename notifier_id to user_id
-	_notification.user_id = _notification.notifier_id;
-	delete _notification.notifier_id;
+	// Rename notifierId to userId
+	_notification.userId = _notification.notifierId;
+	delete _notification.notifierId;
 
-	const me = _notification.notifiee_id;
-	delete _notification.notifiee_id;
+	const me = _notification.notifieeId;
+	delete _notification.notifieeId;
 
 	// Populate notifier
-	_notification.user = await packUser(_notification.user_id, me);
+	_notification.user = await packUser(_notification.userId, me);
 
 	switch (_notification.type) {
 		case 'follow':
@@ -96,7 +96,7 @@ export const pack = (notification: any) => new Promise<any>(async (resolve, reje
 		case 'reaction':
 		case 'poll_vote':
 			// Populate post
-			_notification.post = await packPost(_notification.post_id, me);
+			_notification.post = await packPost(_notification.postId, me);
 			break;
 		default:
 			console.error(`Unknown type: ${_notification.type}`);
diff --git a/src/server/api/models/othello-game.ts b/src/server/api/models/othello-game.ts
index 97508e46d..ebe738815 100644
--- a/src/server/api/models/othello-game.ts
+++ b/src/server/api/models/othello-game.ts
@@ -3,17 +3,17 @@ import deepcopy = require('deepcopy');
 import db from '../../../db/mongodb';
 import { IUser, pack as packUser } from './user';
 
-const Game = db.get<IGame>('othello_games');
-export default Game;
+const OthelloGame = db.get<IOthelloGame>('othelloGames');
+export default OthelloGame;
 
-export interface IGame {
+export interface IOthelloGame {
 	_id: mongo.ObjectID;
-	created_at: Date;
-	started_at: Date;
-	user1_id: mongo.ObjectID;
-	user2_id: mongo.ObjectID;
-	user1_accepted: boolean;
-	user2_accepted: boolean;
+	createdAt: Date;
+	startedAt: Date;
+	user1Id: mongo.ObjectID;
+	user2Id: mongo.ObjectID;
+	user1Accepted: boolean;
+	user2Accepted: boolean;
 
 	/**
 	 * どちらのプレイヤーが先行(黒)か
@@ -22,9 +22,9 @@ export interface IGame {
 	 */
 	black: number;
 
-	is_started: boolean;
-	is_ended: boolean;
-	winner_id: mongo.ObjectID;
+	isStarted: boolean;
+	isEnded: boolean;
+	winnerId: mongo.ObjectID;
 	logs: Array<{
 		at: Date;
 		color: boolean;
@@ -33,9 +33,9 @@ export interface IGame {
 	settings: {
 		map: string[];
 		bw: string | number;
-		is_llotheo: boolean;
-		can_put_everywhere: boolean;
-		looped_board: boolean;
+		isLlotheo: boolean;
+		canPutEverywhere: boolean;
+		loopedBoard: boolean;
 	};
 	form1: any;
 	form2: any;
@@ -62,11 +62,11 @@ export const pack = (
 
 	// Populate the game if 'game' is ID
 	if (mongo.ObjectID.prototype.isPrototypeOf(game)) {
-		_game = await Game.findOne({
+		_game = await OthelloGame.findOne({
 			_id: game
 		});
 	} else if (typeof game === 'string') {
-		_game = await Game.findOne({
+		_game = await OthelloGame.findOne({
 			_id: new mongo.ObjectID(game)
 		});
 	} else {
@@ -97,10 +97,10 @@ export const pack = (
 	}
 
 	// Populate user
-	_game.user1 = await packUser(_game.user1_id, meId);
-	_game.user2 = await packUser(_game.user2_id, meId);
-	if (_game.winner_id) {
-		_game.winner = await packUser(_game.winner_id, meId);
+	_game.user1 = await packUser(_game.user1Id, meId);
+	_game.user2 = await packUser(_game.user2Id, meId);
+	if (_game.winnerId) {
+		_game.winner = await packUser(_game.winnerId, meId);
 	} else {
 		_game.winner = null;
 	}
diff --git a/src/server/api/models/othello-matching.ts b/src/server/api/models/othello-matching.ts
index 3c29e6a00..a294bd1ef 100644
--- a/src/server/api/models/othello-matching.ts
+++ b/src/server/api/models/othello-matching.ts
@@ -3,14 +3,14 @@ import deepcopy = require('deepcopy');
 import db from '../../../db/mongodb';
 import { IUser, pack as packUser } from './user';
 
-const Matching = db.get<IMatching>('othello_matchings');
+const Matching = db.get<IMatching>('othelloMatchings');
 export default Matching;
 
 export interface IMatching {
 	_id: mongo.ObjectID;
-	created_at: Date;
-	parent_id: mongo.ObjectID;
-	child_id: mongo.ObjectID;
+	createdAt: Date;
+	parentId: mongo.ObjectID;
+	childId: mongo.ObjectID;
 }
 
 /**
@@ -37,8 +37,8 @@ export const pack = (
 	delete _matching._id;
 
 	// Populate user
-	_matching.parent = await packUser(_matching.parent_id, meId);
-	_matching.child = await packUser(_matching.child_id, meId);
+	_matching.parent = await packUser(_matching.parentId, meId);
+	_matching.child = await packUser(_matching.childId, meId);
 
 	resolve(_matching);
 });
diff --git a/src/server/api/models/poll-vote.ts b/src/server/api/models/poll-vote.ts
index c6638ccf1..1cad95e5d 100644
--- a/src/server/api/models/poll-vote.ts
+++ b/src/server/api/models/poll-vote.ts
@@ -1,3 +1,17 @@
+<<<<<<< HEAD:src/server/api/models/poll-vote.ts
 import db from '../../../db/mongodb';
+=======
+import * as mongo from 'mongodb';
+import db from '../../db/mongodb';
+>>>>>>> refs/remotes/origin/master:src/api/models/poll-vote.ts
 
-export default db.get('poll_votes') as any; // fuck type definition
+const PollVote = db.get<IPollVote>('pollVotes');
+export default PollVote;
+
+export interface IPollVote {
+	_id: mongo.ObjectID;
+	createdAt: Date;
+	userId: mongo.ObjectID;
+	postId: mongo.ObjectID;
+	choice: number;
+}
diff --git a/src/server/api/models/post-reaction.ts b/src/server/api/models/post-reaction.ts
index 5cd122d76..f9a3f91c2 100644
--- a/src/server/api/models/post-reaction.ts
+++ b/src/server/api/models/post-reaction.ts
@@ -4,13 +4,15 @@ import db from '../../../db/mongodb';
 import Reaction from './post-reaction';
 import { pack as packUser } from './user';
 
-const PostReaction = db.get<IPostReaction>('post_reactions');
+const PostReaction = db.get<IPostReaction>('postReactions');
 export default PostReaction;
 
 export interface IPostReaction {
 	_id: mongo.ObjectID;
-	created_at: Date;
-	deleted_at: Date;
+	createdAt: Date;
+	deletedAt: Date;
+	postId: mongo.ObjectID;
+	userId: mongo.ObjectID;
 	reaction: string;
 }
 
@@ -45,7 +47,7 @@ export const pack = (
 	delete _reaction._id;
 
 	// Populate user
-	_reaction.user = await packUser(_reaction.user_id, me);
+	_reaction.user = await packUser(_reaction.userId, me);
 
 	resolve(_reaction);
 });
diff --git a/src/server/api/models/post-watching.ts b/src/server/api/models/post-watching.ts
index 9a4163c8d..abd632249 100644
--- a/src/server/api/models/post-watching.ts
+++ b/src/server/api/models/post-watching.ts
@@ -1,3 +1,12 @@
+import * as mongo from 'mongodb';
 import db from '../../../db/mongodb';
 
-export default db.get('post_watching') as any; // fuck type definition
+const PostWatching = db.get<IPostWatching>('postWatching');
+export default PostWatching;
+
+export interface IPostWatching {
+	_id: mongo.ObjectID;
+	createdAt: Date;
+	userId: mongo.ObjectID;
+	postId: mongo.ObjectID;
+}
diff --git a/src/server/api/models/post.ts b/src/server/api/models/post.ts
index 3f648e08c..0317cff3f 100644
--- a/src/server/api/models/post.ts
+++ b/src/server/api/models/post.ts
@@ -20,18 +20,20 @@ export function isValidText(text: string): boolean {
 
 export type IPost = {
 	_id: mongo.ObjectID;
-	channel_id: mongo.ObjectID;
-	created_at: Date;
-	media_ids: mongo.ObjectID[];
-	reply_id: mongo.ObjectID;
-	repost_id: mongo.ObjectID;
+	channelId: mongo.ObjectID;
+	createdAt: Date;
+	mediaIds: mongo.ObjectID[];
+	replyId: mongo.ObjectID;
+	repostId: mongo.ObjectID;
 	poll: any; // todo
 	text: string;
-	user_id: mongo.ObjectID;
-	app_id: mongo.ObjectID;
-	category: string;
-	is_category_verified: boolean;
-	via_mobile: boolean;
+	userId: mongo.ObjectID;
+	appId: mongo.ObjectID;
+	viaMobile: boolean;
+	repostCount: number;
+	repliesCount: number;
+	reactionCounts: any;
+	mentions: mongo.ObjectID[];
 	geo: {
 		latitude: number;
 		longitude: number;
@@ -102,21 +104,21 @@ export const pack = async (
 	}
 
 	// Populate user
-	_post.user = packUser(_post.user_id, meId);
+	_post.user = packUser(_post.userId, meId);
 
 	// Populate app
-	if (_post.app_id) {
-		_post.app = packApp(_post.app_id);
+	if (_post.appId) {
+		_post.app = packApp(_post.appId);
 	}
 
 	// Populate channel
-	if (_post.channel_id) {
-		_post.channel = packChannel(_post.channel_id);
+	if (_post.channelId) {
+		_post.channel = packChannel(_post.channelId);
 	}
 
 	// Populate media
-	if (_post.media_ids) {
-		_post.media = Promise.all(_post.media_ids.map(fileId =>
+	if (_post.mediaIds) {
+		_post.media = Promise.all(_post.mediaIds.map(fileId =>
 			packFile(fileId)
 		));
 	}
@@ -126,7 +128,7 @@ export const pack = async (
 		// Get previous post info
 		_post.prev = (async () => {
 			const prev = await Post.findOne({
-				user_id: _post.user_id,
+				userId: _post.userId,
 				_id: {
 					$lt: id
 				}
@@ -144,7 +146,7 @@ export const pack = async (
 		// Get next post info
 		_post.next = (async () => {
 			const next = await Post.findOne({
-				user_id: _post.user_id,
+				userId: _post.userId,
 				_id: {
 					$gt: id
 				}
@@ -159,16 +161,16 @@ export const pack = async (
 			return next ? next._id : null;
 		})();
 
-		if (_post.reply_id) {
+		if (_post.replyId) {
 			// Populate reply to post
-			_post.reply = pack(_post.reply_id, meId, {
+			_post.reply = pack(_post.replyId, meId, {
 				detail: false
 			});
 		}
 
-		if (_post.repost_id) {
+		if (_post.repostId) {
 			// Populate repost
-			_post.repost = pack(_post.repost_id, meId, {
+			_post.repost = pack(_post.repostId, meId, {
 				detail: _post.text == null
 			});
 		}
@@ -178,15 +180,15 @@ export const pack = async (
 			_post.poll = (async (poll) => {
 				const vote = await Vote
 					.findOne({
-						user_id: meId,
-						post_id: id
+						userId: meId,
+						postId: id
 					});
 
 				if (vote != null) {
 					const myChoice = poll.choices
 						.filter(c => c.id == vote.choice)[0];
 
-					myChoice.is_voted = true;
+					myChoice.isVoted = true;
 				}
 
 				return poll;
@@ -195,12 +197,12 @@ export const pack = async (
 
 		// Fetch my reaction
 		if (meId) {
-			_post.my_reaction = (async () => {
+			_post.myReaction = (async () => {
 				const reaction = await Reaction
 					.findOne({
-						user_id: meId,
-						post_id: id,
-						deleted_at: { $exists: false }
+						userId: meId,
+						postId: id,
+						deletedAt: { $exists: false }
 					});
 
 				if (reaction) {
diff --git a/src/server/api/models/signin.ts b/src/server/api/models/signin.ts
index 5cffb3c31..bec635947 100644
--- a/src/server/api/models/signin.ts
+++ b/src/server/api/models/signin.ts
@@ -7,6 +7,11 @@ export default Signin;
 
 export interface ISignin {
 	_id: mongo.ObjectID;
+	createdAt: Date;
+	userId: mongo.ObjectID;
+	ip: string;
+	headers: any;
+	success: boolean;
 }
 
 /**
diff --git a/src/server/api/models/sw-subscription.ts b/src/server/api/models/sw-subscription.ts
index 4506a982f..d3bbd75a6 100644
--- a/src/server/api/models/sw-subscription.ts
+++ b/src/server/api/models/sw-subscription.ts
@@ -1,3 +1,13 @@
+import * as mongo from 'mongodb';
 import db from '../../../db/mongodb';
 
-export default db.get('sw_subscriptions') as any; // fuck type definition
+const SwSubscription = db.get<ISwSubscription>('swSubscriptions');
+export default SwSubscription;
+
+export interface ISwSubscription {
+	_id: mongo.ObjectID;
+	userId: mongo.ObjectID;
+	endpoint: string;
+	auth: string;
+	publickey: string;
+}
diff --git a/src/server/api/models/user.ts b/src/server/api/models/user.ts
index 8e7d50baa..419ad5397 100644
--- a/src/server/api/models/user.ts
+++ b/src/server/api/models/user.ts
@@ -46,25 +46,26 @@ export type ILocalAccount = {
 	password: string;
 	token: string;
 	twitter: {
-		access_token: string;
-		access_token_secret: string;
-		user_id: string;
-		screen_name: string;
+		accessToken: string;
+		accessTokenSecret: string;
+		userId: string;
+		screenName: string;
 	};
 	line: {
-		user_id: string;
+		userId: string;
 	};
 	profile: {
 		location: string;
 		birthday: string; // 'YYYY-MM-DD'
 		tags: string[];
 	};
-	last_used_at: Date;
-	is_bot: boolean;
-	is_pro: boolean;
-	two_factor_secret: string;
-	two_factor_enabled: boolean;
-	client_settings: any;
+	lastUsedAt: Date;
+	isBot: boolean;
+	isPro: boolean;
+	twoFactorSecret: string;
+	twoFactorEnabled: boolean;
+	twoFactorTempSecret: string;
+	clientSettings: any;
 	settings: any;
 };
 
@@ -74,33 +75,33 @@ export type IRemoteAccount = {
 
 export type IUser = {
 	_id: mongo.ObjectID;
-	created_at: Date;
-	deleted_at: Date;
-	followers_count: number;
-	following_count: number;
+	createdAt: Date;
+	deletedAt: Date;
+	followersCount: number;
+	followingCount: number;
 	name: string;
-	posts_count: number;
-	drive_capacity: number;
+	postsCount: number;
+	driveCapacity: number;
 	username: string;
-	username_lower: string;
-	avatar_id: mongo.ObjectID;
-	banner_id: mongo.ObjectID;
+	usernameLower: string;
+	avatarId: mongo.ObjectID;
+	bannerId: mongo.ObjectID;
 	data: any;
 	description: string;
-	latest_post: IPost;
-	pinned_post_id: mongo.ObjectID;
-	is_suspended: boolean;
+	latestPost: IPost;
+	pinnedPostId: mongo.ObjectID;
+	isSuspended: boolean;
 	keywords: string[];
 	host: string;
-	host_lower: string;
+	hostLower: string;
 	account: ILocalAccount | IRemoteAccount;
 };
 
 export function init(user): IUser {
 	user._id = new mongo.ObjectID(user._id);
-	user.avatar_id = new mongo.ObjectID(user.avatar_id);
-	user.banner_id = new mongo.ObjectID(user.banner_id);
-	user.pinned_post_id = new mongo.ObjectID(user.pinned_post_id);
+	user.avatarId = new mongo.ObjectID(user.avatarId);
+	user.bannerId = new mongo.ObjectID(user.bannerId);
+	user.pinnedPostId = new mongo.ObjectID(user.pinnedPostId);
 	return user;
 }
 
@@ -131,7 +132,7 @@ export const pack = (
 	const fields = opts.detail ? {
 	} : {
 		'account.settings': false,
-		'account.client_settings': false,
+		'account.clientSettings': false,
 		'account.profile': false,
 		'account.keywords': false,
 		'account.domains': false
@@ -166,19 +167,19 @@ export const pack = (
 	delete _user._id;
 
 	// Remove needless properties
-	delete _user.latest_post;
+	delete _user.latestPost;
 
 	if (!_user.host) {
 		// Remove private properties
 		delete _user.account.keypair;
 		delete _user.account.password;
 		delete _user.account.token;
-		delete _user.account.two_factor_temp_secret;
-		delete _user.account.two_factor_secret;
-		delete _user.username_lower;
+		delete _user.account.twoFactorTempSecret;
+		delete _user.account.twoFactorSecret;
+		delete _user.usernameLower;
 		if (_user.account.twitter) {
-			delete _user.account.twitter.access_token;
-			delete _user.account.twitter.access_token_secret;
+			delete _user.account.twitter.accessToken;
+			delete _user.account.twitter.accessTokenSecret;
 		}
 		delete _user.account.line;
 
@@ -186,65 +187,65 @@ export const pack = (
 		if (!opts.includeSecrets) {
 			delete _user.account.email;
 			delete _user.account.settings;
-			delete _user.account.client_settings;
+			delete _user.account.clientSettings;
 		}
 
 		if (!opts.detail) {
-			delete _user.account.two_factor_enabled;
+			delete _user.account.twoFactorEnabled;
 		}
 	}
 
-	_user.avatar_url = _user.avatar_id != null
-		? `${config.drive_url}/${_user.avatar_id}`
+	_user.avatarUrl = _user.avatarId != null
+		? `${config.drive_url}/${_user.avatarId}`
 		: `${config.drive_url}/default-avatar.jpg`;
 
-	_user.banner_url = _user.banner_id != null
-		? `${config.drive_url}/${_user.banner_id}`
+	_user.bannerUrl = _user.bannerId != null
+		? `${config.drive_url}/${_user.bannerId}`
 		: null;
 
 	if (!meId || !meId.equals(_user.id) || !opts.detail) {
-		delete _user.avatar_id;
-		delete _user.banner_id;
+		delete _user.avatarId;
+		delete _user.bannerId;
 
-		delete _user.drive_capacity;
+		delete _user.driveCapacity;
 	}
 
 	if (meId && !meId.equals(_user.id)) {
 		// Whether the user is following
-		_user.is_following = (async () => {
+		_user.isFollowing = (async () => {
 			const follow = await Following.findOne({
-				follower_id: meId,
-				followee_id: _user.id,
-				deleted_at: { $exists: false }
+				followerId: meId,
+				followeeId: _user.id,
+				deletedAt: { $exists: false }
 			});
 			return follow !== null;
 		})();
 
 		// Whether the user is followed
-		_user.is_followed = (async () => {
+		_user.isFollowed = (async () => {
 			const follow2 = await Following.findOne({
-				follower_id: _user.id,
-				followee_id: meId,
-				deleted_at: { $exists: false }
+				followerId: _user.id,
+				followeeId: meId,
+				deletedAt: { $exists: false }
 			});
 			return follow2 !== null;
 		})();
 
 		// Whether the user is muted
-		_user.is_muted = (async () => {
+		_user.isMuted = (async () => {
 			const mute = await Mute.findOne({
-				muter_id: meId,
-				mutee_id: _user.id,
-				deleted_at: { $exists: false }
+				muterId: meId,
+				muteeId: _user.id,
+				deletedAt: { $exists: false }
 			});
 			return mute !== null;
 		})();
 	}
 
 	if (opts.detail) {
-		if (_user.pinned_post_id) {
+		if (_user.pinnedPostId) {
 			// Populate pinned post
-			_user.pinned_post = packPost(_user.pinned_post_id, meId, {
+			_user.pinnedPost = packPost(_user.pinnedPostId, meId, {
 				detail: true
 			});
 		}
@@ -253,17 +254,17 @@ export const pack = (
 			const myFollowingIds = await getFriends(meId);
 
 			// Get following you know count
-			_user.following_you_know_count = Following.count({
-				followee_id: { $in: myFollowingIds },
-				follower_id: _user.id,
-				deleted_at: { $exists: false }
+			_user.followingYouKnowCount = Following.count({
+				followeeId: { $in: myFollowingIds },
+				followerId: _user.id,
+				deletedAt: { $exists: false }
 			});
 
 			// Get followers you know count
-			_user.followers_you_know_count = Following.count({
-				followee_id: _user.id,
-				follower_id: { $in: myFollowingIds },
-				deleted_at: { $exists: false }
+			_user.followersYouKnowCount = Following.count({
+				followeeId: _user.id,
+				followerId: { $in: myFollowingIds },
+				deletedAt: { $exists: false }
 			});
 		}
 	}
@@ -322,7 +323,7 @@ export const packForAp = (
 		"name": _user.name,
 		"summary": _user.description,
 		"icon": [
-			`${config.drive_url}/${_user.avatar_id}`
+			`${config.drive_url}/${_user.avatarId}`
 		]
 	});
 });
diff --git a/src/server/api/private/signin.ts b/src/server/api/private/signin.ts
index bbc990899..4b60f4c75 100644
--- a/src/server/api/private/signin.ts
+++ b/src/server/api/private/signin.ts
@@ -32,7 +32,7 @@ export default async (req: express.Request, res: express.Response) => {
 
 	// Fetch user
 	const user: IUser = await User.findOne({
-		username_lower: username.toLowerCase(),
+		usernameLower: username.toLowerCase(),
 		host: null
 	}, {
 		fields: {
@@ -54,9 +54,9 @@ export default async (req: express.Request, res: express.Response) => {
 	const same = await bcrypt.compare(password, account.password);
 
 	if (same) {
-		if (account.two_factor_enabled) {
+		if (account.twoFactorEnabled) {
 			const verified = (speakeasy as any).totp.verify({
-				secret: account.two_factor_secret,
+				secret: account.twoFactorSecret,
 				encoding: 'base32',
 				token: token
 			});
@@ -79,8 +79,8 @@ export default async (req: express.Request, res: express.Response) => {
 
 	// Append signin history
 	const record = await Signin.insert({
-		created_at: new Date(),
-		user_id: user._id,
+		createdAt: new Date(),
+		userId: user._id,
 		ip: req.ip,
 		headers: req.headers,
 		success: same
diff --git a/src/server/api/private/signup.ts b/src/server/api/private/signup.ts
index 9f5539331..cad9752c4 100644
--- a/src/server/api/private/signup.ts
+++ b/src/server/api/private/signup.ts
@@ -64,7 +64,7 @@ export default async (req: express.Request, res: express.Response) => {
 	// Fetch exist user that same username
 	const usernameExist = await User
 		.count({
-			username_lower: username.toLowerCase(),
+			usernameLower: username.toLowerCase(),
 			host: null
 		}, {
 			limit: 1
@@ -107,21 +107,19 @@ export default async (req: express.Request, res: express.Response) => {
 
 	// Create account
 	const account: IUser = await User.insert({
-		avatar_id: null,
-		banner_id: null,
-		created_at: new Date(),
+		avatarId: null,
+		bannerId: null,
+		createdAt: new Date(),
 		description: null,
-		followers_count: 0,
-		following_count: 0,
+		followersCount: 0,
+		followingCount: 0,
 		name: name,
-		posts_count: 0,
-		likes_count: 0,
-		liked_count: 0,
-		drive_capacity: 1073741824, // 1GB
+		postsCount: 0,
+		driveCapacity: 1073741824, // 1GB
 		username: username,
-		username_lower: username.toLowerCase(),
+		usernameLower: username.toLowerCase(),
 		host: null,
-		host_lower: null,
+		hostLower: null,
 		account: {
 			keypair: generateKeypair(),
 			token: secret,
@@ -139,9 +137,9 @@ export default async (req: express.Request, res: express.Response) => {
 				weight: null
 			},
 			settings: {
-				auto_watch: true
+				autoWatch: true
 			},
-			client_settings: {
+			clientSettings: {
 				home: homeData
 			}
 		}
diff --git a/src/server/api/service/github.ts b/src/server/api/service/github.ts
index a33d35975..98732e6b8 100644
--- a/src/server/api/service/github.ts
+++ b/src/server/api/service/github.ts
@@ -9,7 +9,7 @@ module.exports = async (app: express.Application) => {
 	if (config.github_bot == null) return;
 
 	const bot = await User.findOne({
-		username_lower: config.github_bot.username.toLowerCase()
+		usernameLower: config.github_bot.username.toLowerCase()
 	});
 
 	if (bot == null) {
diff --git a/src/server/api/service/twitter.ts b/src/server/api/service/twitter.ts
index 861f63ed6..bdbedc864 100644
--- a/src/server/api/service/twitter.ts
+++ b/src/server/api/service/twitter.ts
@@ -128,7 +128,7 @@ module.exports = (app: express.Application) => {
 
 				const user = await User.findOne({
 					host: null,
-					'account.twitter.user_id': result.userId
+					'account.twitter.userId': result.userId
 				});
 
 				if (user == null) {
@@ -155,10 +155,10 @@ module.exports = (app: express.Application) => {
 				}, {
 					$set: {
 						'account.twitter': {
-							access_token: result.accessToken,
-							access_token_secret: result.accessTokenSecret,
-							user_id: result.userId,
-							screen_name: result.screenName
+							accessToken: result.accessToken,
+							accessTokenSecret: result.accessTokenSecret,
+							userId: result.userId,
+							screenName: result.screenName
 						}
 					}
 				});
diff --git a/src/server/api/stream/home.ts b/src/server/api/stream/home.ts
index 1ef0f33b4..291be0824 100644
--- a/src/server/api/stream/home.ts
+++ b/src/server/api/stream/home.ts
@@ -14,10 +14,10 @@ export default async function(request: websocket.request, connection: websocket.
 	subscriber.subscribe(`misskey:user-stream:${user._id}`);
 
 	const mute = await Mute.find({
-		muter_id: user._id,
-		deleted_at: { $exists: false }
+		muterId: user._id,
+		deletedAt: { $exists: false }
 	});
-	const mutedUserIds = mute.map(m => m.mutee_id.toString());
+	const mutedUserIds = mute.map(m => m.muteeId.toString());
 
 	subscriber.on('message', async (channel, data) => {
 		switch (channel.split(':')[1]) {
@@ -26,17 +26,17 @@ export default async function(request: websocket.request, connection: websocket.
 					const x = JSON.parse(data);
 
 					if (x.type == 'post') {
-						if (mutedUserIds.indexOf(x.body.user_id) != -1) {
+						if (mutedUserIds.indexOf(x.body.userId) != -1) {
 							return;
 						}
-						if (x.body.reply != null && mutedUserIds.indexOf(x.body.reply.user_id) != -1) {
+						if (x.body.reply != null && mutedUserIds.indexOf(x.body.reply.userId) != -1) {
 							return;
 						}
-						if (x.body.repost != null && mutedUserIds.indexOf(x.body.repost.user_id) != -1) {
+						if (x.body.repost != null && mutedUserIds.indexOf(x.body.repost.userId) != -1) {
 							return;
 						}
 					} else if (x.type == 'notification') {
-						if (mutedUserIds.indexOf(x.body.user_id) != -1) {
+						if (mutedUserIds.indexOf(x.body.userId) != -1) {
 							return;
 						}
 					}
@@ -74,7 +74,7 @@ export default async function(request: websocket.request, connection: websocket.
 				// Update lastUsedAt
 				User.update({ _id: user._id }, {
 					$set: {
-						'account.last_used_at': new Date()
+						'account.lastUsedAt': new Date()
 					}
 				});
 				break;
diff --git a/src/server/api/stream/othello-game.ts b/src/server/api/stream/othello-game.ts
index 1c846f27a..e48d93cdd 100644
--- a/src/server/api/stream/othello-game.ts
+++ b/src/server/api/stream/othello-game.ts
@@ -1,7 +1,7 @@
 import * as websocket from 'websocket';
 import * as redis from 'redis';
 import * as CRC32 from 'crc-32';
-import Game, { pack } from '../models/othello-game';
+import OthelloGame, { pack } from '../models/othello-game';
 import { publishOthelloGameStream } from '../event';
 import Othello from '../../common/othello/core';
 import * as maps from '../../common/othello/maps';
@@ -60,14 +60,14 @@ export default function(request: websocket.request, connection: websocket.connec
 	});
 
 	async function updateSettings(settings) {
-		const game = await Game.findOne({ _id: gameId });
+		const game = await OthelloGame.findOne({ _id: gameId });
 
-		if (game.is_started) return;
-		if (!game.user1_id.equals(user._id) && !game.user2_id.equals(user._id)) return;
-		if (game.user1_id.equals(user._id) && game.user1_accepted) return;
-		if (game.user2_id.equals(user._id) && game.user2_accepted) return;
+		if (game.isStarted) return;
+		if (!game.user1Id.equals(user._id) && !game.user2Id.equals(user._id)) return;
+		if (game.user1Id.equals(user._id) && game.user1Accepted) return;
+		if (game.user2Id.equals(user._id) && game.user2Accepted) return;
 
-		await Game.update({ _id: gameId }, {
+		await OthelloGame.update({ _id: gameId }, {
 			$set: {
 				settings
 			}
@@ -77,34 +77,34 @@ export default function(request: websocket.request, connection: websocket.connec
 	}
 
 	async function initForm(form) {
-		const game = await Game.findOne({ _id: gameId });
+		const game = await OthelloGame.findOne({ _id: gameId });
 
-		if (game.is_started) return;
-		if (!game.user1_id.equals(user._id) && !game.user2_id.equals(user._id)) return;
+		if (game.isStarted) return;
+		if (!game.user1Id.equals(user._id) && !game.user2Id.equals(user._id)) return;
 
-		const set = game.user1_id.equals(user._id) ? {
+		const set = game.user1Id.equals(user._id) ? {
 			form1: form
 		} : {
 			form2: form
 		};
 
-		await Game.update({ _id: gameId }, {
+		await OthelloGame.update({ _id: gameId }, {
 			$set: set
 		});
 
 		publishOthelloGameStream(gameId, 'init-form', {
-			user_id: user._id,
+			userId: user._id,
 			form
 		});
 	}
 
 	async function updateForm(id, value) {
-		const game = await Game.findOne({ _id: gameId });
+		const game = await OthelloGame.findOne({ _id: gameId });
 
-		if (game.is_started) return;
-		if (!game.user1_id.equals(user._id) && !game.user2_id.equals(user._id)) return;
+		if (game.isStarted) return;
+		if (!game.user1Id.equals(user._id) && !game.user2Id.equals(user._id)) return;
 
-		const form = game.user1_id.equals(user._id) ? game.form2 : game.form1;
+		const form = game.user1Id.equals(user._id) ? game.form2 : game.form1;
 
 		const item = form.find(i => i.id == id);
 
@@ -112,18 +112,18 @@ export default function(request: websocket.request, connection: websocket.connec
 
 		item.value = value;
 
-		const set = game.user1_id.equals(user._id) ? {
+		const set = game.user1Id.equals(user._id) ? {
 			form2: form
 		} : {
 			form1: form
 		};
 
-		await Game.update({ _id: gameId }, {
+		await OthelloGame.update({ _id: gameId }, {
 			$set: set
 		});
 
 		publishOthelloGameStream(gameId, 'update-form', {
-			user_id: user._id,
+			userId: user._id,
 			id,
 			value
 		});
@@ -132,44 +132,44 @@ export default function(request: websocket.request, connection: websocket.connec
 	async function message(message) {
 		message.id = Math.random();
 		publishOthelloGameStream(gameId, 'message', {
-			user_id: user._id,
+			userId: user._id,
 			message
 		});
 	}
 
 	async function accept(accept: boolean) {
-		const game = await Game.findOne({ _id: gameId });
+		const game = await OthelloGame.findOne({ _id: gameId });
 
-		if (game.is_started) return;
+		if (game.isStarted) return;
 
 		let bothAccepted = false;
 
-		if (game.user1_id.equals(user._id)) {
-			await Game.update({ _id: gameId }, {
+		if (game.user1Id.equals(user._id)) {
+			await OthelloGame.update({ _id: gameId }, {
 				$set: {
-					user1_accepted: accept
+					user1Accepted: accept
 				}
 			});
 
 			publishOthelloGameStream(gameId, 'change-accepts', {
 				user1: accept,
-				user2: game.user2_accepted
+				user2: game.user2Accepted
 			});
 
-			if (accept && game.user2_accepted) bothAccepted = true;
-		} else if (game.user2_id.equals(user._id)) {
-			await Game.update({ _id: gameId }, {
+			if (accept && game.user2Accepted) bothAccepted = true;
+		} else if (game.user2Id.equals(user._id)) {
+			await OthelloGame.update({ _id: gameId }, {
 				$set: {
-					user2_accepted: accept
+					user2Accepted: accept
 				}
 			});
 
 			publishOthelloGameStream(gameId, 'change-accepts', {
-				user1: game.user1_accepted,
+				user1: game.user1Accepted,
 				user2: accept
 			});
 
-			if (accept && game.user1_accepted) bothAccepted = true;
+			if (accept && game.user1Accepted) bothAccepted = true;
 		} else {
 			return;
 		}
@@ -177,9 +177,9 @@ export default function(request: websocket.request, connection: websocket.connec
 		if (bothAccepted) {
 			// 3秒後、まだacceptされていたらゲーム開始
 			setTimeout(async () => {
-				const freshGame = await Game.findOne({ _id: gameId });
-				if (freshGame == null || freshGame.is_started || freshGame.is_ended) return;
-				if (!freshGame.user1_accepted || !freshGame.user2_accepted) return;
+				const freshGame = await OthelloGame.findOne({ _id: gameId });
+				if (freshGame == null || freshGame.isStarted || freshGame.isEnded) return;
+				if (!freshGame.user1Accepted || !freshGame.user2Accepted) return;
 
 				let bw: number;
 				if (freshGame.settings.bw == 'random') {
@@ -196,10 +196,10 @@ export default function(request: websocket.request, connection: websocket.connec
 
 				const map = freshGame.settings.map != null ? freshGame.settings.map : getRandomMap();
 
-				await Game.update({ _id: gameId }, {
+				await OthelloGame.update({ _id: gameId }, {
 					$set: {
-						started_at: new Date(),
-						is_started: true,
+						startedAt: new Date(),
+						isStarted: true,
 						black: bw,
 						'settings.map': map
 					}
@@ -207,32 +207,32 @@ export default function(request: websocket.request, connection: websocket.connec
 
 				//#region 盤面に最初から石がないなどして始まった瞬間に勝敗が決定する場合があるのでその処理
 				const o = new Othello(map, {
-					isLlotheo: freshGame.settings.is_llotheo,
-					canPutEverywhere: freshGame.settings.can_put_everywhere,
-					loopedBoard: freshGame.settings.looped_board
+					isLlotheo: freshGame.settings.isLlotheo,
+					canPutEverywhere: freshGame.settings.canPutEverywhere,
+					loopedBoard: freshGame.settings.loopedBoard
 				});
 
 				if (o.isEnded) {
 					let winner;
 					if (o.winner === true) {
-						winner = freshGame.black == 1 ? freshGame.user1_id : freshGame.user2_id;
+						winner = freshGame.black == 1 ? freshGame.user1Id : freshGame.user2Id;
 					} else if (o.winner === false) {
-						winner = freshGame.black == 1 ? freshGame.user2_id : freshGame.user1_id;
+						winner = freshGame.black == 1 ? freshGame.user2Id : freshGame.user1Id;
 					} else {
 						winner = null;
 					}
 
-					await Game.update({
+					await OthelloGame.update({
 						_id: gameId
 					}, {
 						$set: {
-							is_ended: true,
-							winner_id: winner
+							isEnded: true,
+							winnerId: winner
 						}
 					});
 
 					publishOthelloGameStream(gameId, 'ended', {
-						winner_id: winner,
+						winnerId: winner,
 						game: await pack(gameId, user)
 					});
 				}
@@ -245,16 +245,16 @@ export default function(request: websocket.request, connection: websocket.connec
 
 	// 石を打つ
 	async function set(pos) {
-		const game = await Game.findOne({ _id: gameId });
+		const game = await OthelloGame.findOne({ _id: gameId });
 
-		if (!game.is_started) return;
-		if (game.is_ended) return;
-		if (!game.user1_id.equals(user._id) && !game.user2_id.equals(user._id)) return;
+		if (!game.isStarted) return;
+		if (game.isEnded) return;
+		if (!game.user1Id.equals(user._id) && !game.user2Id.equals(user._id)) return;
 
 		const o = new Othello(game.settings.map, {
-			isLlotheo: game.settings.is_llotheo,
-			canPutEverywhere: game.settings.can_put_everywhere,
-			loopedBoard: game.settings.looped_board
+			isLlotheo: game.settings.isLlotheo,
+			canPutEverywhere: game.settings.canPutEverywhere,
+			loopedBoard: game.settings.loopedBoard
 		});
 
 		game.logs.forEach(log => {
@@ -262,7 +262,7 @@ export default function(request: websocket.request, connection: websocket.connec
 		});
 
 		const myColor =
-			(game.user1_id.equals(user._id) && game.black == 1) || (game.user2_id.equals(user._id) && game.black == 2)
+			(game.user1Id.equals(user._id) && game.black == 1) || (game.user2Id.equals(user._id) && game.black == 2)
 				? true
 				: false;
 
@@ -272,9 +272,9 @@ export default function(request: websocket.request, connection: websocket.connec
 		let winner;
 		if (o.isEnded) {
 			if (o.winner === true) {
-				winner = game.black == 1 ? game.user1_id : game.user2_id;
+				winner = game.black == 1 ? game.user1Id : game.user2Id;
 			} else if (o.winner === false) {
-				winner = game.black == 1 ? game.user2_id : game.user1_id;
+				winner = game.black == 1 ? game.user2Id : game.user1Id;
 			} else {
 				winner = null;
 			}
@@ -288,13 +288,13 @@ export default function(request: websocket.request, connection: websocket.connec
 
 		const crc32 = CRC32.str(game.logs.map(x => x.pos.toString()).join('') + pos.toString());
 
-		await Game.update({
+		await OthelloGame.update({
 			_id: gameId
 		}, {
 			$set: {
 				crc32,
-				is_ended: o.isEnded,
-				winner_id: winner
+				isEnded: o.isEnded,
+				winnerId: winner
 			},
 			$push: {
 				logs: log
@@ -307,16 +307,16 @@ export default function(request: websocket.request, connection: websocket.connec
 
 		if (o.isEnded) {
 			publishOthelloGameStream(gameId, 'ended', {
-				winner_id: winner,
+				winnerId: winner,
 				game: await pack(gameId, user)
 			});
 		}
 	}
 
 	async function check(crc32) {
-		const game = await Game.findOne({ _id: gameId });
+		const game = await OthelloGame.findOne({ _id: gameId });
 
-		if (!game.is_started) return;
+		if (!game.isStarted) return;
 
 		// 互換性のため
 		if (game.crc32 == null) return;
diff --git a/src/server/api/stream/othello.ts b/src/server/api/stream/othello.ts
index bd3b4a763..55c993ec8 100644
--- a/src/server/api/stream/othello.ts
+++ b/src/server/api/stream/othello.ts
@@ -18,11 +18,11 @@ export default function(request: websocket.request, connection: websocket.connec
 			case 'ping':
 				if (msg.id == null) return;
 				const matching = await Matching.findOne({
-					parent_id: user._id,
-					child_id: new mongo.ObjectID(msg.id)
+					parentId: user._id,
+					childId: new mongo.ObjectID(msg.id)
 				});
 				if (matching == null) return;
-				publishUserStream(matching.child_id, 'othello_invited', await pack(matching, matching.child_id));
+				publishUserStream(matching.childId, 'othello_invited', await pack(matching, matching.childId));
 				break;
 		}
 	});
diff --git a/src/server/api/streaming.ts b/src/server/api/streaming.ts
index 95f444e00..73f099bd8 100644
--- a/src/server/api/streaming.ts
+++ b/src/server/api/streaming.ts
@@ -110,7 +110,7 @@ function authenticate(token: string): Promise<IUser> {
 
 			// Fetch user
 			const user: IUser = await User
-				.findOne({ _id: accessToken.user_id });
+				.findOne({ _id: accessToken.userId });
 
 			resolve(user);
 		}
diff --git a/src/server/common/get-post-summary.ts b/src/server/common/get-post-summary.ts
index 6e8f65708..8d0033064 100644
--- a/src/server/common/get-post-summary.ts
+++ b/src/server/common/get-post-summary.ts
@@ -22,7 +22,7 @@ const summarize = (post: any): string => {
 	}
 
 	// 返信のとき
-	if (post.reply_id) {
+	if (post.replyId) {
 		if (post.reply) {
 			summary += ` RE: ${summarize(post.reply)}`;
 		} else {
@@ -31,7 +31,7 @@ const summarize = (post: any): string => {
 	}
 
 	// Repostのとき
-	if (post.repost_id) {
+	if (post.repostId) {
 		if (post.repost) {
 			summary += ` RP: ${summarize(post.repost)}`;
 		} else {
diff --git a/src/server/common/othello/ai/back.ts b/src/server/common/othello/ai/back.ts
index c20c6fed2..629e57113 100644
--- a/src/server/common/othello/ai/back.ts
+++ b/src/server/common/othello/ai/back.ts
@@ -44,7 +44,7 @@ process.on('message', async msg => {
 		//#region TLに投稿する
 		const game = msg.body;
 		const url = `${conf.url}/othello/${game.id}`;
-		const user = game.user1_id == id ? game.user2 : game.user1;
+		const user = game.user1Id == id ? game.user2 : game.user1;
 		const isSettai = form[0].value === 0;
 		const text = isSettai
 			? `?[${user.name}](${conf.url}/@${user.username})さんの接待を始めました!`
@@ -56,7 +56,7 @@ process.on('message', async msg => {
 			}
 		});
 
-		post = res.created_post;
+		post = res.createdPost;
 		//#endregion
 	}
 
@@ -68,23 +68,23 @@ process.on('message', async msg => {
 		});
 
 		//#region TLに投稿する
-		const user = game.user1_id == id ? game.user2 : game.user1;
+		const user = game.user1Id == id ? game.user2 : game.user1;
 		const isSettai = form[0].value === 0;
 		const text = isSettai
-			? msg.body.winner_id === null
+			? msg.body.winnerId === null
 				? `?[${user.name}](${conf.url}/@${user.username})さんに接待で引き分けました...`
-				: msg.body.winner_id == id
+				: msg.body.winnerId == id
 					? `?[${user.name}](${conf.url}/@${user.username})さんに接待で勝ってしまいました...`
 					: `?[${user.name}](${conf.url}/@${user.username})さんに接待で負けてあげました♪`
-			: msg.body.winner_id === null
+			: msg.body.winnerId === null
 				? `?[${user.name}](${conf.url}/@${user.username})さんと引き分けました~`
-				: msg.body.winner_id == id
+				: msg.body.winnerId == id
 					? `?[${user.name}](${conf.url}/@${user.username})さんに勝ちました♪`
 					: `?[${user.name}](${conf.url}/@${user.username})さんに負けました...`;
 
 		await request.post(`${conf.api_url}/posts/create`, {
 			json: { i,
-				repost_id: post.id,
+				repostId: post.id,
 				text: text
 			}
 		});
@@ -114,9 +114,9 @@ function onGameStarted(g) {
 
 	// オセロエンジン初期化
 	o = new Othello(game.settings.map, {
-		isLlotheo: game.settings.is_llotheo,
-		canPutEverywhere: game.settings.can_put_everywhere,
-		loopedBoard: game.settings.looped_board
+		isLlotheo: game.settings.isLlotheo,
+		canPutEverywhere: game.settings.canPutEverywhere,
+		loopedBoard: game.settings.loopedBoard
 	});
 
 	// 各マスの価値を計算しておく
@@ -141,7 +141,7 @@ function onGameStarted(g) {
 		return count >= 4 ? 1 : 0;
 	});
 
-	botColor = game.user1_id == id && game.black == 1 || game.user2_id == id && game.black == 2;
+	botColor = game.user1Id == id && game.black == 1 || game.user2Id == id && game.black == 2;
 
 	if (botColor) {
 		think();
@@ -188,7 +188,7 @@ function think() {
 		});
 
 		// ロセオならスコアを反転
-		if (game.settings.is_llotheo) score = -score;
+		if (game.settings.isLlotheo) score = -score;
 
 		// 接待ならスコアを反転
 		if (isSettai) score = -score;
@@ -234,7 +234,7 @@ function think() {
 
 			let score;
 
-			if (game.settings.is_llotheo) {
+			if (game.settings.isLlotheo) {
 				// 勝ちは勝ちでも、より自分の石を少なくした方が美しい勝ちだと判定する
 				score = o.winner ? base - (o.blackCount * 100) : base - (o.whiteCount * 100);
 			} else {
@@ -317,7 +317,7 @@ function think() {
 
 			let score;
 
-			if (game.settings.is_llotheo) {
+			if (game.settings.isLlotheo) {
 				// 勝ちは勝ちでも、より自分の石を少なくした方が美しい勝ちだと判定する
 				score = o.winner ? base - (o.blackCount * 100) : base - (o.whiteCount * 100);
 			} else {
diff --git a/src/server/common/othello/ai/front.ts b/src/server/common/othello/ai/front.ts
index af0b748fc..fb7a9be13 100644
--- a/src/server/common/othello/ai/front.ts
+++ b/src/server/common/othello/ai/front.ts
@@ -48,12 +48,12 @@ homeStream.on('message', message => {
 	if (msg.type == 'mention' || msg.type == 'reply') {
 		const post = msg.body;
 
-		if (post.user_id == id) return;
+		if (post.userId == id) return;
 
 		// リアクションする
 		request.post(`${conf.api_url}/posts/reactions/create`, {
 			json: { i,
-				post_id: post.id,
+				postId: post.id,
 				reaction: 'love'
 			}
 		});
@@ -62,12 +62,12 @@ homeStream.on('message', message => {
 			if (post.text.indexOf('オセロ') > -1) {
 				request.post(`${conf.api_url}/posts/create`, {
 					json: { i,
-						reply_id: post.id,
+						replyId: post.id,
 						text: '良いですよ~'
 					}
 				});
 
-				invite(post.user_id);
+				invite(post.userId);
 			}
 		}
 	}
@@ -79,12 +79,12 @@ homeStream.on('message', message => {
 			if (message.text.indexOf('オセロ') > -1) {
 				request.post(`${conf.api_url}/messaging/messages/create`, {
 					json: { i,
-						user_id: message.user_id,
+						userId: message.userId,
 						text: '良いですよ~'
 					}
 				});
 
-				invite(message.user_id);
+				invite(message.userId);
 			}
 		}
 	}
@@ -94,7 +94,7 @@ homeStream.on('message', message => {
 function invite(userId) {
 	request.post(`${conf.api_url}/othello/match`, {
 		json: { i,
-			user_id: userId
+			userId: userId
 		}
 	});
 }
@@ -225,7 +225,7 @@ async function onInviteMe(inviter) {
 	const game = await request.post(`${conf.api_url}/othello/match`, {
 		json: {
 			i,
-			user_id: inviter.id
+			userId: inviter.id
 		}
 	});
 
diff --git a/src/server/common/user/get-summary.ts b/src/server/common/user/get-summary.ts
index f9b7125e3..b314a5cef 100644
--- a/src/server/common/user/get-summary.ts
+++ b/src/server/common/user/get-summary.ts
@@ -7,7 +7,7 @@ import getAcct from './get-acct';
  */
 export default function(user: IUser): string {
 	let string = `${user.name} (@${getAcct(user)})\n` +
-		`${user.posts_count}投稿、${user.following_count}フォロー、${user.followers_count}フォロワー\n`;
+		`${user.postsCount}投稿、${user.followingCount}フォロー、${user.followersCount}フォロワー\n`;
 
 	if (user.host === null) {
 		const account = user.account as ILocalAccount;
diff --git a/src/server/web/app/auth/views/form.vue b/src/server/web/app/auth/views/form.vue
index d86ed58b3..9d9e8cdb1 100644
--- a/src/server/web/app/auth/views/form.vue
+++ b/src/server/web/app/auth/views/form.vue
@@ -7,7 +7,7 @@
 	<div class="app">
 		<section>
 			<h2>{{ app.name }}</h2>
-			<p class="nid">{{ app.name_id }}</p>
+			<p class="nid">{{ app.nameId }}</p>
 			<p class="description">{{ app.description }}</p>
 		</section>
 		<section>
diff --git a/src/server/web/app/auth/views/index.vue b/src/server/web/app/auth/views/index.vue
index 17e5cc610..e1e1b265e 100644
--- a/src/server/web/app/auth/views/index.vue
+++ b/src/server/web/app/auth/views/index.vue
@@ -14,9 +14,9 @@
 			<p>このアプリがあなたのアカウントにアクセスすることはありません。</p>
 		</div>
 		<div class="accepted" v-if="state == 'accepted'">
-			<h1>{{ session.app.is_authorized ? 'このアプリは既に連携済みです' : 'アプリケーションの連携を許可しました'}}</h1>
-			<p v-if="session.app.callback_url">アプリケーションに戻っています<mk-ellipsis/></p>
-			<p v-if="!session.app.callback_url">アプリケーションに戻って、やっていってください。</p>
+			<h1>{{ session.app.isAuthorized ? 'このアプリは既に連携済みです' : 'アプリケーションの連携を許可しました' }}</h1>
+			<p v-if="session.app.callbackUrl">アプリケーションに戻っています<mk-ellipsis/></p>
+			<p v-if="!session.app.callbackUrl">アプリケーションに戻って、やっていってください。</p>
 		</div>
 		<div class="error" v-if="state == 'fetch-session-error'">
 			<p>セッションが存在しません。</p>
@@ -61,7 +61,7 @@ export default Vue.extend({
 			this.fetching = false;
 
 			// 既に連携していた場合
-			if (this.session.app.is_authorized) {
+			if (this.session.app.isAuthorized) {
 				this.$root.$data.os.api('auth/accept', {
 					token: this.session.token
 				}).then(() => {
@@ -77,8 +77,8 @@ export default Vue.extend({
 	methods: {
 		accepted() {
 			this.state = 'accepted';
-			if (this.session.app.callback_url) {
-				location.href = this.session.app.callback_url + '?token=' + this.session.token;
+			if (this.session.app.callbackUrl) {
+				location.href = this.session.app.callbackUrl + '?token=' + this.session.token;
 			}
 		}
 	}
diff --git a/src/server/web/app/ch/tags/channel.tag b/src/server/web/app/ch/tags/channel.tag
index dc4b8e142..2abfb106a 100644
--- a/src/server/web/app/ch/tags/channel.tag
+++ b/src/server/web/app/ch/tags/channel.tag
@@ -5,8 +5,8 @@
 		<h1>{ channel.title }</h1>
 
 		<div v-if="$root.$data.os.isSignedIn">
-			<p v-if="channel.is_watching">このチャンネルをウォッチしています <a @click="unwatch">ウォッチ解除</a></p>
-			<p v-if="!channel.is_watching"><a @click="watch">このチャンネルをウォッチする</a></p>
+			<p v-if="channel.isWatching">このチャンネルをウォッチしています <a @click="unwatch">ウォッチ解除</a></p>
+			<p v-if="!channel.isWatching"><a @click="watch">このチャンネルをウォッチする</a></p>
 		</div>
 
 		<div class="share">
@@ -77,7 +77,7 @@
 
 			// チャンネル概要読み込み
 			this.$root.$data.os.api('channels/show', {
-				channel_id: this.id
+				channelId: this.id
 			}).then(channel => {
 				if (fetched) {
 					Progress.done();
@@ -96,7 +96,7 @@
 
 			// 投稿読み込み
 			this.$root.$data.os.api('channels/posts', {
-				channel_id: this.id
+				channelId: this.id
 			}).then(posts => {
 				if (fetched) {
 					Progress.done();
@@ -125,7 +125,7 @@
 			this.posts.unshift(post);
 			this.update();
 
-			if (document.hidden && this.$root.$data.os.isSignedIn && post.user_id !== this.$root.$data.os.i.id) {
+			if (document.hidden && this.$root.$data.os.isSignedIn && post.userId !== this.$root.$data.os.i.id) {
 				this.unreadCount++;
 				document.title = `(${this.unreadCount}) ${this.channel.title} | Misskey`;
 			}
@@ -140,9 +140,9 @@
 
 		this.watch = () => {
 			this.$root.$data.os.api('channels/watch', {
-				channel_id: this.id
+				channelId: this.id
 			}).then(() => {
-				this.channel.is_watching = true;
+				this.channel.isWatching = true;
 				this.update();
 			}, e => {
 				alert('error');
@@ -151,9 +151,9 @@
 
 		this.unwatch = () => {
 			this.$root.$data.os.api('channels/unwatch', {
-				channel_id: this.id
+				channelId: this.id
 			}).then(() => {
-				this.channel.is_watching = false;
+				this.channel.isWatching = false;
 				this.update();
 			}, e => {
 				alert('error');
@@ -166,8 +166,8 @@
 	<header>
 		<a class="index" @click="reply">{ post.index }:</a>
 		<a class="name" href={ _URL_ + '/@' + acct }><b>{ post.user.name }</b></a>
-		<mk-time time={ post.created_at }/>
-		<mk-time time={ post.created_at } mode="detail"/>
+		<mk-time time={ post.createdAt }/>
+		<mk-time time={ post.createdAt } mode="detail"/>
 		<span>ID:<i>{ acct }</i></span>
 	</header>
 	<div>
@@ -328,9 +328,9 @@
 
 			this.$root.$data.os.api('posts/create', {
 				text: this.$refs.text.value == '' ? undefined : this.$refs.text.value,
-				media_ids: files,
-				reply_id: this.reply ? this.reply.id : undefined,
-				channel_id: this.channel.id
+				mediaIds: files,
+				replyId: this.reply ? this.reply.id : undefined,
+				channelId: this.channel.id
 			}).then(data => {
 				this.clear();
 			}).catch(err => {
diff --git a/src/server/web/app/common/define-widget.ts b/src/server/web/app/common/define-widget.ts
index d8d29873a..27db59b5e 100644
--- a/src/server/web/app/common/define-widget.ts
+++ b/src/server/web/app/common/define-widget.ts
@@ -56,14 +56,14 @@ export default function<T extends object>(data: {
 						id: this.id,
 						data: newProps
 					}).then(() => {
-						(this as any).os.i.account.client_settings.mobile_home.find(w => w.id == this.id).data = newProps;
+						(this as any).os.i.account.clientSettings.mobile_home.find(w => w.id == this.id).data = newProps;
 					});
 				} else {
 					(this as any).api('i/update_home', {
 						id: this.id,
 						data: newProps
 					}).then(() => {
-						(this as any).os.i.account.client_settings.home.find(w => w.id == this.id).data = newProps;
+						(this as any).os.i.account.clientSettings.home.find(w => w.id == this.id).data = newProps;
 					});
 				}
 			}, {
diff --git a/src/server/web/app/common/mios.ts b/src/server/web/app/common/mios.ts
index 2c6c9988e..bcb8b6067 100644
--- a/src/server/web/app/common/mios.ts
+++ b/src/server/web/app/common/mios.ts
@@ -294,12 +294,12 @@ export default class MiOS extends EventEmitter {
 		const fetched = me => {
 			if (me) {
 				// デフォルトの設定をマージ
-				me.account.client_settings = Object.assign({
+				me.account.clientSettings = Object.assign({
 					fetchOnScroll: true,
 					showMaps: true,
 					showPostFormOnTopOfTl: false,
 					gradientWindowHeader: false
-				}, me.account.client_settings);
+				}, me.account.clientSettings);
 
 				// ローカルストレージにキャッシュ
 				localStorage.setItem('me', JSON.stringify(me));
diff --git a/src/server/web/app/common/scripts/compose-notification.ts b/src/server/web/app/common/scripts/compose-notification.ts
index e1dbd3bc1..273579cbc 100644
--- a/src/server/web/app/common/scripts/compose-notification.ts
+++ b/src/server/web/app/common/scripts/compose-notification.ts
@@ -23,42 +23,42 @@ export default function(type, data): Notification {
 			return {
 				title: `${data.user.name}さんから:`,
 				body: getPostSummary(data),
-				icon: data.user.avatar_url + '?thumbnail&size=64'
+				icon: data.user.avatarUrl + '?thumbnail&size=64'
 			};
 
 		case 'reply':
 			return {
 				title: `${data.user.name}さんから返信:`,
 				body: getPostSummary(data),
-				icon: data.user.avatar_url + '?thumbnail&size=64'
+				icon: data.user.avatarUrl + '?thumbnail&size=64'
 			};
 
 		case 'quote':
 			return {
 				title: `${data.user.name}さんが引用:`,
 				body: getPostSummary(data),
-				icon: data.user.avatar_url + '?thumbnail&size=64'
+				icon: data.user.avatarUrl + '?thumbnail&size=64'
 			};
 
 		case 'reaction':
 			return {
 				title: `${data.user.name}: ${getReactionEmoji(data.reaction)}:`,
 				body: getPostSummary(data.post),
-				icon: data.user.avatar_url + '?thumbnail&size=64'
+				icon: data.user.avatarUrl + '?thumbnail&size=64'
 			};
 
 		case 'unread_messaging_message':
 			return {
 				title: `${data.user.name}さんからメッセージ:`,
 				body: data.text, // TODO: getMessagingMessageSummary(data),
-				icon: data.user.avatar_url + '?thumbnail&size=64'
+				icon: data.user.avatarUrl + '?thumbnail&size=64'
 			};
 
 		case 'othello_invited':
 			return {
 				title: '対局への招待があります',
 				body: `${data.parent.name}さんから`,
-				icon: data.parent.avatar_url + '?thumbnail&size=64'
+				icon: data.parent.avatarUrl + '?thumbnail&size=64'
 			};
 
 		default:
diff --git a/src/server/web/app/common/scripts/parse-search-query.ts b/src/server/web/app/common/scripts/parse-search-query.ts
index 512791ecb..4f09d2b93 100644
--- a/src/server/web/app/common/scripts/parse-search-query.ts
+++ b/src/server/web/app/common/scripts/parse-search-query.ts
@@ -8,10 +8,10 @@ export default function(qs: string) {
 			const [key, value] = x.split(':');
 			switch (key) {
 				case 'user':
-					q['include_user_usernames'] = value.split(',');
+					q['includeUserUsernames'] = value.split(',');
 					break;
 				case 'exclude_user':
-					q['exclude_user_usernames'] = value.split(',');
+					q['excludeUserUsernames'] = value.split(',');
 					break;
 				case 'follow':
 					q['following'] = value == 'null' ? null : value == 'true';
diff --git a/src/server/web/app/common/scripts/streaming/home.ts b/src/server/web/app/common/scripts/streaming/home.ts
index ffcf6e536..c19861940 100644
--- a/src/server/web/app/common/scripts/streaming/home.ts
+++ b/src/server/web/app/common/scripts/streaming/home.ts
@@ -16,7 +16,7 @@ export class HomeStream extends Stream {
 		// 最終利用日時を更新するため定期的にaliveメッセージを送信
 		setInterval(() => {
 			this.send({ type: 'alive' });
-			me.account.last_used_at = new Date();
+			me.account.lastUsedAt = new Date();
 		}, 1000 * 60);
 
 		// 自分の情報が更新されたとき
diff --git a/src/server/web/app/common/views/components/autocomplete.vue b/src/server/web/app/common/views/components/autocomplete.vue
index 8afa291e3..79bd2ba02 100644
--- a/src/server/web/app/common/views/components/autocomplete.vue
+++ b/src/server/web/app/common/views/components/autocomplete.vue
@@ -2,7 +2,7 @@
 <div class="mk-autocomplete" @contextmenu.prevent="() => {}">
 	<ol class="users" ref="suggests" v-if="users.length > 0">
 		<li v-for="user in users" @click="complete(type, user)" @keydown="onKeydown" tabindex="-1">
-			<img class="avatar" :src="`${user.avatar_url}?thumbnail&size=32`" alt=""/>
+			<img class="avatar" :src="`${user.avatarUrl}?thumbnail&size=32`" alt=""/>
 			<span class="name">{{ user.name }}</span>
 			<span class="username">@{{ getAcct(user) }}</span>
 		</li>
diff --git a/src/server/web/app/common/views/components/messaging-room.form.vue b/src/server/web/app/common/views/components/messaging-room.form.vue
index 01886b19c..704f2016d 100644
--- a/src/server/web/app/common/views/components/messaging-room.form.vue
+++ b/src/server/web/app/common/views/components/messaging-room.form.vue
@@ -151,9 +151,9 @@ export default Vue.extend({
 		send() {
 			this.sending = true;
 			(this as any).api('messaging/messages/create', {
-				user_id: this.user.id,
+				userId: this.user.id,
 				text: this.text ? this.text : undefined,
-				file_id: this.file ? this.file.id : undefined
+				fileId: this.file ? this.file.id : undefined
 			}).then(message => {
 				this.clear();
 			}).catch(err => {
@@ -173,7 +173,7 @@ export default Vue.extend({
 			const data = JSON.parse(localStorage.getItem('message_drafts') || '{}');
 
 			data[this.draftId] = {
-				updated_at: new Date(),
+				updatedAt: new Date(),
 				data: {
 					text: this.text,
 					file: this.file
diff --git a/src/server/web/app/common/views/components/messaging-room.message.vue b/src/server/web/app/common/views/components/messaging-room.message.vue
index 5f2eb1ba8..94f87fd70 100644
--- a/src/server/web/app/common/views/components/messaging-room.message.vue
+++ b/src/server/web/app/common/views/components/messaging-room.message.vue
@@ -1,15 +1,15 @@
 <template>
 <div class="message" :data-is-me="isMe">
 	<router-link class="avatar-anchor" :to="`/@${acct}`" :title="acct" target="_blank">
-		<img class="avatar" :src="`${message.user.avatar_url}?thumbnail&size=80`" alt=""/>
+		<img class="avatar" :src="`${message.user.avatarUrl}?thumbnail&size=80`" alt=""/>
 	</router-link>
 	<div class="content">
 		<div class="balloon" :data-no-text="message.text == null">
-			<p class="read" v-if="isMe && message.is_read">%i18n:common.tags.mk-messaging-message.is-read%</p>
+			<p class="read" v-if="isMe && message.isRead">%i18n:common.tags.mk-messaging-message.is-read%</p>
 			<button class="delete-button" v-if="isMe" title="%i18n:common.delete%">
 				<img src="/assets/desktop/messaging/delete.png" alt="Delete"/>
 			</button>
-			<div class="content" v-if="!message.is_deleted">
+			<div class="content" v-if="!message.isDeleted">
 				<mk-post-html class="text" v-if="message.ast" :ast="message.ast" :i="os.i"/>
 				<div class="file" v-if="message.file">
 					<a :href="message.file.url" target="_blank" :title="message.file.name">
@@ -18,14 +18,14 @@
 					</a>
 				</div>
 			</div>
-			<div class="content" v-if="message.is_deleted">
+			<div class="content" v-if="message.isDeleted">
 				<p class="is-deleted">%i18n:common.tags.mk-messaging-message.deleted%</p>
 			</div>
 		</div>
 		<div></div>
 		<mk-url-preview v-for="url in urls" :url="url" :key="url"/>
 		<footer>
-			<mk-time :time="message.created_at"/>
+			<mk-time :time="message.createdAt"/>
 			<template v-if="message.is_edited">%fa:pencil-alt%</template>
 		</footer>
 	</div>
@@ -43,7 +43,7 @@ export default Vue.extend({
 			return getAcct(this.message.user);
 		},
 		isMe(): boolean {
-			return this.message.user_id == (this as any).os.i.id;
+			return this.message.userId == (this as any).os.i.id;
 		},
 		urls(): string[] {
 			if (this.message.ast) {
diff --git a/src/server/web/app/common/views/components/messaging-room.vue b/src/server/web/app/common/views/components/messaging-room.vue
index 6ff808b61..d30c64d74 100644
--- a/src/server/web/app/common/views/components/messaging-room.vue
+++ b/src/server/web/app/common/views/components/messaging-room.vue
@@ -52,8 +52,8 @@ export default Vue.extend({
 	computed: {
 		_messages(): any[] {
 			return (this.messages as any).map(message => {
-				const date = new Date(message.created_at).getDate();
-				const month = new Date(message.created_at).getMonth() + 1;
+				const date = new Date(message.createdAt).getDate();
+				const month = new Date(message.createdAt).getMonth() + 1;
 				message._date = date;
 				message._datetext = `${month}月 ${date}日`;
 				return message;
@@ -123,9 +123,9 @@ export default Vue.extend({
 				const max = this.existMoreMessages ? 20 : 10;
 
 				(this as any).api('messaging/messages', {
-					user_id: this.user.id,
+					userId: this.user.id,
 					limit: max + 1,
-					until_id: this.existMoreMessages ? this.messages[0].id : undefined
+					untilId: this.existMoreMessages ? this.messages[0].id : undefined
 				}).then(messages => {
 					if (messages.length == max + 1) {
 						this.existMoreMessages = true;
@@ -158,7 +158,7 @@ export default Vue.extend({
 			const isBottom = this.isBottom();
 
 			this.messages.push(message);
-			if (message.user_id != (this as any).os.i.id && !document.hidden) {
+			if (message.userId != (this as any).os.i.id && !document.hidden) {
 				this.connection.send({
 					type: 'read',
 					id: message.id
@@ -170,7 +170,7 @@ export default Vue.extend({
 				this.$nextTick(() => {
 					this.scrollToBottom();
 				});
-			} else if (message.user_id != (this as any).os.i.id) {
+			} else if (message.userId != (this as any).os.i.id) {
 				// Notify
 				this.notify('%i18n:common.tags.mk-messaging-room.new-message%');
 			}
@@ -181,7 +181,7 @@ export default Vue.extend({
 			ids.forEach(id => {
 				if (this.messages.some(x => x.id == id)) {
 					const exist = this.messages.map(x => x.id).indexOf(id);
-					this.messages[exist].is_read = true;
+					this.messages[exist].isRead = true;
 				}
 			});
 		},
@@ -223,7 +223,7 @@ export default Vue.extend({
 		onVisibilitychange() {
 			if (document.hidden) return;
 			this.messages.forEach(message => {
-				if (message.user_id !== (this as any).os.i.id && !message.is_read) {
+				if (message.userId !== (this as any).os.i.id && !message.isRead) {
 					this.connection.send({
 						type: 'read',
 						id: message.id
diff --git a/src/server/web/app/common/views/components/messaging.vue b/src/server/web/app/common/views/components/messaging.vue
index 88574b94d..8317c3738 100644
--- a/src/server/web/app/common/views/components/messaging.vue
+++ b/src/server/web/app/common/views/components/messaging.vue
@@ -13,7 +13,7 @@
 					@click="navigate(user)"
 					tabindex="-1"
 				>
-					<img class="avatar" :src="`${user.avatar_url}?thumbnail&size=32`" alt=""/>
+					<img class="avatar" :src="`${user.avatarUrl}?thumbnail&size=32`" alt=""/>
 					<span class="name">{{ user.name }}</span>
 					<span class="username">@{{ getAcct(user) }}</span>
 				</li>
@@ -26,16 +26,16 @@
 				class="user"
 				:href="`/i/messaging/${getAcct(isMe(message) ? message.recipient : message.user)}`"
 				:data-is-me="isMe(message)"
-				:data-is-read="message.is_read"
+				:data-is-read="message.isRead"
 				@click.prevent="navigate(isMe(message) ? message.recipient : message.user)"
 				:key="message.id"
 			>
 				<div>
-					<img class="avatar" :src="`${isMe(message) ? message.recipient.avatar_url : message.user.avatar_url}?thumbnail&size=64`" alt=""/>
+					<img class="avatar" :src="`${isMe(message) ? message.recipient.avatarUrl : message.user.avatarUrl}?thumbnail&size=64`" alt=""/>
 					<header>
 						<span class="name">{{ isMe(message) ? message.recipient.name : message.user.name }}</span>
 						<span class="username">@{{ getAcct(isMe(message) ? message.recipient : message.user) }}</span>
-						<mk-time :time="message.created_at"/>
+						<mk-time :time="message.createdAt"/>
 					</header>
 					<div class="body">
 						<p class="text"><span class="me" v-if="isMe(message)">%i18n:common.tags.mk-messaging.you%:</span>{{ message.text }}</p>
@@ -95,19 +95,19 @@ export default Vue.extend({
 	methods: {
 		getAcct,
 		isMe(message) {
-			return message.user_id == (this as any).os.i.id;
+			return message.userId == (this as any).os.i.id;
 		},
 		onMessage(message) {
 			this.messages = this.messages.filter(m => !(
-				(m.recipient_id == message.recipient_id && m.user_id == message.user_id) ||
-				(m.recipient_id == message.user_id && m.user_id == message.recipient_id)));
+				(m.recipientId == message.recipientId && m.userId == message.userId) ||
+				(m.recipientId == message.userId && m.userId == message.recipientId)));
 
 			this.messages.unshift(message);
 		},
 		onRead(ids) {
 			ids.forEach(id => {
 				const found = this.messages.find(m => m.id == id);
-				if (found) found.is_read = true;
+				if (found) found.isRead = true;
 			});
 		},
 		search() {
diff --git a/src/server/web/app/common/views/components/othello.game.vue b/src/server/web/app/common/views/components/othello.game.vue
index 414d819a5..f08742ad1 100644
--- a/src/server/web/app/common/views/components/othello.game.vue
+++ b/src/server/web/app/common/views/components/othello.game.vue
@@ -3,30 +3,30 @@
 	<header><b>{{ blackUser.name }}</b>(黒) vs <b>{{ whiteUser.name }}</b>(白)</header>
 
 	<div style="overflow: hidden">
-		<p class="turn" v-if="!iAmPlayer && !game.is_ended">{{ turnUser.name }}のターンです<mk-ellipsis/></p>
+		<p class="turn" v-if="!iAmPlayer && !game.isEnded">{{ turnUser.name }}のターンです<mk-ellipsis/></p>
 		<p class="turn" v-if="logPos != logs.length">{{ turnUser.name }}のターン</p>
-		<p class="turn1" v-if="iAmPlayer && !game.is_ended && !isMyTurn">相手のターンです<mk-ellipsis/></p>
-		<p class="turn2" v-if="iAmPlayer && !game.is_ended && isMyTurn" v-animate-css="{ classes: 'tada', iteration: 'infinite' }">あなたのターンです</p>
-		<p class="result" v-if="game.is_ended && logPos == logs.length">
-			<template v-if="game.winner"><b>{{ game.winner.name }}</b>の勝ち{{ game.settings.is_llotheo ? ' (ロセオ)' : '' }}</template>
+		<p class="turn1" v-if="iAmPlayer && !game.isEnded && !isMyTurn">相手のターンです<mk-ellipsis/></p>
+		<p class="turn2" v-if="iAmPlayer && !game.isEnded && isMyTurn" v-animate-css="{ classes: 'tada', iteration: 'infinite' }">あなたのターンです</p>
+		<p class="result" v-if="game.isEnded && logPos == logs.length">
+			<template v-if="game.winner"><b>{{ game.winner.name }}</b>の勝ち{{ game.settings.isLlotheo ? ' (ロセオ)' : '' }}</template>
 			<template v-else>引き分け</template>
 		</p>
 	</div>
 
 	<div class="board" :style="{ 'grid-template-rows': `repeat(${ game.settings.map.length }, 1fr)`, 'grid-template-columns': `repeat(${ game.settings.map[0].length }, 1fr)` }">
 		<div v-for="(stone, i) in o.board"
-			:class="{ empty: stone == null, none: o.map[i] == 'null', isEnded: game.is_ended, myTurn: !game.is_ended && isMyTurn, can: turnUser ? o.canPut(turnUser.id == blackUser.id, i) : null, prev: o.prevPos == i }"
+			:class="{ empty: stone == null, none: o.map[i] == 'null', isEnded: game.isEnded, myTurn: !game.isEnded && isMyTurn, can: turnUser ? o.canPut(turnUser.id == blackUser.id, i) : null, prev: o.prevPos == i }"
 			@click="set(i)"
 			:title="'[' + (o.transformPosToXy(i)[0] + 1) + ', ' + (o.transformPosToXy(i)[1] + 1) + '] (' + i + ')'"
 		>
-			<img v-if="stone === true" :src="`${blackUser.avatar_url}?thumbnail&size=128`" alt="">
-			<img v-if="stone === false" :src="`${whiteUser.avatar_url}?thumbnail&size=128`" alt="">
+			<img v-if="stone === true" :src="`${blackUser.avatarUrl}?thumbnail&size=128`" alt="">
+			<img v-if="stone === false" :src="`${whiteUser.avatarUrl}?thumbnail&size=128`" alt="">
 		</div>
 	</div>
 
 	<p class="status"><b>{{ logPos }}ターン目</b> 黒:{{ o.blackCount }} 白:{{ o.whiteCount }} 合計:{{ o.blackCount + o.whiteCount }}</p>
 
-	<div class="player" v-if="game.is_ended">
+	<div class="player" v-if="game.isEnded">
 		<el-button-group>
 			<el-button type="primary" @click="logPos = 0" :disabled="logPos == 0">%fa:angle-double-left%</el-button>
 			<el-button type="primary" @click="logPos--" :disabled="logPos == 0">%fa:angle-left%</el-button>
@@ -62,12 +62,12 @@ export default Vue.extend({
 	computed: {
 		iAmPlayer(): boolean {
 			if (!(this as any).os.isSignedIn) return false;
-			return this.game.user1_id == (this as any).os.i.id || this.game.user2_id == (this as any).os.i.id;
+			return this.game.user1Id == (this as any).os.i.id || this.game.user2Id == (this as any).os.i.id;
 		},
 		myColor(): Color {
 			if (!this.iAmPlayer) return null;
-			if (this.game.user1_id == (this as any).os.i.id && this.game.black == 1) return true;
-			if (this.game.user2_id == (this as any).os.i.id && this.game.black == 2) return true;
+			if (this.game.user1Id == (this as any).os.i.id && this.game.black == 1) return true;
+			if (this.game.user2Id == (this as any).os.i.id && this.game.black == 2) return true;
 			return false;
 		},
 		opColor(): Color {
@@ -97,11 +97,11 @@ export default Vue.extend({
 
 	watch: {
 		logPos(v) {
-			if (!this.game.is_ended) return;
+			if (!this.game.isEnded) return;
 			this.o = new Othello(this.game.settings.map, {
-				isLlotheo: this.game.settings.is_llotheo,
-				canPutEverywhere: this.game.settings.can_put_everywhere,
-				loopedBoard: this.game.settings.looped_board
+				isLlotheo: this.game.settings.isLlotheo,
+				canPutEverywhere: this.game.settings.canPutEverywhere,
+				loopedBoard: this.game.settings.loopedBoard
 			});
 			this.logs.forEach((log, i) => {
 				if (i < v) {
@@ -116,9 +116,9 @@ export default Vue.extend({
 		this.game = this.initGame;
 
 		this.o = new Othello(this.game.settings.map, {
-			isLlotheo: this.game.settings.is_llotheo,
-			canPutEverywhere: this.game.settings.can_put_everywhere,
-			loopedBoard: this.game.settings.looped_board
+			isLlotheo: this.game.settings.isLlotheo,
+			canPutEverywhere: this.game.settings.canPutEverywhere,
+			loopedBoard: this.game.settings.loopedBoard
 		});
 
 		this.game.logs.forEach(log => {
@@ -129,7 +129,7 @@ export default Vue.extend({
 		this.logPos = this.logs.length;
 
 		// 通信を取りこぼしてもいいように定期的にポーリングさせる
-		if (this.game.is_started && !this.game.is_ended) {
+		if (this.game.isStarted && !this.game.isEnded) {
 			this.pollingClock = setInterval(() => {
 				const crc32 = CRC32.str(this.logs.map(x => x.pos.toString()).join(''));
 				this.connection.send({
@@ -154,7 +154,7 @@ export default Vue.extend({
 
 	methods: {
 		set(pos) {
-			if (this.game.is_ended) return;
+			if (this.game.isEnded) return;
 			if (!this.iAmPlayer) return;
 			if (!this.isMyTurn) return;
 			if (!this.o.canPut(this.myColor, pos)) return;
@@ -194,16 +194,16 @@ export default Vue.extend({
 		},
 
 		checkEnd() {
-			this.game.is_ended = this.o.isEnded;
-			if (this.game.is_ended) {
+			this.game.isEnded = this.o.isEnded;
+			if (this.game.isEnded) {
 				if (this.o.winner === true) {
-					this.game.winner_id = this.game.black == 1 ? this.game.user1_id : this.game.user2_id;
+					this.game.winnerId = this.game.black == 1 ? this.game.user1Id : this.game.user2Id;
 					this.game.winner = this.game.black == 1 ? this.game.user1 : this.game.user2;
 				} else if (this.o.winner === false) {
-					this.game.winner_id = this.game.black == 1 ? this.game.user2_id : this.game.user1_id;
+					this.game.winnerId = this.game.black == 1 ? this.game.user2Id : this.game.user1Id;
 					this.game.winner = this.game.black == 1 ? this.game.user2 : this.game.user1;
 				} else {
-					this.game.winner_id = null;
+					this.game.winnerId = null;
 					this.game.winner = null;
 				}
 			}
@@ -214,9 +214,9 @@ export default Vue.extend({
 			this.game = game;
 
 			this.o = new Othello(this.game.settings.map, {
-				isLlotheo: this.game.settings.is_llotheo,
-				canPutEverywhere: this.game.settings.can_put_everywhere,
-				loopedBoard: this.game.settings.looped_board
+				isLlotheo: this.game.settings.isLlotheo,
+				canPutEverywhere: this.game.settings.canPutEverywhere,
+				loopedBoard: this.game.settings.loopedBoard
 			});
 
 			this.game.logs.forEach(log => {
diff --git a/src/server/web/app/common/views/components/othello.gameroom.vue b/src/server/web/app/common/views/components/othello.gameroom.vue
index 38a25f668..dba9ccd16 100644
--- a/src/server/web/app/common/views/components/othello.gameroom.vue
+++ b/src/server/web/app/common/views/components/othello.gameroom.vue
@@ -1,6 +1,6 @@
 <template>
 <div>
-	<x-room v-if="!g.is_started" :game="g" :connection="connection"/>
+	<x-room v-if="!g.isStarted" :game="g" :connection="connection"/>
 	<x-game v-else :init-game="g" :connection="connection"/>
 </div>
 </template>
diff --git a/src/server/web/app/common/views/components/othello.room.vue b/src/server/web/app/common/views/components/othello.room.vue
index 396541483..a32be6b74 100644
--- a/src/server/web/app/common/views/components/othello.room.vue
+++ b/src/server/web/app/common/views/components/othello.room.vue
@@ -41,9 +41,9 @@
 			<div slot="header">
 				<span>ルール</span>
 			</div>
-			<mk-switch v-model="game.settings.is_llotheo" @change="updateSettings" text="石の少ない方が勝ち(ロセオ)"/>
-			<mk-switch v-model="game.settings.looped_board" @change="updateSettings" text="ループマップ"/>
-			<mk-switch v-model="game.settings.can_put_everywhere" @change="updateSettings" text="どこでも置けるモード"/>
+			<mk-switch v-model="game.settings.isLlotheo" @change="updateSettings" text="石の少ない方が勝ち(ロセオ)"/>
+			<mk-switch v-model="game.settings.loopedBoard" @change="updateSettings" text="ループマップ"/>
+			<mk-switch v-model="game.settings.canPutEverywhere" @change="updateSettings" text="どこでも置けるモード"/>
 		</el-card>
 
 		<el-card class="bot-form" v-if="form">
@@ -116,13 +116,13 @@ export default Vue.extend({
 			return categories.filter((item, pos) => categories.indexOf(item) == pos);
 		},
 		isAccepted(): boolean {
-			if (this.game.user1_id == (this as any).os.i.id && this.game.user1_accepted) return true;
-			if (this.game.user2_id == (this as any).os.i.id && this.game.user2_accepted) return true;
+			if (this.game.user1Id == (this as any).os.i.id && this.game.user1Accepted) return true;
+			if (this.game.user2Id == (this as any).os.i.id && this.game.user2Accepted) return true;
 			return false;
 		},
 		isOpAccepted(): boolean {
-			if (this.game.user1_id != (this as any).os.i.id && this.game.user1_accepted) return true;
-			if (this.game.user2_id != (this as any).os.i.id && this.game.user2_accepted) return true;
+			if (this.game.user1Id != (this as any).os.i.id && this.game.user1Accepted) return true;
+			if (this.game.user2Id != (this as any).os.i.id && this.game.user2Accepted) return true;
 			return false;
 		}
 	},
@@ -133,8 +133,8 @@ export default Vue.extend({
 		this.connection.on('init-form', this.onInitForm);
 		this.connection.on('message', this.onMessage);
 
-		if (this.game.user1_id != (this as any).os.i.id && this.game.settings.form1) this.form = this.game.settings.form1;
-		if (this.game.user2_id != (this as any).os.i.id && this.game.settings.form2) this.form = this.game.settings.form2;
+		if (this.game.user1Id != (this as any).os.i.id && this.game.settings.form1) this.form = this.game.settings.form1;
+		if (this.game.user2Id != (this as any).os.i.id && this.game.settings.form2) this.form = this.game.settings.form2;
 	},
 
 	beforeDestroy() {
@@ -162,8 +162,8 @@ export default Vue.extend({
 		},
 
 		onChangeAccepts(accepts) {
-			this.game.user1_accepted = accepts.user1;
-			this.game.user2_accepted = accepts.user2;
+			this.game.user1Accepted = accepts.user1;
+			this.game.user2Accepted = accepts.user2;
 			this.$forceUpdate();
 		},
 
@@ -185,12 +185,12 @@ export default Vue.extend({
 		},
 
 		onInitForm(x) {
-			if (x.user_id == (this as any).os.i.id) return;
+			if (x.userId == (this as any).os.i.id) return;
 			this.form = x.form;
 		},
 
 		onMessage(x) {
-			if (x.user_id == (this as any).os.i.id) return;
+			if (x.userId == (this as any).os.i.id) return;
 			this.messages.unshift(x.message);
 		},
 
diff --git a/src/server/web/app/common/views/components/othello.vue b/src/server/web/app/common/views/components/othello.vue
index d65032234..8f7d9dfd6 100644
--- a/src/server/web/app/common/views/components/othello.vue
+++ b/src/server/web/app/common/views/components/othello.vue
@@ -31,28 +31,28 @@
 		<section v-if="invitations.length > 0">
 			<h2>対局の招待があります!:</h2>
 			<div class="invitation" v-for="i in invitations" tabindex="-1" @click="accept(i)">
-				<img :src="`${i.parent.avatar_url}?thumbnail&size=32`" alt="">
+				<img :src="`${i.parent.avatarUrl}?thumbnail&size=32`" alt="">
 				<span class="name"><b>{{ i.parent.name }}</b></span>
 				<span class="username">@{{ i.parent.username }}</span>
-				<mk-time :time="i.created_at"/>
+				<mk-time :time="i.createdAt"/>
 			</div>
 		</section>
 		<section v-if="myGames.length > 0">
 			<h2>自分の対局</h2>
 			<a class="game" v-for="g in myGames" tabindex="-1" @click.prevent="go(g)" :href="`/othello/${g.id}`">
-				<img :src="`${g.user1.avatar_url}?thumbnail&size=32`" alt="">
-				<img :src="`${g.user2.avatar_url}?thumbnail&size=32`" alt="">
+				<img :src="`${g.user1.avatarUrl}?thumbnail&size=32`" alt="">
+				<img :src="`${g.user2.avatarUrl}?thumbnail&size=32`" alt="">
 				<span><b>{{ g.user1.name }}</b> vs <b>{{ g.user2.name }}</b></span>
-				<span class="state">{{ g.is_ended ? '終了' : '進行中' }}</span>
+				<span class="state">{{ g.isEnded ? '終了' : '進行中' }}</span>
 			</a>
 		</section>
 		<section v-if="games.length > 0">
 			<h2>みんなの対局</h2>
 			<a class="game" v-for="g in games" tabindex="-1" @click.prevent="go(g)" :href="`/othello/${g.id}`">
-				<img :src="`${g.user1.avatar_url}?thumbnail&size=32`" alt="">
-				<img :src="`${g.user2.avatar_url}?thumbnail&size=32`" alt="">
+				<img :src="`${g.user1.avatarUrl}?thumbnail&size=32`" alt="">
+				<img :src="`${g.user2.avatarUrl}?thumbnail&size=32`" alt="">
 				<span><b>{{ g.user1.name }}</b> vs <b>{{ g.user2.name }}</b></span>
-				<span class="state">{{ g.is_ended ? '終了' : '進行中' }}</span>
+				<span class="state">{{ g.isEnded ? '終了' : '進行中' }}</span>
 			</a>
 		</section>
 	</div>
@@ -133,7 +133,7 @@ export default Vue.extend({
 	methods: {
 		go(game) {
 			(this as any).api('othello/games/show', {
-				game_id: game.id
+				gameId: game.id
 			}).then(game => {
 				this.matching = null;
 				this.game = game;
@@ -147,7 +147,7 @@ export default Vue.extend({
 					username
 				}).then(user => {
 					(this as any).api('othello/match', {
-						user_id: user.id
+						userId: user.id
 					}).then(res => {
 						if (res == null) {
 							this.matching = user;
@@ -164,7 +164,7 @@ export default Vue.extend({
 		},
 		accept(invitation) {
 			(this as any).api('othello/match', {
-				user_id: invitation.parent.id
+				userId: invitation.parent.id
 			}).then(game => {
 				if (game) {
 					this.matching = null;
diff --git a/src/server/web/app/common/views/components/poll.vue b/src/server/web/app/common/views/components/poll.vue
index 8156c8bc5..711d89720 100644
--- a/src/server/web/app/common/views/components/poll.vue
+++ b/src/server/web/app/common/views/components/poll.vue
@@ -4,7 +4,7 @@
 		<li v-for="choice in poll.choices" :key="choice.id" @click="vote(choice.id)" :class="{ voted: choice.voted }" :title="!isVoted ? '%i18n:common.tags.mk-poll.vote-to%'.replace('{}', choice.text) : ''">
 			<div class="backdrop" :style="{ 'width': (showResult ? (choice.votes / total * 100) : 0) + '%' }"></div>
 			<span>
-				<template v-if="choice.is_voted">%fa:check%</template>
+				<template v-if="choice.isVoted">%fa:check%</template>
 				<span>{{ choice.text }}</span>
 				<span class="votes" v-if="showResult">({{ '%i18n:common.tags.mk-poll.vote-count%'.replace('{}', choice.votes) }})</span>
 			</span>
@@ -36,7 +36,7 @@ export default Vue.extend({
 			return this.poll.choices.reduce((a, b) => a + b.votes, 0);
 		},
 		isVoted(): boolean {
-			return this.poll.choices.some(c => c.is_voted);
+			return this.poll.choices.some(c => c.isVoted);
 		}
 	},
 	created() {
@@ -47,15 +47,15 @@ export default Vue.extend({
 			this.showResult = !this.showResult;
 		},
 		vote(id) {
-			if (this.poll.choices.some(c => c.is_voted)) return;
+			if (this.poll.choices.some(c => c.isVoted)) return;
 			(this as any).api('posts/polls/vote', {
-				post_id: this.post.id,
+				postId: this.post.id,
 				choice: id
 			}).then(() => {
 				this.poll.choices.forEach(c => {
 					if (c.id == id) {
 						c.votes++;
-						Vue.set(c, 'is_voted', true);
+						Vue.set(c, 'isVoted', true);
 					}
 				});
 				this.showResult = true;
diff --git a/src/server/web/app/common/views/components/post-menu.vue b/src/server/web/app/common/views/components/post-menu.vue
index a53680e55..35116db7e 100644
--- a/src/server/web/app/common/views/components/post-menu.vue
+++ b/src/server/web/app/common/views/components/post-menu.vue
@@ -2,7 +2,7 @@
 <div class="mk-post-menu">
 	<div class="backdrop" ref="backdrop" @click="close"></div>
 	<div class="popover" :class="{ compact }" ref="popover">
-		<button v-if="post.user_id == os.i.id" @click="pin">%i18n:common.tags.mk-post-menu.pin%</button>
+		<button v-if="post.userId == os.i.id" @click="pin">%i18n:common.tags.mk-post-menu.pin%</button>
 	</div>
 </div>
 </template>
@@ -51,7 +51,7 @@ export default Vue.extend({
 	methods: {
 		pin() {
 			(this as any).api('i/pin', {
-				post_id: this.post.id
+				postId: this.post.id
 			}).then(() => {
 				this.$destroy();
 			});
diff --git a/src/server/web/app/common/views/components/reaction-picker.vue b/src/server/web/app/common/views/components/reaction-picker.vue
index df8100f2f..bcb6b2b96 100644
--- a/src/server/web/app/common/views/components/reaction-picker.vue
+++ b/src/server/web/app/common/views/components/reaction-picker.vue
@@ -69,7 +69,7 @@ export default Vue.extend({
 	methods: {
 		react(reaction) {
 			(this as any).api('posts/reactions/create', {
-				post_id: this.post.id,
+				postId: this.post.id,
 				reaction: reaction
 			}).then(() => {
 				if (this.cb) this.cb();
diff --git a/src/server/web/app/common/views/components/reactions-viewer.vue b/src/server/web/app/common/views/components/reactions-viewer.vue
index f6a27d913..246451008 100644
--- a/src/server/web/app/common/views/components/reactions-viewer.vue
+++ b/src/server/web/app/common/views/components/reactions-viewer.vue
@@ -20,7 +20,7 @@ export default Vue.extend({
 	props: ['post'],
 	computed: {
 		reactions(): number {
-			return this.post.reaction_counts;
+			return this.post.reactionCounts;
 		}
 	}
 });
diff --git a/src/server/web/app/common/views/components/signin.vue b/src/server/web/app/common/views/components/signin.vue
index 243468408..17154e6b3 100644
--- a/src/server/web/app/common/views/components/signin.vue
+++ b/src/server/web/app/common/views/components/signin.vue
@@ -1,12 +1,12 @@
 <template>
 <form class="mk-signin" :class="{ signing }" @submit.prevent="onSubmit">
 	<label class="user-name">
-		<input v-model="username" type="text" pattern="^[a-zA-Z0-9-]+$" placeholder="%i18n:common.tags.mk-signin.username%" autofocus required @change="onUsernameChange"/>%fa:at%
+		<input v-model="username" type="text" pattern="^[a-zA-Z0-9_]+$" placeholder="%i18n:common.tags.mk-signin.username%" autofocus required @change="onUsernameChange"/>%fa:at%
 	</label>
 	<label class="password">
 		<input v-model="password" type="password" placeholder="%i18n:common.tags.mk-signin.password%" required/>%fa:lock%
 	</label>
-	<label class="token" v-if="user && user.account.two_factor_enabled">
+	<label class="token" v-if="user && user.account.twoFactorEnabled">
 		<input v-model="token" type="number" placeholder="%i18n:common.tags.mk-signin.token%" required/>%fa:lock%
 	</label>
 	<button type="submit" :disabled="signing">{{ signing ? '%i18n:common.tags.mk-signin.signing-in%' : '%i18n:common.tags.mk-signin.signin%' }}</button>
@@ -43,7 +43,7 @@ export default Vue.extend({
 			(this as any).api('signin', {
 				username: this.username,
 				password: this.password,
-				token: this.user && this.user.account.two_factor_enabled ? this.token : undefined
+				token: this.user && this.user.account.twoFactorEnabled ? this.token : undefined
 			}).then(() => {
 				location.reload();
 			}).catch(() => {
diff --git a/src/server/web/app/common/views/components/signup.vue b/src/server/web/app/common/views/components/signup.vue
index c2e78aa8a..e77d849ad 100644
--- a/src/server/web/app/common/views/components/signup.vue
+++ b/src/server/web/app/common/views/components/signup.vue
@@ -2,7 +2,7 @@
 <form class="mk-signup" @submit.prevent="onSubmit" autocomplete="off">
 	<label class="username">
 		<p class="caption">%fa:at%%i18n:common.tags.mk-signup.username%</p>
-		<input v-model="username" type="text" pattern="^[a-zA-Z0-9-]{3,20}$" placeholder="a~z、A~Z、0~9、-" autocomplete="off" required @input="onChangeUsername"/>
+		<input v-model="username" type="text" pattern="^[a-zA-Z0-9_]{3,20}$" placeholder="a~z、A~Z、0~9、-" autocomplete="off" required @input="onChangeUsername"/>
 		<p class="profile-page-url-preview" v-if="shouldShowProfileUrl">{{ `${url}/@${username}` }}</p>
 		<p class="info" v-if="usernameState == 'wait'" style="color:#999">%fa:spinner .pulse .fw%%i18n:common.tags.mk-signup.checking%</p>
 		<p class="info" v-if="usernameState == 'ok'" style="color:#3CB7B5">%fa:check .fw%%i18n:common.tags.mk-signup.available%</p>
diff --git a/src/server/web/app/common/views/components/twitter-setting.vue b/src/server/web/app/common/views/components/twitter-setting.vue
index 15968d20a..082d2b435 100644
--- a/src/server/web/app/common/views/components/twitter-setting.vue
+++ b/src/server/web/app/common/views/components/twitter-setting.vue
@@ -1,13 +1,13 @@
 <template>
 <div class="mk-twitter-setting">
 	<p>%i18n:common.tags.mk-twitter-setting.description%<a :href="`${docsUrl}/link-to-twitter`" target="_blank">%i18n:common.tags.mk-twitter-setting.detail%</a></p>
-	<p class="account" v-if="os.i.account.twitter" :title="`Twitter ID: ${os.i.account.twitter.user_id}`">%i18n:common.tags.mk-twitter-setting.connected-to%: <a :href="`https://twitter.com/${os.i.account.twitter.screen_name}`" target="_blank">@{{ os.i.account.twitter.screen_name }}</a></p>
+	<p class="account" v-if="os.i.account.twitter" :title="`Twitter ID: ${os.i.account.twitter.userId}`">%i18n:common.tags.mk-twitter-setting.connected-to%: <a :href="`https://twitter.com/${os.i.account.twitter.screenName}`" target="_blank">@{{ os.i.account.twitter.screenName }}</a></p>
 	<p>
 		<a :href="`${apiUrl}/connect/twitter`" target="_blank" @click.prevent="connect">{{ os.i.account.twitter ? '%i18n:common.tags.mk-twitter-setting.reconnect%' : '%i18n:common.tags.mk-twitter-setting.connect%' }}</a>
 		<span v-if="os.i.account.twitter"> or </span>
 		<a :href="`${apiUrl}/disconnect/twitter`" target="_blank" v-if="os.i.account.twitter" @click.prevent="disconnect">%i18n:common.tags.mk-twitter-setting.disconnect%</a>
 	</p>
-	<p class="id" v-if="os.i.account.twitter">Twitter ID: {{ os.i.account.twitter.user_id }}</p>
+	<p class="id" v-if="os.i.account.twitter">Twitter ID: {{ os.i.account.twitter.userId }}</p>
 </div>
 </template>
 
diff --git a/src/server/web/app/common/views/components/uploader.vue b/src/server/web/app/common/views/components/uploader.vue
index 73006b16e..c74a1edb4 100644
--- a/src/server/web/app/common/views/components/uploader.vue
+++ b/src/server/web/app/common/views/components/uploader.vue
@@ -53,7 +53,7 @@ export default Vue.extend({
 			data.append('i', (this as any).os.i.account.token);
 			data.append('file', file);
 
-			if (folder) data.append('folder_id', folder);
+			if (folder) data.append('folderId', folder);
 
 			const xhr = new XMLHttpRequest();
 			xhr.open('POST', apiUrl + '/drive/files/create', true);
diff --git a/src/server/web/app/common/views/components/welcome-timeline.vue b/src/server/web/app/common/views/components/welcome-timeline.vue
index 7586e9264..8f6199732 100644
--- a/src/server/web/app/common/views/components/welcome-timeline.vue
+++ b/src/server/web/app/common/views/components/welcome-timeline.vue
@@ -2,7 +2,7 @@
 <div class="mk-welcome-timeline">
 	<div v-for="post in posts">
 		<router-link class="avatar-anchor" :to="`/@${getAcct(post.user)}`" v-user-preview="post.user.id">
-			<img class="avatar" :src="`${post.user.avatar_url}?thumbnail&size=96`" alt="avatar"/>
+			<img class="avatar" :src="`${post.user.avatarUrl}?thumbnail&size=96`" alt="avatar"/>
 		</router-link>
 		<div class="body">
 			<header>
@@ -10,7 +10,7 @@
 				<span class="username">@{{ getAcct(post.user) }}</span>
 				<div class="info">
 					<router-link class="created-at" :to="`/@${getAcct(post.user)}/${post.id}`">
-						<mk-time :time="post.created_at"/>
+						<mk-time :time="post.createdAt"/>
 					</router-link>
 				</div>
 			</header>
diff --git a/src/server/web/app/common/views/directives/autocomplete.ts b/src/server/web/app/common/views/directives/autocomplete.ts
index 3440c4212..94635d301 100644
--- a/src/server/web/app/common/views/directives/autocomplete.ts
+++ b/src/server/web/app/common/views/directives/autocomplete.ts
@@ -77,7 +77,7 @@ class Autocomplete {
 
 		if (mentionIndex != -1 && mentionIndex > emojiIndex) {
 			const username = text.substr(mentionIndex + 1);
-			if (username != '' && username.match(/^[a-zA-Z0-9-]+$/)) {
+			if (username != '' && username.match(/^[a-zA-Z0-9_]+$/)) {
 				this.open('user', username);
 				opened = true;
 			}
diff --git a/src/server/web/app/common/views/widgets/slideshow.vue b/src/server/web/app/common/views/widgets/slideshow.vue
index e9451663e..ad32299f3 100644
--- a/src/server/web/app/common/views/widgets/slideshow.vue
+++ b/src/server/web/app/common/views/widgets/slideshow.vue
@@ -97,7 +97,7 @@ export default define({
 			this.fetching = true;
 
 			(this as any).api('drive/files', {
-				folder_id: this.props.folder,
+				folderId: this.props.folder,
 				type: 'image/*',
 				limit: 100
 			}).then(images => {
diff --git a/src/server/web/app/common/views/widgets/version.vue b/src/server/web/app/common/views/widgets/version.vue
index 5072d9b74..30b632b39 100644
--- a/src/server/web/app/common/views/widgets/version.vue
+++ b/src/server/web/app/common/views/widgets/version.vue
@@ -1,16 +1,17 @@
 <template>
-<p>ver {{ v }} (葵 aoi)</p>
+<p>ver {{ version }} ({{ codename }})</p>
 </template>
 
 <script lang="ts">
-import { version } from '../../../config';
+import { version, codename } from '../../../config';
 import define from '../../../common/define-widget';
 export default define({
 	name: 'version'
 }).extend({
 	data() {
 		return {
-			v: version
+			version,
+			codename
 		};
 	}
 });
diff --git a/src/server/web/app/config.ts b/src/server/web/app/config.ts
index 8ea6f7010..522d7ff05 100644
--- a/src/server/web/app/config.ts
+++ b/src/server/web/app/config.ts
@@ -7,13 +7,13 @@ declare const _DOCS_URL_: string;
 declare const _STATS_URL_: string;
 declare const _STATUS_URL_: string;
 declare const _DEV_URL_: string;
-declare const _CH_URL_: string;
 declare const _LANG_: string;
 declare const _RECAPTCHA_SITEKEY_: string;
 declare const _SW_PUBLICKEY_: string;
 declare const _THEME_COLOR_: string;
 declare const _COPYRIGHT_: string;
 declare const _VERSION_: string;
+declare const _CODENAME_: string;
 declare const _LICENSE_: string;
 declare const _GOOGLE_MAPS_API_KEY_: string;
 
@@ -26,12 +26,12 @@ export const docsUrl = _DOCS_URL_;
 export const statsUrl = _STATS_URL_;
 export const statusUrl = _STATUS_URL_;
 export const devUrl = _DEV_URL_;
-export const chUrl = _CH_URL_;
 export const lang = _LANG_;
 export const recaptchaSitekey = _RECAPTCHA_SITEKEY_;
 export const swPublickey = _SW_PUBLICKEY_;
 export const themeColor = _THEME_COLOR_;
 export const copyright = _COPYRIGHT_;
 export const version = _VERSION_;
+export const codename = _CODENAME_;
 export const license = _LICENSE_;
 export const googleMapsApiKey = _GOOGLE_MAPS_API_KEY_;
diff --git a/src/server/web/app/desktop/api/update-avatar.ts b/src/server/web/app/desktop/api/update-avatar.ts
index 8f748d853..36a2ffe91 100644
--- a/src/server/web/app/desktop/api/update-avatar.ts
+++ b/src/server/web/app/desktop/api/update-avatar.ts
@@ -49,7 +49,7 @@ export default (os: OS) => (cb, file = null) => {
 		}).$mount();
 		document.body.appendChild(dialog.$el);
 
-		if (folder) data.append('folder_id', folder.id);
+		if (folder) data.append('folderId', folder.id);
 
 		const xhr = new XMLHttpRequest();
 		xhr.open('POST', apiUrl + '/drive/files/create', true);
@@ -68,10 +68,10 @@ export default (os: OS) => (cb, file = null) => {
 
 	const set = file => {
 		os.api('i/update', {
-			avatar_id: file.id
+			avatarId: file.id
 		}).then(i => {
-			os.i.avatar_id = i.avatar_id;
-			os.i.avatar_url = i.avatar_url;
+			os.i.avatarId = i.avatarId;
+			os.i.avatarUrl = i.avatarUrl;
 
 			os.apis.dialog({
 				title: '%fa:info-circle%アバターを更新しました',
diff --git a/src/server/web/app/desktop/api/update-banner.ts b/src/server/web/app/desktop/api/update-banner.ts
index 9ed48b267..e66dbf016 100644
--- a/src/server/web/app/desktop/api/update-banner.ts
+++ b/src/server/web/app/desktop/api/update-banner.ts
@@ -49,7 +49,7 @@ export default (os: OS) => (cb, file = null) => {
 		}).$mount();
 		document.body.appendChild(dialog.$el);
 
-		if (folder) data.append('folder_id', folder.id);
+		if (folder) data.append('folderId', folder.id);
 
 		const xhr = new XMLHttpRequest();
 		xhr.open('POST', apiUrl + '/drive/files/create', true);
@@ -68,10 +68,10 @@ export default (os: OS) => (cb, file = null) => {
 
 	const set = file => {
 		os.api('i/update', {
-			banner_id: file.id
+			bannerId: file.id
 		}).then(i => {
-			os.i.banner_id = i.banner_id;
-			os.i.banner_url = i.banner_url;
+			os.i.bannerId = i.bannerId;
+			os.i.bannerUrl = i.bannerUrl;
 
 			os.apis.dialog({
 				title: '%fa:info-circle%バナーを更新しました',
diff --git a/src/server/web/app/desktop/views/components/activity.vue b/src/server/web/app/desktop/views/components/activity.vue
index 33b53eb70..480b956ec 100644
--- a/src/server/web/app/desktop/views/components/activity.vue
+++ b/src/server/web/app/desktop/views/components/activity.vue
@@ -43,7 +43,7 @@ export default Vue.extend({
 	},
 	mounted() {
 		(this as any).api('aggregation/users/activity', {
-			user_id: this.user.id,
+			userId: this.user.id,
 			limit: 20 * 7
 		}).then(activity => {
 			this.activity = activity;
diff --git a/src/server/web/app/desktop/views/components/drive.file.vue b/src/server/web/app/desktop/views/components/drive.file.vue
index 924ff7052..85f8361c9 100644
--- a/src/server/web/app/desktop/views/components/drive.file.vue
+++ b/src/server/web/app/desktop/views/components/drive.file.vue
@@ -9,10 +9,10 @@
 	@contextmenu.prevent.stop="onContextmenu"
 	:title="title"
 >
-	<div class="label" v-if="os.i.avatar_id == file.id"><img src="/assets/label.svg"/>
+	<div class="label" v-if="os.i.avatarId == file.id"><img src="/assets/label.svg"/>
 		<p>%i18n:desktop.tags.mk-drive-browser-file.avatar%</p>
 	</div>
-	<div class="label" v-if="os.i.banner_id == file.id"><img src="/assets/label.svg"/>
+	<div class="label" v-if="os.i.bannerId == file.id"><img src="/assets/label.svg"/>
 		<p>%i18n:desktop.tags.mk-drive-browser-file.banner%</p>
 	</div>
 	<div class="thumbnail" ref="thumbnail" :style="`background-color: ${ background }`">
@@ -50,8 +50,8 @@ export default Vue.extend({
 			return `${this.file.name}\n${this.file.type} ${Vue.filter('bytes')(this.file.datasize)}`;
 		},
 		background(): string {
-			return this.file.properties.average_color
-				? `rgb(${this.file.properties.average_color.join(',')})`
+			return this.file.properties.avgColor
+				? `rgb(${this.file.properties.avgColor.join(',')})`
 				: 'transparent';
 		}
 	},
@@ -129,10 +129,10 @@ export default Vue.extend({
 		},
 
 		onThumbnailLoaded() {
-			if (this.file.properties.average_color) {
+			if (this.file.properties.avgColor) {
 				anime({
 					targets: this.$refs.thumbnail,
-					backgroundColor: `rgba(${this.file.properties.average_color.join(',')}, 0)`,
+					backgroundColor: `rgba(${this.file.properties.avgColor.join(',')}, 0)`,
 					duration: 100,
 					easing: 'linear'
 				});
@@ -147,7 +147,7 @@ export default Vue.extend({
 				allowEmpty: false
 			}).then(name => {
 				(this as any).api('drive/files/update', {
-					file_id: this.file.id,
+					fileId: this.file.id,
 					name: name
 				})
 			});
diff --git a/src/server/web/app/desktop/views/components/drive.folder.vue b/src/server/web/app/desktop/views/components/drive.folder.vue
index a8a9a0137..a926bf47b 100644
--- a/src/server/web/app/desktop/views/components/drive.folder.vue
+++ b/src/server/web/app/desktop/views/components/drive.folder.vue
@@ -135,8 +135,8 @@ export default Vue.extend({
 				const file = JSON.parse(driveFile);
 				this.browser.removeFile(file.id);
 				(this as any).api('drive/files/update', {
-					file_id: file.id,
-					folder_id: this.folder.id
+					fileId: file.id,
+					folderId: this.folder.id
 				});
 			}
 			//#endregion
@@ -151,8 +151,8 @@ export default Vue.extend({
 
 				this.browser.removeFolder(folder.id);
 				(this as any).api('drive/folders/update', {
-					folder_id: folder.id,
-					parent_id: this.folder.id
+					folderId: folder.id,
+					parentId: this.folder.id
 				}).then(() => {
 					// noop
 				}).catch(err => {
@@ -204,7 +204,7 @@ export default Vue.extend({
 				default: this.folder.name
 			}).then(name => {
 				(this as any).api('drive/folders/update', {
-					folder_id: this.folder.id,
+					folderId: this.folder.id,
 					name: name
 				});
 			});
diff --git a/src/server/web/app/desktop/views/components/drive.nav-folder.vue b/src/server/web/app/desktop/views/components/drive.nav-folder.vue
index dfbf116bf..d885a72f7 100644
--- a/src/server/web/app/desktop/views/components/drive.nav-folder.vue
+++ b/src/server/web/app/desktop/views/components/drive.nav-folder.vue
@@ -78,8 +78,8 @@ export default Vue.extend({
 				const file = JSON.parse(driveFile);
 				this.browser.removeFile(file.id);
 				(this as any).api('drive/files/update', {
-					file_id: file.id,
-					folder_id: this.folder ? this.folder.id : null
+					fileId: file.id,
+					folderId: this.folder ? this.folder.id : null
 				});
 			}
 			//#endregion
@@ -92,8 +92,8 @@ export default Vue.extend({
 				if (this.folder && folder.id == this.folder.id) return;
 				this.browser.removeFolder(folder.id);
 				(this as any).api('drive/folders/update', {
-					folder_id: folder.id,
-					parent_id: this.folder ? this.folder.id : null
+					folderId: folder.id,
+					parentId: this.folder ? this.folder.id : null
 				});
 			}
 			//#endregion
diff --git a/src/server/web/app/desktop/views/components/drive.vue b/src/server/web/app/desktop/views/components/drive.vue
index 0fafa8cf2..c766dfec1 100644
--- a/src/server/web/app/desktop/views/components/drive.vue
+++ b/src/server/web/app/desktop/views/components/drive.vue
@@ -160,7 +160,7 @@ export default Vue.extend({
 
 		onStreamDriveFileUpdated(file) {
 			const current = this.folder ? this.folder.id : null;
-			if (current != file.folder_id) {
+			if (current != file.folderId) {
 				this.removeFile(file);
 			} else {
 				this.addFile(file, true);
@@ -173,7 +173,7 @@ export default Vue.extend({
 
 		onStreamDriveFolderUpdated(folder) {
 			const current = this.folder ? this.folder.id : null;
-			if (current != folder.parent_id) {
+			if (current != folder.parentId) {
 				this.removeFolder(folder);
 			} else {
 				this.addFolder(folder, true);
@@ -282,8 +282,8 @@ export default Vue.extend({
 				if (this.files.some(f => f.id == file.id)) return;
 				this.removeFile(file.id);
 				(this as any).api('drive/files/update', {
-					file_id: file.id,
-					folder_id: this.folder ? this.folder.id : null
+					fileId: file.id,
+					folderId: this.folder ? this.folder.id : null
 				});
 			}
 			//#endregion
@@ -298,8 +298,8 @@ export default Vue.extend({
 				if (this.folders.some(f => f.id == folder.id)) return false;
 				this.removeFolder(folder.id);
 				(this as any).api('drive/folders/update', {
-					folder_id: folder.id,
-					parent_id: this.folder ? this.folder.id : null
+					folderId: folder.id,
+					parentId: this.folder ? this.folder.id : null
 				}).then(() => {
 					// noop
 				}).catch(err => {
@@ -332,7 +332,7 @@ export default Vue.extend({
 			}).then(url => {
 				(this as any).api('drive/files/upload_from_url', {
 					url: url,
-					folder_id: this.folder ? this.folder.id : undefined
+					folderId: this.folder ? this.folder.id : undefined
 				});
 
 				(this as any).apis.dialog({
@@ -352,7 +352,7 @@ export default Vue.extend({
 			}).then(name => {
 				(this as any).api('drive/folders/create', {
 					name: name,
-					folder_id: this.folder ? this.folder.id : undefined
+					folderId: this.folder ? this.folder.id : undefined
 				}).then(folder => {
 					this.addFolder(folder, true);
 				});
@@ -412,7 +412,7 @@ export default Vue.extend({
 			this.fetching = true;
 
 			(this as any).api('drive/folders/show', {
-				folder_id: target
+				folderId: target
 			}).then(folder => {
 				this.folder = folder;
 				this.hierarchyFolders = [];
@@ -431,7 +431,7 @@ export default Vue.extend({
 
 		addFolder(folder, unshift = false) {
 			const current = this.folder ? this.folder.id : null;
-			if (current != folder.parent_id) return;
+			if (current != folder.parentId) return;
 
 			if (this.folders.some(f => f.id == folder.id)) {
 				const exist = this.folders.map(f => f.id).indexOf(folder.id);
@@ -448,7 +448,7 @@ export default Vue.extend({
 
 		addFile(file, unshift = false) {
 			const current = this.folder ? this.folder.id : null;
-			if (current != file.folder_id) return;
+			if (current != file.folderId) return;
 
 			if (this.files.some(f => f.id == file.id)) {
 				const exist = this.files.map(f => f.id).indexOf(file.id);
@@ -514,7 +514,7 @@ export default Vue.extend({
 
 			// フォルダ一覧取得
 			(this as any).api('drive/folders', {
-				folder_id: this.folder ? this.folder.id : null,
+				folderId: this.folder ? this.folder.id : null,
 				limit: foldersMax + 1
 			}).then(folders => {
 				if (folders.length == foldersMax + 1) {
@@ -527,7 +527,7 @@ export default Vue.extend({
 
 			// ファイル一覧取得
 			(this as any).api('drive/files', {
-				folder_id: this.folder ? this.folder.id : null,
+				folderId: this.folder ? this.folder.id : null,
 				limit: filesMax + 1
 			}).then(files => {
 				if (files.length == filesMax + 1) {
@@ -557,7 +557,7 @@ export default Vue.extend({
 
 			// ファイル一覧取得
 			(this as any).api('drive/files', {
-				folder_id: this.folder ? this.folder.id : null,
+				folderId: this.folder ? this.folder.id : null,
 				limit: max + 1
 			}).then(files => {
 				if (files.length == max + 1) {
diff --git a/src/server/web/app/desktop/views/components/follow-button.vue b/src/server/web/app/desktop/views/components/follow-button.vue
index fc4f87188..9eb22b0fb 100644
--- a/src/server/web/app/desktop/views/components/follow-button.vue
+++ b/src/server/web/app/desktop/views/components/follow-button.vue
@@ -1,15 +1,15 @@
 <template>
 <button class="mk-follow-button"
-	:class="{ wait, follow: !user.is_following, unfollow: user.is_following, big: size == 'big' }"
+	:class="{ wait, follow: !user.isFollowing, unfollow: user.isFollowing, big: size == 'big' }"
 	@click="onClick"
 	:disabled="wait"
-	:title="user.is_following ? 'フォロー解除' : 'フォローする'"
+	:title="user.isFollowing ? 'フォロー解除' : 'フォローする'"
 >
-	<template v-if="!wait && user.is_following">
+	<template v-if="!wait && user.isFollowing">
 		<template v-if="size == 'compact'">%fa:minus%</template>
 		<template v-if="size == 'big'">%fa:minus%フォロー解除</template>
 	</template>
-	<template v-if="!wait && !user.is_following">
+	<template v-if="!wait && !user.isFollowing">
 		<template v-if="size == 'compact'">%fa:plus%</template>
 		<template v-if="size == 'big'">%fa:plus%フォロー</template>
 	</template>
@@ -53,23 +53,23 @@ export default Vue.extend({
 
 		onFollow(user) {
 			if (user.id == this.user.id) {
-				this.user.is_following = user.is_following;
+				this.user.isFollowing = user.isFollowing;
 			}
 		},
 
 		onUnfollow(user) {
 			if (user.id == this.user.id) {
-				this.user.is_following = user.is_following;
+				this.user.isFollowing = user.isFollowing;
 			}
 		},
 
 		onClick() {
 			this.wait = true;
-			if (this.user.is_following) {
+			if (this.user.isFollowing) {
 				(this as any).api('following/delete', {
-					user_id: this.user.id
+					userId: this.user.id
 				}).then(() => {
-					this.user.is_following = false;
+					this.user.isFollowing = false;
 				}).catch(err => {
 					console.error(err);
 				}).then(() => {
@@ -77,9 +77,9 @@ export default Vue.extend({
 				});
 			} else {
 				(this as any).api('following/create', {
-					user_id: this.user.id
+					userId: this.user.id
 				}).then(() => {
-					this.user.is_following = true;
+					this.user.isFollowing = true;
 				}).catch(err => {
 					console.error(err);
 				}).then(() => {
diff --git a/src/server/web/app/desktop/views/components/followers-window.vue b/src/server/web/app/desktop/views/components/followers-window.vue
index d41d356f9..623971fa3 100644
--- a/src/server/web/app/desktop/views/components/followers-window.vue
+++ b/src/server/web/app/desktop/views/components/followers-window.vue
@@ -1,7 +1,7 @@
 <template>
 <mk-window width="400px" height="550px" @closed="$destroy">
 	<span slot="header" :class="$style.header">
-		<img :src="`${user.avatar_url}?thumbnail&size=64`" alt=""/>{{ user.name }}のフォロワー
+		<img :src="`${user.avatarUrl}?thumbnail&size=64`" alt=""/>{{ user.name }}のフォロワー
 	</span>
 	<mk-followers :user="user"/>
 </mk-window>
diff --git a/src/server/web/app/desktop/views/components/followers.vue b/src/server/web/app/desktop/views/components/followers.vue
index 4541a0007..a1b98995d 100644
--- a/src/server/web/app/desktop/views/components/followers.vue
+++ b/src/server/web/app/desktop/views/components/followers.vue
@@ -1,8 +1,8 @@
 <template>
 <mk-users-list
 	:fetch="fetch"
-	:count="user.followers_count"
-	:you-know-count="user.followers_you_know_count"
+	:count="user.followersCount"
+	:you-know-count="user.followersYouKnowCount"
 >
 	フォロワーはいないようです。
 </mk-users-list>
@@ -15,7 +15,7 @@ export default Vue.extend({
 	methods: {
 		fetch(iknow, limit, cursor, cb) {
 			(this as any).api('users/followers', {
-				user_id: this.user.id,
+				userId: this.user.id,
 				iknow: iknow,
 				limit: limit,
 				cursor: cursor ? cursor : undefined
diff --git a/src/server/web/app/desktop/views/components/following-window.vue b/src/server/web/app/desktop/views/components/following-window.vue
index c516b3b17..612847b38 100644
--- a/src/server/web/app/desktop/views/components/following-window.vue
+++ b/src/server/web/app/desktop/views/components/following-window.vue
@@ -1,7 +1,7 @@
 <template>
 <mk-window width="400px" height="550px" @closed="$destroy">
 	<span slot="header" :class="$style.header">
-		<img :src="`${user.avatar_url}?thumbnail&size=64`" alt=""/>{{ user.name }}のフォロー
+		<img :src="`${user.avatarUrl}?thumbnail&size=64`" alt=""/>{{ user.name }}のフォロー
 	</span>
 	<mk-following :user="user"/>
 </mk-window>
diff --git a/src/server/web/app/desktop/views/components/following.vue b/src/server/web/app/desktop/views/components/following.vue
index e0b9f1169..b7aedda84 100644
--- a/src/server/web/app/desktop/views/components/following.vue
+++ b/src/server/web/app/desktop/views/components/following.vue
@@ -1,8 +1,8 @@
 <template>
 <mk-users-list
 	:fetch="fetch"
-	:count="user.following_count"
-	:you-know-count="user.following_you_know_count"
+	:count="user.followingCount"
+	:you-know-count="user.followingYouKnowCount"
 >
 	フォロー中のユーザーはいないようです。
 </mk-users-list>
@@ -15,7 +15,7 @@ export default Vue.extend({
 	methods: {
 		fetch(iknow, limit, cursor, cb) {
 			(this as any).api('users/following', {
-				user_id: this.user.id,
+				userId: this.user.id,
 				iknow: iknow,
 				limit: limit,
 				cursor: cursor ? cursor : undefined
diff --git a/src/server/web/app/desktop/views/components/friends-maker.vue b/src/server/web/app/desktop/views/components/friends-maker.vue
index eed15e077..fd9914b15 100644
--- a/src/server/web/app/desktop/views/components/friends-maker.vue
+++ b/src/server/web/app/desktop/views/components/friends-maker.vue
@@ -4,7 +4,7 @@
 	<div class="users" v-if="!fetching && users.length > 0">
 		<div class="user" v-for="user in users" :key="user.id">
 			<router-link class="avatar-anchor" :to="`/@${getAcct(user)}`">
-				<img class="avatar" :src="`${user.avatar_url}?thumbnail&size=42`" alt="" v-user-preview="user.id"/>
+				<img class="avatar" :src="`${user.avatarUrl}?thumbnail&size=42`" alt="" v-user-preview="user.id"/>
 			</router-link>
 			<div class="body">
 				<router-link class="name" :to="`/@${getAcct(user)}`" v-user-preview="user.id">{{ user.name }}</router-link>
diff --git a/src/server/web/app/desktop/views/components/home.vue b/src/server/web/app/desktop/views/components/home.vue
index a4ce1ef94..7145ddce0 100644
--- a/src/server/web/app/desktop/views/components/home.vue
+++ b/src/server/web/app/desktop/views/components/home.vue
@@ -53,7 +53,7 @@
 			<div class="main">
 				<a @click="hint">カスタマイズのヒント</a>
 				<div>
-					<mk-post-form v-if="os.i.account.client_settings.showPostFormOnTopOfTl"/>
+					<mk-post-form v-if="os.i.account.clientSettings.showPostFormOnTopOfTl"/>
 					<mk-timeline ref="tl" @loaded="onTlLoaded"/>
 				</div>
 			</div>
@@ -63,7 +63,7 @@
 				<component v-for="widget in widgets[place]" :is="`mkw-${widget.name}`" :key="widget.id" :ref="widget.id" :widget="widget" @chosen="warp"/>
 			</div>
 			<div class="main">
-				<mk-post-form v-if="os.i.account.client_settings.showPostFormOnTopOfTl"/>
+				<mk-post-form v-if="os.i.account.clientSettings.showPostFormOnTopOfTl"/>
 				<mk-timeline ref="tl" @loaded="onTlLoaded" v-if="mode == 'timeline'"/>
 				<mk-mentions @loaded="onTlLoaded" v-if="mode == 'mentions'"/>
 			</div>
@@ -104,16 +104,16 @@ export default Vue.extend({
 		home: {
 			get(): any[] {
 				//#region 互換性のため
-				(this as any).os.i.account.client_settings.home.forEach(w => {
+				(this as any).os.i.account.clientSettings.home.forEach(w => {
 					if (w.name == 'rss-reader') w.name = 'rss';
 					if (w.name == 'user-recommendation') w.name = 'users';
 					if (w.name == 'recommended-polls') w.name = 'polls';
 				});
 				//#endregion
-				return (this as any).os.i.account.client_settings.home;
+				return (this as any).os.i.account.clientSettings.home;
 			},
 			set(value) {
-				(this as any).os.i.account.client_settings.home = value;
+				(this as any).os.i.account.clientSettings.home = value;
 			}
 		},
 		left(): any[] {
@@ -126,7 +126,7 @@ export default Vue.extend({
 	created() {
 		this.widgets.left = this.left;
 		this.widgets.right = this.right;
-		this.$watch('os.i.account.client_settings', i => {
+		this.$watch('os.i.account.clientSettings', i => {
 			this.widgets.left = this.left;
 			this.widgets.right = this.right;
 		}, {
@@ -161,17 +161,17 @@ export default Vue.extend({
 		},
 		onHomeUpdated(data) {
 			if (data.home) {
-				(this as any).os.i.account.client_settings.home = data.home;
+				(this as any).os.i.account.clientSettings.home = data.home;
 				this.widgets.left = data.home.filter(w => w.place == 'left');
 				this.widgets.right = data.home.filter(w => w.place == 'right');
 			} else {
-				const w = (this as any).os.i.account.client_settings.home.find(w => w.id == data.id);
+				const w = (this as any).os.i.account.clientSettings.home.find(w => w.id == data.id);
 				if (w != null) {
 					w.data = data.data;
 					this.$refs[w.id][0].preventSave = true;
 					this.$refs[w.id][0].props = w.data;
-					this.widgets.left = (this as any).os.i.account.client_settings.home.filter(w => w.place == 'left');
-					this.widgets.right = (this as any).os.i.account.client_settings.home.filter(w => w.place == 'right');
+					this.widgets.left = (this as any).os.i.account.clientSettings.home.filter(w => w.place == 'left');
+					this.widgets.right = (this as any).os.i.account.clientSettings.home.filter(w => w.place == 'right');
 				}
 			}
 		},
diff --git a/src/server/web/app/desktop/views/components/media-image.vue b/src/server/web/app/desktop/views/components/media-image.vue
index bc02d0f9b..51309a057 100644
--- a/src/server/web/app/desktop/views/components/media-image.vue
+++ b/src/server/web/app/desktop/views/components/media-image.vue
@@ -18,7 +18,7 @@ export default Vue.extend({
 	computed: {
 		style(): any {
 			return {
-				'background-color': this.image.properties.average_color ? `rgb(${this.image.properties.average_color.join(',')})` : 'transparent',
+				'background-color': this.image.properties.avgColor ? `rgb(${this.image.properties.avgColor.join(',')})` : 'transparent',
 				'background-image': `url(${this.image.url}?thumbnail&size=512)`
 			};
 		}
diff --git a/src/server/web/app/desktop/views/components/mentions.vue b/src/server/web/app/desktop/views/components/mentions.vue
index 47066e813..90a92495b 100644
--- a/src/server/web/app/desktop/views/components/mentions.vue
+++ b/src/server/web/app/desktop/views/components/mentions.vue
@@ -70,7 +70,7 @@ export default Vue.extend({
 			this.moreFetching = true;
 			(this as any).api('posts/mentions', {
 				following: this.mode == 'following',
-				until_id: this.posts[this.posts.length - 1].id
+				untilId: this.posts[this.posts.length - 1].id
 			}).then(posts => {
 				this.posts = this.posts.concat(posts);
 				this.moreFetching = false;
diff --git a/src/server/web/app/desktop/views/components/notifications.vue b/src/server/web/app/desktop/views/components/notifications.vue
index b48ffc174..5e6db08c1 100644
--- a/src/server/web/app/desktop/views/components/notifications.vue
+++ b/src/server/web/app/desktop/views/components/notifications.vue
@@ -3,10 +3,10 @@
 	<div class="notifications" v-if="notifications.length != 0">
 		<template v-for="(notification, i) in _notifications">
 			<div class="notification" :class="notification.type" :key="notification.id">
-				<mk-time :time="notification.created_at"/>
+				<mk-time :time="notification.createdAt"/>
 				<template v-if="notification.type == 'reaction'">
 					<router-link class="avatar-anchor" :to="`/@${getAcct(notification.user)}`" v-user-preview="notification.user.id">
-						<img class="avatar" :src="`${notification.user.avatar_url}?thumbnail&size=48`" alt="avatar"/>
+						<img class="avatar" :src="`${notification.user.avatarUrl}?thumbnail&size=48`" alt="avatar"/>
 					</router-link>
 					<div class="text">
 						<p>
@@ -19,12 +19,12 @@
 					</div>
 				</template>
 				<template v-if="notification.type == 'repost'">
-					<router-link class="avatar-anchor" :to="`/@${getAcct(notification.post.user)}`" v-user-preview="notification.post.user_id">
-						<img class="avatar" :src="`${notification.post.user.avatar_url}?thumbnail&size=48`" alt="avatar"/>
+					<router-link class="avatar-anchor" :to="`/@${getAcct(notification.post.user)}`" v-user-preview="notification.post.userId">
+						<img class="avatar" :src="`${notification.post.user.avatarUrl}?thumbnail&size=48`" alt="avatar"/>
 					</router-link>
 					<div class="text">
 						<p>%fa:retweet%
-							<router-link :to="`/@${getAcct(notification.post.user)}`" v-user-preview="notification.post.user_id">{{ notification.post.user.name }}</router-link>
+							<router-link :to="`/@${getAcct(notification.post.user)}`" v-user-preview="notification.post.userId">{{ notification.post.user.name }}</router-link>
 						</p>
 						<router-link class="post-ref" :to="`/@${getAcct(notification.post.user)}/${notification.post.id}`">
 							%fa:quote-left%{{ getPostSummary(notification.post.repost) }}%fa:quote-right%
@@ -32,19 +32,19 @@
 					</div>
 				</template>
 				<template v-if="notification.type == 'quote'">
-					<router-link class="avatar-anchor" :to="`/@${getAcct(notification.post.user)}`" v-user-preview="notification.post.user_id">
-						<img class="avatar" :src="`${notification.post.user.avatar_url}?thumbnail&size=48`" alt="avatar"/>
+					<router-link class="avatar-anchor" :to="`/@${getAcct(notification.post.user)}`" v-user-preview="notification.post.userId">
+						<img class="avatar" :src="`${notification.post.user.avatarUrl}?thumbnail&size=48`" alt="avatar"/>
 					</router-link>
 					<div class="text">
 						<p>%fa:quote-left%
-							<router-link :to="`/@${getAcct(notification.post.user)}`" v-user-preview="notification.post.user_id">{{ notification.post.user.name }}</router-link>
+							<router-link :to="`/@${getAcct(notification.post.user)}`" v-user-preview="notification.post.userId">{{ notification.post.user.name }}</router-link>
 						</p>
 						<router-link class="post-preview" :to="`/@${getAcct(notification.post.user)}/${notification.post.id}`">{{ getPostSummary(notification.post) }}</router-link>
 					</div>
 				</template>
 				<template v-if="notification.type == 'follow'">
 					<router-link class="avatar-anchor" :to="`/@${getAcct(notification.user)}`" v-user-preview="notification.user.id">
-						<img class="avatar" :src="`${notification.user.avatar_url}?thumbnail&size=48`" alt="avatar"/>
+						<img class="avatar" :src="`${notification.user.avatarUrl}?thumbnail&size=48`" alt="avatar"/>
 					</router-link>
 					<div class="text">
 						<p>%fa:user-plus%
@@ -53,30 +53,30 @@
 					</div>
 				</template>
 				<template v-if="notification.type == 'reply'">
-					<router-link class="avatar-anchor" :to="`/@${getAcct(notification.post.user)}`" v-user-preview="notification.post.user_id">
-						<img class="avatar" :src="`${notification.post.user.avatar_url}?thumbnail&size=48`" alt="avatar"/>
+					<router-link class="avatar-anchor" :to="`/@${getAcct(notification.post.user)}`" v-user-preview="notification.post.userId">
+						<img class="avatar" :src="`${notification.post.user.avatarUrl}?thumbnail&size=48`" alt="avatar"/>
 					</router-link>
 					<div class="text">
 						<p>%fa:reply%
-							<router-link :to="`/@${getAcct(notification.post.user)}`" v-user-preview="notification.post.user_id">{{ notification.post.user.name }}</router-link>
+							<router-link :to="`/@${getAcct(notification.post.user)}`" v-user-preview="notification.post.userId">{{ notification.post.user.name }}</router-link>
 						</p>
 						<router-link class="post-preview" :to="`/@${getAcct(notification.post.user)}/${notification.post.id}`">{{ getPostSummary(notification.post) }}</router-link>
 					</div>
 				</template>
 				<template v-if="notification.type == 'mention'">
-					<router-link class="avatar-anchor" :to="`/@${getAcct(notification.post.user)}`" v-user-preview="notification.post.user_id">
-						<img class="avatar" :src="`${notification.post.user.avatar_url}?thumbnail&size=48`" alt="avatar"/>
+					<router-link class="avatar-anchor" :to="`/@${getAcct(notification.post.user)}`" v-user-preview="notification.post.userId">
+						<img class="avatar" :src="`${notification.post.user.avatarUrl}?thumbnail&size=48`" alt="avatar"/>
 					</router-link>
 					<div class="text">
 						<p>%fa:at%
-							<router-link :to="`/@${getAcct(notification.post.user)}`" v-user-preview="notification.post.user_id">{{ notification.post.user.name }}</router-link>
+							<router-link :to="`/@${getAcct(notification.post.user)}`" v-user-preview="notification.post.userId">{{ notification.post.user.name }}</router-link>
 						</p>
 						<a class="post-preview" :href="`/@${getAcct(notification.post.user)}/${notification.post.id}`">{{ getPostSummary(notification.post) }}</a>
 					</div>
 				</template>
 				<template v-if="notification.type == 'poll_vote'">
 					<router-link class="avatar-anchor" :to="`/@${getAcct(notification.user)}`" v-user-preview="notification.user.id">
-						<img class="avatar" :src="`${notification.user.avatar_url}?thumbnail&size=48`" alt="avatar"/>
+						<img class="avatar" :src="`${notification.user.avatarUrl}?thumbnail&size=48`" alt="avatar"/>
 					</router-link>
 					<div class="text">
 						<p>%fa:chart-pie%<a :href="`/@${getAcct(notification.user)}`" v-user-preview="notification.user.id">{{ notification.user.name }}</a></p>
@@ -120,8 +120,8 @@ export default Vue.extend({
 	computed: {
 		_notifications(): any[] {
 			return (this.notifications as any).map(notification => {
-				const date = new Date(notification.created_at).getDate();
-				const month = new Date(notification.created_at).getMonth() + 1;
+				const date = new Date(notification.createdAt).getDate();
+				const month = new Date(notification.createdAt).getMonth() + 1;
 				notification._date = date;
 				notification._datetext = `${month}月 ${date}日`;
 				return notification;
@@ -161,7 +161,7 @@ export default Vue.extend({
 
 			(this as any).api('i/notifications', {
 				limit: max + 1,
-				until_id: this.notifications[this.notifications.length - 1].id
+				untilId: this.notifications[this.notifications.length - 1].id
 			}).then(notifications => {
 				if (notifications.length == max + 1) {
 					this.moreNotifications = true;
diff --git a/src/server/web/app/desktop/views/components/post-detail.sub.vue b/src/server/web/app/desktop/views/components/post-detail.sub.vue
index 59d8db04c..35377e7c2 100644
--- a/src/server/web/app/desktop/views/components/post-detail.sub.vue
+++ b/src/server/web/app/desktop/views/components/post-detail.sub.vue
@@ -1,17 +1,17 @@
 <template>
 <div class="sub" :title="title">
 	<router-link class="avatar-anchor" :to="`/@${acct}`">
-		<img class="avatar" :src="`${post.user.avatar_url}?thumbnail&size=64`" alt="avatar" v-user-preview="post.user_id"/>
+		<img class="avatar" :src="`${post.user.avatarUrl}?thumbnail&size=64`" alt="avatar" v-user-preview="post.userId"/>
 	</router-link>
 	<div class="main">
 		<header>
 			<div class="left">
-				<router-link class="name" :to="`/@${acct}`" v-user-preview="post.user_id">{{ post.user.name }}</router-link>
+				<router-link class="name" :to="`/@${acct}`" v-user-preview="post.userId">{{ post.user.name }}</router-link>
 				<span class="username">@{{ acct }}</span>
 			</div>
 			<div class="right">
 				<router-link class="time" :to="`/@${acct}/${post.id}`">
-					<mk-time :time="post.created_at"/>
+					<mk-time :time="post.createdAt"/>
 				</router-link>
 			</div>
 		</header>
@@ -37,7 +37,7 @@ export default Vue.extend({
 			return getAcct(this.post.user);
 		},
 		title(): string {
-			return dateStringify(this.post.created_at);
+			return dateStringify(this.post.createdAt);
 		}
 	}
 });
diff --git a/src/server/web/app/desktop/views/components/post-detail.vue b/src/server/web/app/desktop/views/components/post-detail.vue
index f09bf4cbd..7783ec62c 100644
--- a/src/server/web/app/desktop/views/components/post-detail.vue
+++ b/src/server/web/app/desktop/views/components/post-detail.vue
@@ -2,7 +2,7 @@
 <div class="mk-post-detail" :title="title">
 	<button
 		class="read-more"
-		v-if="p.reply && p.reply.reply_id && context == null"
+		v-if="p.reply && p.reply.replyId && context == null"
 		title="会話をもっと読み込む"
 		@click="fetchContext"
 		:disabled="contextFetching"
@@ -18,8 +18,8 @@
 	</div>
 	<div class="repost" v-if="isRepost">
 		<p>
-			<router-link class="avatar-anchor" :to="`/@${acct}`" v-user-preview="post.user_id">
-				<img class="avatar" :src="`${post.user.avatar_url}?thumbnail&size=32`" alt="avatar"/>
+			<router-link class="avatar-anchor" :to="`/@${acct}`" v-user-preview="post.userId">
+				<img class="avatar" :src="`${post.user.avatarUrl}?thumbnail&size=32`" alt="avatar"/>
 			</router-link>
 			%fa:retweet%
 			<router-link class="name" :href="`/@${acct}`">{{ post.user.name }}</router-link>
@@ -28,13 +28,13 @@
 	</div>
 	<article>
 		<router-link class="avatar-anchor" :to="`/@${acct}`">
-			<img class="avatar" :src="`${p.user.avatar_url}?thumbnail&size=64`" alt="avatar" v-user-preview="p.user.id"/>
+			<img class="avatar" :src="`${p.user.avatarUrl}?thumbnail&size=64`" alt="avatar" v-user-preview="p.user.id"/>
 		</router-link>
 		<header>
 			<router-link class="name" :to="`/@${acct}`" v-user-preview="p.user.id">{{ p.user.name }}</router-link>
 			<span class="username">@{{ acct }}</span>
 			<router-link class="time" :to="`/@${acct}/${p.id}`">
-				<mk-time :time="p.created_at"/>
+				<mk-time :time="p.createdAt"/>
 			</router-link>
 		</header>
 		<div class="body">
@@ -56,12 +56,12 @@
 		<footer>
 			<mk-reactions-viewer :post="p"/>
 			<button @click="reply" title="返信">
-				%fa:reply%<p class="count" v-if="p.replies_count > 0">{{ p.replies_count }}</p>
+				%fa:reply%<p class="count" v-if="p.repliesCount > 0">{{ p.repliesCount }}</p>
 			</button>
 			<button @click="repost" title="Repost">
-				%fa:retweet%<p class="count" v-if="p.repost_count > 0">{{ p.repost_count }}</p>
+				%fa:retweet%<p class="count" v-if="p.repostCount > 0">{{ p.repostCount }}</p>
 			</button>
-			<button :class="{ reacted: p.my_reaction != null }" @click="react" ref="reactButton" title="リアクション">
+			<button :class="{ reacted: p.myReaction != null }" @click="react" ref="reactButton" title="リアクション">
 				%fa:plus%<p class="count" v-if="p.reactions_count > 0">{{ p.reactions_count }}</p>
 			</button>
 			<button @click="menu" ref="menuButton">
@@ -115,21 +115,21 @@ export default Vue.extend({
 		isRepost(): boolean {
 			return (this.post.repost &&
 				this.post.text == null &&
-				this.post.media_ids == null &&
+				this.post.mediaIds == null &&
 				this.post.poll == null);
 		},
 		p(): any {
 			return this.isRepost ? this.post.repost : this.post;
 		},
 		reactionsCount(): number {
-			return this.p.reaction_counts
-				? Object.keys(this.p.reaction_counts)
-					.map(key => this.p.reaction_counts[key])
+			return this.p.reactionCounts
+				? Object.keys(this.p.reactionCounts)
+					.map(key => this.p.reactionCounts[key])
 					.reduce((a, b) => a + b)
 				: 0;
 		},
 		title(): string {
-			return dateStringify(this.p.created_at);
+			return dateStringify(this.p.createdAt);
 		},
 		urls(): string[] {
 			if (this.p.ast) {
@@ -145,7 +145,7 @@ export default Vue.extend({
 		// Get replies
 		if (!this.compact) {
 			(this as any).api('posts/replies', {
-				post_id: this.p.id,
+				postId: this.p.id,
 				limit: 8
 			}).then(replies => {
 				this.replies = replies;
@@ -154,7 +154,7 @@ export default Vue.extend({
 
 		// Draw map
 		if (this.p.geo) {
-			const shouldShowMap = (this as any).os.isSignedIn ? (this as any).os.i.account.client_settings.showMaps : true;
+			const shouldShowMap = (this as any).os.isSignedIn ? (this as any).os.i.account.clientSettings.showMaps : true;
 			if (shouldShowMap) {
 				(this as any).os.getGoogleMaps().then(maps => {
 					const uluru = new maps.LatLng(this.p.geo.latitude, this.p.geo.longitude);
@@ -176,7 +176,7 @@ export default Vue.extend({
 
 			// Fetch context
 			(this as any).api('posts/context', {
-				post_id: this.p.reply_id
+				postId: this.p.replyId
 			}).then(context => {
 				this.contextFetching = false;
 				this.context = context.reverse();
diff --git a/src/server/web/app/desktop/views/components/post-form.vue b/src/server/web/app/desktop/views/components/post-form.vue
index 78f6d445a..11028ceb5 100644
--- a/src/server/web/app/desktop/views/components/post-form.vue
+++ b/src/server/web/app/desktop/views/components/post-form.vue
@@ -219,9 +219,9 @@ export default Vue.extend({
 
 			(this as any).api('posts/create', {
 				text: this.text == '' ? undefined : this.text,
-				media_ids: this.files.length > 0 ? this.files.map(f => f.id) : undefined,
-				reply_id: this.reply ? this.reply.id : undefined,
-				repost_id: this.repost ? this.repost.id : undefined,
+				mediaIds: this.files.length > 0 ? this.files.map(f => f.id) : undefined,
+				replyId: this.reply ? this.reply.id : undefined,
+				repostId: this.repost ? this.repost.id : undefined,
 				poll: this.poll ? (this.$refs.poll as any).get() : undefined,
 				geo: this.geo ? {
 					latitude: this.geo.latitude,
@@ -255,7 +255,7 @@ export default Vue.extend({
 			const data = JSON.parse(localStorage.getItem('drafts') || '{}');
 
 			data[this.draftId] = {
-				updated_at: new Date(),
+				updatedAt: new Date(),
 				data: {
 					text: this.text,
 					files: this.files,
diff --git a/src/server/web/app/desktop/views/components/post-preview.vue b/src/server/web/app/desktop/views/components/post-preview.vue
index 808220c0e..0ac3223be 100644
--- a/src/server/web/app/desktop/views/components/post-preview.vue
+++ b/src/server/web/app/desktop/views/components/post-preview.vue
@@ -1,14 +1,14 @@
 <template>
 <div class="mk-post-preview" :title="title">
 	<router-link class="avatar-anchor" :to="`/@${acct}`">
-		<img class="avatar" :src="`${post.user.avatar_url}?thumbnail&size=64`" alt="avatar" v-user-preview="post.user_id"/>
+		<img class="avatar" :src="`${post.user.avatarUrl}?thumbnail&size=64`" alt="avatar" v-user-preview="post.userId"/>
 	</router-link>
 	<div class="main">
 		<header>
-			<router-link class="name" :to="`/@${acct}`" v-user-preview="post.user_id">{{ post.user.name }}</router-link>
+			<router-link class="name" :to="`/@${acct}`" v-user-preview="post.userId">{{ post.user.name }}</router-link>
 			<span class="username">@{{ acct }}</span>
 			<router-link class="time" :to="`/@${acct}/${post.id}`">
-				<mk-time :time="post.created_at"/>
+				<mk-time :time="post.createdAt"/>
 			</router-link>
 		</header>
 		<div class="body">
@@ -30,7 +30,7 @@ export default Vue.extend({
 			return getAcct(this.post.user);
 		},
 		title(): string {
-			return dateStringify(this.post.created_at);
+			return dateStringify(this.post.createdAt);
 		}
 	}
 });
diff --git a/src/server/web/app/desktop/views/components/posts.post.sub.vue b/src/server/web/app/desktop/views/components/posts.post.sub.vue
index 120700877..65d3017d3 100644
--- a/src/server/web/app/desktop/views/components/posts.post.sub.vue
+++ b/src/server/web/app/desktop/views/components/posts.post.sub.vue
@@ -1,14 +1,14 @@
 <template>
 <div class="sub" :title="title">
 	<router-link class="avatar-anchor" :to="`/@${acct}`">
-		<img class="avatar" :src="`${post.user.avatar_url}?thumbnail&size=64`" alt="avatar" v-user-preview="post.user_id"/>
+		<img class="avatar" :src="`${post.user.avatarUrl}?thumbnail&size=64`" alt="avatar" v-user-preview="post.userId"/>
 	</router-link>
 	<div class="main">
 		<header>
-			<router-link class="name" :to="`/@${acct}`" v-user-preview="post.user_id">{{ post.user.name }}</router-link>
+			<router-link class="name" :to="`/@${acct}`" v-user-preview="post.userId">{{ post.user.name }}</router-link>
 			<span class="username">@{{ acct }}</span>
 			<router-link class="created-at" :to="`/@${acct}/${post.id}`">
-				<mk-time :time="post.created_at"/>
+				<mk-time :time="post.createdAt"/>
 			</router-link>
 		</header>
 		<div class="body">
@@ -30,7 +30,7 @@ export default Vue.extend({
 			return getAcct(this.post.user);
 		},
 		title(): string {
-			return dateStringify(this.post.created_at);
+			return dateStringify(this.post.createdAt);
 		}
 	}
 });
diff --git a/src/server/web/app/desktop/views/components/posts.post.vue b/src/server/web/app/desktop/views/components/posts.post.vue
index 6b4d3d278..c70e01911 100644
--- a/src/server/web/app/desktop/views/components/posts.post.vue
+++ b/src/server/web/app/desktop/views/components/posts.post.vue
@@ -5,30 +5,30 @@
 	</div>
 	<div class="repost" v-if="isRepost">
 		<p>
-			<router-link class="avatar-anchor" :to="`/@${acct}`" v-user-preview="post.user_id">
-				<img class="avatar" :src="`${post.user.avatar_url}?thumbnail&size=32`" alt="avatar"/>
+			<router-link class="avatar-anchor" :to="`/@${acct}`" v-user-preview="post.userId">
+				<img class="avatar" :src="`${post.user.avatarUrl}?thumbnail&size=32`" alt="avatar"/>
 			</router-link>
 			%fa:retweet%
 			<span>{{ '%i18n:desktop.tags.mk-timeline-post.reposted-by%'.substr(0, '%i18n:desktop.tags.mk-timeline-post.reposted-by%'.indexOf('{')) }}</span>
-			<a class="name" :href="`/@${acct}`" v-user-preview="post.user_id">{{ post.user.name }}</a>
+			<a class="name" :href="`/@${acct}`" v-user-preview="post.userId">{{ post.user.name }}</a>
 			<span>{{ '%i18n:desktop.tags.mk-timeline-post.reposted-by%'.substr('%i18n:desktop.tags.mk-timeline-post.reposted-by%'.indexOf('}') + 1) }}</span>
 		</p>
-		<mk-time :time="post.created_at"/>
+		<mk-time :time="post.createdAt"/>
 	</div>
 	<article>
 		<router-link class="avatar-anchor" :to="`/@${acct}`">
-			<img class="avatar" :src="`${p.user.avatar_url}?thumbnail&size=64`" alt="avatar" v-user-preview="p.user.id"/>
+			<img class="avatar" :src="`${p.user.avatarUrl}?thumbnail&size=64`" alt="avatar" v-user-preview="p.user.id"/>
 		</router-link>
 		<div class="main">
 			<header>
 				<router-link class="name" :to="`/@${acct}`" v-user-preview="p.user.id">{{ acct }}</router-link>
-				<span class="is-bot" v-if="p.user.host === null && p.user.account.is_bot">bot</span>
+				<span class="is-bot" v-if="p.user.host === null && p.user.account.isBot">bot</span>
 				<span class="username">@{{ acct }}</span>
 				<div class="info">
 					<span class="app" v-if="p.app">via <b>{{ p.app.name }}</b></span>
-					<span class="mobile" v-if="p.via_mobile">%fa:mobile-alt%</span>
+					<span class="mobile" v-if="p.viaMobile">%fa:mobile-alt%</span>
 					<router-link class="created-at" :to="url">
-						<mk-time :time="p.created_at"/>
+						<mk-time :time="p.createdAt"/>
 					</router-link>
 				</div>
 			</header>
@@ -58,12 +58,12 @@
 			<footer>
 				<mk-reactions-viewer :post="p" ref="reactionsViewer"/>
 				<button @click="reply" title="%i18n:desktop.tags.mk-timeline-post.reply%">
-					%fa:reply%<p class="count" v-if="p.replies_count > 0">{{ p.replies_count }}</p>
+					%fa:reply%<p class="count" v-if="p.repliesCount > 0">{{ p.repliesCount }}</p>
 				</button>
 				<button @click="repost" title="%i18n:desktop.tags.mk-timeline-post.repost%">
-					%fa:retweet%<p class="count" v-if="p.repost_count > 0">{{ p.repost_count }}</p>
+					%fa:retweet%<p class="count" v-if="p.repostCount > 0">{{ p.repostCount }}</p>
 				</button>
-				<button :class="{ reacted: p.my_reaction != null }" @click="react" ref="reactButton" title="%i18n:desktop.tags.mk-timeline-post.add-reaction%">
+				<button :class="{ reacted: p.myReaction != null }" @click="react" ref="reactButton" title="%i18n:desktop.tags.mk-timeline-post.add-reaction%">
 					%fa:plus%<p class="count" v-if="p.reactions_count > 0">{{ p.reactions_count }}</p>
 				</button>
 				<button @click="menu" ref="menuButton">
@@ -122,21 +122,21 @@ export default Vue.extend({
 		isRepost(): boolean {
 			return (this.post.repost &&
 				this.post.text == null &&
-				this.post.media_ids == null &&
+				this.post.mediaIds == null &&
 				this.post.poll == null);
 		},
 		p(): any {
 			return this.isRepost ? this.post.repost : this.post;
 		},
 		reactionsCount(): number {
-			return this.p.reaction_counts
-				? Object.keys(this.p.reaction_counts)
-					.map(key => this.p.reaction_counts[key])
+			return this.p.reactionCounts
+				? Object.keys(this.p.reactionCounts)
+					.map(key => this.p.reactionCounts[key])
 					.reduce((a, b) => a + b)
 				: 0;
 		},
 		title(): string {
-			return dateStringify(this.p.created_at);
+			return dateStringify(this.p.createdAt);
 		},
 		url(): string {
 			return `/@${this.acct}/${this.p.id}`;
@@ -166,7 +166,7 @@ export default Vue.extend({
 
 		// Draw map
 		if (this.p.geo) {
-			const shouldShowMap = (this as any).os.isSignedIn ? (this as any).os.i.account.client_settings.showMaps : true;
+			const shouldShowMap = (this as any).os.isSignedIn ? (this as any).os.i.account.clientSettings.showMaps : true;
 			if (shouldShowMap) {
 				(this as any).os.getGoogleMaps().then(maps => {
 					const uluru = new maps.LatLng(this.p.geo.latitude, this.p.geo.longitude);
@@ -216,7 +216,7 @@ export default Vue.extend({
 			const post = data.post;
 			if (post.id == this.post.id) {
 				this.$emit('update:post', post);
-			} else if (post.id == this.post.repost_id) {
+			} else if (post.id == this.post.repostId) {
 				this.post.repost = post;
 			}
 		},
diff --git a/src/server/web/app/desktop/views/components/posts.vue b/src/server/web/app/desktop/views/components/posts.vue
index ffceff876..5031667c7 100644
--- a/src/server/web/app/desktop/views/components/posts.vue
+++ b/src/server/web/app/desktop/views/components/posts.vue
@@ -30,8 +30,8 @@ export default Vue.extend({
 	computed: {
 		_posts(): any[] {
 			return (this.posts as any).map(post => {
-				const date = new Date(post.created_at).getDate();
-				const month = new Date(post.created_at).getMonth() + 1;
+				const date = new Date(post.createdAt).getDate();
+				const month = new Date(post.createdAt).getMonth() + 1;
 				post._date = date;
 				post._datetext = `${month}月 ${date}日`;
 				return post;
diff --git a/src/server/web/app/desktop/views/components/repost-form.vue b/src/server/web/app/desktop/views/components/repost-form.vue
index f2774b817..3a5e3a7c5 100644
--- a/src/server/web/app/desktop/views/components/repost-form.vue
+++ b/src/server/web/app/desktop/views/components/repost-form.vue
@@ -29,7 +29,7 @@ export default Vue.extend({
 		ok() {
 			this.wait = true;
 			(this as any).api('posts/create', {
-				repost_id: this.post.id
+				repostId: this.post.id
 			}).then(data => {
 				this.$emit('posted');
 				(this as any).apis.notify('%i18n:desktop.tags.mk-repost-form.success%');
diff --git a/src/server/web/app/desktop/views/components/settings.2fa.vue b/src/server/web/app/desktop/views/components/settings.2fa.vue
index 85f2d6ba5..b8dd1dfd9 100644
--- a/src/server/web/app/desktop/views/components/settings.2fa.vue
+++ b/src/server/web/app/desktop/views/components/settings.2fa.vue
@@ -2,8 +2,8 @@
 <div class="2fa">
 	<p>%i18n:desktop.tags.mk-2fa-setting.intro%<a href="%i18n:desktop.tags.mk-2fa-setting.url%" target="_blank">%i18n:desktop.tags.mk-2fa-setting.detail%</a></p>
 	<div class="ui info warn"><p>%fa:exclamation-triangle%%i18n:desktop.tags.mk-2fa-setting.caution%</p></div>
-	<p v-if="!data && !os.i.account.two_factor_enabled"><button @click="register" class="ui primary">%i18n:desktop.tags.mk-2fa-setting.register%</button></p>
-	<template v-if="os.i.account.two_factor_enabled">
+	<p v-if="!data && !os.i.account.twoFactorEnabled"><button @click="register" class="ui primary">%i18n:desktop.tags.mk-2fa-setting.register%</button></p>
+	<template v-if="os.i.account.twoFactorEnabled">
 		<p>%i18n:desktop.tags.mk-2fa-setting.already-registered%</p>
 		<button @click="unregister" class="ui">%i18n:desktop.tags.mk-2fa-setting.unregister%</button>
 	</template>
@@ -54,7 +54,7 @@ export default Vue.extend({
 					password: password
 				}).then(() => {
 					(this as any).apis.notify('%i18n:desktop.tags.mk-2fa-setting.unregistered%');
-					(this as any).os.i.account.two_factor_enabled = false;
+					(this as any).os.i.account.twoFactorEnabled = false;
 				});
 			});
 		},
@@ -64,7 +64,7 @@ export default Vue.extend({
 				token: this.token
 			}).then(() => {
 				(this as any).apis.notify('%i18n:desktop.tags.mk-2fa-setting.success%');
-				(this as any).os.i.account.two_factor_enabled = true;
+				(this as any).os.i.account.twoFactorEnabled = true;
 			}).catch(() => {
 				(this as any).apis.notify('%i18n:desktop.tags.mk-2fa-setting.failed%');
 			});
diff --git a/src/server/web/app/desktop/views/components/settings.password.vue b/src/server/web/app/desktop/views/components/settings.password.vue
index be3f0370d..f883b5406 100644
--- a/src/server/web/app/desktop/views/components/settings.password.vue
+++ b/src/server/web/app/desktop/views/components/settings.password.vue
@@ -33,8 +33,8 @@ export default Vue.extend({
 							return;
 						}
 						(this as any).api('i/change_password', {
-							current_password: currentPassword,
-							new_password: newPassword
+							currentPasword: currentPassword,
+							newPassword: newPassword
 						}).then(() => {
 							(this as any).apis.notify('%i18n:desktop.tags.mk-password-setting.changed%');
 						});
diff --git a/src/server/web/app/desktop/views/components/settings.profile.vue b/src/server/web/app/desktop/views/components/settings.profile.vue
index 67a211c79..ba86286f8 100644
--- a/src/server/web/app/desktop/views/components/settings.profile.vue
+++ b/src/server/web/app/desktop/views/components/settings.profile.vue
@@ -2,7 +2,7 @@
 <div class="profile">
 	<label class="avatar ui from group">
 		<p>%i18n:desktop.tags.mk-profile-setting.avatar%</p>
-		<img class="avatar" :src="`${os.i.avatar_url}?thumbnail&size=64`" alt="avatar"/>
+		<img class="avatar" :src="`${os.i.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
 		<button class="ui" @click="updateAvatar">%i18n:desktop.tags.mk-profile-setting.choice-avatar%</button>
 	</label>
 	<label class="ui from group">
@@ -24,7 +24,7 @@
 	<button class="ui primary" @click="save">%i18n:desktop.tags.mk-profile-setting.save%</button>
 	<section>
 		<h2>その他</h2>
-		<mk-switch v-model="os.i.account.is_bot" @change="onChangeIsBot" text="このアカウントはbotです"/>
+		<mk-switch v-model="os.i.account.isBot" @change="onChangeIsBot" text="このアカウントはbotです"/>
 	</section>
 </div>
 </template>
@@ -63,7 +63,7 @@ export default Vue.extend({
 		},
 		onChangeIsBot() {
 			(this as any).api('i/update', {
-				is_bot: (this as any).os.i.account.is_bot
+				isBot: (this as any).os.i.account.isBot
 			});
 		}
 	}
diff --git a/src/server/web/app/desktop/views/components/settings.signins.vue b/src/server/web/app/desktop/views/components/settings.signins.vue
index ddc567f06..a414c95c2 100644
--- a/src/server/web/app/desktop/views/components/settings.signins.vue
+++ b/src/server/web/app/desktop/views/components/settings.signins.vue
@@ -6,7 +6,7 @@
 			<template v-if="signin.success">%fa:check%</template>
 			<template v-else>%fa:times%</template>
 			<span class="ip">{{ signin.ip }}</span>
-			<mk-time :time="signin.created_at"/>
+			<mk-time :time="signin.createdAt"/>
 		</header>
 		<div class="headers" v-show="signin._show">
 			<tree-view :data="signin.headers"/>
diff --git a/src/server/web/app/desktop/views/components/settings.vue b/src/server/web/app/desktop/views/components/settings.vue
index 3e6a477ce..fd82c171c 100644
--- a/src/server/web/app/desktop/views/components/settings.vue
+++ b/src/server/web/app/desktop/views/components/settings.vue
@@ -20,7 +20,7 @@
 
 		<section class="web" v-show="page == 'web'">
 			<h1>動作</h1>
-			<mk-switch v-model="os.i.account.client_settings.fetchOnScroll" @change="onChangeFetchOnScroll" text="スクロールで自動読み込み">
+			<mk-switch v-model="os.i.account.clientSettings.fetchOnScroll" @change="onChangeFetchOnScroll" text="スクロールで自動読み込み">
 				<span>ページを下までスクロールしたときに自動で追加のコンテンツを読み込みます。</span>
 			</mk-switch>
 			<mk-switch v-model="autoPopout" text="ウィンドウの自動ポップアウト">
@@ -33,11 +33,11 @@
 			<div class="div">
 				<button class="ui button" @click="customizeHome">ホームをカスタマイズ</button>
 			</div>
-			<mk-switch v-model="os.i.account.client_settings.showPostFormOnTopOfTl" @change="onChangeShowPostFormOnTopOfTl" text="タイムライン上部に投稿フォームを表示する"/>
-			<mk-switch v-model="os.i.account.client_settings.showMaps" @change="onChangeShowMaps" text="マップの自動展開">
+			<mk-switch v-model="os.i.account.clientSettings.showPostFormOnTopOfTl" @change="onChangeShowPostFormOnTopOfTl" text="タイムライン上部に投稿フォームを表示する"/>
+			<mk-switch v-model="os.i.account.clientSettings.showMaps" @change="onChangeShowMaps" text="マップの自動展開">
 				<span>位置情報が添付された投稿のマップを自動的に展開します。</span>
 			</mk-switch>
-			<mk-switch v-model="os.i.account.client_settings.gradientWindowHeader" @change="onChangeGradientWindowHeader" text="ウィンドウのタイトルバーにグラデーションを使用"/>
+			<mk-switch v-model="os.i.account.clientSettings.gradientWindowHeader" @change="onChangeGradientWindowHeader" text="ウィンドウのタイトルバーにグラデーションを使用"/>
 		</section>
 
 		<section class="web" v-show="page == 'web'">
@@ -57,7 +57,7 @@
 
 		<section class="web" v-show="page == 'web'">
 			<h1>モバイル</h1>
-			<mk-switch v-model="os.i.account.client_settings.disableViaMobile" @change="onChangeDisableViaMobile" text="「モバイルからの投稿」フラグを付けない"/>
+			<mk-switch v-model="os.i.account.clientSettings.disableViaMobile" @change="onChangeDisableViaMobile" text="「モバイルからの投稿」フラグを付けない"/>
 		</section>
 
 		<section class="web" v-show="page == 'web'">
@@ -86,7 +86,7 @@
 
 		<section class="notification" v-show="page == 'notification'">
 			<h1>通知</h1>
-			<mk-switch v-model="os.i.account.settings.auto_watch" @change="onChangeAutoWatch" text="投稿の自動ウォッチ">
+			<mk-switch v-model="os.i.account.settings.autoWatch" @change="onChangeAutoWatch" text="投稿の自動ウォッチ">
 				<span>リアクションしたり返信したりした投稿に関する通知を自動的に受け取るようにします。</span>
 			</mk-switch>
 		</section>
@@ -283,7 +283,7 @@ export default Vue.extend({
 		},
 		onChangeAutoWatch(v) {
 			(this as any).api('i/update', {
-				auto_watch: v
+				autoWatch: v
 			});
 		},
 		onChangeShowPostFormOnTopOfTl(v) {
diff --git a/src/server/web/app/desktop/views/components/sub-post-content.vue b/src/server/web/app/desktop/views/components/sub-post-content.vue
index 8c8f42c80..f13822331 100644
--- a/src/server/web/app/desktop/views/components/sub-post-content.vue
+++ b/src/server/web/app/desktop/views/components/sub-post-content.vue
@@ -1,9 +1,9 @@
 <template>
 <div class="mk-sub-post-content">
 	<div class="body">
-		<a class="reply" v-if="post.reply_id">%fa:reply%</a>
+		<a class="reply" v-if="post.replyId">%fa:reply%</a>
 		<mk-post-html :ast="post.ast" :i="os.i"/>
-		<a class="rp" v-if="post.repost_id" :href="`/post:${post.repost_id}`">RP: ...</a>
+		<a class="rp" v-if="post.repostId" :href="`/post:${post.repostId}`">RP: ...</a>
 		<mk-url-preview v-for="url in urls" :url="url" :key="url"/>
 	</div>
 	<details v-if="post.media">
diff --git a/src/server/web/app/desktop/views/components/timeline.vue b/src/server/web/app/desktop/views/components/timeline.vue
index 47a9688b6..65b4bd1c7 100644
--- a/src/server/web/app/desktop/views/components/timeline.vue
+++ b/src/server/web/app/desktop/views/components/timeline.vue
@@ -34,7 +34,7 @@ export default Vue.extend({
 	},
 	computed: {
 		alone(): boolean {
-			return (this as any).os.i.following_count == 0;
+			return (this as any).os.i.followingCount == 0;
 		}
 	},
 	mounted() {
@@ -65,7 +65,7 @@ export default Vue.extend({
 
 			(this as any).api('posts/timeline', {
 				limit: 11,
-				until_date: this.date ? this.date.getTime() : undefined
+				untilDate: this.date ? this.date.getTime() : undefined
 			}).then(posts => {
 				if (posts.length == 11) {
 					posts.pop();
@@ -82,7 +82,7 @@ export default Vue.extend({
 			this.moreFetching = true;
 			(this as any).api('posts/timeline', {
 				limit: 11,
-				until_id: this.posts[this.posts.length - 1].id
+				untilId: this.posts[this.posts.length - 1].id
 			}).then(posts => {
 				if (posts.length == 11) {
 					posts.pop();
@@ -107,7 +107,7 @@ export default Vue.extend({
 			this.fetch();
 		},
 		onScroll() {
-			if ((this as any).os.i.account.client_settings.fetchOnScroll !== false) {
+			if ((this as any).os.i.account.clientSettings.fetchOnScroll !== false) {
 				const current = window.scrollY + window.innerHeight;
 				if (current > document.body.offsetHeight - 8) this.more();
 			}
diff --git a/src/server/web/app/desktop/views/components/ui.header.account.vue b/src/server/web/app/desktop/views/components/ui.header.account.vue
index 19b9d7779..ec4635f33 100644
--- a/src/server/web/app/desktop/views/components/ui.header.account.vue
+++ b/src/server/web/app/desktop/views/components/ui.header.account.vue
@@ -2,7 +2,7 @@
 <div class="account">
 	<button class="header" :data-active="isOpen" @click="toggle">
 		<span class="username">{{ os.i.username }}<template v-if="!isOpen">%fa:angle-down%</template><template v-if="isOpen">%fa:angle-up%</template></span>
-		<img class="avatar" :src="`${ os.i.avatar_url }?thumbnail&size=64`" alt="avatar"/>
+		<img class="avatar" :src="`${ os.i.avatarUrl }?thumbnail&size=64`" alt="avatar"/>
 	</button>
 	<transition name="zoom-in-top">
 		<div class="menu" v-if="isOpen">
diff --git a/src/server/web/app/desktop/views/components/ui.header.vue b/src/server/web/app/desktop/views/components/ui.header.vue
index 8af0e2fbe..7e337d2ae 100644
--- a/src/server/web/app/desktop/views/components/ui.header.vue
+++ b/src/server/web/app/desktop/views/components/ui.header.vue
@@ -44,9 +44,9 @@ export default Vue.extend({
 	},
 	mounted() {
 		if ((this as any).os.isSignedIn) {
-			const ago = (new Date().getTime() - new Date((this as any).os.i.account.last_used_at).getTime()) / 1000
+			const ago = (new Date().getTime() - new Date((this as any).os.i.account.lastUsedAt).getTime()) / 1000
 			const isHisasiburi = ago >= 3600;
-			(this as any).os.i.account.last_used_at = new Date();
+			(this as any).os.i.account.lastUsedAt = new Date();
 			if (isHisasiburi) {
 				(this.$refs.welcomeback as any).style.display = 'block';
 				(this.$refs.main as any).style.overflow = 'hidden';
diff --git a/src/server/web/app/desktop/views/components/user-preview.vue b/src/server/web/app/desktop/views/components/user-preview.vue
index 24d613f12..8c86b2efe 100644
--- a/src/server/web/app/desktop/views/components/user-preview.vue
+++ b/src/server/web/app/desktop/views/components/user-preview.vue
@@ -1,9 +1,9 @@
 <template>
 <div class="mk-user-preview">
 	<template v-if="u != null">
-		<div class="banner" :style="u.banner_url ? `background-image: url(${u.banner_url}?thumbnail&size=512)` : ''"></div>
+		<div class="banner" :style="u.bannerUrl ? `background-image: url(${u.bannerUrl}?thumbnail&size=512)` : ''"></div>
 		<router-link class="avatar" :to="`/@${acct}`">
-			<img :src="`${u.avatar_url}?thumbnail&size=64`" alt="avatar"/>
+			<img :src="`${u.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
 		</router-link>
 		<div class="title">
 			<router-link class="name" :to="`/@${acct}`">{{ u.name }}</router-link>
@@ -12,13 +12,13 @@
 		<div class="description">{{ u.description }}</div>
 		<div class="status">
 			<div>
-				<p>投稿</p><a>{{ u.posts_count }}</a>
+				<p>投稿</p><a>{{ u.postsCount }}</a>
 			</div>
 			<div>
-				<p>フォロー</p><a>{{ u.following_count }}</a>
+				<p>フォロー</p><a>{{ u.followingCount }}</a>
 			</div>
 			<div>
-				<p>フォロワー</p><a>{{ u.followers_count }}</a>
+				<p>フォロワー</p><a>{{ u.followersCount }}</a>
 			</div>
 		</div>
 		<mk-follow-button v-if="os.isSignedIn && user.id != os.i.id" :user="u"/>
@@ -58,7 +58,7 @@ export default Vue.extend({
 		} else {
 			const query = this.user[0] == '@' ?
 				parseAcct(this.user[0].substr(1)) :
-				{ user_id: this.user[0] };
+				{ userId: this.user[0] };
 
 			(this as any).api('users/show', query).then(user => {
 				this.u = user;
diff --git a/src/server/web/app/desktop/views/components/users-list.item.vue b/src/server/web/app/desktop/views/components/users-list.item.vue
index e02d1311d..d2bfc117d 100644
--- a/src/server/web/app/desktop/views/components/users-list.item.vue
+++ b/src/server/web/app/desktop/views/components/users-list.item.vue
@@ -1,7 +1,7 @@
 <template>
 <div class="root item">
 	<router-link class="avatar-anchor" :to="`/@${acct}`" v-user-preview="user.id">
-		<img class="avatar" :src="`${user.avatar_url}?thumbnail&size=64`" alt="avatar"/>
+		<img class="avatar" :src="`${user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
 	</router-link>
 	<div class="main">
 		<header>
@@ -9,7 +9,7 @@
 			<span class="username">@{{ acct }}</span>
 		</header>
 		<div class="body">
-			<p class="followed" v-if="user.is_followed">フォローされています</p>
+			<p class="followed" v-if="user.isFollowed">フォローされています</p>
 			<div class="description">{{ user.description }}</div>
 		</div>
 	</div>
diff --git a/src/server/web/app/desktop/views/components/widget-container.vue b/src/server/web/app/desktop/views/components/widget-container.vue
index dd42be63b..68c5bcb8d 100644
--- a/src/server/web/app/desktop/views/components/widget-container.vue
+++ b/src/server/web/app/desktop/views/components/widget-container.vue
@@ -24,8 +24,8 @@ export default Vue.extend({
 	computed: {
 		withGradient(): boolean {
 			return (this as any).os.isSignedIn
-				? (this as any).os.i.account.client_settings.gradientWindowHeader != null
-					? (this as any).os.i.account.client_settings.gradientWindowHeader
+				? (this as any).os.i.account.clientSettings.gradientWindowHeader != null
+					? (this as any).os.i.account.clientSettings.gradientWindowHeader
 					: false
 				: false;
 		}
diff --git a/src/server/web/app/desktop/views/components/window.vue b/src/server/web/app/desktop/views/components/window.vue
index 75f725d4b..48dc46feb 100644
--- a/src/server/web/app/desktop/views/components/window.vue
+++ b/src/server/web/app/desktop/views/components/window.vue
@@ -92,8 +92,8 @@ export default Vue.extend({
 		},
 		withGradient(): boolean {
 			return (this as any).os.isSignedIn
-				? (this as any).os.i.account.client_settings.gradientWindowHeader != null
-					? (this as any).os.i.account.client_settings.gradientWindowHeader
+				? (this as any).os.i.account.clientSettings.gradientWindowHeader != null
+					? (this as any).os.i.account.clientSettings.gradientWindowHeader
 					: false
 				: false;
 		}
diff --git a/src/server/web/app/desktop/views/pages/home.vue b/src/server/web/app/desktop/views/pages/home.vue
index e1464bab1..69e134f79 100644
--- a/src/server/web/app/desktop/views/pages/home.vue
+++ b/src/server/web/app/desktop/views/pages/home.vue
@@ -45,7 +45,7 @@ export default Vue.extend({
 		},
 
 		onStreamPost(post) {
-			if (document.hidden && post.user_id != (this as any).os.i.id) {
+			if (document.hidden && post.userId != (this as any).os.i.id) {
 				this.unreadCount++;
 				document.title = `(${this.unreadCount}) ${getPostSummary(post)}`;
 			}
diff --git a/src/server/web/app/desktop/views/pages/othello.vue b/src/server/web/app/desktop/views/pages/othello.vue
index 160dd9a35..0d8e987dd 100644
--- a/src/server/web/app/desktop/views/pages/othello.vue
+++ b/src/server/web/app/desktop/views/pages/othello.vue
@@ -34,7 +34,7 @@ export default Vue.extend({
 			this.fetching = true;
 
 			(this as any).api('othello/games/show', {
-				game_id: this.$route.params.game
+				gameId: this.$route.params.game
 			}).then(game => {
 				this.game = game;
 				this.fetching = false;
diff --git a/src/server/web/app/desktop/views/pages/post.vue b/src/server/web/app/desktop/views/pages/post.vue
index c7b8729b7..dbd707e04 100644
--- a/src/server/web/app/desktop/views/pages/post.vue
+++ b/src/server/web/app/desktop/views/pages/post.vue
@@ -31,7 +31,7 @@ export default Vue.extend({
 			this.fetching = true;
 
 			(this as any).api('posts/show', {
-				post_id: this.$route.params.post
+				postId: this.$route.params.post
 			}).then(post => {
 				this.post = post;
 				this.fetching = false;
diff --git a/src/server/web/app/desktop/views/pages/user/user.followers-you-know.vue b/src/server/web/app/desktop/views/pages/user/user.followers-you-know.vue
index 80b38e8ac..d0dab6c3d 100644
--- a/src/server/web/app/desktop/views/pages/user/user.followers-you-know.vue
+++ b/src/server/web/app/desktop/views/pages/user/user.followers-you-know.vue
@@ -4,7 +4,7 @@
 	<p class="initializing" v-if="fetching">%fa:spinner .pulse .fw%%i18n:desktop.tags.mk-user.followers-you-know.loading%<mk-ellipsis/></p>
 	<div v-if="!fetching && users.length > 0">
 	<router-link v-for="user in users" :to="`/@${getAcct(user)}`" :key="user.id">
-		<img :src="`${user.avatar_url}?thumbnail&size=64`" :alt="user.name" v-user-preview="user.id"/>
+		<img :src="`${user.avatarUrl}?thumbnail&size=64`" :alt="user.name" v-user-preview="user.id"/>
 	</router-link>
 	</div>
 	<p class="empty" v-if="!fetching && users.length == 0">%i18n:desktop.tags.mk-user.followers-you-know.no-users%</p>
@@ -28,7 +28,7 @@ export default Vue.extend({
 	},
 	mounted() {
 		(this as any).api('users/followers', {
-			user_id: this.user.id,
+			userId: this.user.id,
 			iknow: true,
 			limit: 16
 		}).then(x => {
diff --git a/src/server/web/app/desktop/views/pages/user/user.friends.vue b/src/server/web/app/desktop/views/pages/user/user.friends.vue
index 57e6def27..3ec30fb43 100644
--- a/src/server/web/app/desktop/views/pages/user/user.friends.vue
+++ b/src/server/web/app/desktop/views/pages/user/user.friends.vue
@@ -5,7 +5,7 @@
 	<template v-if="!fetching && users.length != 0">
 		<div class="user" v-for="friend in users">
 			<router-link class="avatar-anchor" :to="`/@${getAcct(friend)}`">
-				<img class="avatar" :src="`${friend.avatar_url}?thumbnail&size=42`" alt="" v-user-preview="friend.id"/>
+				<img class="avatar" :src="`${friend.avatarUrl}?thumbnail&size=42`" alt="" v-user-preview="friend.id"/>
 			</router-link>
 			<div class="body">
 				<router-link class="name" :to="`/@${getAcct(friend)}`" v-user-preview="friend.id">{{ friend.name }}</router-link>
@@ -35,7 +35,7 @@ export default Vue.extend({
 	},
 	mounted() {
 		(this as any).api('users/get_frequently_replied_users', {
-			user_id: this.user.id,
+			userId: this.user.id,
 			limit: 4
 		}).then(docs => {
 			this.users = docs.map(doc => doc.user);
diff --git a/src/server/web/app/desktop/views/pages/user/user.header.vue b/src/server/web/app/desktop/views/pages/user/user.header.vue
index 3522e76bd..54f431fd2 100644
--- a/src/server/web/app/desktop/views/pages/user/user.header.vue
+++ b/src/server/web/app/desktop/views/pages/user/user.header.vue
@@ -1,11 +1,11 @@
 <template>
-<div class="header" :data-is-dark-background="user.banner_url != null">
-	<div class="banner-container" :style="user.banner_url ? `background-image: url(${user.banner_url}?thumbnail&size=2048)` : ''">
-		<div class="banner" ref="banner" :style="user.banner_url ? `background-image: url(${user.banner_url}?thumbnail&size=2048)` : ''" @click="onBannerClick"></div>
+<div class="header" :data-is-dark-background="user.bannerUrl != null">
+	<div class="banner-container" :style="user.bannerUrl ? `background-image: url(${user.bannerUrl}?thumbnail&size=2048)` : ''">
+		<div class="banner" ref="banner" :style="user.bannerUrl ? `background-image: url(${user.bannerUrl}?thumbnail&size=2048)` : ''" @click="onBannerClick"></div>
 	</div>
 	<div class="fade"></div>
 	<div class="container">
-		<img class="avatar" :src="`${user.avatar_url}?thumbnail&size=150`" alt="avatar"/>
+		<img class="avatar" :src="`${user.avatarUrl}?thumbnail&size=150`" alt="avatar"/>
 		<div class="title">
 			<p class="name">{{ user.name }}</p>
 			<p class="username">@{{ acct }}</p>
@@ -59,7 +59,7 @@ export default Vue.extend({
 			if (!(this as any).os.isSignedIn || (this as any).os.i.id != this.user.id) return;
 
 			(this as any).apis.updateBanner((this as any).os.i, i => {
-				this.user.banner_url = i.banner_url;
+				this.user.bannerUrl = i.bannerUrl;
 			});
 		}
 	}
diff --git a/src/server/web/app/desktop/views/pages/user/user.home.vue b/src/server/web/app/desktop/views/pages/user/user.home.vue
index 2483a6c72..071c9bb61 100644
--- a/src/server/web/app/desktop/views/pages/user/user.home.vue
+++ b/src/server/web/app/desktop/views/pages/user/user.home.vue
@@ -5,16 +5,16 @@
 			<x-profile :user="user"/>
 			<x-photos :user="user"/>
 			<x-followers-you-know v-if="os.isSignedIn && os.i.id != user.id" :user="user"/>
-			<p v-if="user.host === null">%i18n:desktop.tags.mk-user.last-used-at%: <b><mk-time :time="user.account.last_used_at"/></b></p>
+			<p v-if="user.host === null">%i18n:desktop.tags.mk-user.last-used-at%: <b><mk-time :time="user.account.lastUsedAt"/></b></p>
 		</div>
 	</div>
 	<main>
-		<mk-post-detail v-if="user.pinned_post" :post="user.pinned_post" :compact="true"/>
+		<mk-post-detail v-if="user.pinnedPost" :post="user.pinnedPost" :compact="true"/>
 		<x-timeline class="timeline" ref="tl" :user="user"/>
 	</main>
 	<div>
 		<div ref="right">
-			<mk-calendar @chosen="warp" :start="new Date(user.created_at)"/>
+			<mk-calendar @chosen="warp" :start="new Date(user.createdAt)"/>
 			<mk-activity :user="user"/>
 			<x-friends :user="user"/>
 			<div class="nav"><mk-nav/></div>
diff --git a/src/server/web/app/desktop/views/pages/user/user.photos.vue b/src/server/web/app/desktop/views/pages/user/user.photos.vue
index db29a9945..1ff79b4ae 100644
--- a/src/server/web/app/desktop/views/pages/user/user.photos.vue
+++ b/src/server/web/app/desktop/views/pages/user/user.photos.vue
@@ -23,8 +23,8 @@ export default Vue.extend({
 	},
 	mounted() {
 		(this as any).api('users/posts', {
-			user_id: this.user.id,
-			with_media: true,
+			userId: this.user.id,
+			withMedia: true,
 			limit: 9
 		}).then(posts => {
 			posts.forEach(post => {
diff --git a/src/server/web/app/desktop/views/pages/user/user.profile.vue b/src/server/web/app/desktop/views/pages/user/user.profile.vue
index b51aae18f..f5562d091 100644
--- a/src/server/web/app/desktop/views/pages/user/user.profile.vue
+++ b/src/server/web/app/desktop/views/pages/user/user.profile.vue
@@ -2,21 +2,21 @@
 <div class="profile">
 	<div class="friend-form" v-if="os.isSignedIn && os.i.id != user.id">
 		<mk-follow-button :user="user" size="big"/>
-		<p class="followed" v-if="user.is_followed">%i18n:desktop.tags.mk-user.follows-you%</p>
-		<p v-if="user.is_muted">%i18n:desktop.tags.mk-user.muted% <a @click="unmute">%i18n:desktop.tags.mk-user.unmute%</a></p>
-		<p v-if="!user.is_muted"><a @click="mute">%i18n:desktop.tags.mk-user.mute%</a></p>
+		<p class="followed" v-if="user.isFollowed">%i18n:desktop.tags.mk-user.follows-you%</p>
+		<p v-if="user.isMuted">%i18n:desktop.tags.mk-user.muted% <a @click="unmute">%i18n:desktop.tags.mk-user.unmute%</a></p>
+		<p v-if="!user.isMuted"><a @click="mute">%i18n:desktop.tags.mk-user.mute%</a></p>
 	</div>
 	<div class="description" v-if="user.description">{{ user.description }}</div>
 	<div class="birthday" v-if="user.host === null && user.account.profile.birthday">
 		<p>%fa:birthday-cake%{{ user.account.profile.birthday.replace('-', '年').replace('-', '月') + '日' }} ({{ age }}歳)</p>
 	</div>
 	<div class="twitter" v-if="user.host === null && user.account.twitter">
-		<p>%fa:B twitter%<a :href="`https://twitter.com/${user.account.twitter.screen_name}`" target="_blank">@{{ user.account.twitter.screen_name }}</a></p>
+		<p>%fa:B twitter%<a :href="`https://twitter.com/${user.account.twitter.screenName}`" target="_blank">@{{ user.account.twitter.screenName }}</a></p>
 	</div>
 	<div class="status">
-		<p class="posts-count">%fa:angle-right%<a>{{ user.posts_count }}</a><b>投稿</b></p>
-		<p class="following">%fa:angle-right%<a @click="showFollowing">{{ user.following_count }}</a>人を<b>フォロー</b></p>
-		<p class="followers">%fa:angle-right%<a @click="showFollowers">{{ user.followers_count }}</a>人の<b>フォロワー</b></p>
+		<p class="posts-count">%fa:angle-right%<a>{{ user.postsCount }}</a><b>投稿</b></p>
+		<p class="following">%fa:angle-right%<a @click="showFollowing">{{ user.followingCount }}</a>人を<b>フォロー</b></p>
+		<p class="followers">%fa:angle-right%<a @click="showFollowers">{{ user.followersCount }}</a>人の<b>フォロワー</b></p>
 	</div>
 </div>
 </template>
@@ -49,9 +49,9 @@ export default Vue.extend({
 
 		mute() {
 			(this as any).api('mute/create', {
-				user_id: this.user.id
+				userId: this.user.id
 			}).then(() => {
-				this.user.is_muted = true;
+				this.user.isMuted = true;
 			}, () => {
 				alert('error');
 			});
@@ -59,9 +59,9 @@ export default Vue.extend({
 
 		unmute() {
 			(this as any).api('mute/delete', {
-				user_id: this.user.id
+				userId: this.user.id
 			}).then(() => {
-				this.user.is_muted = false;
+				this.user.isMuted = false;
 			}, () => {
 				alert('error');
 			});
diff --git a/src/server/web/app/desktop/views/pages/user/user.timeline.vue b/src/server/web/app/desktop/views/pages/user/user.timeline.vue
index 60eef8951..134ad423c 100644
--- a/src/server/web/app/desktop/views/pages/user/user.timeline.vue
+++ b/src/server/web/app/desktop/views/pages/user/user.timeline.vue
@@ -61,8 +61,8 @@ export default Vue.extend({
 		},
 		fetch(cb?) {
 			(this as any).api('users/posts', {
-				user_id: this.user.id,
-				until_date: this.date ? this.date.getTime() : undefined,
+				userId: this.user.id,
+				untilDate: this.date ? this.date.getTime() : undefined,
 				with_replies: this.mode == 'with-replies'
 			}).then(posts => {
 				this.posts = posts;
@@ -74,9 +74,9 @@ export default Vue.extend({
 			if (this.moreFetching || this.fetching || this.posts.length == 0) return;
 			this.moreFetching = true;
 			(this as any).api('users/posts', {
-				user_id: this.user.id,
+				userId: this.user.id,
 				with_replies: this.mode == 'with-replies',
-				until_id: this.posts[this.posts.length - 1].id
+				untilId: this.posts[this.posts.length - 1].id
 			}).then(posts => {
 				this.moreFetching = false;
 				this.posts = this.posts.concat(posts);
diff --git a/src/server/web/app/desktop/views/pages/welcome.vue b/src/server/web/app/desktop/views/pages/welcome.vue
index 927ddf575..34c28854b 100644
--- a/src/server/web/app/desktop/views/pages/welcome.vue
+++ b/src/server/web/app/desktop/views/pages/welcome.vue
@@ -9,7 +9,7 @@
 					<p><button class="signup" @click="signup">はじめる</button><button class="signin" @click="signin">ログイン</button></p>
 					<div class="users">
 						<router-link v-for="user in users" :key="user.id" class="avatar-anchor" :to="`/@${getAcct(user)}`" v-user-preview="user.id">
-							<img class="avatar" :src="`${user.avatar_url}?thumbnail&size=64`" alt="avatar"/>
+							<img class="avatar" :src="`${user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
 						</router-link>
 					</div>
 				</div>
diff --git a/src/server/web/app/desktop/views/widgets/channel.channel.form.vue b/src/server/web/app/desktop/views/widgets/channel.channel.form.vue
index 392ba5924..aaf327f1e 100644
--- a/src/server/web/app/desktop/views/widgets/channel.channel.form.vue
+++ b/src/server/web/app/desktop/views/widgets/channel.channel.form.vue
@@ -30,8 +30,8 @@ export default Vue.extend({
 
 			(this as any).api('posts/create', {
 				text: this.text,
-				reply_id: reply ? reply.id : undefined,
-				channel_id: (this.$parent as any).channel.id
+				replyId: reply ? reply.id : undefined,
+				channelId: (this.$parent as any).channel.id
 			}).then(data => {
 				this.text = '';
 			}).catch(err => {
diff --git a/src/server/web/app/desktop/views/widgets/channel.channel.vue b/src/server/web/app/desktop/views/widgets/channel.channel.vue
index de5885bfc..e9fb9e3fd 100644
--- a/src/server/web/app/desktop/views/widgets/channel.channel.vue
+++ b/src/server/web/app/desktop/views/widgets/channel.channel.vue
@@ -44,7 +44,7 @@ export default Vue.extend({
 			this.fetching = true;
 
 			(this as any).api('channels/posts', {
-				channel_id: this.channel.id
+				channelId: this.channel.id
 			}).then(posts => {
 				this.posts = posts;
 				this.fetching = false;
diff --git a/src/server/web/app/desktop/views/widgets/channel.vue b/src/server/web/app/desktop/views/widgets/channel.vue
index fc143bb1d..c9b62dfea 100644
--- a/src/server/web/app/desktop/views/widgets/channel.vue
+++ b/src/server/web/app/desktop/views/widgets/channel.vue
@@ -48,7 +48,7 @@ export default define({
 			this.fetching = true;
 
 			(this as any).api('channels/show', {
-				channel_id: this.props.channel
+				channelId: this.props.channel
 			}).then(channel => {
 				this.channel = channel;
 				this.fetching = false;
diff --git a/src/server/web/app/desktop/views/widgets/profile.vue b/src/server/web/app/desktop/views/widgets/profile.vue
index 394010619..83cd67b50 100644
--- a/src/server/web/app/desktop/views/widgets/profile.vue
+++ b/src/server/web/app/desktop/views/widgets/profile.vue
@@ -4,12 +4,12 @@
 	:data-melt="props.design == 2"
 >
 	<div class="banner"
-		:style="os.i.banner_url ? `background-image: url(${os.i.banner_url}?thumbnail&size=256)` : ''"
+		:style="os.i.bannerUrl ? `background-image: url(${os.i.bannerUrl}?thumbnail&size=256)` : ''"
 		title="クリックでバナー編集"
 		@click="os.apis.updateBanner"
 	></div>
 	<img class="avatar"
-		:src="`${os.i.avatar_url}?thumbnail&size=96`"
+		:src="`${os.i.avatarUrl}?thumbnail&size=96`"
 		@click="os.apis.updateAvatar"
 		alt="avatar"
 		title="クリックでアバター編集"
diff --git a/src/server/web/app/desktop/views/widgets/users.vue b/src/server/web/app/desktop/views/widgets/users.vue
index 10e3c529e..7b8944112 100644
--- a/src/server/web/app/desktop/views/widgets/users.vue
+++ b/src/server/web/app/desktop/views/widgets/users.vue
@@ -8,7 +8,7 @@
 	<template v-else-if="users.length != 0">
 		<div class="user" v-for="_user in users">
 			<router-link class="avatar-anchor" :to="`/@${getAcct(_user)}`">
-				<img class="avatar" :src="`${_user.avatar_url}?thumbnail&size=42`" alt="" v-user-preview="_user.id"/>
+				<img class="avatar" :src="`${_user.avatarUrl}?thumbnail&size=42`" alt="" v-user-preview="_user.id"/>
 			</router-link>
 			<div class="body">
 				<router-link class="name" :to="`/@${getAcct(_user)}`" v-user-preview="_user.id">{{ _user.name }}</router-link>
diff --git a/src/server/web/app/dev/views/app.vue b/src/server/web/app/dev/views/app.vue
index 2c2a3c83c..a35b032b7 100644
--- a/src/server/web/app/dev/views/app.vue
+++ b/src/server/web/app/dev/views/app.vue
@@ -28,7 +28,7 @@ export default Vue.extend({
 		fetch() {
 			this.fetching = true;
 			(this as any).api('app/show', {
-				app_id: this.$route.params.id
+				appId: this.$route.params.id
 			}).then(app => {
 				this.app = app;
 				this.fetching = false;
diff --git a/src/server/web/app/dev/views/new-app.vue b/src/server/web/app/dev/views/new-app.vue
index 344e8468f..e407ca00d 100644
--- a/src/server/web/app/dev/views/new-app.vue
+++ b/src/server/web/app/dev/views/new-app.vue
@@ -6,12 +6,12 @@
 				<b-form-input v-model="name" type="text" placeholder="ex) Misskey for iOS" autocomplete="off" required/>
 			</b-form-group>
 			<b-form-group label="ID" description="あなたのアプリのID。">
-				<b-input v-model="nid" type="text" pattern="^[a-zA-Z0-9-]{3,30}$" placeholder="ex) misskey-for-ios" autocomplete="off" required/>
+				<b-input v-model="nid" type="text" pattern="^[a-zA-Z0-9_]{3,30}$" placeholder="ex) misskey-for-ios" autocomplete="off" required/>
 				<p class="info" v-if="nidState == 'wait'" style="color:#999">%fa:spinner .pulse .fw%確認しています...</p>
 				<p class="info" v-if="nidState == 'ok'" style="color:#3CB7B5">%fa:fw check%利用できます</p>
 				<p class="info" v-if="nidState == 'unavailable'" style="color:#FF1161">%fa:fw exclamation-triangle%既に利用されています</p>
 				<p class="info" v-if="nidState == 'error'" style="color:#FF1161">%fa:fw exclamation-triangle%通信エラー</p>
-				<p class="info" v-if="nidState == 'invalid-format'" style="color:#FF1161">%fa:fw exclamation-triangle%a~z、A~Z、0~9、-(ハイフン)が使えます</p>
+				<p class="info" v-if="nidState == 'invalid-format'" style="color:#FF1161">%fa:fw exclamation-triangle%a~z、A~Z、0~9、_が使えます</p>
 				<p class="info" v-if="nidState == 'min-range'" style="color:#FF1161">%fa:fw exclamation-triangle%3文字以上でお願いします!</p>
 				<p class="info" v-if="nidState == 'max-range'" style="color:#FF1161">%fa:fw exclamation-triangle%30文字以内でお願いします</p>
 			</b-form-group>
@@ -77,8 +77,8 @@ export default Vue.extend({
 
 			this.nidState = 'wait';
 
-			(this as any).api('app/name_id/available', {
-				name_id: this.nid
+			(this as any).api('app/nameId/available', {
+				nameId: this.nid
 			}).then(result => {
 				this.nidState = result.available ? 'ok' : 'unavailable';
 			}).catch(err => {
@@ -90,9 +90,9 @@ export default Vue.extend({
 		onSubmit() {
 			(this as any).api('app/create', {
 				name: this.name,
-				name_id: this.nid,
+				nameId: this.nid,
 				description: this.description,
-				callback_url: this.cb,
+				callbackUrl: this.cb,
 				permission: this.permission
 			}).then(() => {
 				location.href = '/apps';
diff --git a/src/server/web/app/init.ts b/src/server/web/app/init.ts
index 521dade86..3e5c38961 100644
--- a/src/server/web/app/init.ts
+++ b/src/server/web/app/init.ts
@@ -14,7 +14,7 @@ import ElementLocaleJa from 'element-ui/lib/locale/lang/ja';
 import App from './app.vue';
 import checkForUpdate from './common/scripts/check-for-update';
 import MiOS, { API } from './common/mios';
-import { version, hostname, lang } from './config';
+import { version, codename, hostname, lang } from './config';
 
 let elementLocale;
 switch (lang) {
@@ -51,7 +51,7 @@ Vue.mixin({
  * APP ENTRY POINT!
  */
 
-console.info(`Misskey v${version} (葵 aoi)`);
+console.info(`Misskey v${version} (${codename})`);
 console.info(
 	'%cここにコードを入力したり張り付けたりしないでください。アカウントが不正利用される可能性があります。',
 	'color: red; background: yellow; font-size: 16px; font-weight: bold;');
diff --git a/src/server/web/app/mobile/api/post.ts b/src/server/web/app/mobile/api/post.ts
index 9b78ce10c..841103fee 100644
--- a/src/server/web/app/mobile/api/post.ts
+++ b/src/server/web/app/mobile/api/post.ts
@@ -18,7 +18,7 @@ export default (os) => (opts) => {
 		const text = window.prompt(`「${getPostSummary(o.repost)}」をRepost`);
 		if (text == null) return;
 		os.api('posts/create', {
-			repost_id: o.repost.id,
+			repostId: o.repost.id,
 			text: text == '' ? undefined : text
 		});
 	} else {
diff --git a/src/server/web/app/mobile/views/components/activity.vue b/src/server/web/app/mobile/views/components/activity.vue
index b50044b3d..2e44017e7 100644
--- a/src/server/web/app/mobile/views/components/activity.vue
+++ b/src/server/web/app/mobile/views/components/activity.vue
@@ -29,7 +29,7 @@ export default Vue.extend({
 	},
 	mounted() {
 		(this as any).api('aggregation/users/activity', {
-			user_id: this.user.id,
+			userId: this.user.id,
 			limit: 30
 		}).then(data => {
 			data.forEach(d => d.total = d.posts + d.replies + d.reposts);
diff --git a/src/server/web/app/mobile/views/components/drive.file-detail.vue b/src/server/web/app/mobile/views/components/drive.file-detail.vue
index e41ebbb45..f3274f677 100644
--- a/src/server/web/app/mobile/views/components/drive.file-detail.vue
+++ b/src/server/web/app/mobile/views/components/drive.file-detail.vue
@@ -29,7 +29,7 @@
 			<span class="separator"></span>
 			<span class="data-size">{{ file.datasize | bytes }}</span>
 			<span class="separator"></span>
-			<span class="created-at" @click="showCreatedAt">%fa:R clock%<mk-time :time="file.created_at"/></span>
+			<span class="created-at" @click="showCreatedAt">%fa:R clock%<mk-time :time="file.createdAt"/></span>
 		</div>
 	</div>
 	<div class="menu">
@@ -86,8 +86,8 @@ export default Vue.extend({
 			return this.file.type.split('/')[0];
 		},
 		style(): any {
-			return this.file.properties.average_color ? {
-				'background-color': `rgb(${ this.file.properties.average_color.join(',') })`
+			return this.file.properties.avgColor ? {
+				'background-color': `rgb(${ this.file.properties.avgColor.join(',') })`
 			} : {};
 		}
 	},
@@ -96,7 +96,7 @@ export default Vue.extend({
 			const name = window.prompt('名前を変更', this.file.name);
 			if (name == null || name == '' || name == this.file.name) return;
 			(this as any).api('drive/files/update', {
-				file_id: this.file.id,
+				fileId: this.file.id,
 				name: name
 			}).then(() => {
 				this.browser.cf(this.file, true);
@@ -105,15 +105,15 @@ export default Vue.extend({
 		move() {
 			(this as any).apis.chooseDriveFolder().then(folder => {
 				(this as any).api('drive/files/update', {
-					file_id: this.file.id,
-					folder_id: folder == null ? null : folder.id
+					fileId: this.file.id,
+					folderId: folder == null ? null : folder.id
 				}).then(() => {
 					this.browser.cf(this.file, true);
 				});
 			});
 		},
 		showCreatedAt() {
-			alert(new Date(this.file.created_at).toLocaleString());
+			alert(new Date(this.file.createdAt).toLocaleString());
 		},
 		onImageLoaded() {
 			const self = this;
diff --git a/src/server/web/app/mobile/views/components/drive.file.vue b/src/server/web/app/mobile/views/components/drive.file.vue
index db7381628..7d1957042 100644
--- a/src/server/web/app/mobile/views/components/drive.file.vue
+++ b/src/server/web/app/mobile/views/components/drive.file.vue
@@ -19,7 +19,7 @@
 				<p class="data-size">{{ file.datasize | bytes }}</p>
 				<p class="separator"></p>
 				<p class="created-at">
-					%fa:R clock%<mk-time :time="file.created_at"/>
+					%fa:R clock%<mk-time :time="file.createdAt"/>
 				</p>
 			</footer>
 		</div>
@@ -42,7 +42,7 @@ export default Vue.extend({
 		},
 		thumbnail(): any {
 			return {
-				'background-color': this.file.properties.average_color ? `rgb(${this.file.properties.average_color.join(',')})` : 'transparent',
+				'background-color': this.file.properties.avgColor ? `rgb(${this.file.properties.avgColor.join(',')})` : 'transparent',
 				'background-image': `url(${this.file.url}?thumbnail&size=128)`
 			};
 		}
diff --git a/src/server/web/app/mobile/views/components/drive.vue b/src/server/web/app/mobile/views/components/drive.vue
index 696c63e2a..ff5366a0a 100644
--- a/src/server/web/app/mobile/views/components/drive.vue
+++ b/src/server/web/app/mobile/views/components/drive.vue
@@ -19,10 +19,10 @@
 	<div class="browser" :class="{ fetching }" v-if="file == null">
 		<div class="info" v-if="info">
 			<p v-if="folder == null">{{ (info.usage / info.capacity * 100).toFixed(1) }}% %i18n:mobile.tags.mk-drive.used%</p>
-			<p v-if="folder != null && (folder.folders_count > 0 || folder.files_count > 0)">
-				<template v-if="folder.folders_count > 0">{{ folder.folders_count }} %i18n:mobile.tags.mk-drive.folder-count%</template>
-				<template v-if="folder.folders_count > 0 && folder.files_count > 0">%i18n:mobile.tags.mk-drive.count-separator%</template>
-				<template v-if="folder.files_count > 0">{{ folder.files_count }} %i18n:mobile.tags.mk-drive.file-count%</template>
+			<p v-if="folder != null && (folder.foldersCount > 0 || folder.filesCount > 0)">
+				<template v-if="folder.foldersCount > 0">{{ folder.foldersCount }} %i18n:mobile.tags.mk-drive.folder-count%</template>
+				<template v-if="folder.foldersCount > 0 && folder.filesCount > 0">%i18n:mobile.tags.mk-drive.count-separator%</template>
+				<template v-if="folder.filesCount > 0">{{ folder.filesCount }} %i18n:mobile.tags.mk-drive.file-count%</template>
 			</p>
 		</div>
 		<div class="folders" v-if="folders.length > 0">
@@ -129,7 +129,7 @@ export default Vue.extend({
 
 		onStreamDriveFileUpdated(file) {
 			const current = this.folder ? this.folder.id : null;
-			if (current != file.folder_id) {
+			if (current != file.folderId) {
 				this.removeFile(file);
 			} else {
 				this.addFile(file, true);
@@ -142,7 +142,7 @@ export default Vue.extend({
 
 		onStreamDriveFolderUpdated(folder) {
 			const current = this.folder ? this.folder.id : null;
-			if (current != folder.parent_id) {
+			if (current != folder.parentId) {
 				this.removeFolder(folder);
 			} else {
 				this.addFolder(folder, true);
@@ -167,7 +167,7 @@ export default Vue.extend({
 			this.fetching = true;
 
 			(this as any).api('drive/folders/show', {
-				folder_id: target
+				folderId: target
 			}).then(folder => {
 				this.folder = folder;
 				this.hierarchyFolders = [];
@@ -182,7 +182,7 @@ export default Vue.extend({
 		addFolder(folder, unshift = false) {
 			const current = this.folder ? this.folder.id : null;
 			// 追加しようとしているフォルダが、今居る階層とは違う階層のものだったら中断
-			if (current != folder.parent_id) return;
+			if (current != folder.parentId) return;
 
 			// 追加しようとしているフォルダを既に所有してたら中断
 			if (this.folders.some(f => f.id == folder.id)) return;
@@ -197,7 +197,7 @@ export default Vue.extend({
 		addFile(file, unshift = false) {
 			const current = this.folder ? this.folder.id : null;
 			// 追加しようとしているファイルが、今居る階層とは違う階層のものだったら中断
-			if (current != file.folder_id) return;
+			if (current != file.folderId) return;
 
 			if (this.files.some(f => f.id == file.id)) {
 				const exist = this.files.map(f => f.id).indexOf(file.id);
@@ -262,7 +262,7 @@ export default Vue.extend({
 
 			// フォルダ一覧取得
 			(this as any).api('drive/folders', {
-				folder_id: this.folder ? this.folder.id : null,
+				folderId: this.folder ? this.folder.id : null,
 				limit: foldersMax + 1
 			}).then(folders => {
 				if (folders.length == foldersMax + 1) {
@@ -275,7 +275,7 @@ export default Vue.extend({
 
 			// ファイル一覧取得
 			(this as any).api('drive/files', {
-				folder_id: this.folder ? this.folder.id : null,
+				folderId: this.folder ? this.folder.id : null,
 				limit: filesMax + 1
 			}).then(files => {
 				if (files.length == filesMax + 1) {
@@ -318,9 +318,9 @@ export default Vue.extend({
 
 			// ファイル一覧取得
 			(this as any).api('drive/files', {
-				folder_id: this.folder ? this.folder.id : null,
+				folderId: this.folder ? this.folder.id : null,
 				limit: max + 1,
-				until_id: this.files[this.files.length - 1].id
+				untilId: this.files[this.files.length - 1].id
 			}).then(files => {
 				if (files.length == max + 1) {
 					this.moreFiles = true;
@@ -357,7 +357,7 @@ export default Vue.extend({
 			this.fetching = true;
 
 			(this as any).api('drive/files/show', {
-				file_id: file
+				fileId: file
 			}).then(file => {
 				this.file = file;
 				this.folder = null;
@@ -405,7 +405,7 @@ export default Vue.extend({
 			if (name == null || name == '') return;
 			(this as any).api('drive/folders/create', {
 				name: name,
-				parent_id: this.folder ? this.folder.id : undefined
+				parentId: this.folder ? this.folder.id : undefined
 			}).then(folder => {
 				this.addFolder(folder, true);
 			});
@@ -420,7 +420,7 @@ export default Vue.extend({
 			if (name == null || name == '') return;
 			(this as any).api('drive/folders/update', {
 				name: name,
-				folder_id: this.folder.id
+				folderId: this.folder.id
 			}).then(folder => {
 				this.cd(folder);
 			});
@@ -433,8 +433,8 @@ export default Vue.extend({
 			}
 			(this as any).apis.chooseDriveFolder().then(folder => {
 				(this as any).api('drive/folders/update', {
-					parent_id: folder ? folder.id : null,
-					folder_id: this.folder.id
+					parentId: folder ? folder.id : null,
+					folderId: this.folder.id
 				}).then(folder => {
 					this.cd(folder);
 				});
@@ -446,7 +446,7 @@ export default Vue.extend({
 			if (url == null || url == '') return;
 			(this as any).api('drive/files/upload_from_url', {
 				url: url,
-				folder_id: this.folder ? this.folder.id : undefined
+				folderId: this.folder ? this.folder.id : undefined
 			});
 			alert('アップロードをリクエストしました。アップロードが完了するまで時間がかかる場合があります。');
 		},
diff --git a/src/server/web/app/mobile/views/components/follow-button.vue b/src/server/web/app/mobile/views/components/follow-button.vue
index fb6eaa39c..43c69d4e0 100644
--- a/src/server/web/app/mobile/views/components/follow-button.vue
+++ b/src/server/web/app/mobile/views/components/follow-button.vue
@@ -1,13 +1,13 @@
 <template>
 <button class="mk-follow-button"
-	:class="{ wait: wait, follow: !user.is_following, unfollow: user.is_following }"
+	:class="{ wait: wait, follow: !user.isFollowing, unfollow: user.isFollowing }"
 	@click="onClick"
 	:disabled="wait"
 >
-	<template v-if="!wait && user.is_following">%fa:minus%</template>
-	<template v-if="!wait && !user.is_following">%fa:plus%</template>
+	<template v-if="!wait && user.isFollowing">%fa:minus%</template>
+	<template v-if="!wait && !user.isFollowing">%fa:plus%</template>
 	<template v-if="wait">%fa:spinner .pulse .fw%</template>
-	{{ user.is_following ? '%i18n:mobile.tags.mk-follow-button.unfollow%' : '%i18n:mobile.tags.mk-follow-button.follow%' }}
+	{{ user.isFollowing ? '%i18n:mobile.tags.mk-follow-button.unfollow%' : '%i18n:mobile.tags.mk-follow-button.follow%' }}
 </button>
 </template>
 
@@ -43,23 +43,23 @@ export default Vue.extend({
 
 		onFollow(user) {
 			if (user.id == this.user.id) {
-				this.user.is_following = user.is_following;
+				this.user.isFollowing = user.isFollowing;
 			}
 		},
 
 		onUnfollow(user) {
 			if (user.id == this.user.id) {
-				this.user.is_following = user.is_following;
+				this.user.isFollowing = user.isFollowing;
 			}
 		},
 
 		onClick() {
 			this.wait = true;
-			if (this.user.is_following) {
+			if (this.user.isFollowing) {
 				(this as any).api('following/delete', {
-					user_id: this.user.id
+					userId: this.user.id
 				}).then(() => {
-					this.user.is_following = false;
+					this.user.isFollowing = false;
 				}).catch(err => {
 					console.error(err);
 				}).then(() => {
@@ -67,9 +67,9 @@ export default Vue.extend({
 				});
 			} else {
 				(this as any).api('following/create', {
-					user_id: this.user.id
+					userId: this.user.id
 				}).then(() => {
-					this.user.is_following = true;
+					this.user.isFollowing = true;
 				}).catch(err => {
 					console.error(err);
 				}).then(() => {
diff --git a/src/server/web/app/mobile/views/components/media-image.vue b/src/server/web/app/mobile/views/components/media-image.vue
index faf8bad48..cfc213498 100644
--- a/src/server/web/app/mobile/views/components/media-image.vue
+++ b/src/server/web/app/mobile/views/components/media-image.vue
@@ -10,7 +10,7 @@ export default Vue.extend({
 	computed: {
 		style(): any {
 			return {
-				'background-color': this.image.properties.average_color ? `rgb(${this.image.properties.average_color.join(',')})` : 'transparent',
+				'background-color': this.image.properties.avgColor ? `rgb(${this.image.properties.avgColor.join(',')})` : 'transparent',
 				'background-image': `url(${this.image.url}?thumbnail&size=512)`
 			};
 		}
diff --git a/src/server/web/app/mobile/views/components/notification-preview.vue b/src/server/web/app/mobile/views/components/notification-preview.vue
index 47df626fa..fce9ed82f 100644
--- a/src/server/web/app/mobile/views/components/notification-preview.vue
+++ b/src/server/web/app/mobile/views/components/notification-preview.vue
@@ -1,7 +1,7 @@
 <template>
 <div class="mk-notification-preview" :class="notification.type">
 	<template v-if="notification.type == 'reaction'">
-		<img class="avatar" :src="`${notification.user.avatar_url}?thumbnail&size=64`" alt="avatar"/>
+		<img class="avatar" :src="`${notification.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
 		<div class="text">
 			<p><mk-reaction-icon :reaction="notification.reaction"/>{{ notification.user.name }}</p>
 			<p class="post-ref">%fa:quote-left%{{ getPostSummary(notification.post) }}%fa:quote-right%</p>
@@ -9,7 +9,7 @@
 	</template>
 
 	<template v-if="notification.type == 'repost'">
-		<img class="avatar" :src="`${notification.post.user.avatar_url}?thumbnail&size=64`" alt="avatar"/>
+		<img class="avatar" :src="`${notification.post.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
 		<div class="text">
 			<p>%fa:retweet%{{ notification.post.user.name }}</p>
 			<p class="post-ref">%fa:quote-left%{{ getPostSummary(notification.post.repost) }}%fa:quote-right%</p>
@@ -17,7 +17,7 @@
 	</template>
 
 	<template v-if="notification.type == 'quote'">
-		<img class="avatar" :src="`${notification.post.user.avatar_url}?thumbnail&size=64`" alt="avatar"/>
+		<img class="avatar" :src="`${notification.post.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
 		<div class="text">
 			<p>%fa:quote-left%{{ notification.post.user.name }}</p>
 			<p class="post-preview">{{ getPostSummary(notification.post) }}</p>
@@ -25,14 +25,14 @@
 	</template>
 
 	<template v-if="notification.type == 'follow'">
-		<img class="avatar" :src="`${notification.user.avatar_url}?thumbnail&size=64`" alt="avatar"/>
+		<img class="avatar" :src="`${notification.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
 		<div class="text">
 			<p>%fa:user-plus%{{ notification.user.name }}</p>
 		</div>
 	</template>
 
 	<template v-if="notification.type == 'reply'">
-		<img class="avatar" :src="`${notification.post.user.avatar_url}?thumbnail&size=64`" alt="avatar"/>
+		<img class="avatar" :src="`${notification.post.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
 		<div class="text">
 			<p>%fa:reply%{{ notification.post.user.name }}</p>
 			<p class="post-preview">{{ getPostSummary(notification.post) }}</p>
@@ -40,7 +40,7 @@
 	</template>
 
 	<template v-if="notification.type == 'mention'">
-		<img class="avatar" :src="`${notification.post.user.avatar_url}?thumbnail&size=64`" alt="avatar"/>
+		<img class="avatar" :src="`${notification.post.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
 		<div class="text">
 			<p>%fa:at%{{ notification.post.user.name }}</p>
 			<p class="post-preview">{{ getPostSummary(notification.post) }}</p>
@@ -48,7 +48,7 @@
 	</template>
 
 	<template v-if="notification.type == 'poll_vote'">
-		<img class="avatar" :src="`${notification.user.avatar_url}?thumbnail&size=64`" alt="avatar"/>
+		<img class="avatar" :src="`${notification.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
 		<div class="text">
 			<p>%fa:chart-pie%{{ notification.user.name }}</p>
 			<p class="post-ref">%fa:quote-left%{{ getPostSummary(notification.post) }}%fa:quote-right%</p>
diff --git a/src/server/web/app/mobile/views/components/notification.vue b/src/server/web/app/mobile/views/components/notification.vue
index 150ac0fd8..e221fb3ac 100644
--- a/src/server/web/app/mobile/views/components/notification.vue
+++ b/src/server/web/app/mobile/views/components/notification.vue
@@ -1,9 +1,9 @@
 <template>
 <div class="mk-notification">
 	<div class="notification reaction" v-if="notification.type == 'reaction'">
-		<mk-time :time="notification.created_at"/>
+		<mk-time :time="notification.createdAt"/>
 		<router-link class="avatar-anchor" :to="`/@${acct}`">
-			<img class="avatar" :src="`${notification.user.avatar_url}?thumbnail&size=64`" alt="avatar"/>
+			<img class="avatar" :src="`${notification.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
 		</router-link>
 		<div class="text">
 			<p>
@@ -18,9 +18,9 @@
 	</div>
 
 	<div class="notification repost" v-if="notification.type == 'repost'">
-		<mk-time :time="notification.created_at"/>
+		<mk-time :time="notification.createdAt"/>
 		<router-link class="avatar-anchor" :to="`/@${acct}`">
-			<img class="avatar" :src="`${notification.post.user.avatar_url}?thumbnail&size=64`" alt="avatar"/>
+			<img class="avatar" :src="`${notification.post.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
 		</router-link>
 		<div class="text">
 			<p>
@@ -38,9 +38,9 @@
 	</template>
 
 	<div class="notification follow" v-if="notification.type == 'follow'">
-		<mk-time :time="notification.created_at"/>
+		<mk-time :time="notification.createdAt"/>
 		<router-link class="avatar-anchor" :to="`/@${acct}`">
-			<img class="avatar" :src="`${notification.user.avatar_url}?thumbnail&size=64`" alt="avatar"/>
+			<img class="avatar" :src="`${notification.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
 		</router-link>
 		<div class="text">
 			<p>
@@ -59,9 +59,9 @@
 	</template>
 
 	<div class="notification poll_vote" v-if="notification.type == 'poll_vote'">
-		<mk-time :time="notification.created_at"/>
+		<mk-time :time="notification.createdAt"/>
 		<router-link class="avatar-anchor" :to="`/@${acct}`">
-			<img class="avatar" :src="`${notification.user.avatar_url}?thumbnail&size=64`" alt="avatar"/>
+			<img class="avatar" :src="`${notification.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
 		</router-link>
 		<div class="text">
 			<p>
diff --git a/src/server/web/app/mobile/views/components/notifications.vue b/src/server/web/app/mobile/views/components/notifications.vue
index 1cd6e2bc1..d68b990df 100644
--- a/src/server/web/app/mobile/views/components/notifications.vue
+++ b/src/server/web/app/mobile/views/components/notifications.vue
@@ -34,8 +34,8 @@ export default Vue.extend({
 	computed: {
 		_notifications(): any[] {
 			return (this.notifications as any).map(notification => {
-				const date = new Date(notification.created_at).getDate();
-				const month = new Date(notification.created_at).getMonth() + 1;
+				const date = new Date(notification.createdAt).getDate();
+				const month = new Date(notification.createdAt).getMonth() + 1;
 				notification._date = date;
 				notification._datetext = `${month}月 ${date}日`;
 				return notification;
@@ -75,7 +75,7 @@ export default Vue.extend({
 
 			(this as any).api('i/notifications', {
 				limit: max + 1,
-				until_id: this.notifications[this.notifications.length - 1].id
+				untilId: this.notifications[this.notifications.length - 1].id
 			}).then(notifications => {
 				if (notifications.length == max + 1) {
 					this.moreNotifications = true;
diff --git a/src/server/web/app/mobile/views/components/post-card.vue b/src/server/web/app/mobile/views/components/post-card.vue
index 8ca7550c2..10dfd9241 100644
--- a/src/server/web/app/mobile/views/components/post-card.vue
+++ b/src/server/web/app/mobile/views/components/post-card.vue
@@ -7,7 +7,7 @@
 		<div>
 			{{ text }}
 		</div>
-		<mk-time :time="post.created_at"/>
+		<mk-time :time="post.createdAt"/>
 	</a>
 </div>
 </template>
diff --git a/src/server/web/app/mobile/views/components/post-detail.sub.vue b/src/server/web/app/mobile/views/components/post-detail.sub.vue
index 6906cf570..db7567834 100644
--- a/src/server/web/app/mobile/views/components/post-detail.sub.vue
+++ b/src/server/web/app/mobile/views/components/post-detail.sub.vue
@@ -1,14 +1,14 @@
 <template>
 <div class="root sub">
 	<router-link class="avatar-anchor" :to="`/@${acct}`">
-		<img class="avatar" :src="`${post.user.avatar_url}?thumbnail&size=64`" alt="avatar"/>
+		<img class="avatar" :src="`${post.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
 	</router-link>
 	<div class="main">
 		<header>
 			<router-link class="name" :to="`/@${acct}`">{{ post.user.name }}</router-link>
 			<span class="username">@{{ acct }}</span>
 			<router-link class="time" :to="`/@${acct}/${post.id}`">
-				<mk-time :time="post.created_at"/>
+				<mk-time :time="post.createdAt"/>
 			</router-link>
 		</header>
 		<div class="body">
diff --git a/src/server/web/app/mobile/views/components/post-detail.vue b/src/server/web/app/mobile/views/components/post-detail.vue
index b5c915830..29993c79e 100644
--- a/src/server/web/app/mobile/views/components/post-detail.vue
+++ b/src/server/web/app/mobile/views/components/post-detail.vue
@@ -2,7 +2,7 @@
 <div class="mk-post-detail">
 	<button
 		class="more"
-		v-if="p.reply && p.reply.reply_id && context == null"
+		v-if="p.reply && p.reply.replyId && context == null"
 		@click="fetchContext"
 		:disabled="fetchingContext"
 	>
@@ -18,7 +18,7 @@
 	<div class="repost" v-if="isRepost">
 		<p>
 			<router-link class="avatar-anchor" :to="`/@${acct}`">
-				<img class="avatar" :src="`${post.user.avatar_url}?thumbnail&size=32`" alt="avatar"/>
+				<img class="avatar" :src="`${post.user.avatarUrl}?thumbnail&size=32`" alt="avatar"/>
 			</router-link>
 			%fa:retweet%
 			<router-link class="name" :to="`/@${acct}`">
@@ -30,7 +30,7 @@
 	<article>
 		<header>
 			<router-link class="avatar-anchor" :to="`/@${pAcct}`">
-				<img class="avatar" :src="`${p.user.avatar_url}?thumbnail&size=64`" alt="avatar"/>
+				<img class="avatar" :src="`${p.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
 			</router-link>
 			<div>
 				<router-link class="name" :to="`/@${pAcct}`">{{ p.user.name }}</router-link>
@@ -54,17 +54,17 @@
 			</div>
 		</div>
 		<router-link class="time" :to="`/@${pAcct}/${p.id}`">
-			<mk-time :time="p.created_at" mode="detail"/>
+			<mk-time :time="p.createdAt" mode="detail"/>
 		</router-link>
 		<footer>
 			<mk-reactions-viewer :post="p"/>
 			<button @click="reply" title="%i18n:mobile.tags.mk-post-detail.reply%">
-				%fa:reply%<p class="count" v-if="p.replies_count > 0">{{ p.replies_count }}</p>
+				%fa:reply%<p class="count" v-if="p.repliesCount > 0">{{ p.repliesCount }}</p>
 			</button>
 			<button @click="repost" title="Repost">
-				%fa:retweet%<p class="count" v-if="p.repost_count > 0">{{ p.repost_count }}</p>
+				%fa:retweet%<p class="count" v-if="p.repostCount > 0">{{ p.repostCount }}</p>
 			</button>
-			<button :class="{ reacted: p.my_reaction != null }" @click="react" ref="reactButton" title="%i18n:mobile.tags.mk-post-detail.reaction%">
+			<button :class="{ reacted: p.myReaction != null }" @click="react" ref="reactButton" title="%i18n:mobile.tags.mk-post-detail.reaction%">
 				%fa:plus%<p class="count" v-if="p.reactions_count > 0">{{ p.reactions_count }}</p>
 			</button>
 			<button @click="menu" ref="menuButton">
@@ -115,16 +115,16 @@ export default Vue.extend({
 		isRepost(): boolean {
 			return (this.post.repost &&
 				this.post.text == null &&
-				this.post.media_ids == null &&
+				this.post.mediaIds == null &&
 				this.post.poll == null);
 		},
 		p(): any {
 			return this.isRepost ? this.post.repost : this.post;
 		},
 		reactionsCount(): number {
-			return this.p.reaction_counts
-				? Object.keys(this.p.reaction_counts)
-					.map(key => this.p.reaction_counts[key])
+			return this.p.reactionCounts
+				? Object.keys(this.p.reactionCounts)
+					.map(key => this.p.reactionCounts[key])
 					.reduce((a, b) => a + b)
 				: 0;
 		},
@@ -142,7 +142,7 @@ export default Vue.extend({
 		// Get replies
 		if (!this.compact) {
 			(this as any).api('posts/replies', {
-				post_id: this.p.id,
+				postId: this.p.id,
 				limit: 8
 			}).then(replies => {
 				this.replies = replies;
@@ -151,7 +151,7 @@ export default Vue.extend({
 
 		// Draw map
 		if (this.p.geo) {
-			const shouldShowMap = (this as any).os.isSignedIn ? (this as any).os.i.account.client_settings.showMaps : true;
+			const shouldShowMap = (this as any).os.isSignedIn ? (this as any).os.i.account.clientSettings.showMaps : true;
 			if (shouldShowMap) {
 				(this as any).os.getGoogleMaps().then(maps => {
 					const uluru = new maps.LatLng(this.p.geo.latitude, this.p.geo.longitude);
@@ -173,7 +173,7 @@ export default Vue.extend({
 
 			// Fetch context
 			(this as any).api('posts/context', {
-				post_id: this.p.reply_id
+				postId: this.p.replyId
 			}).then(context => {
 				this.contextFetching = false;
 				this.context = context.reverse();
diff --git a/src/server/web/app/mobile/views/components/post-form.vue b/src/server/web/app/mobile/views/components/post-form.vue
index 2aa3c6f6c..929dc5933 100644
--- a/src/server/web/app/mobile/views/components/post-form.vue
+++ b/src/server/web/app/mobile/views/components/post-form.vue
@@ -111,11 +111,11 @@ export default Vue.extend({
 		},
 		post() {
 			this.posting = true;
-			const viaMobile = (this as any).os.i.account.client_settings.disableViaMobile !== true;
+			const viaMobile = (this as any).os.i.account.clientSettings.disableViaMobile !== true;
 			(this as any).api('posts/create', {
 				text: this.text == '' ? undefined : this.text,
-				media_ids: this.files.length > 0 ? this.files.map(f => f.id) : undefined,
-				reply_id: this.reply ? this.reply.id : undefined,
+				mediaIds: this.files.length > 0 ? this.files.map(f => f.id) : undefined,
+				replyId: this.reply ? this.reply.id : undefined,
 				poll: this.poll ? (this.$refs.poll as any).get() : undefined,
 				geo: this.geo ? {
 					latitude: this.geo.latitude,
@@ -126,7 +126,7 @@ export default Vue.extend({
 					heading: isNaN(this.geo.heading) ? null : this.geo.heading,
 					speed: this.geo.speed,
 				} : null,
-				via_mobile: viaMobile
+				viaMobile: viaMobile
 			}).then(data => {
 				this.$emit('post');
 				this.$destroy();
diff --git a/src/server/web/app/mobile/views/components/post-preview.vue b/src/server/web/app/mobile/views/components/post-preview.vue
index 0bd0a355b..a6141dc8e 100644
--- a/src/server/web/app/mobile/views/components/post-preview.vue
+++ b/src/server/web/app/mobile/views/components/post-preview.vue
@@ -1,14 +1,14 @@
 <template>
 <div class="mk-post-preview">
 	<router-link class="avatar-anchor" :to="`/@${acct}`">
-		<img class="avatar" :src="`${post.user.avatar_url}?thumbnail&size=64`" alt="avatar"/>
+		<img class="avatar" :src="`${post.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
 	</router-link>
 	<div class="main">
 		<header>
 			<router-link class="name" :to="`/@${acct}`">{{ post.user.name }}</router-link>
 			<span class="username">@{{ acct }}</span>
 			<router-link class="time" :to="`/@${acct}/${post.id}`">
-				<mk-time :time="post.created_at"/>
+				<mk-time :time="post.createdAt"/>
 			</router-link>
 		</header>
 		<div class="body">
diff --git a/src/server/web/app/mobile/views/components/post.sub.vue b/src/server/web/app/mobile/views/components/post.sub.vue
index b6ee7c1e0..adf444a2d 100644
--- a/src/server/web/app/mobile/views/components/post.sub.vue
+++ b/src/server/web/app/mobile/views/components/post.sub.vue
@@ -1,14 +1,14 @@
 <template>
 <div class="sub">
 	<router-link class="avatar-anchor" :to="`/@${acct}`">
-		<img class="avatar" :src="`${post.user.avatar_url}?thumbnail&size=96`" alt="avatar"/>
+		<img class="avatar" :src="`${post.user.avatarUrl}?thumbnail&size=96`" alt="avatar"/>
 	</router-link>
 	<div class="main">
 		<header>
 			<router-link class="name" :to="`/@${acct}`">{{ post.user.name }}</router-link>
 			<span class="username">@{{ acct }}</span>
 			<router-link class="created-at" :to="`/@${acct}/${post.id}`">
-				<mk-time :time="post.created_at"/>
+				<mk-time :time="post.createdAt"/>
 			</router-link>
 		</header>
 		<div class="body">
diff --git a/src/server/web/app/mobile/views/components/post.vue b/src/server/web/app/mobile/views/components/post.vue
index e5bc96479..66c595f4e 100644
--- a/src/server/web/app/mobile/views/components/post.vue
+++ b/src/server/web/app/mobile/views/components/post.vue
@@ -6,28 +6,28 @@
 	<div class="repost" v-if="isRepost">
 		<p>
 			<router-link class="avatar-anchor" :to="`/@${acct}`">
-				<img class="avatar" :src="`${post.user.avatar_url}?thumbnail&size=64`" alt="avatar"/>
+				<img class="avatar" :src="`${post.user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
 			</router-link>
 			%fa:retweet%
 			<span>{{ '%i18n:mobile.tags.mk-timeline-post.reposted-by%'.substr(0, '%i18n:mobile.tags.mk-timeline-post.reposted-by%'.indexOf('{')) }}</span>
 			<router-link class="name" :to="`/@${acct}`">{{ post.user.name }}</router-link>
 			<span>{{ '%i18n:mobile.tags.mk-timeline-post.reposted-by%'.substr('%i18n:mobile.tags.mk-timeline-post.reposted-by%'.indexOf('}') + 1) }}</span>
 		</p>
-		<mk-time :time="post.created_at"/>
+		<mk-time :time="post.createdAt"/>
 	</div>
 	<article>
 		<router-link class="avatar-anchor" :to="`/@${pAcct}`">
-			<img class="avatar" :src="`${p.user.avatar_url}?thumbnail&size=96`" alt="avatar"/>
+			<img class="avatar" :src="`${p.user.avatarUrl}?thumbnail&size=96`" alt="avatar"/>
 		</router-link>
 		<div class="main">
 			<header>
 				<router-link class="name" :to="`/@${pAcct}`">{{ p.user.name }}</router-link>
-				<span class="is-bot" v-if="p.user.host === null && p.user.account.is_bot">bot</span>
+				<span class="is-bot" v-if="p.user.host === null && p.user.account.isBot">bot</span>
 				<span class="username">@{{ pAcct }}</span>
 				<div class="info">
-					<span class="mobile" v-if="p.via_mobile">%fa:mobile-alt%</span>
+					<span class="mobile" v-if="p.viaMobile">%fa:mobile-alt%</span>
 					<router-link class="created-at" :to="url">
-						<mk-time :time="p.created_at"/>
+						<mk-time :time="p.createdAt"/>
 					</router-link>
 				</div>
 			</header>
@@ -58,12 +58,12 @@
 			<footer>
 				<mk-reactions-viewer :post="p" ref="reactionsViewer"/>
 				<button @click="reply">
-					%fa:reply%<p class="count" v-if="p.replies_count > 0">{{ p.replies_count }}</p>
+					%fa:reply%<p class="count" v-if="p.repliesCount > 0">{{ p.repliesCount }}</p>
 				</button>
 				<button @click="repost" title="Repost">
-					%fa:retweet%<p class="count" v-if="p.repost_count > 0">{{ p.repost_count }}</p>
+					%fa:retweet%<p class="count" v-if="p.repostCount > 0">{{ p.repostCount }}</p>
 				</button>
-				<button :class="{ reacted: p.my_reaction != null }" @click="react" ref="reactButton">
+				<button :class="{ reacted: p.myReaction != null }" @click="react" ref="reactButton">
 					%fa:plus%<p class="count" v-if="p.reactions_count > 0">{{ p.reactions_count }}</p>
 				</button>
 				<button class="menu" @click="menu" ref="menuButton">
@@ -103,16 +103,16 @@ export default Vue.extend({
 		isRepost(): boolean {
 			return (this.post.repost &&
 				this.post.text == null &&
-				this.post.media_ids == null &&
+				this.post.mediaIds == null &&
 				this.post.poll == null);
 		},
 		p(): any {
 			return this.isRepost ? this.post.repost : this.post;
 		},
 		reactionsCount(): number {
-			return this.p.reaction_counts
-				? Object.keys(this.p.reaction_counts)
-					.map(key => this.p.reaction_counts[key])
+			return this.p.reactionCounts
+				? Object.keys(this.p.reactionCounts)
+					.map(key => this.p.reactionCounts[key])
 					.reduce((a, b) => a + b)
 				: 0;
 		},
@@ -144,7 +144,7 @@ export default Vue.extend({
 
 		// Draw map
 		if (this.p.geo) {
-			const shouldShowMap = (this as any).os.isSignedIn ? (this as any).os.i.account.client_settings.showMaps : true;
+			const shouldShowMap = (this as any).os.isSignedIn ? (this as any).os.i.account.clientSettings.showMaps : true;
 			if (shouldShowMap) {
 				(this as any).os.getGoogleMaps().then(maps => {
 					const uluru = new maps.LatLng(this.p.geo.latitude, this.p.geo.longitude);
@@ -194,7 +194,7 @@ export default Vue.extend({
 			const post = data.post;
 			if (post.id == this.post.id) {
 				this.$emit('update:post', post);
-			} else if (post.id == this.post.repost_id) {
+			} else if (post.id == this.post.repostId) {
 				this.post.repost = post;
 			}
 		},
diff --git a/src/server/web/app/mobile/views/components/posts.vue b/src/server/web/app/mobile/views/components/posts.vue
index 7e71fa098..4695f1bea 100644
--- a/src/server/web/app/mobile/views/components/posts.vue
+++ b/src/server/web/app/mobile/views/components/posts.vue
@@ -28,8 +28,8 @@ export default Vue.extend({
 	computed: {
 		_posts(): any[] {
 			return (this.posts as any).map(post => {
-				const date = new Date(post.created_at).getDate();
-				const month = new Date(post.created_at).getMonth() + 1;
+				const date = new Date(post.createdAt).getDate();
+				const month = new Date(post.createdAt).getMonth() + 1;
 				post._date = date;
 				post._datetext = `${month}月 ${date}日`;
 				return post;
diff --git a/src/server/web/app/mobile/views/components/sub-post-content.vue b/src/server/web/app/mobile/views/components/sub-post-content.vue
index 389fc420e..b95883de7 100644
--- a/src/server/web/app/mobile/views/components/sub-post-content.vue
+++ b/src/server/web/app/mobile/views/components/sub-post-content.vue
@@ -1,9 +1,9 @@
 <template>
 <div class="mk-sub-post-content">
 	<div class="body">
-		<a class="reply" v-if="post.reply_id">%fa:reply%</a>
+		<a class="reply" v-if="post.replyId">%fa:reply%</a>
 		<mk-post-html v-if="post.ast" :ast="post.ast" :i="os.i"/>
-		<a class="rp" v-if="post.repost_id">RP: ...</a>
+		<a class="rp" v-if="post.repostId">RP: ...</a>
 	</div>
 	<details v-if="post.media">
 		<summary>({{ post.media.length }}個のメディア)</summary>
diff --git a/src/server/web/app/mobile/views/components/timeline.vue b/src/server/web/app/mobile/views/components/timeline.vue
index c0e766523..7b5948faf 100644
--- a/src/server/web/app/mobile/views/components/timeline.vue
+++ b/src/server/web/app/mobile/views/components/timeline.vue
@@ -41,7 +41,7 @@ export default Vue.extend({
 	},
 	computed: {
 		alone(): boolean {
-			return (this as any).os.i.following_count == 0;
+			return (this as any).os.i.followingCount == 0;
 		}
 	},
 	mounted() {
@@ -65,7 +65,7 @@ export default Vue.extend({
 			this.fetching = true;
 			(this as any).api('posts/timeline', {
 				limit: limit + 1,
-				until_date: this.date ? (this.date as any).getTime() : undefined
+				untilDate: this.date ? (this.date as any).getTime() : undefined
 			}).then(posts => {
 				if (posts.length == limit + 1) {
 					posts.pop();
@@ -81,7 +81,7 @@ export default Vue.extend({
 			this.moreFetching = true;
 			(this as any).api('posts/timeline', {
 				limit: limit + 1,
-				until_id: this.posts[this.posts.length - 1].id
+				untilId: this.posts[this.posts.length - 1].id
 			}).then(posts => {
 				if (posts.length == limit + 1) {
 					posts.pop();
diff --git a/src/server/web/app/mobile/views/components/ui.header.vue b/src/server/web/app/mobile/views/components/ui.header.vue
index 66e10a0f8..2bf47a90a 100644
--- a/src/server/web/app/mobile/views/components/ui.header.vue
+++ b/src/server/web/app/mobile/views/components/ui.header.vue
@@ -57,9 +57,9 @@ export default Vue.extend({
 				}
 			});
 
-			const ago = (new Date().getTime() - new Date((this as any).os.i.account.last_used_at).getTime()) / 1000
+			const ago = (new Date().getTime() - new Date((this as any).os.i.account.lastUsedAt).getTime()) / 1000
 			const isHisasiburi = ago >= 3600;
-			(this as any).os.i.account.last_used_at = new Date();
+			(this as any).os.i.account.lastUsedAt = new Date();
 			if (isHisasiburi) {
 				(this.$refs.welcomeback as any).style.display = 'block';
 				(this.$refs.main as any).style.overflow = 'hidden';
diff --git a/src/server/web/app/mobile/views/components/ui.nav.vue b/src/server/web/app/mobile/views/components/ui.nav.vue
index 760a5b518..a923774a7 100644
--- a/src/server/web/app/mobile/views/components/ui.nav.vue
+++ b/src/server/web/app/mobile/views/components/ui.nav.vue
@@ -10,7 +10,7 @@
 	<transition name="nav">
 		<div class="body" v-if="isOpen">
 			<router-link class="me" v-if="os.isSignedIn" :to="`/@${os.i.username}`">
-				<img class="avatar" :src="`${os.i.avatar_url}?thumbnail&size=128`" alt="avatar"/>
+				<img class="avatar" :src="`${os.i.avatarUrl}?thumbnail&size=128`" alt="avatar"/>
 				<p class="name">{{ os.i.name }}</p>
 			</router-link>
 			<div class="links">
diff --git a/src/server/web/app/mobile/views/components/user-card.vue b/src/server/web/app/mobile/views/components/user-card.vue
index 5a7309cfd..ffa110051 100644
--- a/src/server/web/app/mobile/views/components/user-card.vue
+++ b/src/server/web/app/mobile/views/components/user-card.vue
@@ -1,8 +1,8 @@
 <template>
 <div class="mk-user-card">
-	<header :style="user.banner_url ? `background-image: url(${user.banner_url}?thumbnail&size=1024)` : ''">
+	<header :style="user.bannerUrl ? `background-image: url(${user.bannerUrl}?thumbnail&size=1024)` : ''">
 		<a :href="`/@${acct}`">
-			<img :src="`${user.avatar_url}?thumbnail&size=200`" alt="avatar"/>
+			<img :src="`${user.avatarUrl}?thumbnail&size=200`" alt="avatar"/>
 		</a>
 	</header>
 	<a class="name" :href="`/@${acct}`" target="_blank">{{ user.name }}</a>
diff --git a/src/server/web/app/mobile/views/components/user-preview.vue b/src/server/web/app/mobile/views/components/user-preview.vue
index be80582ca..e51e4353d 100644
--- a/src/server/web/app/mobile/views/components/user-preview.vue
+++ b/src/server/web/app/mobile/views/components/user-preview.vue
@@ -1,7 +1,7 @@
 <template>
 <div class="mk-user-preview">
 	<router-link class="avatar-anchor" :to="`/@${acct}`">
-		<img class="avatar" :src="`${user.avatar_url}?thumbnail&size=64`" alt="avatar"/>
+		<img class="avatar" :src="`${user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
 	</router-link>
 	<div class="main">
 		<header>
diff --git a/src/server/web/app/mobile/views/components/user-timeline.vue b/src/server/web/app/mobile/views/components/user-timeline.vue
index 39f959187..bd3e3d0c8 100644
--- a/src/server/web/app/mobile/views/components/user-timeline.vue
+++ b/src/server/web/app/mobile/views/components/user-timeline.vue
@@ -33,8 +33,8 @@ export default Vue.extend({
 	},
 	mounted() {
 		(this as any).api('users/posts', {
-			user_id: this.user.id,
-			with_media: this.withMedia,
+			userId: this.user.id,
+			withMedia: this.withMedia,
 			limit: limit + 1
 		}).then(posts => {
 			if (posts.length == limit + 1) {
@@ -50,10 +50,10 @@ export default Vue.extend({
 		more() {
 			this.moreFetching = true;
 			(this as any).api('users/posts', {
-				user_id: this.user.id,
-				with_media: this.withMedia,
+				userId: this.user.id,
+				withMedia: this.withMedia,
 				limit: limit + 1,
-				until_id: this.posts[this.posts.length - 1].id
+				untilId: this.posts[this.posts.length - 1].id
 			}).then(posts => {
 				if (posts.length == limit + 1) {
 					posts.pop();
diff --git a/src/server/web/app/mobile/views/pages/followers.vue b/src/server/web/app/mobile/views/pages/followers.vue
index 1edf4e38a..8c058eb4e 100644
--- a/src/server/web/app/mobile/views/pages/followers.vue
+++ b/src/server/web/app/mobile/views/pages/followers.vue
@@ -1,14 +1,14 @@
 <template>
 <mk-ui>
 	<template slot="header" v-if="!fetching">
-		<img :src="`${user.avatar_url}?thumbnail&size=64`" alt="">
+		<img :src="`${user.avatarUrl}?thumbnail&size=64`" alt="">
 		{{ '%i18n:mobile.tags.mk-user-followers-page.followers-of%'.replace('{}', user.name) }}
 	</template>
 	<mk-users-list
 		v-if="!fetching"
 		:fetch="fetchUsers"
-		:count="user.followers_count"
-		:you-know-count="user.followers_you_know_count"
+		:count="user.followersCount"
+		:you-know-count="user.followersYouKnowCount"
 		@loaded="onLoaded"
 	>
 		%i18n:mobile.tags.mk-user-followers.no-users%
@@ -54,7 +54,7 @@ export default Vue.extend({
 		},
 		fetchUsers(iknow, limit, cursor, cb) {
 			(this as any).api('users/followers', {
-				user_id: this.user.id,
+				userId: this.user.id,
 				iknow: iknow,
 				limit: limit,
 				cursor: cursor ? cursor : undefined
diff --git a/src/server/web/app/mobile/views/pages/following.vue b/src/server/web/app/mobile/views/pages/following.vue
index 0dd171cce..a73c9d171 100644
--- a/src/server/web/app/mobile/views/pages/following.vue
+++ b/src/server/web/app/mobile/views/pages/following.vue
@@ -1,14 +1,14 @@
 <template>
 <mk-ui>
 	<template slot="header" v-if="!fetching">
-		<img :src="`${user.avatar_url}?thumbnail&size=64`" alt="">
+		<img :src="`${user.avatarUrl}?thumbnail&size=64`" alt="">
 		{{ '%i18n:mobile.tags.mk-user-following-page.following-of%'.replace('{}', user.name) }}
 	</template>
 	<mk-users-list
 		v-if="!fetching"
 		:fetch="fetchUsers"
-		:count="user.following_count"
-		:you-know-count="user.following_you_know_count"
+		:count="user.followingCount"
+		:you-know-count="user.followingYouKnowCount"
 		@loaded="onLoaded"
 	>
 		%i18n:mobile.tags.mk-user-following.no-users%
@@ -54,7 +54,7 @@ export default Vue.extend({
 		},
 		fetchUsers(iknow, limit, cursor, cb) {
 			(this as any).api('users/following', {
-				user_id: this.user.id,
+				userId: this.user.id,
 				iknow: iknow,
 				limit: limit,
 				cursor: cursor ? cursor : undefined
diff --git a/src/server/web/app/mobile/views/pages/home.vue b/src/server/web/app/mobile/views/pages/home.vue
index b110fc409..be9101aa7 100644
--- a/src/server/web/app/mobile/views/pages/home.vue
+++ b/src/server/web/app/mobile/views/pages/home.vue
@@ -82,8 +82,8 @@ export default Vue.extend({
 		};
 	},
 	created() {
-		if ((this as any).os.i.account.client_settings.mobile_home == null) {
-			Vue.set((this as any).os.i.account.client_settings, 'mobile_home', [{
+		if ((this as any).os.i.account.clientSettings.mobile_home == null) {
+			Vue.set((this as any).os.i.account.clientSettings, 'mobile_home', [{
 				name: 'calendar',
 				id: 'a', data: {}
 			}, {
@@ -105,14 +105,14 @@ export default Vue.extend({
 				name: 'version',
 				id: 'g', data: {}
 			}]);
-			this.widgets = (this as any).os.i.account.client_settings.mobile_home;
+			this.widgets = (this as any).os.i.account.clientSettings.mobile_home;
 			this.saveHome();
 		} else {
-			this.widgets = (this as any).os.i.account.client_settings.mobile_home;
+			this.widgets = (this as any).os.i.account.clientSettings.mobile_home;
 		}
 
-		this.$watch('os.i.account.client_settings', i => {
-			this.widgets = (this as any).os.i.account.client_settings.mobile_home;
+		this.$watch('os.i.account.clientSettings', i => {
+			this.widgets = (this as any).os.i.account.clientSettings.mobile_home;
 		}, {
 			deep: true
 		});
@@ -144,7 +144,7 @@ export default Vue.extend({
 			Progress.done();
 		},
 		onStreamPost(post) {
-			if (document.hidden && post.user_id !== (this as any).os.i.id) {
+			if (document.hidden && post.userId !== (this as any).os.i.id) {
 				this.unreadCount++;
 				document.title = `(${this.unreadCount}) ${getPostSummary(post)}`;
 			}
@@ -157,15 +157,15 @@ export default Vue.extend({
 		},
 		onHomeUpdated(data) {
 			if (data.home) {
-				(this as any).os.i.account.client_settings.mobile_home = data.home;
+				(this as any).os.i.account.clientSettings.mobile_home = data.home;
 				this.widgets = data.home;
 			} else {
-				const w = (this as any).os.i.account.client_settings.mobile_home.find(w => w.id == data.id);
+				const w = (this as any).os.i.account.clientSettings.mobile_home.find(w => w.id == data.id);
 				if (w != null) {
 					w.data = data.data;
 					this.$refs[w.id][0].preventSave = true;
 					this.$refs[w.id][0].props = w.data;
-					this.widgets = (this as any).os.i.account.client_settings.mobile_home;
+					this.widgets = (this as any).os.i.account.clientSettings.mobile_home;
 				}
 			}
 		},
@@ -194,7 +194,7 @@ export default Vue.extend({
 			this.saveHome();
 		},
 		saveHome() {
-			(this as any).os.i.account.client_settings.mobile_home = this.widgets;
+			(this as any).os.i.account.clientSettings.mobile_home = this.widgets;
 			(this as any).api('i/update_mobile_home', {
 				home: this.widgets
 			});
diff --git a/src/server/web/app/mobile/views/pages/notifications.vue b/src/server/web/app/mobile/views/pages/notifications.vue
index 3dcfb2f38..6d45e22a9 100644
--- a/src/server/web/app/mobile/views/pages/notifications.vue
+++ b/src/server/web/app/mobile/views/pages/notifications.vue
@@ -22,7 +22,7 @@ export default Vue.extend({
 			const ok = window.confirm('%i18n:mobile.tags.mk-notifications-page.read-all%');
 			if (!ok) return;
 
-			(this as any).api('notifications/mark_as_read_all');
+			(this as any).api('notifications/markAsRead_all');
 		},
 		onFetched() {
 			Progress.done();
diff --git a/src/server/web/app/mobile/views/pages/othello.vue b/src/server/web/app/mobile/views/pages/othello.vue
index b110bf309..e04e583c2 100644
--- a/src/server/web/app/mobile/views/pages/othello.vue
+++ b/src/server/web/app/mobile/views/pages/othello.vue
@@ -34,7 +34,7 @@ export default Vue.extend({
 			this.fetching = true;
 
 			(this as any).api('othello/games/show', {
-				game_id: this.$route.params.game
+				gameId: this.$route.params.game
 			}).then(game => {
 				this.game = game;
 				this.fetching = false;
diff --git a/src/server/web/app/mobile/views/pages/post.vue b/src/server/web/app/mobile/views/pages/post.vue
index 2ed2ebfcf..49a4bfd9d 100644
--- a/src/server/web/app/mobile/views/pages/post.vue
+++ b/src/server/web/app/mobile/views/pages/post.vue
@@ -38,7 +38,7 @@ export default Vue.extend({
 			this.fetching = true;
 
 			(this as any).api('posts/show', {
-				post_id: this.$route.params.post
+				postId: this.$route.params.post
 			}).then(post => {
 				this.post = post;
 				this.fetching = false;
diff --git a/src/server/web/app/mobile/views/pages/profile-setting.vue b/src/server/web/app/mobile/views/pages/profile-setting.vue
index 941165c99..15f9bc9b6 100644
--- a/src/server/web/app/mobile/views/pages/profile-setting.vue
+++ b/src/server/web/app/mobile/views/pages/profile-setting.vue
@@ -4,8 +4,8 @@
 	<div :class="$style.content">
 		<p>%fa:info-circle%%i18n:mobile.tags.mk-profile-setting.will-be-published%</p>
 		<div :class="$style.form">
-			<div :style="os.i.banner_url ? `background-image: url(${os.i.banner_url}?thumbnail&size=1024)` : ''" @click="setBanner">
-				<img :src="`${os.i.avatar_url}?thumbnail&size=200`" alt="avatar" @click="setAvatar"/>
+			<div :style="os.i.bannerUrl ? `background-image: url(${os.i.bannerUrl}?thumbnail&size=1024)` : ''" @click="setBanner">
+				<img :src="`${os.i.avatarUrl}?thumbnail&size=200`" alt="avatar" @click="setAvatar"/>
 			</div>
 			<label>
 				<p>%i18n:mobile.tags.mk-profile-setting.name%</p>
@@ -69,7 +69,7 @@ export default Vue.extend({
 				this.avatarSaving = true;
 
 				(this as any).api('i/update', {
-					avatar_id: file.id
+					avatarId: file.id
 				}).then(() => {
 					this.avatarSaving = false;
 					alert('%i18n:mobile.tags.mk-profile-setting.avatar-saved%');
@@ -83,7 +83,7 @@ export default Vue.extend({
 				this.bannerSaving = true;
 
 				(this as any).api('i/update', {
-					banner_id: file.id
+					bannerId: file.id
 				}).then(() => {
 					this.bannerSaving = false;
 					alert('%i18n:mobile.tags.mk-profile-setting.banner-saved%');
diff --git a/src/server/web/app/mobile/views/pages/settings.vue b/src/server/web/app/mobile/views/pages/settings.vue
index 3250999e1..a945a21c5 100644
--- a/src/server/web/app/mobile/views/pages/settings.vue
+++ b/src/server/web/app/mobile/views/pages/settings.vue
@@ -12,19 +12,20 @@
 		<ul>
 			<li><a @click="signout">%fa:power-off%%i18n:mobile.tags.mk-settings-page.signout%</a></li>
 		</ul>
-		<p><small>ver {{ v }} (葵 aoi)</small></p>
+		<p><small>ver {{ version }} ({{ codename }})</small></p>
 	</div>
 </mk-ui>
 </template>
 
 <script lang="ts">
 import Vue from 'vue';
-import { version } from '../../../config';
+import { version, codename } from '../../../config';
 
 export default Vue.extend({
 	data() {
 		return {
-			v: version
+			version,
+			codename
 		};
 	},
 	mounted() {
diff --git a/src/server/web/app/mobile/views/pages/user.vue b/src/server/web/app/mobile/views/pages/user.vue
index 7ff897e42..114decb8e 100644
--- a/src/server/web/app/mobile/views/pages/user.vue
+++ b/src/server/web/app/mobile/views/pages/user.vue
@@ -3,18 +3,18 @@
 	<span slot="header" v-if="!fetching">%fa:user% {{ user.name }}</span>
 	<main v-if="!fetching">
 		<header>
-			<div class="banner" :style="user.banner_url ? `background-image: url(${user.banner_url}?thumbnail&size=1024)` : ''"></div>
+			<div class="banner" :style="user.bannerUrl ? `background-image: url(${user.bannerUrl}?thumbnail&size=1024)` : ''"></div>
 			<div class="body">
 				<div class="top">
 					<a class="avatar">
-						<img :src="`${user.avatar_url}?thumbnail&size=200`" alt="avatar"/>
+						<img :src="`${user.avatarUrl}?thumbnail&size=200`" alt="avatar"/>
 					</a>
 					<mk-follow-button v-if="os.isSignedIn && os.i.id != user.id" :user="user"/>
 				</div>
 				<div class="title">
 					<h1>{{ user.name }}</h1>
 					<span class="username">@{{ acct }}</span>
-					<span class="followed" v-if="user.is_followed">%i18n:mobile.tags.mk-user.follows-you%</span>
+					<span class="followed" v-if="user.isFollowed">%i18n:mobile.tags.mk-user.follows-you%</span>
 				</div>
 				<div class="description">{{ user.description }}</div>
 				<div class="info">
@@ -27,15 +27,15 @@
 				</div>
 				<div class="status">
 					<a>
-						<b>{{ user.posts_count | number }}</b>
+						<b>{{ user.postsCount | number }}</b>
 						<i>%i18n:mobile.tags.mk-user.posts%</i>
 					</a>
 					<a :href="`@${acct}/following`">
-						<b>{{ user.following_count | number }}</b>
+						<b>{{ user.followingCount | number }}</b>
 						<i>%i18n:mobile.tags.mk-user.following%</i>
 					</a>
 					<a :href="`@${acct}/followers`">
-						<b>{{ user.followers_count | number }}</b>
+						<b>{{ user.followersCount | number }}</b>
 						<i>%i18n:mobile.tags.mk-user.followers%</i>
 					</a>
 				</div>
diff --git a/src/server/web/app/mobile/views/pages/user/home.followers-you-know.vue b/src/server/web/app/mobile/views/pages/user/home.followers-you-know.vue
index 1a2b8f708..8c84d2dbb 100644
--- a/src/server/web/app/mobile/views/pages/user/home.followers-you-know.vue
+++ b/src/server/web/app/mobile/views/pages/user/home.followers-you-know.vue
@@ -3,7 +3,7 @@
 	<p class="initializing" v-if="fetching">%fa:spinner .pulse .fw%%i18n:mobile.tags.mk-user-overview-followers-you-know.loading%<mk-ellipsis/></p>
 	<div v-if="!fetching && users.length > 0">
 		<a v-for="user in users" :key="user.id" :href="`/@${getAcct(user)}`">
-			<img :src="`${user.avatar_url}?thumbnail&size=64`" :alt="user.name"/>
+			<img :src="`${user.avatarUrl}?thumbnail&size=64`" :alt="user.name"/>
 		</a>
 	</div>
 	<p class="empty" v-if="!fetching && users.length == 0">%i18n:mobile.tags.mk-user-overview-followers-you-know.no-users%</p>
@@ -27,7 +27,7 @@ export default Vue.extend({
 	},
 	mounted() {
 		(this as any).api('users/followers', {
-			user_id: this.user.id,
+			userId: this.user.id,
 			iknow: true,
 			limit: 30
 		}).then(res => {
diff --git a/src/server/web/app/mobile/views/pages/user/home.friends.vue b/src/server/web/app/mobile/views/pages/user/home.friends.vue
index b37f1a2fe..469781abb 100644
--- a/src/server/web/app/mobile/views/pages/user/home.friends.vue
+++ b/src/server/web/app/mobile/views/pages/user/home.friends.vue
@@ -20,7 +20,7 @@ export default Vue.extend({
 	},
 	mounted() {
 		(this as any).api('users/get_frequently_replied_users', {
-			user_id: this.user.id
+			userId: this.user.id
 		}).then(res => {
 			this.users = res.map(x => x.user);
 			this.fetching = false;
diff --git a/src/server/web/app/mobile/views/pages/user/home.photos.vue b/src/server/web/app/mobile/views/pages/user/home.photos.vue
index f12f59a40..f703f8a74 100644
--- a/src/server/web/app/mobile/views/pages/user/home.photos.vue
+++ b/src/server/web/app/mobile/views/pages/user/home.photos.vue
@@ -29,8 +29,8 @@ export default Vue.extend({
 	},
 	mounted() {
 		(this as any).api('users/posts', {
-			user_id: this.user.id,
-			with_media: true,
+			userId: this.user.id,
+			withMedia: true,
 			limit: 6
 		}).then(posts => {
 			posts.forEach(post => {
diff --git a/src/server/web/app/mobile/views/pages/user/home.posts.vue b/src/server/web/app/mobile/views/pages/user/home.posts.vue
index 70b20ce94..654f7f63e 100644
--- a/src/server/web/app/mobile/views/pages/user/home.posts.vue
+++ b/src/server/web/app/mobile/views/pages/user/home.posts.vue
@@ -20,7 +20,7 @@ export default Vue.extend({
 	},
 	mounted() {
 		(this as any).api('users/posts', {
-			user_id: this.user.id
+			userId: this.user.id
 		}).then(posts => {
 			this.posts = posts;
 			this.fetching = false;
diff --git a/src/server/web/app/mobile/views/pages/user/home.vue b/src/server/web/app/mobile/views/pages/user/home.vue
index e3def6151..1afcd1f5b 100644
--- a/src/server/web/app/mobile/views/pages/user/home.vue
+++ b/src/server/web/app/mobile/views/pages/user/home.vue
@@ -1,6 +1,6 @@
 <template>
 <div class="root home">
-	<mk-post-detail v-if="user.pinned_post" :post="user.pinned_post" :compact="true"/>
+	<mk-post-detail v-if="user.pinnedPost" :post="user.pinnedPost" :compact="true"/>
 	<section class="recent-posts">
 		<h2>%fa:R comments%%i18n:mobile.tags.mk-user-overview.recent-posts%</h2>
 		<div>
@@ -31,7 +31,7 @@
 			<x-followers-you-know :user="user"/>
 		</div>
 	</section>
-	<p v-if="user.host === null">%i18n:mobile.tags.mk-user-overview.last-used-at%: <b><mk-time :time="user.account.last_used_at"/></b></p>
+	<p v-if="user.host === null">%i18n:mobile.tags.mk-user-overview.last-used-at%: <b><mk-time :time="user.account.lastUsedAt"/></b></p>
 </div>
 </template>
 
diff --git a/src/server/web/app/mobile/views/pages/welcome.vue b/src/server/web/app/mobile/views/pages/welcome.vue
index 3384ee699..17cdf9306 100644
--- a/src/server/web/app/mobile/views/pages/welcome.vue
+++ b/src/server/web/app/mobile/views/pages/welcome.vue
@@ -6,9 +6,9 @@
 		<p>%fa:lock% ログイン</p>
 		<div>
 			<form @submit.prevent="onSubmit">
-				<input v-model="username" type="text" pattern="^[a-zA-Z0-9-]+$" placeholder="ユーザー名" autofocus required @change="onUsernameChange"/>
+				<input v-model="username" type="text" pattern="^[a-zA-Z0-9_]+$" placeholder="ユーザー名" autofocus required @change="onUsernameChange"/>
 				<input v-model="password" type="password" placeholder="パスワード" required/>
-				<input v-if="user && user.account.two_factor_enabled" v-model="token" type="number" placeholder="トークン" required/>
+				<input v-if="user && user.account.twoFactorEnabled" v-model="token" type="number" placeholder="トークン" required/>
 				<button type="submit" :disabled="signing">{{ signing ? 'ログインしています' : 'ログイン' }}</button>
 			</form>
 			<div>
@@ -22,7 +22,7 @@
 	</div>
 	<div class="users">
 		<router-link v-for="user in users" :key="user.id" class="avatar-anchor" :to="`/@${user.username}`">
-			<img class="avatar" :src="`${user.avatar_url}?thumbnail&size=64`" alt="avatar"/>
+			<img class="avatar" :src="`${user.avatarUrl}?thumbnail&size=64`" alt="avatar"/>
 		</router-link>
 	</div>
 	<footer>
@@ -70,7 +70,7 @@ export default Vue.extend({
 			(this as any).api('signin', {
 				username: this.username,
 				password: this.password,
-				token: this.user && this.user.account.two_factor_enabled ? this.token : undefined
+				token: this.user && this.user.account.twoFactorEnabled ? this.token : undefined
 			}).then(() => {
 				location.reload();
 			}).catch(() => {
diff --git a/src/server/web/app/mobile/views/widgets/profile.vue b/src/server/web/app/mobile/views/widgets/profile.vue
index 1c9d038b4..f1d283e45 100644
--- a/src/server/web/app/mobile/views/widgets/profile.vue
+++ b/src/server/web/app/mobile/views/widgets/profile.vue
@@ -2,10 +2,10 @@
 <div class="mkw-profile">
 	<mk-widget-container>
 		<div :class="$style.banner"
-			:style="os.i.banner_url ? `background-image: url(${os.i.banner_url}?thumbnail&size=256)` : ''"
+			:style="os.i.bannerUrl ? `background-image: url(${os.i.bannerUrl}?thumbnail&size=256)` : ''"
 		></div>
 		<img :class="$style.avatar"
-			:src="`${os.i.avatar_url}?thumbnail&size=96`"
+			:src="`${os.i.avatarUrl}?thumbnail&size=96`"
 			alt="avatar"
 		/>
 		<router-link :class="$style.name" :to="`/@${os.i.username}`">{{ os.i.name }}</router-link>
diff --git a/src/server/web/app/stats/tags/index.tag b/src/server/web/app/stats/tags/index.tag
index 4b167ccbc..63fdd2404 100644
--- a/src/server/web/app/stats/tags/index.tag
+++ b/src/server/web/app/stats/tags/index.tag
@@ -57,7 +57,7 @@
 </mk-index>
 
 <mk-posts>
-	<h2>%i18n:stats.posts-count% <b>{ stats.posts_count }</b></h2>
+	<h2>%i18n:stats.posts-count% <b>{ stats.postsCount }</b></h2>
 	<mk-posts-chart v-if="!initializing" data={ data }/>
 	<style lang="stylus" scoped>
 		:scope
@@ -83,7 +83,7 @@
 </mk-posts>
 
 <mk-users>
-	<h2>%i18n:stats.users-count% <b>{ stats.users_count }</b></h2>
+	<h2>%i18n:stats.users-count% <b>{ stats.usersCount }</b></h2>
 	<mk-users-chart v-if="!initializing" data={ data }/>
 	<style lang="stylus" scoped>
 		:scope
diff --git a/src/server/web/docs/api.ja.pug b/src/server/web/docs/api.ja.pug
index 2bb08f7f3..665cfdc4b 100644
--- a/src/server/web/docs/api.ja.pug
+++ b/src/server/web/docs/api.ja.pug
@@ -54,7 +54,7 @@ section
 		h3 2.ユーザーに認証させる
 		p あなたのアプリを使ってもらうには、ユーザーにアカウントへのアクセスの許可をもらう必要があります。
 		p
-			| 認証セッションを開始するには、#{common.config.api_url}/auth/session/generate へパラメータに app_secret としてシークレットキーを含めたリクエストを送信します。
+			| 認証セッションを開始するには、#{common.config.api_url}/auth/session/generate へパラメータに appSecret としてシークレットキーを含めたリクエストを送信します。
 			| リクエスト形式はJSONで、メソッドはPOSTです。
 			| レスポンスとして認証セッションのトークンや認証フォームのURLが取得できるので、認証フォームのURLをブラウザで表示し、ユーザーにフォームを提示してください。
 
@@ -76,7 +76,7 @@ section
 					th 説明
 			tbody
 				tr
-					td app_secret
+					td appSecret
 					td string
 					td あなたのアプリのシークレットキー
 				tr
diff --git a/src/server/web/docs/api/endpoints/posts/create.yaml b/src/server/web/docs/api/endpoints/posts/create.yaml
index 5e2307dab..11d9f40c5 100644
--- a/src/server/web/docs/api/endpoints/posts/create.yaml
+++ b/src/server/web/docs/api/endpoints/posts/create.yaml
@@ -11,19 +11,19 @@ params:
     desc:
       ja: "投稿の本文"
       en: "The text of your post"
-  - name: "media_ids"
+  - name: "mediaIds"
     type: "id(DriveFile)[]"
     optional: true
     desc:
       ja: "添付するメディア(1~4つ)"
       en: "Media you want to attach (1~4)"
-  - name: "reply_id"
+  - name: "replyId"
     type: "id(Post)"
     optional: true
     desc:
       ja: "返信する投稿"
       en: "The post you want to reply"
-  - name: "repost_id"
+  - name: "repostId"
     type: "id(Post)"
     optional: true
     desc:
@@ -45,7 +45,7 @@ params:
           en: "Choices of a poll"
 
 res:
-  - name: "created_post"
+  - name: "createdPost"
     type: "entity(Post)"
     optional: false
     desc:
diff --git a/src/server/web/docs/api/endpoints/posts/timeline.yaml b/src/server/web/docs/api/endpoints/posts/timeline.yaml
index 01976b061..9c44dd736 100644
--- a/src/server/web/docs/api/endpoints/posts/timeline.yaml
+++ b/src/server/web/docs/api/endpoints/posts/timeline.yaml
@@ -10,22 +10,22 @@ params:
     optional: true
     desc:
       ja: "取得する最大の数"
-  - name: "since_id"
+  - name: "sinceId"
     type: "id(Post)"
     optional: true
     desc:
       ja: "指定すると、この投稿を基点としてより新しい投稿を取得します"
-  - name: "until_id"
+  - name: "untilId"
     type: "id(Post)"
     optional: true
     desc:
       ja: "指定すると、この投稿を基点としてより古い投稿を取得します"
-  - name: "since_date"
+  - name: "sinceDate"
     type: "number"
     optional: true
     desc:
       ja: "指定した時間を基点としてより新しい投稿を取得します。数値は、1970 年 1 月 1 日 00:00:00 UTC から指定した日時までの経過時間をミリ秒単位で表します。"
-  - name: "until_date"
+  - name: "untilDate"
     type: "number"
     optional: true
     desc:
diff --git a/src/server/web/docs/api/entities/drive-file.yaml b/src/server/web/docs/api/entities/drive-file.yaml
index 2ebbb089a..02ab0d608 100644
--- a/src/server/web/docs/api/entities/drive-file.yaml
+++ b/src/server/web/docs/api/entities/drive-file.yaml
@@ -11,13 +11,13 @@ props:
     desc:
       ja: "ファイルID"
       en: "The ID of this file"
-  - name: "created_at"
+  - name: "createdAt"
     type: "date"
     optional: false
     desc:
       ja: "アップロード日時"
       en: "The upload date of this file"
-  - name: "user_id"
+  - name: "userId"
     type: "id(User)"
     optional: false
     desc:
@@ -59,7 +59,7 @@ props:
     desc:
       ja: "ファイルのURL"
       en: "The URL of this file"
-  - name: "folder_id"
+  - name: "folderId"
     type: "id(DriveFolder)"
     optional: true
     desc:
diff --git a/src/server/web/docs/api/entities/post.yaml b/src/server/web/docs/api/entities/post.yaml
index f78026314..71b6a6412 100644
--- a/src/server/web/docs/api/entities/post.yaml
+++ b/src/server/web/docs/api/entities/post.yaml
@@ -11,13 +11,13 @@ props:
     desc:
       ja: "投稿ID"
       en: "The ID of this post"
-  - name: "created_at"
+  - name: "createdAt"
     type: "date"
     optional: false
     desc:
       ja: "投稿日時"
       en: "The posted date of this post"
-  - name: "via_mobile"
+  - name: "viaMobile"
     type: "boolean"
     optional: true
     desc:
@@ -29,7 +29,7 @@ props:
     desc:
       ja: "投稿の本文"
       en: "The text of this post"
-  - name: "media_ids"
+  - name: "mediaIds"
     type: "id(DriveFile)[]"
     optional: true
     desc:
@@ -41,7 +41,7 @@ props:
     desc:
       ja: "添付されているメディア"
       en: "The attached media"
-  - name: "user_id"
+  - name: "userId"
     type: "id(User)"
     optional: false
     desc:
@@ -53,18 +53,18 @@ props:
     desc:
       ja: "投稿者"
       en: "The author of this post"
-  - name: "my_reaction"
+  - name: "myReaction"
     type: "string"
     optional: true
     desc:
       ja: "この投稿に対する自分の<a href='/docs/api/reactions'>リアクション</a>"
       en: "The your <a href='/docs/api/reactions'>reaction</a> of this post"
-  - name: "reaction_counts"
+  - name: "reactionCounts"
     type: "object"
     optional: false
     desc:
       ja: "<a href='/docs/api/reactions'>リアクション</a>をキーとし、この投稿に対するそのリアクションの数を値としたオブジェクト"
-  - name: "reply_id"
+  - name: "replyId"
     type: "id(Post)"
     optional: true
     desc:
@@ -76,7 +76,7 @@ props:
     desc:
       ja: "返信した投稿"
       en: "The replyed post"
-  - name: "repost_id"
+  - name: "repostId"
     type: "id(Post)"
     optional: true
     desc:
@@ -110,7 +110,7 @@ props:
             desc:
               ja: "選択肢ID"
               en: "The ID of this choice"
-          - name: "is_voted"
+          - name: "isVoted"
             type: "boolean"
             optional: true
             desc:
diff --git a/src/server/web/docs/api/entities/user.yaml b/src/server/web/docs/api/entities/user.yaml
index a451a4080..a1fae1482 100644
--- a/src/server/web/docs/api/entities/user.yaml
+++ b/src/server/web/docs/api/entities/user.yaml
@@ -11,7 +11,7 @@ props:
     desc:
       ja: "ユーザーID"
       en: "The ID of this user"
-  - name: "created_at"
+  - name: "createdAt"
     type: "date"
     optional: false
     desc:
@@ -29,77 +29,77 @@ props:
     desc:
       ja: "アカウントの説明(自己紹介)"
       en: "The description of this user"
-  - name: "avatar_id"
+  - name: "avatarId"
     type: "id(DriveFile)"
     optional: true
     desc:
       ja: "アバターのID"
       en: "The ID of the avatar of this user"
-  - name: "avatar_url"
+  - name: "avatarUrl"
     type: "string"
     optional: false
     desc:
       ja: "アバターのURL"
       en: "The URL of the avatar of this user"
-  - name: "banner_id"
+  - name: "bannerId"
     type: "id(DriveFile)"
     optional: true
     desc:
       ja: "バナーのID"
       en: "The ID of the banner of this user"
-  - name: "banner_url"
+  - name: "bannerUrl"
     type: "string"
     optional: false
     desc:
       ja: "バナーのURL"
       en: "The URL of the banner of this user"
-  - name: "followers_count"
+  - name: "followersCount"
     type: "number"
     optional: false
     desc:
       ja: "フォロワーの数"
       en: "The number of the followers for this user"
-  - name: "following_count"
+  - name: "followingCount"
     type: "number"
     optional: false
     desc:
       ja: "フォローしているユーザーの数"
       en: "The number of the following users for this user"
-  - name: "is_following"
+  - name: "isFollowing"
     type: "boolean"
     optional: true
     desc:
       ja: "自分がこのユーザーをフォローしているか"
-  - name: "is_followed"
+  - name: "isFollowed"
     type: "boolean"
     optional: true
     desc:
       ja: "自分がこのユーザーにフォローされているか"
-  - name: "is_muted"
+  - name: "isMuted"
     type: "boolean"
     optional: true
     desc:
       ja: "自分がこのユーザーをミュートしているか"
       en: "Whether you muted this user"
-  - name: "posts_count"
+  - name: "postsCount"
     type: "number"
     optional: false
     desc:
       ja: "投稿の数"
       en: "The number of the posts of this user"
-  - name: "pinned_post"
+  - name: "pinnedPost"
     type: "entity(Post)"
     optional: true
     desc:
       ja: "ピン留めされた投稿"
       en: "The pinned post of this user"
-  - name: "pinned_post_id"
+  - name: "pinnedPostId"
     type: "id(Post)"
     optional: true
     desc:
       ja: "ピン留めされた投稿のID"
       en: "The ID of the pinned post of this user"
-  - name: "drive_capacity"
+  - name: "driveCapacity"
     type: "number"
     optional: false
     desc:
@@ -119,13 +119,13 @@ props:
       en: "The account of this user on this server"
     defName: "account"
     def:
-      - name: "last_used_at"
+      - name: "lastUsedAt"
         type: "date"
         optional: false
         desc:
           ja: "最終利用日時"
           en: "The last used date of this user"
-      - name: "is_bot"
+      - name: "isBot"
         type: "boolean"
         optional: true
         desc:
@@ -139,13 +139,13 @@ props:
           en: "The info of the connected twitter account of this user"
         defName: "twitter"
         def:
-          - name: "user_id"
+          - name: "userId"
             type: "string"
             optional: false
             desc:
               ja: "ユーザーID"
               en: "The user ID"
-          - name: "screen_name"
+          - name: "screenName"
             type: "string"
             optional: false
             desc:
diff --git a/src/tools/analysis/extract-user-domains.ts b/src/tools/analysis/extract-user-domains.ts
index ba472b89a..1aa456db8 100644
--- a/src/tools/analysis/extract-user-domains.ts
+++ b/src/tools/analysis/extract-user-domains.ts
@@ -50,7 +50,7 @@ function extractDomainsOne(id) {
 
 		// Fetch recent posts
 		const recentPosts = await Post.find({
-			user_id: id,
+			userId: id,
 			text: {
 				$exists: true
 			}
diff --git a/src/tools/analysis/extract-user-keywords.ts b/src/tools/analysis/extract-user-keywords.ts
index 4fa9b384e..9b0691b7d 100644
--- a/src/tools/analysis/extract-user-keywords.ts
+++ b/src/tools/analysis/extract-user-keywords.ts
@@ -96,7 +96,7 @@ function extractKeywordsOne(id) {
 
 		// Fetch recent posts
 		const recentPosts = await Post.find({
-			user_id: id,
+			userId: id,
 			text: {
 				$exists: true
 			}
diff --git a/src/tools/analysis/predict-user-interst.ts b/src/tools/analysis/predict-user-interst.ts
index 6599fb220..a101f2010 100644
--- a/src/tools/analysis/predict-user-interst.ts
+++ b/src/tools/analysis/predict-user-interst.ts
@@ -6,7 +6,7 @@ export async function predictOne(id) {
 
 	// TODO: repostなども含める
 	const recentPosts = await Post.find({
-		user_id: id,
+		userId: id,
 		category: {
 			$exists: true
 		}
diff --git a/swagger.js b/swagger.js
index 0cfd2fff0..ebd7a356e 100644
--- a/swagger.js
+++ b/swagger.js
@@ -23,7 +23,7 @@ const defaultSwagger = {
   "swagger": "2.0",
   "info": {
     "title": "Misskey API",
-    "version": "aoi"
+    "version": "nighthike"
   },
   "host": "api.misskey.xyz",
   "schemes": [
@@ -83,7 +83,7 @@ const defaultSwagger = {
           "type": "string",
           "description": "アバターに設定しているドライブのファイルのID"
         },
-        "avatar_url": {
+        "avatarUrl": {
           "type": "string",
           "description": "アバターURL"
         },
@@ -91,7 +91,7 @@ const defaultSwagger = {
           "type": "string",
           "description": "バナーに設定しているドライブのファイルのID"
         },
-        "banner_url": {
+        "bannerUrl": {
           "type": "string",
           "description": "バナーURL"
         },
@@ -218,8 +218,8 @@ options.apis = files.map(c => {return `${apiRoot}/${c}`;});
 if(fs.existsSync('.config/config.yml')){
   var config = yaml.safeLoad(fs.readFileSync('./.config/config.yml', 'utf8'));
   options.swaggerDefinition.host = `api.${config.url.match(/\:\/\/(.+)$/)[1]}`;
-  options.swaggerDefinition.schemes = config.https.enable ? 
-                                      ['https'] : 
+  options.swaggerDefinition.schemes = config.https.enable ?
+                                      ['https'] :
                                       ['http'];
 }
 
diff --git a/tools/migration/node.1522066477.user-account-keypair.js b/tools/migration/nighthike/1.js
similarity index 79%
rename from tools/migration/node.1522066477.user-account-keypair.js
rename to tools/migration/nighthike/1.js
index c413e3db1..d7e011c5b 100644
--- a/tools/migration/node.1522066477.user-account-keypair.js
+++ b/tools/migration/nighthike/1.js
@@ -1,13 +1,13 @@
 // for Node.js interpret
 
-const { default: User } = require('../../built/api/models/user');
-const { generate } = require('../../built/crypto_key');
+const { default: User } = require('../../../built/api/models/user');
 const { default: zip } = require('@prezzemolo/zip')
 
 const migrate = async (user) => {
 	const result = await User.update(user._id, {
 		$set: {
-			'account.keypair': generate()
+			'username': user.username.replace(/\-/g, '_'),
+			'username_lower': user.username_lower.replace(/\-/g, '_')
 		}
 	});
 	return result.ok === 1;
diff --git a/tools/migration/nighthike/2.js b/tools/migration/nighthike/2.js
new file mode 100644
index 000000000..8fb5bbb08
--- /dev/null
+++ b/tools/migration/nighthike/2.js
@@ -0,0 +1,39 @@
+// for Node.js interpret
+
+const { default: App } = require('../../../built/api/models/app');
+const { default: zip } = require('@prezzemolo/zip')
+
+const migrate = async (app) => {
+	const result = await User.update(app._id, {
+		$set: {
+			'name_id': app.name_id.replace(/\-/g, '_'),
+			'name_id_lower': app.name_id_lower.replace(/\-/g, '_')
+		}
+	});
+	return result.ok === 1;
+}
+
+async function main() {
+	const count = await App.count({});
+
+	const dop = Number.parseInt(process.argv[2]) || 5
+	const idop = ((count - (count % dop)) / dop) + 1
+
+	return zip(
+		1,
+		async (time) => {
+			console.log(`${time} / ${idop}`)
+			const doc = await App.find({}, {
+				limit: dop, skip: time * dop
+			})
+			return Promise.all(doc.map(migrate))
+		},
+		idop
+	).then(a => {
+		const rv = []
+		a.forEach(e => rv.push(...e))
+		return rv
+	})
+}
+
+main().then(console.dir).catch(console.error)
diff --git a/tools/migration/nighthike/3.js b/tools/migration/nighthike/3.js
new file mode 100644
index 000000000..cc0603d9e
--- /dev/null
+++ b/tools/migration/nighthike/3.js
@@ -0,0 +1,73 @@
+// for Node.js interpret
+
+const { default: User } = require('../../../built/api/models/user');
+const { generate } = require('../../../built/crypto_key');
+const { default: zip } = require('@prezzemolo/zip')
+
+const migrate = async (user) => {
+	const result = await User.update(user._id, {
+		$unset: {
+			email: '',
+			links: '',
+			password: '',
+			token: '',
+			twitter: '',
+			line: '',
+			profile: '',
+			last_used_at: '',
+			is_bot: '',
+			is_pro: '',
+			two_factor_secret: '',
+			two_factor_enabled: '',
+			client_settings: '',
+			settings: ''
+		},
+		$set: {
+			host: null,
+			host_lower: null,
+			account: {
+				email: user.email,
+				links: user.links,
+				password: user.password,
+				token: user.token,
+				twitter: user.twitter,
+				line: user.line,
+				profile: user.profile,
+				last_used_at: user.last_used_at,
+				is_bot: user.is_bot,
+				is_pro: user.is_pro,
+				two_factor_secret: user.two_factor_secret,
+				two_factor_enabled: user.two_factor_enabled,
+				client_settings: user.client_settings,
+				settings: user.settings,
+				keypair: generate()
+			}
+		}
+	});
+	return result.ok === 1;
+}
+
+async function main() {
+	const count = await User.count({});
+
+	const dop = Number.parseInt(process.argv[2]) || 5
+	const idop = ((count - (count % dop)) / dop) + 1
+
+	return zip(
+		1,
+		async (time) => {
+			console.log(`${time} / ${idop}`)
+			const doc = await User.find({}, {
+				limit: dop, skip: time * dop
+			})
+			return Promise.all(doc.map(migrate))
+		},
+		idop
+	).then(a => {
+		const rv = []
+		a.forEach(e => rv.push(...e))
+		return rv
+	})
+}
+
+main().then(console.dir).catch(console.error)
diff --git a/tools/migration/nighthike/4.js b/tools/migration/nighthike/4.js
new file mode 100644
index 000000000..2e252b7f4
--- /dev/null
+++ b/tools/migration/nighthike/4.js
@@ -0,0 +1,232 @@
+// このスクリプトを走らせる前か後に notifications コレクションはdropしてください
+
+db.access_tokens.renameCollection('accessTokens');
+db.accessTokens.update({}, {
+	$rename: {
+		created_at: 'createdAt',
+		app_id: 'appId',
+		user_id: 'userId',
+	}
+}, false, true);
+
+db.apps.update({}, {
+	$rename: {
+		created_at: 'createdAt',
+		user_id: 'userId',
+		name_id: 'nameId',
+		name_id_lower: 'nameIdLower',
+		callback_url: 'callbackUrl',
+	}
+}, false, true);
+
+db.auth_sessions.renameCollection('authSessions');
+db.authSessions.update({}, {
+	$rename: {
+		created_at: 'createdAt',
+		app_id: 'appId',
+		user_id: 'userId',
+	}
+}, false, true);
+
+db.channel_watching.renameCollection('channelWatching');
+db.channelWatching.update({}, {
+	$rename: {
+		created_at: 'createdAt',
+		deleted_at: 'deletedAt',
+		channel_id: 'channelId',
+		user_id: 'userId',
+	}
+}, false, true);
+
+db.channels.update({}, {
+	$rename: {
+		created_at: 'createdAt',
+		user_id: 'userId',
+		watching_count: 'watchingCount'
+	}
+}, false, true);
+
+db.drive_files.files.renameCollection('driveFiles.files');
+db.drive_files.chunks.renameCollection('driveFiles.chunks');
+db.driveFiles.files.update({}, {
+	$rename: {
+		'metadata.user_id': 'metadata.userId',
+		'metadata.folder_id': 'metadata.folderId',
+		'metadata.properties.average_color': 'metadata.properties.avgColor'
+	}
+}, false, true);
+
+db.drive_folders.renameCollection('driveFolders');
+db.driveFolders.update({}, {
+	$rename: {
+		created_at: 'createdAt',
+		user_id: 'userId',
+		parent_id: 'parentId',
+	}
+}, false, true);
+
+db.favorites.update({}, {
+	$rename: {
+		created_at: 'createdAt',
+		user_id: 'userId',
+		post_id: 'postId',
+	}
+}, false, true);
+
+db.following.update({}, {
+	$rename: {
+		created_at: 'createdAt',
+		deleted_at: 'deletedAt',
+		followee_id: 'followeeId',
+		follower_id: 'followerId',
+	}
+}, false, true);
+
+db.messaging_histories.renameCollection('messagingHistories');
+db.messagingHistories.update({}, {
+	$rename: {
+		updated_at: 'updatedAt',
+		user_id: 'userId',
+		partner: 'partnerId',
+		message: 'messageId',
+	}
+}, false, true);
+
+db.messaging_messages.renameCollection('messagingMessages');
+db.messagingMessages.update({}, {
+	$rename: {
+		created_at: 'createdAt',
+		user_id: 'userId',
+		recipient_id: 'recipientId',
+		file_id: 'fileId',
+		is_read: 'isRead'
+	}
+}, false, true);
+
+db.mute.update({}, {
+	$rename: {
+		created_at: 'createdAt',
+		deleted_at: 'deletedAt',
+		mutee_id: 'muteeId',
+		muter_id: 'muterId',
+	}
+}, false, true);
+
+db.othello_games.renameCollection('othelloGames');
+db.othelloGames.update({}, {
+	$rename: {
+		created_at: 'createdAt',
+		started_at: 'startedAt',
+		is_started: 'isStarted',
+		is_ended: 'isEnded',
+		user1_id: 'user1Id',
+		user2_id: 'user2Id',
+		user1_accepted: 'user1Accepted',
+		user2_accepted: 'user2Accepted',
+		winner_id: 'winnerId',
+		'settings.is_llotheo': 'settings.isLlotheo',
+		'settings.can_put_everywhere': 'settings.canPutEverywhere',
+		'settings.looped_board': 'settings.loopedBoard',
+	}
+}, false, true);
+
+db.othello_matchings.renameCollection('othelloMatchings');
+db.othelloMatchings.update({}, {
+	$rename: {
+		created_at: 'createdAt',
+		parent_id: 'parentId',
+		child_id: 'childId'
+	}
+}, false, true);
+
+db.poll_votes.renameCollection('pollVotes');
+db.pollVotes.update({}, {
+	$rename: {
+		created_at: 'createdAt',
+		user_id: 'userId',
+		post_id: 'postId'
+	}
+}, false, true);
+
+db.post_reactions.renameCollection('postReactions');
+db.postReactions.update({}, {
+	$rename: {
+		created_at: 'createdAt',
+		user_id: 'userId',
+		post_id: 'postId'
+	}
+}, false, true);
+
+db.post_watching.renameCollection('postWatching');
+db.postWatching.update({}, {
+	$rename: {
+		created_at: 'createdAt',
+		user_id: 'userId',
+		post_id: 'postId'
+	}
+}, false, true);
+
+db.posts.update({}, {
+	$rename: {
+		created_at: 'createdAt',
+		channel_id: 'channelId',
+		user_id: 'userId',
+		app_id: 'appId',
+		media_ids: 'mediaIds',
+		reply_id: 'replyId',
+		repost_id: 'repostId',
+		via_mobile: 'viaMobile',
+		reaction_counts: 'reactionCounts',
+		replies_count: 'repliesCount',
+		repost_count: 'repostCount',
+		'_reply.user_id': '_reply.userId',
+		'_repost.user_id': '_repost.userId',
+	}
+}, false, true);
+
+db.signin.update({}, {
+	$rename: {
+		created_at: 'createdAt',
+		user_id: 'userId',
+	}
+}, false, true);
+
+db.sw_subscriptions.renameCollection('swSubscriptions');
+db.swSubscriptions.update({}, {
+	$rename: {
+		user_id: 'userId',
+	}
+}, false, true);
+
+db.users.update({}, {
+	$rename: {
+		created_at: 'createdAt',
+		deleted_at: 'deletedAt',
+		followers_count: 'followersCount',
+		following_count: 'followingCount',
+		posts_count: 'postsCount',
+		drive_capacity: 'driveCapacity',
+		username_lower: 'usernameLower',
+		avatar_id: 'avatarId',
+		banner_id: 'bannerId',
+		pinned_post_id: 'pinnedPostId',
+		is_suspended: 'isSuspended',
+		host_lower: 'hostLower',
+		'account.last_used_at': 'account.lastUsedAt',
+		'account.is_bot': 'account.isBot',
+		'account.is_pro': 'account.isPro',
+		'account.two_factor_secret': 'account.twoFactorSecret',
+		'account.two_factor_enabled': 'account.twoFactorEnabled',
+		'account.client_settings': 'account.clientSettings'
+	},
+	$unset: {
+		likes_count: '',
+		liked_count: '',
+		latest_post: '',
+		'account.twitter.access_token': '',
+		'account.twitter.access_token_secret': '',
+		'account.twitter.user_id': '',
+		'account.twitter.screen_name': '',
+		'account.line.user_id': ''
+	}
+}, false, true);
diff --git a/tools/migration/shell.1522038492.user-account.js b/tools/migration/shell.1522038492.user-account.js
deleted file mode 100644
index 056c29e8e..000000000
--- a/tools/migration/shell.1522038492.user-account.js
+++ /dev/null
@@ -1,41 +0,0 @@
-db.users.dropIndex({ token: 1 });
-
-db.users.find({}).forEach(function(user) {
-	print(user._id);
-	db.users.update({ _id: user._id }, {
-		$unset: {
-			email: '',
-			links: '',
-			password: '',
-			token: '',
-			twitter: '',
-			line: '',
-			profile: '',
-			last_used_at: '',
-			is_bot: '',
-			is_pro: '',
-			two_factor_secret: '',
-			two_factor_enabled: '',
-			client_settings: '',
-			settings: ''
-		},
-		$set: {
-			account: {
-				email: user.email,
-				links: user.links,
-				password: user.password,
-				token: user.token,
-				twitter: user.twitter,
-				line: user.line,
-				profile: user.profile,
-				last_used_at: user.last_used_at,
-				is_bot: user.is_bot,
-				is_pro: user.is_pro,
-				two_factor_secret: user.two_factor_secret,
-				two_factor_enabled: user.two_factor_enabled,
-				client_settings: user.client_settings,
-				settings: user.settings
-			}
-		}
-	}, false, false);
-});
diff --git a/tools/migration/shell.1522116709.user-host.js b/tools/migration/shell.1522116709.user-host.js
deleted file mode 100644
index b354709a6..000000000
--- a/tools/migration/shell.1522116709.user-host.js
+++ /dev/null
@@ -1 +0,0 @@
-db.users.update({ }, { $set: { host: null } }, { multi: true });
diff --git a/tools/migration/shell.1522116710.user-host_lower.js b/tools/migration/shell.1522116710.user-host_lower.js
deleted file mode 100644
index 31ec6c468..000000000
--- a/tools/migration/shell.1522116710.user-host_lower.js
+++ /dev/null
@@ -1 +0,0 @@
-db.users.update({ }, { $set: { host_lower: null } }, { multi: true });
diff --git a/webpack.config.ts b/webpack.config.ts
index 6f16fcbfa..53e3d2630 100644
--- a/webpack.config.ts
+++ b/webpack.config.ts
@@ -20,6 +20,7 @@ import { licenseHtml } from './src/build/license';
 import locales from './locales';
 const meta = require('./package.json');
 const version = meta.version;
+const codename = meta.codename;
 
 //#region Replacer definitions
 global['faReplacement'] = faReplacement;
@@ -76,13 +77,13 @@ module.exports = entries.map(x => {
 		_THEME_COLOR_: constants.themeColor,
 		_COPYRIGHT_: constants.copyright,
 		_VERSION_: version,
+		_CODENAME_: codename,
 		_STATUS_URL_: config.status_url,
 		_STATS_URL_: config.stats_url,
 		_DOCS_URL_: config.docs_url,
 		_API_URL_: config.api_url,
 		_WS_URL_: config.ws_url,
 		_DEV_URL_: config.dev_url,
-		_CH_URL_: config.ch_url,
 		_LANG_: lang,
 		_HOST_: config.host,
 		_HOSTNAME_: config.hostname,