Campus Helpdesk Agent Skill
このスキルは、Campus Helpdesk Webアプリケーションを開発、拡張、保守するための技術標準、ワークフロー、ベストプラクティスを定義します。このプロジェクトに機能を追加したり、コンポーネントをリファクタリングしたり、ステータスワークフローを更新したり、データモデルを変更する際には、このガイドに従ってください。
1. クリーンで再利用可能なReactコンポーネントの作成
モジュール化され、疎結合なコンポーネントアーキテクチャを維持します。
- 単一責任の原則: 各コンポーネントは1つのことをうまく実行する必要があります。
- フォームロジックと入力は
IssueForm.jsxに属します。 - 公開検索、フィルタリング、チケットカード表示は
TicketList.jsxに属します。 - 分析メトリクス、視覚的なプログレスバー、管理テーブルは
AdminDashboard.jsxに属します。 - モーダルインスペクションと履歴タイムラインは
TicketModal.jsxに属します。 - 通知は
Toast.jsxに属します。
- フォームロジックと入力は
- Props と State の設計:
- 状態は可能な限り局所的に保ちます。グローバルな
tickets、activeTab、toastsなど、異なるビュー間で共有される場合にのみ、App.jsxに状態を引き上げます。 - 可能な限り純粋なプレゼンテーション用子コンポーネントを使用し、コールバック(
onSelectTicket、onUpdateStatus、onDeleteTicket)をクリーンに渡します。 - 重複した状態を避け、
useMemoを使用して派生値(フィルタリングされたチケット、KPI統計など)を計算します。
- 状態は可能な限り局所的に保ちます。グローバルな
- 命名規則とクリーンコード:
- コンポーネントファイルは PascalCase を使用します(
AdminDashboard.jsx、IssueForm.jsx)。 - ユーティリティファイルと定数ファイルは camelCase を使用します(
storage.js、constants.js)。 - イベントハンドラは
handle[Action]パターンに従う必要があります(例:handleSubmit、handleStatusChange)。 - コメントとドキュメント文字列を保持します。明確で説明的な変数名を使用して、自己説明的なコードを記述します。
- コンポーネントファイルは PascalCase を使用します(
- 外部依存関係は最小限に:
- 軽量なアーキテクチャを維持します。ネイティブのReactフック、純粋なインラインSVGアイコン、スコープ付きCSSクラスを使用し、大規模なサードパーティコンポーネントライブラリを取り込まないようにします。
2. レスポンシブでアクセシブルなUIの作成
Campus Helpdeskポータルは、すべてのデバイス(モバイル、タブレット、ノートパソコン、大型モニター)でシームレスなユーザーエクスペリエンスを提供する必要があります。
- 流動的なレイアウトとブレークポイント:
- モバイルファーストまたはデスクトップダウンで設計し、一貫性のあるブレークポイントを使用します。
- デスクトップ: 最大コンテナ幅
1240px、マルチカラムグリッド(5つのメトリクスカード、2カラムの分析、2カラムのフォーム)。 - タブレット(
<= 1024px): 5カラムのメトリクスグリッドを3または2カラムに折りたたみ、分析チャートを1カラムにスタックします。 - モバイル(
<= 768px): ヘッダーナビゲーション、フォーム入力を1カラムにスタックし、データテーブルで水平スクロールを有効にします。 - 小型画面(
<= 480px): 全幅のメトリクスカード、積み重ねられたアクションボタン、固定された下部のトースト通知。
- デスクトップ: 最大コンテナ幅
- モバイルファーストまたはデスクトップダウンで設計し、一貫性のあるブレークポイントを使用します。
- アクセシビリティ(a11y):
- すべてのインタラクティブ要素は、適切なセマンティックHTML(
<button>、<input>、<select>、<textarea>)を持つ必要があります。 - フォームコントロールには、一致する
id属性を持つ関連付けられた<label htmlFor="...">要素が必要です。 - モーダルダイアログは、
role="dialog"、aria-modal="true"を持ち、背景クリックとエスケープキーによる閉じ操作をサポートする必要があります。 - インタラクティブなアイコンやアイコンのみのボタンには、説明的な
aria-labelまたはtitle属性を含める必要があります。 - ステータスバッジや優先度タグのテキストには、アクセシブルなカラーコントラスト比を維持します。
- すべてのインタラクティブ要素は、適切なセマンティックHTML(
- 視覚的なフィードバックとトランジション:
- インタラクティブ要素は、明確な
:hover、:focus、:active状態を表示する必要があります。 - フォーカスされたフォームフィールドは、ハイコントラストのフォーカスリング(
var(--primary-ring))を表示する必要があります。 - マイクロアニメーション(トーストのスライドイン、モーダルのスケールアップ、ボタンのスピナー)を使用して、レイアウトシフトを起こさずにバックグラウンドアクションをユーザーに通知します。
- インタラクティブ要素は、明確な
3. 学生課題フォームの検証
IssueForm.jsx を通じて送信されるすべての課題は、状態変更またはストレージ保存の前に、厳格なクライアントサイド検証ルールに従う必要があります。
検証ルールマトリックス
| フィールド | ルール | エラーメッセージ |
|---|---|---|
| 氏名 | 必須、トリミング後、空でない | "氏名を入力してください。" |
| キャンパスメール | 必須、有効な正規表現パターン /^[^\s@]+@[^\s@]+\.[^\s@]+$/ | "有効なメールアドレスを入力してください。" |
| 場所 / 部屋 | 必須、トリミング後、空でない | "建物、ホール、またはキャンパスの場所を指定してください。" |
| カテゴリ | 必須、CATEGORIES リストに一致する | デフォルトで自動選択 |
| 優先度 | 必須、PRIORITIES("低", "中", "高", "緊急")に一致する | デフォルトは "中" |
| 課題件名 / タイトル | 必須、トリミング後、最小長 $≥ 5$ 文字 | "タイトルは5文字以上である必要があります。" |
| 詳細説明 | 必須、トリミング後、最小長 $≥ 15$ 文字 | "説明は15文字以上である必要があります。" |
検証実装手順
- フィールド名をエラー文字列にマッピングする
errors状態オブジェクトを維持します。 - ユーザーが入力(
handleChange)を変更したときに、特定のフィールドのエラーをクリアします。 handleSubmitですべてのルールをチェックします。エラーが存在する場合は、送信を防ぎ、.input-errorと.field-errorで無効なフィールドを強調表示します。- 成功時:
- 一意のID(例:
TCK-XXXX)を生成します。 - 初期ステータスを「保留中」として割り当てます。
- 初期送信タイムスタンプと履歴ノードを記録します。
- フォームフィールドとエラー状態をリセットします。
- 成功トーストをトリガーし、チケットトラッカービューに移動します。
- 一意のID(例:
4. 保留中、進行中、解決済みのステータスの管理
Campus Helpdeskは、厳密に定義された3段階のライフサイクルに従います。
[ 保留中 ] ───► [ 進行中 ] ───► [ 解決済み ]
▲ ▲ │
└──────────────────────┴─────────────────────┘ (必要に応じて再オープン可能)
ステータス定義とビジュアルデザインシステム
保留中:
- 意味: 学生/スタッフから提出された新しい課題で、トリアージまたは割り当てを待っています。
- カラーテーマ: アンバー(
#d97706)、背景#fef3c7、境界線#fde68a。 - 進捗段階: ステップ1がアクティブ。
進行中:
- 意味: 技術者またはキャンパス部門がチケットを引き受け、積極的に調査または修理を行っています。
- カラーテーマ: ロイヤルブルー(
#2563eb)、背景#dbeafe、境界線#bfdbfe。 - 進捗段階: ステップ1と2がアクティブ。
解決済み:
- 意味: 修正が完了し、機器が交換され、またはサービスが復旧しました。
- カラーテーマ: エメラルドグリーン(
#059669)、背景#d1fae5、境界線#a7f3d0。 - 進捗段階: ステップ1、2、3がアクティブ。
ライフサイクルルールと監査履歴
- すべてのステータス遷移は、チケットの
history配列にイベントを追加する必要があります。{ status: newStatus, timestamp: new Date().toISOString(), note: `ステータスが ${newStatus} に更新されました` } - 内部スタッフメモの更新は、チケットの元の
createdAtをリセットせずに、adminNoteとupdatedAtを更新する必要があります。 - 更新は直ちに
localStorage(campus_helpdesk_tickets_v1)と同期する必要があります。
5. ダッシュボード統計の正確性の維持
管理ダッシュボードは、リアルタイムの運用可視性を提供します。すべてのKPIメトリクスとチャート計算は、信頼できる情報源である tickets 配列から動的に導出される必要があります。
メトリクス計算
- チケット総数: $$\text{Total} = \text{tickets.length}$$
- 保留中件数: $$\text{Pending} = \text{tickets.filter}(t \Rightarrow t.\text{status} === \text{STATUSES.PENDING}).\text{length}$$
- 進行中件数: $$\text{In Progress} = \text{tickets.filter}(t \Rightarrow t.\text{status} === \text{STATUSES.IN_PROGRESS}).\text{length}$$
- 解決済み件数: $$\text{Resolved} = \text{tickets.filter}(t \Rightarrow t.\text{status} === \text{STATUSES.RESOLVED}).\text{length}$$
- 解決率 (%): $$\text{Resolution Rate} = \begin{cases} \text{Math.round}\left(\frac{\text{Resolved}}{\text{Total}} \times 100\right), & \text{if Total} > 0 \ 0, & \text{otherwise} \end{cases}$$
- 高優先度および緊急優先度キュー: $$\text{Urgent/High} = \text{tickets.filter}(t \Rightarrow t.\text{priority} === 'Urgent' \lor t.\text{priority} === 'High').\text{length}$$
- カテゴリと優先度の分布:
- カウントが0の場合でも、事前定義されたすべてのカテゴリと優先度のカウントを計算し、UIのちらつきやゼロ除算を防ぎます。
- プログレスバーの幅のパーセンテージが常に $\le 100%$ になるようにします。
すべての統計計算は、パフォーマンスを維持するために、依存関係を [tickets] としてReactの useMemo フック内にラップします。
6. 変更のテストとビルドの実行
コード変更を送信したり、タスクを完了としてマークしたりする前に、静的分析とプロダクションビルド手順の両方を通じてアプリケーションを検証します。
検証プロトコル
- プロジェクトディレクトリに移動:
cd "campus-helpdesk"
- 静的コードリントの実行:
npm run lint
- 終了コード
0で終了する必要があります。 - 未使用のインポート、変数、またはエスケープされていないJSXエンティティがないことを確認します。
- プロダクションビルドの実行:
npm run build
- Viteがエラーや警告なしにプロダクションアセットのバンドルを完了することを確認します。
dist/index.html、dist/assets/*.css、dist/assets/*.jsが正常に作成されていることを確認します。
- localStorageの永続性の確認:
- チケットを送信すると、
localStorage.getItem('campus_helpdesk_tickets_v1')が更新されることをテストします。 - チケットステータスの更新がページリフレッシュ後も保持されることをテストします。
- "サンプルデータをリセット" および "すべてクリア" 機能をテストします。
7. エラーの正直な報告
システムのステータスやエラーを報告する際には、誠実さと正直さが不可欠です。
- 失敗を隠さない: ビルドエラー、構文エラー、リント失敗が発生した場合は、正確なエラーメッセージ、ファイル名、行番号を報告します。
- 根本原因の説明: エラーが発生した理由を説明します(例:インポート不足、ストレージパーサーでの未処理のnullケース、壊れたプロップコントラクト)。
- 確認済みの修正のみ: 確認コマンド(
npm run lint/npm run build)を再実行し、終了コード0を確認せずに、問題が修正されたと主張しないでください。 - ユーザーへの透明性: 予期しないブラウザの制限やlocalStorageのクォータ問題が発生した場合は、ユーザーに積極的に制限を説明し、明確な技術的オプションを提示します。