# デベNAVI

## 概要

### 物件管理

不動産開発を行う企業は、単に仲介営業から提案される物件チラシから「現地調査」「相場調査」「法規制の調査」などたくさんの業務を行い、開発を行う判断をしなければなりません。

それだけではなく、その土地にどのような建物をつくれるかということも、建築士などに依頼して２週間程度待つなど、非効率なことが多くあります。

「デベNAVI」を使うことで、それら面倒だった案件管理～調査業務が完結し、業務生産性が向上します。

<figure><img src="/files/v9KmNXLd4sDHWlxAdf3Q" alt=""><figcaption></figcaption></figure>

## 技術スタック

### 選定基準

「フルスタック」なものを使わない。フルスタックなものを使うことにより、以下の問題があると考えられるため、これを避ける観点で選定しています。

1. コンポーネント設計に対する制約が課せられる
2. 記法が複雑化する傾向がみられる
3. メモリ空間に対するフットプリントが大きくなる傾向がみられる
4. 他の技術への乗り換えが困難となる
5. 規模が大きくなった時にコンポーネントの分割が難しくなる

### 全般

全方位TypeScriptで作ることとし、リポジトリはモノレポ構成です。

```bash
.
├── Makefile
├── README.md
├── apps
│   ├── client_webapp
│   ├── public_api
│   ├── server
│   └── workers
├── infra
│   ├── README.md
│   └── index.ts
├── package.json
├── packages
│   ├── api
│   └── schema
└── scripts
```

パッケージマネージャは安全性と速度の観点から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としても一定のシェアを持っていることから採用

アプリケーション構成としてはレイヤードアーキテクチャに倣った構成を取っています。

<figure><img src="/files/Ps8W950rIP5roZyntZLX" alt=""><figcaption></figcaption></figure>

レイヤーはそれぞれ、以下のような配置をしています。

```
apps/server/src
├── domain      // 副作用を伴わない純粋なビジネスロジックの配置場所
├── handler     // クライアントからのリクエストをどの処理に流すかを制御するプログラムの配置場所
├── infra       // データベースなどと通信するプログラムの配置場所
├── service     // 実態としての処理が行われるプログラムの配置場所
├── test        // 主にdomainに対するテストプログラムの配置場所
├── transaction // Handlerから処理をうけとり、複数のServiceやDomainを連携した処理プログラムの配置場所
└── views       // テンプレートエンジンetaのテンプレート。メール送信の際のテンプレなどを配置
```

### 建築アルゴリズムAPI

AIエンジニアと建築士が協力し、仕様検討から実装までPythonを用いて行っています。\
単純なWebアプリを開発するだけでは触れることがない数学を駆使した構造計算など、高度理系人材向けの技術要素が含まれています。

### データベース

PlanetScaleを採用しているのが大きなポイントです。

PlanetScaleは、いわゆるサーバレスのDB as a Serviceです。PlanetScale最大の特徴は「JITスキーマ変更」と「ブランチ」の概念があることで、これらが開発者生産性に大きく寄与すると判断したため採用しています。

* JITスキーマ変更：本番環境でのスキーマ変更をダウンタイム無しで行え、かつ切り戻しにも対応している。
* ブランチ：ブランチを作成すると、既存のDDLを引き継いだ別のデータベース接続エンドポイントが作成されます。更にスキーマ変更を「Deploy Request」として管理することができるため、開発者が開発者のメンタルモデルでデータベースを扱うことができる点が、他のDBaaSと大きく異なる利点です。

### インフラ（IaC）

「全方位TypeScript」の実践として [Pulumi](https://www.pulumi.com/docs/languages-sdks/javascript/) を採用しています。

Pulumi を採用したことで、インフラ関連の操作も単純なTypeScriptのプログラムに落とし込むことができ、自動化も一般的なTypeScriptのプログラムのビルドプロセスとほぼ変わらない形で実行できるようになっています。

また、後述のインフラへの更新反映などがシンプルになるのと、プログラマであってもインフラにどのようなものが展開されているのかという事を把握することができるようになりました。

## プルリクのレビュー

* プルリク画面の「Review in codespace」からCodespaceを起動 or 既存のCodespace上で `gh pr checkout [pr-number]` してプルリクを手元に持ってくる。

<figure><img src="/files/z7dion5cTpe9dZi9R8jy" alt=""><figcaption><p>プルリク単位でCodespaceを立ち上げてレビューをします</p></figcaption></figure>

* `make auth-pscale` でPlanetScaleにログイン。
* `make run` すると、プルリクに対応するデータベースブランチを参照した状態で起動するため、いちいち自分でデータベースへのMigrationなどを走らせる必要はありません。

## リリース戦略

### リリースノートの自動生成とビルド

リリース前にはその準備を自動で行うGitHub Actionsを用意しています。

![](/files/wHNL574yonLwlIDkmIXu)

このActionsを通じて

1. リリースタグの作成（いつのリリースかなどをわかりやすくするため、calvarを採用しています）
2. リリースノートの作成（前回のリリースノートからのマージ差分を抽出しての自動作成）
3. コンテナのビルド
4. ビルドしたコンテナをレジストリへプッシュ
5. GitHubのReleaseを作成

という一連の作業が行われ、フロントエンド、バックエンド、インフラへの反映準備ができます。

### インフラへの更新反映

こちらもGitHub Actionsで実行できるように整備しており、↑の手順後に作成されたリリースの内容を本番環境に反映させることができるようになっています。

![](/files/KdHsRJNLNgik3OH4tMI9)

その時のリリースに、インフラへの変更を必要とする場合にはそのタグを指定してActionsを実行します。「Is dryrun?」のチェックを外さない限り本番環境への変更は行われないので、事前に実行してどのような変更があるかの確認も気軽に行うことができます。

### データベースへの更新反映

データベースにはPlanetScaleを利用しており、Deploy Request機能を用いてこれを実現しています。

![](/files/NUptK0OXpT2M0fZqRn4W)

開発者はCodespace上でブランチを作り適切な初期化処理を走らせることでPlanetScale上にデータベースのブランチを作成し、その上で開発作業を行うことができます。データベースへの変更がある場合、コード変更の際のPull Requestのように反映依頼を出します。

反映依頼はPlanetScaleのコンソール上で、GitHubのPull Requestをレビューするのと同じようにレビューし、本番環境のデータベースに反映させることができます。

![](/files/1ao2E9ct9zasPSKInW55)

### バックエンドのデプロイ

「リリースノートの自動生成とビルド」で作られたコンテナを用いてデプロイする手法を取っています。PaaSのインプレースデプロイは「新しいコンテナをpull→起動してヘルスチェックがクリアになる→既存コンテナと置き換わる」という挙動で差し替えが行われます。

指定のタグでビルドされたコンテナを送り込む処理を実行することができるGitHub Actionsを作成して、そちらで実行しています。

![](/files/3tJYr6c5qzh7aYmGbt1K)

同時にPaaSのログストリームを確認しながら実施するやり方を取れるため、本番でしか出ない不具合に遭遇してもすぐに戻すことができます。

### フロントエンドのデプロイ

フロントエンドへのリリースはGitHub Actionsを用いて行っており、こちらもリリースタグを指定して実行することでデプロイを行います。

![](/files/rXnZA60G7Wi1RxMC4T4t)

フロントエンドのデプロイ環境はNodeなどを用いずにstatic buildしたものをデプロイする構成を取っているため、このActionsの中で静的サイトとして書き出しを行い、サーバへ展開しています。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://engineer.toggle.co.jp/chapter-2-products-and-development/toggle-sketch.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
