本文へ移動

2026-08-01 時点の資料です。読みやすさのために、一部の文字の色を濃くしています。

採用技術/ Tech Stack

この仕組みを構成する技術と、それぞれの役割

共有リンクのために新しく持ち込んだ技術はほとんどありません。アプリの他の部分ですでに動いているものを、この機能の要求に合わせて組み合わせています。ここでは、どの技術がどの役割を担っているかを一覧します。

01

画面Frontend

受取ページ・Box の共有リンクタブ・全社管理画面の 3 面は、同じ仕組みで作られています。受取ページだけはログインが無いため、認証を前提にした部品を一切通しません。

Next.jsApp Router

3 つの画面すべての土台。受取ページは他の画面と共通の外枠を継承せず、独立した構成にしています(本体ホストへの相対リンクが公開ホストに残らないようにするため)。

ReactUI

画面の組み立て。受取ページの状態遷移は、純粋な関数として切り出して自動テストの対象にしています。

TypeScriptTypes

画面とサーバのやりとりの形を、型として 1 か所で定義。どちらかを変えるともう一方が壊れることが、実行する前に分かります。

Tailwind CSSStyling

見た目の指定。色や余白はデザインの決め事から作った変数を通して使い、画面ごとに数値を書きません。

shadcn/ui + Base UIComponents

ダイアログ・入力欄・表などの部品。キーボード操作や読み上げへの対応が組み込まれたものを土台にしています。

TanStack QueryData Fetching

データの取得と再取得。ZIP の進捗確認では「準備中のときだけ 5 秒ごとに、それ以外は止める」という制御をここで行っています。

nuqs

nuqsURL State

一覧のフィルタや並べ替えを URL に保持。管理者どうしで「この状態の画面」をそのまま共有できます。総当たり検知の通知メールから直接この状態へ着地します。

ZodValidation

入出力の検証。同じ定義を画面とサーバの両方が読むので、片方だけ緩いという状態になりません。

Rc

RechartsCharts

アクセス傾向の 2 つのグラフ。この機能でアプリに初めて導入しました。

02

サーバとデータBackend & Data

共有リンクのために追加した API は 23 本(受け取り用の公開 8 本、発行と管理 9 本、全社管理 6 本)、テーブルは 3 つです。

HonoAPI

API の土台。受け取り用の公開 API は独立したまとまりとして分け、ログイン前提の部品をそこへ持ち込めないよう機械的に検査しています。

Node.jsRuntime

API と ZIP 生成の実行環境。パスワードのハッシュ計算は、他の要求の処理を止めない方式で呼んでいます。

PostgreSQLDatabase

リンク本体・アクセス記録・確認コードの 3 テーブル。行ごとのアクセス制御を使い、経路ごとに見える範囲と書ける列を絞っています。

SupabaseManaged Postgres

PostgreSQL の運用基盤。接続の集約やバックアップを任せています。

PrismaORM & Migration

テーブル定義と変更の管理。行ごとのアクセス制御など表現できない部分は、変更ファイルの末尾に直接記述します。本番への適用は手動で行います。

yazl

yazlZIP

フォルダの ZIP 生成。全部をいったん保存してから固めるのではなく、読みながら書き出します。途中で失敗したときはあえて壊れた状態で終えることで、中途半端な ZIP を「できあがったもの」として配らないようにしています。

03

クラウド基盤Google Cloud

公開ホストの入口から、ZIP の生成、掃除処理まで。共有リンクのために新しく作ったサービスはありません(既存のサービスに処理を足しています)。

Cloud Load Balancing + Cloud DNSEntry

1 台の負荷分散がホスト名を見て本体と公開ホストへ振り分けます。証明書は 2 ホスト分を 1 枚にまとめています。

Armor

Cloud ArmorWAF

公開ホストの外周。接続元ごとのレート制限で頭打ちにします。本体アプリとは別のルールです。

Run

Cloud RunServices

画面と API の実行環境。共有リンクのための新しいサービスは作らず、既存の 2 つに機能を足しました。

Jobs

Cloud Run JobsBatch

ZIP の生成と、日次の掃除処理。ZIP は要求のたびに単発で起動し、完了を待たずに受け付けを返します。

Cloud StorageObject Storage

検査済みファイルの保管場所と、ZIP の一時置き場。一時置き場は 72 時間で自動削除する設定にしています。

P/S

Pub/SubMessaging

案内メールと総当たり通知の配送経路。配送できなかったものを退避する仕組みと、その監視を組にしています。

Sched

Cloud SchedulerCron

日次の掃除処理の起動。期限切れ ZIP の後始末と、条件が消えたアラートの整理を行います。

04

暗号・メール・テストSecurity, Mail & Testing

scrypt

scryptPassword Hashing

パスワードの保存。計算時間だけでなくメモリも要求するため、専用ハードウェアによる総当たりに強い方式です。設定値を保存形の中に書き込み、将来の強化に備えています。

HMAC

HMAC-SHA256 + HKDFCodes & Cookie

確認コードの保存と、認可 Cookie の署名。鍵はアプリが既に持っている秘密から用途ごとに導き出し、新しい秘密を増やしていません。

URL

署名付き URLSigned URLs

ファイルの配布。短時間だけ有効な URL を発行し、ブラウザが Cloud Storage から直接取得します。ファイルの中身が API を通ることはありません。

ResendEmail Delivery

4 通のメールの配送。届かなかった宛先の情報が戻ってくるので、一覧に「届かなかった」印を出せます。

HBS

React Email + HandlebarsTemplates

メールの外枠と本文。発行時に入力したメッセージは、先に無害化してから改行を反映する処理を通します。

VitestUnit & Integration

単体テスト 17 ファイル、データベース結合 9 ファイル、アクセス権限の網羅 5 ファイル。権限のテストは役割 × 操作を総当たりで確認します。

PW

PlaywrightEnd-to-End

画面を実際に操作する通しテスト 3 スイート。発行 → 一覧反映 → 無効化、受け取りの一連、管理画面の操作をブラウザで再現します。

テストの置き場所を分けています: 手元で毎回動かすのは、外部に依存しない単体テストだけです。データベースやブラウザを必要とするものは、変更を本番へ入れる直前の自動検査でだけ動かします。手元では動かないぶん、手元で緑だったのに検査で落ちることがあります。これは意図した切り分けです。