Email template management

This commit is contained in:
James Pattinson
2025-11-10 16:07:22 +00:00
parent 43b13ef52d
commit 7fd237c28b
17 changed files with 1421 additions and 259 deletions

View File

@@ -1,5 +1,5 @@
from fastapi import APIRouter
from . import auth, users, tiers, memberships, payments, email
from . import auth, users, tiers, memberships, payments, email, email_templates
api_router = APIRouter()
@@ -9,3 +9,4 @@ api_router.include_router(tiers.router, prefix="/tiers", tags=["membership-tiers
api_router.include_router(memberships.router, prefix="/memberships", tags=["memberships"])
api_router.include_router(payments.router, prefix="/payments", tags=["payments"])
api_router.include_router(email.router, prefix="/email", tags=["email"])
api_router.include_router(email_templates.router, prefix="/email-templates", tags=["email-templates"])

View File

@@ -52,7 +52,8 @@ async def register(
try:
await email_service.send_welcome_email(
to_email=db_user.email,
first_name=db_user.first_name
first_name=db_user.first_name,
db=db
)
except Exception as e:
# Log error but don't fail registration
@@ -171,7 +172,8 @@ async def forgot_password(
await email_service.send_password_reset_email(
to_email=user.email,
first_name=user.first_name,
reset_token=reset_token
reset_token=reset_token,
db=db
)
except Exception as e:
# Log error but don't fail the request

View File

@@ -0,0 +1,98 @@
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from typing import List
from ...core.database import get_db
from ...models.models import EmailTemplate
from ...schemas import (
EmailTemplateCreate, EmailTemplateUpdate, EmailTemplateResponse, MessageResponse
)
from ...api.dependencies import get_super_admin_user
router = APIRouter()
@router.get("/", response_model=List[EmailTemplateResponse])
async def list_email_templates(
skip: int = 0,
limit: int = 100,
current_user = Depends(get_super_admin_user),
db: Session = Depends(get_db)
):
"""List all email templates (super admin only)"""
templates = db.query(EmailTemplate).offset(skip).limit(limit).all()
return templates
@router.get("/{template_key}", response_model=EmailTemplateResponse)
async def get_email_template(
template_key: str,
current_user = Depends(get_super_admin_user),
db: Session = Depends(get_db)
):
"""Get email template by key (super admin only)"""
template = db.query(EmailTemplate).filter(EmailTemplate.template_key == template_key).first()
if not template:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Email template not found"
)
return template
@router.put("/{template_key}", response_model=EmailTemplateResponse)
async def update_email_template(
template_key: str,
template_update: EmailTemplateUpdate,
current_user = Depends(get_super_admin_user),
db: Session = Depends(get_db)
):
"""Update email template (super admin only)"""
template = db.query(EmailTemplate).filter(EmailTemplate.template_key == template_key).first()
if not template:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Email template not found"
)
update_data = template_update.model_dump(exclude_unset=True)
for field, value in update_data.items():
setattr(template, field, value)
db.commit()
db.refresh(template)
return template
@router.post("/seed-defaults", response_model=MessageResponse)
async def seed_default_templates(
current_user = Depends(get_super_admin_user),
db: Session = Depends(get_db)
):
"""Seed database with default email templates (super admin only)"""
from ...services.email_service import get_default_templates
default_templates = get_default_templates()
created_count = 0
for template_data in default_templates:
# Check if template already exists
existing = db.query(EmailTemplate).filter(
EmailTemplate.template_key == template_data["template_key"]
).first()
if not existing:
template = EmailTemplate(**template_data)
db.add(template)
created_count += 1
if created_count > 0:
db.commit()
return {"message": f"Created {created_count} default email templates"}
else:
return {"message": "All default templates already exist"}

View File

@@ -145,7 +145,8 @@ async def update_membership(
annual_fee=membership.tier.annual_fee,
payment_amount=payment_amount,
payment_method=payment_method,
renewal_date=membership.end_date.strftime("%d %B %Y")
renewal_date=membership.end_date.strftime("%d %B %Y"),
db=db
)
except Exception as e:
# Log error but don't fail the membership update

View File

@@ -134,7 +134,8 @@ async def update_payment(
annual_fee=payment.membership.tier.annual_fee,
payment_amount=payment.amount,
payment_method=payment.payment_method.value,
renewal_date=payment.membership.end_date.strftime("%d %B %Y")
renewal_date=payment.membership.end_date.strftime("%d %B %Y"),
db=db
)
except Exception as e:
# Log error but don't fail the payment update
@@ -219,7 +220,8 @@ async def record_manual_payment(
annual_fee=membership.tier.annual_fee,
payment_amount=payment.amount,
payment_method=payment.payment_method.value,
renewal_date=membership.end_date.strftime("%d %B %Y")
renewal_date=membership.end_date.strftime("%d %B %Y"),
db=db
)
except Exception as e:
# Log error but don't fail the payment creation