Skip to content

Reafactor 202512#210

Merged
kashu-02 merged 63 commits intomasterfrom
reafactor-202512
Jan 31, 2026
Merged

Reafactor 202512#210
kashu-02 merged 63 commits intomasterfrom
reafactor-202512

Conversation

@kashu-02
Copy link
Member

@kashu-02 kashu-02 commented Dec 15, 2025

This pull request migrates the frontend application from Vue.js to React, updates the build and development tooling to use Vite and TypeScript, and modernizes the CI/CD pipeline and configuration files. The changes include a complete rewrite of the frontend codebase, updates to environment variables and dependencies, and improvements to project documentation and workflow automation.

Frontend migration and modernization:

  • Migrated the frontend from Vue.js to React 19 with TypeScript and Vite, replacing all Vue-specific files (App.vue, .eslintrc.js, babel.config.js, postcss.config.js, etc.) with React equivalents (App.tsx, App.module.css, eslint.config.js, etc.) and updating the project structure and main entry point (index.html, main.tsx). [1] [2] [3] [4] [5] [6] [7]
  • Updated environment variable usage to use Vite conventions (VITE_ROOMNAME, VITE_SHOWQUESTION) and removed legacy Vue environment files. [1] [2] [3]

Dependency and configuration updates:

  • Replaced Vue-related dependencies with React, React Router, React Bootstrap, and TypeScript packages in package.json, and updated linting and formatting configurations for the new stack. [1] [2] [3] [4] [5]
  • Improved .gitignore to better support Node.js and Vite projects, including logs and editor configuration files.

Documentation improvements:

  • Rewrote README.md to reflect the new React/TypeScript/Vite stack, including development setup, project structure, key components, and API integration details.

CI/CD and workflow updates:

  • Updated GitHub Actions workflow in .github/workflows/main.yml to use the latest versions of actions (actions/checkout@v4, actions/cache@v4, etc.), added Node.js 20 setup, and improved caching and artifact handling for the new frontend build process. [1] [2] [3] [4]

Cleanup and removal of legacy files:

  • Removed obsolete files and configurations related to the previous Vue.js setup, including browserlist, editorconfig, legacy environment files, and build/release scripts. [1] [2] [3] [4] [5] [6] [7] [8] [9]

