🔭

Resume

Hirotaka Miyagi | 宮城 広隆

  • 開発チームがぶつかる壁に対して自分ごととして捉え、フルサイクルに向き合うことを大事にしています。
  • 開発とBizを巻き込んだプロジェクト進行など、不確実性を排除しながら前に進む動きが得意です。
  • 開発者体験の向上 / レガシーコードからの脱却 / 4 keys / 変化圧の強いフロントエンドの動向 などに興味があります。
  • 「人が本質(価値・幸せ)に向き合う時間を増やすために、それ以外を技術で解決する」を人生で取り組みたいと思っています。

Experience

株式会社タイミー(2022/4~2022/10)

業務委託として開発プラットフォームチームに所属し、Rails/Next.jsでのGraphQLの導入・初期設計・各種オンボーディングを担当しました。

株式会社ビットジャーニー(2021/9〜現在)

業務委託として https://kibe.la/ の開発チームに参画し、フロントエンドをメインにフルサイクルに開発を進行しました。

ProseMirrorを利用したリッチテキストエディタの開発

  • ProseMirrorの木構造⇄DOM⇄markdown textの相互変換により、リッチテキストエディタで記入したテキストを即座にmarkdownに変換させる
    • ユーザーフレンドリーなテーブル記法の入力UIの実装
      1. image
      2. https://blog.kibe.la/entry/rich-text-editor-beta-table
    • 列・行・セルの選択や追加、削除などを直感的に行えるように
    • DOMを効率的にレンダリングするためのキャッシュアルゴリズムの実装

      ProseMirrorはユーザーのイベント(keydown, mousemove)ごとにDOMを再構築します。Reactのように差分更新するアルゴリズムはあるものの、テーブル操作中は各種ボタン等含めテーブルの全てのDOMが再構築されることとなり、キーリピート等がチラつくほどにパフォーマンスが劣化する問題がありました。

      そのため簡易的なReact.memoのようなアルゴリズムを実装し、特定の条件下のみ特定のDOMを更新することで全体の再構築を防ぐ仕組みを作りました。

フルサイクルな機能開発

  • DB設計・RailsのMVC設計・GraphQLインターフェース・Reactコンポーネント・Redash/GA4での分析までを一貫して担当
  • GitHub Actionsの導入と開発プロセス中のトイルの自動化

リリース7年が経過するRails + Reactアプリケーションのモダン化

  • Sassの@import非推奨によるsassc-railsからcssbundling-railsへの移行
  • webpack.config.jsの最適化
  • Sass →CSS in JSへの移行のための技術選定
  • jQueryからの安全な脱却ロードマップの策定・進行(進行中)、ES5を上げていくためのリスク評価、古いpolyfillの削除等

株式会社リゾートワークス(2020/12〜現在)

ワーケーションを通じて働く人の“創造性“を刺激する福利厚生サブスクリプションサービス ResortWorx で、インフラ/バックエンドエンジニアを担当しました。

インフラ構築の0→1に伴う技術選定と構築

プロダクトローンチ初期に求められる最低限の構成で、ランニングコストの抑制とエンジニアがキャッチアップできるようなドキュメンテーションを心がけました。

  • Nuxt.js + Rails API の利用者向け Web アプリケーションと、Rails SSR による管理画面のホスティング
  • Route53 → ALB → ECS / RDS の一般的な Rails のホスティング
  • GitHub Actions による CD 環境、 SSM を利用した ssh(rails c 等)実行環境
  • CloudWatch によるロギングとアラート、AWS Chatbot による Slack 通知
  • S3 + CloudFront による SPA のホスティング、GitHub Actions による CD, workflow dispatch を利用したブランチ指定のデプロイ
    • のちに Nuxt の SSR も必要になったため Vercel へ移行
  • 上記の AWS リソースを terraform で IaC 化、draw.io + VSCodeによるアーキテクチャ図の記載、その他オペレーションをドキュメント化

チケットベースでのチーム開発

  • Rails, Nuxtでの機能追加
  • CloudWatch Logs Insights で可視化・検索ができるよう Rails のログの JSON 化

企画LPサイトの構築

  • Nuxt.js(composition API), Tailwind CSS, Vercelによる0→1を一人で担当
  • デザイナーとFigma上で会話しながら背中合わせで進行
  • Lighthouseの点数をほぼ100点に

株式会社タイミー(2018/07〜2021/09)

サービスローンチの 1 ヶ月前にジョイン、初期は1人サーバーサイドとして Rails をメインに、プロダクト/会社の成長とともに幅広い業務を担当しました。

