Skip to content

A modern company search system built with React and TypeScript, featuring incremental search with Japanese IME support, employee information management, and comprehensive security measures.

Notifications You must be signed in to change notification settings

okamyuji/incremental-search

Repository files navigation

インクリメンタルサーチ実装プロジェクト

このプロジェクトは、React + TypeScript + Viteを使用して実装された企業検索システムです。

主な機能

  • 企業名のインクリメンタルサーチ
  • 担当者情報の表示と検索
  • 日本語 IME 入力対応
  • レスポンシブデザイン
  • CSRF 対策とレートリミット

技術スタック

  • React 18
  • TypeScript
  • Vite
  • Redux Toolkit
  • Vitest
  • MirageJS

開発環境のセットアップ

# 依存関係のインストール
npm install

# 開発サーバーの起動
npm run dev

# テストの実行
npm test

# ビルド
npm run build

ESLint設定

  • 本番アプリケーションを開発する場合、型認識可能なlintルールを有効にすることを推奨します
export default tseslint.config({
  languageOptions: {
    parserOptions: {
      project: ['./tsconfig.node.json', './tsconfig.app.json'],
      tsconfigRootDir: import.meta.dirname,
    },
  },
})

アプリケーション設計

状態管理(Redux)

  • 企業情報と担当者情報の状態を分離して管理

  • 企業情報の管理

    • companySlice: 企業リストと検索状態を管理
    • searchInput: 検索入力値の管理
    • filterText: フィルタリング用テキストの管理
    • status: API リクエスト状態の管理
  • 担当者情報の管理

    • peopleSlice: 担当者リストと検索状態を管理
    • filterText: 担当者フィルタリング用テキストの管理
    • peopleByCompany: 会社ごとの担当者情報を管理

キャッシュ戦略

  • 企業検索

    • キャッシュなし
    • 常に最新のデータを取得
    • 理由:企業情報は頻繁に更新される可能性があるため
  • 担当者情報

    • 会社IDごとにキャッシュ
    • peopleByCompanyオブジェクトを使用
    • 理由:担当者情報は更新頻度が低いため

インクリメンタルサーチの実装

  1. 入力処理

    const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
      if (e.key === "Enter" && !isComposing.current) {
        const trimmedInput = input.trim();
        if (!trimmedInput) {
          console.log("検索条件が空のため検索を実行しません");
          return; // 空文字では検索を実行しない
        }
        console.log("Enterキー押下で検索を実行");
        dispatch(fetchCompanies(trimmedInput));
      }
    };
  2. 検索処理

    const handleCompositionEnd = (
      e: React.CompositionEvent<HTMLInputElement>
    ) => {
      isComposing.current = false; // IME変換モード終了
      console.log("IME変換モード終了");
      console.log(e.data);
      // IME確定後に検索を実行
      if (e.data?.trim()) {
        console.log("検索実行");
        // e.data が undefined の場合を考慮
        dispatch(fetchCompanies(input.trim()));
      }
    };

検索機能の実装

  1. 企業検索

    • Enterキー押下またはIME確定時に検索実行
    • 空文字列の場合は検索を実行しない
    • 検索結果は最大300件まで表示
  2. 担当者検索

    • 選択された企業の担当者をリアルタイムでフィルタリング
    • 名前、部署、役職での検索が可能

セキュリティ機能

  • CSRF対策(トークンベース)
  • レート制限(IPベース)
  • 最大300件の検索結果制限

テスト

Vitestを使用した単体テストを実装

  • Reduxスライスのテスト
  • Reactコンポーネントのテスト
  • 非同期処理のテスト

プロジェクト構造

src/
├── components/ # Reactコンポーネント
├── store/ # Reduxストア
├── server/ # モックサーバー
└── test/ # テスト

制限事項

  • 検索結果は最大300件まで表示
  • IME入力中は検索を実行しない
  • CSRFトークンが無効な場合は403エラー
  • レート制限超過時は429エラー

About

A modern company search system built with React and TypeScript, featuring incremental search with Japanese IME support, employee information management, and comprehensive security measures.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published