- NFCリーダーのコードを整理し、定数名を大文字に変更
- データベース接続のプール設定を追加し、エラーハンドリングを強化
- ユーザーの入退室ログをトランザクションで管理し、エラーメッセージを詳細化
- APIハンドラーでのリクエストボディの解析を改善し、エラーハンドリングを統一
- cronジョブの設定を更新し、毎日の強制退室と月次ログ送信を追加
- Slack APIとの連携を強化し、エラーメッセージを明確化
- go.mod: golang.org/x/netの依存関係をv0.47.0からv0.48.0に変更
- go.sum: golang.org/x/net v0.48.0のハッシュを追加
- DISPLAY環境変数を設定
- Chromiumブラウザを無対話モード、キオスク、シークレットモードで起動するコマンドを追加
- nfc_reader.pyを新規作成し、学生IDおよび大学カードの読み取り機能を実装
- requirements.txtにnfcpyの依存関係を追加
database.dbを.gitignoreからserver/test/ディレクトリに移動しました。
- elsystemd.service: ユーザーとグループをrootからgeekに変更、PIDFileを削除
- elsystemf.service: ユーザーをpiからgeekに変更
- log.go: "encoding/json" と "io" のインポートを削除
- socket.go: Writeメソッドのエラーハンドリングを修正
- user.go: 不要なインポートを削除
@kashu-02 kashu-02 self-assigned this Dec 15, 2025
kashu-02 and others added 21 commits December 15, 2025 23:10
- Goodbyeコンポーネントを追加し、3秒後にトップページに遷移する機能を実装
- Questionコンポーネントを追加し、ユーザーからの入力を受け付ける機能を実装
- Registerコンポーネントを追加し、学生番号の入力を受け付ける機能を実装
- Topコンポーネントを追加し、カードリーダーとのWebSocket接続を管理
- Welcomeコンポーネントを追加し、ユーザーを歓迎するメッセージを表示
- CSSモジュールを使用してスタイルを適用
- VueからReactへの移行に伴い、Vue関連のファイルを削除
- API呼び出しを行うユーティリティ関数を新たに作成
- TypeScriptを導入し、型定義を追加
- Viteを使用してビルド設定を行う
- データベース初期化SQLから不要なデータを削除
Forgotコンポーネントの入力フィールドのプレースホルダーを"s12xxxxx"から"s13xxxxx"に変更しました。
Question.module.cssのh2セレクタから重複したfont-weightプロパティを削除しました。
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Top.tsxの「Forgot card?」リンクのクラス名を「forgotLink」から「forgotPos」に変更しました。
h3セレクタから重複していたfont-weightプロパティを削除しました。
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
README.mdから特定の環境向けのビルド手順を削除しました。
Top.tsxの50行目で、カードリーダーが停止した際にconnectCardReader()を呼び出すのではなく、window.location.reload()を実行するように変更しました。
Top.tsxの「Forgot card?」リンクのクラス名を「forgotPos」から「forgetPos」に変更しました。
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Top.tsxファイルで、react-routerからreact-router-domへのインポートを変更しました。
Top.tsxでconnectCardReader関数をuseCallbackでラップし、再接続時の処理を改善しました。また、WebSocketのoncloseイベントでの再接続処理を修正しました。
eslint.config.jsからdefineConfigのインポートを削除し、エクスポートを簡素化しました。
- go.modにgithub.com/gorilla/websocket v1.5.3とgithub.com/slack-go/slack v0.17.3を追加しました。
- go.sumに対応するハッシュを追加しました。
- WebHookおよびAttachment構造体を削除し、slack-goライブラリのWebhookMessageを直接使用するように変更
- SlackNotify関数内の変数名を小文字に統一し、可読性を向上
- エラーハンドリングのメッセージを改善
- .gitignoreに.envファイルを追加
- go.modから依存関係を整理し、Slackの依存関係を直接追加
- SlackのSocket Modeクライアントを初期化する機能を追加
- Slackの設定構造体を更新し、必要なトークンを環境変数から取得
- Slack通知機能を改善し、Socket Modeを使用するように変更
- Forgot.tsx: useLocationを追加し、エラーメッセージを表示する機能を実装
- Top.tsx: カードリーダー通信エラー時のナビゲーション先を'/forgot'に変更
- App.module.cssのフォントファミリーをverdanaから"Noto Sans"に変更しました。
- フォントのインポート文を追加しました。
Welcomeコンポーネントの挨拶文を「Welcome to {room},<br/>{username}!」に変更し、改行を追加しました。
- HTTP POSTリクエストによるファイルアップロードを、SlackクライアントのUploadFileV2メソッドを使用する形式に変更
- 不要なインポート文を削除
- エラーハンドリングを簡素化
Top.tsxにおいて、カードリーダーのエラー処理をcardReaderError関数として抽出し、エラーハンドリングを一元化しました。これにより、コードの可読性と保守性が向上しました。
socket.goファイルのReaderErrorRetryDelayを60秒から5秒に変更しました。これにより、NFCリーダーエラー発生時の再試行が迅速になります。
- Welcome.tsx: ユーザー名がある場合とない場合で表示内容を分岐させるロジックを追加
- api.ts: 不要な204ステータスの処理を削除
- log.go: 不要なエラーハンドリングを削除
- user.go: ユーザー作成ハンドラーを削除し、GETメソッドの処理に統一
- slack.go: 未登録ユーザーの通知メッセージを追加
- update_app.sh: アプリケーションの再ビルドを行うスクリプトを追加
- update_user.sh: ユーザー情報をデータベースにインポートするスクリプトを追加
'scripts/update_app.sh'ファイル内のgit pullコマンドのブランチ名を'main'から'master'に修正しました。
- nfc_reader.pyのファイルモードを100644から100755に変更し、実行可能にしました。
- 新規ファイル: scripts/frontstart.shを追加
- elsystemf.serviceのExecStartを/home/geek/EnterLeaveSystem/scripts/frontstart.shに変更
elsystemf.serviceファイルを削除しました。このファイルはもはや必要なくなったため、コードベースから除去しました。
update_app.shからelsystemf.serviceの停止および開始のコマンドを削除しました。これにより、サービスの管理がelsystemd.serviceのみに統一されました。
log.goファイルのAddLog関数において、ユーザーが未登録の場合にプレースホルダーを作成する処理を追加しました。これにより、ユーザーの入退室ステータスを更新する際のエラーハンドリングが強化されました。
@kashu-02 kashu-02 marked this pull request as ready for review January 10, 2026 13:28
Copilot AI review requested due to automatic review settings January 10, 2026 13:28
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request represents a major refactoring of the Enter Leave System, modernizing both the backend and frontend infrastructure. The changes include migrating from Vue.js to React 19 with TypeScript, updating the Slack integration from webhooks to the official slack-go SDK with socket mode support, improving database schema with constraints and indexes, adding graceful shutdown to the server, and updating the NFC reader from Python 2.7 to Python 3.