PjM/PdM/バックエンドエンジニア (2020/08〜2021/04)

当時の課題

会社の成長に伴いガバナンスを強めていく必要性があり、プロダクト「タイミー」における社内オペレーション改善や、コーポレートエンジニアリングの領域で開発を進行しました。

メンバー構成

プロジェクトの開発メンバーとしては 2 名で、関係部署にヒアリングしながら遊軍のように活動しました。

  • 自身: プロジェクトマネジメント/ 要件定義/ Rails や Go での実装
  • チームメンバー: 元 iOS エンジニア(Rails はビギナー)/ 要件定義/ Rails や Go での実装
  • 関わる部署: 経理財務、 CS

やったこと

ヒアリングや SaaS の選定、スケジューリングや開発着手、リリースまで一気通貫で担当しました。(NDAレベルの業務が多く少しぼかしています)

  • CRM ツール HubSpot の API 連携
  • 経理・財務業務 SaaS との API 連携
  • 内部統制に伴う各種機能開発の進行(職務権限規定に沿った権限管理・与信・反社チェックなど)
  • 社内業務のオペレーション改善
  • Mac にインストールし deamon で常駐起動するソフトウェアを Go で開発
    • 主に非機能要件であるリリースパイプラインの設計を担当 死活監視、バイナリのセルフアップデート機構、リトライ制御など
  • チームメンバーに Rails を指導 コードレビューやキャッチアップのための順序立てたタスク振りなど

新規事業 PjM/バックエンドエンジニア/フロントエンドエンジニア (2021/04〜2021/08)

メンバー構成

  • 開発チーム: iOS 担当 1 名、 デザイナー1 名、 Web フロントエンド&バックエンド API2 名
  • 関わった部署: 経営, Sales, CS, 経理

役割

  • プロジェクトマネジメント・技術選定・設計・実装(Rails, Vue.js)を担当
  • チームのエンジニアは それぞれ iOS と Rails に強いメンバーとのプロジェクトだったため、それぞれの強みを活かしてもらいつつ取りこぼしがないよう拾う立ち回りに努めた
  • Biz サイドとの折衝、サポートや経理とのオペレーション構築など
  • エンジニアリングとしてはコアドメインのモデリングや Stripe を利用した決済周りの設計実装を主に担当した

技術選定・初期設計

  • Vue.js/vue-router を使った SPA の実装
  • 一般的な Rails の環境構築(annotate/rails-erd/bullet/rspec/rubocop)
  • 監視/ロギング/CI/CD の導入(Datadog, Sentry, lograge を利用したログの JSON 化、 CircleCI)
  • 商品情報登録・在庫管理・注文・決済履歴などのドメインの境界を意識したモデリング
  • Rails プロジェクトでの行動指針決め
    • 原則テストコードを書く、書けないなら書けるよう責務を分割する
    • トランザクションやロックなど SQL を適切に書く
    • シンプル・ミニマルに

決済機能の要件定義・技術選定・Stripe APIの実装/運用

新規事業の決済機能としてStripeを導入する上で考えたこと全て - Timee Product Team Blog

