/`ãå¯äžã®éçŽç¹ã `api/router.py`ã`tests/` ã¯ã©ã³ã¿ã€ã ã¢ãžã¥ãŒã«ããã©ãŒã
+- **ãã¡ã€ã³ã®è¿œå **: `items/` ãã³ããŒããšã³ãã£ã㣠/ ã¹ããŒã / ã¯ã©ã¹ããªããŒã ã`__init__.py` ã®åãšã¯ã¹ããŒããæŽæ°ã`src/app/api/router.py` ã§ router ãç»é²ããã¹ãã¢ãžã¥ãŒã«ã远å ã`main.py` ã®ç·šéã¯äžèŠã§ãã
diff --git a/docs/ja/tutorial/first-project.md b/docs/ja/tutorial/first-project.md
new file mode 100644
index 0000000..7e7cc03
--- /dev/null
+++ b/docs/ja/tutorial/first-project.md
@@ -0,0 +1,1252 @@
+# æåã®ãããžã§ã¯ã
+
+FastAPI-fastkit ã䜿ã£ãŠããŠãŒã¶ãŒç®¡çã»æçš¿äœæã»ã³ã¡ã³ãæ©èœãåããå®å
šãªããã° API ãæ§ç¯ããŸãã
+
+## ãããžã§ã¯ãæŠèŠ
+
+ãã®ãã¥ãŒããªã¢ã«ã§ã¯ãæ¬¡ã®æ©èœãæã€ **ããã° API** ãäœæããŸã:
+
+- **ãŠãŒã¶ãŒç®¡ç**: ãŠãŒã¶ãŒç»é²ãèªèšŒããããã£ãŒã«
+- **æçš¿ç®¡ç**: ããã°æçš¿ã®äœæã»ååŸã»æŽæ°ã»åé€
+- **ã³ã¡ã³ãæ©èœ**: ããã°æçš¿ã«ã³ã¡ã³ãã远å
+- **ããŒã¿æ€èšŒ**: å
ç¢ãªå
¥åæ€èšŒãšãšã©ãŒåŠç
+- **API ããã¥ã¡ã³ã**: èªå OpenAPI ããã¥ã¡ã³ã
+- **ãã¹ã**: å
æ¬çãªãã¹ãã¹ã€ãŒã
+
+### åŠã¹ãããš
+
+ãã®ãã¥ãŒããªã¢ã«ãçµãããšã次ãçè§£ã§ããŸã:
+
+- FastAPI-fastkit ãããžã§ã¯ãã®å¿çšçãªæ§é
+- SQLAlchemy ã«ããããŒã¿ããŒã¹çµ±å
+- ãŠãŒã¶ãŒèªèšŒãšèªå¯
+- è€éãªããŒã¿é¢ä¿
+- ãšã©ãŒåŠçãšæ€èšŒ
+- ãã¹ãã®ãã¹ããã©ã¯ãã£ã¹
+
+## åææ¡ä»¶
+
+éå§åã«ã次ãçšæãããŠããããšã確èªããŠãã ãã:
+
+- [ã¯ããã«](getting-started.md) ãã¥ãŒããªã¢ã«ãå®äºæžã¿
+- REST API ã®åºæ¬çè§£
+- Python 3.12 以äžãã€ã³ã¹ããŒã«æžã¿
+- ããã¹ããšãã£ã¿ãŸã㯠IDE ãå©çšå¯èœ
+
+## ã¹ããã 1: ãããžã§ã¯ãã®äœæ
+
+ããŒã¿ããŒã¹å¯Ÿå¿ãå«ããããã**STANDARD** ã¹ã¿ãã¯ã§æ°ãããããžã§ã¯ããäœæããŸã:
+
+
+
+```console
+$ fastkit init
+Enter the project name: blog-api
+Enter the author name: Your Name
+Enter the author email: your.email@example.com
+Enter the project description: A complete blog API with users, posts, and comments
+
+ Project Information
+ââââââââââââââââ¬ââââââââââââââââââââââââââââââââââââââââââ
+â Project Name â blog-api â
+â Author â Your Name â
+â Author Email â your.email@example.com â
+â Description â A complete blog API with users, posts, â
+â â and comments â
+ââââââââââââââââŽââââââââââââââââââââââââââââââââââââââââââ
+
+Available Stacks and Dependencies:
+ MINIMAL Stack
+ââââââââââââââââ¬ââââââââââââââââââââ
+â Dependency 1 â fastapi â
+â Dependency 2 â uvicorn â
+â Dependency 3 â pydantic â
+â Dependency 4 â pydantic-settings â
+ââââââââââââââââŽââââââââââââââââââââ
+
+ STANDARD Stack
+ââââââââââââââââ¬ââââââââââââââââââââ
+â Dependency 1 â fastapi â
+â Dependency 2 â uvicorn â
+â Dependency 3 â sqlalchemy â
+â Dependency 4 â alembic â
+â Dependency 5 â pytest â
+â Dependency 6 â pydantic â
+â Dependency 7 â pydantic-settings â
+ââââââââââââââââŽââââââââââââââââââââ
+
+Select stack (minimal, standard, full): standard
+
+Available Package Managers:
+ Package Managers
+ââââââââââ¬âââââââââââââââââââââââââââââââââââââââââââââ
+â PIP â Standard Python package manager â
+â UV â Fast Python package manager â
+â PDM â Modern Python dependency management â
+â POETRY â Python dependency management and packaging â
+ââââââââââŽâââââââââââââââââââââââââââââââââââââââââââââ
+
+Select package manager (pip, uv, pdm, poetry) [uv]: uv
+Do you want to proceed with project creation? [y/N]: y
+
+âš FastAPI project 'blog-api' has been created successfully!
+```
+
+
+
+## ã¹ããã 2: ãããžã§ã¯ãã®ã»ããã¢ãã
+
+ãããžã§ã¯ãã«ç§»åããä»®æ³ç°å¢ãæå¹åããŸã:
+
+
+
+```console
+$ cd blog-api
+$ source .venv/bin/activate
+```
+
+
+
+## ã¹ããã 3: å¿
èŠãªã«ãŒãã远å
+
+ããã° API ã®ã¡ã€ã³ãªãœãŒã¹ã远å ããŸããã:
+
+
+
+```console
+$ fastkit addroute users blog-api
+âš Successfully added new route 'users' to project 'blog-api'
+
+$ fastkit addroute posts blog-api
+âš Successfully added new route 'posts' to project 'blog-api'
+
+$ fastkit addroute comments blog-api
+âš Successfully added new route 'comments' to project 'blog-api'
+```
+
+
+
+## ã¹ããã 4: ããŒã¿ã¢ãã«ã®èšèš
+
+ããŒã¿ã¹ããŒããèšèšããŸããããå®çšçãªå
容ã«ããããããŸããŠãŒã¶ãŒã¹ããŒããæŽæ°ããŸãããã
+
+### ãŠãŒã¶ãŒã¹ããŒãã®æŽæ°
+
+`src/schemas/users.py` ãç·šéããŸã:
+
+```python
+from typing import Optional, List
+from datetime import datetime
+from pydantic import BaseModel, EmailStr, Field
+
+class UserBase(BaseModel):
+ email: EmailStr
+ username: str = Field(..., min_length=3, max_length=50)
+ full_name: Optional[str] = None
+ bio: Optional[str] = Field(None, max_length=500)
+ is_active: bool = True
+
+class UserCreate(UserBase):
+ password: str = Field(..., min_length=8)
+
+class UserUpdate(BaseModel):
+ email: Optional[EmailStr] = None
+ username: Optional[str] = Field(None, min_length=3, max_length=50)
+ full_name: Optional[str] = None
+ bio: Optional[str] = Field(None, max_length=500)
+ is_active: Optional[bool] = None
+
+class User(UserBase):
+ id: int
+ created_at: datetime
+ posts_count: int = 0
+
+ class Config:
+ from_attributes = True
+
+class UserInDB(User):
+ hashed_password: str
+```
+
+### æçš¿ã¹ããŒãã®äœæ
+
+`src/schemas/posts.py` ãç·šéããŸã:
+
+```python
+from typing import Optional, List
+from datetime import datetime
+from pydantic import BaseModel, Field
+
+class PostBase(BaseModel):
+ title: str = Field(..., min_length=1, max_length=200)
+ content: str = Field(..., min_length=1)
+ published: bool = True
+
+class PostCreate(PostBase):
+ pass
+
+class PostUpdate(BaseModel):
+ title: Optional[str] = Field(None, min_length=1, max_length=200)
+ content: Optional[str] = Field(None, min_length=1)
+ published: Optional[bool] = None
+
+class Post(PostBase):
+ id: int
+ author_id: int
+ created_at: datetime
+ updated_at: datetime
+ comments_count: int = 0
+
+ class Config:
+ from_attributes = True
+
+class PostWithAuthor(Post):
+ author: "User"
+
+class PostWithComments(Post):
+ comments: List["Comment"] = []
+
+# 埪ç°ã€ã³ããŒããé¿ããããã®ã€ã³ããŒã
+from src.schemas.users import User
+from src.schemas.comments import Comment
+PostWithAuthor.model_rebuild()
+PostWithComments.model_rebuild()
+```
+
+### ã³ã¡ã³ãã¹ããŒãã®äœæ
+
+`src/schemas/comments.py` ãç·šéããŸã:
+
+```python
+from typing import Optional
+from datetime import datetime
+from pydantic import BaseModel, Field
+
+class CommentBase(BaseModel):
+ content: str = Field(..., min_length=1, max_length=1000)
+
+class CommentCreate(CommentBase):
+ post_id: int
+
+class CommentUpdate(BaseModel):
+ content: Optional[str] = Field(None, min_length=1, max_length=1000)
+
+class Comment(CommentBase):
+ id: int
+ post_id: int
+ author_id: int
+ created_at: datetime
+ updated_at: datetime
+
+ class Config:
+ from_attributes = True
+
+class CommentWithAuthor(Comment):
+ author: "User"
+
+# 埪ç°ã€ã³ããŒããé¿ããããã®ã€ã³ããŒã
+from src.schemas.users import User
+CommentWithAuthor.model_rebuild()
+```
+
+## ã¹ããã 5: é«åºŠãª CRUD æäœã®å®è£
+
+### ãŠãŒã¶ãŒ CRUD ã®æ¡åŒµ
+
+`src/crud/users.py` ãæŽæ°ããŸã:
+
+```python
+from typing import List, Optional
+from datetime import datetime
+import hashlib
+from src.schemas.users import UserCreate, UserUpdate, UserInDB
+
+class UsersCRUD:
+ def __init__(self):
+ self._users: List[UserInDB] = []
+ self._next_id = 1
+
+ def _hash_password(self, password: str) -> str:
+ """ã·ã³ãã«ãªãã¹ã¯ãŒãããã·ã¥ (æ¬çªã§ã¯ bcrypt ã䜿çš)"""
+ return hashlib.sha256(password.encode()).hexdigest()
+
+ def _verify_password(self, plain_password: str, hashed_password: str) -> bool:
+ """ããã·ã¥ãšãã¹ã¯ãŒããç
§å"""
+ return self._hash_password(plain_password) == hashed_password
+
+ def get_all(self) -> List[UserInDB]:
+ """ãã¹ãŠã®ãŠãŒã¶ãŒãååŸ"""
+ return [user for user in self._users if user.is_active]
+
+ def get_by_id(self, user_id: int) -> Optional[UserInDB]:
+ """ID ã§ãŠãŒã¶ãŒãååŸ"""
+ return next((user for user in self._users if user.id == user_id), None)
+
+ def get_by_email(self, email: str) -> Optional[UserInDB]:
+ """ã¡ãŒã«ã¢ãã¬ã¹ã§ãŠãŒã¶ãŒãååŸ"""
+ return next((user for user in self._users if user.email == email), None)
+
+ def get_by_username(self, username: str) -> Optional[UserInDB]:
+ """ãŠãŒã¶ãŒåã§ãŠãŒã¶ãŒãååŸ"""
+ return next((user for user in self._users if user.username == username), None)
+
+ def create(self, user: UserCreate) -> UserInDB:
+ """æ€èšŒä»ãã§æ°ãããŠãŒã¶ãŒãäœæ"""
+ # éè€ãã§ãã¯
+ if self.get_by_email(user.email):
+ raise ValueError("Email already registered")
+ if self.get_by_username(user.username):
+ raise ValueError("Username already taken")
+
+ new_user = UserInDB(
+ id=self._next_id,
+ email=user.email,
+ username=user.username,
+ full_name=user.full_name,
+ bio=user.bio,
+ is_active=user.is_active,
+ created_at=datetime.now(),
+ posts_count=0,
+ hashed_password=self._hash_password(user.password)
+ )
+ self._next_id += 1
+ self._users.append(new_user)
+ return new_user
+
+ def update(self, user_id: int, user_update: UserUpdate) -> Optional[UserInDB]:
+ """æ¢åãŠãŒã¶ãŒãæŽæ°"""
+ user = self.get_by_id(user_id)
+ if not user:
+ return None
+
+ # ã¡ãŒã« / ãŠãŒã¶ãŒåã®éè€ãã§ãã¯
+ update_data = user_update.dict(exclude_unset=True)
+ if "email" in update_data and update_data["email"] != user.email:
+ if self.get_by_email(update_data["email"]):
+ raise ValueError("Email already registered")
+
+ if "username" in update_data and update_data["username"] != user.username:
+ if self.get_by_username(update_data["username"]):
+ raise ValueError("Username already taken")
+
+ for field, value in update_data.items():
+ setattr(user, field, value)
+
+ return user
+
+ def delete(self, user_id: int) -> bool:
+ """ãŠãŒã¶ãŒãè«çåé€ (éã¢ã¯ãã£ãå)"""
+ user = self.get_by_id(user_id)
+ if user:
+ user.is_active = False
+ return True
+ return False
+
+ def authenticate(self, email: str, password: str) -> Optional[UserInDB]:
+ """ã¡ãŒã«ãšãã¹ã¯ãŒãã§ãŠãŒã¶ãŒãèªèšŒ"""
+ user = self.get_by_email(email)
+ if user and self._verify_password(password, user.hashed_password):
+ return user
+ return None
+
+users_crud = UsersCRUD()
+```
+
+### æçš¿ã® CRUD
+
+`src/crud/posts.py` ãæŽæ°ããŸã:
+
+```python
+from typing import List, Optional
+from datetime import datetime
+from src.schemas.posts import PostCreate, PostUpdate, Post
+
+class PostsCRUD:
+ def __init__(self):
+ self._posts: List[Post] = []
+ self._next_id = 1
+
+ def get_all(self, skip: int = 0, limit: int = 100, published_only: bool = True) -> List[Post]:
+ """ããŒãžããŒã·ã§ã³ä»ãã§å
šæçš¿ãååŸ"""
+ posts = self._posts
+ if published_only:
+ posts = [post for post in posts if post.published]
+ return posts[skip:skip + limit]
+
+ def get_by_id(self, post_id: int) -> Optional[Post]:
+ """ID ã§æçš¿ãååŸ"""
+ return next((post for post in self._posts if post.id == post_id), None)
+
+ def get_by_author(self, author_id: int, skip: int = 0, limit: int = 100) -> List[Post]:
+ """äœè
ããšã®æçš¿ãååŸ"""
+ author_posts = [post for post in self._posts if post.author_id == author_id]
+ return author_posts[skip:skip + limit]
+
+ def create(self, post: PostCreate, author_id: int) -> Post:
+ """æ°ããæçš¿ãäœæ"""
+ now = datetime.now()
+ new_post = Post(
+ id=self._next_id,
+ title=post.title,
+ content=post.content,
+ published=post.published,
+ author_id=author_id,
+ created_at=now,
+ updated_at=now,
+ comments_count=0
+ )
+ self._next_id += 1
+ self._posts.append(new_post)
+
+ # äœè
ã®æçš¿æ°ãæŽæ°
+ from src.crud.users import users_crud
+ author = users_crud.get_by_id(author_id)
+ if author:
+ author.posts_count += 1
+
+ return new_post
+
+ def update(self, post_id: int, post_update: PostUpdate, author_id: int) -> Optional[Post]:
+ """æ¢åæçš¿ãæŽæ°"""
+ post = self.get_by_id(post_id)
+ if not post or post.author_id != author_id:
+ return None
+
+ update_data = post_update.dict(exclude_unset=True)
+ for field, value in update_data.items():
+ setattr(post, field, value)
+
+ post.updated_at = datetime.now()
+ return post
+
+ def delete(self, post_id: int, author_id: int) -> bool:
+ """æçš¿ãåé€"""
+ post = self.get_by_id(post_id)
+ if post and post.author_id == author_id:
+ self._posts.remove(post)
+
+ # äœè
ã®æçš¿æ°ãæŽæ°
+ from src.crud.users import users_crud
+ author = users_crud.get_by_id(author_id)
+ if author:
+ author.posts_count = max(0, author.posts_count - 1)
+
+ return True
+ return False
+
+ def search(self, query: str, skip: int = 0, limit: int = 100) -> List[Post]:
+ """ã¿ã€ãã«ãæ¬æã§æçš¿ãæ€çŽ¢"""
+ query_lower = query.lower()
+ matching_posts = [
+ post for post in self._posts
+ if post.published and (
+ query_lower in post.title.lower() or
+ query_lower in post.content.lower()
+ )
+ ]
+ return matching_posts[skip:skip + limit]
+
+posts_crud = PostsCRUD()
+```
+
+### ã³ã¡ã³ãã® CRUD
+
+`src/crud/comments.py` ãæŽæ°ããŸã:
+
+```python
+from typing import List, Optional
+from datetime import datetime
+from src.schemas.comments import CommentCreate, CommentUpdate, Comment
+
+class CommentsCRUD:
+ def __init__(self):
+ self._comments: List[Comment] = []
+ self._next_id = 1
+
+ def get_all(self) -> List[Comment]:
+ """ãã¹ãŠã®ã³ã¡ã³ããååŸ"""
+ return self._comments
+
+ def get_by_id(self, comment_id: int) -> Optional[Comment]:
+ """ID ã§ã³ã¡ã³ããååŸ"""
+ return next((comment for comment in self._comments if comment.id == comment_id), None)
+
+ def get_by_post(self, post_id: int, skip: int = 0, limit: int = 100) -> List[Comment]:
+ """ç¹å®æçš¿ã®ã³ã¡ã³ããååŸ"""
+ post_comments = [comment for comment in self._comments if comment.post_id == post_id]
+ return post_comments[skip:skip + limit]
+
+ def get_by_author(self, author_id: int, skip: int = 0, limit: int = 100) -> List[Comment]:
+ """äœè
ããšã®ã³ã¡ã³ããååŸ"""
+ author_comments = [comment for comment in self._comments if comment.author_id == author_id]
+ return author_comments[skip:skip + limit]
+
+ def create(self, comment: CommentCreate, author_id: int) -> Comment:
+ """æ°ããã³ã¡ã³ããäœæ"""
+ # æçš¿ã®ååšç¢ºèª
+ from src.crud.posts import posts_crud
+ post = posts_crud.get_by_id(comment.post_id)
+ if not post:
+ raise ValueError("Post not found")
+
+ now = datetime.now()
+ new_comment = Comment(
+ id=self._next_id,
+ content=comment.content,
+ post_id=comment.post_id,
+ author_id=author_id,
+ created_at=now,
+ updated_at=now
+ )
+ self._next_id += 1
+ self._comments.append(new_comment)
+
+ # æçš¿ã®ã³ã¡ã³ãæ°ãæŽæ°
+ post.comments_count += 1
+
+ return new_comment
+
+ def update(self, comment_id: int, comment_update: CommentUpdate, author_id: int) -> Optional[Comment]:
+ """æ¢åã³ã¡ã³ããæŽæ°"""
+ comment = self.get_by_id(comment_id)
+ if not comment or comment.author_id != author_id:
+ return None
+
+ update_data = comment_update.dict(exclude_unset=True)
+ for field, value in update_data.items():
+ setattr(comment, field, value)
+
+ comment.updated_at = datetime.now()
+ return comment
+
+ def delete(self, comment_id: int, author_id: int) -> bool:
+ """ã³ã¡ã³ããåé€"""
+ comment = self.get_by_id(comment_id)
+ if comment and comment.author_id == author_id:
+ self._comments.remove(comment)
+
+ # æçš¿ã®ã³ã¡ã³ãæ°ãæŽæ°
+ from src.crud.posts import posts_crud
+ post = posts_crud.get_by_id(comment.post_id)
+ if post:
+ post.comments_count = max(0, post.comments_count - 1)
+
+ return True
+ return False
+
+comments_crud = CommentsCRUD()
+```
+
+## ã¹ããã 6: é«åºŠãª API ã«ãŒãã®å®è£
+
+### ãŠãŒã¶ãŒã«ãŒãã®æ¡åŒµ
+
+`src/api/routes/users.py` ãæŽæ°ããŸã:
+
+```python
+from typing import List
+from fastapi import APIRouter, HTTPException, status, Depends, Query
+from src.schemas.users import User, UserCreate, UserUpdate
+from src.crud.users import users_crud
+
+router = APIRouter()
+
+# çŸåšã®ãŠãŒã¶ãŒãååŸãããã«ã (ãã¥ãŒããªã¢ã«çšã«ç°¡ç¥å)
+def get_current_user_id() -> int:
+ # å®éã®ã¢ããªã§ã¯ JWT ãæ€èšŒããŠãŠãŒã¶ãŒ ID ãè¿ã
+ return 1 # ãã¥ãŒããªã¢ã«çš
+
+@router.get("/", response_model=List[User])
+def read_users(
+ skip: int = Query(0, ge=0),
+ limit: int = Query(100, ge=1, le=100)
+):
+ """ããŒãžããŒã·ã§ã³ä»ãã§å
šãŠãŒã¶ãŒãååŸ"""
+ users = users_crud.get_all()[skip:skip + limit]
+ return [User(**user.dict()) for user in users]
+
+@router.post("/", response_model=User, status_code=status.HTTP_201_CREATED)
+def create_user(user: UserCreate):
+ """æ°ãããŠãŒã¶ãŒãç»é²"""
+ try:
+ new_user = users_crud.create(user)
+ return User(**new_user.dict())
+ except ValueError as e:
+ raise HTTPException(
+ status_code=status.HTTP_400_BAD_REQUEST,
+ detail=str(e)
+ )
+
+@router.get("/{user_id}", response_model=User)
+def read_user(user_id: int):
+ """ç¹å®ã®ãŠãŒã¶ãŒãååŸ"""
+ user = users_crud.get_by_id(user_id)
+ if not user:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail=f"User with id {user_id} not found"
+ )
+ return User(**user.dict())
+
+@router.put("/{user_id}", response_model=User)
+def update_user(
+ user_id: int,
+ user_update: UserUpdate,
+ current_user_id: int = Depends(get_current_user_id)
+):
+ """ãŠãŒã¶ãŒãããã£ãŒã«ãæŽæ°"""
+ if user_id != current_user_id:
+ raise HTTPException(
+ status_code=status.HTTP_403_FORBIDDEN,
+ detail="You can only update your own profile"
+ )
+
+ try:
+ updated_user = users_crud.update(user_id, user_update)
+ if not updated_user:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail="User not found"
+ )
+ return User(**updated_user.dict())
+ except ValueError as e:
+ raise HTTPException(
+ status_code=status.HTTP_400_BAD_REQUEST,
+ detail=str(e)
+ )
+
+@router.delete("/{user_id}", status_code=status.HTTP_204_NO_CONTENT)
+def delete_user(
+ user_id: int,
+ current_user_id: int = Depends(get_current_user_id)
+):
+ """ãŠãŒã¶ãŒã¢ã«ãŠã³ããéã¢ã¯ãã£ãå"""
+ if user_id != current_user_id:
+ raise HTTPException(
+ status_code=status.HTTP_403_FORBIDDEN,
+ detail="You can only delete your own account"
+ )
+
+ success = users_crud.delete(user_id)
+ if not success:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail="User not found"
+ )
+
+@router.post("/login")
+def login(email: str, password: str):
+ """ãŠãŒã¶ãŒãèªèšŒ"""
+ user = users_crud.authenticate(email, password)
+ if not user:
+ raise HTTPException(
+ status_code=status.HTTP_401_UNAUTHORIZED,
+ detail="Invalid email or password"
+ )
+
+ # å®ã¢ããªã§ã¯ JWT ãè¿ã
+ return {
+ "message": "Login successful",
+ "user_id": user.id,
+ "username": user.username
+ }
+```
+
+### æçš¿ã«ãŒãã®æ¡åŒµ
+
+`src/api/routes/posts.py` ãæŽæ°ããŸã:
+
+```python
+from typing import List, Optional
+from fastapi import APIRouter, HTTPException, status, Depends, Query
+from src.schemas.posts import Post, PostCreate, PostUpdate
+from src.crud.posts import posts_crud
+
+router = APIRouter()
+
+def get_current_user_id() -> int:
+ return 1 # ãã¥ãŒããªã¢ã«çšã«ç°¡ç¥å
+
+@router.get("/", response_model=List[Post])
+def read_posts(
+ skip: int = Query(0, ge=0),
+ limit: int = Query(100, ge=1, le=100),
+ search: Optional[str] = Query(None)
+):
+ """æ€çŽ¢ãªãã·ã§ã³ä»ãã§å
šæçš¿ãååŸ"""
+ if search:
+ posts = posts_crud.search(search, skip, limit)
+ else:
+ posts = posts_crud.get_all(skip, limit)
+ return posts
+
+@router.post("/", response_model=Post, status_code=status.HTTP_201_CREATED)
+def create_post(
+ post: PostCreate,
+ current_user_id: int = Depends(get_current_user_id)
+):
+ """æ°ããããã°æçš¿ãäœæ"""
+ new_post = posts_crud.create(post, current_user_id)
+ return new_post
+
+@router.get("/{post_id}", response_model=Post)
+def read_post(post_id: int):
+ """ç¹å®ã®æçš¿ãååŸ"""
+ post = posts_crud.get_by_id(post_id)
+ if not post:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail="Post not found"
+ )
+ return post
+
+@router.put("/{post_id}", response_model=Post)
+def update_post(
+ post_id: int,
+ post_update: PostUpdate,
+ current_user_id: int = Depends(get_current_user_id)
+):
+ """ããã°æçš¿ãæŽæ°"""
+ updated_post = posts_crud.update(post_id, post_update, current_user_id)
+ if not updated_post:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail="Post not found or you don't have permission to edit it"
+ )
+ return updated_post
+
+@router.delete("/{post_id}", status_code=status.HTTP_204_NO_CONTENT)
+def delete_post(
+ post_id: int,
+ current_user_id: int = Depends(get_current_user_id)
+):
+ """ããã°æçš¿ãåé€"""
+ success = posts_crud.delete(post_id, current_user_id)
+ if not success:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail="Post not found or you don't have permission to delete it"
+ )
+
+@router.get("/author/{author_id}", response_model=List[Post])
+def read_posts_by_author(
+ author_id: int,
+ skip: int = Query(0, ge=0),
+ limit: int = Query(100, ge=1, le=100)
+):
+ """ç¹å®ã®äœè
ã®æçš¿ãååŸ"""
+ posts = posts_crud.get_by_author(author_id, skip, limit)
+ return posts
+```
+
+### ã³ã¡ã³ãã«ãŒãã®æ¡åŒµ
+
+`src/api/routes/comments.py` ãæŽæ°ããŸã:
+
+```python
+from typing import List
+from fastapi import APIRouter, HTTPException, status, Depends, Query
+from src.schemas.comments import Comment, CommentCreate, CommentUpdate
+from src.crud.comments import comments_crud
+
+router = APIRouter()
+
+def get_current_user_id() -> int:
+ return 1 # ãã¥ãŒããªã¢ã«çšã«ç°¡ç¥å
+
+@router.get("/", response_model=List[Comment])
+def read_comments(
+ skip: int = Query(0, ge=0),
+ limit: int = Query(100, ge=1, le=100)
+):
+ """ãã¹ãŠã®ã³ã¡ã³ããååŸ"""
+ comments = comments_crud.get_all()[skip:skip + limit]
+ return comments
+
+@router.post("/", response_model=Comment, status_code=status.HTTP_201_CREATED)
+def create_comment(
+ comment: CommentCreate,
+ current_user_id: int = Depends(get_current_user_id)
+):
+ """æ°ããã³ã¡ã³ããäœæ"""
+ try:
+ new_comment = comments_crud.create(comment, current_user_id)
+ return new_comment
+ except ValueError as e:
+ raise HTTPException(
+ status_code=status.HTTP_400_BAD_REQUEST,
+ detail=str(e)
+ )
+
+@router.get("/{comment_id}", response_model=Comment)
+def read_comment(comment_id: int):
+ """ç¹å®ã®ã³ã¡ã³ããååŸ"""
+ comment = comments_crud.get_by_id(comment_id)
+ if not comment:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail="Comment not found"
+ )
+ return comment
+
+@router.put("/{comment_id}", response_model=Comment)
+def update_comment(
+ comment_id: int,
+ comment_update: CommentUpdate,
+ current_user_id: int = Depends(get_current_user_id)
+):
+ """ã³ã¡ã³ããæŽæ°"""
+ updated_comment = comments_crud.update(comment_id, comment_update, current_user_id)
+ if not updated_comment:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail="Comment not found or you don't have permission to edit it"
+ )
+ return updated_comment
+
+@router.delete("/{comment_id}", status_code=status.HTTP_204_NO_CONTENT)
+def delete_comment(
+ comment_id: int,
+ current_user_id: int = Depends(get_current_user_id)
+):
+ """ã³ã¡ã³ããåé€"""
+ success = comments_crud.delete(comment_id, current_user_id)
+ if not success:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail="Comment not found or you don't have permission to delete it"
+ )
+
+@router.get("/post/{post_id}", response_model=List[Comment])
+def read_comments_by_post(
+ post_id: int,
+ skip: int = Query(0, ge=0),
+ limit: int = Query(100, ge=1, le=100)
+):
+ """ç¹å®æçš¿ã®ã³ã¡ã³ããååŸ"""
+ comments = comments_crud.get_by_post(post_id, skip, limit)
+ return comments
+
+@router.get("/author/{author_id}", response_model=List[Comment])
+def read_comments_by_author(
+ author_id: int,
+ skip: int = Query(0, ge=0),
+ limit: int = Query(100, ge=1, le=100)
+):
+ """ç¹å®äœè
ã®ã³ã¡ã³ããååŸ"""
+ comments = comments_crud.get_by_author(author_id, skip, limit)
+ return comments
+```
+
+## ã¹ããã 7: ããã° API ã®ãã¹ã
+
+ãµãŒããŒãèµ·åããŠã宿ããããã° API ããã¹ãããŸããã:
+
+
+
+```console
+$ fastkit runserver
+INFO: Uvicorn running on http://127.0.0.1:8000
+```
+
+
+
+### ãŠãŒã¶ãŒç»é²ã®ãã¹ã
+
+
+
+```console
+$ curl -X POST "http://127.0.0.1:8000/api/v1/users/" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "email": "john@example.com",
+ "username": "john_doe",
+ "full_name": "John Doe",
+ "bio": "Software developer and blogger",
+ "password": "securepassword123"
+ }'
+
+{
+ "id": 1,
+ "email": "john@example.com",
+ "username": "john_doe",
+ "full_name": "John Doe",
+ "bio": "Software developer and blogger",
+ "is_active": true,
+ "created_at": "2023-12-07T10:30:00",
+ "posts_count": 0
+}
+```
+
+
+
+### ãã°ã€ã³ã®ãã¹ã
+
+
+
+```console
+$ curl -X POST "http://127.0.0.1:8000/api/v1/users/login" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "email": "john@example.com",
+ "password": "securepassword123"
+ }'
+
+{
+ "message": "Login successful",
+ "user_id": 1,
+ "username": "john_doe"
+}
+```
+
+
+
+### æçš¿äœæã®ãã¹ã
+
+
+
+```console
+$ curl -X POST "http://127.0.0.1:8000/api/v1/posts/" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "title": "My First Blog Post",
+ "content": "This is the content of my first blog post. It'\''s about learning FastAPI with FastAPI-fastkit!",
+ "published": true
+ }'
+
+{
+ "id": 1,
+ "title": "My First Blog Post",
+ "content": "This is the content of my first blog post. It's about learning FastAPI with FastAPI-fastkit!",
+ "published": true,
+ "author_id": 1,
+ "created_at": "2023-12-07T10:35:00",
+ "updated_at": "2023-12-07T10:35:00",
+ "comments_count": 0
+}
+```
+
+
+
+### ã³ã¡ã³ãäœæã®ãã¹ã
+
+
+
+```console
+$ curl -X POST "http://127.0.0.1:8000/api/v1/comments/" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "content": "Great post! I learned a lot from this.",
+ "post_id": 1
+ }'
+
+{
+ "id": 1,
+ "content": "Great post! I learned a lot from this.",
+ "post_id": 1,
+ "author_id": 1,
+ "created_at": "2023-12-07T10:40:00",
+ "updated_at": "2023-12-07T10:40:00"
+}
+```
+
+
+
+### æ€çŽ¢æ©èœã®ãã¹ã
+
+
+
+```console
+$ curl "http://127.0.0.1:8000/api/v1/posts/?search=FastAPI"
+
+[
+ {
+ "id": 1,
+ "title": "My First Blog Post",
+ "content": "This is the content of my first blog post. It's about learning FastAPI with FastAPI-fastkit!",
+ "published": true,
+ "author_id": 1,
+ "created_at": "2023-12-07T10:35:00",
+ "updated_at": "2023-12-07T10:35:00",
+ "comments_count": 1
+ }
+]
+```
+
+
+
+## ã¹ããã 8: API ããã¥ã¡ã³ã
+
+[http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs) ãéããŠã宿ãã API ããã¥ã¡ã³ãã確èªããŸããããæ¬¡ã衚瀺ãããã¯ãã§ã:
+
+- **Users**: ç»é²ããã°ã€ã³ããããã£ãŒã«ç®¡ç
+- **Posts**: CRUDãæ€çŽ¢ãäœè
ãã£ã«ã¿
+- **Comments**: CRUDãæçš¿ / äœè
ã«ãããã£ã«ã¿
+- **Items**: å
ã®ãµã³ãã«ãšã³ããã€ã³ã
+
+ããã¥ã¡ã³ãã«ã¯æ¬¡ãå«ãŸããŸã:
+
+- å©çšå¯èœãªãã¹ãŠã®ãšã³ããã€ã³ã
+- ãªã¯ãšã¹ã / ã¬ã¹ãã³ã¹ã¹ããŒã
+- ããŒã¿æ€èšŒã«ãŒã«
+- ãšã©ãŒã¬ã¹ãã³ã¹
+
+## ã¹ããã 9: ãã¹ãã®äœæ
+
+ããã° API ã®å
æ¬çãªãã¹ããäœæããŸãããã`tests/test_blog_api.py` ãäœæããŸã:
+
+```python
+from fastapi.testclient import TestClient
+from src.main import app
+
+client = TestClient(app)
+
+class TestUserAPI:
+ def test_create_user(self):
+ user_data = {
+ "email": "test@example.com",
+ "username": "testuser",
+ "full_name": "Test User",
+ "bio": "Test bio",
+ "password": "testpassword123"
+ }
+ response = client.post("/api/v1/users/", json=user_data)
+ assert response.status_code == 201
+ data = response.json()
+ assert data["email"] == user_data["email"]
+ assert data["username"] == user_data["username"]
+ assert "id" in data
+ assert "hashed_password" not in data # ãã¹ã¯ãŒããé²åºãããªã
+
+ def test_duplicate_email(self):
+ # 1 人ç®ã®ãŠãŒã¶ãŒ
+ user_data1 = {
+ "email": "duplicate@example.com",
+ "username": "user1",
+ "password": "password123"
+ }
+ response1 = client.post("/api/v1/users/", json=user_data1)
+ assert response1.status_code == 201
+
+ # 2 人ç®ãåãã¡ãŒã«ã§äœæ
+ user_data2 = {
+ "email": "duplicate@example.com",
+ "username": "user2",
+ "password": "password123"
+ }
+ response2 = client.post("/api/v1/users/", json=user_data2)
+ assert response2.status_code == 400
+ assert "Email already registered" in response2.json()["detail"]
+
+ def test_login(self):
+ # ãŸããŠãŒã¶ãŒãäœæ
+ user_data = {
+ "email": "login@example.com",
+ "username": "loginuser",
+ "password": "loginpassword123"
+ }
+ client.post("/api/v1/users/", json=user_data)
+
+ # ãã°ã€ã³ããã¹ã
+ login_data = {
+ "email": "login@example.com",
+ "password": "loginpassword123"
+ }
+ response = client.post("/api/v1/users/login", json=login_data)
+ assert response.status_code == 200
+ data = response.json()
+ assert "user_id" in data
+ assert data["username"] == "loginuser"
+
+class TestPostAPI:
+ def test_create_post(self):
+ post_data = {
+ "title": "Test Post",
+ "content": "This is a test post content",
+ "published": True
+ }
+ response = client.post("/api/v1/posts/", json=post_data)
+ assert response.status_code == 201
+ data = response.json()
+ assert data["title"] == post_data["title"]
+ assert data["content"] == post_data["content"]
+ assert "id" in data
+ assert "author_id" in data
+
+ def test_read_posts(self):
+ response = client.get("/api/v1/posts/")
+ assert response.status_code == 200
+ data = response.json()
+ assert isinstance(data, list)
+
+ def test_search_posts(self):
+ # ç¹å®ã®å
容ãå«ãæçš¿ãäœæ
+ post_data = {
+ "title": "FastAPI Tutorial",
+ "content": "Learn how to build APIs with FastAPI",
+ "published": True
+ }
+ client.post("/api/v1/posts/", json=post_data)
+
+ # æçš¿ãæ€çŽ¢
+ response = client.get("/api/v1/posts/?search=FastAPI")
+ assert response.status_code == 200
+ data = response.json()
+ assert len(data) > 0
+ assert any("FastAPI" in post["title"] or "FastAPI" in post["content"] for post in data)
+
+class TestCommentAPI:
+ def test_create_comment(self):
+ # ãŸãæçš¿ãäœæ
+ post_data = {
+ "title": "Post for Comments",
+ "content": "This post will receive comments",
+ "published": True
+ }
+ post_response = client.post("/api/v1/posts/", json=post_data)
+ post_id = post_response.json()["id"]
+
+ # ã³ã¡ã³ããäœæ
+ comment_data = {
+ "content": "This is a test comment",
+ "post_id": post_id
+ }
+ response = client.post("/api/v1/comments/", json=comment_data)
+ assert response.status_code == 201
+ data = response.json()
+ assert data["content"] == comment_data["content"]
+ assert data["post_id"] == post_id
+
+ def test_get_comments_by_post(self):
+ # ãŸãæçš¿ãšã³ã¡ã³ããäœæ
+ post_data = {
+ "title": "Post with Comments",
+ "content": "This post has comments",
+ "published": True
+ }
+ post_response = client.post("/api/v1/posts/", json=post_data)
+ post_id = post_response.json()["id"]
+
+ comment_data = {
+ "content": "Comment on post",
+ "post_id": post_id
+ }
+ client.post("/api/v1/comments/", json=comment_data)
+
+ # æçš¿ã®ã³ã¡ã³ããååŸ
+ response = client.get(f"/api/v1/comments/post/{post_id}")
+ assert response.status_code == 200
+ data = response.json()
+ assert len(data) > 0
+ assert all(comment["post_id"] == post_id for comment in data)
+
+# ãã¹ãå®è¡
+if __name__ == "__main__":
+ import pytest
+ pytest.main([__file__])
+```
+
+### ãã¹ããå®è¡ãã
+
+
+
+```console
+$ python -m pytest tests/test_blog_api.py -v
+======================== test session starts ========================
+tests/test_blog_api.py::TestUserAPI::test_create_user PASSED
+tests/test_blog_api.py::TestUserAPI::test_duplicate_email PASSED
+tests/test_blog_api.py::TestUserAPI::test_login PASSED
+tests/test_blog_api.py::TestPostAPI::test_create_post PASSED
+tests/test_blog_api.py::TestPostAPI::test_read_posts PASSED
+tests/test_blog_api.py::TestPostAPI::test_search_posts PASSED
+tests/test_blog_api.py::TestCommentAPI::test_create_comment PASSED
+tests/test_blog_api.py::TestCommentAPI::test_get_comments_by_post PASSED
+======================== 8 passed in 1.23s ========================
+```
+
+
+
+## æ§ç¯ãããã®
+
+ããã§ãšãããããŸã! æ¬¡ã®æ©èœãåããå®å
šãªããã° API ãæ§ç¯ã§ããŸãã:
+
+### â
å®è£
ããæ©èœ
+
+- **ãŠãŒã¶ãŒç®¡ç**
+ - æ€èšŒä»ãã®ãŠãŒã¶ãŒç»é²
+ - ãŠãŒã¶ãŒèªèšŒ (ãã°ã€ã³)
+ - ãããã£ãŒã«ç®¡ç
+ - éè€é²æ¢
+
+- **ããã°æçš¿**
+ - æçš¿ã®äœæãååŸãæŽæ°ãåé€
+ - äœè
ã«ãããã£ã«ã¿
+ - æ€çŽ¢æ©èœ
+ - å
¬é / äžæžãã®ç¶æ
+
+- **ã³ã¡ã³ãæ©èœ**
+ - æçš¿ãžã®ã³ã¡ã³ã远å
+ - æçš¿ / äœè
ããšã®ã³ã¡ã³ã衚瀺
+ - ã³ã¡ã³ã管ç
+
+- **ããŒã¿æ€èšŒ**
+ - ã¡ãŒã«ã¢ãã¬ã¹ã®æ€èšŒ
+ - ãã¹ã¯ãŒãèŠä»¶
+ - ã³ã³ãã³ãé·ã®å¶é
+ - å¿
é ãã£ãŒã«ãã®æ€èšŒ
+
+- **ãšã©ãŒåŠç**
+ - é©å㪠HTTP ã¹ããŒã¿ã¹ã³ãŒã
+ - 説æçãªãšã©ãŒã¡ãã»ãŒãž
+ - å
¥åæ€èšŒãšã©ãŒ
+
+- **API ããã¥ã¡ã³ã**
+ - èªå OpenAPI çæ
+ - 察話åãã¹ãã€ã³ã¿ãŒãã§ã€ã¹
+ - ãªã¯ãšã¹ã / ã¬ã¹ãã³ã¹ã¹ããŒã
+
+- **ãã¹ã**
+ - å
æ¬çãªãã¹ãã«ãã¬ããž
+ - å
šãšã³ããã€ã³ãã®åäœãã¹ã
+ - ãšããžã±ãŒã¹ã®ãã¹ã
+
+## 次ã®ã¹ããã
+
+### æ¡åŒµã®ã¢ã€ãã¢
+
+1. **æ¬æ ŒçãªèªèšŒ**
+ - JWT ããŒã¯ã³ã®å®è£
+ - bcrypt ã«ãããã¹ã¯ãŒãããã·ã¥
+ - ããŒã«ããŒã¹ã®æš©é管ç
+
+2. **ããŒã¿ããŒã¹çµ±å**
+ - PostgreSQL ã MySQL ã®å©çš
+ - é©åãªããŒã¿ããŒã¹ã¢ãã«
+ - ããŒã¿ããŒã¹ãã€ã°ã¬ãŒã·ã§ã³
+
+3. **é«åºŠãªæ©èœ**
+ - ç»åã®ãã¡ã€ã«ã¢ããããŒã
+ - ã¡ãŒã«éç¥
+ - æçš¿ã«ããŽãª / ã¿ã°
+ - ããã / ãããªããæ©èœ
+
+4. **æ¬çªéçšãžã®å¯Ÿå¿**
+ - ãã°ã®è¿œå
+ - ãã£ãã·ã¥ã®å®è£
+ - ã¬ãŒãå¶é
+ - ç°å¢ããšã®èšå®
+
+### åŠç¿ãç¶ãã
+
+1. **[ãã³ãã¬ãŒãã®å©çš](../user-guide/using-templates.md)**: ããŒã¿ããŒã¹çµ±åã®ããã« `fastapi-psql-orm` ãã³ãã¬ãŒãã詊ã
+2. **[ã«ãŒãã®è¿œå ](../user-guide/adding-routes.md)**: ããé«åºŠãªã«ãŒãã£ã³ã°ãã¿ãŒã³ãåŠã¶
+3. **[ã³ã³ããªãã¥ãŒã](../contributing/development-setup.md)**: FastAPI-fastkit ã«è²¢ç®ãã
+
+!!! tip "åŠãã ãã¹ããã©ã¯ãã£ã¹"
+ - **ã¢ãžã¥ãŒã«åã¢ãŒããã¯ãã£**: schemasãCRUDãroutes ã«ããé¢å¿äºã®åé¢
+ - **ããŒã¿æ€èšŒ**: Pydantic ã䜿ã£ãå
ç¢ãªå
¥åæ€èšŒ
+ - **ãšã©ãŒåŠç**: é©å㪠HTTP ã¹ããŒã¿ã¹ã³ãŒããšãšã©ãŒã¡ãã»ãŒãž
+ - **ãã¹ã**: ãã¹ãŠã®æ©èœã®å
æ¬çãªãã¹ãã«ãã¬ããž
+ - **ããã¥ã¡ã³ã**: èªå API ããã¥ã¡ã³ãçæã®æŽ»çš
+
+ããã§ FastAPI-fastkit ã䜿ã£ãŠãããã¯ã·ã§ã³å質㮠API ãæ§ç¯ããã¹ãã«ã身ã«ã€ããŸãã! ð
diff --git a/docs/ja/tutorial/getting-started.md b/docs/ja/tutorial/getting-started.md
new file mode 100644
index 0000000..351c6b1
--- /dev/null
+++ b/docs/ja/tutorial/getting-started.md
@@ -0,0 +1,564 @@
+# ã¯ããã«
+
+FastAPI-fastkit ãå§ããããã®ãå
æ¬çãã€æ®µéçãªãã¥ãŒããªã¢ã«ã§ããã€ã³ã¹ããŒã«ããæåã® API ã®èµ·åãŸã§ãçŽ 15 åã§é²ããããŸãã
+
+## åææ¡ä»¶
+
+éå§åã«ã次ãçšæãããŠããã確èªããŠãã ãã:
+
+- ã·ã¹ãã ã« **Python 3.12 以äž** ãã€ã³ã¹ããŒã«ãããŠããããš
+- **Python ã®åºç€ç¥è** (倿°ã»é¢æ°ã»ã¯ã©ã¹)
+- **ã¿ãŒããã« / ã³ãã³ãã©ã€ã³** ã®å©çš
+- **ããã¹ããšãã£ã¿ãŸã㯠IDE** (VS CodeãPyCharm ãªã©)
+
+## ã¹ããã 1: ã€ã³ã¹ããŒã«
+
+ãŸã FastAPI-fastkit ãã€ã³ã¹ããŒã«ããŸãããããããžã§ã¯ããåé¢ãããããä»®æ³ç°å¢ã®å©çšãæšå¥šããŸãã
+
+### ãªãã·ã§ã³ A: pip ã䜿ã (åŸæ¥å)
+
+
+
+```console
+$ pip install fastapi-fastkit
+---> 100%
+Successfully installed fastapi-fastkit
+```
+
+
+
+### ãªãã·ã§ã³ B: UV ã䜿ã (æšå¥šã»é«é)
+
+UV ã¯é«é㪠Python ããã±ãŒãžãããŒãžã£ãŒã§ããUV ããŸã å
¥ããŠããªãå Žå:
+
+
+
+```console
+# ãŸã UV ãã€ã³ã¹ããŒã«
+$ curl -LsSf https://astral.sh/uv/install.sh | sh
+
+# 次㫠FastAPI-fastkit ãã€ã³ã¹ããŒã«
+$ uv pip install fastapi-fastkit
+---> 100%
+Successfully installed fastapi-fastkit
+```
+
+
+
+### ãªãã·ã§ã³ C: ä»®æ³ç°å¢ã䜿ã
+
+
+
+```console
+$ python -m venv fastapi-env
+$ source fastapi-env/bin/activate # Windows ã®å Žå: fastapi-env\Scripts\activate
+$ pip install fastapi-fastkit
+```
+
+
+
+### ã€ã³ã¹ããŒã«ã®ç¢ºèª
+
+FastAPI-fastkit ãæ£ããã€ã³ã¹ããŒã«ãããã確èªããŸã:
+
+
+
+```console
+$ fastkit --version
+FastAPI-fastkit version 1.0.0
+```
+
+
+
+## ã¹ããã 2: æåã®ãããžã§ã¯ããäœæ
+
+察話åã® `init` ã³ãã³ãã§ãæåã® FastAPI ãããžã§ã¯ããäœæããŸããã:
+
+
+
+```console
+$ fastkit init
+Enter the project name: my-first-api
+Enter the author name: Your Name
+Enter the author email: your.email@example.com
+Enter the project description: My first FastAPI project
+
+ Project Information
+ââââââââââââââââ¬ââââââââââââââââââââââââââ
+â Project Name â my-first-api â
+â Author â Your Name â
+â Author Email â your.email@example.com â
+â Description â My first FastAPI projectâ
+ââââââââââââââââŽââââââââââââââââââââââââââ
+
+Available Stacks and Dependencies:
+ MINIMAL Stack
+ââââââââââââââââ¬ââââââââââââââââââââ
+â Dependency 1 â fastapi â
+â Dependency 2 â uvicorn â
+â Dependency 3 â pydantic â
+â Dependency 4 â pydantic-settings â
+ââââââââââââââââŽââââââââââââââââââââ
+
+ STANDARD Stack
+ââââââââââââââââ¬ââââââââââââââââââââ
+â Dependency 1 â fastapi â
+â Dependency 2 â uvicorn â
+â Dependency 3 â sqlalchemy â
+â Dependency 4 â alembic â
+â Dependency 5 â pytest â
+â Dependency 6 â pydantic â
+â Dependency 7 â pydantic-settings â
+ââââââââââââââââŽââââââââââââââââââââ
+
+Select stack (minimal, standard, full): minimal
+
+Available Package Managers:
+ Package Managers
+ââââââââââ¬âââââââââââââââââââââââââââââââââââââââââââââ
+â PIP â Standard Python package manager â
+â UV â Fast Python package manager â
+â PDM â Modern Python dependency management â
+â POETRY â Python dependency management and packaging â
+ââââââââââŽâââââââââââââââââââââââââââââââââââââââââââââ
+
+Select package manager (pip, uv, pdm, poetry) [uv]: uv
+Do you want to proceed with project creation? [y/N]: y
+
+Creating virtual environment...
+Installing dependencies...
+âš FastAPI project 'my-first-api' has been created successfully!
+```
+
+
+
+!!! note "ã¹ã¿ãã¯ã®éžæ"
+ ãã®ãã¥ãŒããªã¢ã«ã§ã¯è©±ãç°¡æœã«ä¿ã€ãã **MINIMAL** ãéžã³ãŸãããå®ãããžã§ã¯ãã§ã¯ã**STANDARD** (ããŒã¿ããŒã¹å¯Ÿå¿ãå«ã) ã **FULL** (ããã¯ã°ã©ãŠã³ãã¿ã¹ã¯ãå«ã) ã®å©çšãæ€èšããŸãããã
+
+## ã¹ããã 3: ãããžã§ã¯ãã«ç§»å
+
+æ°ããäœããããããžã§ã¯ããã£ã¬ã¯ããªãžç§»åããŸã:
+
+
+
+```console
+$ cd my-first-api
+$ ls -la
+total 32
+drwxr-xr-x 8 user user 256 Dec 7 10:30 .
+drwxr-xr-x 3 user user 96 Dec 7 10:30 ..
+drwxr-xr-x 5 user user 160 Dec 7 10:30 .venv
+-rw-r--r-- 1 user user 156 Dec 7 10:30 README.md
+-rw-r--r-- 1 user user 243 Dec 7 10:30 requirements.txt
+drwxr-xr-x 3 user user 96 Dec 7 10:30 scripts
+-rw-r--r-- 1 user user 1245 Dec 7 10:30 setup.py
+drwxr-xr-x 8 user user 256 Dec 7 10:30 src
+drwxr-xr-x 3 user user 96 Dec 7 10:30 tests
+```
+
+
+
+## ã¹ããã 4: ä»®æ³ç°å¢ãæå¹å
+
+ãããžã§ã¯ãã«ã¯ãä»®æ³ç°å¢ããããããçšæãããŠããŸãããããæå¹åããŸããã:
+
+
+
+```console
+$ source .venv/bin/activate # Windows ã®å Žå: .venv\Scripts\activate
+(my-first-api) $
+```
+
+
+
+ã¿ãŒããã«ã®ããã³ããã« `(my-first-api)` ãšè¡šç€ºãããä»®æ³ç°å¢ãæå¹ã«ãªã£ãŠããããšãåãããŸãã
+
+## ã¹ããã 5: éçºãµãŒããŒãèµ·å
+
+ãããããæ¥œããéšåã§ã â FastAPI ãµãŒããŒãèµ·åããŸããã:
+
+
+
+```console
+$ fastkit runserver
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+INFO: Started reloader process [28720] using StatReload
+INFO: Started server process [28722]
+INFO: Waiting for application startup.
+INFO: Application startup complete.
+```
+
+
+
+ð **ããã§ãšãããããŸã!** ããªãã® FastAPI ãµãŒããŒãèµ·åããŠããŸãã
+
+## ã¹ããã 6: API ã®ãã¹ã
+
+API ãããã€ãã®æ¹æ³ã§ãã¹ãããŠã¿ãŸããã:
+
+### æ¹æ³ 1: ãã©ãŠã¶
+
+Web ãã©ãŠã¶ã§æ¬¡ã«ã¢ã¯ã»ã¹ããŸã:
+
+- **ã¡ã€ã³ API ãšã³ããã€ã³ã**: [http://127.0.0.1:8000](http://127.0.0.1:8000)
+
+次ã®ããã«è¡šç€ºãããã¯ãã§ã:
+```json
+{"message": "Hello World"}
+```
+
+### æ¹æ³ 2: 察話å API ããã¥ã¡ã³ã
+
+èªåçæããã API ããã¥ã¡ã³ããéããŸã:
+
+- **Swagger UI**: [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs)
+- **ReDoc**: [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc)
+
+ç¹ã« Swagger UI ã¯äŸ¿å©ã§ããæ¬¡ã®ããšãã§ããŸã:
+
+- å©çšå¯èœãªãšã³ããã€ã³ãã®äžèŠ§è¡šç€º
+- ãã©ãŠã¶ããçŽæ¥ãšã³ããã€ã³ãããã¹ã
+- ãªã¯ãšã¹ã / ã¬ã¹ãã³ã¹ã¹ããŒãã®ç¢ºèª
+- OpenAPI 仿§ã®ããŠã³ããŒã
+
+### æ¹æ³ 3: ã³ãã³ãã©ã€ã³
+
+æ°ããã¿ãŒããã«ãéã㊠(ãµãŒããŒã¯èµ·åãããŸãŸ)ãcurl ã§ãã¹ãããŸã:
+
+
+
+```console
+$ curl http://127.0.0.1:8000
+{"message":"Hello World"}
+
+$ curl http://127.0.0.1:8000/api/v1/items/
+[]
+
+$ curl -X POST "http://127.0.0.1:8000/api/v1/items/" \
+ -H "Content-Type: application/json" \
+ -d '{"title": "My First Item", "description": "This is a test item"}'
+{
+ "id": 1,
+ "title": "My First Item",
+ "description": "This is a test item"
+}
+```
+
+
+
+## ã¹ããã 7: ãããžã§ã¯ãæ§é ã®çè§£
+
+FastAPI-fastkit ãäœãçæãããã確èªããŸããã:
+
+
+
+```console
+$ tree src
+src/
+âââ __init__.py
+âââ main.py # FastAPI ã¢ããªã±ãŒã·ã§ã³ã®ãšã³ããªãã€ã³ã
+âââ core/
+â âââ __init__.py
+â âââ config.py # ã¢ããªã±ãŒã·ã§ã³èšå®
+âââ api/
+â âââ __init__.py
+â âââ api.py # ã¡ã€ã³ã® API ã«ãŒã¿ãŒ
+â âââ routes/
+â âââ __init__.py
+â âââ items.py # Items API ãšã³ããã€ã³ã
+âââ crud/
+â âââ __init__.py
+â âââ items.py # items ã®ããžãã¹ããžãã¯
+âââ schemas/
+â âââ __init__.py
+â âââ items.py # ããŒã¿æ€èšŒã¹ããŒã
+âââ mocks/
+ âââ __init__.py
+ âââ mock_items.json # ãµã³ãã«ããŒã¿
+```
+
+
+
+### äž»èŠãã¡ã€ã«ã®è§£èª¬
+
+**`src/main.py`** â ã¢ããªã±ãŒã·ã§ã³ã®äžæ ž:
+```python
+from fastapi import FastAPI
+from src.api.api import api_router
+from src.core.config import settings
+
+app = FastAPI(
+ title=settings.PROJECT_NAME,
+ version=settings.VERSION,
+ openapi_url=f"{settings.API_V1_STR}/openapi.json"
+)
+
+app.include_router(api_router, prefix=settings.API_V1_STR)
+
+@app.get("/")
+def read_root():
+ return {"message": "Hello World"}
+```
+
+**`src/core/config.py`** â ã¢ããªã±ãŒã·ã§ã³èšå®:
+```python
+from pydantic_settings import BaseSettings
+
+class Settings(BaseSettings):
+ PROJECT_NAME: str = "my-first-api"
+ VERSION: str = "1.0.0"
+ API_V1_STR: str = "/api/v1"
+
+ class Config:
+ env_file = ".env"
+
+settings = Settings()
+```
+
+**`src/api/routes/items.py`** â API ãšã³ããã€ã³ã:
+```python
+from typing import List
+from fastapi import APIRouter, HTTPException
+from src.schemas.items import Item, ItemCreate, ItemUpdate
+from src.crud.items import items_crud
+
+router = APIRouter()
+
+@router.get("/", response_model=List[Item])
+def read_items():
+ """Get all items"""
+ return items_crud.get_all()
+
+@router.post("/", response_model=Item)
+def create_item(item: ItemCreate):
+ """Create a new item"""
+ return items_crud.create(item)
+```
+
+## ã¹ããã 8: æåã®ã«ã¹ã¿ã ã«ãŒãã远å
+
+åŠãã ããšãå®è·µãããããæ°ãã API ã«ãŒãã远å ããŠã¿ãŸããã:
+
+
+
+```console
+$ fastkit addroute users my-first-api
+ Adding New Route
+ââââââââââââââââââââ¬âââââââââââââââââââââââââââââââââââââââââââ
+â Project â my-first-api â
+â Route Name â users â
+â Target Directory â ~/my-first-api â
+ââââââââââââââââââââŽâââââââââââââââââââââââââââââââââââââââââââ
+
+Do you want to add route 'users' to project 'my-first-api'? [Y/n]: y
+
+âš Successfully added new route 'users' to project 'my-first-api'
+```
+
+
+
+ãµãŒããŒã¯èªåçã«åèµ·åããæ°ãããšã³ããã€ã³ãã䜿ããããã«ãªããŸã:
+
+- `GET /api/v1/users/` - ãã¹ãŠã®ãŠãŒã¶ãŒãååŸ
+- `POST /api/v1/users/` - æ°ãããŠãŒã¶ãŒãäœæ
+- `GET /api/v1/users/{user_id}` - ç¹å®ã®ãŠãŒã¶ãŒãååŸ
+- ã»ã
+
+### æ°ããã«ãŒãããã¹ããã
+
+
+
+```console
+$ curl -X POST "http://127.0.0.1:8000/api/v1/users/" \
+ -H "Content-Type: application/json" \
+ -d '{"title": "John Doe", "description": "Software Developer"}'
+{
+ "id": 1,
+ "title": "John Doe",
+ "description": "Software Developer"
+}
+
+$ curl http://127.0.0.1:8000/api/v1/users/
+[
+ {
+ "id": 1,
+ "title": "John Doe",
+ "description": "Software Developer"
+ }
+]
+```
+
+
+
+## ã¹ããã 9: ã³ãŒããèªãã§å€æŽãã
+
+ã³ãŒããã©ã®ããã«åãããçè§£ãããããå°ããªå€æŽãå ããŠã¿ãŸãããã
+
+### ãŠã§ã«ã«ã ã¡ãã»ãŒãžã®å€æŽ
+
+ãšãã£ã¿ã§ `src/main.py` ãéããã«ãŒããšã³ããã€ã³ãã倿ŽããŸã:
+
+```python
+@app.get("/")
+def read_root():
+ return {"message": "Welcome to my first FastAPI application!"}
+```
+
+ãã¡ã€ã«ãä¿åããŸããèªåãªããŒãã®ãããã§ãµãŒããŒã¯èªåçã«åèµ·åããŸãã
+
+### 倿Žããã¹ããã
+
+
+
+```console
+$ curl http://127.0.0.1:8000
+{"message":"Welcome to my first FastAPI application!"}
+```
+
+
+
+### æ°ãããšã³ããã€ã³ãã远å ãã
+
+`src/main.py` ã«ã·ã³ãã«ãªãšã³ããã€ã³ãã远å ããŸã:
+
+```python
+@app.get("/hello/{name}")
+def say_hello(name: str):
+ return {"message": f"Hello, {name}!"}
+```
+
+### æ°ãããšã³ããã€ã³ãããã¹ããã
+
+
+
+```console
+$ curl http://127.0.0.1:8000/hello/World
+{"message":"Hello, World!"}
+
+$ curl http://127.0.0.1:8000/hello/FastAPI
+{"message":"Hello, FastAPI!"}
+```
+
+
+
+## ã¹ããã 10: ãã¹ããå®è¡
+
+ãããžã§ã¯ãã«ã¯äºåæ§ææžã¿ã®ãã¹ããå«ãŸããŸããå®è¡ããŠã¿ãŸããã:
+
+
+
+```console
+$ python -m pytest
+======================== test session starts ========================
+collected 5 items
+
+tests/test_items.py::test_create_item PASSED
+tests/test_items.py::test_read_items PASSED
+tests/test_items.py::test_read_item PASSED
+tests/test_items.py::test_update_item PASSED
+tests/test_items.py::test_delete_item PASSED
+
+======================== 5 passed in 0.45s ========================
+```
+
+
+
+## äžæ žãšãªãæŠå¿µ
+
+### 1. FastAPI ã¢ããªã±ãŒã·ã§ã³ã®æ§é
+
+FastAPI-fastkit 㯠**ã¢ãžã¥ãŒã«åã¢ãŒããã¯ãã£** ã«åŸããŸã:
+
+- **`main.py`**: ã¢ããªã±ãŒã·ã§ã³ã®ãšã³ããªãã€ã³ããšã°ããŒãã«ãšã³ããã€ã³ã
+- **`api/`**: API ã«ãŒãã®æŽç
+- **`core/`**: ã¢ããªã±ãŒã·ã§ã³èšå®
+- **`crud/`**: ããžãã¹ããžãã¯ãšããŒã¿æäœ
+- **`schemas/`**: ããŒã¿æ€èšŒãšã·ãªã¢ã©ã€ãº
+- **`tests/`**: èªåãã¹ã
+
+### 2. äŸåé¢ä¿ç®¡ç
+
+ãããžã§ã¯ãã¯ã¢ãã³ãª Python ã®äŸåé¢ä¿ç®¡çã䜿ããŸã:
+
+- **ä»®æ³ç°å¢**: éé¢ããã Python ç°å¢
+- **requirements.txt**: ãã¹ãŠã®äŸåé¢ä¿ããªã¹ã
+- **èªåã€ã³ã¹ããŒã«**: ãããžã§ã¯ãäœææã«äŸåé¢ä¿ãèªåã§ã€ã³ã¹ããŒã«ããã
+
+### 3. éçºãµãŒããŒ
+
+FastAPI-fastkit 㯠**Uvicorn** ã ASGI ãµãŒããŒãšããŠå©çšããŸã:
+
+- **èªåãªããŒã**: ã³ãŒã倿޿ã«èªååèµ·å
+- **é«éèµ·å**: éçºã®ã€ãã¬ãŒã·ã§ã³ãéã
+- **æ¬çªéçšå¯Ÿå¿**: æ¬çªã§ãåããµãŒããŒãå©çš
+
+### 4. API ããã¥ã¡ã³ã
+
+FastAPI ãæ¬¡ãèªåçæããŸã:
+
+- **OpenAPI 仿§**: æ¥çæšæºã® API ããã¥ã¡ã³ã
+- **Swagger UI**: 察話åã®ãã¹ãã€ã³ã¿ãŒãã§ã€ã¹
+- **ReDoc**: å¥åœ¢åŒã®ããã¥ã¡ã³ã衚瀺
+
+## 次ã®ã¹ããã
+
+ããã§ãšãããããŸã! 以äžãéæããŸãã:
+
+â
FastAPI-fastkit ã®ã€ã³ã¹ããŒã«
+â
æåã®ãããžã§ã¯ãäœæ
+â
éçºãµãŒããŒã®èµ·å
+â
API ãšã³ããã€ã³ãã®ãã¹ã
+â
æ°ããã«ãŒãã®è¿œå
+â
æ¢åã³ãŒãã®å€æŽ
+â
ãã¹ãã®å®è¡
+
+### åŠç¿ãç¶ãã
+
+1. **[æåã®ãããžã§ã¯ã](first-project.md)**: é«åºŠãªæ©èœãå«ãå®å
šãªããã° API ãæ§ç¯
+2. **[ã«ãŒãã®è¿œå ](../user-guide/adding-routes.md)**: ããè€é㪠API ãšã³ããã€ã³ããåŠã¶
+3. **[ãã³ãã¬ãŒãã®å©çš](../user-guide/using-templates.md)**: äºåæ§ç¯æžã¿ãã³ãã¬ãŒãã詊ã
+
+### ããã«è©Šã
+
+次ã®èª²é¡ã«ææŠããŠã¿ãŸããã:
+
+1. **æ€èšŒã®è¿œå **: ã¹ããŒãã«ããŒã¿æ€èšŒã«ãŒã«ã远å
+2. **ã«ã¹ã¿ã ã¬ã¹ãã³ã¹**: ã«ãŒãã®ã¬ã¹ãã³ã¹åœ¢åŒã倿Ž
+3. **ç°å¢å€æ°**: `.env` ãã¡ã€ã«ã§èšå®
+4. **ããã«ãŠã§ã¢ã®è¿œå **: CORS ãèªèšŒãå®è£
+5. **ããŒã¿ããŒã¹çµ±å**: STANDARD ã¹ã¿ãã¯ã«ã¢ããã°ã¬ãŒãããŠããŒã¿ããŒã¹å¯Ÿå¿
+
+### ããããåé¡ãšè§£æ±ºæ³
+
+**ãµãŒããŒãèµ·åããªã:**
+
+- ãããžã§ã¯ããã£ã¬ã¯ããªã«ããã確èª
+- ä»®æ³ç°å¢ãæå¹åãããŠããã確èª
+- ã³ãŒãã«æ§æãšã©ãŒããªãã確èª
+
+**ã€ã³ããŒããšã©ãŒ:**
+
+- ãã¹ãŠã® `__init__.py` ãã¡ã€ã«ãååšããã確èª
+- ã€ã³ããŒããã¹ãæ£ããã確èª
+- ä»®æ³ç°å¢ã䜿ã£ãŠããã確èª
+
+**ããŒããæ¢ã«äœ¿çšäž:**
+```console
+$ fastkit runserver --port 8080
+```
+
+## åŠãã ãã¹ããã©ã¯ãã£ã¹
+
+1. **ä»®æ³ç°å¢**: åžžã«éé¢ãããç°å¢ã䜿ã
+2. **ãããžã§ã¯ãæ§é **: æŽçãããã¢ãžã¥ãŒã«åã¢ãŒããã¯ãã£ã«åŸã
+3. **èªåãªããŒã**: éçºãµãŒããŒã§çŽ æ©ãã€ãã¬ãŒã·ã§ã³
+4. **API ããã¥ã¡ã³ã**: èªåããã¥ã¡ã³ãçæã掻çš
+5. **ãã¹ã**: éçºäžã¯å®æçã«ãã¹ããå®è¡
+
+!!! tip "éçºã®ãã³ã"
+ - ã³ãŒãã£ã³ã°äžã¯éçºãµãŒããŒãèµ·åãããŸãŸã«ãã
+ - 察話åããã¥ã¡ã³ã (`/docs`) ã§ API ããã¹ããã
+ - 圹ç«ã€ãšã©ãŒã¡ãã»ãŒãžã¯ã¿ãŒããã«ã«è¡šç€ºããã
+ - ããŸãã«ããŒãžã§ã³ç®¡çã«ã³ããããã
+
+ããã§ FastAPI-fastkit ã䜿ã£ãŠçŽ æŽããã API ãæ§ç¯ããæºåãæŽããŸãã! ð
diff --git a/docs/ja/tutorial/mcp-integration.md b/docs/ja/tutorial/mcp-integration.md
new file mode 100644
index 0000000..835b390
--- /dev/null
+++ b/docs/ja/tutorial/mcp-integration.md
@@ -0,0 +1,1730 @@
+# MCP (Model Context Protocol) ãšã®çµ±å
+
+Model Context Protocol (MCP) ã FastAPI ãšçµ±åããAI ã¢ãã«ã API ãšã³ããã€ã³ããããŒã«ãšããŠå©çšã§ããã·ã¹ãã ãæ§ç¯ããŸãã`fastapi-mcp` ãã³ãã¬ãŒãã䜿ããèªèšŒãæš©é管çãMCP ãµãŒããŒå®è£
ãŸã§å«ãå®å
šãª AI çµ±å API ãå®è£
ããŸãã
+
+## ãã®ãã¥ãŒããªã¢ã«ã§åŠã¶ããš
+
+- Model Context Protocol (MCP) ã®æŠå¿µãšå®è£
+- JWT ããŒã¹ã®èªèšŒã·ã¹ãã æ§ç¯
+- ããŒã«ããŒã¹ã¢ã¯ã»ã¹å¶åŸ¡ (RBAC) ã®å®è£
+- MCP ããŒã«ã®å
¬éãšç®¡ç
+- AI ã¢ãã«ãšã®å®å
šãª API éä¿¡
+- ãŠãŒã¶ãŒã»ãã·ã§ã³ãšã³ã³ããã¹ã管ç
+
+## åææ¡ä»¶
+
+- [ã«ã¹ã¿ã ã¬ã¹ãã³ã¹åŠçãã¥ãŒããªã¢ã«](custom-response-handling.md) ãå®äºæžã¿
+- JWT ãš OAuth2 ã®åºæ¬æŠå¿µã®çè§£
+- AI / LLM ã¢ãã«ãšã® API éä¿¡ã®åºç€
+- MCP ãããã³ã«ã®åºç€ç¥è
+
+## Model Context Protocol (MCP) ãšã¯
+
+MCP 㯠AI ã¢ãã«ãå€éšã·ã¹ãã ãšããåãã§ããããã«ããããã®æšæºåããããããã³ã«ã§ãã
+
+### åŸæ¥ã®ã¢ãããŒããš MCP ã¢ãããŒãã®æ¯èŒ
+
+**åŸæ¥ã®ã¢ãããŒã (çŽæ¥ API åŒã³åºã):**
+```
+AI ã¢ãã« â HTTP ãªã¯ãšã¹ã â API ãµãŒã㌠â ã¬ã¹ãã³ã¹
+```
+
+**MCP ã¢ãããŒã:**
+```
+AI ã¢ãã« â MCP ã¯ã©ã€ã¢ã³ã â MCP ãµãŒã㌠(FastAPI) â å®å
šãªããŒã«å®è¡ â ã¬ã¹ãã³ã¹
+```
+
+### MCP ã®å©ç¹
+
+- **ã»ãã¥ãªãã£**: èªèšŒãšæš©é管çãçµ±å
+- **æšæºå**: äžè²«ããã€ã³ã¿ãŒãã§ã€ã¹ãæäŸ
+- **ã³ã³ããã¹ã管ç**: ã»ãã·ã§ã³ããŒã¹ã®ç¶æ
ä¿æ
+- **ããŒã«æœè±¡å**: è€é㪠API ãã·ã³ãã«ãªããŒã«ãšããŠå
Ž
+
+## ã¹ããã 1: MCP çµ±åãããžã§ã¯ãã®äœæ
+
+`fastapi-mcp` ãã³ãã¬ãŒãã§ãããžã§ã¯ããäœæããŸã:
+
+
+
+```console
+$ fastkit startdemo fastapi-mcp
+Enter the project name: ai-integrated-api
+Enter the author name: Developer Kim
+Enter the author email: developer@example.com
+Enter the project description: MCP-based API server integrated with AI models
+Deploying FastAPI project using 'fastapi-mcp' template
+
+ Project Information
+ââââââââââââââââ¬ââââââââââââââââââââââââââââââââââââââââââââââ
+â Project Name â ai-integrated-api â
+â Author â Developer Kim â
+â Author Email â developer@example.com â
+â Description â MCP-based API server integrated with AI models â
+ââââââââââââââââŽââââââââââââââââââââââââââââââââââââââââââââââ
+
+ Template Dependencies
+ââââââââââââââââ¬âââââââââââââââââ
+â Dependency 1 â fastapi â
+â Dependency 2 â uvicorn â
+â Dependency 3 â pydantic â
+â Dependency 4 â python-jose â
+â Dependency 5 â passlib â
+â Dependency 6 â python-multipartâ
+â Dependency 7 â mcp â
+ââââââââââââââââŽâââââââââââââââââ
+
+Select package manager (pip, uv, pdm, poetry) [uv]: uv
+Do you want to proceed with project creation? [y/N]: y
+
+âš FastAPI project 'ai-integrated-api' from 'fastapi-mcp' has been created successfully!
+```
+
+
+
+## ã¹ããã 2: ãããžã§ã¯ãæ§é ã®è§£æ
+
+çæãããžã§ã¯ãã®æ§é ãèŠãŠãããŸã:
+
+```
+ai-integrated-api/
+âââ src/
+â âââ main.py # FastAPI ã¢ããª
+â âââ auth/
+â â âââ __init__.py
+â â âââ models.py # èªèšŒé¢é£ããŒã¿ã¢ãã«
+â â âââ jwt_handler.py # JWT ããŒã¯ã³åŠç
+â â âââ dependencies.py # èªèšŒçšäŸåæ§
+â â âââ routes.py # èªèšŒã«ãŒã¿ãŒ
+â âââ mcp/
+â â âââ __init__.py
+â â âââ server.py # MCP ãµãŒããŒå®è£
+â â âââ tools.py # MCP ããŒã«å®çŸ©
+â â âââ client.py # MCP ã¯ã©ã€ã¢ã³ã (ãã¹ãçš)
+â âââ api/
+â â âââ __init__.py
+â â âââ api.py # API ã«ãŒã¿ãŒéçŽ
+â â âââ routes/
+â â âââ items.py # item 管ç API
+â â âââ users.py # ãŠãŒã¶ãŒç®¡ç API
+â â âââ admin.py # 管ç API
+â âââ schemas/
+â â âââ __init__.py
+â â âââ auth.py # èªèšŒã¹ããŒã
+â â âââ users.py # ãŠãŒã¶ãŒã¹ããŒã
+â â âââ items.py # item ã¹ããŒã
+â âââ core/
+â âââ __init__.py
+â âââ config.py # èšå®
+â âââ database.py # ããŒã¿ããŒã¹ (ã€ã³ã¡ã¢ãª)
+â âââ security.py # ã»ãã¥ãªãã£èšå®
+âââ tests/
+ âââ test_auth.py # èªèšŒãã¹ã
+ âââ test_mcp.py # MCP ãã¹ã
+ âââ test_integration.py # çµ±åãã¹ã
+```
+
+## ã¹ããã 3: èªèšŒã·ã¹ãã ã®å®è£
+
+### JWT ããŒã¯ã³åŠç (`src/auth/jwt_handler.py`)
+
+```python
+from datetime import datetime, timedelta
+from typing import Optional, Dict, Any
+from jose import JWTError, jwt
+from passlib.context import CryptContext
+
+from src.core.config import settings
+
+# ãã¹ã¯ãŒãããã·ã¥å
+pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
+
+def verify_password(plain_password: str, hashed_password: str) -> bool:
+ """ãã¹ã¯ãŒãæ€èšŒ"""
+ return pwd_context.verify(plain_password, hashed_password)
+
+def get_password_hash(password: str) -> str:
+ """ãã¹ã¯ãŒãããã·ã¥å"""
+ return pwd_context.hash(password)
+
+def create_access_token(data: Dict[str, Any], expires_delta: Optional[timedelta] = None) -> str:
+ """ã¢ã¯ã»ã¹ããŒã¯ã³çæ"""
+ to_encode = data.copy()
+
+ if expires_delta:
+ expire = datetime.utcnow() + expires_delta
+ else:
+ expire = datetime.utcnow() + timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
+
+ to_encode.update({"exp": expire, "iat": datetime.utcnow()})
+
+ encoded_jwt = jwt.encode(
+ to_encode,
+ settings.SECRET_KEY,
+ algorithm=settings.ALGORITHM
+ )
+
+ return encoded_jwt
+
+def create_refresh_token(user_id: str) -> str:
+ """ãªãã¬ãã·ã¥ããŒã¯ã³çæ"""
+ data = {"sub": user_id, "type": "refresh"}
+ expire = datetime.utcnow() + timedelta(days=settings.REFRESH_TOKEN_EXPIRE_DAYS)
+
+ to_encode = data.copy()
+ to_encode.update({"exp": expire, "iat": datetime.utcnow()})
+
+ return jwt.encode(
+ to_encode,
+ settings.SECRET_KEY,
+ algorithm=settings.ALGORITHM
+ )
+
+def decode_token(token: str) -> Optional[Dict[str, Any]]:
+ """ããŒã¯ã³ããã³ãŒã"""
+ try:
+ payload = jwt.decode(
+ token,
+ settings.SECRET_KEY,
+ algorithms=[settings.ALGORITHM]
+ )
+ return payload
+ except JWTError:
+ return None
+
+def verify_token(token: str, token_type: str = "access") -> Optional[str]:
+ """ããŒã¯ã³æ€èšŒãšãŠãŒã¶ãŒ ID ã®è¿åŽ"""
+ payload = decode_token(token)
+
+ if not payload:
+ return None
+
+ # ããŒã¯ã³çš®å¥ã®æ€èšŒ
+ if token_type == "refresh" and payload.get("type") != "refresh":
+ return None
+
+ user_id = payload.get("sub")
+ if not user_id:
+ return None
+
+ return user_id
+
+class TokenManager:
+ """ããŒã¯ã³ç®¡çã¯ã©ã¹"""
+
+ def __init__(self):
+ self.blacklisted_tokens = set()
+
+ def blacklist_token(self, token: str):
+ """ããŒã¯ã³ããã©ãã¯ãªã¹ãã«è¿œå """
+ self.blacklisted_tokens.add(token)
+
+ def is_blacklisted(self, token: str) -> bool:
+ """ããŒã¯ã³ããã©ãã¯ãªã¹ããã確èª"""
+ return token in self.blacklisted_tokens
+
+ def create_token_pair(self, user_id: str, user_role: str) -> Dict[str, str]:
+ """access / refresh ããŒã¯ã³ãã¢ãçæ"""
+ access_token_data = {
+ "sub": user_id,
+ "role": user_role,
+ "type": "access"
+ }
+
+ access_token = create_access_token(access_token_data)
+ refresh_token = create_refresh_token(user_id)
+
+ return {
+ "access_token": access_token,
+ "refresh_token": refresh_token,
+ "token_type": "bearer"
+ }
+
+# ã°ããŒãã«ããŒã¯ã³ãããŒãžã£
+token_manager = TokenManager()
+```
+
+### ãŠãŒã¶ãŒã¢ãã«ãšããŒã¿ããŒã¹ (`src/auth/models.py`)
+
+```python
+from typing import List, Optional, Dict, Any
+from pydantic import BaseModel, EmailStr
+from enum import Enum
+from datetime import datetime
+
+class UserRole(str, Enum):
+ """ãŠãŒã¶ãŒããŒã«"""
+ ADMIN = "admin"
+ USER = "user"
+ AI_AGENT = "ai_agent"
+ READONLY = "readonly"
+
+class Permission(str, Enum):
+ """æš©é"""
+ READ_ITEMS = "read:items"
+ WRITE_ITEMS = "write:items"
+ DELETE_ITEMS = "delete:items"
+ MANAGE_USERS = "manage:users"
+ USE_MCP_TOOLS = "use:mcp_tools"
+ ADMIN_MCP = "admin:mcp"
+
+class User(BaseModel):
+ """ãŠãŒã¶ãŒã¢ãã«"""
+ id: str
+ email: EmailStr
+ username: str
+ full_name: Optional[str] = None
+ role: UserRole
+ permissions: List[Permission]
+ is_active: bool = True
+ created_at: datetime
+ last_login: Optional[datetime] = None
+ api_key: Optional[str] = None # MCP ã¯ã©ã€ã¢ã³ãçš
+
+class UserInDB(User):
+ """ããŒã¿ããŒã¹ä¿åçšãŠãŒã¶ãŒã¢ãã«"""
+ hashed_password: str
+
+class UserCreate(BaseModel):
+ """ãŠãŒã¶ãŒäœæã¹ããŒã"""
+ email: EmailStr
+ username: str
+ password: str
+ full_name: Optional[str] = None
+ role: UserRole = UserRole.USER
+
+class UserUpdate(BaseModel):
+ """ãŠãŒã¶ãŒæŽæ°ã¹ããŒã"""
+ email: Optional[EmailStr] = None
+ username: Optional[str] = None
+ full_name: Optional[str] = None
+ role: Optional[UserRole] = None
+ is_active: Optional[bool] = None
+
+class LoginRequest(BaseModel):
+ """ãã°ã€ã³ãªã¯ãšã¹ãã¹ããŒã"""
+ username: str
+ password: str
+
+class TokenResponse(BaseModel):
+ """ããŒã¯ã³ã¬ã¹ãã³ã¹ã¹ããŒã"""
+ access_token: str
+ refresh_token: str
+ token_type: str = "bearer"
+ expires_in: int
+ user: User
+
+# ããŒã«ããšã®ããã©ã«ãæš©é
+ROLE_PERMISSIONS = {
+ UserRole.ADMIN: [
+ Permission.READ_ITEMS,
+ Permission.WRITE_ITEMS,
+ Permission.DELETE_ITEMS,
+ Permission.MANAGE_USERS,
+ Permission.USE_MCP_TOOLS,
+ Permission.ADMIN_MCP
+ ],
+ UserRole.USER: [
+ Permission.READ_ITEMS,
+ Permission.WRITE_ITEMS,
+ Permission.USE_MCP_TOOLS
+ ],
+ UserRole.AI_AGENT: [
+ Permission.READ_ITEMS,
+ Permission.WRITE_ITEMS,
+ Permission.USE_MCP_TOOLS
+ ],
+ UserRole.READONLY: [
+ Permission.READ_ITEMS
+ ]
+}
+
+class UserDatabase:
+ """ã¡ã¢ãªããŒã¹ã®ãŠãŒã¶ãŒããŒã¿ããŒã¹"""
+
+ def __init__(self):
+ self.users: Dict[str, UserInDB] = {}
+ self._init_default_users()
+
+ def _init_default_users(self):
+ """ããã©ã«ããŠãŒã¶ãŒãäœæ"""
+ from src.auth.jwt_handler import get_password_hash
+ import uuid
+
+ # 管çè
ã¢ã«ãŠã³ã
+ admin_id = str(uuid.uuid4())
+ self.users[admin_id] = UserInDB(
+ id=admin_id,
+ email="admin@example.com",
+ username="admin",
+ full_name="System Administrator",
+ role=UserRole.ADMIN,
+ permissions=ROLE_PERMISSIONS[UserRole.ADMIN],
+ hashed_password=get_password_hash("admin123"),
+ created_at=datetime.utcnow(),
+ api_key=str(uuid.uuid4())
+ )
+
+ # AI ãšãŒãžã§ã³ãã¢ã«ãŠã³ã
+ ai_id = str(uuid.uuid4())
+ self.users[ai_id] = UserInDB(
+ id=ai_id,
+ email="ai@example.com",
+ username="ai_agent",
+ full_name="AI Assistant",
+ role=UserRole.AI_AGENT,
+ permissions=ROLE_PERMISSIONS[UserRole.AI_AGENT],
+ hashed_password=get_password_hash("ai123"),
+ created_at=datetime.utcnow(),
+ api_key=str(uuid.uuid4())
+ )
+
+ def get_user_by_username(self, username: str) -> Optional[UserInDB]:
+ """ãŠãŒã¶ãŒåã§æ€çŽ¢"""
+ return next(
+ (user for user in self.users.values() if user.username == username),
+ None
+ )
+
+ def get_user_by_id(self, user_id: str) -> Optional[UserInDB]:
+ """ID ã§æ€çŽ¢"""
+ return self.users.get(user_id)
+
+ def get_user_by_api_key(self, api_key: str) -> Optional[UserInDB]:
+ """API ããŒã§æ€çŽ¢"""
+ return next(
+ (user for user in self.users.values() if user.api_key == api_key),
+ None
+ )
+
+ def create_user(self, user_create: UserCreate) -> UserInDB:
+ """ãŠãŒã¶ãŒãäœæ"""
+ import uuid
+ from src.auth.jwt_handler import get_password_hash
+
+ user_id = str(uuid.uuid4())
+ user = UserInDB(
+ id=user_id,
+ email=user_create.email,
+ username=user_create.username,
+ full_name=user_create.full_name,
+ role=user_create.role,
+ permissions=ROLE_PERMISSIONS[user_create.role],
+ hashed_password=get_password_hash(user_create.password),
+ created_at=datetime.utcnow(),
+ api_key=str(uuid.uuid4())
+ )
+
+ self.users[user_id] = user
+ return user
+
+ def update_user(self, user_id: str, user_update: UserUpdate) -> Optional[UserInDB]:
+ """ãŠãŒã¶ãŒãæŽæ°"""
+ if user_id not in self.users:
+ return None
+
+ user = self.users[user_id]
+ update_data = user_update.dict(exclude_unset=True)
+
+ for field, value in update_data.items():
+ setattr(user, field, value)
+
+ # ããŒã«å€æŽæã¯æš©éãæŽæ°
+ if "role" in update_data:
+ user.permissions = ROLE_PERMISSIONS[user.role]
+
+ return user
+
+ def update_last_login(self, user_id: str):
+ """æçµãã°ã€ã³æå»ãæŽæ°"""
+ if user_id in self.users:
+ self.users[user_id].last_login = datetime.utcnow()
+
+# ã°ããŒãã«ããŒã¿ããŒã¹
+user_db = UserDatabase()
+```
+
+## ã¹ããã 4: èªèšŒçšäŸåæ§ã®å®è£
+
+### èªèšŒçšäŸåæ§ (`src/auth/dependencies.py`)
+
+```python
+from typing import Optional, List
+from fastapi import Depends, HTTPException, status, Security
+from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials, APIKeyHeader
+from jose import JWTError
+
+from src.auth.jwt_handler import decode_token, token_manager
+from src.auth.models import User, UserInDB, Permission, user_db
+
+# ã»ãã¥ãªãã£ã¹ããŒã
+security = HTTPBearer()
+api_key_header = APIKeyHeader(name="X-API-Key", auto_error=False)
+
+async def get_current_user(
+ credentials: HTTPAuthorizationCredentials = Security(security)
+) -> User:
+ """çŸåšã®èªèšŒæžã¿ãŠãŒã¶ãŒãååŸ"""
+ credentials_exception = HTTPException(
+ status_code=status.HTTP_401_UNAUTHORIZED,
+ detail="Could not validate credentials",
+ headers={"WWW-Authenticate": "Bearer"},
+ )
+
+ try:
+ token = credentials.credentials
+
+ # ãã©ãã¯ãªã¹ãã確èª
+ if token_manager.is_blacklisted(token):
+ raise credentials_exception
+
+ payload = decode_token(token)
+ if payload is None:
+ raise credentials_exception
+
+ user_id: str = payload.get("sub")
+ if user_id is None:
+ raise credentials_exception
+
+ except JWTError:
+ raise credentials_exception
+
+ user = user_db.get_user_by_id(user_id)
+ if user is None:
+ raise credentials_exception
+
+ if not user.is_active:
+ raise HTTPException(
+ status_code=status.HTTP_400_BAD_REQUEST,
+ detail="Inactive user"
+ )
+
+ return User(**user.dict())
+
+async def get_current_user_by_api_key(
+ api_key: Optional[str] = Security(api_key_header)
+) -> Optional[User]:
+ """API ããŒã§ãŠãŒã¶ãŒãèªèšŒ"""
+ if not api_key:
+ return None
+
+ user = user_db.get_user_by_api_key(api_key)
+ if not user or not user.is_active:
+ return None
+
+ return User(**user.dict())
+
+async def get_current_user_flexible(
+ token_user: Optional[User] = Depends(get_current_user),
+ api_key_user: Optional[User] = Depends(get_current_user_by_api_key)
+) -> User:
+ """ããŒã¯ã³ãŸã㯠API ããŒã§èªèšŒ (æè»ãªèªèšŒ)"""
+ user = token_user or api_key_user
+
+ if not user:
+ raise HTTPException(
+ status_code=status.HTTP_401_UNAUTHORIZED,
+ detail="Authentication required"
+ )
+
+ return user
+
+def require_permissions(*required_permissions: Permission):
+ """ç¹å®ã®æš©éãèŠæ±ããäŸåæ§"""
+ def permission_checker(current_user: User = Depends(get_current_user_flexible)) -> User:
+ for permission in required_permissions:
+ if permission not in current_user.permissions:
+ raise HTTPException(
+ status_code=status.HTTP_403_FORBIDDEN,
+ detail=f"Permission '{permission}' required"
+ )
+ return current_user
+
+ return permission_checker
+
+def require_roles(*required_roles):
+ """ç¹å®ã®ããŒã«ãèŠæ±ããäŸåæ§"""
+ def role_checker(current_user: User = Depends(get_current_user_flexible)) -> User:
+ if current_user.role not in required_roles:
+ raise HTTPException(
+ status_code=status.HTTP_403_FORBIDDEN,
+ detail=f"Role must be one of: {', '.join(required_roles)}"
+ )
+ return current_user
+
+ return role_checker
+
+# ããäœ¿ãæš©éäŸåæ§
+RequireAdmin = require_roles("admin")
+RequireReadItems = require_permissions(Permission.READ_ITEMS)
+RequireWriteItems = require_permissions(Permission.WRITE_ITEMS)
+RequireDeleteItems = require_permissions(Permission.DELETE_ITEMS)
+RequireMCPTools = require_permissions(Permission.USE_MCP_TOOLS)
+RequireAdminMCP = require_permissions(Permission.ADMIN_MCP)
+```
+
+### èªèšŒã«ãŒã¿ãŒ (`src/auth/routes.py`)
+
+```python
+from datetime import timedelta
+from fastapi import APIRouter, Depends, HTTPException, status
+from fastapi.security import OAuth2PasswordRequestForm
+
+from src.auth.models import (
+ User, UserCreate, UserUpdate, LoginRequest, TokenResponse,
+ user_db, UserRole
+)
+from src.auth.jwt_handler import (
+ verify_password, token_manager, verify_token, create_access_token
+)
+from src.auth.dependencies import get_current_user, RequireAdmin
+from src.core.config import settings
+
+router = APIRouter(prefix="/auth", tags=["authentication"])
+
+@router.post("/register", response_model=User)
+async def register_user(user_create: UserCreate):
+ """ãŠãŒã¶ãŒãç»é²"""
+ # ãŠãŒã¶ãŒåéè€ãã§ãã¯
+ if user_db.get_user_by_username(user_create.username):
+ raise HTTPException(
+ status_code=status.HTTP_400_BAD_REQUEST,
+ detail="Username already registered"
+ )
+
+ # æåã®ãŠãŒã¶ãŒã¯èªåçã«ç®¡çè
ã«
+ if not user_db.users:
+ user_create.role = UserRole.ADMIN
+
+ user = user_db.create_user(user_create)
+ return User(**user.dict())
+
+@router.post("/login", response_model=TokenResponse)
+async def login_user(form_data: OAuth2PasswordRequestForm = Depends()):
+ """ãŠãŒã¶ãŒãã°ã€ã³"""
+ user = user_db.get_user_by_username(form_data.username)
+
+ if not user or not verify_password(form_data.password, user.hashed_password):
+ raise HTTPException(
+ status_code=status.HTTP_401_UNAUTHORIZED,
+ detail="Incorrect username or password",
+ headers={"WWW-Authenticate": "Bearer"},
+ )
+
+ if not user.is_active:
+ raise HTTPException(
+ status_code=status.HTTP_400_BAD_REQUEST,
+ detail="Inactive user"
+ )
+
+ # ããŒã¯ã³ãçæ
+ tokens = token_manager.create_token_pair(user.id, user.role)
+
+ # æçµãã°ã€ã³æå»ãæŽæ°
+ user_db.update_last_login(user.id)
+
+ return TokenResponse(
+ access_token=tokens["access_token"],
+ refresh_token=tokens["refresh_token"],
+ token_type=tokens["token_type"],
+ expires_in=settings.ACCESS_TOKEN_EXPIRE_MINUTES * 60,
+ user=User(**user.dict())
+ )
+
+@router.post("/refresh", response_model=dict)
+async def refresh_token(refresh_token: str):
+ """ããŒã¯ã³ããªãã¬ãã·ã¥"""
+ user_id = verify_token(refresh_token, "refresh")
+
+ if not user_id:
+ raise HTTPException(
+ status_code=status.HTTP_401_UNAUTHORIZED,
+ detail="Invalid refresh token"
+ )
+
+ user = user_db.get_user_by_id(user_id)
+ if not user or not user.is_active:
+ raise HTTPException(
+ status_code=status.HTTP_401_UNAUTHORIZED,
+ detail="User not found or inactive"
+ )
+
+ # æ°ããããŒã¯ã³ãã¢ãçæ
+ tokens = token_manager.create_token_pair(user.id, user.role)
+
+ return {
+ "access_token": tokens["access_token"],
+ "refresh_token": tokens["refresh_token"],
+ "token_type": tokens["token_type"],
+ "expires_in": settings.ACCESS_TOKEN_EXPIRE_MINUTES * 60
+ }
+
+@router.post("/logout")
+async def logout_user(current_user: User = Depends(get_current_user)):
+ """ãŠãŒã¶ãŒãã°ã¢ãŠã"""
+ # å®è£
ã§ã¯ããŒã¯ã³ããã©ãã¯ãªã¹ããžè¿œå
+ return {"message": "Successfully logged out"}
+
+@router.get("/me", response_model=User)
+async def get_current_user_info(current_user: User = Depends(get_current_user)):
+ """çŸåšã®ãŠãŒã¶ãŒæ
å ±ãååŸ"""
+ return current_user
+
+@router.put("/me", response_model=User)
+async def update_current_user(
+ user_update: UserUpdate,
+ current_user: User = Depends(get_current_user)
+):
+ """çŸåšã®ãŠãŒã¶ãŒæ
å ±ãæŽæ°"""
+ # äžè¬ãŠãŒã¶ãŒã¯ããŒã«å€æŽäžå¯
+ if user_update.role and current_user.role != UserRole.ADMIN:
+ user_update.role = None
+
+ updated_user = user_db.update_user(current_user.id, user_update)
+ if not updated_user:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail="User not found"
+ )
+
+ return User(**updated_user.dict())
+
+@router.get("/users", response_model=list[User])
+async def list_users(admin_user: User = Depends(RequireAdmin)):
+ """ãŠãŒã¶ãŒäžèЧãååŸ (管çè
ã®ã¿)"""
+ return [User(**user.dict()) for user in user_db.users.values()]
+
+@router.post("/users/{user_id}/generate-api-key")
+async def generate_api_key(
+ user_id: str,
+ admin_user: User = Depends(RequireAdmin)
+):
+ """ãŠãŒã¶ãŒã® API ããŒãçæ (管çè
ã®ã¿)"""
+ import uuid
+
+ user = user_db.get_user_by_id(user_id)
+ if not user:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail="User not found"
+ )
+
+ # æ°ãã API ããŒãçæ
+ new_api_key = str(uuid.uuid4())
+ user.api_key = new_api_key
+
+ return {
+ "api_key": new_api_key,
+ "message": "API key generated successfully"
+ }
+```
+
+## ã¹ããã 5: MCP ãµãŒããŒã®å®è£
+
+### MCP ããŒã«ã®å®çŸ© (`src/mcp/tools.py`)
+
+```python
+from typing import Dict, Any, List, Optional
+from pydantic import BaseModel, Field
+from enum import Enum
+
+class ToolCategory(str, Enum):
+ """ããŒã«ã«ããŽãª"""
+ DATA_MANAGEMENT = "data_management"
+ SEARCH = "search"
+ ANALYSIS = "analysis"
+ ADMIN = "admin"
+
+class MCPTool(BaseModel):
+ """MCP ããŒã«å®çŸ©"""
+ name: str = Field(..., description="Tool name")
+ description: str = Field(..., description="Tool description")
+ category: ToolCategory = Field(..., description="Tool category")
+ parameters: Dict[str, Any] = Field(default_factory=dict, description="Parameter schema")
+ required_permissions: List[str] = Field(default_factory=list, description="Required permissions")
+ examples: List[Dict[str, Any]] = Field(default_factory=list, description="Usage examples")
+
+class ToolRegistry:
+ """ããŒã«ã¬ãžã¹ããª"""
+
+ def __init__(self):
+ self.tools: Dict[str, MCPTool] = {}
+ self._register_default_tools()
+
+ def _register_default_tools(self):
+ """ããã©ã«ãããŒã«ãç»é²"""
+
+ # item äœæããŒã«
+ self.register_tool(MCPTool(
+ name="create_item",
+ description="Create a new item",
+ category=ToolCategory.DATA_MANAGEMENT,
+ parameters={
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Item name"
+ },
+ "description": {
+ "type": "string",
+ "description": "Item description"
+ },
+ "price": {
+ "type": "number",
+ "description": "Item price",
+ "minimum": 0
+ },
+ "category": {
+ "type": "string",
+ "description": "Item category"
+ }
+ },
+ "required": ["name", "price"]
+ },
+ required_permissions=["write:items"],
+ examples=[
+ {
+ "name": "Notebook",
+ "description": "High-performance gaming notebook",
+ "price": 1500000,
+ "category": "electronics"
+ }
+ ]
+ ))
+
+ # item æ€çŽ¢ããŒã«
+ self.register_tool(MCPTool(
+ name="search_items",
+ description="Search for items",
+ category=ToolCategory.SEARCH,
+ parameters={
+ "type": "object",
+ "properties": {
+ "query": {
+ "type": "string",
+ "description": "Search query"
+ },
+ "category": {
+ "type": "string",
+ "description": "Category filter"
+ },
+ "min_price": {
+ "type": "number",
+ "description": "Minimum price"
+ },
+ "max_price": {
+ "type": "number",
+ "description": "Maximum price"
+ },
+ "limit": {
+ "type": "integer",
+ "description": "Result count limit",
+ "default": 10,
+ "maximum": 100
+ }
+ },
+ "required": ["query"]
+ },
+ required_permissions=["read:items"],
+ examples=[
+ {
+ "query": "Notebook",
+ "category": "electronics",
+ "max_price": 2000000,
+ "limit": 5
+ }
+ ]
+ ))
+
+ # item åæããŒã«
+ self.register_tool(MCPTool(
+ name="analyze_items",
+ description="Analyze item data",
+ category=ToolCategory.ANALYSIS,
+ parameters={
+ "type": "object",
+ "properties": {
+ "analysis_type": {
+ "type": "string",
+ "enum": ["price_distribution", "category_breakdown", "trend_analysis"],
+ "description": "Analysis type"
+ },
+ "date_range": {
+ "type": "object",
+ "properties": {
+ "start_date": {"type": "string", "format": "date"},
+ "end_date": {"type": "string", "format": "date"}
+ },
+ "description": "Analysis period"
+ }
+ },
+ "required": ["analysis_type"]
+ },
+ required_permissions=["read:items"],
+ examples=[
+ {
+ "analysis_type": "price_distribution",
+ "date_range": {
+ "start_date": "2024-01-01",
+ "end_date": "2024-12-31"
+ }
+ }
+ ]
+ ))
+
+ # ãŠãŒã¶ãŒç®¡çããŒã« (管çè
ã®ã¿)
+ self.register_tool(MCPTool(
+ name="manage_users",
+ description="Manage users",
+ category=ToolCategory.ADMIN,
+ parameters={
+ "type": "object",
+ "properties": {
+ "action": {
+ "type": "string",
+ "enum": ["list", "create", "update", "deactivate"],
+ "description": "Action to perform"
+ },
+ "user_data": {
+ "type": "object",
+ "description": "User data (create/update)"
+ },
+ "user_id": {
+ "type": "string",
+ "description": "User ID (update/deactivate)"
+ }
+ },
+ "required": ["action"]
+ },
+ required_permissions=["manage:users"],
+ examples=[
+ {
+ "action": "list"
+ },
+ {
+ "action": "create",
+ "user_data": {
+ "username": "newuser",
+ "email": "newuser@example.com",
+ "role": "user"
+ }
+ }
+ ]
+ ))
+
+ def register_tool(self, tool: MCPTool):
+ """ããŒã«ãç»é²"""
+ self.tools[tool.name] = tool
+
+ def get_tool(self, tool_name: str) -> Optional[MCPTool]:
+ """ããŒã«ãååŸ"""
+ return self.tools.get(tool_name)
+
+ def list_tools(self, user_permissions: List[str] = None) -> List[MCPTool]:
+ """ãŠãŒã¶ãŒæš©éã«å¿ããŠããŒã«äžèЧãè¿ã"""
+ if user_permissions is None:
+ return list(self.tools.values())
+
+ available_tools = []
+ for tool in self.tools.values():
+ # æš©éãã§ãã¯
+ if all(perm in user_permissions for perm in tool.required_permissions):
+ available_tools.append(tool)
+
+ return available_tools
+
+ def get_tools_by_category(self, category: ToolCategory, user_permissions: List[str] = None) -> List[MCPTool]:
+ """ã«ããŽãªå¥ã®ããŒã«äžèЧ"""
+ tools = self.list_tools(user_permissions)
+ return [tool for tool in tools if tool.category == category]
+
+# ã°ããŒãã«ããŒã«ã¬ãžã¹ããª
+tool_registry = ToolRegistry()
+```
+
+### MCP ãµãŒããŒå®è£
(`src/mcp/server.py`)
+
+```python
+from typing import Dict, Any, List, Optional
+from fastapi import HTTPException, status
+import asyncio
+import json
+
+from src.mcp.tools import tool_registry, ToolCategory
+from src.auth.models import User, Permission
+from src.api.routes.items import ItemCRUD
+from src.auth.models import user_db
+
+class MCPServer:
+ """Model Context Protocol ãµãŒããŒ"""
+
+ def __init__(self):
+ self.item_crud = ItemCRUD()
+ self.active_sessions: Dict[str, Dict[str, Any]] = {}
+
+ async def create_session(self, user: User) -> str:
+ """MCP ã»ãã·ã§ã³ãäœæ"""
+ import uuid
+
+ session_id = str(uuid.uuid4())
+ self.active_sessions[session_id] = {
+ "user_id": user.id,
+ "user": user,
+ "created_at": datetime.utcnow(),
+ "context": {},
+ "tool_usage_count": 0,
+ "last_activity": datetime.utcnow()
+ }
+
+ return session_id
+
+ async def get_session(self, session_id: str) -> Optional[Dict[str, Any]]:
+ """ã»ãã·ã§ã³ãååŸ"""
+ session = self.active_sessions.get(session_id)
+ if session:
+ session["last_activity"] = datetime.utcnow()
+ return session
+
+ async def close_session(self, session_id: str):
+ """ã»ãã·ã§ã³ãéãã"""
+ if session_id in self.active_sessions:
+ del self.active_sessions[session_id]
+
+ async def list_tools(self, user: User) -> List[Dict[str, Any]]:
+ """ãŠãŒã¶ãŒãå©çšå¯èœãªããŒã«äžèЧ"""
+ user_permissions = [perm.value for perm in user.permissions]
+ tools = tool_registry.list_tools(user_permissions)
+
+ return [
+ {
+ "name": tool.name,
+ "description": tool.description,
+ "category": tool.category,
+ "parameters": tool.parameters,
+ "examples": tool.examples
+ }
+ for tool in tools
+ ]
+
+ async def execute_tool(
+ self,
+ tool_name: str,
+ parameters: Dict[str, Any],
+ user: User,
+ session_id: Optional[str] = None
+ ) -> Dict[str, Any]:
+ """ããŒã«ãå®è¡"""
+
+ # ããŒã«ã®ååšç¢ºèª
+ tool = tool_registry.get_tool(tool_name)
+ if not tool:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail=f"Tool '{tool_name}' not found"
+ )
+
+ # æš©éãã§ãã¯
+ user_permissions = [perm.value for perm in user.permissions]
+ for required_perm in tool.required_permissions:
+ if required_perm not in user_permissions:
+ raise HTTPException(
+ status_code=status.HTTP_403_FORBIDDEN,
+ detail=f"Permission '{required_perm}' required for tool '{tool_name}'"
+ )
+
+ # ã»ãã·ã§ã³æŽæ°
+ if session_id:
+ session = await self.get_session(session_id)
+ if session:
+ session["tool_usage_count"] += 1
+
+ # ããŒã«å®è¡
+ try:
+ result = await self._execute_tool_logic(tool_name, parameters, user)
+
+ return {
+ "success": True,
+ "tool": tool_name,
+ "result": result,
+ "timestamp": datetime.utcnow().isoformat()
+ }
+
+ except Exception as e:
+ return {
+ "success": False,
+ "tool": tool_name,
+ "error": str(e),
+ "timestamp": datetime.utcnow().isoformat()
+ }
+
+ async def _execute_tool_logic(
+ self,
+ tool_name: str,
+ parameters: Dict[str, Any],
+ user: User
+ ) -> Any:
+ """ããŒã«ããžãã¯ã®å®è¡"""
+
+ if tool_name == "create_item":
+ return await self._create_item(parameters)
+
+ elif tool_name == "search_items":
+ return await self._search_items(parameters)
+
+ elif tool_name == "analyze_items":
+ return await self._analyze_items(parameters)
+
+ elif tool_name == "manage_users":
+ return await self._manage_users(parameters, user)
+
+ else:
+ raise ValueError(f"Tool '{tool_name}' implementation not found")
+
+ async def _create_item(self, parameters: Dict[str, Any]) -> Dict[str, Any]:
+ """item äœæããŒã«ã®å®è£
"""
+ from src.schemas.items import ItemCreate
+
+ try:
+ item_create = ItemCreate(**parameters)
+ created_item = await self.item_crud.create(item_create)
+
+ return {
+ "action": "create_item",
+ "item": created_item.dict(),
+ "message": f"Item '{created_item.name}' created successfully"
+ }
+ except Exception as e:
+ raise ValueError(f"Failed to create item: {str(e)}")
+
+ async def _search_items(self, parameters: Dict[str, Any]) -> Dict[str, Any]:
+ """item æ€çŽ¢ããŒã«ã®å®è£
"""
+ query = parameters.get("query", "")
+ category = parameters.get("category")
+ min_price = parameters.get("min_price")
+ max_price = parameters.get("max_price")
+ limit = parameters.get("limit", 10)
+
+ # æ€çŽ¢ããžãã¯ã®å®è£
+ all_items = await self.item_crud.get_all()
+ filtered_items = []
+
+ for item in all_items:
+ # ããã¹ãæ€çŽ¢
+ if query.lower() not in item.name.lower() and query.lower() not in (item.description or "").lower():
+ continue
+
+ # ã«ããŽãªãã£ã«ã¿
+ if category and getattr(item, 'category', None) != category:
+ continue
+
+ # äŸ¡æ Œãã£ã«ã¿
+ if min_price is not None and item.price < min_price:
+ continue
+ if max_price is not None and item.price > max_price:
+ continue
+
+ filtered_items.append(item)
+
+ # ä»¶æ°å¶é
+ result_items = filtered_items[:limit]
+
+ return {
+ "action": "search_items",
+ "query": query,
+ "total_found": len(filtered_items),
+ "returned_count": len(result_items),
+ "items": [item.dict() for item in result_items]
+ }
+
+ async def _analyze_items(self, parameters: Dict[str, Any]) -> Dict[str, Any]:
+ """item åæããŒã«ã®å®è£
"""
+ analysis_type = parameters.get("analysis_type")
+ date_range = parameters.get("date_range", {})
+
+ all_items = await self.item_crud.get_all()
+
+ if analysis_type == "price_distribution":
+ prices = [item.price for item in all_items]
+ if not prices:
+ return {"analysis": "price_distribution", "result": "No items found"}
+
+ return {
+ "analysis": "price_distribution",
+ "result": {
+ "total_items": len(prices),
+ "min_price": min(prices),
+ "max_price": max(prices),
+ "average_price": sum(prices) / len(prices),
+ "price_ranges": {
+ "under_100k": len([p for p in prices if p < 100000]),
+ "100k_to_500k": len([p for p in prices if 100000 <= p < 500000]),
+ "500k_to_1m": len([p for p in prices if 500000 <= p < 1000000]),
+ "over_1m": len([p for p in prices if p >= 1000000])
+ }
+ }
+ }
+
+ elif analysis_type == "category_breakdown":
+ categories = {}
+ for item in all_items:
+ category = getattr(item, 'category', 'uncategorized')
+ categories[category] = categories.get(category, 0) + 1
+
+ return {
+ "analysis": "category_breakdown",
+ "result": {
+ "total_categories": len(categories),
+ "categories": categories
+ }
+ }
+
+ else:
+ raise ValueError(f"Unknown analysis type: {analysis_type}")
+
+ async def _manage_users(self, parameters: Dict[str, Any], requesting_user: User) -> Dict[str, Any]:
+ """ãŠãŒã¶ãŒç®¡çããŒã«ã®å®è£
"""
+ action = parameters.get("action")
+
+ # 管çè
æš©éãã§ãã¯
+ if Permission.MANAGE_USERS not in requesting_user.permissions:
+ raise ValueError("Insufficient permissions for user management")
+
+ if action == "list":
+ users = [User(**user.dict()) for user in user_db.users.values()]
+ return {
+ "action": "list_users",
+ "total_users": len(users),
+ "users": [user.dict() for user in users]
+ }
+
+ elif action == "create":
+ user_data = parameters.get("user_data", {})
+ from src.auth.models import UserCreate
+
+ user_create = UserCreate(**user_data)
+ created_user = user_db.create_user(user_create)
+
+ return {
+ "action": "create_user",
+ "user": User(**created_user.dict()).dict(),
+ "message": f"User '{created_user.username}' created successfully"
+ }
+
+ else:
+ raise ValueError(f"Unknown user management action: {action}")
+
+# ã°ããŒãã« MCP ãµãŒããŒ
+mcp_server = MCPServer()
+```
+
+## ã¹ããã 6: MCP API ãšã³ããã€ã³ãã®å®è£
+
+### MCP API ã«ãŒã¿ãŒ (`src/api/routes/mcp.py`)
+
+```python
+from typing import Dict, Any, Optional
+from fastapi import APIRouter, Depends, HTTPException, status, BackgroundTasks
+from pydantic import BaseModel
+
+from src.auth.dependencies import get_current_user_flexible, RequireMCPTools
+from src.auth.models import User
+from src.mcp.server import mcp_server
+from src.mcp.tools import ToolCategory
+
+router = APIRouter(prefix="/mcp", tags=["MCP"])
+
+class ToolExecuteRequest(BaseModel):
+ """ããŒã«å®è¡ãªã¯ãšã¹ã"""
+ tool_name: str
+ parameters: Dict[str, Any]
+ session_id: Optional[str] = None
+
+class SessionCreateResponse(BaseModel):
+ """ã»ãã·ã§ã³äœæã¬ã¹ãã³ã¹"""
+ session_id: str
+ message: str
+
+@router.post("/session", response_model=SessionCreateResponse)
+async def create_mcp_session(
+ current_user: User = Depends(RequireMCPTools)
+):
+ """MCP ã»ãã·ã§ã³ãäœæ"""
+ session_id = await mcp_server.create_session(current_user)
+
+ return SessionCreateResponse(
+ session_id=session_id,
+ message=f"MCP session created (User: {current_user.username})"
+ )
+
+@router.delete("/session/{session_id}")
+async def close_mcp_session(
+ session_id: str,
+ current_user: User = Depends(RequireMCPTools)
+):
+ """MCP ã»ãã·ã§ã³ãéãã"""
+ session = await mcp_server.get_session(session_id)
+
+ if not session:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail="Session not found"
+ )
+
+ # ã»ãã·ã§ã³ææè
ã確èª
+ if session["user_id"] != current_user.id:
+ raise HTTPException(
+ status_code=status.HTTP_403_FORBIDDEN,
+ detail="Cannot close another user's session"
+ )
+
+ await mcp_server.close_session(session_id)
+
+ return {"message": "Session closed successfully"}
+
+@router.get("/tools")
+async def list_mcp_tools(
+ category: Optional[ToolCategory] = None,
+ current_user: User = Depends(RequireMCPTools)
+):
+ """å©çšå¯èœãª MCP ããŒã«ã®äžèЧ"""
+ tools = await mcp_server.list_tools(current_user)
+
+ if category:
+ tools = [tool for tool in tools if tool["category"] == category]
+
+ return {
+ "user": current_user.username,
+ "total_tools": len(tools),
+ "tools": tools
+ }
+
+@router.post("/execute")
+async def execute_mcp_tool(
+ request: ToolExecuteRequest,
+ background_tasks: BackgroundTasks,
+ current_user: User = Depends(RequireMCPTools)
+):
+ """MCP ããŒã«ãå®è¡"""
+
+ # ã»ãã·ã§ã³ç¢ºèª (ä»»æ)
+ if request.session_id:
+ session = await mcp_server.get_session(request.session_id)
+ if not session:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail="Session not found"
+ )
+
+ if session["user_id"] != current_user.id:
+ raise HTTPException(
+ status_code=status.HTTP_403_FORBIDDEN,
+ detail="Cannot use another user's session"
+ )
+
+ # ããŒã«ãå®è¡
+ result = await mcp_server.execute_tool(
+ tool_name=request.tool_name,
+ parameters=request.parameters,
+ user=current_user,
+ session_id=request.session_id
+ )
+
+ # å©çšãã°ãããã¯ã°ã©ãŠã³ãã§èšé²
+ background_tasks.add_task(
+ log_tool_usage,
+ current_user.id,
+ request.tool_name,
+ result["success"]
+ )
+
+ return result
+
+@router.get("/sessions")
+async def list_user_sessions(
+ current_user: User = Depends(RequireMCPTools)
+):
+ """ãŠãŒã¶ãŒã®ã¢ã¯ãã£ãã»ãã·ã§ã³äžèЧ"""
+ user_sessions = []
+
+ for session_id, session_data in mcp_server.active_sessions.items():
+ if session_data["user_id"] == current_user.id:
+ user_sessions.append({
+ "session_id": session_id,
+ "created_at": session_data["created_at"],
+ "tool_usage_count": session_data["tool_usage_count"],
+ "last_activity": session_data["last_activity"]
+ })
+
+ return {
+ "user": current_user.username,
+ "active_sessions": len(user_sessions),
+ "sessions": user_sessions
+ }
+
+@router.get("/stats")
+async def get_mcp_stats(
+ current_user: User = Depends(RequireMCPTools)
+):
+ """MCP å©çšçµ±èš"""
+ total_sessions = len(mcp_server.active_sessions)
+ user_sessions = len([
+ s for s in mcp_server.active_sessions.values()
+ if s["user_id"] == current_user.id
+ ])
+
+ return {
+ "user_stats": {
+ "username": current_user.username,
+ "active_sessions": user_sessions,
+ "permissions": [perm.value for perm in current_user.permissions]
+ },
+ "server_stats": {
+ "total_active_sessions": total_sessions,
+ "available_tools": len(await mcp_server.list_tools(current_user))
+ }
+ }
+
+async def log_tool_usage(user_id: str, tool_name: str, success: bool):
+ """ããŒã«å©çšãã° (ããã¯ã°ã©ãŠã³ããžã§ã)"""
+ import logging
+
+ logger = logging.getLogger("mcp.usage")
+ logger.info(
+ f"Tool usage - User: {user_id}, Tool: {tool_name}, Success: {success}"
+ )
+```
+
+## ã¹ããã 7: ã¢ããªã±ãŒã·ã§ã³ã®çµ±åãšãã¹ã
+
+### ã¡ã€ã³ã¢ããªã±ãŒã·ã§ã³ (`src/main.py`)
+
+```python
+from fastapi import FastAPI
+from fastapi.middleware.cors import CORSMiddleware
+
+from src.auth.routes import router as auth_router
+from src.api.routes.items import router as items_router
+from src.api.routes.mcp import router as mcp_router
+from src.core.config import settings
+
+app = FastAPI(
+ title="AI Integrated API",
+ description="AI model integrated MCP-based API server",
+ version="1.0.0"
+)
+
+# CORS èšå®
+app.add_middleware(
+ CORSMiddleware,
+ allow_origins=settings.ALLOWED_HOSTS,
+ allow_credentials=True,
+ allow_methods=["*"],
+ allow_headers=["*"],
+)
+
+# ã«ãŒã¿ãŒãåã蟌ã
+app.include_router(auth_router)
+app.include_router(items_router, prefix="/api/v1")
+app.include_router(mcp_router, prefix="/api/v1")
+
+@app.get("/")
+async def root():
+ return {
+ "message": "AI Integrated API with MCP Support",
+ "version": "1.0.0",
+ "endpoints": {
+ "authentication": "/auth",
+ "items": "/api/v1/items",
+ "mcp": "/api/v1/mcp",
+ "docs": "/docs"
+ }
+ }
+
+@app.get("/health")
+async def health_check():
+ """ãã«ã¹ãã§ãã¯ãšã³ããã€ã³ã"""
+ return {
+ "status": "healthy",
+ "version": "1.0.0",
+ "services": {
+ "auth": "operational",
+ "mcp": "operational",
+ "database": "operational"
+ }
+ }
+```
+
+### ãµãŒããŒã®èµ·åãšãã¹ã
+
+
+
+```console
+$ cd ai-integrated-api
+$ fastkit runserver
+Starting FastAPI server at 127.0.0.1:8000...
+
+# ãŠãŒã¶ãŒãã°ã€ã³
+$ curl -X POST "http://localhost:8000/auth/login" \
+ -H "Content-Type: application/x-www-form-urlencoded" \
+ -d "username=admin&password=admin123"
+
+{
+ "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
+ "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
+ "token_type": "bearer",
+ "expires_in": 1800,
+ "user": {
+ "id": "123e4567-e89b-12d3-a456-426614174000",
+ "email": "admin@example.com",
+ "username": "admin",
+ "role": "admin",
+ "permissions": ["read:items", "write:items", ...]
+ }
+}
+
+# MCP ã»ãã·ã§ã³ãäœæ
+$ curl -X POST "http://localhost:8000/api/v1/mcp/session" \
+ -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
+
+{
+ "session_id": "abc123-def456-ghi789",
+ "message": "MCP session created (User: admin)"
+}
+
+# å©çšå¯èœãªããŒã«ãäžèЧ
+$ curl "http://localhost:8000/api/v1/mcp/tools" \
+ -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
+
+{
+ "user": "admin",
+ "total_tools": 4,
+ "tools": [
+ {
+ "name": "create_item",
+ "description": "Create a new item",
+ "category": "data_management",
+ "parameters": {...},
+ "examples": [...]
+ },
+ ...
+ ]
+}
+
+# MCP ããŒã«ãå®è¡ (item äœæ)
+$ curl -X POST "http://localhost:8000/api/v1/mcp/execute" \
+ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "tool_name": "create_item",
+ "parameters": {
+ "name": "AI generated item",
+ "description": "MCP through AI generated item",
+ "price": 500000,
+ "category": "ai_generated"
+ },
+ "session_id": "abc123-def456-ghi789"
+ }'
+
+{
+ "success": true,
+ "tool": "create_item",
+ "result": {
+ "action": "create_item",
+ "item": {
+ "id": 1,
+ "name": "AI generated item",
+ "description": "MCP through AI generated item",
+ "price": 500000,
+ "category": "ai_generated",
+ "created_at": "2024-01-01T12:00:00Z"
+ },
+ "message": "Item 'AI generated item' created successfully"
+ },
+ "timestamp": "2024-01-01T12:00:00.123456Z"
+}
+
+# MCP ããŒã«ãå®è¡ (item æ€çŽ¢)
+$ curl -X POST "http://localhost:8000/api/v1/mcp/execute" \
+ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "tool_name": "search_items",
+ "parameters": {
+ "query": "AI",
+ "limit": 5
+ }
+ }'
+```
+
+
+
+## ã¹ããã 8: AI ã¯ã©ã€ã¢ã³ãäŸ
+
+### Python MCP ã¯ã©ã€ã¢ã³ãäŸ
+
+```python
+# client_example.py
+import asyncio
+import aiohttp
+from typing import Dict, Any, List
+
+class MCPClient:
+ """MCP ã¯ã©ã€ã¢ã³ãäŸ"""
+
+ def __init__(self, base_url: str, api_key: str):
+ self.base_url = base_url
+ self.api_key = api_key
+ self.session_id = None
+ self.session = None
+
+ async def __aenter__(self):
+ self.session = aiohttp.ClientSession(
+ headers={"X-API-Key": self.api_key}
+ )
+ return self
+
+ async def __aexit__(self, exc_type, exc_val, exc_tb):
+ if self.session_id:
+ await self.close_session()
+ if self.session:
+ await self.session.close()
+
+ async def create_session(self) -> str:
+ """MCP ã»ãã·ã§ã³ãäœæ"""
+ async with self.session.post(f"{self.base_url}/api/v1/mcp/session") as resp:
+ data = await resp.json()
+ self.session_id = data["session_id"]
+ return self.session_id
+
+ async def close_session(self):
+ """MCP ã»ãã·ã§ã³ãéãã"""
+ if self.session_id:
+ async with self.session.delete(f"{self.base_url}/api/v1/mcp/session/{self.session_id}"):
+ pass
+ self.session_id = None
+
+ async def list_tools(self) -> List[Dict[str, Any]]:
+ """å©çšå¯èœããŒã«ã®äžèЧ"""
+ async with self.session.get(f"{self.base_url}/api/v1/mcp/tools") as resp:
+ data = await resp.json()
+ return data["tools"]
+
+ async def execute_tool(self, tool_name: str, parameters: Dict[str, Any]) -> Dict[str, Any]:
+ """ããŒã«ãå®è¡"""
+ payload = {
+ "tool_name": tool_name,
+ "parameters": parameters,
+ "session_id": self.session_id
+ }
+
+ async with self.session.post(
+ f"{self.base_url}/api/v1/mcp/execute",
+ json=payload
+ ) as resp:
+ return await resp.json()
+
+ async def ai_assistant_workflow(self, user_request: str) -> str:
+ """AI ã¢ã·ã¹ã¿ã³ãã®ã¯ãŒã¯ãããŒã·ãã¥ã¬ãŒã·ã§ã³"""
+
+ # 1. ã»ãã·ã§ã³äœæ
+ await self.create_session()
+ print(f"Session created: {self.session_id}")
+
+ # 2. ãŠãŒã¶ãŒãªã¯ãšã¹ããè§£æããŠé©åãªããŒã«ãéžæ
+ if "Create item" in user_request or "Create" in user_request:
+ # item äœæãªã¯ãšã¹ã
+ result = await self.execute_tool("create_item", {
+ "name": "AI recommended item",
+ "description": "AI generated item based on user request",
+ "price": 100000,
+ "category": "ai_recommended"
+ })
+
+ if result["success"]:
+ item_name = result["result"]["item"]["name"]
+ return f"â
'{item_name}' item created successfully!"
+ else:
+ return f"â Item creation failed: {result.get('error', 'Unknown error')}"
+
+ elif "Search" in user_request or "Find" in user_request:
+ # æ€çŽ¢ãªã¯ãšã¹ã
+ search_query = "Item" # å®é㯠NLP ã§æœåº
+ result = await self.execute_tool("search_items", {
+ "query": search_query,
+ "limit": 5
+ })
+
+ if result["success"]:
+ items = result["result"]["items"]
+ item_list = "\n".join([f"- {item['name']} (â©{item['price']:,})" for item in items])
+ return f"ð Search results ({len(items)} items):\n{item_list}"
+ else:
+ return f"â Search failed: {result.get('error', 'Unknown error')}"
+
+ elif "Analyze" in user_request:
+ # åæãªã¯ãšã¹ã
+ result = await self.execute_tool("analyze_items", {
+ "analysis_type": "price_distribution"
+ })
+
+ if result["success"]:
+ analysis = result["result"]["result"]
+ return f"ð Price analysis:\nAverage price: â©{analysis['average_price']:,.0f}\nMinimum: â©{analysis['min_price']:,} - Maximum: â©{analysis['max_price']:,}"
+ else:
+ return f"â Analysis failed: {result.get('error', 'Unknown error')}"
+
+ else:
+ return "Sorry, I couldn't find a tool to handle that request."
+
+async def main():
+ """ã¯ã©ã€ã¢ã³ããã¹ã"""
+ async with MCPClient("http://localhost:8000", "your-api-key-here") as client:
+
+ # å©çšå¯èœãªããŒã«ã衚瀺
+ tools = await client.list_tools()
+ print(f"Available tools: {len(tools)}")
+ for tool in tools:
+ print(f"- {tool['name']}: {tool['description']}")
+
+ print("\n" + "="*50 + "\n")
+
+ # AI ã¢ã·ã¹ã¿ã³ãã®ã·ãã¥ã¬ãŒã·ã§ã³
+ test_requests = [
+ "Create a new item",
+ "Search for items",
+ "Analyze price distribution"
+ ]
+
+ for request in test_requests:
+ print(f"User request: {request}")
+ response = await client.ai_assistant_workflow(request)
+ print(f"AI response: {response}")
+ print("-" * 30)
+
+if __name__ == "__main__":
+ asyncio.run(main())
+```
+
+
+
+
+
+## ãŸãšã
+
+ãã®ãã¥ãŒããªã¢ã«ã§ã¯ãMCP (Model Context Protocol) ã®çµ±åãšããŠæ¬¡ãå®è£
ããŸãã:
+
+- â
JWT ããŒã¹ã®èªèšŒã·ã¹ãã æ§ç¯
+- â
ããŒã«ããŒã¹ã¢ã¯ã»ã¹å¶åŸ¡ (RBAC) ã®å®è£
+- â
MCP ãµãŒããŒãšããŒã«ã·ã¹ãã ã®å®è£
+- â
ã»ãã·ã§ã³ããŒã¹ã®ã³ã³ããã¹ã管ç
+- â
AI ã¢ãã«ãšã®å®å
šãª API éä¿¡
+- â
ããŒã«æš©é管çãšå©çšè¿œè·¡
+- â
å®éã® AI ã¯ã©ã€ã¢ã³ãäŸã®å®è£
+
+ããã§ãAI ã¢ãã«ã API æ©èœãå®å
šãã€å¹ççã«å©çšã§ãã MCP ããŒã¹ã®ã·ã¹ãã ãæ§ç¯ã§ããŸãã
diff --git a/docs/ja/user-guide/adding-routes.md b/docs/ja/user-guide/adding-routes.md
new file mode 100644
index 0000000..d2e1078
--- /dev/null
+++ b/docs/ja/user-guide/adding-routes.md
@@ -0,0 +1,581 @@
+# ã«ãŒãã®è¿œå
+
+æ¢åã® FastAPI ãããžã§ã¯ãã«æ°ãã API ã«ãŒãã远å ããæ¹æ³ãåŠã³ãŸãã
+
+## åºæ¬çãªã«ãŒã远å
+
+### `addroute` ã³ãã³ãã䜿ã
+
+FastAPI-fastkit ã® `addroute` ã³ãã³ãã¯ãæ°ããã«ãŒãã®è¿œå ãç°¡åã«ããŸã:
+
+
+
+```console
+$ fastkit addroute users my-awesome-api
+ Adding New Route
+ââââââââââââââââââââ¬âââââââââââââââââââââââââââââââââââââââââââ
+â Project â my-awesome-api â
+â Route Name â users â
+â Target Directory â ~/my-awesome-api â
+ââââââââââââââââââââŽâââââââââââââââââââââââââââââââââââââââââââ
+
+Do you want to add route 'users' to project 'my-awesome-api'? [Y/n]: y
+
+âââââââââââââââââââââââââ Info âââââââââââââââââââââââââ®
+â â¹ Updated main.py to include the API router â
+â°âââââââââââââââââââââââââââââââââââââââââââââââââââââââ¯
+ââââââââââââââââââââââââ Success ââââââââââââââââââââââââ®
+â âš Successfully added new route 'users' to project â
+â `my-awesome-api` â
+â°ââââââââââââââââââââââââââââââââââââââââââââââââââââââââ¯
+```
+
+
+
+## äœãäœæãããã
+
+ã«ãŒãã远å ãããšãFastAPI-fastkit ã¯æ¬¡ã®ãã¡ã€ã«ãèšå®ãèªåã§çæããŸã:
+
+### 1. ã«ãŒããã¡ã€ã«: `src/api/routes/users.py`
+
+```python
+from typing import List
+from fastapi import APIRouter, HTTPException, status
+from src.schemas.users import User, UserCreate, UserUpdate
+from src.crud.users import users_crud
+
+router = APIRouter()
+
+@router.get("/", response_model=List[User])
+def read_users():
+ """Get all users"""
+ return users_crud.get_all()
+
+@router.post("/", response_model=User, status_code=status.HTTP_201_CREATED)
+def create_user(user: UserCreate):
+ """Create a new user"""
+ return users_crud.create(user)
+
+@router.get("/{user_id}", response_model=User)
+def read_user(user_id: int):
+ """Get a specific user"""
+ user = users_crud.get_by_id(user_id)
+ if user is None:
+ raise HTTPException(status_code=404, detail="User not found")
+ return user
+
+@router.put("/{user_id}", response_model=User)
+def update_user(user_id: int, user: UserUpdate):
+ """Update a user"""
+ updated_user = users_crud.update(user_id, user)
+ if updated_user is None:
+ raise HTTPException(status_code=404, detail="User not found")
+ return updated_user
+
+@router.delete("/{user_id}", status_code=status.HTTP_204_NO_CONTENT)
+def delete_user(user_id: int):
+ """Delete a user"""
+ success = users_crud.delete(user_id)
+ if not success:
+ raise HTTPException(status_code=404, detail="User not found")
+```
+
+### 2. CRUD æäœ: `src/crud/users.py`
+
+```python
+from typing import List, Optional
+from src.schemas.users import User, UserCreate, UserUpdate
+
+class UsersCRUD:
+ def __init__(self):
+ self._users: List[User] = []
+ self._next_id = 1
+
+ def get_all(self) -> List[User]:
+ """Get all users"""
+ return self._users
+
+ def get_by_id(self, user_id: int) -> Optional[User]:
+ """Get user by ID"""
+ return next((user for user in self._users if user.id == user_id), None)
+
+ def create(self, user: UserCreate) -> User:
+ """Create a new user"""
+ new_user = User(
+ id=self._next_id,
+ title=user.title,
+ description=user.description
+ )
+ self._next_id += 1
+ self._users.append(new_user)
+ return new_user
+
+ def update(self, user_id: int, user: UserUpdate) -> Optional[User]:
+ """Update an existing user"""
+ existing_user = self.get_by_id(user_id)
+ if existing_user:
+ update_data = user.dict(exclude_unset=True)
+ for field, value in update_data.items():
+ setattr(existing_user, field, value)
+ return existing_user
+ return None
+
+ def delete(self, user_id: int) -> bool:
+ """Delete a user"""
+ user = self.get_by_id(user_id)
+ if user:
+ self._users.remove(user)
+ return True
+ return False
+
+users_crud = UsersCRUD()
+```
+
+### 3. Pydantic ã¹ããŒã: `src/schemas/users.py`
+
+```python
+from typing import Optional
+from pydantic import BaseModel
+
+class UserBase(BaseModel):
+ title: str
+ description: Optional[str] = None
+
+class UserCreate(UserBase):
+ pass
+
+class UserUpdate(BaseModel):
+ title: Optional[str] = None
+ description: Optional[str] = None
+
+class User(UserBase):
+ id: int
+
+ class Config:
+ from_attributes = True
+```
+
+### 4. ã«ãŒã¿ãŒã®ç»é²
+
+ãã®ã³ãã³ã㯠`src/api/api.py` ãèªåã§æŽæ°ããæ°ããã«ãŒã¿ãŒãåã蟌ã¿ãŸã:
+
+```python
+from fastapi import APIRouter
+from src.api.routes import items, users
+
+api_router = APIRouter()
+
+api_router.include_router(items.router, prefix="/items", tags=["items"])
+api_router.include_router(users.router, prefix="/users", tags=["users"])
+```
+
+## çæããã API ãšã³ããã€ã³ã
+
+`users` ã«ãŒãã远å ãããšã次ã®ãšã³ããã€ã³ãã䜿ããããã«ãªããŸã:
+
+| ã¡ãœãã | ãšã³ããã€ã³ã | 説æ |
+|---|---|---|
+| `GET` | `/api/v1/users/` | ãã¹ãŠã®ãŠãŒã¶ãŒãååŸ |
+| `POST` | `/api/v1/users/` | æ°ãããŠãŒã¶ãŒãäœæ |
+| `GET` | `/api/v1/users/{user_id}` | ç¹å®ã®ãŠãŒã¶ãŒãååŸ |
+| `PUT` | `/api/v1/users/{user_id}` | ãŠãŒã¶ãŒãæŽæ° |
+| `DELETE` | `/api/v1/users/{user_id}` | ãŠãŒã¶ãŒãåé€ |
+
+## æ°ããã«ãŒãã®ãã¹ã
+
+### 1. ãµãŒããŒã®èµ·å
+
+
+
+```console
+$ fastkit runserver
+INFO: Uvicorn running on http://127.0.0.1:8000
+```
+
+
+
+### 2. API ããã¥ã¡ã³ãã®ç¢ºèª
+
+[http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs) ã«ã¢ã¯ã»ã¹ããŠã察話åããã¥ã¡ã³ãã§æ°ãããšã³ããã€ã³ãã確èªããŸãããã
+
+### 3. curl ã§ã®ãã¹ã
+
+**ãŠãŒã¶ãŒãäœæ:**
+
+
+```console
+$ curl -X POST "http://127.0.0.1:8000/api/v1/users/" \
+ -H "Content-Type: application/json" \
+ -d '{"title": "John Doe", "description": "Software Developer"}'
+
+{
+ "id": 1,
+ "title": "John Doe",
+ "description": "Software Developer"
+}
+```
+
+
+
+**ãã¹ãŠã®ãŠãŒã¶ãŒãååŸ:**
+
+
+```console
+$ curl http://127.0.0.1:8000/api/v1/users/
+
+[
+ {
+ "id": 1,
+ "title": "John Doe",
+ "description": "Software Developer"
+ }
+]
+```
+
+
+
+**ç¹å®ã®ãŠãŒã¶ãŒãååŸ:**
+
+
+```console
+$ curl http://127.0.0.1:8000/api/v1/users/1
+
+{
+ "id": 1,
+ "title": "John Doe",
+ "description": "Software Developer"
+}
+```
+
+
+
+## çæã³ãŒãã®ã«ã¹ã¿ãã€ãº
+
+çæãããã³ãŒãã¯å®å
šã«ã«ã¹ã¿ãã€ãºå¯èœã§ããããè¡ã倿ŽäŸã瀺ããŸã:
+
+### 1. ãŠãŒã¶ãŒã¹ããŒãã®æ¡åŒµ
+
+`src/schemas/users.py` ãããå®çšçãªãŠãŒã¶ãŒããŒã¿åãã«å€æŽããŸã:
+
+```python
+from typing import Optional
+from datetime import datetime
+from pydantic import BaseModel, EmailStr, Field
+
+class UserBase(BaseModel):
+ email: EmailStr
+ username: str = Field(..., min_length=3, max_length=50)
+ full_name: Optional[str] = None
+ is_active: bool = True
+
+class UserCreate(UserBase):
+ password: str = Field(..., min_length=8)
+
+class UserUpdate(BaseModel):
+ email: Optional[EmailStr] = None
+ username: Optional[str] = Field(None, min_length=3, max_length=50)
+ full_name: Optional[str] = None
+ is_active: Optional[bool] = None
+
+class User(UserBase):
+ id: int
+ created_at: datetime
+
+ class Config:
+ from_attributes = True
+
+class UserInDB(User):
+ hashed_password: str
+```
+
+### 2. æ€èšŒã€ãã® CRUD æ¡åŒµ
+
+`src/crud/users.py` ããããæŽç·Žãããæ€èšŒã§æŽæ°ããŸã:
+
+```python
+from typing import List, Optional
+from datetime import datetime
+import hashlib
+from src.schemas.users import UserCreate, UserUpdate, UserInDB
+
+class UsersCRUD:
+ def __init__(self):
+ self._users: List[UserInDB] = []
+ self._next_id = 1
+
+ def _hash_password(self, password: str) -> str:
+ """Simple password hashing (use bcrypt in production)"""
+ return hashlib.sha256(password.encode()).hexdigest()
+
+ def get_by_email(self, email: str) -> Optional[UserInDB]:
+ """Get user by email"""
+ return next((user for user in self._users if user.email == email), None)
+
+ def get_by_username(self, username: str) -> Optional[UserInDB]:
+ """Get user by username"""
+ return next((user for user in self._users if user.username == username), None)
+
+ def create(self, user: UserCreate) -> UserInDB:
+ """Create a new user with validation"""
+ # Check for duplicates
+ if self.get_by_email(user.email):
+ raise ValueError("Email already registered")
+ if self.get_by_username(user.username):
+ raise ValueError("Username already taken")
+
+ new_user = UserInDB(
+ id=self._next_id,
+ email=user.email,
+ username=user.username,
+ full_name=user.full_name,
+ is_active=user.is_active,
+ created_at=datetime.now(),
+ hashed_password=self._hash_password(user.password)
+ )
+ self._next_id += 1
+ self._users.append(new_user)
+ return new_user
+
+users_crud = UsersCRUD()
+```
+
+### 3. ãšã©ãŒãã³ããªã³ã°ã匷åããã«ãŒã
+
+`src/api/routes/users.py` ããããäžå¯§ãªãšã©ãŒãã³ããªã³ã°ã§æŽæ°ããŸã:
+
+```python
+from typing import List
+from fastapi import APIRouter, HTTPException, status
+from src.schemas.users import User, UserCreate, UserUpdate
+from src.crud.users import users_crud
+
+router = APIRouter()
+
+@router.post("/", response_model=User, status_code=status.HTTP_201_CREATED)
+def create_user(user: UserCreate):
+ """Create a new user"""
+ try:
+ new_user = users_crud.create(user)
+ # Return user without password hash
+ return User(**new_user.dict())
+ except ValueError as e:
+ raise HTTPException(
+ status_code=status.HTTP_400_BAD_REQUEST,
+ detail=str(e)
+ )
+
+@router.get("/{user_id}", response_model=User)
+def read_user(user_id: int):
+ """Get a specific user"""
+ user = users_crud.get_by_id(user_id)
+ if not user:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail=f"User with id {user_id} not found"
+ )
+ return User(**user.dict())
+```
+
+## è€æ°ã®ã«ãŒãã远å ãã
+
+è€æ°ã®ã«ãŒãã远å ããŠãæ¬æ Œç㪠API ã«è²ãŠãŠããããšãã§ããŸã:
+
+
+
+```console
+# ãªãœãŒã¹ã«ãŒãã远å (ã«ãŒãåãå
ããããžã§ã¯ããã£ã¬ã¯ããªãåŸ)
+$ fastkit addroute products my-awesome-api
+$ fastkit addroute orders my-awesome-api
+$ fastkit addroute categories my-awesome-api
+
+# ãããããå®å
šãª CRUD æ§é ãçæããŸã
+```
+
+
+
+ããã§æ¬¡ã®ãããªå
æ¬ç㪠API ãçæãããŸã:
+
+- `/api/v1/users/` - ãŠãŒã¶ãŒç®¡ç
+- `/api/v1/products/` - ååã«ã¿ãã°
+- `/api/v1/orders/` - 泚æåŠç
+- `/api/v1/categories/` - ã«ããŽãªç®¡ç
+
+## ã«ãŒãã®æŽç
+
+### é¢é£ãšã³ããã€ã³ãã®ã°ã«ãŒãå
+
+ãã¡ã€ã³ããšã«ã«ãŒããæŽçã§ããŸã:
+
+```python
+# src/api/api.py
+from fastapi import APIRouter
+from src.api.routes import users, products, orders, categories
+
+api_router = APIRouter()
+
+# User management
+api_router.include_router(
+ users.router,
+ prefix="/users",
+ tags=["User Management"]
+)
+
+# E-commerce
+api_router.include_router(
+ products.router,
+ prefix="/products",
+ tags=["E-commerce"]
+)
+api_router.include_router(
+ orders.router,
+ prefix="/orders",
+ tags=["E-commerce"]
+)
+api_router.include_router(
+ categories.router,
+ prefix="/categories",
+ tags=["E-commerce"]
+)
+```
+
+### ã«ãŒãã«äŸåæ§ã远å
+
+èªèšŒãªã©ã®äŸåæ§ã远å ããŸã:
+
+```python
+from fastapi import APIRouter, Depends
+from src.core.auth import get_current_user
+
+router = APIRouter()
+
+@router.get("/profile", response_model=User)
+def get_user_profile(current_user: User = Depends(get_current_user)):
+ """Get current user's profile"""
+ return current_user
+
+@router.post("/", response_model=User)
+def create_user(
+ user: UserCreate,
+ current_user: User = Depends(get_current_user)
+):
+ """Create a new user (admin only)"""
+ if not current_user.is_admin:
+ raise HTTPException(status_code=403, detail="Admin access required")
+ return users_crud.create(user)
+```
+
+## ãã¹ããã©ã¯ãã£ã¹
+
+### 1. äžè²«ããåœå
+
+äžè²«ããåœåèŠåã«åŸããŸããã:
+
+- **ã«ãŒãå**: è€æ°åœ¢ã®åè©ãäœ¿çš (`users`ã`products`ã`orders`)
+- **ã¹ããŒãå**: åæ°åœ¢ãäœ¿çš (`User`ã`Product`ã`Order`)
+- **CRUD ã¯ã©ã¹**: æ«å°Ÿã `CRUD` ã«çµ±äž (`UsersCRUD`ã`ProductsCRUD`)
+
+### 2. ãšã©ãŒãã³ããªã³ã°
+
+åžžã«ãšã©ãŒãäžå¯§ã«æ±ããŸããã:
+
+```python
+@router.post("/", response_model=User)
+def create_user(user: UserCreate):
+ try:
+ return users_crud.create(user)
+ except ValueError as e:
+ raise HTTPException(status_code=400, detail=str(e))
+ except Exception as e:
+ raise HTTPException(status_code=500, detail="Internal server error")
+```
+
+### 3. ããã¥ã¡ã³ã
+
+å
å®ãã docstring ãæžããŸããã:
+
+```python
+@router.get("/{user_id}", response_model=User)
+def read_user(user_id: int):
+ """
+ Get a specific user by ID.
+
+ Args:
+ user_id: The unique identifier for the user
+
+ Returns:
+ User: The user object with all details
+
+ Raises:
+ HTTPException: 404 if user not found
+ """
+ user = users_crud.get_by_id(user_id)
+ if not user:
+ raise HTTPException(status_code=404, detail="User not found")
+ return user
+```
+
+### 4. ãã¹ã
+
+æ°ããã«ãŒãã«ã¯å¿
ããã¹ããæžããŸããã:
+
+```python
+# tests/test_users.py
+from fastapi.testclient import TestClient
+from src.main import app
+
+client = TestClient(app)
+
+def test_create_user():
+ user_data = {
+ "email": "test@example.com",
+ "username": "testuser",
+ "password": "securepassword123"
+ }
+ response = client.post("/api/v1/users/", json=user_data)
+ assert response.status_code == 201
+ assert response.json()["email"] == user_data["email"]
+
+def test_get_user():
+ response = client.get("/api/v1/users/1")
+ assert response.status_code == 200
+```
+
+## ãã©ãã«ã·ã¥ãŒãã£ã³ã°
+
+### ã«ãŒãã衚瀺ãããªã
+
+API ããã¥ã¡ã³ãã«ã«ãŒãã衚瀺ãããªãå Žå:
+
+1. `src/api/api.py` ã® **ã«ãŒã¿ãŒç»é²ã確èª**
+2. ã«ãŒã远å åŸã« **ãµãŒããŒãåèµ·å**
+3. ã«ãŒããã¡ã€ã«ã« **ã€ã³ããŒããšã©ãŒããªãã確èª**
+
+### ã€ã³ããŒããšã©ãŒ
+
+ã€ã³ããŒããšã©ãŒãçºçããå Žå:
+
+1. **ãã¡ã€ã«æ§é ** ãæ³å®ã©ããã確èª
+2. ã«ãŒããš CRUD ãã¡ã€ã«ã® **ã¹ããŒãã€ã³ããŒã** ã確èª
+3. **ãã¹ãŠã® `__init__.py` ãã¡ã€ã«ãååšããã確èª**
+
+### ãµãŒããŒãèµ·åããªã
+
+ã«ãŒã远å åŸã«ãµãŒããŒãèµ·åããªãå Žå:
+
+1. çæãã¡ã€ã«ã« **æ§æãšã©ãŒããªãã確èª**
+2. ãã¡ã€ã«éã® **ã¹ããŒãäºææ§** ã確èª
+3. å
·äœçãªãšã©ãŒã¡ãã»ãŒãžã«ã€ã㊠**ãã°ã確èª**
+
+## 次ã®ã¹ããã
+
+ã«ãŒãã®è¿œå æ¹æ³ãçè§£ã§ããã:
+
+1. **[æåã®ãããžã§ã¯ã](../tutorial/first-project.md)**: å®å
šãªããã° API ãæ§ç¯
+2. **[CLI ãªãã¡ã¬ã³ã¹](cli-reference.md)**: å©çšå¯èœãªãã¹ãŠã®ã³ãã³ããåŠã¶
+3. **[ãã³ãã¬ãŒãã®å©çš](using-templates.md)**: äºåæ§ç¯æžã¿ã®ãããžã§ã¯ããã³ãã¬ãŒãã詊ã
+
+!!! tip "ã«ãŒãéçºã®ãã³ã"
+ - æ°ããã«ãŒãã¯åžžã«å¯Ÿè©±åããã¥ã¡ã³ã (`/docs`) ã§ãã¹ãããŸããã
+ - æå³ã®ãã HTTP ã¹ããŒã¿ã¹ã³ãŒãã䜿ããŸããã
+ - ãã¹ãŠã®ãšã³ããã€ã³ãã«é©åãªãšã©ãŒãã³ããªã³ã°ãå®è£
ããŸããã
+ - ã«ãŒããã³ãã©ã¯ã·ã³ãã«ã«ä¿ã¡ãããžãã¹ããžãã¯ã¯ CRUD ã¯ã©ã¹ãžå§è²ããŸããã
diff --git a/docs/ja/user-guide/choosing-a-starter.md b/docs/ja/user-guide/choosing-a-starter.md
new file mode 100644
index 0000000..aeb6475
--- /dev/null
+++ b/docs/ja/user-guide/choosing-a-starter.md
@@ -0,0 +1,145 @@
+# ã©ã®ã¹ã¿ãŒã¿ãŒãéžã¶ã¹ã?
+
+FastAPI-fastkit ã«ã¯ããããžã§ã¯ããå§ããããã®æ¹æ³ãããã€ãçšæãããŠããŸãããã®ããŒãžã¯åããŠã®æ¹ã®ããã® **éžã³æ¹ã¬ã€ã** ã§ããããã§æ¹åæ§ã決ããããã§ãå®éã®ãããžã§ã¯ãçæã¯ [ã¯ã€ãã¯ã¹ã¿ãŒã](quick-start.md) ã«é²ãã§ãã ããã
+
+è¿·ã£ãŠããå Žåã®çãã¯æ¬¡ã®ãšããã§ã:
+
+> **`fastkit init --interactive` ã§å§ãã`domain-starter` ããªã»ãããéžãã§ãã ããã** ããã¯çŸä»£ç㪠API ãããžã§ã¯ãã«å¯Ÿããæšå¥šããã©ã«ãã§ãã
+
+ãã®ããŒãžã®æ®ãã®éšåã§ã¯ããã®çç±ãšãå¥ã®éžæãåãã¹ãå Žé¢ã説æããŸãã
+
+## TL;DR â ãŠãŒã¶ãŒã¿ã€ãå¥ã®éžã³æ¹
+
+| ããªãã... | åºçºç¹ |
+|---|---|
+| FastAPI ãåããŠã§ãã¬ã€ãä»ãã§é²ããã | `fastkit init --interactive` (preset: **`domain-starter`**) |
+| åäœãã CRUD ãã¢ãèªã¿ã»æžãæããªããåŠã³ãã | `fastkit startdemo fastapi-default` |
+| å¯èœãªéãå°ããã¹ãã£ãã©ãŒã«ããæ¬²ãã | `fastkit init --interactive` (preset: **`minimal`**) |
+| ç°¡åãªãããã¿ã€ã / åäžãã¡ã€ã«ã®ã¹ã¯ãªãããæžã | `fastkit init --interactive` (preset: **`single-module`**) |
+| å®éã®ããŒã¿ããŒã¹ãå¿
èŠ (PostgreSQL + SQLAlchemy + Alembic) | `fastkit startdemo fastapi-psql-orm` |
+| äžèŠæš¡ API ã®ããã®æ¬çªå¿åã®ãã¡ã€ã³ã¬ã€ã¢ãŠããæ¬²ãã | `fastkit init --interactive` (preset: **`domain-starter`**) |
+
+## `startdemo` ãš `init --interactive` ã®éãã¯?
+
+ãããã 2 ã€ã®äž»ãªãšã³ããªãã€ã³ãã§ãããããç°ãªãçšéãæã¡ãŸãã
+
+### `fastkit startdemo `
+
+忢±ãã³ãã¬ãŒã (`fastapi-default`ã`fastapi-async-crud`ã`fastapi-psql-orm`ã`fastapi-domain-starter`ã...) ã®ãããããããšã«ã**宿æžã¿ã§åäœããäŸé¡ãããžã§ã¯ã** ããã£ã¹ã¯ã«å±éããŸãããã³ãã¬ãŒãã®ãœãŒã¹ã³ãŒãã¯ã»ãŒãã®ãŸãŸã³ããŒãããã¡ã¿ããŒã¿ã®ãã¬ãŒã¹ãã«ã (`` ãªã©) ã®ã¿ãåã蟌ãŸããŸãã
+
+- â
åäœãããã¢ãŸã§ã®æçã«ãŒãã
+- â
ã³ãŒãã¯ãã¹ãŠå®éã«åããèªã¿ããã â äŸé¡ã«ããåŠç¿ã«æé©ã
+- â ãã³ãã¬ãŒãã®ã¹ã¿ãã¯ãšæ§é ã¯åºå®ãããŠãããçææã«ãCORS ã ãå
¥ããŠèªèšŒã¯å€ãããšãã£ãçµã¿åããã¯ã§ããŸããã
+
+```console
+$ fastkit list-templates # å©çšå¯èœãªãã³ãã¬ãŒãäžèЧã衚瀺
+$ fastkit startdemo fastapi-default # ãã®äžã® 1 ã€ã§ãããžã§ã¯ããçæ
+```
+
+### `fastkit init --interactive`
+
+**察話åãŠã£ã¶ãŒã** ã«æ²¿ã£ãŠé²ããŸã: ãããžã§ã¯ãã¡ã¿ããŒã¿ â ã¢ãŒããã¯ãã£ããªã»ãã â æ©èœéžæ (ããŒã¿ããŒã¹ãèªèšŒããã¹ãããããã€ã...) â ããã±ãŒãžãããŒãžã£ãŒ â 確èªããšããæµãã§ãããžã§ãã¬ãŒã¿ãŒã¯ããªã»ããããšã«é©åãªããŒã¹ãã³ãã¬ãŒããéžã³ããã®äžã«éžæããæ©èœãéããŠãããŸãã
+
+- â
èªåãæ¬åœã«æ¬²ããã¹ã¿ãã¯ãçµã¿ç«ãŠãããã
+- â
ã¢ãŒããã¯ãã£ããªã»ããããããžã§ã¯ãã¬ã€ã¢ãŠã (åäžãã¡ã€ã«ãã¬ã€ã€ãŒåããã¡ã€ã³æåã...) ãæ±ºå®ã
+- â `main.py` ããã®ãŸãŸäœ¿ãæ§æã®å
å®ããããªã»ãã (`classic-layered`ã`domain-starter`) ã§ã¯ãèšå®ã¢ãžã¥ãŒã«ã¯çæãããŸãããããã忢±ã®ã«ãŒã¿ãŒã«çµã¿èŸŒãé
ç·ã¯ãŠãŒã¶ãŒèªèº«ãè¡ãåæã§ããããªã»ãã / æ©èœããšã®ä»æ§ã¯ [ã¢ãŒããã¯ãã£ããªã»ãããããªã¯ã¹](../reference/preset-feature-matrix.md) ãåç
§ããŠãã ããã
+
+```console
+$ fastkit init --interactive
+```
+
+## 4 çš®é¡ã®ã¢ãŒããã¯ãã£ããªã»ãã
+
+ããã㯠`fastkit init --interactive` ã®ãããžã§ã¯ãæ
å ±å
¥ååŸã«è¡šç€ºãããŸããã©ã®ããªã»ãããéžã¶ã決ããéã«ãã®ã»ã¯ã·ã§ã³ã䜿ã£ãŠãã ããã
+
+### `minimal` â æå°ããå§ããåŸã§è²ãŠã
+
+æå°æ§æã®åäœå¯èœãª FastAPI ã¢ããªã空ã®ã¹ãã£ãã©ãŒã«ã + æ©èœãã©ã°ããåçæãããåäžã® `src/main.py` ã§ããCORSãã¬ãŒãå¶éãPrometheus èšè£
ã¯ãéžææã«èªåã§ `main.py` ã«é
ç·ãããŸãã
+
+- ð€ **察象**: ãããžã§ã¯ããæé·ããã«ã€ããŠèªåã§æ§é ãçµã¿ç«ãŠãã人ããç¹å®ã®ã¬ã€ã¢ãŠãã«çžããã FastAPI ã詊ããã人ã
+- ðŠ **ããŒã¹ãã³ãã¬ãŒã**: `fastapi-empty`ã
+- ð§ **ã¡ã³ã¿ã«ã¢ãã«**: ãFastAPI ã import ãã 1 ãã¡ã€ã«ã ãçšæããŠãããã°ãæ®ãã¯èªåã§ãããã
+
+### `single-module` â ã¹ã¯ãªããåãããã¿ã€ã
+
+ãã¹ãŠã®ã³ãŒãã 1 ã¢ãžã¥ãŒã«ã®äžã«ãããŸãã`minimal` ãšåã `main.py` åçæãªãŒããŒã¬ã€ã䜿ããŸãã
+
+- ð€ **察象**: ã°ã«ãŒã¹ã¯ãªãããå°ã㪠webhookããããã¯ããã±ãŒãžå¢çãäžèŠãª 1 æ¥ã§ã§ãããããã¿ã€ãã
+- ðŠ **ããŒã¹ãã³ãã¬ãŒã**: `fastapi-single-module`ã
+- ð§ **ã¡ã³ã¿ã«ã¢ãã«**: ãå®è¡ãéèªãã²ãšæ¯ã§ã§ãã Python ãã¡ã€ã« 1 ã€ããã°ååãã
+
+### `classic-layered` â ã¬ã€ã€ãŒååå² (api / crud / schemas / core)
+
+ãDjango 颚ãã¬ã€ã¢ãŠã â ã³ãŒããé¢å¿äºããšã«æ°Žå¹³åå²ããŸã: ã«ãŒã¿ãŒã¯ãã¹ãŠ `api/` ã«ãCRUD ããžãã¯ã¯ãã¹ãŠ `crud/` ã«ãpydantic ã¹ããŒãã¯ãã¹ãŠ `schemas/` ã«ãèšå®ã¯ãã¹ãŠ `core/` ã«ãŸãšããŸãã忢±ã® `main.py` 㯠**ä¿å** ãããŠãã (CORS ã®é
ç·æžã¿)ãçæãããããŒã¿ããŒã¹ / èªèšŒèšå®ã¯ `src/core/` é
äžã«é
眮ãããŸãã
+
+- ð€ **察象**: Django / Rails 颚ã¬ã€ã¢ãŠãã«æ
£ããããŒã ãå
±éã® CRUD é
管ãå
±æããå°ããªãšã³ããã€ã³ããå€ããããžã§ã¯ãã
+- ðŠ **ããŒã¹ãã³ãã¬ãŒã**: `fastapi-default`ã
+- ð§ **ã¡ã³ã¿ã«ã¢ãã«**: ãã³ãŒãã *äœã§ããã* ã§åãããã
+
+### `domain-starter` â ãã¡ã€ã³æå (æšå¥šããã©ã«ã)
+
+ã³ãŒãã **ããžãã¹æŠå¿µããš** ã«åçŽåå²ããŸã: åãã¡ã€ã³ãèªèº«ã®ã«ãŒã¿ãŒããµãŒãã¹ããªããžããªãã¹ããŒãã `src/app/domains//` é
äžã«æã¡ãŸãã`/health` ãšã³ããã€ã³ããšãæ°ããæŠå¿µããšã«ã³ããŒããŠãªããŒã ããé圢ãšãªã `items` ãã¡ã€ã³ã®äŸã忢±ãããŠããŸãã忢±ã® `main.py` (`src/app/` é
äž) ã¯ä¿åãããçæãããèšå®ã¯ `src/app/core/` é
äžã«é
眮ãããŸãã
+
+- ð€ **察象**: è€æ°ã®ç°ãªãããžãã¹æŠå¿µ (usersãordersãbillingã...) ã«æé·ããŠããäžèŠæš¡ APIãæšå¥šãããçŸä»£çãªããã©ã«ãã§ãã
+- ðŠ **ããŒã¹ãã³ãã¬ãŒã**: `fastapi-domain-starter`ã
+- ð§ **ã¡ã³ã¿ã«ã¢ãã«**: ãã³ãŒãã *ããžãã¹ã«ãšã£ãŠäœãããã* ã§åãããã
+
+## æ¯èŒãããªã¯ã¹
+
+暪䞊ã³ã§äžç®ã§æ¯ã¹ãããããã«ãããã®ã§ãã
+
+| | `minimal` | `single-module` | `classic-layered` | `domain-starter` |
+|---|---|---|---|---|
+| ããŒã¹ãã³ãã¬ãŒã | `fastapi-empty` | `fastapi-single-module` | `fastapi-default` | `fastapi-domain-starter` |
+| ãããžã§ã¯ãå
¥å£ | `src/main.py` | `src/main.py` | `src/main.py` | `src/app/main.py` |
+| ã«ãŒã¿ãŒé
眮 | (èªåã§è¿œå ) | (`main.py` ã®äž) | `src/api/routes/` | `src/app/domains//router.py` |
+| ãã¡ã€ã³å¥ãã©ã«ã | â | â | â | â
|
+| `/health` ãšã³ããã€ã³ãæšæºæèŒ | â
| â
| â | â
|
+| `main.py` ãæ©èœããåçæ | â
| â
| â | â |
+| `main.py` ã« CORS äºåé
ç· | éžææã«è¿œå | éžææã«è¿œå | ãã (ç°å¢å€æ°é§å) | ãã (ç°å¢å€æ°é§å) |
+| pyproject ãã¡ãŒã¹ã | ä»»æ | ä»»æ | ä»»æ | â
|
+| é©ããçšé | ãèªåã§æ§é ãè²ãŠããã | ã1 ãã¡ã€ã«ã®ãããã¿ã€ãã | ãé¢å¿äºã§åããã | ãããžãã¹æŠå¿µã§åããã |
+
+æ©èœããšã®å®å
šãªå¥çŽ (ããŒã¿ããŒã¹ / èªèšŒã®èšå®ãé
眮ããããã¹ãèªåé
ç·ãããªãéžæãèŠåãåºãæ¡ä»¶) 㯠[ã¢ãŒããã¯ãã£ããªã»ãããããªã¯ã¹](../reference/preset-feature-matrix.md) ãåç
§ããŠãã ããã
+
+## `startdemo` ãã³ãã¬ãŒãã®éžã³æ¹
+
+`fastkit startdemo ` ã¯ãã¬ã€ãä»ãã§çµã¿ç«ãŠãããã **宿æžã¿ã§å®è¡å¯èœãªäŸé¡** ãæ¬²ãããšãã«æé©ã§ããã»ãšãã©ã®ãã³ãã¬ãŒãã¯åè¿°ã® 4 ã€ã®ããªã»ããã®ããããã«ãããã察å¿ããŠããŸããã远å ã®ãµã³ãã«ã³ãŒã (ã¢ãã¯ã¹ãã¢äžã® CRUD ãšã³ããã€ã³ããã«ã¹ã¿ã ã¬ã¹ãã³ã¹åŠçãDocker ããŒã«ãªã©) ã忢±ããŠããŸãã
+
+| ãã³ãã¬ãŒã | æãè¿ãããªã»ãã | éžã¶å Žé¢ |
+|---|---|---|
+| `fastapi-default` | `classic-layered` | ã¬ã€ã€ãŒåã¬ã€ã¢ãŠãã§åã CRUD ãã¢ãæåã®åºçºç¹ãšããŠæå
ãã |
+| `fastapi-empty` | `minimal` | çŽ ã®ã¹ãã£ãã©ãŒã«ãã`minimal` ãšåã圢ã«ãªããŸãã |
+| `fastapi-single-module` | `single-module` | åäžãã¡ã€ã«ã®ãã¢ã |
+| `fastapi-domain-starter` | `domain-starter` | æšå¥šãããçŸä»£çããã©ã«ããitems ãã¡ã€ã³ã®äŸã忢±ã |
+| `fastapi-async-crud` | `classic-layered` | `fastapi-default` ã®éåæçã |
+| `fastapi-custom-response` | `classic-layered` | ã«ã¹ã¿ã ã¬ã¹ãã³ã¹ãšã³ãããŒã / ãã©ãŒãããã®ãã¢ã |
+| `fastapi-dockerized` | `classic-layered` | ããã©ã«ãã¬ã€ã¢ãŠãã«æ¬çªçšã® Dockerfile ã远å ã |
+| `fastapi-psql-orm` | (çŽæ¥å¯Ÿå¿ããããªã»ãããªã) | PostgreSQL + SQLAlchemy + Alembicãå®éã®ããŒã¿ããŒã¹ãå¿
èŠãªãšãã«éžæã |
+| `fastapi-mcp` | (çŽæ¥å¯Ÿå¿ããããªã»ãããªã) | Model Context Protocol 飿ºã |
+
+`fastkit list-templates` ã§ 1 è¡èª¬æä»ãã®ææ°ãªã¹ãã確èªã§ããŸãã
+
+## ãããã質å
+
+**Q. ããªã»ãã / ãã³ãã¬ãŒãã¯æåã«æ±ºããªããšãããªã?**
+ããã â åŸããæåã§çææžã¿ã³ãŒããåæ§æããããšã¯ãã€ã§ãã§ããŸããããªã»ããã¯ãããŸã§åºçºç¹ã§ããå¥çŽã§ã¯ãããŸãããéžæãèãéããªãã§ãã ããã
+
+**Q. ãçŸä»£çããªéžæè¢ã¯ã©ã?**
+`domain-starter` ã§ããpyproject ãã¡ãŒã¹ãã§ã`/health` ãšã³ããã€ã³ããä»å±ããããéå¶ãããŠããäžèŠæš¡ FastAPI ãããžã§ã¯ããåæããŠããã¬ã€ã¢ãŠããæ¡çšããŠããŸãã
+
+**Q. åŸãã `classic-layered` ãã `domain-starter` ã«åãæ¿ãã§ãã?**
+ã§ããŸããæåã®ãªãã¡ã¯ã¿ãªã³ã°ã§ã â ãã€ã°ã¬ãŒã·ã§ã³ã³ãã³ãã¯ãããŸããããããžã§ã¯ãããã¡ã€ã³ãã©ã«ããå¿
èŠãšããã»ã©æé·ãããšæããªããæåãããããéžãã§ãã ããã
+
+**Q. ãšã«ãã FastAPI ãåŠã³ããã ãã**
+ãŸã `fastkit startdemo fastapi-default` ããå§ããŠãã ãã â ã³ãŒããèªã¿ããã¹ããå®è¡ããããã€ãã®ãšã³ããã€ã³ããæžãæããŠã¿ãŸããããæ
£ããŠãããã`fastkit init --interactive` ã§ `domain-starter` ããªã»ãããéžã¶ã®ãèªç¶ãªæ¬¡ã®äžæ©ã§ãã
+
+**Q. åããªã»ãããçæããæ£ç¢ºãªãã¡ã€ã«äžèЧã¯ã©ãã§èŠããã?**
+[ã¢ãŒããã¯ãã£ããªã»ãããããªã¯ã¹](../reference/preset-feature-matrix.md) ããã®ãªãã¡ã¬ã³ã¹ããŒãžã§ãã
+
+## 次ã®ã¹ããã
+
+- [ã¯ã€ãã¯ã¹ã¿ãŒã](quick-start.md) â å®éã«æåã®ãããžã§ã¯ããäœæã
+- [ãããžã§ã¯ãã®äœæ](creating-projects.md) â CLI ãã©ã°ã®ããèžã¿èŸŒãã ãŠã©ãŒã¯ã¹ã«ãŒã
+- [ãã¡ã€ã³æåãããžã§ã¯ãã®ãã¥ãŒããªã¢ã«](../tutorial/domain-starter.md) â `domain-starter` ãéžãã å Žåã®ãçæããªãŒã忢±ã® `items` äŸã次ã®ãã¡ã€ã³ã®è¿œå æ¹æ³ãŸã§ãéãããšã³ãããŒãšã³ãã®è§£èª¬ã
+- [ã¢ãŒããã¯ãã£ããªã»ãããããªã¯ã¹](../reference/preset-feature-matrix.md) â ããªã»ãã / æ©èœããšã®å®å
šãªå¥çŽã
diff --git a/docs/ja/user-guide/cli-reference.md b/docs/ja/user-guide/cli-reference.md
new file mode 100644
index 0000000..1235793
--- /dev/null
+++ b/docs/ja/user-guide/cli-reference.md
@@ -0,0 +1,832 @@
+# CLI ãªãã¡ã¬ã³ã¹
+
+FastAPI-fastkit ã®å
š CLI ã³ãã³ããç¶²çŸ
ãããªãã¡ã¬ã³ã¹ã§ãã
+
+## ã°ããŒãã«ãªãã·ã§ã³
+
+ãã¹ãŠã®ã³ãã³ãã¯æ¬¡ã®ã°ããŒãã«ãªãã·ã§ã³ããµããŒãããŠããŸã:
+
+```console
+$ fastkit [GLOBAL_OPTIONS] COMMAND [COMMAND_OPTIONS]
+```
+
+### ã°ããŒãã«ãªãã·ã§ã³
+
+| ãªãã·ã§ã³ | 説æ |
+|---|---|
+| `--version` | FastAPI-fastkit ã®ããŒãžã§ã³ã衚瀺 |
+| `--help` | ãã«ãã¡ãã»ãŒãžã衚瀺 |
+
+### äŸ
+
+
+
+```console
+$ fastkit --version
+FastAPI-fastkit version 1.0.0
+
+$ fastkit --help
+Usage: fastkit [OPTIONS] COMMAND [ARGS]...
+
+ FastAPI-fastkit CLI
+
+Options:
+ --version Show the version and exit.
+ --help Show this message and exit.
+
+Commands:
+ addroute Add a new route to FastAPI project
+ init Create a new FastAPI project
+ list-templates List available FastAPI templates
+ runserver Start FastAPI development server
+ startdemo Create FastAPI project from template
+```
+
+
+
+## ã³ãã³ã
+
+### `init`
+
+察話åã»ããã¢ããã§æ°ãã FastAPI ãããžã§ã¯ããäœæããŸãã
+
+#### æ§æ
+
+```console
+$ fastkit init [OPTIONS]
+```
+
+#### ãªãã·ã§ã³
+
+| ãªãã·ã§ã³ | 説æ | ããã©ã«ã |
+|---|---|---|
+| `--package-manager` | 䜿çšããããã±ãŒãžãããŒãžã£ãŒ (pip, uv, pdm, poetry) | uv |
+| `--help` | ã³ãã³ãã®ãã«ãã衚瀺 | - |
+
+#### 察話åããã³ãã
+
+`init` ã³ãã³ãã¯ä»¥äžãå°ããŸã:
+
+1. **ãããžã§ã¯ãå**: ãã£ã¬ã¯ããªåããã³ããã±ãŒãžå
+2. **äœè
å**: ããã±ãŒãžã®äœè
æ
å ±
+3. **äœè
ã¡ãŒã«**: ããã±ãŒãžã®é£çµ¡å
ã¡ãŒã«
+4. **ãããžã§ã¯ã説æ**: ãããžã§ã¯ãã®æŠèŠ
+5. **ã¹ã¿ãã¯éžæ**: minimalãstandardãfull ããéžæ
+6. **ããã±ãŒãžãããŒãžã£ãŒéžæ**: pipãuvãpdmãpoetry ããéžæ (`--package-manager` ã§æå®ããªãå Žå)
+
+#### ã¹ã¿ãã¯ãªãã·ã§ã³
+
+**MINIMAL ã¹ã¿ãã¯:**
+
+- `fastapi` - FastAPI ãã¬ãŒã ã¯ãŒã¯
+- `uvicorn` - ASGI ãµãŒããŒ
+- `pydantic` - ããŒã¿æ€èšŒ
+- `pydantic-settings` - èšå®ç®¡ç
+
+**STANDARD ã¹ã¿ãã¯:**
+
+- MINIMAL ã¹ã¿ãã¯ã®ãã¹ãŠã®ããã±ãŒãž
+- `sqlalchemy` - SQL ããŒã«ãããããã³ ORM
+- `alembic` - ããŒã¿ããŒã¹ãã€ã°ã¬ãŒã·ã§ã³ããŒã«
+- `pytest` - ãã¹ããã¬ãŒã ã¯ãŒã¯
+
+**FULL ã¹ã¿ãã¯:**
+
+- STANDARD ã¹ã¿ãã¯ã®ãã¹ãŠã®ããã±ãŒãž
+- `redis` - ã€ã³ã¡ã¢ãªããŒã¿ã¹ãã¢
+- `celery` - 忣ã¿ã¹ã¯ãã¥ãŒ
+
+#### äŸ
+
+
+
+```console
+$ fastkit init
+Enter the project name: my-api
+Enter the author name: John Doe
+Enter the author email: john@example.com
+Enter the project description: My awesome API
+
+Select stack (minimal, standard, full): standard
+Select package manager (pip, uv, pdm, poetry) [uv]: uv
+Do you want to proceed with project creation? [y/N]: y
+
+âš FastAPI project 'my-api' has been created successfully!
+```
+
+
+
+#### çæãããæ§é
+
+æ¬¡ã®æ§é ã®ãããžã§ã¯ããäœæãããŸã:
+
+```
+my-api/
+âââ .venv/ # ä»®æ³ç°å¢
+âââ src/
+â âââ __init__.py
+â âââ main.py # FastAPI ã¢ããªã±ãŒã·ã§ã³
+â âââ core/
+â â âââ __init__.py
+â â âââ config.py # èšå®
+â âââ api/
+â â âââ __init__.py
+â â âââ api.py # API ã«ãŒã¿ãŒéçŽ
+â â âââ routes/
+â â âââ __init__.py
+â â âââ items.py # ãµã³ãã«ã«ãŒã
+â âââ crud/
+â â âââ __init__.py
+â â âââ items.py # CRUD æäœ
+â âââ schemas/
+â â âââ __init__.py
+â â âââ items.py # Pydantic ã¹ããŒã
+â âââ mocks/
+â âââ __init__.py
+â âââ mock_items.json # ãã¹ãããŒã¿
+âââ tests/
+âââ scripts/
+âââ requirements.txt
+âââ setup.py
+âââ README.md
+```
+
+### `addroute`
+
+æ¢åã® FastAPI ãããžã§ã¯ãã«æ°ãã API ã«ãŒãã远å ããŸãã
+
+#### æ§æ
+
+```console
+$ fastkit addroute ROUTE_NAME [PROJECT_DIR] [OPTIONS]
+```
+
+#### åŒæ°
+
+| åŒæ° | 説æ | å¿
é |
+|---|---|---|
+| `ROUTE_NAME` | æ°ããã«ãŒãå (è€æ°åœ¢ãæšå¥š) | ã¯ã |
+| `PROJECT_DIR` | 察象ã®ãããžã§ã¯ããã£ã¬ã¯ã㪠(ããã©ã«ã㯠`.` (çŸåšã®ãã£ã¬ã¯ããª)) | ããã |
+
+#### ãªãã·ã§ã³
+
+| ãªãã·ã§ã³ | 説æ | ããã©ã«ã |
+|---|---|---|
+| `--help` | ã³ãã³ãã®ãã«ãã衚瀺 | - |
+
+#### äŸ
+
+
+
+```console
+$ cd my-api
+$ fastkit addroute users
+ Adding New Route
+ââââââââââââââââââââ¬âââââââââââââââââââââââââââââââââââââââââââ
+â Project â my-api â
+â Route Name â users â
+â Target Directory â ~/my-api â
+ââââââââââââââââââââŽâââââââââââââââââââââââââââââââââââââââââââ
+
+Do you want to add route 'users' to project 'my-api'? [Y/n]: y
+
+âš Successfully added new route 'users' to project 'my-api'
+```
+
+
+
+`cd` ããªããŠãã察象ã®ãããžã§ã¯ããååã§æå®ã§ããŸã:
+
+
+
+```console
+$ fastkit addroute users my-api
+```
+
+
+
+#### çæããããã¡ã€ã«
+
+ãããžã§ã¯ãã«æ¬¡ã®ãã¡ã€ã«ãäœæãããŸã:
+
+- `src/api/routes/users.py` - ã«ãŒããã³ãã©
+- `src/crud/users.py` - CRUD æäœ
+- `src/schemas/users.py` - Pydantic ã¹ããŒã
+
+ãŸããæ°ããã«ãŒã¿ãŒãåã蟌ããã `src/api/api.py` ãèªåæŽæ°ãããŸãã
+
+#### çæããããšã³ããã€ã³ã
+
+å®å
šãª CRUD ãšã³ããã€ã³ããäœæãããŸã:
+
+| ã¡ãœãã | ãšã³ããã€ã³ã | 説æ |
+|---|---|---|
+| `GET` | `/api/v1/users/` | ãã¹ãŠã®ãŠãŒã¶ãŒãååŸ |
+| `POST` | `/api/v1/users/` | æ°ãããŠãŒã¶ãŒãäœæ |
+| `GET` | `/api/v1/users/{user_id}` | ç¹å®ã®ãŠãŒã¶ãŒãååŸ |
+| `PUT` | `/api/v1/users/{user_id}` | ãŠãŒã¶ãŒãæŽæ° |
+| `DELETE` | `/api/v1/users/{user_id}` | ãŠãŒã¶ãŒãåé€ |
+
+### `startdemo`
+
+ãããããçšæããããã³ãã¬ãŒããã FastAPI ãããžã§ã¯ããäœæããŸãã
+
+#### æ§æ
+
+```console
+$ fastkit startdemo [OPTIONS]
+```
+
+#### ãªãã·ã§ã³
+
+| ãªãã·ã§ã³ | 説æ | ããã©ã«ã |
+|---|---|---|
+| `--package-manager` | 䜿çšããããã±ãŒãžãããŒãžã£ãŒ (pip, uv, pdm, poetry) | uv |
+| `--help` | ã³ãã³ãã®ãã«ãã衚瀺 | - |
+
+#### 察話åããã³ãã
+
+`startdemo` ã³ãã³ãã¯ä»¥äžãå°ããŸã:
+
+1. **ãããžã§ã¯ãå**: æ°ãããããžã§ã¯ãã®ãã£ã¬ã¯ããªå
+2. **äœè
å**: ããã±ãŒãžã®äœè
æ
å ±
+3. **äœè
ã¡ãŒã«**: é£çµ¡å
ã¡ãŒã«
+4. **ãããžã§ã¯ã説æ**: ãããžã§ã¯ãã®æŠèŠ
+5. **ããã±ãŒãžãããŒãžã£ãŒéžæ**: pipãuvãpdmãpoetry ããéžæ (`--package-manager` ã§æå®ããªãå Žå)
+
+#### å©çšå¯èœãªãã³ãã¬ãŒã
+
+| ãã³ãã¬ãŒã | 説æ | æ©èœ |
+|---|---|---|
+| `fastapi-default` | ã·ã³ãã«ãª FastAPI ãããžã§ã¯ã | åºæ¬ç㪠CRUDãã¢ãã¯ããŒã¿ |
+| `fastapi-async-crud` | éåæã¢ã€ãã 管ç API | async/awaitãããã©ãŒãã³ã¹éèŠ |
+| `fastapi-custom-response` | ã«ã¹ã¿ã ã¬ã¹ãã³ã¹æ©æ§ | ã«ã¹ã¿ã ã¬ã¹ãã³ã¹ãããŒãžããŒã·ã§ã³ |
+| `fastapi-dockerized` | Docker åããã FastAPI API | Dockerãæ¬çªéçšå¯Ÿå¿ |
+| `fastapi-psql-orm` | PostgreSQL 飿º FastAPI API | PostgreSQLãSQLAlchemyãAlembic |
+| `fastapi-empty` | æå°æ§æ FastAPI ãããžã§ã¯ã | å¿
èŠæäœéã®ã»ããã¢ãã |
+
+#### äŸ
+
+
+
+```console
+$ fastkit startdemo fastapi-psql-orm
+Enter the project name: my-blog
+Enter the author name: Jane Smith
+Enter the author email: jane@example.com
+Enter the project description: Blog API with PostgreSQL
+
+Select package manager (pip, uv, pdm, poetry) [uv]: poetry
+Do you want to proceed with project creation? [y/N]: y
+
+âš FastAPI project 'my-blog' from 'fastapi-psql-orm' has been created!
+```
+
+
+
+### `runserver`
+
+FastAPI éçºãµãŒããŒãèµ·åããŸãã
+
+#### æ§æ
+
+```console
+$ fastkit runserver [OPTIONS]
+```
+
+#### ãªãã·ã§ã³
+
+| ãªãã·ã§ã³ | ç瞮圢 | 説æ | ããã©ã«ã |
+|---|---|---|---|
+| `--host` | `-h` | ãã€ã³ããããã¹ã | `127.0.0.1` |
+| `--port` | `-p` | ãã€ã³ãããããŒã | `8000` |
+| `--reload` | `-r` | èªåãªããŒããæå¹å | `True` |
+| `--workers` | `-w` | ã¯ãŒã«ãŒæ° | `1` |
+| `--help` | | ã³ãã³ãã®ãã«ãã衚瀺 | - |
+
+#### äŸ
+
+
+
+```console
+# åºæ¬çãªäœ¿ãæ¹ (ããã©ã«ãèšå®)
+$ fastkit runserver
+INFO: Uvicorn running on http://127.0.0.1:8000
+
+# ãã¹ããšããŒãã®ã«ã¹ã¿ãã€ãº
+$ fastkit runserver --host 0.0.0.0 --port 8080
+INFO: Uvicorn running on http://0.0.0.0:8080
+
+# èªåãªããŒããç¡å¹å
+$ fastkit runserver --no-reload
+INFO: Uvicorn running on http://127.0.0.1:8000
+
+# è€æ°ã¯ãŒã«ãŒ (æ¬çªéçš)
+$ fastkit runserver --workers 4
+INFO: Uvicorn running on http://127.0.0.1:8000
+```
+
+
+
+#### åäœèŠä»¶
+
+- FastAPI ãããžã§ã¯ãã®ãã£ã¬ã¯ããªã§å®è¡ããå¿
èŠããã
+- ãããžã§ã¯ãã« FastAPI ã¢ããªãå«ã `src/main.py` ãååšããå¿
èŠããã
+- ä»®æ³ç°å¢ãæå¹åããŠããããš
+
+### `list-templates`
+
+å©çšå¯èœãªãã¹ãŠã® FastAPI ãããžã§ã¯ããã³ãã¬ãŒããäžèŠ§è¡šç€ºããŸãã
+
+#### æ§æ
+
+```console
+$ fastkit list-templates [OPTIONS]
+```
+
+#### ãªãã·ã§ã³
+
+| ãªãã·ã§ã³ | 説æ | ããã©ã«ã |
+|---|---|---|
+| `--help` | ã³ãã³ãã®ãã«ãã衚瀺 | - |
+
+#### äŸ
+
+
+
+```console
+$ fastkit list-templates
+ Available Templates
+âââââââââââââââââââââââââââ¬ââââââââââââââââââââââââââââââââââââ
+â fastapi-custom-response â Async Item Management API with â
+â â Custom Response System â
+â fastapi-dockerized â Dockerized FastAPI Item â
+â â Management API â
+â fastapi-empty â No description â
+â fastapi-async-crud â Async Item Management API Server â
+â fastapi-psql-orm â Dockerized FastAPI Item â
+â â Management API with PostgreSQL â
+â fastapi-default â Simple FastAPI Project â
+âââââââââââââââââââââââââââŽââââââââââââââââââââââââââââââââââââ
+```
+
+
+
+## ç°å¢å€æ°
+
+FastAPI-fastkit ã¯æ¬¡ã®ç°å¢å€æ°ãå°éããŸã:
+
+| 倿° | 説æ | ããã©ã«ã |
+|---|---|---|
+| `FASTKIT_CONFIG_DIR` | èšå®ãã£ã¬ã¯ã㪠| `~/.fastkit` |
+| `FASTKIT_TEMPLATES_DIR` | ã«ã¹ã¿ã ãã³ãã¬ãŒãã®ãã£ã¬ã¯ã㪠| çµã¿èŸŒã¿ãã³ãã¬ãŒã |
+| `FASTKIT_LOG_LEVEL` | ãã®ã³ã°ã¬ãã« | `INFO` |
+
+### äŸ
+
+
+
+```console
+# èšå®ãã£ã¬ã¯ããªã®ã«ã¹ã¿ãã€ãº
+$ export FASTKIT_CONFIG_DIR=~/my-fastkit-config
+$ fastkit init
+
+# ã«ã¹ã¿ã ãã³ãã¬ãŒããã£ã¬ã¯ããª
+$ export FASTKIT_TEMPLATES_DIR=~/my-templates
+$ fastkit list-templates
+
+# ãããã°ãã°
+$ export FASTKIT_LOG_LEVEL=DEBUG
+$ fastkit init
+```
+
+
+
+## èšå®ãã¡ã€ã«
+
+FastAPI-fastkit ã¯ããã©ã«ãèšå®ãšããŠèšå®ãã¡ã€ã«ãå©çšã§ããŸãã
+
+### èšå®ãã¡ã€ã«ã®å Žæ
+
+1. `$FASTKIT_CONFIG_DIR/config.yaml` (`FASTKIT_CONFIG_DIR` ãèšå®ãããŠããå Žå)
+2. `~/.fastkit/config.yaml` (ããã©ã«ã)
+3. `./fastkit.yaml` (ãããžã§ã¯ãåºæ)
+
+### èšå®ãã¡ã€ã«åœ¢åŒ
+
+```yaml
+# ~/.fastkit/config.yaml
+default:
+ author:
+ name: "Your Name"
+ email: "your.email@example.com"
+
+ project:
+ stack: "standard"
+ create_venv: true
+ install_deps: true
+
+ server:
+ host: "127.0.0.1"
+ port: 8000
+ reload: true
+
+templates:
+ custom_dir: "~/my-templates"
+
+logging:
+ level: "INFO"
+ file: "~/.fastkit/logs/fastkit.log"
+```
+
+## ããããã¯ãŒã¯ãããŒ
+
+### 1. æ°ãããããžã§ã¯ããäœæãã
+
+
+
+```console
+# æ°ãããããžã§ã¯ããäœæ
+$ fastkit init
+# ããã³ããã«åŸã ...
+
+# ãããžã§ã¯ãã«ç§»å
+$ cd my-awesome-api
+
+# ä»®æ³ç°å¢ãæå¹å
+$ source .venv/bin/activate
+
+# éçºãµãŒããŒãèµ·å
+$ fastkit runserver
+```
+
+
+
+### 2. æ¢åãããžã§ã¯ãã«æ©èœã远å ãã
+
+
+
+```console
+# è€æ°ã®ã«ãŒãã远å (2 çªç®ã®äœçœ®åŒæ° = 察象ã®ãããžã§ã¯ããã£ã¬ã¯ããª)
+$ fastkit addroute users my-api
+$ fastkit addroute products my-api
+$ fastkit addroute orders my-api
+
+# API ããã¹ã
+$ fastkit runserver
+# http://127.0.0.1:8000/docs ãéã
+```
+
+
+
+### 3. è€éãªãããžã§ã¯ãã®ããã«ãã³ãã¬ãŒããå©çšãã
+
+
+
+```console
+# å©çšå¯èœãªãã³ãã¬ãŒãã衚瀺
+$ fastkit list-templates
+
+# ãã³ãã¬ãŒãããäœæ
+$ fastkit startdemo
+# ããŒã¿ããŒã¹ãããžã§ã¯ãã«ã¯ fastapi-psql-orm ãéžæ
+
+# ããŒã¿ããŒã¹ã®ã»ããã¢ãã (PostgreSQL ãã³ãã¬ãŒãã®å Žå)
+$ cd my-project
+$ docker-compose up -d postgres
+$ source .venv/bin/activate
+$ alembic upgrade head
+$ fastkit runserver
+```
+
+
+
+## ãã©ãã«ã·ã¥ãŒãã£ã³ã°
+
+### ã³ãã³ããèŠã€ãããªã
+
+`fastkit` ã³ãã³ããèŠã€ãããªãå Žå:
+
+1. **ã€ã³ã¹ããŒã«ã確èª:**
+
+ ```console
+ $ pip show fastapi-fastkit
+ ```
+
+
+2. **å¿
èŠã«å¿ããŠåã€ã³ã¹ããŒã«:**
+
+ ```console
+ $ pip uninstall fastapi-fastkit
+ $ pip install fastapi-fastkit
+ ```
+
+
+3. **PATH ã確èª:**
+
+ ```console
+ $ which fastkit
+ ```
+
+
+### ä»®æ³ç°å¢ã®åé¡
+
+ä»®æ³ç°å¢ã®äœæã«å€±æããå Žå:
+
+1. **Python ã®ããŒãžã§ã³ã確èª:**
+
+ ```console
+ $ python --version # 3.12+ ã§ããå¿
èŠããããŸã
+ ```
+
+
+2. **venv ã¢ãžã¥ãŒã«ã確èª:**
+
+ ```console
+ $ python -m venv --help
+ ```
+
+
+3. **æåã§ä»®æ³ç°å¢ãäœæ:**
+
+ ```console
+ $ python -m venv .venv
+ $ source .venv/bin/activate
+ $ pip install -r requirements.txt
+ ```
+
+
+### ãµãŒããŒãèµ·åããªã
+
+`fastkit runserver` ã«å€±æããå Žå:
+
+1. **ãããžã§ã¯ããã£ã¬ã¯ããªã«ããã確èª**
+2. **`src/main.py` ãååšããã確èª**
+3. **ä»®æ³ç°å¢ãæå¹å:**
+
+ ```console
+ $ source .venv/bin/activate
+ ```
+
+
+4. **æ§æãšã©ãŒã確èª:**
+
+ ```console
+ $ python -c "from src.main import app"
+ ```
+
+
+### ããŒããæ¢ã«äœ¿ãããŠãã
+
+ããŒã 8000 ãããžãŒç¶æ
ã®å Žå:
+
+
+
+```console
+# å¥ã®ããŒãã䜿ã
+$ fastkit runserver --port 8080
+
+# ãããã¯æ¢åããã»ã¹ãçµäº
+$ lsof -ti:8000 | xargs kill -9
+```
+
+
+
+## é«åºŠãªäœ¿ãæ¹
+
+### ã«ã¹ã¿ã ãã³ãã¬ãŒã
+
+æ¬¡ã®æé ã§ã«ã¹ã¿ã ãã³ãã¬ãŒããäœæã§ããŸã:
+
+1. **ãã³ãã¬ãŒããã£ã¬ã¯ããªãäœæ:**
+ ```
+ my-template/
+ âââ src/
+ â âââ main.py-tpl
+ âââ requirements.txt-tpl
+ âââ setup.py-tpl
+ ```
+
+2. **ç°å¢å€æ°ãèšå®:**
+
+ ```console
+ $ export FASTKIT_TEMPLATES_DIR=~/my-templates
+ ```
+
+
+3. **ã«ã¹ã¿ã ãã³ãã¬ãŒããå©çš:**
+
+ ```console
+ $ fastkit startdemo
+ # äžèЧã«ã«ã¹ã¿ã ãã³ãã¬ãŒãã衚瀺ãããŸã
+ ```
+
+
+### FastAPI-fastkit ãã¹ã¯ãªãããã䜿ã
+
+FastAPI-fastkit ã¯ã¹ã¯ãªããããå©çšã§ããŸã:
+
+```bash
+#!/bin/bash
+# create-microservices.sh
+
+for service in users products orders; do
+ echo "Creating $service service..."
+ fastkit init <
+
+```console
+$ fastkit init --package-manager uv
+# UV çšèšå®ã® pyproject.toml ãçæ
+```
+
+
+
+#### PDM
+- **ã¢ãã³**: PEP 582 / PEP 621 ããµããŒã
+- **é«åºŠ**: æŽç·ŽãããäŸåé¢ä¿è§£æ±º
+- **æè»**: è€æ°ã®ãããžã§ã¯ãã¬ã€ã¢ãŠãã«å¯Ÿå¿
+
+
+
+```console
+$ fastkit init --package-manager pdm
+# PDM çšèšå®ã® pyproject.toml ãçæ
+```
+
+
+
+#### Poetry
+- **å®çª**: æçããŠããåºãæ¡çš
+- **çµ±å**: ãã«ãã»å
¬éãŸã§ãµããŒã
+- **ããã¯ãã¡ã€ã«**: poetry.lock ã«ããåçŸå¯èœãªãã«ã
+
+
+
+```console
+$ fastkit init --package-manager poetry
+# Poetry çšèšå®ã® pyproject.toml ãçæ
+```
+
+
+
+#### PIP
+- **æšæº**: Python ã«æšæºã§å«ãŸãã
+- **äºææ§**: ããããç°å¢ã§åäœ
+- **ã·ã³ãã«**: çŽ çŽãªäŸåé¢ä¿ç®¡ç
+
+
+
+```console
+$ fastkit init --package-manager pip
+# requirements.txt ãçæ
+```
+
+
+
+### ãããžã§ã¯ãã§ã®äœæ¥
+
+ç¹å®ã®ããã±ãŒãžãããŒãžã£ãŒã§ãããžã§ã¯ããäœæããåŸã¯:
+
+#### UV ãããžã§ã¯ã
+```console
+cd my-project
+uv sync # äŸåé¢ä¿ãã€ã³ã¹ããŒã«
+uv add requests # æ°ããäŸåé¢ä¿ã远å
+uv run pytest # ç°å¢å
ã§ã³ãã³ããå®è¡
+```
+
+#### PDM ãããžã§ã¯ã
+```console
+cd my-project
+pdm install # äŸåé¢ä¿ãã€ã³ã¹ããŒã«
+pdm add requests # æ°ããäŸåé¢ä¿ã远å
+pdm run pytest # ç°å¢å
ã§ã³ãã³ããå®è¡
+```
+
+#### Poetry ãããžã§ã¯ã
+```console
+cd my-project
+poetry install # äŸåé¢ä¿ãã€ã³ã¹ããŒã«
+poetry add requests # æ°ããäŸåé¢ä¿ã远å
+poetry run pytest # ç°å¢å
ã§ã³ãã³ããå®è¡
+```
+
+#### PIP ãããžã§ã¯ã
+```console
+cd my-project
+source .venv/bin/activate # Linux/macOS
+.venv\Scripts\activate # Windows
+pip install -r requirements.txt
+pip install requests
+pytest
+```
+
+## 次ã®ã¹ããã
+
+CLI ãçè§£ã§ããã:
+
+1. **[ã¯ã€ãã¯ã¹ã¿ãŒã](quick-start.md)**: ã³ãã³ããå®éã«è©Šã
+2. **[æåã®ãããžã§ã¯ã](../tutorial/first-project.md)**: å®å
šãªã¢ããªã±ãŒã·ã§ã³ãæ§ç¯
+3. **[ã³ã³ããªãã¥ãŒã](../contributing/development-setup.md)**: FastAPI-fastkit ã«è²¢ç®ãã
+
+!!! tip "CLI ã®ãã³ã"
+ - 詳现ãªãã«ããåŸãã«ã¯åã³ãã³ãã« `--help` ãä»ããŸããã
+ - æ¢å®å€ãèšå®ãããšããããžã§ã¯ãäœæãé«éåã§ããŸã
+ - æ§æãè€éãªãããžã§ã¯ãã§ã¯ãã³ãã¬ãŒããæŽ»çšããŸããã
+ - ã³ãã³ããçµã¿åãããŠåŒ·åãªã¯ãŒã¯ãããŒãäœããŸããã
diff --git a/docs/ja/user-guide/creating-projects.md b/docs/ja/user-guide/creating-projects.md
new file mode 100644
index 0000000..1ba98eb
--- /dev/null
+++ b/docs/ja/user-guide/creating-projects.md
@@ -0,0 +1,540 @@
+# ãããžã§ã¯ãã®äœæ
+
+FastAPI-fastkit ã§ããŸããŸãªçš®é¡ã® FastAPI ãããžã§ã¯ããäœæãã詳现ã¬ã€ãã§ãã
+
+## åºæ¬ã®ãããžã§ã¯ãäœæ
+
+### 1. 察話åã¢ãŒãã§ã®ãããžã§ã¯ãäœæ
+
+æãåºæ¬çãªæ¹æ³ã¯ã察話åã§ãããžã§ã¯ããäœæããããšã§ã:
+
+
+
+```console
+$ fastkit init
+Enter the project name: my-awesome-api
+Enter the author name: John Doe
+Enter the author email: john@example.com
+Enter the project description: Awesome FastAPI project
+
+ Project Information
+ââââââââââââââââ¬ââââââââââââââââââââââââââ
+â Project Name â my-awesome-api â
+â Author â John Doe â
+â Author Email â john@example.com â
+â Description â Awesome FastAPI project â
+ââââââââââââââââŽââââââââââââââââââââââââââ
+```
+
+
+
+### 2. ã¹ã¿ãã¯ã®éžæ
+
+ãããžã§ã¯ãã«å«ããäŸåé¢ä¿ã¹ã¿ãã¯ãéžã³ãŸã:
+
+#### MINIMAL ã¹ã¿ã㯠(ããã©ã«ã)
+
+æãåºæ¬ç㪠FastAPI ãããžã§ã¯ãã§ã:
+
+- `fastapi` - FastAPI ãã¬ãŒã ã¯ãŒã¯
+- `uvicorn` - ASGI ãµãŒããŒ
+- `pydantic` - ããŒã¿æ€èšŒ
+- `pydantic-settings` - èšå®ç®¡ç
+
+**é©ããçšé:**
+
+- FastAPI ã®åŠç¿
+- ã·ã³ãã«ãª API
+- ãããã¿ã€ã
+- ãã€ã¯ããµãŒãã¹
+
+#### STANDARD ã¹ã¿ãã¯
+
+ããŒã¿ããŒã¹å¯Ÿå¿ãšãã¹ããå«ã¿ãŸã:
+
+- MINIMAL ã®ãã¹ãŠã®äŸåé¢ä¿
+- `sqlalchemy` - ããŒã¿ããŒã¹æäœã®ããã® ORM
+- `alembic` - ããŒã¿ããŒã¹ãã€ã°ã¬ãŒã·ã§ã³
+- `pytest` - ãã¹ããã¬ãŒã ã¯ãŒã¯
+
+**é©ããçšé:**
+
+- å€ãã® Web ã¢ããªã±ãŒã·ã§ã³
+- ããŒã¿ããŒã¹ã䜿ã API
+- æ¬çªéçšãèŠæ®ããã¢ããªã±ãŒã·ã§ã³
+- ããŒã ãããžã§ã¯ã
+
+#### FULL ã¹ã¿ãã¯
+
+å®å
šãªéçºç°å¢ãæäŸããŸã:
+
+- STANDARD ã®ãã¹ãŠã®äŸåé¢ä¿
+- `redis` - ãã£ãã·ã¥ãšã»ãã·ã§ã³ã¹ãã¬ãŒãž
+- `celery` - ããã¯ã°ã©ãŠã³ãã¿ã¹ã¯åŠç
+
+**é©ããçšé:**
+
+- å€§èŠæš¡ã¢ããªã±ãŒã·ã§ã³
+- é«ããã©ãŒãã³ã¹ãèŠæ±ãããå Žé¢
+- è€éãªããžãã¹ããžãã¯
+- ãšã³ã¿ãŒãã©ã€ãºã¢ããªã±ãŒã·ã§ã³
+
+## é«åºŠãªãããžã§ã¯ããªãã·ã§ã³
+
+### ãããžã§ã¯ãæ§æã®ã«ã¹ã¿ãã€ãº
+
+äœææã«ãããžã§ã¯ããã«ã¹ã¿ãã€ãºã§ããŸã:
+
+
+
+```console
+$ fastkit init
+Enter the project name: advanced-api
+Enter the author name: Development Team
+Enter the author email: dev@company.com
+Enter the project description: Advanced FastAPI application with custom features
+
+# ããŒã¿ããŒã¹å¯Ÿå¿ã®ãã STANDARD ã¹ã¿ãã¯ãéžæ
+Select stack (minimal, standard, full): standard
+Do you want to proceed with project creation? [y/N]: y
+```
+
+
+
+### ãããžã§ã¯ãæ§é ã®èª¬æ
+
+ãããžã§ã¯ããäœæãããšãFastAPI-fastkit ã¯æ¬¡ã®æ§é ãçæããŸã:
+
+```
+my-awesome-api/
+âââ .venv/ # ä»®æ³ç°å¢
+âââ src/ # ãœãŒã¹ã³ãŒã
+â âââ __init__.py
+â âââ main.py # ã¢ããªã±ãŒã·ã§ã³ã®ãšã³ããªãã€ã³ã
+â âââ core/ # ã³ã¢èšå®
+â â âââ __init__.py
+â â âââ config.py # èšå® / ç°å¢å€æ°
+â âââ api/ # API ã¬ã€ã€ãŒ
+â â âââ __init__.py
+â â âââ api.py # ã¡ã€ã³ã® API ã«ãŒã¿ãŒ
+â â âââ routes/ # åå¥ã®ã«ãŒãã¢ãžã¥ãŒã«
+â â âââ __init__.py
+â â âââ items.py # ãµã³ãã«ã® items ãšã³ããã€ã³ã
+â âââ crud/ # ããŒã¿ããŒã¹æäœ
+â â âââ __init__.py
+â â âââ items.py # items çšã® CRUD æäœ
+â âââ schemas/ # Pydantic ã¢ãã«
+â â âââ __init__.py
+â â âââ items.py # ããŒã¿æ€èšŒã¹ããŒã
+â âââ mocks/ # ãã¹ãããŒã¿
+â âââ __init__.py
+â âââ mock_items.json # éçºçšã®ãµã³ãã«ããŒã¿
+âââ tests/ # ãã¹ãã¹ã€ãŒã
+â âââ __init__.py
+â âââ conftest.py # ãã¹ãèšå®
+â âââ test_items.py # ãµã³ãã«ãã¹ã
+âââ scripts/ # ãŠãŒãã£ãªãã£ã¹ã¯ãªãã
+â âââ test.sh # ãã¹ãå®è¡
+â âââ coverage.sh # ã«ãã¬ããžæž¬å®
+â âââ lint.sh # ã³ãŒããªã³ãã£ã³ã°
+âââ requirements.txt # Python äŸåé¢ä¿
+âââ setup.py # ããã±ãŒãžèšå®
+âââ README.md # ãããžã§ã¯ãããã¥ã¡ã³ã
+```
+
+### 3. ããã±ãŒãžãããŒãžã£ãŒã®éžæ
+
+FastAPI-fastkit ã¯è€æ°ã® Python ããã±ãŒãžãããŒãžã£ãŒããµããŒãããŠããŸããéçºã¯ãŒã¯ãããŒã«æãåããã®ãéžãã§ãã ãã:
+
+#### å©çšå¯èœãªããã±ãŒãžãããŒãžã£ãŒ
+
+
+
+```console
+Available Package Managers:
+ Package Managers
+ââââââââââ¬âââââââââââââââââââââââââââââââââââââââââââââ
+â PIP â Standard Python package manager â
+â UV â Fast Python package manager â
+â PDM â Modern Python dependency management â
+â POETRY â Python dependency management and packaging â
+ââââââââââŽâââââââââââââââââââââââââââââââââââââââââââââ
+
+Select package manager (pip, uv, pdm, poetry) [uv]: uv
+```
+
+
+
+åããã±ãŒãžãããŒãžã£ãŒã®å©ç¹ã¯æ¬¡ã®ãšããã§ã:
+
+#### UV (ããã©ã«ãã»æšå¥š)
+
+**Rust 補ã®é«éããã±ãŒãžãããŒãžã£ãŒ**
+
+- â¡ **è¶
é«é**: pip ãã 10ã100 åé«é
+- ð§ **ãã®ãŸãŸçœ®ãæãããã**: pip ã®ã¯ãŒã¯ãããŒãšã»ãŒåãæèŠã§äœ¿ãã
+- ðŠ **ã¢ãã³**: PEP 621 ãå®å
šãµããŒã
+- ð ïž **ä¿¡é Œæ§**: åçŸæ§ã®ããäŸåé¢ä¿è§£æ±º
+
+**çæããããã¡ã€ã«:**
+
+- `pyproject.toml` (PEP 621 圢åŒ)
+- `uv.lock` (ããã¯ãã¡ã€ã«)
+
+**äœæåŸã®äœ¿ãæ¹:**
+```console
+cd my-project
+uv sync # äŸåé¢ä¿ãã€ã³ã¹ããŒã«
+uv add requests # æ°ããäŸåé¢ä¿ã远å
+uv run pytest # ãã¹ããå®è¡
+```
+
+#### PDM
+
+**ã¢ãã³ãª Python äŸåé¢ä¿ç®¡ç**
+
+- ð **ã¢ãã³**: PEP 582 / PEP 621 ããµããŒã
+- ð§ **è³¢ã**: é«åºŠãªäŸåé¢ä¿è§£æ±º
+- ðŒ **æ¥ååã**: ã¯ãŒã¯ã¹ããŒã¹ãšãã«ããããžã§ã¯ã察å¿
+- ð **è§£æ**: äŸåé¢ä¿è§£æããŒã«
+
+**çæããããã¡ã€ã«:**
+
+- `pyproject.toml` (PEP 621 圢åŒ)
+- `pdm.lock` (ããã¯ãã¡ã€ã«)
+
+**äœæåŸã®äœ¿ãæ¹:**
+```console
+cd my-project
+pdm install # äŸåé¢ä¿ãã€ã³ã¹ããŒã«
+pdm add requests # æ°ããäŸåé¢ä¿ã远å
+pdm run pytest # ãã¹ããå®è¡
+```
+
+#### Poetry
+
+**æçããäŸåé¢ä¿ç®¡çãšããã±ãŒãžã³ã°**
+
+- â
**å®çª**: æçããŠããåºãæ¡çšãããŠãã
+- ðŠ **çµ±å**: ãã«ãã»å
¬éãŸã§ãµããŒã
+- ð **åçŸå¯èœ**: poetry.lock ã«ããå³å¯ãªããŒãžã§ã³ç®¡ç
+- ðïž **å
æ¬ç**: ãããžã§ã¯ãã®ã©ã€ããµã€ã¯ã«å
šäœã管ç
+
+**çæããããã¡ã€ã«:**
+
+- `pyproject.toml` (Poetry 圢åŒ)
+- `poetry.lock` (ããã¯ãã¡ã€ã«)
+
+**äœæåŸã®äœ¿ãæ¹:**
+```console
+cd my-project
+poetry install # äŸåé¢ä¿ãã€ã³ã¹ããŒã«
+poetry add requests # æ°ããäŸåé¢ä¿ã远å
+poetry run pytest # ãã¹ããå®è¡
+```
+
+#### PIP
+
+**æšæºã® Python ããã±ãŒãžãããŒãžã£ãŒ**
+
+- ð **忢±**: Python ã«æšæºã§å«ãŸãã
+- ð **ã©ãã§ãåã**: ããããç°å¢ã§å©çšå¯èœ
+- ð **æ
£ããŠãã**: å€ãã®éçºè
ããã§ã«ç¥ã£ãŠãã
+- ð§ **ã·ã³ãã«**: çŽ çŽãªã¯ãŒã¯ãããŒ
+
+**çæããããã¡ã€ã«:**
+
+- `requirements.txt`
+
+**äœæåŸã®äœ¿ãæ¹:**
+```console
+cd my-project
+source .venv/bin/activate # Linux/macOS
+.venv\Scripts\activate # Windows
+pip install -r requirements.txt
+pip install requests
+pytest
+```
+
+#### ããã±ãŒãžãããŒãžã£ãŒã®æå®
+
+奜ã¿ã®ããã±ãŒãžãããŒãžã£ãŒã¯æ¬¡ã®æ¹æ³ã§æå®ã§ããŸã:
+
+**察話åéžæ (ããã©ã«ã):**
+```console
+$ fastkit init
+# ... ããã±ãŒãžãããŒãžã£ãŒéžæã®ããã³ããã«åŸã
+```
+
+**ã³ãã³ãã©ã€ã³ãªãã·ã§ã³:**
+```console
+$ fastkit init --package-manager poetry
+$ fastkit init --package-manager pdm
+$ fastkit init --package-manager uv
+$ fastkit init --package-manager pip
+```
+
+### åãã£ã¬ã¯ããªã®åœ¹å²
+
+#### `src/` ãã£ã¬ã¯ããª
+
+Python ã®ããã±ãŒãžã³ã°ã®ãã¹ããã©ã¯ãã£ã¹ã§ãã **src ã¬ã€ã¢ãŠã** ã«åŸã£ãŠãã¢ããªã±ãŒã·ã§ã³ã®ãœãŒã¹ã³ãŒãããã¹ãŠæ ŒçŽããŸãã
+
+#### `core/` ã¢ãžã¥ãŒã«
+
+- **config.py**: ã¢ããªã±ãŒã·ã§ã³ã®èšå®ãç°å¢å€æ°ãæ§æ
+- ãã¹ãŠã®èšå®ç®¡çãäžå
å
+- ç°å¢å¥èšå®ã®ããã® `.env` ãã¡ã€ã«ããµããŒã
+
+#### `api/` ã¢ãžã¥ãŒã«
+
+- **api.py**: ãã¹ãŠã®ãµãã«ãŒã¿ãŒããŸãšããã¡ã€ã³ã® API ã«ãŒã¿ãŒ
+- **routes/**: åãªãœãŒã¹ã«å¯Ÿå¿ããåå¥ã®ã«ãŒãã¢ãžã¥ãŒã«
+- API ãšã³ããã€ã³ãããšã«é¢å¿äºãæç¢ºã«åé¢
+
+#### `crud/` ã¢ãžã¥ãŒã«
+
+- ããŒã¿ããŒã¹æäœãšããžãã¹ããžãã¯
+- **C**reateã**R**eadã**U**pdateã**D**elete ã®æäœ
+- API ã«ãŒããšããŒã¿ã¹ãã¬ãŒãžã®éã®æœè±¡åã¬ã€ã€ãŒ
+
+#### `schemas/` ã¢ãžã¥ãŒã«
+
+- ããŒã¿æ€èšŒã®ããã® Pydantic ã¢ãã«
+- ãªã¯ãšã¹ã / ã¬ã¹ãã³ã¹ã¹ããŒã
+- åå®çŸ©ãšããŒã¿ã¢ãã«
+
+#### `tests/` ãã£ã¬ã¯ããª
+
+- ã¢ããªã±ãŒã·ã§ã³ã®å®å
šãªãã¹ãã¹ã€ãŒã
+- ãŠããããã¹ããšçµ±åãã¹ããå«ã
+- pytest ã§ãããããæ§ææžã¿
+
+## ã¹ã¿ãã¯æ¯èŒ
+
+| æ©èœ | MINIMAL | STANDARD | FULL |
+|---|---|---|---|
+| FastAPI ãš Uvicorn | â
| â
| â
|
+| ããŒã¿æ€èšŒ | â
| â
| â
|
+| ããŒã¿ããŒã¹å¯Ÿå¿ | â | â
| â
|
+| ãã€ã°ã¬ãŒã·ã§ã³ | â | â
| â
|
+| ãã¹ããã¬ãŒã ã¯ãŒã¯ | â | â
| â
|
+| ãã£ãã·ã¥ (Redis) | â | â | â
|
+| ããã¯ã°ã©ãŠã³ãã¿ã¹ã¯ | â | â | â
|
+| **é©ããçšé** | åŠç¿ / ã·ã³ãã«ãª API | å€ãã®ã¢ããªã±ãŒã·ã§ã³ | ãšã³ã¿ãŒãã©ã€ãº / è€éãªã¢ã㪠|
+
+## ãããžã§ã¯ãäœæã®äŸ
+
+### äŸ 1: åŠç¿çšãããžã§ã¯ã
+
+
+
+```console
+$ fastkit init
+Enter the project name: fastapi-learning
+Enter the author name: Student
+Enter the author email: student@example.com
+Enter the project description: Learning FastAPI basics
+
+Select stack (minimal, standard, full): minimal
+Do you want to proceed with project creation? [y/N]: y
+```
+
+
+
+### äŸ 2: EC ãµã€ã API
+
+
+
+```console
+$ fastkit init
+Enter the project name: ecommerce-api
+Enter the author name: E-commerce Team
+Enter the author email: team@ecommerce.com
+Enter the project description: E-commerce platform API
+
+Select stack (minimal, standard, full): standard
+Do you want to proceed with project creation? [y/N]: y
+```
+
+
+
+### äŸ 3: é«ããã©ãŒãã³ã¹ã¢ããªã±ãŒã·ã§ã³
+
+
+
+```console
+$ fastkit init
+Enter the project name: enterprise-api
+Enter the author name: Enterprise Team
+Enter the author email: enterprise@company.com
+Enter the project description: High-performance enterprise API
+
+Select stack (minimal, standard, full): full
+Do you want to proceed with project creation? [y/N]: y
+```
+
+
+
+## ãããžã§ã¯ãäœæåŸ
+
+### 1. ä»®æ³ç°å¢ã®æå¹å
+
+
+
+```console
+$ cd my-awesome-api
+$ source .venv/bin/activate # Linux/macOS
+$ .venv\Scripts\activate # Windows
+```
+
+
+
+### 2. ã€ã³ã¹ããŒã«ã®ç¢ºèª
+
+
+
+```console
+$ pip list
+Package Version
+fastapi 0.104.1
+uvicorn 0.24.0
+pydantic 2.5.0
+...
+```
+
+
+
+### 3. éçºã®éå§
+
+
+
+```console
+$ fastkit runserver
+INFO: Uvicorn running on http://127.0.0.1:8000
+```
+
+
+
+## èšå®ç®¡ç
+
+### ç°å¢å€æ°
+
+ãããžã§ã¯ã㯠`.env` ãã¡ã€ã«ã«ããç°å¢ããŒã¹ã®èšå®ããµããŒãããŠããŸãã
+
+ãããžã§ã¯ãã«ãŒãã« `.env` ãã¡ã€ã«ãäœæããŸããã:
+
+```env
+# .env
+APP_NAME=My Awesome API
+APP_VERSION=1.0.0
+DEBUG=True
+DATABASE_URL=sqlite:///./app.db
+SECRET_KEY=your-secret-key-here
+```
+
+### ã³ãŒãããã®èšå®
+
+çæããã `src/core/config.py` ããããã®å€æ°ãèªåã§èªã¿èŸŒã¿ãŸã:
+
+```python
+from pydantic_settings import BaseSettings
+
+class Settings(BaseSettings):
+ APP_NAME: str = "FastAPI Application"
+ APP_VERSION: str = "1.0.0"
+ DEBUG: bool = False
+ DATABASE_URL: str = "sqlite:///./app.db"
+ SECRET_KEY: str = "dev-secret-key"
+
+ class Config:
+ env_file = ".env"
+
+settings = Settings()
+```
+
+## ã«ã¹ã¿ãã€ãº
+
+### äŸåé¢ä¿ã®è¿œå
+
+ãããžã§ã¯ãäœæåŸã远å ã®äŸåé¢ä¿ãã€ã³ã¹ããŒã«ã§ããŸã:
+
+
+
+```console
+$ pip install requests httpx python-jose
+$ pip freeze > requirements.txt
+```
+
+
+
+### ãããžã§ã¯ãæ§é ã®å€æŽ
+
+çæãããæ§é ã¯ãã¹ããã©ã¯ãã£ã¹ã«åŸã£ãŠããŸãããå¿
èŠã«å¿ããŠå€æŽã§ããŸã:
+
+- `src/` ã«æ°ããã¢ãžã¥ãŒã«ã远å
+- `api/routes/` ã«ã«ãŒããã¡ã€ã«ã远å
+- `crud/` ã§ CRUD æäœãæ¡åŒµ
+- `schemas/` ã«ã¹ããŒãã远å
+
+## ãã¹ããã©ã¯ãã£ã¹
+
+### 1. ä»®æ³ç°å¢
+
+ãããžã§ã¯ãã®äŸåé¢ä¿ãåé¢ãããããåžžã«ä»®æ³ç°å¢ã䜿ããŸããã:
+
+```bash
+# ä»®æ³ç°å¢ä»ãã§ãããžã§ã¯ããäœæ
+$ fastkit init # .venv/ ãèªåçæããã
+
+# äœæ¥æã«æå¹å
+$ source .venv/bin/activate
+```
+
+### 2. ããŒãžã§ã³ç®¡ç
+
+ãããžã§ã¯ãäœæåŸã« Git ãªããžããªãåæåããŸããã:
+
+
+
+```console
+$ cd my-awesome-api
+$ git init
+$ git add .
+$ git commit -m "Initial commit - FastAPI project setup"
+```
+
+
+
+### 3. ç°å¢èšå®
+
+- ããŒã«ã«éçºã«ã¯ `.env` ãã¡ã€ã«ã䜿çš
+- æ¬çªç°å¢ã§ã¯ç°å¢å€æ°ãå©çš
+- æ©å¯ããŒã¿ã¯ããŒãžã§ã³ç®¡çã«æ±ºããŠã³ãããããªã
+
+### 4. ãã¹ã
+
+忢±ã®ãã¹ããã¬ãŒã ã¯ãŒã¯ã掻çšããŸããã:
+
+
+
+```console
+$ python -m pytest
+$ bash scripts/test.sh
+```
+
+
+
+## 次ã®ã¹ããã
+
+ãããžã§ã¯ããäœæããã:
+
+1. **[ã«ãŒãã®è¿œå ](adding-routes.md)**: æ°ãã API ãšã³ããã€ã³ãã®è¿œå æ¹æ³ãåŠã¶
+2. **[CLI ãªãã¡ã¬ã³ã¹](cli-reference.md)**: å©çšå¯èœãªãã¹ãŠã®ã³ãã³ããç¿åŸ
+3. **[æåã®ãããžã§ã¯ãã®ãã¥ãŒããªã¢ã«](../tutorial/first-project.md)**: å®å
šãªã¢ããªã±ãŒã·ã§ã³ãæ§ç¯
+
+!!! tip "ãããžã§ã¯ãäœæã®ãã³ã"
+ - ãããžã§ã¯ãèŠä»¶ã«ãããããã¹ã¿ãã¯ãéžã³ãŸããã
+ - åŠç¿ãªã MINIMALãã»ãšãã©ã®ãããžã§ã¯ããªã STANDARD ãã
+ - ãããžã§ã¯ãæ§é ã¯æ¡åŒµæ§ãšä¿å®æ§ãæèããèšèšã§ã
+ - çæãããã³ãŒãã¯ãã¹ãŠ FastAPI ã®ãã¹ããã©ã¯ãã£ã¹ã«åŸã£ãŠããŸã
diff --git a/docs/ja/user-guide/installation.md b/docs/ja/user-guide/installation.md
new file mode 100644
index 0000000..ecfa762
--- /dev/null
+++ b/docs/ja/user-guide/installation.md
@@ -0,0 +1,209 @@
+# ã€ã³ã¹ããŒã«
+
+ãã®ã¬ã€ãã§ã¯ãFastAPI-fastkit ã®ã€ã³ã¹ããŒã«æ¹æ³ã説æããŸãã
+
+## åäœèŠä»¶
+
+FastAPI-fastkit ã䜿çšããã«ã¯ã次ã®èŠä»¶ãæºããå¿
èŠããããŸã:
+
+- **Python**: 3.12 以äž
+- **ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã **: WindowsãmacOSãLinux ã«å¯Ÿå¿
+
+## ã€ã³ã¹ããŒã«æ¹æ³
+
+### pip ã§ã€ã³ã¹ããŒã« (æšå¥š)
+
+æãã·ã³ãã«ãªã€ã³ã¹ããŒã«æ¹æ³ã§ã:
+
+
+
+```console
+$ pip install FastAPI-fastkit
+---> 100%
+Successfully installed FastAPI-fastkit
+```
+
+
+
+### ç¹å®ããŒãžã§ã³ãã€ã³ã¹ããŒã«
+
+ç¹å®ã®ããŒãžã§ã³ãã€ã³ã¹ããŒã«ããå Žå:
+
+
+
+```console
+$ pip install FastAPI-fastkit==1.0.0
+---> 100%
+Successfully installed FastAPI-fastkit-1.0.0
+```
+
+
+
+### éçºçãã€ã³ã¹ããŒã«
+
+GitHub ããçŽæ¥ãææ°ã®éçºçãã€ã³ã¹ããŒã«ããå Žå:
+
+
+
+```console
+$ pip install git+https://github.com/bnbong/FastAPI-fastkit.git
+---> 100%
+Successfully installed FastAPI-fastkit
+```
+
+
+
+!!! warning "éçºçã«é¢ããæ³šæ"
+ éçºçã¯äžå®å®ãªå¯èœæ§ããããæ¬çªç°å¢ã§ã®å©çšã¯æšå¥šãããŸããã
+
+## ä»®æ³ç°å¢ã®ã»ããã¢ãã (æšå¥š)
+
+äŸåé¢ä¿ã®ç«¶åãé¿ãããããä»®æ³ç°å¢ã®å©çšãåŒ·ãæšå¥šããŸã:
+
+### venv ã䜿ã
+
+
+
+```console
+$ python -m venv fastapi-env
+$ source fastapi-env/bin/activate # Linux/macOS
+$ fastapi-env\Scripts\activate # Windows
+$ pip install FastAPI-fastkit
+```
+
+
+
+### conda ã䜿ã
+
+
+
+```console
+$ conda create -n fastapi-env python=3.12
+$ conda activate fastapi-env
+$ pip install FastAPI-fastkit
+```
+
+
+
+## ã€ã³ã¹ããŒã«ã®ç¢ºèª
+
+ã€ã³ã¹ããŒã«åŸãFastAPI-fastkit ãæ£ããã€ã³ã¹ããŒã«ãããŠããã確èªããŸããã:
+
+
+
+```console
+$ fastkit --version
+FastAPI-fastkit version 1.0.0
+```
+
+
+
+
+
+```console
+$ fastkit --help
+Usage: fastkit [OPTIONS] COMMAND [ARGS]...
+
+ FastAPI-fastkit CLI
+
+Options:
+ --version Show the version and exit.
+ --help Show this message and exit.
+
+Commands:
+ addroute Add a new route to FastAPI project
+ init Create a new FastAPI project
+ list-templates List available FastAPI templates
+ runserver Start FastAPI development server
+ startdemo Create FastAPI project from template
+```
+
+
+
+## ãã©ãã«ã·ã¥ãŒãã£ã³ã°
+
+### ã³ãã³ããèŠã€ãããªã
+
+ãcommand not foundããšã©ãŒãåºãå Žå:
+
+1. **FastAPI-fastkit ãã€ã³ã¹ããŒã«ãããŠããã確èª**:
+
+
+ ```console
+ $ pip show FastAPI-fastkit
+ ```
+
+
+2. **ä»®æ³ç°å¢ã確èª**:
+
+
+ ```console
+ $ which python
+ $ which pip
+ ```
+
+
+3. **FastAPI-fastkit ãåã€ã³ã¹ããŒã«**:
+
+
+ ```console
+ $ pip uninstall FastAPI-fastkit
+ $ pip install FastAPI-fastkit
+ ```
+
+
+### ããŒããã·ã§ã³ãšã©ãŒ
+
+ã€ã³ã¹ããŒã«æã«ããŒããã·ã§ã³ãšã©ãŒãçºçããå Žå:
+
+**Linux/macOS ã®å Žå:**
+
+
+
+```console
+$ pip install --user FastAPI-fastkit
+```
+
+
+
+**Windows ã®å Žå (管çè
ãšããŠå®è¡):**
+
+
+
+```console
+$ pip install FastAPI-fastkit
+```
+
+
+
+### Python ããŒãžã§ã³ã®äºææ§
+
+FastAPI-fastkit 㯠Python 3.12 以äžãå¿
èŠã§ããPython ã®ããŒãžã§ã³ã確èªããŸããã:
+
+
+
+```console
+$ python --version
+Python 3.12.0
+```
+
+
+
+å€ãããŒãžã§ã³ã䜿ã£ãŠããå ŽåãPython ãã¢ããã°ã¬ãŒãããŠãã ãã:
+
+- **å
¬åŒ Python**: [python.org/downloads](https://www.python.org/downloads/)
+- **pyenv ã®å Žå**: `pyenv install 3.12.0`
+- **conda ã®å Žå**: `conda install python=3.12`
+
+## 次ã®ã¹ããã
+
+ã€ã³ã¹ããŒã«ãå®äºããã:
+
+1. **[ã¯ã€ãã¯ã¹ã¿ãŒã](quick-start.md)**: 5 åã§æåã®ãããžã§ã¯ããäœæ
+2. **[å
¥éãã¥ãŒããªã¢ã«](../tutorial/getting-started.md)**: 段éçãªè©³çްãã¥ãŒããªã¢ã«
+3. **[CLI ãªãã¡ã¬ã³ã¹](cli-reference.md)**: å
šã³ãã³ãã®ãªãã¡ã¬ã³ã¹
+
+!!! tip "ã€ã³ã¹ããŒã«ã®ãã³ã"
+ - ãããžã§ã¯ãåé¢ã®ãããåžžã«ä»®æ³ç°å¢ãå©çšããŸããã
+ - FastAPI-fastkit ã¯ææ°çã«æŽæ°ãä¿ã¡ãŸããã
+ - æŽæ°æ
å ±ã Issue 㯠[GitHub ãªããžããª](https://github.com/bnbong/FastAPI-fastkit) ã§ç¢ºèªããŸããã
diff --git a/docs/ja/user-guide/quick-start.md b/docs/ja/user-guide/quick-start.md
new file mode 100644
index 0000000..6c59dd5
--- /dev/null
+++ b/docs/ja/user-guide/quick-start.md
@@ -0,0 +1,366 @@
+# ã¯ã€ãã¯ã¹ã¿ãŒã
+
+FastAPI-fastkit ã§ 5 å以å
ã«æåã® FastAPI ãããžã§ã¯ããäœæããŸããã!
+
+!!! tip "ã©ã®ã¹ã¿ãŒã¿ãŒãéžã¹ã°ãããåãããªããšã"
+ `startdemo` ãã³ãã¬ãŒããšå¯Ÿè©±åã®ã¢ãŒããã¯ãã£ããªã»ãã (`minimal` / `single-module` / `classic-layered` / `domain-starter`) ãåå¿è
åãã«æ¯èŒãã [**ã©ã®ã¹ã¿ãŒã¿ãŒãéžã¶ã¹ã?**](choosing-a-starter.md) ãåç
§ããŠãã ãããçãèšãã°ã**`fastkit init --interactive` ã® `domain-starter` ããªã»ãããçŸåšã®æšå¥šããã©ã«ã** ã§ãã
+
+## 1. ãããžã§ã¯ãã®äœæ
+
+FastAPI-fastkit ã® `init` ã³ãã³ãã§æ°ãããããžã§ã¯ããäœæããŸã:
+
+
+
+```console
+$ fastkit init
+Enter the project name: my-first-app
+Enter the author name: Your Name
+Enter the author email: your.email@example.com
+Enter the project description: My first FastAPI application
+
+ Project Information
+ââââââââââââââââ¬ââââââââââââââââââââââââââââââ
+â Project Name â my-first-app â
+â Author â Your Name â
+â Author Email â your.email@example.com â
+â Description â My first FastAPI applicationâ
+ââââââââââââââââŽââââââââââââââââââââââââââââââ
+
+Available Stacks and Dependencies:
+ MINIMAL Stack
+ââââââââââââââââ¬ââââââââââââââââââââ
+â Dependency 1 â fastapi â
+â Dependency 2 â uvicorn â
+â Dependency 3 â pydantic â
+â Dependency 4 â pydantic-settings â
+ââââââââââââââââŽââââââââââââââââââââ
+
+ STANDARD Stack
+ââââââââââââââââ¬ââââââââââââââââââââ
+â Dependency 1 â fastapi â
+â Dependency 2 â uvicorn â
+â Dependency 3 â sqlalchemy â
+â Dependency 4 â alembic â
+â Dependency 5 â pytest â
+â Dependency 6 â pydantic â
+â Dependency 7 â pydantic-settings â
+ââââââââââââââââŽââââââââââââââââââââ
+
+ FULL Stack
+ââââââââââââââââ¬ââââââââââââââââââââ
+â Dependency 1 â fastapi â
+â Dependency 2 â uvicorn â
+â Dependency 3 â sqlalchemy â
+â Dependency 4 â alembic â
+â Dependency 5 â pytest â
+â Dependency 6 â redis â
+â Dependency 7 â celery â
+â Dependency 8 â pydantic â
+â Dependency 9 â pydantic-settings â
+ââââââââââââââââŽââââââââââââââââââââ
+
+Select stack (minimal, standard, full): minimal
+
+Available Package Managers:
+ Package Managers
+ââââââââââ¬âââââââââââââââââââââââââââââââââââââââââââââ
+â PIP â Standard Python package manager â
+â UV â Fast Python package manager â
+â PDM â Modern Python dependency management â
+â POETRY â Python dependency management and packaging â
+ââââââââââŽâââââââââââââââââââââââââââââââââââââââââââââ
+
+Select package manager (pip, uv, pdm, poetry) [uv]: uv
+Do you want to proceed with project creation? [y/N]: y
+
+âš FastAPI project 'my-first-app' has been created successfully!
+```
+
+
+
+## 2. ä»®æ³ç°å¢ã®æå¹å
+
+ãããžã§ã¯ããã£ã¬ã¯ããªãžç§»åããä»®æ³ç°å¢ãæå¹åããŸã:
+
+
+
+```console
+$ cd my-first-app
+$ source .venv/bin/activate # Linux/macOS
+$ .venv\Scripts\activate # Windows
+```
+
+
+
+## 3. éçºãµãŒããŒã®èµ·å
+
+FastAPI éçºãµãŒããŒãèµ·åããŸã:
+
+
+
+```console
+$ fastkit runserver
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+INFO: Started reloader process [28720]
+INFO: Started server process [28722]
+INFO: Waiting for application startup.
+INFO: Application startup complete.
+```
+
+
+
+!!! success "ããã§ãšãããããŸã!"
+ FastAPI ãµãŒããŒãèµ·åäžã§ã! ãã©ãŠã¶ã§ç¢ºèªããŠã¿ãŸãããã
+
+## 4. API ã®ãã¹ã
+
+ãã©ãŠã¶ã§æ¬¡ã® URL ãéããŠã¿ãŸããã:
+
+### ã¡ã€ã³ãšã³ããã€ã³ã
+
+[http://127.0.0.1:8000](http://127.0.0.1:8000) ã«ã¢ã¯ã»ã¹ãããšã次ã®ããã«è¡šç€ºãããŸã:
+
+```json
+{"message": "Hello World"}
+```
+
+### 察話å API ããã¥ã¡ã³ã
+
+[http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs) ãéããŠãã ããã
+
+ããã¯èªåçæããã **Swagger UI** ããã¥ã¡ã³ãã§ã以äžã®ããšãå¯èœã§ã:
+
+- ãã¹ãŠã® API ãšã³ããã€ã³ãã衚瀺
+- ãã©ãŠã¶ããçŽæ¥ãšã³ããã€ã³ãããã¹ã
+- ãªã¯ãšã¹ã / ã¬ã¹ãã³ã¹ã¹ããŒãã確èª
+
+### 代æ¿ããã¥ã¡ã³ã
+
+[http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc) ãéããŠãã ããã
+
+å¥ã®ãã£ãããããã¶ã€ã³ã® **ReDoc** ããã¥ã¡ã³ãç»é¢ã§ãã
+
+## 5. æåã®ã«ãŒãã®è¿œå
+
+ãããžã§ã¯ãã«æ°ãã API ã«ãŒãã远å ããŠã¿ãŸããã:
+
+
+
+```console
+$ fastkit addroute users my-first-app
+ Adding New Route
+ââââââââââââââââââââ¬âââââââââââââââââââââââââââââââââââââââââââ
+â Project â my-first-app â
+â Route Name â users â
+â Target Directory â ~/my-first-app â
+ââââââââââââââââââââŽâââââââââââââââââââââââââââââââââââââââââââ
+
+Do you want to add route 'users' to project 'my-first-app'? [Y/n]: y
+
+âââââââââââââââââââââââââ Info âââââââââââââââââââââââââ®
+â â¹ Updated main.py to include the API router â
+â°âââââââââââââââââââââââââââââââââââââââââââââââââââââââ¯
+ââââââââââââââââââââââââ Success ââââââââââââââââââââââââ®
+â âš Successfully added new route 'users' to project â
+â `my-first-app` â
+â°ââââââââââââââââââââââââââââââââââââââââââââââââââââââââ¯
+```
+
+
+
+ãµãŒããŒã¯èªåçã«åèªã¿èŸŒã¿ãããæ°ãããšã³ããã€ã³ããå©çšå¯èœã«ãªããŸã:
+
+- `GET /api/v1/users/` - ãã¹ãŠã®ãŠãŒã¶ãŒãååŸ
+- `POST /api/v1/users/` - æ°ãããŠãŒã¶ãŒãäœæ
+- `GET /api/v1/users/{user_id}` - ç¹å®ã®ãŠãŒã¶ãŒãååŸ
+- `PUT /api/v1/users/{user_id}` - ãŠãŒã¶ãŒãæŽæ°
+- `DELETE /api/v1/users/{user_id}` - ãŠãŒã¶ãŒãåé€
+
+## 6. æ°ãã API ã®ãã¹ã
+
+### curl ã䜿ã
+
+**ãã¹ãŠã®ãŠãŒã¶ãŒãååŸ:**
+
+
+
+```console
+$ curl http://127.0.0.1:8000/api/v1/users/
+[]
+```
+
+
+
+**æ°ãããŠãŒã¶ãŒãäœæ:**
+
+
+
+```console
+$ curl -X POST "http://127.0.0.1:8000/api/v1/users/" \
+ -H "Content-Type: application/json" \
+ -d '{"title": "John Doe", "description": "Software Developer"}'
+{
+ "id": 1,
+ "title": "John Doe",
+ "description": "Software Developer"
+}
+```
+
+
+
+### 察話åããã¥ã¡ã³ãã䜿ã
+
+1. [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs) ã«ã¢ã¯ã»ã¹ããŸãã
+2. **"users"** ã»ã¯ã·ã§ã³ãå±éããŸãã
+3. **"POST /api/v1/users/"** ãã¯ãªãã¯ããŸãã
+4. **"Try it out"** ãã¯ãªãã¯ããŸãã
+5. ãªã¯ãšã¹ãããã£ãå
¥åããŸã:
+ ```json
+ {
+ "title": "Jane Smith",
+ "description": "Product Manager"
+ }
+ ```
+6. **"Execute"** ãã¯ãªãã¯ããŸãã
+
+## 7. ãããžã§ã¯ãæ§é ã®ç¢ºèª
+
+çæããããããžã§ã¯ãã¯æŽçãããæ§é ãæã¡ãŸã:
+
+```
+my-first-app/
+âââ .venv/ # ä»®æ³ç°å¢
+âââ src/
+â âââ __init__.py
+â âââ main.py # FastAPI ã¢ããªã®ãšã³ããªãã€ã³ã
+â âââ core/
+â â âââ __init__.py
+â â âââ config.py # ã¢ããªèšå®
+â âââ api/
+â â âââ __init__.py
+â â âââ api.py # API ã«ãŒã¿ãŒããŸãšãã
+â â âââ routes/
+â â âââ __init__.py
+â â âââ items.py # ããã©ã«ãã® items ã«ãŒã
+â â âââ users.py # æ°ãã远å ãã users ã«ãŒã
+â âââ crud/
+â â âââ __init__.py
+â â âââ items.py # items çšã® CRUD æäœ
+â â âââ users.py # users çšã® CRUD æäœ
+â âââ schemas/
+â â âââ __init__.py
+â â âââ items.py # items çš Pydantic ã¹ããŒã
+â â âââ users.py # users çš Pydantic ã¹ããŒã
+â âââ mocks/
+â âââ __init__.py
+â âââ mock_items.json # ãã¹ãããŒã¿
+âââ tests/ # ãã¹ããã¡ã€ã«
+âââ scripts/ # ãŠãŒãã£ãªãã£ã¹ã¯ãªãã
+âââ requirements.txt # Python äŸåé¢ä¿
+âââ setup.py # ããã±ãŒãžèšå®
+âââ README.md # ãããžã§ã¯ãããã¥ã¡ã³ã
+```
+
+## 8. ããã±ãŒãžãããŒãžã£ãŒã®éžæè¢
+
+FastAPI-fastkit ã¯å¥œã¿ã«åãããŠè€æ°ã® Python ããã±ãŒãžãããŒãžã£ãŒããµããŒãããŠããŸã:
+
+### å©çšå¯èœãªããã±ãŒãžãããŒãžã£ãŒ
+
+| ãããŒãžã£ãŒ | 説æ | é©ããŠããå Žé¢ |
+|---|---|---|
+| **UV** | é«é㪠Python ããã±ãŒãžãããŒãžã£ãŒ (ããã©ã«ã) | é床ãšããã©ãŒãã³ã¹ |
+| **PDM** | ã¢ãã³ãª Python äŸåé¢ä¿ç®¡ç | é«åºŠãªäŸåé¢ä¿è§£æ±º |
+| **Poetry** | Python äŸåé¢ä¿ç®¡çãšããã±ãŒãžã³ã° | Poetry äžå¿ã®ã¯ãŒã¯ãã㌠|
+| **PIP** | æšæºã® Python ããã±ãŒãžãããŒãžã£ãŒ | äŒçµ±ç㪠Python éçº |
+
+### ããã±ãŒãžãããŒãžã£ãŒã®æå®æ¹æ³
+
+奜ã¿ã®ããã±ãŒãžãããŒãžã£ãŒã¯æ¬¡ã®æ¹æ³ã§æå®ã§ããŸã:
+
+#### 1. 察話åéžæ (ããã©ã«ã)
+
+`fastkit init` ãŸã㯠`fastkit startdemo` ãå®è¡ãããšãéžæããã³ããã衚瀺ãããŸã:
+
+
+
+```console
+$ fastkit init
+# ... ãããžã§ã¯ãæ
å ±ãšã¹ã¿ãã¯ãéžæããåŸ ...
+
+Available Package Managers:
+ Package Managers
+ââââââââââ¬âââââââââââââââââââââââââââââââââââââââââââââ
+â PIP â Standard Python package manager â
+â UV â Fast Python package manager â
+â PDM â Modern Python dependency management â
+â POETRY â Python dependency management and packaging â
+ââââââââââŽâââââââââââââââââââââââââââââââââââââââââââââ
+
+Select package manager (pip, uv, pdm, poetry) [uv]: uv
+```
+
+
+
+#### 2. ã³ãã³ãã©ã€ã³ãªãã·ã§ã³
+
+察話åããã³ãããé£ã°ããããã±ãŒãžãããŒãžã£ãŒãçŽæ¥æå®ã§ããŸã:
+
+
+
+```console
+$ fastkit init --package-manager poetry
+$ fastkit startdemo --package-manager pdm
+```
+
+
+
+### çæãããäŸåé¢ä¿ãã¡ã€ã«
+
+åããã±ãŒãžãããŒãžã£ãŒã¯ããããé©åãªäŸåé¢ä¿ãã¡ã€ã«ãçæããŸã:
+
+- **UV/PDM**: `pyproject.toml` (PEP 621 圢åŒ)
+- **Poetry**: `pyproject.toml` (Poetry 圢åŒ)
+- **PIP**: `requirements.txt`
+
+## 9. 次ã®ã¹ããã
+
+ããã§ãšãããããŸã! 以äžããã¹ãŠéæããŸãã:
+
+â
æåã® FastAPI ãããžã§ã¯ããäœæ
+â
éçºãµãŒããŒãèµ·å
+â
æ°ãã API ã«ãŒãã远å
+â
API ããã¹ã
+
+### åŠç¿ãç¶ãã
+
+1. **[æåã®ãããžã§ã¯ããäœã](../tutorial/first-project.md)**: ããè€éãªããã° API ãæ§ç¯
+2. **[ãããžã§ã¯ãã®äœæ](creating-projects.md)**: æ§ã
ãªã¹ã¿ãã¯ãšãªãã·ã§ã³ãåŠã¶
+3. **[ã«ãŒãã®è¿œå ](adding-routes.md)**: API éçºã®ã¹ãã«ã身ã«ã€ãã
+4. **[ãã³ãã¬ãŒãã®å©çš](using-templates.md)**: ãããããçšæããããããžã§ã¯ããã³ãã¬ãŒãã詊ã
+
+### ããã«è©ŠããŠã¿ã
+
+次ã®ã³ãã³ãã§ãããå€ãã®æ©èœãæ¢çŽ¢ã§ããŸã:
+
+
+
+```console
+# å©çšå¯èœãªãã³ãã¬ãŒãäžèЧ
+$ fastkit list-templates
+
+# ãã³ãã¬ãŒããããããžã§ã¯ããçæ
+$ fastkit startdemo
+
+# ã«ãŒããããã«è¿œå (ã«ãŒãåãå
ããããžã§ã¯ããã£ã¬ã¯ããªãåŸ)
+$ fastkit addroute products my-first-app
+$ fastkit addroute orders my-first-app
+```
+
+
+
+!!! tip "éçºã®ãã³ã"
+ - ãã¡ã€ã«ã倿ŽãããšãµãŒããŒãèªåçã«åèªã¿èŸŒã¿ãããŸã
+ - æ°æ©èœã远å ãããã³ã« `/docs` ã§å¯Ÿè©±åããã¥ã¡ã³ãã確èªããŸããã
+ - äŸåé¢ä¿ã®åé¢ã®ããã«ä»®æ³ç°å¢ã掻çšããŸããã
+ - çæãããã³ãŒããèªãã§ãããžã§ã¯ãæ§é ãçè§£ããŸããã
diff --git a/docs/ja/user-guide/using-templates.md b/docs/ja/user-guide/using-templates.md
new file mode 100644
index 0000000..1b4df25
--- /dev/null
+++ b/docs/ja/user-guide/using-templates.md
@@ -0,0 +1,608 @@
+# ãã³ãã¬ãŒãã®å©çš
+
+FastAPI-fastkit ã¯ãããŸããŸãªæè¡ã¹ã¿ãã¯ã§ãã°ããéçºãå§ããããããããããããçšæããããããžã§ã¯ããã³ãã¬ãŒããæäŸããŠããŸãã
+
+## å©çšå¯èœãªãã³ãã¬ãŒã
+
+`list-templates` ã³ãã³ãã§å©çšå¯èœãªãã³ãã¬ãŒãã確èªã§ããŸã:
+
+
+
+```console
+$ fastkit list-templates
+ Available Templates
+âââââââââââââââââââââââââââ¬ââââââââââââââââââââââââââââââââââââ
+â fastapi-custom-response â Async Item Management API with â
+â â Custom Response System â
+â fastapi-dockerized â Dockerized FastAPI Item â
+â â Management API â
+â fastapi-empty â No description â
+â fastapi-async-crud â Async Item Management API Server â
+â fastapi-psql-orm â Dockerized FastAPI Item â
+â â Management API with PostgreSQL â
+â fastapi-default â Simple FastAPI Project â
+âââââââââââââââââââââââââââŽââââââââââââââââââââââââââââââââââââ
+```
+
+
+
+## ãã³ãã¬ãŒãã®èª¬æ
+
+### 1. `fastapi-default`
+
+**ã·ã³ãã«ãª FastAPI ãããžã§ã¯ã**
+
+- å¿
èŠååãªæ©èœãåããåºæ¬ç㪠FastAPI ã»ããã¢ãã
+- ã¢ãã¯ããŒã¿ã䜿ã£ãã¢ã€ãã 管ç
+- åŠç¿ãã·ã³ãã«ãª API ã«æé©
+- åºæ¬ç㪠CRUD æäœãå«ã
+
+**é©ããçšé:**
+
+- FastAPI ã®åå¿è
+- ã·ã³ãã«ãª Web API
+- åŠç¿ããããã¿ã€ãã³ã°
+
+### 2. `fastapi-async-crud`
+
+**éåæã¢ã€ãã 管ç API ãµãŒããŒ**
+
+- å®å
šã«éåæãª FastAPI ã¢ããªã±ãŒã·ã§ã³
+- async / await ã䜿ã£ãé«åºŠãª CRUD æäœ
+- I/O æäœã®ããã©ãŒãã³ã¹åäž
+- éåæãã¿ãŒã³ãçšããã¢ãã¯ããŒã¿ã¹ãã¬ãŒãž
+
+**é©ããçšé:**
+
+- é«ããã©ãŒãã³ã¹ã¢ããªã±ãŒã·ã§ã³
+- I/O éçŽçãªåŠç
+- ã¢ãã³ãªéåæ Python éçº
+
+### 3. `fastapi-custom-response`
+
+**ã«ã¹ã¿ã ã¬ã¹ãã³ã¹æ©æ§ãåããéåæã¢ã€ãã 管ç API**
+
+- ã«ã¹ã¿ã ã¬ã¹ãã³ã¹ã¢ãã«ãšãã©ãŒããã
+- é«åºŠãªãšã©ãŒãã³ããªã³ã°
+- ããŒãžããŒã·ã§ã³å¯Ÿå¿
+- ã«ã¹ã¿ã HTTP ã¹ããŒã¿ã¹ã³ãŒããšã¬ã¹ãã³ã¹
+
+**é©ããçšé:**
+
+- ç¹å®ã®ã¬ã¹ãã³ã¹åœ¢åŒãèŠæ±ããã API
+- é«åºŠãªãšã©ãŒãã³ããªã³ã°ãå¿
èŠãªå Žé¢
+- ã¬ã¹ãã³ã¹ã«ã«ã¹ã¿ã ããžãã¹ããžãã¯ãå«ããå Žå
+
+### 4. `fastapi-dockerized`
+
+**Docker åããã FastAPI ã¢ã€ãã 管ç API**
+
+- å®å
šãª Docker ã³ã³ããå
+- æ¬çªéçšåãã®ãããã€æ§æ
+- ãã«ãã¹ããŒãž Docker ãã«ã
+- ç°å¢ããŒã¹ã®èšå®
+
+**é©ããçšé:**
+
+- æ¬çªãããã€
+- ã³ã³ããåãããç°å¢
+- DevOps ãš CI/CD ãã€ãã©ã€ã³
+
+### 5. `fastapi-psql-orm`
+
+**PostgreSQL 察å¿ã® Docker åããã FastAPI ã¢ã€ãã 管ç API**
+
+- PostgreSQL ããŒã¿ããŒã¹çµ±å
+- SQLAlchemy ORM ãš Alembic ãã€ã°ã¬ãŒã·ã§ã³
+- ããŒã«ã«éçºã®ããã® Docker Compose
+- ãã«æ©èœã®ããŒã¿ããŒã¹ CRUD æäœ
+
+**é©ããçšé:**
+
+- ããŒã¿ããŒã¹é§åã®ã¢ããªã±ãŒã·ã§ã³
+- æ¬çªå質ã®ããŒã¿ã¹ãã¬ãŒãž
+- è€éãªããŒã¿ãªã¬ãŒã·ã§ã³ã·ãã
+
+### 6. `fastapi-empty`
+
+**æå°æ§æã® FastAPI ãããžã§ã¯ã**
+
+- å¿
èŠæå°éã® FastAPI ã»ããã¢ãã
+- ãããããçšæãããæ©èœã¯ãããŸãã
+- ã«ã¹ã¿ã éçºã®ããã®ãŸã£ãããªã¹ã¿ãŒã
+
+**é©ããçšé:**
+
+- ãŒãããå§ãã
+- æå°éã®äŸåé¢ä¿
+- ç¬èªã®ã¢ãŒããã¯ãã£èŠä»¶
+
+## ãã³ãã¬ãŒããããããžã§ã¯ããäœæãã
+
+`startdemo` ã³ãã³ãã§ãã³ãã¬ãŒããããããžã§ã¯ããäœæããŸã:
+
+
+
+```console
+$ fastkit startdemo
+Enter the project name: my-blog-api
+Enter the author name: John Doe
+Enter the author email: john@example.com
+Enter the project description: Blog API with PostgreSQL
+
+Available Templates:
+ fastapi-default
+âââââââââââââââ¬âââââââââââââââââââââââ
+â Description â Simple FastAPI â
+â â Project â
+â Stack â FastAPI, Uvicorn â
+â Database â Mock Data â
+â Features â Basic CRUD â
+âââââââââââââââŽâââââââââââââââââââââââ
+
+ fastapi-psql-orm
+âââââââââââââââ¬âââââââââââââââââââââââ
+â Description â Dockerized FastAPI â
+â â Item Management API â
+â â with PostgreSQL â
+â Stack â FastAPI, PostgreSQL, â
+â â SQLAlchemy, Docker â
+â Database â PostgreSQL â
+â Features â Full ORM, Migrations â
+âââââââââââââââŽâââââââââââââââââââââââ
+
+Select template (fastapi-default, fastapi-async-crud, fastapi-custom-response, fastapi-dockerized, fastapi-psql-orm, fastapi-empty): fastapi-psql-orm
+
+ Project Information
+ââââââââââââââââ¬ââââââââââââââââââââââ
+â Project Name â my-blog-api â
+â Author â John Doe â
+â Author Email â john@example.com â
+â Description â Blog API with â
+â â PostgreSQL â
+ââââââââââââââââŽââââââââââââââââââââââ
+
+ Template Dependencies
+ââââââââââââââââ¬ââââââââââââââââââââ
+â Dependency 1 â fastapi â
+â Dependency 2 â uvicorn â
+â Dependency 3 â sqlalchemy â
+â Dependency 4 â alembic â
+â Dependency 5 â psycopg2-binary â
+â Dependency 6 â python-dotenv â
+â Dependency 7 â pytest â
+ââââââââââââââââŽââââââââââââââââââââ
+
+Available Package Managers:
+ Package Managers
+ââââââââââ¬âââââââââââââââââââââââââââââââââââââââââââââ
+â PIP â Standard Python package manager â
+â UV â Fast Python package manager â
+â PDM â Modern Python dependency management â
+â POETRY â Python dependency management and packaging â
+ââââââââââŽâââââââââââââââââââââââââââââââââââââââââââââ
+
+Select package manager (pip, uv, pdm, poetry) [uv]: uv
+Do you want to proceed with project creation? [y/N]: y
+
+âš FastAPI project 'my-blog-api' from 'fastapi-psql-orm' has been created successfully!
+```
+
+
+
+## ãã³ãã¬ãŒãã®æ©èœæ¯èŒ
+
+| æ©èœ | Default | Async CRUD | Custom Response | Dockerized | PostgreSQL ORM | Empty |
+|---|---|---|---|---|---|---|
+| **åºæ¬ FastAPI** | â
| â
| â
| â
| â
| â
|
+| **ã¢ãã¯ããŒã¿** | â
| â
| â
| â
| â | â |
+| **éåæãµããŒã** | åºæ¬ | â
| â
| â
| â
| â |
+| **ã«ã¹ã¿ã ã¬ã¹ãã³ã¹** | â | â | â
| â | â | â |
+| **Docker** | â | â | â | â
| â
| â |
+| **ããŒã¿ããŒã¹** | ã¢ã㯠| ã¢ã㯠| ã¢ã㯠| ã¢ã㯠| PostgreSQL | ãªã |
+| **ORM** | â | â | â | â | SQLAlchemy | â |
+| **ãã€ã°ã¬ãŒã·ã§ã³** | â | â | â | â | Alembic | â |
+| **ãã¹ã** | â
| â
| â
| â
| â
| â |
+| **é©ããçšé** | åŠç¿ | ããã©ãŒãã³ã¹ | ã«ã¹ã¿ã API | æ¬çªéçš | DB ã¢ã㪠| ã«ã¹ã¿ã |
+
+## ãã³ãã¬ãŒãããšã®ã»ããã¢ãã
+
+### `fastapi-psql-orm` ã䜿ã
+
+ãã®ãã³ãã¬ãŒã㯠PostgreSQL ã®ãã«ã»ããã¢ãããå«ã¿ãŸããäœæåŸ:
+
+1. **Docker ã§ PostgreSQL ãèµ·å:**
+
+
+
+```console
+$ cd my-blog-api
+$ docker-compose up -d postgres
+Starting my-blog-api_postgres_1 ... done
+```
+
+
+
+2. **ããŒã¿ããŒã¹ãã€ã°ã¬ãŒã·ã§ã³ãå®è¡:**
+
+
+
+```console
+$ source .venv/bin/activate
+$ alembic upgrade head
+INFO [alembic.runtime.migration] Context impl PostgresqlImpl.
+INFO [alembic.runtime.migration] Will assume transactional DDL.
+INFO [alembic.runtime.migration] Running upgrade -> bedcdc35b64a, first alembic
+```
+
+
+
+3. **API ãµãŒããŒãèµ·å:**
+
+
+
+```console
+$ fastkit runserver
+INFO: Uvicorn running on http://127.0.0.1:8000
+```
+
+
+
+### `fastapi-dockerized` ã䜿ã
+
+ãã®ãã³ãã¬ãŒã㯠Docker ã®ãã«æ©èœãæäŸããŸã:
+
+1. **Docker ã€ã¡ãŒãžã®ãã«ã:**
+
+
+
+```console
+$ cd my-dockerized-api
+$ docker build -t my-dockerized-api .
+Successfully built abc123def456
+Successfully tagged my-dockerized-api:latest
+```
+
+
+
+2. **ã³ã³ããã®èµ·å:**
+
+
+
+```console
+$ docker run -p 8000:8000 my-dockerized-api
+INFO: Uvicorn running on http://0.0.0.0:8000
+```
+
+
+
+### `fastapi-custom-response` ã䜿ã
+
+ãã®ãã³ãã¬ãŒãã«ã¯é«åºŠãªã¬ã¹ãã³ã¹åŠçãå«ãŸããŠããŸã:
+
+1. **ã«ã¹ã¿ã ã¬ã¹ãã³ã¹ã¢ãã«:**
+
+```python
+from src.helper.pagination import PaginatedResponse
+from src.schemas.base import StandardResponse
+
+@router.get("/", response_model=PaginatedResponse[Item])
+def read_items(skip: int = 0, limit: int = 10):
+ items = items_crud.get_multi(skip=skip, limit=limit)
+ total = items_crud.count()
+
+ return PaginatedResponse(
+ data=items,
+ total=total,
+ page=skip // limit + 1,
+ pages=(total + limit - 1) // limit
+ )
+
+@router.post("/", response_model=StandardResponse[Item])
+def create_item(item: ItemCreate):
+ new_item = items_crud.create(item)
+ return StandardResponse(
+ data=new_item,
+ message="Item created successfully",
+ status_code=201
+ )
+```
+
+2. **æ¡åŒµããããšã©ãŒãã³ããªã³ã°:**
+
+```python
+from src.helper.exceptions import ItemNotFoundError, ValidationError
+
+@router.get("/{item_id}", response_model=StandardResponse[Item])
+def read_item(item_id: int):
+ try:
+ item = items_crud.get(item_id)
+ return StandardResponse(data=item)
+ except ItemNotFoundError:
+ raise HTTPException(
+ status_code=404,
+ detail=f"Item with id {item_id} not found"
+ )
+```
+
+## ãã³ãã¬ãŒãã®ãããžã§ã¯ãæ§é
+
+åãã³ãã¬ãŒãã¯äžè²«ãããããããã³ãã¬ãŒãããšã«èª¿æŽãããæ§é ãæã¡ãŸã:
+
+### `fastapi-default` ã®æ§é
+```
+my-project/
+âââ src/
+â âââ main.py
+â âââ core/config.py
+â âââ api/
+â â âââ api.py
+â â âââ routes/items.py
+â âââ crud/items.py
+â âââ schemas/items.py
+â âââ mocks/mock_items.json
+âââ tests/
+âââ scripts/
+âââ requirements.txt
+```
+
+### `fastapi-psql-orm` ã®æ§é
+```
+my-project/
+âââ src/
+â âââ main.py
+â âââ core/
+â â âââ config.py
+â â âââ db.py
+â âââ api/
+â â âââ api.py
+â â âââ deps.py
+â â âââ routes/items.py
+â âââ crud/items.py
+â âââ schemas/items.py
+â âââ alembic/
+â â âââ env.py
+â â âââ versions/
+â âââ utils/
+âââ tests/
+âââ scripts/
+âââ docker-compose.yml
+âââ Dockerfile
+âââ alembic.ini
+âââ requirements.txt
+```
+
+## ãã³ãã¬ãŒãã®ã«ã¹ã¿ãã€ãº
+
+ãã³ãã¬ãŒããããããžã§ã¯ããäœæããåŸãå¿
èŠã«å¿ããŠã«ã¹ã¿ãã€ãºã§ããŸã:
+
+### 1. æ°ããã«ãŒãã远å
+
+
+
+```console
+$ fastkit addroute posts my-blog-api
+$ fastkit addroute users my-blog-api
+$ fastkit addroute comments my-blog-api
+```
+
+
+
+### 2. èšå®ã®å€æŽ
+
+`src/core/config.py` ãç·šéããŠããŒãºã«åãããŸã:
+
+```python
+from pydantic_settings import BaseSettings
+
+class Settings(BaseSettings):
+ PROJECT_NAME: str = "My Blog API"
+ VERSION: str = "1.0.0"
+ API_V1_STR: str = "/api/v1"
+
+ # Database settings (for PostgreSQL templates)
+ DATABASE_URL: str = "postgresql://user:password@localhost/dbname"
+
+ # Security settings
+ SECRET_KEY: str = "your-secret-key-here"
+ ACCESS_TOKEN_EXPIRE_MINUTES: int = 30
+
+ class Config:
+ env_file = ".env"
+
+settings = Settings()
+```
+
+### 3. ç°å¢å€æ°ã®è¿œå
+
+ãããžã§ã¯ãã«ãŒãã« `.env` ãã¡ã€ã«ãäœæããŸã:
+
+```env
+# .env
+PROJECT_NAME=My Blog API
+VERSION=1.0.0
+DEBUG=True
+
+# Database (for PostgreSQL templates)
+DATABASE_URL=postgresql://user:password@localhost:5432/myblogdb
+POSTGRES_USER=user
+POSTGRES_PASSWORD=password
+POSTGRES_DB=myblogdb
+
+# Security
+SECRET_KEY=your-super-secret-key-here
+ACCESS_TOKEN_EXPIRE_MINUTES=30
+```
+
+## ãã³ãã¬ãŒãã®ãã¹ã
+
+åãã³ãã¬ãŒãã¯ãããããæ§æããããã¹ããåããŠããŸã:
+
+
+
+```console
+$ cd my-blog-api
+$ source .venv/bin/activate
+$ python -m pytest
+
+======================== test session starts ========================
+tests/test_items.py::test_create_item PASSED
+tests/test_items.py::test_read_items PASSED
+tests/test_items.py::test_read_item PASSED
+tests/test_items.py::test_update_item PASSED
+tests/test_items.py::test_delete_item PASSED
+======================== 5 passed in 0.23s ========================
+```
+
+
+
+## ãã³ãã¬ãŒãéçºã®ã¯ãŒã¯ãããŒ
+
+### 1. é©åãªãã³ãã¬ãŒããéžã¶
+
+- **åŠç¿ / ã·ã³ãã«ãª API**: `fastapi-default`
+- **é«ããã©ãŒãã³ã¹**: `fastapi-async-crud`
+- **ã«ã¹ã¿ã ã¬ã¹ãã³ã¹åœ¢åŒ**: `fastapi-custom-response`
+- **æ¬çªãããã€**: `fastapi-dockerized`
+- **ããŒã¿ããŒã¹ã¢ããªã±ãŒã·ã§ã³**: `fastapi-psql-orm`
+- **ç¬èªã¢ãŒããã¯ãã£**: `fastapi-empty`
+
+### 2. äœæãšã»ããã¢ãã
+
+
+
+```console
+$ fastkit startdemo
+# ããã³ããã«åŸã
+$ cd your-project
+$ source .venv/bin/activate
+```
+
+
+
+### 3. éçº
+
+
+
+```console
+# éçºãµãŒããŒãèµ·å
+$ fastkit runserver
+
+# ãã¹ããå®è¡
+$ python -m pytest
+
+# æ°æ©èœã远å
+$ fastkit addroute new-resource your-project
+```
+
+
+
+### 4. ãããã€
+
+æ¬çªåããã³ãã¬ãŒã (`fastapi-dockerized`ã`fastapi-psql-orm`) ã®å Žå:
+
+
+
+```console
+# æ¬çªãã«ã
+$ docker build -t your-app .
+
+# Docker Compose ã§ãããã€
+$ docker-compose up -d
+```
+
+
+
+## ãã¹ããã©ã¯ãã£ã¹
+
+### 1. ãã³ãã¬ãŒããè³¢ãéžã¶
+
+- åŠç¿ã«ã¯ã·ã³ãã«ãªãã³ãã¬ãŒãããå§ãã
+- ããŒã¿é§ååã¢ããªã«ã¯ããŒã¿ããŒã¹å¯Ÿå¿ã®ãã³ãã¬ãŒã
+- æ¬çªãããã€ã«ã¯ Docker 察å¿ãã³ãã¬ãŒã
+
+### 2. ç°å¢ç®¡ç
+
+- èšå®ã«ã¯åžžã« `.env` ãã¡ã€ã«ã䜿ã
+- æ©å¯ããŒã¿ã¯ããŒãžã§ã³ç®¡çã«ã³ãããããªã
+- éçºãšæ¬çªã§ç°ãªãç°å¢ã䜿ã
+
+### 3. ã«ã¹ã¿ãã€ãºã®æ¹é
+
+- æ°ããã«ãŒã㯠`fastkit addroute` ã§è¿œå
+- æ¢åã³ãŒãã¯èªåã®ããžãã¹ããžãã¯ã«åãããŠå€æŽ
+- ãããžã§ã¯ãæ§é ã¯æŽçãããç¶æ
ãç¶æ
+
+### 4. ãã¹ã
+
+- éçºäžã¯å®æçã«ãã¹ããå®è¡
+- å®è£
ããæ°æ©èœã«ã¯ãã¹ãã远å
+- 忢±ã®ãã¹ãæ§é ãã¬ã€ããšããŠæŽ»çš
+
+## ãã©ãã«ã·ã¥ãŒãã£ã³ã°
+
+### ããŒã¿ããŒã¹æ¥ç¶ã®åé¡ (PostgreSQL ãã³ãã¬ãŒã)
+
+PostgreSQL ã«æ¥ç¶ã§ããªãå Žå:
+
+1. **Docker ãåäœããŠããã確èª:**
+
+
+ ```console
+ $ docker ps
+ ```
+
+
+2. **PostgreSQL ã³ã³ããã確èª:**
+
+
+ ```console
+ $ docker-compose logs postgres
+ ```
+
+
+3. **ç°å¢å€æ°ã確èª:**
+
+ ```env
+ DATABASE_URL=postgresql://user:password@localhost:5432/dbname
+ ```
+
+### Docker ãã«ãã®å€±æ
+
+Docker ãã«ãã«å€±æããå Žå:
+
+1. **Dockerfile ã®æ§æã確èª**
+2. **å¿
èŠãªãã¡ã€ã«ããã¹ãŠååšããã確èª**
+3. **Docker ããŒã¢ã³ãåäœããŠããã確èª**
+
+### äŸåé¢ä¿ãèŠã€ãããªã
+
+import ãšã©ãŒãåºãå Žå:
+
+1. **ä»®æ³ç°å¢ãæå¹å:**
+
+ ```console
+ $ source .venv/bin/activate
+ ```
+
+
+2. **äŸåé¢ä¿ãã€ã³ã¹ããŒã«:**
+
+ ```console
+ $ pip install -r requirements.txt
+ ```
+
+
+## 次ã®ã¹ããã
+
+ãã³ãã¬ãŒããçè§£ã§ããã:
+
+1. **[æåã®ãããžã§ã¯ã](../tutorial/first-project.md)**: å®å
šãªã¢ããªã±ãŒã·ã§ã³ãæ§ç¯
+2. **[ã«ãŒãã®è¿œå ](adding-routes.md)**: ãã³ãã¬ãŒãããŒã¹ã®ãããžã§ã¯ããæ¡åŒµ
+3. **[CLI ãªãã¡ã¬ã³ã¹](cli-reference.md)**: å©çšå¯èœãªãã¹ãŠã®ã³ãã³ããç¿åŸ
+
+!!! tip "ãã³ãã¬ãŒãã®ãã³ã"
+ - ãã³ãã¬ãŒãã¯åºçºç¹ã§ãã£ãŠæçµçãªè§£ã§ã¯ãããŸãã
+ - èªåã®èŠä»¶ã«åãããŠãã³ãã¬ãŒããã«ã¹ã¿ãã€ãºããŸããã
+ - ãã³ãã¬ãŒãã®ã³ãŒããèªã¿ãFastAPI ã®ãã¹ããã©ã¯ãã£ã¹ãåŠã³ãŸããã
+ - èªåã®ã«ã¹ã¿ãã€ãºã远ããããããŒãžã§ã³ç®¡çãæŽ»çšããŸããã
diff --git a/docs/ko/reference/translation-status.md b/docs/ko/reference/translation-status.md
index f73f7d4..3de70f9 100644
--- a/docs/ko/reference/translation-status.md
+++ b/docs/ko/reference/translation-status.md
@@ -20,13 +20,13 @@ FastAPI-fastkit 묞ìë ì¬ë¬ ìžìŽë¡ ë¹ëëì§ë§, 몚ë ë²ììŽ **
|---|---|---:|---|
| ð¬ð§ English (`en`) | â
ì볞 | 26 / 26 | êž°ì€ìŽ ëë ì묞ì
ëë€. |
| ð°ð· íêµìŽ (`ko`) | â
ìë£ | 26 / 26 | ìžìŽë³ íìŽì§ë 몚ë 졎ì¬í©ëë€. Phase 1: ìµìì + íµì¬ user-guide, Phase 2: ëëšžì§ user-guide + 몚ë tutorial, Phase 3: contributing + reference. `docs/ko/changelog.md` ë ì묞 êž°ì€ `CHANGELOG.md` 륌 ê·žëë¡ ì¬ì©í©ëë€. |
-| ð¯ðµ ìŒë³žìŽ (`ja`) | ðŽ êž°ë³ž êµ¬ì¡°ë§ ìì | 0 / 26 | ë¹ë ëìë§ ì€ì ëìŽ ììŒë©°, 몚ë íìŽì§ë ììŽ ì묞ìŒë¡ íìë©ëë€. |
+| ð¯ðµ ìŒë³žìŽ (`ja`) | â
ìë£ | 26 / 26 | ìžìŽë³ íìŽì§ë 몚ë 졎ì¬í©ëë€. Phase 1: ìµìì + íµì¬ user-guide, Phase 2: ëëšžì§ user-guide + 몚ë tutorial, Phase 3: contributing + reference. `docs/ja/changelog.md` ë ì묞 êž°ì€ `CHANGELOG.md` 륌 ê·žëë¡ ì¬ì©í©ëë€. |
| ðšð³ ì€êµìŽ (`zh`) | ðŽ êž°ë³ž êµ¬ì¡°ë§ ìì | 0 / 26 | ë¹ë ëìë§ ì€ì ëìŽ ììŒë©°, 몚ë íìŽì§ë ììŽ ì묞ìŒë¡ íìë©ëë€. |
| ðªðž ì€íìžìŽ (`es`) | ðŽ êž°ë³ž êµ¬ì¡°ë§ ìì | 0 / 26 | ë¹ë ëìë§ ì€ì ëìŽ ììŒë©°, 몚ë íìŽì§ë ììŽ ì묞ìŒë¡ íìë©ëë€. |
| ð«ð· íëì€ìŽ (`fr`) | ðŽ êž°ë³ž êµ¬ì¡°ë§ ìì | 0 / 26 | ë¹ë ëìë§ ì€ì ëìŽ ììŒë©°, 몚ë íìŽì§ë ììŽ ì묞ìŒë¡ íìë©ëë€. |
| ð©ðª ë
ìŒìŽ (`de`) | ðŽ êž°ë³ž êµ¬ì¡°ë§ ìì | 0 / 26 | ë¹ë ëìë§ ì€ì ëìŽ ììŒë©°, 몚ë íìŽì§ë ììŽ ì묞ìŒë¡ íìë©ëë€. |
-*ì€ë
ì· ê²ìŠ ìì : 2026-05-07. Phase 3(contributing + reference) ìì
ìŽ ë°ìë íì¬ ëžëì¹ êž°ì€ìŒë¡ `ko` íì ë€ì ì§ê³íìµëë€. íêµìŽë ìžìŽë³ íìŽì§ê° 몚ë 졎ì¬íë©°, `docs/ko/changelog.md` ë ì묞 êž°ì€ changelog륌 ê·žëë¡ ê°ëЬíµëë€.* ìŽ íë ìëìŒë¡ êŽëЬë©ëë€. 늬í¬ì§í 늬 룚ížìì íì¬ ìí륌 ë€ì ìžê³ ì¶ë€ë©Ž ë€ì ëª
ë ¹ì ì€ííìžì:
+*ì€ë
ì· ê²ìŠ ìì : 2026-05-10. Phase 3(contributing + reference) ìì
ìŽ ë°ìë íì¬ ëžëì¹ êž°ì€ìŒë¡ `ja` íì ë€ì ì§ê³íìµëë€. ìŒë³žìŽë ìžìŽë³ íìŽì§ê° 몚ë 졎ì¬íë©°, `docs/ja/changelog.md` ë ì묞 êž°ì€ changelog륌 ê·žëë¡ ê°ëЬíµëë€.* ìŽ íë ìëìŒë¡ êŽëЬë©ëë€. 늬í¬ì§í 늬 룚ížìì íì¬ ìí륌 ë€ì ìžê³ ì¶ë€ë©Ž ë€ì ëª
ë ¹ì ì€ííìžì:
```console
$ for loc in en ko ja zh es fr de; do