🏢つくるAI
不動産開発用地仕入の生産性を「爆上げ」するオンラインサービス
最終更新
不動産開発を行う企業は、単に仲介営業から提案される物件チラシから「現地調査」「相場調査」「法規制の調査」などたくさんの業務を行い、開発を行う判断をしなければなりません。
「物件管理」を使うことで、それら面倒だった案件管理~調査業務が完結し、業務生産性が向上します。
これまでは建築士が数万円~10万円程度で2週間くらいかけて作成していた「ある土地にどんな建物が建てられるか」というプランを、スマホで住所だけ入れればわかるようにするサービス。
地図技術と3D、建築士が行う高度な計算ロジックを備えており、物件管理と合わせて使うことで不動産開発に関わる人々の生産性が「爆上げ」されます。
「フルスタック」なものを使わない。フルスタックなものを使うことにより、以下の問題があると考えられるため、これを避ける観点で選定しています。
コンポーネント設計に対する制約が課せられる
記法が複雑化する傾向がみられる
メモリ空間に対するフットプリントが大きくなる傾向がみられる
他の技術への乗り換えが困難となる
規模が大きくなった時にコンポーネントの分割が難しくなる
全方位TypeScriptで作ることとし、リポジトリはモノレポ構成です。
パッケージマネージャは安全性と速度の観点からpnpmを採用しました。
Vite + React + Ant Design を採用しています。
Viteはesbuildを用いた開発サーバでビルドが高速なので開発者体験が良く、Pluginも充実してきているため採用
Reactはもう特に議論の必要はないレベルでフロントエンドのデファクトだと思います
Ant DesignとChakraで議論になりましたが、B2Bの管理画面向けとして使えるコンポーネントがChakraよりも多くあるため採用
3D表示はThree.jsを用いており、いわゆるDBからデータを取って表示して更新するだけのWebアプリではない技術要素も積極的に取り入れてサービス開発をしています
Hono + Prisma を主なコンポーネントとして採用しています。
HonoはWAFとしてシンプルに振舞うため、乗るアプリのコンポーネント設計と切り離すことができ、高速であるため採用
Prismaはprisma.schemaの定義ができていればTypeとテーブル双方の定義が出来上がるなど、データベースを使った開発の生産性を高めることができ、ORMとしても一定のシェアを持っていることから採用
アプリケーション構成としてはレイヤードアーキテクチャに倣った構成を取っています。
レイヤーはそれぞれ、以下のような配置をしています。
AIエンジニアと建築士が協力し、仕様検討から実装までPythonを用いて行っています。 単純なWebアプリを開発するだけでは触れることがない数学を駆使した構造計算など、高度理系人材向けの技術要素が含まれています。
PlanetScaleを採用しているのが大きなポイントです。
PlanetScaleは、いわゆるサーバレスのDB as a Serviceです。PlanetScale最大の特徴は「JITスキーマ変更」と「ブランチ」の概念があることで、これらが開発者生産性に大きく寄与すると判断したため採用しています。
JITスキーマ変更:本番環境でのスキーマ変更をダウンタイム無しで行え、かつ切り戻しにも対応している。
ブランチ:ブランチを作成すると、既存のDDLを引き継いだ別のデータベース接続エンドポイントが作成されます。更にスキーマ変更を「Deploy Request」として管理することができるため、開発者が開発者のメンタルモデルでデータベースを扱うことができる点が、他のDBaaSと大きく異なる利点です。
「全方位TypeScript」の実践として Pulumi を採用しています。
Pulumi を採用したことで、インフラ関連の操作も単純なTypeScriptのプログラムに落とし込むことができ、自動化も一般的なTypeScriptのプログラムのビルドプロセスとほぼ変わらない形で実行できるようになっています。
また、後述のインフラへの更新反映などがシンプルになるのと、プログラマであってもインフラにどのようなものが展開されているのかという事を把握することができるようになりました。
プルリク画面の「Review in codespace」からCodespaceを起動 or 既存のCodespace上で gh pr checkout [pr-number]
してプルリクを手元に持ってくる。
make auth-pscale
でPlanetScaleにログイン。
make run
すると、プルリクに対応するデータベースブランチを参照した状態で起動するため、いちいち自分でデータベースへのMigrationなどを走らせる必要はありません。
リリース前にはその準備を自動で行うGitHub Actionsを用意しています。
このActionsを通じて
リリースタグの作成(いつのリリースかなどをわかりやすくするため、calvarを採用しています)
リリースノートの作成(前回のリリースノートからのマージ差分を抽出しての自動作成)
コンテナのビルド
ビルドしたコンテナをレジストリへプッシュ
GitHubのReleaseを作成
という一連の作業が行われ、フロントエンド、バックエンド、インフラへの反映準備ができます。
こちらもGitHub Actionsで実行できるように整備しており、↑の手順後に作成されたリリースの内容を本番環境に反映させることができるようになっています。
その時のリリースに、インフラへの変更を必要とする場合にはそのタグを指定してActionsを実行します。「Is dryrun?」のチェックを外さない限り本番環境への変更は行われないので、事前に実行してどのような変更があるかの確認も気軽に行うことができます。
データベースにはPlanetScaleを利用しており、Deploy Request機能を用いてこれを実現しています。
開発者はCodespace上でブランチを作り適切な初期化処理を走らせることでPlanetScale上にデータベースのブランチを作成し、その上で開発作業を行うことができます。データベースへの変更がある場合、コード変更の際のPull Requestのように反映依頼を出します。
反映依頼はPlanetScaleのコンソール上で、GitHubのPull Requestをレビューするのと同じようにレビューし、本番環境のデータベースに反映させることができます。
「リリースノートの自動生成とビルド」で作られたコンテナを用いてデプロイする手法を取っています。PaaSのインプレースデプロイは「新しいコンテナをpull→起動してヘルスチェックがクリアになる→既存コンテナと置き換わる」という挙動で差し替えが行われます。
指定のタグでビルドされたコンテナを送り込む処理を実行することができるGitHub Actionsを作成して、そちらで実行しています。
同時にPaaSのログストリームを確認しながら実施するやり方を取れるため、本番でしか出ない不具合に遭遇してもすぐに戻すことができます。
フロントエンドへのリリースはGitHub Actionsを用いて行っており、こちらもリリースタグを指定して実行することでデプロイを行います。
フロントエンドのデプロイ環境はNodeなどを用いずにstatic buildしたものをデプロイする構成を取っているため、このActionsの中で静的サイトとして書き出しを行い、サーバへ展開しています。