Remove with tenant from mailman

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
Sacha Al Himdani
2026-03-06 11:54:52 +01:00
parent 4d2cb793b6
commit aa01c40184
6 changed files with 38 additions and 49 deletions

View File

@@ -4,8 +4,7 @@ CREATE TABLE mailing_lists (
organization_id TEXT NOT NULL REFERENCES organizations(id) ON UPDATE CASCADE ON DELETE CASCADE,
reply_to CITEXT,
created_at TIMESTAMP WITH TIME ZONE NOT NULL,
updated_at TIMESTAMP WITH TIME ZONE NOT NULL,
UNIQUE (organization_id)
updated_at TIMESTAMP WITH TIME ZONE NOT NULL
);
CREATE TYPE mailing_list_subscriber_status AS ENUM (

View File

@@ -35,26 +35,18 @@ func NewService(pgClient *pg.Client) *Service {
return &Service{pg: pgClient}
}
func (s *Service) WithTenant(tenantID gid.TenantID) *TenantService {
return &TenantService{pg: s.pg, scope: coredata.NewScope(tenantID)}
}
type TenantService struct {
pg *pg.Client
scope coredata.Scoper
}
func (s *TenantService) UpdateMailingList(
func (s *Service) UpdateMailingList(
ctx context.Context,
id gid.GID,
replyTo *mail.Addr,
) (*coredata.MailingList, error) {
var ml coredata.MailingList
scope := coredata.NewScopeFromObjectID(id)
ml := coredata.MailingList{}
err := s.pg.WithConn(
ctx,
func(conn pg.Conn) error {
if err := ml.LoadByID(ctx, conn, s.scope, id); err != nil {
if err := ml.LoadByID(ctx, conn, scope, id); err != nil {
if errors.Is(err, coredata.ErrResourceNotFound) {
return ErrMailingListNotFound
}
@@ -64,7 +56,7 @@ func (s *TenantService) UpdateMailingList(
ml.ReplyTo = replyTo
ml.UpdatedAt = time.Now()
if err := ml.Update(ctx, conn, s.scope); err != nil {
if err := ml.Update(ctx, conn, scope); err != nil {
return fmt.Errorf("cannot update mailing list: %w", err)
}
@@ -78,17 +70,18 @@ func (s *TenantService) UpdateMailingList(
return &ml, nil
}
func (s *TenantService) GetSubscriber(
func (s *Service) GetSubscriber(
ctx context.Context,
mailingListID gid.GID,
email mail.Addr,
) (*coredata.MailingListSubscriber, error) {
var subscriber coredata.MailingListSubscriber
scope := coredata.NewScopeFromObjectID(mailingListID)
subscriber := coredata.MailingListSubscriber{}
err := s.pg.WithConn(
ctx,
func(conn pg.Conn) error {
if err := subscriber.LoadByMailingListIDAndEmail(ctx, conn, s.scope, mailingListID, email); err != nil {
if err := subscriber.LoadByMailingListIDAndEmail(ctx, conn, scope, mailingListID, email); err != nil {
return fmt.Errorf("cannot load mailing list subscriber: %w", err)
}
@@ -105,16 +98,17 @@ func (s *TenantService) GetSubscriber(
return &subscriber, nil
}
func (s *TenantService) CreateSubscriber(
func (s *Service) CreateSubscriber(
ctx context.Context,
mailingListID gid.GID,
email mail.Addr,
fullName string,
) (*coredata.MailingListSubscriber, error) {
scope := coredata.NewScopeFromObjectID(mailingListID)
now := time.Now()
subscriber := &coredata.MailingListSubscriber{
ID: gid.New(s.scope.GetTenantID(), coredata.MailingListSubscriberEntityType),
ID: gid.New(scope.GetTenantID(), coredata.MailingListSubscriberEntityType),
MailingListID: mailingListID,
FullName: fullName,
Email: email,
@@ -126,13 +120,13 @@ func (s *TenantService) CreateSubscriber(
err := s.pg.WithConn(
ctx,
func(conn pg.Conn) error {
var ml coredata.MailingList
if err := ml.LoadByID(ctx, conn, s.scope, mailingListID); err != nil {
ml := coredata.MailingList{}
if err := ml.LoadByID(ctx, conn, scope, mailingListID); err != nil {
return fmt.Errorf("cannot load mailing list: %w", err)
}
subscriber.OrganizationID = ml.OrganizationID
if err := subscriber.Insert(ctx, conn, s.scope); err != nil {
if err := subscriber.Insert(ctx, conn, scope); err != nil {
if errors.Is(err, coredata.ErrResourceAlreadyExists) {
return ErrSubscriberAlreadyExist
}
@@ -149,15 +143,17 @@ func (s *TenantService) CreateSubscriber(
return subscriber, nil
}
func (s *TenantService) DeleteSubscriber(
func (s *Service) DeleteSubscriber(
ctx context.Context,
id gid.GID,
) error {
scope := coredata.NewScopeFromObjectID(id)
err := s.pg.WithConn(
ctx,
func(conn pg.Conn) error {
subscriber := coredata.MailingListSubscriber{ID: id}
if err := subscriber.Delete(ctx, conn, s.scope); err != nil {
if err := subscriber.Delete(ctx, conn, scope); err != nil {
return fmt.Errorf("cannot delete mailing list subscriber: %w", err)
}
return nil
@@ -170,17 +166,18 @@ func (s *TenantService) DeleteSubscriber(
return nil
}
func (s *TenantService) CountSubscribers(
func (s *Service) CountSubscribers(
ctx context.Context,
mailingListID gid.GID,
) (int, error) {
var count int
scope := coredata.NewScopeFromObjectID(mailingListID)
count := 0
err := s.pg.WithConn(
ctx,
func(conn pg.Conn) (err error) {
subscribers := coredata.MailingListSubscribers{}
count, err = subscribers.CountByMailingListID(ctx, conn, s.scope, mailingListID)
count, err = subscribers.CountByMailingListID(ctx, conn, scope, mailingListID)
if err != nil {
return fmt.Errorf("cannot count mailing list subscribers: %w", err)
}
@@ -194,17 +191,18 @@ func (s *TenantService) CountSubscribers(
return count, nil
}
func (s *TenantService) ListSubscribers(
func (s *Service) ListSubscribers(
ctx context.Context,
mailingListID gid.GID,
cursor *page.Cursor[coredata.MailingListSubscriberOrderField],
) (*page.Page[*coredata.MailingListSubscriber, coredata.MailingListSubscriberOrderField], error) {
var subscribers coredata.MailingListSubscribers
scope := coredata.NewScopeFromObjectID(mailingListID)
subscribers := coredata.MailingListSubscribers{}
err := s.pg.WithConn(
ctx,
func(conn pg.Conn) error {
if err := subscribers.LoadByMailingListID(ctx, conn, s.scope, mailingListID, cursor); err != nil {
if err := subscribers.LoadByMailingListID(ctx, conn, scope, mailingListID, cursor); err != nil {
return fmt.Errorf("cannot load mailing list subscribers: %w", err)
}
return nil

View File

@@ -202,9 +202,6 @@ func (r *Resolver) ProboService(ctx context.Context, tenantID gid.TenantID) *pro
return r.probo.WithTenant(tenantID)
}
func (r *Resolver) MailmanService(ctx context.Context, tenantID gid.TenantID) *mailman.TenantService {
return r.mailman.WithTenant(tenantID)
}
func (r *Resolver) Permission(ctx context.Context, obj types.Node, action string) (bool, error) {
return r.authorize(ctx, obj.GetID(), action) == nil, nil

View File

@@ -1537,7 +1537,7 @@ func (r *mailingListResolver) Subscribers(ctx context.Context, obj *types.Mailin
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
result, err := r.MailmanService(ctx, obj.ID.TenantID()).ListSubscribers(ctx, obj.ID, cursor)
result, err := r.mailman.ListSubscribers(ctx, obj.ID, cursor)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot list mailing list subscribers", log.Error(err))
return nil, gqlutils.Internal(ctx)
@@ -1554,7 +1554,7 @@ func (r *mailingListSubscriberConnectionResolver) TotalCount(ctx context.Context
switch obj.Resolver.(type) {
case *mailingListResolver:
count, err := r.MailmanService(ctx, obj.ParentID.TenantID()).CountSubscribers(ctx, obj.ParentID)
count, err := r.mailman.CountSubscribers(ctx, obj.ParentID)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot count mailing list subscribers", log.Error(err))
return 0, gqlutils.Internal(ctx)
@@ -2034,7 +2034,7 @@ func (r *mutationResolver) UpdateMailingList(ctx context.Context, input types.Up
return nil, err
}
ml, err := r.MailmanService(ctx, input.ID.TenantID()).UpdateMailingList(ctx, input.ID, input.ReplyTo)
ml, err := r.mailman.UpdateMailingList(ctx, input.ID, input.ReplyTo)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot update mailing list", log.Error(err))
return nil, gqlutils.Internal(ctx)
@@ -2051,7 +2051,7 @@ func (r *mutationResolver) CreateMailingListSubscriber(ctx context.Context, inpu
return nil, err
}
subscriber, err := r.MailmanService(ctx, input.MailingListID.TenantID()).CreateSubscriber(ctx, input.MailingListID, input.Email, input.FullName)
subscriber, err := r.mailman.CreateSubscriber(ctx, input.MailingListID, input.Email, input.FullName)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot create mailing list subscriber", log.Error(err))
return nil, gqlutils.Internal(ctx)
@@ -2068,7 +2068,7 @@ func (r *mutationResolver) DeleteMailingListSubscriber(ctx context.Context, inpu
return nil, err
}
if err := r.MailmanService(ctx, input.ID.TenantID()).DeleteSubscriber(ctx, input.ID); err != nil {
if err := r.mailman.DeleteSubscriber(ctx, input.ID); err != nil {
r.logger.ErrorCtx(ctx, "cannot delete mailing list subscriber", log.Error(err))
return nil, gqlutils.Internal(ctx)
}

View File

@@ -100,6 +100,3 @@ func (r *Resolver) TrustService(ctx context.Context, tenantID gid.TenantID) *tru
return r.trust.WithTenant(tenantID)
}
func (r *Resolver) MailmanService(ctx context.Context, tenantID gid.TenantID) *mailman.TenantService {
return r.mailman.WithTenant(tenantID)
}

View File

@@ -702,13 +702,12 @@ func (r *mutationResolver) SubscribeToMailingList(ctx context.Context) (*types.S
return nil, gqlutils.NotFoundf(ctx, "mailing list not found")
}
mlSvc := r.MailmanService(ctx, trustCenter.ID.TenantID())
identity := authn.IdentityFromContext(ctx)
subscriber, err := mlSvc.CreateSubscriber(ctx, *trustCenter.MailingListID, identity.EmailAddress, identity.FullName)
subscriber, err := r.mailman.CreateSubscriber(ctx, *trustCenter.MailingListID, identity.EmailAddress, identity.FullName)
if err != nil {
if errors.Is(err, mailman.ErrSubscriberAlreadyExist) {
subscriber, err = mlSvc.GetSubscriber(ctx, *trustCenter.MailingListID, identity.EmailAddress)
subscriber, err = r.mailman.GetSubscriber(ctx, *trustCenter.MailingListID, identity.EmailAddress)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot get existing mailing list subscription", log.Error(err))
return nil, gqlutils.Internal(ctx)
@@ -731,10 +730,9 @@ func (r *mutationResolver) UnsubscribeFromMailingList(ctx context.Context) (*typ
return nil, gqlutils.NotFoundf(ctx, "mailing list not found")
}
mlSvc := r.MailmanService(ctx, trustCenter.ID.TenantID())
identity := authn.IdentityFromContext(ctx)
subscriber, err := mlSvc.GetSubscriber(ctx, *trustCenter.MailingListID, identity.EmailAddress)
subscriber, err := r.mailman.GetSubscriber(ctx, *trustCenter.MailingListID, identity.EmailAddress)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot get mailing list subscription", log.Error(err))
return nil, gqlutils.Internal(ctx)
@@ -743,7 +741,7 @@ func (r *mutationResolver) UnsubscribeFromMailingList(ctx context.Context) (*typ
return nil, gqlutils.NotFoundf(ctx, "mailing list subscription not found")
}
if err := mlSvc.DeleteSubscriber(ctx, subscriber.ID); err != nil {
if err := r.mailman.DeleteSubscriber(ctx, subscriber.ID); err != nil {
r.logger.ErrorCtx(ctx, "cannot unsubscribe from mailing list", log.Error(err))
return nil, gqlutils.Internal(ctx)
}
@@ -1052,7 +1050,7 @@ func (r *trustCenterResolver) ViewerSubscription(ctx context.Context, obj *types
return nil, nil
}
subscriber, err := r.MailmanService(ctx, trustCenter.ID.TenantID()).GetSubscriber(ctx, *trustCenter.MailingListID, identity.EmailAddress)
subscriber, err := r.mailman.GetSubscriber(ctx, *trustCenter.MailingListID, identity.EmailAddress)
if err != nil {
r.logger.ErrorCtx(ctx, "cannot get mailing list subscription", log.Error(err))
return nil, gqlutils.Internal(ctx)