206 lines
5.6 KiB
Python
206 lines
5.6 KiB
Python
from fastapi import APIRouter, Depends, HTTPException, status
|
|
from sqlalchemy.orm import Session
|
|
from sqlalchemy import func
|
|
from typing import List
|
|
from app.db.base import get_db
|
|
from app.core.deps import get_current_user
|
|
from app.models.user import User
|
|
from app.models.list import List as ContactList, ListMember
|
|
from app.models.contact import Contact
|
|
from app.schemas.list import (
|
|
ListCreate, ListUpdate, ListResponse,
|
|
ListMemberAdd, ListMemberRemove
|
|
)
|
|
|
|
router = APIRouter()
|
|
|
|
@router.post("", response_model=ListResponse, status_code=status.HTTP_201_CREATED)
|
|
def create_list(
|
|
list_data: ListCreate,
|
|
current_user: User = Depends(get_current_user),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
db_list = ContactList(
|
|
user_id=current_user.id,
|
|
name=list_data.name
|
|
)
|
|
db.add(db_list)
|
|
db.commit()
|
|
db.refresh(db_list)
|
|
|
|
db_list.member_count = 0
|
|
return db_list
|
|
|
|
@router.get("", response_model=List[ListResponse])
|
|
def list_lists(
|
|
current_user: User = Depends(get_current_user),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
lists = db.query(ContactList).filter(ContactList.user_id == current_user.id).all()
|
|
|
|
# Add member counts
|
|
for lst in lists:
|
|
count = db.query(func.count(ListMember.id)).filter(
|
|
ListMember.list_id == lst.id
|
|
).scalar()
|
|
lst.member_count = count or 0
|
|
|
|
return lists
|
|
|
|
@router.get("/{list_id}", response_model=ListResponse)
|
|
def get_list(
|
|
list_id: int,
|
|
current_user: User = Depends(get_current_user),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
lst = db.query(ContactList).filter(
|
|
ContactList.id == list_id,
|
|
ContactList.user_id == current_user.id
|
|
).first()
|
|
|
|
if not lst:
|
|
raise HTTPException(status_code=404, detail="List not found")
|
|
|
|
count = db.query(func.count(ListMember.id)).filter(
|
|
ListMember.list_id == lst.id
|
|
).scalar()
|
|
lst.member_count = count or 0
|
|
|
|
return lst
|
|
|
|
@router.put("/{list_id}", response_model=ListResponse)
|
|
def update_list(
|
|
list_id: int,
|
|
list_update: ListUpdate,
|
|
current_user: User = Depends(get_current_user),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
lst = db.query(ContactList).filter(
|
|
ContactList.id == list_id,
|
|
ContactList.user_id == current_user.id
|
|
).first()
|
|
|
|
if not lst:
|
|
raise HTTPException(status_code=404, detail="List not found")
|
|
|
|
lst.name = list_update.name
|
|
db.commit()
|
|
db.refresh(lst)
|
|
|
|
count = db.query(func.count(ListMember.id)).filter(
|
|
ListMember.list_id == lst.id
|
|
).scalar()
|
|
lst.member_count = count or 0
|
|
|
|
return lst
|
|
|
|
@router.delete("/{list_id}", status_code=status.HTTP_204_NO_CONTENT)
|
|
def delete_list(
|
|
list_id: int,
|
|
current_user: User = Depends(get_current_user),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
lst = db.query(ContactList).filter(
|
|
ContactList.id == list_id,
|
|
ContactList.user_id == current_user.id
|
|
).first()
|
|
|
|
if not lst:
|
|
raise HTTPException(status_code=404, detail="List not found")
|
|
|
|
db.delete(lst)
|
|
db.commit()
|
|
|
|
return None
|
|
|
|
@router.post("/{list_id}/members", status_code=status.HTTP_204_NO_CONTENT)
|
|
def add_members(
|
|
list_id: int,
|
|
members: ListMemberAdd,
|
|
current_user: User = Depends(get_current_user),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
lst = db.query(ContactList).filter(
|
|
ContactList.id == list_id,
|
|
ContactList.user_id == current_user.id
|
|
).first()
|
|
|
|
if not lst:
|
|
raise HTTPException(status_code=404, detail="List not found")
|
|
|
|
# Verify all contacts belong to user
|
|
contacts = db.query(Contact).filter(
|
|
Contact.id.in_(members.contact_ids),
|
|
Contact.user_id == current_user.id
|
|
).all()
|
|
|
|
if len(contacts) != len(members.contact_ids):
|
|
raise HTTPException(status_code=400, detail="Some contacts not found")
|
|
|
|
# Add members (skip duplicates)
|
|
for contact_id in members.contact_ids:
|
|
existing = db.query(ListMember).filter(
|
|
ListMember.list_id == list_id,
|
|
ListMember.contact_id == contact_id
|
|
).first()
|
|
|
|
if not existing:
|
|
member = ListMember(list_id=list_id, contact_id=contact_id)
|
|
db.add(member)
|
|
|
|
db.commit()
|
|
return None
|
|
|
|
@router.delete("/{list_id}/members", status_code=status.HTTP_204_NO_CONTENT)
|
|
def remove_members(
|
|
list_id: int,
|
|
members: ListMemberRemove,
|
|
current_user: User = Depends(get_current_user),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
lst = db.query(ContactList).filter(
|
|
ContactList.id == list_id,
|
|
ContactList.user_id == current_user.id
|
|
).first()
|
|
|
|
if not lst:
|
|
raise HTTPException(status_code=404, detail="List not found")
|
|
|
|
db.query(ListMember).filter(
|
|
ListMember.list_id == list_id,
|
|
ListMember.contact_id.in_(members.contact_ids)
|
|
).delete(synchronize_session=False)
|
|
|
|
db.commit()
|
|
return None
|
|
|
|
@router.get("/{list_id}/contacts", response_model=List[dict])
|
|
def get_list_contacts(
|
|
list_id: int,
|
|
current_user: User = Depends(get_current_user),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
lst = db.query(ContactList).filter(
|
|
ContactList.id == list_id,
|
|
ContactList.user_id == current_user.id
|
|
).first()
|
|
|
|
if not lst:
|
|
raise HTTPException(status_code=404, detail="List not found")
|
|
|
|
members = db.query(Contact).join(ListMember).filter(
|
|
ListMember.list_id == list_id
|
|
).all()
|
|
|
|
return [
|
|
{
|
|
"id": c.id,
|
|
"phone_e164": c.phone_e164,
|
|
"first_name": c.first_name,
|
|
"last_name": c.last_name,
|
|
"email": c.email,
|
|
"opted_in": c.opted_in
|
|
}
|
|
for c in members
|
|
]
|