Changes:

  • Backend: Migrated Slack integration to slack-go SDK, added database constraints and transactions, implemented graceful shutdown, updated cron library, and improved error handling
  • Frontend: Complete migration from Vue.js 2 to React 19 with TypeScript, replaced Vue Router with React Router v7, modernized build tooling from Vue CLI to Vite
  • Infrastructure: Updated NFC reader to Python 3, revised deployment scripts, updated GitHub Actions workflow, and improved systemd service configuration

Reviewed changes

Copilot reviewed 74 out of 86 changed files in this pull request and generated 28 comments.

Show a summary per file
File Description
go.mod Updated Go version and dependencies (critical: invalid version specified)
server/utils/slack.go Refactored to use slack-go SDK with socket mode instead of webhooks
server/utils/csvexport.go Updated to use slack-go client for file uploads
server/utils/cron.go Updated cron library to v3 with improved comments
server/utils/config.go Restructured Slack configuration for new SDK
server/main.go Added graceful shutdown, structured logging, and improved initialization
server/handler/user.go Removed POST endpoint, added validation (breaking change)
server/handler/socket.go Added mutex protection, improved error handling, updated NFC reader path
server/handler/log.go Refactored request parsing, removed user existence validation
server/handler/handler.go Added common utility functions for validation and error handling
server/db/db.go Added PRIMARY KEY, FOREIGN KEY constraints, connection pooling, and indexes
server/db/user.go Improved error messages, added transaction support for ForceLeave
server/db/log.go Added transaction support, auto-creates placeholder users
server/nfc/nfc_reader.py Migrated from Python 2.7 to Python 3 with improved code structure
server/test/init.sql Removed test data (schema mismatch with production)
scripts/*.sh Updated deployment and utility scripts
scripts/elsystemd.service Updated systemd service configuration
front/src/**/*.tsx Complete frontend rewrite in React 19 with TypeScript
front/package.json Updated to Vite, React 19, and modern tooling
.github/workflows/main.yml Updated GitHub Actions to use newer action versions
Comments suppressed due to low confidence (2)

scripts/update_user.sh:10

  • The database path is relative ("database.db") in line 10 of scripts/update_user.sh, but the script doesn't ensure it's running from the correct directory. If run from the scripts directory, it will create/modify a database file in the wrong location. Consider using an absolute path or changing directory to the project root first.
    server/handler/log.go:76
  • The removal of the username check (previously lines 61-65) means that unregistered users can now create logs. This is a significant behavior change. While the AddLog function in db/log.go creates placeholder users (lines 50-54), this bypasses the previous validation that required users to be registered first. This could lead to database pollution with auto-created user entries. Consider whether this is intentional or if the validation should be restored.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

