import uuid from typing import Any, Dict, List, Union from sqlalchemy import or_ from sqlalchemy.orm import Session from app.crud.base import CRUDBase from app.models.note import Note from app.models.note_tag import NoteTag from app.schemas.note import NoteCreate, NoteUpdate class CRUDNote(CRUDBase[Note, NoteCreate, NoteUpdate]): def get_multi_by_user( self, db: Session, *, user_id: str, skip: int = 0, limit: int = 100, archived: bool = False ) -> List[Note]: """ Get multiple notes for a specific user. """ return ( db.query(self.model) .filter(Note.user_id == user_id, Note.is_archived == archived) .order_by(Note.is_pinned.desc(), Note.created_at.desc()) .offset(skip) .limit(limit) .all() ) def create_with_user( self, db: Session, *, obj_in: NoteCreate, user_id: str ) -> Note: """ Create a new note for a specific user. """ note_id = str(uuid.uuid4()) db_obj = Note( id=note_id, title=obj_in.title, content=obj_in.content, is_archived=obj_in.is_archived, is_pinned=obj_in.is_pinned, user_id=user_id, ) db.add(db_obj) db.commit() db.refresh(db_obj) # Add tags if provided if obj_in.tag_ids: for tag_id in obj_in.tag_ids: note_tag = NoteTag( id=str(uuid.uuid4()), note_id=note_id, tag_id=tag_id, ) db.add(note_tag) db.commit() db.refresh(db_obj) return db_obj def update_note_tags( self, db: Session, *, db_obj: Note, tag_ids: List[str] ) -> Note: """ Update the tags associated with a note. """ # Remove all existing tags db.query(NoteTag).filter(NoteTag.note_id == db_obj.id).delete() # Add new tags for tag_id in tag_ids: note_tag = NoteTag( id=str(uuid.uuid4()), note_id=db_obj.id, tag_id=tag_id, ) db.add(note_tag) db.commit() db.refresh(db_obj) return db_obj def update( self, db: Session, *, db_obj: Note, obj_in: Union[NoteUpdate, Dict[str, Any]] ) -> Note: """ Update a note. """ if isinstance(obj_in, dict): update_data = obj_in tag_ids = update_data.pop("tag_ids", None) else: update_data = obj_in.dict(exclude_unset=True) tag_ids = update_data.pop("tag_ids", None) if hasattr(obj_in, "tag_ids") else None # Update the note obj = super().update(db, db_obj=db_obj, obj_in=update_data) # Update tags if provided if tag_ids is not None: self.update_note_tags(db, db_obj=obj, tag_ids=tag_ids) db.refresh(obj) return obj def search_notes( self, db: Session, *, user_id: str, query: str, skip: int = 0, limit: int = 100 ) -> List[Note]: """ Search for notes by title or content. """ search_term = f"%{query}%" return ( db.query(self.model) .filter( Note.user_id == user_id, or_( Note.title.ilike(search_term), Note.content.ilike(search_term) ) ) .order_by(Note.created_at.desc()) .offset(skip) .limit(limit) .all() ) note = CRUDNote(Note)