こんにちは、 タイミーデリバリー開発チームの宮城です。 この記事は JP_Stripes Advent Calendar 2020 の10日目の記事です。 タイミーデリバリーはデリバリーを頼みたい人が安い価格で注文でき、飲食店も安い利用料で注文を受けられるデリバリープラットフォームです。 その決済機能として今回は Stripeを導入しました。 この記事では、決済基盤の技術選定/Stripeを活用したクレジットカード決済と各事業者への入金までの流れ/ Rails での具体的な実装内容 をそれぞれタイミーデリバリーでの活用事例として紹介します。 タイミーデリバリーでは、 Railsによる APIサーバーと、Web管理画面としてVue.jsによるSPA、ユーザー向け iOSアプリとしてSwiftを採用しています。 1つの モノリスな Railsアプリで利用者別にネームスペースを区切り、それぞれ JSONを返す APIを提供しています。 タイミーデリバリーはプラットフォームビジネスであり、注文者はアプリ上で複数の事業者の商品を閲覧し商品を購入します。 注文者が決済した金額にはプラットフォーム利用料が含まれており、タイミーと事業者双方に分配する必要があります。 まだ弊社には決済機能を導入するノウハウがなかったため、 Railsを使ってどのようにこのビジネスモデルを実現するのかや、そもそも決済機能に求められる通常の要件をどのように達成するのかもわからない状態からスタートしました。 まずは決済基盤に求められる技術選定の基準を作るところから始めました。 弊社 経理 チームやCSチーム、法務チームと相談しながら要件をまとめ技術選定基準を作り、以下の要件が達成できる状態を目指すことにしました。 注文者の体験 注文者がクレジットカードを使ってアプリ上から商品を事前購入することができる 決済情報(クレジットカードなど)はタイミーが保持せず、ログにも残らない 不正利用やマネーロンダリングの対策ができている 注文者が操作に迷わない(UXが高い) 弊社経理チーム、導入事業者の体験 決済された金額から事業者とタイミーに分配できる、またはタイミーから事業者に請求できる 事業者の導入にあたって、契約書の受領からアプリ上に商品を掲載し決済できるようになるまでが簡単で短い 特定の期間で「締め」て、締めたデータは変更されなくなる 必要なデータを後から取り出すことができる 注文者への領収書や店舗ごとの利用明細が表示できる サポートチームの体験 返金のオペレーションが容易にできる 必要なデータを後から取り出すことができる 開発チームの体験 実装コストができるだけ低い サービスが利用できない時間が可能な限り短い(可用性が高い) この時点で「決済を行う」とはここまで考えることがあるのか...と深い闇に迷い込んだ気がしましたが、ここで丁寧に要件をまとめたことで各 ステークホルダー と認識のズレを減らすことができたように思います。 上記の技術選定基準をStripeで達成できるか当てはめたのが以下です。 注文者の体験 注文者がクレジットカードを使ってアプリ上から商品を事前購入することができる クレジットカード、ApplePay、GooglePayなどが可能。 決済情報(クレジットカードなど)はタイミーが保持せず、ログにも残らず、セキュアに管理される APIで問い合わせ、決済情報の登録・閲覧・削除が可能。秘匿情報は全てStripe側で管理し、タイミーが保持するものは結果のみ。 不正利用や マネーロンダリング の対策ができている Stripeに蓄積されているデータを用い、クレジットカードのリスク審査ができるRadarと呼ばれる不正行為検知の機能がある(別料金) 注文者が操作に迷わない(UXが高い) StripeのSwift向け SDKが優秀カードの入力は1度きりでよく、次回決済時にシームレスに利用できる 弊社 経理 チーム、導入事業者の体験 決済された金額から事業者とタイミーに分配できる、またはタイミーから事業者に請求できる 可能。方法は後述 導入にあたって、契約書の受領からアプリ上で決済できるようになるまでが簡単で短い アカウントを登録するための情報は多いが、入力次第すぐに決済が可能。Stripeが並行で審査を進めている 特定の期間で「締め」て、締めたデータは変更されなくなる これはできなさそうだった。だが 経理 上のオペレーションとしては問題なく処理できたので方法を後述 必要なデータを後から取り出すことができる Stripeの ダッシュ ...

新規事業の決済機能としてStripeを導入する上で考えたこと全て - Timee Product Team Blog

スキーマ駆動開発の導入・運用

Rails + RSpec + OpenAPI3 + Committeeでスキーマ駆動開発を運用するTips - Timee Product Team Blog

こんにちは、 タイミーデリバリー開発チームの宮城です。 今回は弊社のOpenAPI3ベースの スキーマ 駆動開発の運用方法を紹介します。 技術スタックは OpenAPI3, Swagger UI, Committee, ActiveModelSerializers Committeeを利用してOpenAPI準拠のRequest Specを行う OpenAPI3のrequiredキーワードに注意する タイミーデリバリーでは、 Railsによる APIサーバーと、Web管理画面としてVue.jsによるSPA、ユーザー向け iOSアプリとしてSwiftを採用しています。 1つの モノリスな Railsで利用者別にネームスペースを区切り、それぞれエンドポイントを提供しています。 サーバーサイドとクライアントサイドを分離し並行して開発を進めるために スキーマ駆動開発を導入しました。 スキーマ 駆動開発の詳しい説明やメリットについては既に多くの記事が存在するため、ここでは参考にさせていただいた記事の紹介までとさせていただきます。 RubyKaigi 2019でOpenAPI 3について登壇しました - おおたの物置 スキーマファースト開発のススメ - onk.ninja スキーマ駆動開発のススメ - Studyplus Engineering Blog この記事では、実際に スキーマ 駆動開発を開発フローに導入する際のTipsを記したいと思います。 Railsで APIサーバーを構築するにあたって、 jsonの生成には ActiveModelSerializersを採用しました。 スキーマ定義には OpenAPI3を採用し、 Swagger UIでドキュメントを閲覧できるようにしています。 この3つに関しては近年では割とよくある一般的な技術スタックかなと思っています。 スキーマ定義を記述する YAMLファイルは Railsの リポジトリ に配置しています。 .