server/db/db.go Outdated
},
{
name: "idcard",
schema: `CREATE TABLE IF NOT EXISTS "idcard" (idm TEXT PRIMARY KEY, sid TEXT NOT NULL, FOREIGN KEY(sid) REFERENCES users(sid))`,
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idcard table has a FOREIGN KEY constraint referencing users(sid), but there's no ON DELETE or ON UPDATE clause specified. If a user is deleted, orphaned card records would remain. Consider adding ON DELETE CASCADE or ON DELETE SET NULL depending on the desired behavior.

Copilot uses AI. Check for mistakes.
Comment on lines +30 to +33
except Exception as e:
# General card - use IDm as identifier
idm_hex = "".join([f"{s:02x}" for s in tag.idm])
print(f"general {idm_hex}")
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The exception handler on line 30 catches all exceptions but doesn't log or report what the actual error was. This makes debugging difficult when legitimate errors occur (not just general cards). Consider logging the exception details before falling back to using the IDm.

Copilot uses AI. Check for mistakes.
Comment on lines 3 to 5
CREATE TABLE IF NOT EXISTS "users" (sid TEXT,name TEXT,isenter INTEGER);
INSERT INTO users VALUES('s1240095','Yusuke Namiki',0);
CREATE TABLE IF NOT EXISTS "idcard" (idm TEXT,sid TEXT);
CREATE TABLE IF NOT EXISTS "log" (sid TEXT,isenter INTEGER,time INTEGER,ext TEXT);
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test database schema (lines 3-5) doesn't match the production schema defined in server/db/db.go (lines 56-67). The production schema has PRIMARY KEY constraints, FOREIGN KEY constraints, DEFAULT values, and an autoincrement ID column in the log table, while the test schema lacks all of these. This mismatch could cause tests to pass while production fails, or vice versa. The schemas should be synchronized.

Copilot uses AI. Check for mistakes.
Comment on lines +36 to +42
def main():
"""Main function to initialize NFC reader and wait for cards."""
clf = nfc.ContactlessFrontend('usb')
try:
clf.connect(rdwr={'on-connect': on_connect})
finally:
clf.close()
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main function doesn't handle exceptions that might occur during NFC reader initialization or connection (lines 38-42). If the USB device is not found or initialization fails, the script will crash with an unhandled exception. Consider adding try-except error handling with a meaningful error message.

Copilot uses AI. Check for mistakes.
Comment on lines 49 to 54
switch r.Method {
case "GET":
getUserHandler(w, r, h.DB)
case "POST":
createUserHandler(w, r, h.DB)
default:
w.WriteHeader(http.StatusMethodNotAllowed)
fmt.Fprintf(w, "Unexpected method")
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the POST handler for registCardInfo (lines 20-38), the API endpoint still exists in the frontend code (front/src/utils/api.ts), but the corresponding POST handler was removed from server/handler/user.go (previously at lines 52-99). This means card registration will fail with a 405 Method Not Allowed error. Either restore the POST handler or remove the frontend registration functionality.

Copilot uses AI. Check for mistakes.
#!/usr/bin/env python3
"""NFC card reader for student ID and university cards."""

import sys
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Import of 'sys' is not used.

Copilot uses AI. Check for mistakes.
- `EnvironmentFile`, `WorkingDirectory`, `ExecStart`のパスをユーザーのホームディレクトリから相対パスに変更しました。
- db.go: idcardテーブルの作成を削除
- user.go: GetUIDByCardIDおよびRegisterCard関数を削除
- init.sql: 初期化SQLファイルを削除
- App.tsx: 時計の更新間隔を500msから1000msに変更
- Forgot.tsx: SIDをAINSIDに変更し、関連する処理を更新
- Question.tsx: SIDをAINSIDに変更し、ログ追加処理を修正
- Register.module.css: クラス名をstudentNUMからainsIDに変更
- Register.tsx: SIDをAINSIDに変更し、関連する処理を更新
- Top.tsx: SIDをAINSIDに変更し、ユーザー情報取得処理を修正
- Welcome.tsx: SIDをAINSIDに変更し、ログ追加処理を修正
- index.ts: UserInfoインターフェースのSIDをAINSIDに変更
- api.ts: getUserInfoとregistCardInfoの引数をSIDからAINSIDに変更
- update_user.sh: ユーザー情報取得スクリプトを修正
- db.go: usersテーブルのSIDをAINSIDに変更
- idcard.go: 新規ファイル作成、AINSIDを使用したカード登録処理を追加
- log.go: ログ処理でのUIDをAINSIDに変更
- user.go: ユーザー情報取得関数をAINSIDに基づくものに変更
- socket.go: IDCardInfo構造体のSIDをAINSIDに変更
- handler.go: SID検証関数をAINSID用に変更
- log.go: ログ処理でのUIDをAINSIDに変更
- ERdiagram.png, api.md, seq.pu, sequence.png, state.png, state.pu, react.svg のファイルを削除しました。
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 78 out of 92 changed files in this pull request and generated 6 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +94 to +95
usage := extMap["Use"]
mess := extMap["message"]
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed type assertions without error checking. Lines 94-95 access extMap["Use"] and extMap["message"] without checking if the keys exist or if the values are the expected types. This could cause a panic if the JSON structure is unexpected. The old code had type assertions with explicit error handling.

Copilot uses AI. Check for mistakes.
resp, err := client.PostForm(
IncomingURL,
url.Values{"payload": {string(params)}},
log.Println(cfg.ChannelID)
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Debug log statement that should be removed before production deployment.

Copilot uses AI. Check for mistakes.
Comment on lines +29 to +32
except Exception as e:
# General card - use IDm as identifier
idm_hex = "".join([f"{s:02x}" for s in tag.idm])
print(f"general {idm_hex}")
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The except block on line 29 catches all exceptions and treats them as general cards. This means genuine errors (like NFC communication failures, decode errors, or IndexError from accessing data[0:4]) will be silently treated as a general card. Consider logging the exception details or handling specific expected exceptions separately from unexpected errors.

Copilot uses AI. Check for mistakes.
import type { UserInfo, RegistResponse } from '../types';

export const getUserInfo = async (ainsID: string): Promise<UserInfo> => {
const response = await fetch(`http://localhost:3000/api/user?AINSID=${ainsID}`, {
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoded localhost URL. The API URL should be configurable via environment variable to support different deployment environments (development, staging, production). Consider using import.meta.env.VITE_API_URL or a similar approach.

Copilot uses AI. Check for mistakes.
func ForceLeave(d *sql.DB) error {
rows, err := d.Query(`SELECT * FROM users where isenter=1`)
// Select all users who are currently in the room
rows, err := tx.Query(`SELECT ainsID FROM log WHERE isEnter=1 AND time<?`, yesterdayStartTime)
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ForceLeave function has a logic issue. It queries SELECT ainsID FROM log WHERE isEnter=1 AND time<? which will select ALL historical enter logs before yesterday, not just users currently in the room. The function should query for the latest log entry per user and check if that entry is an enter (isEnter=1). The current implementation could create duplicate leave logs for users who aren't actually in the room.

Copilot uses AI. Check for mistakes.
}

err = db.RegisterCard(userdat.CardID, userdat.UID, d)
err := db.RegisterCard(userdat.CardID, userdat.AINSID, d)
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CardID from the request is not validated before being passed to db.RegisterCard. The validateCardID function exists in handler.go but is never used. This could allow empty or excessively long CardID values to be stored in the database. Add validation for userdat.CardID before line 119.

Copilot uses AI. Check for mistakes.
- user.go: SQLクエリを修正し、ユーザー名と入室状況を取得するロジックを改善しました。
- nfc_reader.py: 出力される学生IDをs1300071に変更しました。
@kashu-02 kashu-02 merged commit 3d1797a into master Jan 31, 2026
1 of 3 checks passed
@kashu-02 kashu-02 deleted the reafactor-202512 branch January 31, 2026 14:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants