"""Service for managing card positioning and reordering""" from app import db from app.models import Card class CardPositionService: """Service for handling card position management""" @staticmethod def reorder_cards_in_list( list_id: int, moved_card_id: int, new_position: float ) -> None: """ Reorder all cards in a list when one card is moved to a new position. Args: list_id: The ID of the list containing the cards moved_card_id: The ID of the card being moved new_position: The new position for the moved card """ # Get all cards in the list, ordered by their current position all_cards = Card.query.filter_by(list_id=list_id).order_by(Card.pos).all() # Find the moved card in the list moved_card = None other_cards = [] for card in all_cards: if card.id == moved_card_id: moved_card = card else: other_cards.append(card) if not moved_card: return # Card not found in this list # Remove the moved card from other_cards (already done above) # Insert the moved card at the new position in other_cards other_cards.insert(int(new_position), moved_card) # Update positions for all cards to ensure unique, sequential positions for index, card in enumerate(other_cards): card.pos = float(index) db.session.commit() @staticmethod def reorder_cards_between_lists( from_list_id: int, to_list_id: int, moved_card_id: int, new_position: float ) -> None: """ Reorder cards when moving a card from one list to another. Args: from_list_id: The source list ID to_list_id: The destination list ID moved_card_id: The ID of the card being moved new_position: The new position in the destination list """ # Reorder source list (remove the card and compact positions) source_cards = ( Card.query.filter_by(list_id=from_list_id) .filter(Card.id != moved_card_id) .order_by(Card.pos) .all() ) for index, card in enumerate(source_cards): card.pos = float(index) # Reorder destination list (insert the card at new position) dest_cards = Card.query.filter_by(list_id=to_list_id).order_by(Card.pos).all() # Insert moved card at the specified position dest_cards.insert(int(new_position), None) # Placeholder for moved card for index, card in enumerate(dest_cards): if card is None: # This is where our moved card should go moved_card = db.session.get(Card, moved_card_id) if moved_card: moved_card.pos = float(index) else: card.pos = float(index) db.session.commit() @staticmethod def get_next_position(list_id: int) -> float: """ Get the next available position in a list. Args: list_id: The ID of the list Returns: The next available position (float) """ last_card = ( Card.query.filter_by(list_id=list_id).order_by(Card.pos.desc()).first() ) return float(last_card.pos + 1) if last_card else 0.0 @staticmethod def ensure_unique_positions(list_id: int) -> None: """ Ensure all cards in a list have unique, sequential positions. Useful for data cleanup. Args: list_id: The ID of the list to fix """ cards = Card.query.filter_by(list_id=list_id).order_by(Card.pos).all() for index, card in enumerate(cards): card.pos = float(index) db.session.commit()