Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions .cursor/rules/coding_rules.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# コーディングルール

## 共通ルール

- ボーイスカウトルールに従う:コードを見つけたときよりも綺麗にする
- YAGNI(You Aren't Gonna Need It)の原則に従う:必要になるまで機能を実装しない
- DRY(Don't Repeat Yourself)の原則に従う:再利用可能なロジックを関数に抽出し、コードの重複を避ける
- KISS(Keep It Simple Stupid)の原則に従う:シンプルで分かりやすいコードを書く
- SOLIDの原則に従う
- タイポを検出し、修正を提案する

## TypeScript/JavaScript

- インデントには2スペースを使用
- Google JavaScript Style Guideに準拠
- MDNにリストされている非推奨または廃止された機能の使用を避ける
- プロパティ名にはキャメルケースを使用し、必要に応じてPropTypesを適用
- フックの使用に関する公式Reactガイドラインに従う
- インラインスタイルを避ける
- 'var'の代わりに'let'または'const'を使用
- パフォーマンス最適化(メモ化、レンダリング最適化)を適切に実装
- 不要な再レンダリングを防ぐために、関数コンポーネントにはReact.memo()を、クラスコンポーネントにはPureComponentを使用
- コード分割と遅延ロードを実装
- セキュリティ脆弱性(特にXSS)に注意
- ユーザー入力をサニタイズし、dangerouslySetInnerHTMLの使用を避ける

## Go

- インデントにはタブを使用(Go言語の標準的な方法)
- gofmtツールを使用してコードをフォーマット
- goimportsを使用してインポートを管理
- go vetを使用して疑わしい構造を検出
- golintを使用してスタイルエラーを検出
- テストとベンチマークの実行
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Lintツールの統一性を確認してください

golintは非推奨となっており、現在はstaticcheckgolangci-lintの使用が推奨されています。ツールの推奨事項を最新のものに更新することを検討してください。

最新のGo lintingツールの推奨事項を確認するために、以下の情報を検索してください:


🌐 Web query:

Go言語の最新のlintingツール推奨事項 golint 非推奨 staticcheck golangci-lint 2024

💡 Result:

Go言語の静的解析ツールとして、golintはメンテナンスが行われておらず、非推奨となっています。代替として、以下のツールが推奨されています。

1. staticcheck

staticcheckは、Goコードの静的解析を行うツールで、バグの検出やコードの簡素化、未使用コードの検出など、多岐にわたるチェックを提供します。GoチームやGoogleがスポンサーとなっており、信頼性の高いツールです。特定のチェック項目を無効にするなどの設定も可能で、ソースコード内に//lint:ignore Check1[,Check2,...,CheckN] reasonとコメントすることで、特定の警告を無効にできます。 (zenn.dev)

2. revive

reviveは、golintの代替として開発されたツールで、より高速で厳格、かつ拡張性の高い静的解析を提供します。設定可能なルールセットやカスタムルールの追加が可能で、柔軟なコードスタイルのチェックが行えます。 (best-of-web.builder.io)

3. golangci-lint

golangci-lintは、複数の静的解析ツールを統合したラッパーで、staticcheckreviveなど、さまざまなツールを一元的に管理・実行できます。これにより、複数のツールを個別に設定・実行する手間を省き、効率的なコード品質の維持が可能となります。 (golangci-lint.run)

これらのツールは、Go言語のコード品質向上に役立つ強力なツールです。プロジェクトのニーズやチームの方針に合わせて、適切なツールを選択・導入することをおすすめします。

Citations:


Lintツールの推奨を golint から staticcheck / golangci-lint に更新してください

  • ファイル: .cursor/rules/coding_rules.md
  • 行: 33–34

golint は非推奨となっているため、以下のいずれかを検討してください:

- golintを使用してスタイルエラーを検出
+ staticcheckを使用して静的解析とスタイルチェックを実行

または

- golintを使用してスタイルエラーを検出
+ golangci-lintを使用して静的解析とスタイルチェックを実行

プロジェクトの要件に合わせてツールを選択し、設定手順や実行コマンドをドキュメントに追記してください。

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- golintを使用してスタイルエラーを検出
- テストとベンチマークの実行
- staticcheckを使用して静的解析とスタイルチェックを実行
- テストとベンチマークの実行
Suggested change
- golintを使用してスタイルエラーを検出
- テストとベンチマークの実行
- golangci-lintを使用して静的解析とスタイルチェックを実行
- テストとベンチマークの実行
🤖 Prompt for AI Agents
In .cursor/rules/coding_rules.md around lines 33 to 34, update the linting tool
recommendation from the deprecated 'golint' to a currently supported tool such
as 'staticcheck' or 'golangci-lint'. Replace the mention of 'golint' with the
chosen tool's name, and add instructions for installing, configuring, and
running the new lint tool according to the project's needs.

- Go Style Guideに従う
- クリーンアーキテクチャの原則に従う
- DDD(Domain-Driven Design)の原則を適用

## React (TSX)

- セマンティックなHTML要素を使用
- Reactのベストプラクティスに従う
- WAI-ARIA属性を実装
- 適切なキーボードナビゲーションサポート
- 可視テキストのない要素にはaria-labelまたはaria-labelledbyを使用
- モーダルやその他の動的コンテンツにフォーカス管理を実装

## テスト

- テストフレームワークのベストプラクティスに従う
- テストの説明を詳細に記述
- 適切なアサーションとマッチャーを使用
- 重要なパスとエッジケースのテストカバレッジを実装
- テストを独立させ、テスト間で状態を共有しない

## Docker

- Dockerfile Best Practicesに従う
- マルチステージビルドを活用
- 適切なベースイメージを選択
- ビルドキャッシュを効果的に利用
- 最小権限の原則に従う
- .dockerignoreファイルを使用
- RUN命令を結合
- 適切な環境変数の設定
- 必要最小限のファイルのみをコピー
- ヘルスチェックの実装
- Linterツールの使用を検討

## Markdown

- [markdownlint-cli2](https://github.com/DavidAnson/markdownlint-cli2)に準拠していること
7 changes: 7 additions & 0 deletions .cursor/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// TODO:機能している?
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

JSONにコメントは許可されていません。
このままではパースエラーになります。コメントを削除するか、.jsoncに変更してください。

🧰 Tools
🪛 Biome (1.9.4)

[error] 1-3: Expected an array, an object, or a literal but instead found '// TODO:機能している?'.

Expected an array, an object, or a literal here.

(parse)

🤖 Prompt for AI Agents
In .cursor/settings.json at line 1, there is a comment which is not allowed in
standard JSON and will cause a parse error. Remove the comment entirely or
rename the file to use the .jsonc extension to allow comments.

{
"cursor.review": {
"enabled": true,
"autoReview": true
}
}
3 changes: 1 addition & 2 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ if [ -n "$CHANGED_GO_FILES" ]; then
# Lint
echo "Running golangci-lint..."
docker-compose run -T --rm lint
if [ $? -ne 0 ];then
if [ $? -ne 0 ]; then
echo "golangci-lint failed. Please fix the issues before committing."
exit 1
fi
Expand All @@ -32,7 +32,6 @@ if [ -n "$CHANGED_MD_FILES" ]; then
# Markdown Lint
echo "Running markdownlint..."
docker-compose run -T --rm markdownlint npx markdownlint-cli2 --fix $CHANGED_MD_FILES
# npx markdownlint-cli2 --fix $CHANGED_MD_FILES
if [ $? -ne 0 ]; then
echo "markdownlint failed. Please fix the issues before committing."
exit 1
Expand Down
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,3 @@

# テストカバレッジレポート
*/coverage.out

node_modules/
3 changes: 2 additions & 1 deletion .vscode/extensions.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"bierner.markdown-mermaid",
"bradlc.vscode-tailwindcss",
"christian-kohler.npm-intellisense",
"davidanson.vscode-markdownlint"
"davidanson.vscode-markdownlint",
"ms-azuretools.vscode-docker"
]
}
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
# README

## Setup

[Setup procedure](./docs/develop/setup/index.md)
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

リンク先ファイルの存在を確認してください。
docs/develop/setup/index.md が実際に存在するかご確認を。存在しない場合、リンク切れになります。


🏁 Script executed:

#!/bin/bash
# 新規READMEリンク先ファイルの有無チェック
if [ ! -f docs/develop/setup/index.md ]; then
  echo "docs/develop/setup/index.md not found"
  exit 1
fi

Length of output: 138


リンク切れ検出: docs/develop/setup/index.md が存在しません
README.md の 5行目で指定されたリンク先ファイルがリポジトリ内に見つかりませんでした。リンクを正しいパスに修正するか、該当ファイルを追加してください。

  • ファイル: README.md(5行目)
    内容:
    [Setup procedure](./docs/develop/setup/index.md)
    
🤖 Prompt for AI Agents
In README.md at line 5, the link points to ./docs/develop/setup/index.md, but
this file does not exist in the repository. To fix this, either create and add
the missing file at the specified path or update the link to point to the
correct existing file location to avoid broken links.


## Other

![CodeRabbit Pull Request Reviews](https://img.shields.io/coderabbit/prs/github/zucky2021/book-tracker-v2?labelColor=171717&color=FF570A&link=https%3A%2F%2Fcoderabbit.ai&label=CodeRabbit%20Reviews)
1 change: 1 addition & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ services:
markdownlint:
image: node:24-alpine
container_name: markdownlint
restart: no
working_dir: /work
volumes:
- .:/work
Expand Down
1 change: 1 addition & 0 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const App: React.FC = () => {
const checkHealth = async (retries = 5) => {
for (let i = 0; i < retries; i++) {
try {
// FIXME:URLのハードコードを避ける
const response = await fetch("http://localhost:8080/health");
Comment on lines +12 to 13
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

エンドポイントURLを環境変数に切り出してください。
ハードコーディングされたURLは環境によって異なるため、Viteのimport.meta.env.VITE_HEALTH_URLなどで設定を注入し、FIXMEコメントは修正後に削除しましょう。

-          // FIXME:URLのハードコードを避ける
-          const response = await fetch("http://localhost:8080/health");
+          const healthUrl = import.meta.env.VITE_HEALTH_URL || "http://localhost:8080/health";
+          const response = await fetch(healthUrl);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// FIXME:URLのハードコードを避ける
const response = await fetch("http://localhost:8080/health");
const healthUrl = import.meta.env.VITE_HEALTH_URL || "http://localhost:8080/health";
const response = await fetch(healthUrl);
🤖 Prompt for AI Agents
In frontend/src/App.tsx around lines 12 to 13, the health check URL is hardcoded
as "http://localhost:8080/health". Replace this hardcoded URL with an
environment variable by using Vite's import.meta.env.VITE_HEALTH_URL to inject
the URL dynamically. After updating the code to use the environment variable,
remove the FIXME comment to reflect the fix.

if (response.ok) {
const data = await response.json();
Expand Down
19 changes: 12 additions & 7 deletions frontend/src/components/Memo.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useState } from "react";
import { memo, useEffect, useState } from "react";

type MemoProps = {
bookId: string;
Expand All @@ -17,12 +17,14 @@ type MemoData = {
};

// メモモーダル
const Memo = ({ bookId, userId, onClose }: MemoProps) => {
const Memo = memo(({ bookId, userId, onClose }: MemoProps) => {
const [memoText, setMemoText] = useState("");
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const [imgFile, setImgFile] = useState<File | null>(null);

const maxMemoLength = 1000;

useEffect(() => {
const fetchMemo = async () => {
setLoading(true);
Expand All @@ -34,7 +36,6 @@ const Memo = ({ bookId, userId, onClose }: MemoProps) => {
);
if (res.ok) {
const data: { memo: MemoData | null } = await res.json();
console.log("Fetched memo data:", data.memo?.text);
setMemoText(data.memo?.text || "");
} else if (res.status === 404) {
setMemoText("");
Expand Down Expand Up @@ -68,7 +69,7 @@ const Memo = ({ bookId, userId, onClose }: MemoProps) => {
formData.append("bookId", bookId);
formData.append("text", memoText);
if (imgFile) {
formData.append("image", imgFile);
formData.append("imgFile", imgFile);
}

const res = await fetch("http://localhost:8080/api/memo", {
Expand All @@ -86,12 +87,12 @@ const Memo = ({ bookId, userId, onClose }: MemoProps) => {

return (
<div
className="fixed inset-0 z-50 flex items-center justify-items-center bg-black/10"
className="fixed inset-0 z-50 flex items-center justify-center bg-black/10"
role="dialog"
aria-modal="true"
>
<div className="mx-auto w-80 rounded bg-white p-6 shadow-lg">
<h4 className="test-lg mb-2 font-bold">Memo</h4>
<h4 className="text-lg mb-2 font-bold">Memo</h4>
{loading ? (
<p>Loading...</p>
) : (
Expand All @@ -103,7 +104,11 @@ const Memo = ({ bookId, userId, onClose }: MemoProps) => {
onChange={(e) => setMemoText(e.target.value)}
placeholder="Let's Input memo!"
required
maxLength={maxMemoLength}
/>
<p className="text-sm text-gray-500">
{memoText.length}/{maxMemoLength}
</p>
<input
type="file"
accept="image/*"
Expand Down Expand Up @@ -131,6 +136,6 @@ const Memo = ({ bookId, userId, onClose }: MemoProps) => {
</div>
</div>
);
};
});

export default Memo;
Loading