Rails + RSpec + OpenAPI3 + Committeeでスキーマ駆動開発を運用するTips - Timee Product Team Blog

SRE (2021/01〜2021/04)

当時の課題

プロダクトの成長は進みテレビ CM を打つことになり、現状のスケールしない EC2 によるインフラでは耐えられないだろう、という課題がありました。ただひたすらこなしていた開発業務についてもメンバーが増えスクラムを回せるようになり、組織化が進んで自身の属人性は剥がれてきていました。運よくシニアレベルの SRE の方が採用できたこともあり、その方と主に SRE チームを立ち上げ AWS のアーキテクチャから作り変えるプロジェクトを始め、キャッチアップしつつインフラの移行を進めていきました。

メンバー構成

SRE: 2 人(シニアメンバー, 自身)

やったこと(公開情報)

RedashをFargate, Datadog, Terraformで構築/運用する - Timee Product Team Blog

こんにちは、タイミーSREチームの宮城です。 今回は弊社が Redash をFargateで構築/運用している話を紹介します。 タイミーでは、CSやセールスのKPI策定から毎月の事業数値に至るまで、Redashが様々な用途で活用されています。 Fargateで構築する以前はEC2上のdocker-composeで運用されていましたが、以下の課題がありました。 オートスケールできないため、クエリが詰まってCPUが100%になってサービスが停止する。 セットアップしたエンジニアが退社しており、インフラ構成図やノウハウの共有、IaCによる管理ができていない。 クエリやダッシュボードなどのデータの定期的なバックアップができていない。 v7系からv8系へのアップデートがしたいが、アップデートによる影響範囲がわからず恐怖感がある。 事業に大きく関わるサービスなのにも関わらず、モニタリングやアラートができていない。 上記をFargateに移行することで解決することができました。 Redashで利用する ミドルウェアに関しては下記 コンポーネントを使い、全てをterraformで管理しています。 - PostgreSQL -> RDS - Redis -> ElastiCache ここからは、それぞれの構成をTerraformの ソースコードやタスク定義の JSON などを交えつつ説明していきます。 ダッシュボードなどのデータが定期的なバックアップが行われていない問題は、RDSでsnapshotを取得することで解決しました。 それぞれ一番小さい インスタンスタイプのシングルAZ構成で構築しています。 実際に運用してみて負荷が大きければスペックを上げるつもりでしたが、現状問題なく捌けています。 将来、可用性を高めるためマルチAZにすることも容易であり、こういった柔軟なサーバーリソースの活用も クラウド の利点といえるでしょう。 privateサブネットに置いたシンプルな構成です。 applyが完了したらrootユーザーのパスワードを AWS コンソール上から変更し、接続情報をSecretsManagerに保管しています。 resource "aws_db_subnet_group" "redash" { name = "redash" subnet_ids = [ data.aws_subnet.private-subnet-1a.id, data.aws_subnet.private-subnet-1c.id,

RedashをFargate, Datadog, Terraformで構築/運用する - Timee Product Team Blog

バックエンドエンジニア (2018/07〜2020/01)

サービスローンチの 1 ヶ月前にジョイン、初期は 1 人サーバーサイドとして保守運用を担当Rails をメインに、プロダクト/会社の成長とともに幅広い業務を担当しました。

メンバー構成

  • リリース前: iOS…5 人、 サーバーサイド 4 人
  • リリース後〜半年程度: iOS…2 人、 サーバーサイド 1 人、 技術顧問数人
    • 徐々にメンバーは増えていきました

役割

スタートアップのシード期なので、通常の機能開発や運用はもちろん、経営・CS・経理・営業チームからの要望対応も全てバックログに載せただひたすらにこなしていました。

やったこと

  • 0→1 の開発・0→1 後のサービスの保守運用・負債解消
  • RSpec, Rubocop, OpenAPI3 の導入
  • Ruby/Rails のバージョンアップ業
  • API のバージョニング、Serializer のスキーマ分割
  • サービス固有の強いドメインを持つ機能の設計、実装

業務外活動

オープンソース貢献

日常的に行なっています。いくつかリンクを紹介します。

登壇

社内外の勉強会・カンファレンスで発表を行っています。