feat: enhance messaging system with improved API and tests
- Refactor messaging API endpoints for admin, shop, and vendor - Add message-specific exceptions (ConversationNotFoundException, etc.) - Enhance messaging service with additional helper methods - Add comprehensive test fixtures for messaging - Add integration tests for admin and vendor messaging APIs - Add unit tests for messaging and attachment services 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -567,6 +567,118 @@ class MessagingService:
|
||||
db.flush()
|
||||
return result > 0
|
||||
|
||||
# =========================================================================
|
||||
# RECIPIENT QUERIES
|
||||
# =========================================================================
|
||||
|
||||
def get_vendor_recipients(
|
||||
self,
|
||||
db: Session,
|
||||
vendor_id: int | None = None,
|
||||
search: str | None = None,
|
||||
skip: int = 0,
|
||||
limit: int = 50,
|
||||
) -> tuple[list[dict], int]:
|
||||
"""
|
||||
Get list of vendor users as potential recipients.
|
||||
|
||||
Args:
|
||||
db: Database session
|
||||
vendor_id: Optional vendor ID filter
|
||||
search: Search term for name/email
|
||||
skip: Pagination offset
|
||||
limit: Max results
|
||||
|
||||
Returns:
|
||||
Tuple of (recipients list, total count)
|
||||
"""
|
||||
from models.database.vendor import VendorUser
|
||||
|
||||
query = (
|
||||
db.query(User, VendorUser)
|
||||
.join(VendorUser, User.id == VendorUser.user_id)
|
||||
.filter(User.is_active == True) # noqa: E712
|
||||
)
|
||||
|
||||
if vendor_id:
|
||||
query = query.filter(VendorUser.vendor_id == vendor_id)
|
||||
|
||||
if search:
|
||||
search_pattern = f"%{search}%"
|
||||
query = query.filter(
|
||||
(User.username.ilike(search_pattern))
|
||||
| (User.email.ilike(search_pattern))
|
||||
| (User.first_name.ilike(search_pattern))
|
||||
| (User.last_name.ilike(search_pattern))
|
||||
)
|
||||
|
||||
total = query.count()
|
||||
results = query.offset(skip).limit(limit).all()
|
||||
|
||||
recipients = []
|
||||
for user, vendor_user in results:
|
||||
name = f"{user.first_name or ''} {user.last_name or ''}".strip() or user.username
|
||||
recipients.append({
|
||||
"id": user.id,
|
||||
"type": ParticipantType.VENDOR,
|
||||
"name": name,
|
||||
"email": user.email,
|
||||
"vendor_id": vendor_user.vendor_id,
|
||||
"vendor_name": vendor_user.vendor.name if vendor_user.vendor else None,
|
||||
})
|
||||
|
||||
return recipients, total
|
||||
|
||||
def get_customer_recipients(
|
||||
self,
|
||||
db: Session,
|
||||
vendor_id: int | None = None,
|
||||
search: str | None = None,
|
||||
skip: int = 0,
|
||||
limit: int = 50,
|
||||
) -> tuple[list[dict], int]:
|
||||
"""
|
||||
Get list of customers as potential recipients.
|
||||
|
||||
Args:
|
||||
db: Database session
|
||||
vendor_id: Optional vendor ID filter (required for vendor users)
|
||||
search: Search term for name/email
|
||||
skip: Pagination offset
|
||||
limit: Max results
|
||||
|
||||
Returns:
|
||||
Tuple of (recipients list, total count)
|
||||
"""
|
||||
query = db.query(Customer).filter(Customer.is_active == True) # noqa: E712
|
||||
|
||||
if vendor_id:
|
||||
query = query.filter(Customer.vendor_id == vendor_id)
|
||||
|
||||
if search:
|
||||
search_pattern = f"%{search}%"
|
||||
query = query.filter(
|
||||
(Customer.email.ilike(search_pattern))
|
||||
| (Customer.first_name.ilike(search_pattern))
|
||||
| (Customer.last_name.ilike(search_pattern))
|
||||
)
|
||||
|
||||
total = query.count()
|
||||
results = query.offset(skip).limit(limit).all()
|
||||
|
||||
recipients = []
|
||||
for customer in results:
|
||||
name = f"{customer.first_name or ''} {customer.last_name or ''}".strip()
|
||||
recipients.append({
|
||||
"id": customer.id,
|
||||
"type": ParticipantType.CUSTOMER,
|
||||
"name": name or customer.email,
|
||||
"email": customer.email,
|
||||
"vendor_id": customer.vendor_id,
|
||||
})
|
||||
|
||||
return recipients, total
|
||||
|
||||
|
||||
# Singleton instance
|
||||
messaging_service = MessagingService()
|
||||
|
||||
Reference in New Issue
Block a user