package repository import ( "context" "errors" dbgen "Yimaru-Backend/gen/db" "Yimaru-Backend/internal/domain" "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgtype" ) func mapDBTeamInvitation(row dbgen.TeamInvitation) domain.TeamInvitation { inv := domain.TeamInvitation{ ID: row.ID, TeamMemberID: row.TeamMemberID, Token: row.Token, Status: domain.TeamInvitationStatus(row.Status), ExpiresAt: row.ExpiresAt.Time, CreatedAt: row.CreatedAt.Time, } if row.InvitedBy.Valid { inv.InvitedBy = &row.InvitedBy.Int64 } if row.AcceptedAt.Valid { t := row.AcceptedAt.Time inv.AcceptedAt = &t } if row.UpdatedAt.Valid { t := row.UpdatedAt.Time inv.UpdatedAt = &t } return inv } func (s *Store) CreateTeamInvitation(ctx context.Context, invitation domain.TeamInvitation) (domain.TeamInvitation, error) { var invitedBy pgtype.Int8 if invitation.InvitedBy != nil { invitedBy = pgtype.Int8{Int64: *invitation.InvitedBy, Valid: true} } row, err := s.queries.CreateTeamInvitation(ctx, dbgen.CreateTeamInvitationParams{ TeamMemberID: invitation.TeamMemberID, Token: invitation.Token, ExpiresAt: pgtype.Timestamptz{Time: invitation.ExpiresAt, Valid: true}, InvitedBy: invitedBy, }) if err != nil { return domain.TeamInvitation{}, err } return mapDBTeamInvitation(row), nil } func (s *Store) GetTeamInvitationByToken(ctx context.Context, token string) (domain.TeamInvitation, error) { row, err := s.queries.GetTeamInvitationByToken(ctx, token) if err != nil { if errors.Is(err, pgx.ErrNoRows) { return domain.TeamInvitation{}, domain.ErrTeamInvitationNotFound } return domain.TeamInvitation{}, err } return mapDBTeamInvitation(row), nil } func (s *Store) GetTeamInvitationByID(ctx context.Context, id int64) (domain.TeamInvitation, error) { row, err := s.queries.GetTeamInvitationByID(ctx, id) if err != nil { if errors.Is(err, pgx.ErrNoRows) { return domain.TeamInvitation{}, domain.ErrTeamInvitationNotFound } return domain.TeamInvitation{}, err } return mapDBTeamInvitation(row), nil } func (s *Store) GetPendingTeamInvitationByMemberID(ctx context.Context, memberID int64) (domain.TeamInvitation, error) { row, err := s.queries.GetPendingTeamInvitationByMemberID(ctx, memberID) if err != nil { if errors.Is(err, pgx.ErrNoRows) { return domain.TeamInvitation{}, domain.ErrTeamInvitationNotFound } return domain.TeamInvitation{}, err } return mapDBTeamInvitation(row), nil } func (s *Store) RevokePendingTeamInvitationsForMember(ctx context.Context, memberID int64) error { return s.queries.RevokePendingTeamInvitationsForMember(ctx, memberID) } func (s *Store) AcceptTeamInvitation(ctx context.Context, invitationID int64) (domain.TeamInvitation, error) { row, err := s.queries.AcceptTeamInvitation(ctx, invitationID) if err != nil { if errors.Is(err, pgx.ErrNoRows) { return domain.TeamInvitation{}, domain.ErrTeamInvitationNotFound } return domain.TeamInvitation{}, err } return mapDBTeamInvitation(row), nil } func (s *Store) RevokeTeamInvitation(ctx context.Context, invitationID int64) (domain.TeamInvitation, error) { row, err := s.queries.RevokeTeamInvitation(ctx, invitationID) if err != nil { if errors.Is(err, pgx.ErrNoRows) { return domain.TeamInvitation{}, domain.ErrTeamInvitationNotFound } return domain.TeamInvitation{}, err } return mapDBTeamInvitation(row), nil } func (s *Store) ExpireTeamInvitation(ctx context.Context, invitationID int64) error { return s.queries.ExpireTeamInvitation(ctx, invitationID) } func (s *Store) ListTeamInvitations(ctx context.Context, status *string, limit, offset int32) ([]domain.TeamInvitationWithMember, int64, error) { rows, err := s.queries.ListTeamInvitations(ctx, dbgen.ListTeamInvitationsParams{ Status: toPgText(status), Offset: pgtype.Int4{Int32: offset, Valid: true}, Limit: pgtype.Int4{Int32: limit, Valid: true}, }) if err != nil { return nil, 0, err } out := make([]domain.TeamInvitationWithMember, 0, len(rows)) var total int64 for _, row := range rows { inv := mapDBTeamInvitation(dbgen.TeamInvitation{ ID: row.ID, TeamMemberID: row.TeamMemberID, Token: row.Token, Status: row.Status, ExpiresAt: row.ExpiresAt, InvitedBy: row.InvitedBy, AcceptedAt: row.AcceptedAt, CreatedAt: row.CreatedAt, UpdatedAt: row.UpdatedAt, }) out = append(out, domain.TeamInvitationWithMember{ TeamInvitation: inv, Email: row.Email, FirstName: row.FirstName, LastName: row.LastName, TeamRole: domain.TeamRole(row.TeamRole), }) total = row.TotalCount } return out, total, nil }