Tech Square
2022.07 - Present画面

概要
需要企業と供給企業がスマートファクトリーのパートナーを探し、メンタリング、中古設備取引、運用情報を利用できるB2B製造プラットフォームです。
役割・技術スタック
Node.js, Express, TypeORM, MySQL, Vue 3, AWS, GitLab CI/CD
実績 01
Java 8システムをNode.jsプラットフォームへ再構築する移行への参加
- 背景・原因
- Tech Squareの既存システムはJava 8で運用されており、品質と保守性に限界がありました。Vue 3のユーザー・管理者チャネルと技術構成を合わせた新しいプラットフォームが必要でした。
- 検討・選択理由
- 移行の意思決定には参加していません。決定後に加わり、Node.js・Express・TypeORM基盤のシステムを共同構築し、データ移行を担当しました。フロントエンドと言語エコシステムを統一し、協業の境界を減らしました。旧システムと新システムを並行稼働して機能とデータを検証した後、運用を引き継ぎました。
- 結果
- 運用を止めずに新しいプラットフォームへ移行しました。構築後は外注の担当者1名とともに、APIとユーザー・管理者チャネルを運用し改善を続けました。
- 振り返り
- 運用システムの移行は、新技術だけでなく、データ移行、並行運用、引き継ぎ完了の基準を併せて設計してこそ安定して完了します。
実績 02
共通トランザクション層によるデータ整合性基準の統一
- 背景・原因
- 推薦リクエストが重複して受け付けられたり、推薦の状態が実際の進行状況とずれたりすることがありました。同じ業務に属する変更を一つのトランザクションにまとめる必要がありました。重複リクエストと状態変更を一貫して処理する基準も必要でした。
- 検討・選択理由
- ORMの機能だけを使えば初期は速いものの、業務が増えるほどトランザクション境界がコントローラーごとに分散します。長く運用するサービスと考え、初期コストを受け入れました。TypeORMの上にSQLとトランザクションの共通層を自作しました。業務上一つの命令である変更は、一つのトランザクションにまとめました。外部API呼び出しやメール送信のようにロールバックで戻せない処理は、トランザクションの外に出しました。重複リクエストへの対応では、まずトランザクション分離レベルを上げる方法を検討しました。しかし分離レベルを上げても重複した命令自体はなくならず、ロック競合が増えるだけです。そこで業務キーに一意制約を置き、命令識別子と現在状態の検証を併せて設けました。
- 結果
- 3層構造と共通トランザクション層が、61の業務サービスで維持されています。業務が増えた後も、トランザクションの処理方式は分かれていません。
- 振り返り
- トランザクション共通化の目的はコード再利用ではなく、業務単位の成功と失敗の境界を一貫させることです。
実績 03
クエリ再構成による繰り返し参照の改善
- 背景・原因
- 会員、企業、メンタリングのデータ増加により、一覧の各項目で関連情報を再取得する構造が生まれました。検索条件が増えるほどクエリの組み合わせも複雑になっていました。
- 検討・選択理由
- 制限時間を延ばしたり無計画にインデックスを追加したりせず、繰り返し参照を結合と一括取得に置き換えました。動的な検索条件はパラメータバインディングに基づくクエリビルダーで整理し、実行構造と入力安全性をともに改善しました。
- 結果
- 繰り返し参照を減らし、検索条件を安全に組み合わせられるようにしました。一覧とExcelダウンロードも同じ参照基準を共有しています。
- 振り返り
- 遅い参照では、まず結果集合と繰り返し回数を確認し、クエリ構造を正してから必要なインデックスを選ぶべきです。
実績 04
ローカルファイルをS3ベースの共通ファイルフローへ移行
- 背景・原因
- アップロードしたファイルがサーバーのローカルパスに縛られ、環境によって参照・ダウンロード処理が変わっていました。PDF、Excel、画像ごとに個別の例外処理も蓄積していました。
- 検討・選択理由
- サーバーインスタンスとファイルのライフサイクルを分離するためS3へ移行しました。既存ファイルは一度に廃止せず、両方のパスを読める期間を設けました。アップロード、参照、削除、元のファイル名の復元を共通ユーティリティに集約し、保存方式の変更が業務コードへ広がらないようにしました。
- 結果
- 通知、報告書、見積書、画像など異なるファイルフローが共通の保存方式を使うようになり、環境依存のパスと重複処理を減らしました。
- 振り返り
- ファイルストアの移行は単なるオブジェクトコピーではなく、既存キー、元の名前、参照パスの互換性も保つデータ移行です。
実績 05
認証と入力の境界を段階的に強化
- 背景・原因
- ブラウザーからアクセスできる認証トークン、動的SQL、HTML入力、複数のアップロード経路がありました。それぞれが異なるセキュリティリスクを生んでいました。
- 検討・選択理由
- JWTをHttpOnly Cookieへ移し、ブラウザースクリプトからの直接アクセスを防ぎました。同時の401応答は一回のトークン更新に収束させました。SQLのパラメータ化とHTML・ファイルの許可リスト検証により、認証、データ、入力、ファイルの境界ごとに適切な防御を適用しました。
- 結果
- ユーザー・管理者チャネルの認証フローを統一しました。スクリプト入力、SQLインジェクション、危険なファイルレンダリングにつながり得る露出経路を減らしました。
- 振り返り
- セキュリティは一つのフィルターでは解決できません。認証、入力、データ、ファイルの境界をそれぞれ確認し、段階的に絞り込む必要があります。
実績 06
ログ断片をリクエストフローにつなぐ可観測性の構築
- 背景・原因
- サービスごとの`console`ログだけでは、一つのリクエストがAPIとデータ処理をどこまで進んだかをつなげて確認することが困難でした。
- 検討・選択理由
- ログを増やす代わりに、全ソースを構造化ロガーへ統一し、リクエストごとに相関IDを付与しました。OpenTelemetryのtraceIdも接続し、ログ形式を保ちながらサービス境界を越えてリクエストフローを追跡できるようにしました。
- 結果
- 個々のログを別々に検索する代わりに、リクエスト単位で問題の発生箇所を絞り込める運用基盤を整えました。
- 振り返り
- 可観測性ではログ量より、異なる記録を同じリクエストフローにつなげられるかが重要です。
実績 07
シークレットとローカル開発環境を再現可能な構成へ移行
- 背景・原因
- 環境ごとの設定とシークレット管理方式が分散していました。ローカルのデータベーストンネルが切れると、アプリケーション接続も不安定になっていました。
- 検討・選択理由
- 少人数で混成のチームにおける運用負担を考え、Vaultより導入障壁の低いInfisicalを選びました。Docker Composeで実行環境を統一しました。データベーストンネルは切断検知、指数バックオフ再接続、二重起動防止を備えた別プロセスに分離しました。
- 結果
- シークレットをコードとデプロイファイルから分離し、開発者が同じ実行手順を再現できるようにしました。トンネル障害もアプリケーション全体の再起動に頼らず復旧できます。
- 振り返り
- 開発環境の標準化はツールを揃えるだけではなく、設定、シークレット、外部接続の失敗と復旧方法をともに定義することです。
実績 08
バッチ・通知パイプラインによる反復業務の自動化
- 背景・原因
- 外部データの取込み、状態確認、担当者への案内を人が繰り返すと、漏れや処理遅延が発生する可能性がありました。
- 検討・選択理由
- データベースへのリクエスト回数を減らすため、大量データは一件ごとのリクエストではなく一括で取り込みました。業務条件ごとにcronジョブと通知フローを構成しました。重複実行、空の結果、環境ごとの送信可否を分け、例外状況で自動化が不要な作業を生まないようにしました。
- 結果
- 企業データの取込みと運用通知が定めた条件とスケジュールに従って実行され、担当者の繰り返し確認作業を減らしました。
- 振り返り
- バッチ自動化では、定期実行そのものより、重複処理、空の結果、部分失敗を安全に扱うことが重要です。