from datetime import datetime from fastapi import APIRouter, Depends, HTTPException from pydantic import BaseModel from sqlalchemy.orm import Session as DBSession from app.core.notes import next_position, rename_section, set_section from app.db.database import get_db from app.db.models import NotePage router = APIRouter(prefix="/api/notes", tags=["notes"]) class NotePageResponse(BaseModel): id: int title: str content: str position: int section: str | None updated_at: datetime class Config: from_attributes = True class NotePageCreate(BaseModel): title: str = "新しいページ" content: str = "" section: str | None = None class NotePageUpdate(BaseModel): title: str | None = None content: str | None = None section: str | None = None class SectionRenameRequest(BaseModel): old_name: str new_name: str | None = None @router.get("", response_model=list[NotePageResponse]) def list_pages(db: DBSession = Depends(get_db)): return db.query(NotePage).order_by(NotePage.position, NotePage.id).all() @router.post("", response_model=NotePageResponse, status_code=201) def create_page(req: NotePageCreate, db: DBSession = Depends(get_db)): title = req.title.strip() or "新しいページ" page = NotePage(title=title, content=req.content, position=next_position(db)) db.add(page) db.commit() db.refresh(page) if req.section is not None and req.section.strip(): page = set_section(db, page.id, req.section) return page @router.post("/sections/rename") def rename_section_endpoint(req: SectionRenameRequest, db: DBSession = Depends(get_db)): """old_name セクションに属する全ページを new_name セクションへ一括で付け替える。new_name が空ならグループ解除。""" count = rename_section(db, req.old_name, req.new_name) return {"renamed": count} @router.patch("/{page_id}", response_model=NotePageResponse) def update_page(page_id: int, req: NotePageUpdate, db: DBSession = Depends(get_db)): page = db.get(NotePage, page_id) if not page: raise HTTPException(status_code=404, detail="Note page not found") if req.title is not None: title = req.title.strip() if not title: raise HTTPException(status_code=400, detail="title is empty") page.title = title if req.content is not None: page.content = req.content db.commit() db.refresh(page) # section はページの並び順にも影響するため、変更があれば専用ロジックで反映する if "section" in req.model_fields_set: page = set_section(db, page_id, req.section) return page @router.delete("/{page_id}", status_code=204) def delete_page(page_id: int, db: DBSession = Depends(get_db)): page = db.get(NotePage, page_id) if not page: raise HTTPException(status_code=404, detail="Note page not found") db.delete(page) db.commit()