Files
Ronni Skansing d1f100968e added report delivery
Signed-off-by: Ronni Skansing <rskansing@gmail.com>
2026-06-13 12:46:49 +02:00

221 lines
5.1 KiB
Go

package repository
import (
"context"
"fmt"
"time"
"github.com/google/uuid"
"github.com/oapi-codegen/nullable"
"github.com/phishingclub/phishingclub/database"
"github.com/phishingclub/phishingclub/errs"
"github.com/phishingclub/phishingclub/model"
"github.com/phishingclub/phishingclub/vo"
"gorm.io/gorm"
)
// CompanyReportConfig is the repository for company report delivery configuration
type CompanyReportConfig struct {
DB *gorm.DB
}
// Insert inserts a new company report config row
func (r *CompanyReportConfig) Insert(
ctx context.Context,
config *model.CompanyReportConfig,
) (*uuid.UUID, error) {
id := uuid.New()
row := config.ToDBMap()
row["id"] = id
AddTimestamps(row)
// a NULL company_id is the global default config
row["company_id"] = nil
if companyID, err := config.CompanyID.Get(); err == nil {
row["company_id"] = companyID.String()
}
res := r.DB.
Model(&database.CompanyReportConfig{}).
Create(row)
if res.Error != nil {
return nil, errs.Wrap(res.Error)
}
return &id, nil
}
// GetByCompanyID fetches the report config for a given company, or the global
// default config when companyID is nil.
func (r *CompanyReportConfig) GetByCompanyID(
ctx context.Context,
companyID *uuid.UUID,
) (*model.CompanyReportConfig, error) {
var row database.CompanyReportConfig
db := r.DB
if companyID == nil {
db = whereCompanyIsNull(db, database.COMPANY_REPORT_CONFIG_TABLE)
} else {
db = db.Where(
fmt.Sprintf(
"%s = ?",
TableColumn(database.COMPANY_REPORT_CONFIG_TABLE, "company_id"),
),
companyID.String(),
)
}
res := db.First(&row)
if res.Error != nil {
return nil, errs.Wrap(res.Error)
}
return ToCompanyReportConfig(&row), nil
}
// GetByID fetches the report config by its primary key
func (r *CompanyReportConfig) GetByID(
ctx context.Context,
id *uuid.UUID,
) (*model.CompanyReportConfig, error) {
var row database.CompanyReportConfig
res := r.DB.
Where(
fmt.Sprintf(
"%s = ?",
TableColumnID(database.COMPANY_REPORT_CONFIG_TABLE),
),
id.String(),
).
First(&row)
if res.Error != nil {
return nil, errs.Wrap(res.Error)
}
return ToCompanyReportConfig(&row), nil
}
// UpdateByID performs a partial update on the report config via ToDBMap
func (r *CompanyReportConfig) UpdateByID(
ctx context.Context,
id *uuid.UUID,
config *model.CompanyReportConfig,
) error {
row := config.ToDBMap()
AddUpdatedAt(row)
res := r.DB.
Model(&database.CompanyReportConfig{}).
Where(
fmt.Sprintf(
"%s = ?",
TableColumnID(database.COMPANY_REPORT_CONFIG_TABLE),
),
id.String(),
).
Updates(row)
if res.Error != nil {
return errs.Wrap(res.Error)
}
return nil
}
// UpdateLastSentAt sets last_sent_at to the current UTC time for the given config ID
func (r *CompanyReportConfig) UpdateLastSentAt(
ctx context.Context,
id *uuid.UUID,
) error {
now := time.Now().UTC()
row := map[string]any{
"last_sent_at": now,
}
AddUpdatedAt(row)
res := r.DB.
Model(&database.CompanyReportConfig{}).
Where(
fmt.Sprintf(
"%s = ?",
TableColumnID(database.COMPANY_REPORT_CONFIG_TABLE),
),
id.String(),
).
Updates(row)
if res.Error != nil {
return errs.Wrap(res.Error)
}
return nil
}
// DeleteByCompanyID removes the report config for a given company, or the global
// default config when companyID is nil.
func (r *CompanyReportConfig) DeleteByCompanyID(
ctx context.Context,
companyID *uuid.UUID,
) error {
db := r.DB
if companyID == nil {
db = whereCompanyIsNull(db, database.COMPANY_REPORT_CONFIG_TABLE)
} else {
db = db.Where(
fmt.Sprintf(
"%s = ?",
TableColumn(database.COMPANY_REPORT_CONFIG_TABLE, "company_id"),
),
companyID.String(),
)
}
res := db.Delete(&database.CompanyReportConfig{})
if res.Error != nil {
return errs.Wrap(res.Error)
}
return nil
}
// ToCompanyReportConfig maps a database row to the business model
func ToCompanyReportConfig(row *database.CompanyReportConfig) *model.CompanyReportConfig {
id := nullable.NewNullableWithValue(*row.ID)
companyID := nullable.NewNullNullable[uuid.UUID]()
if row.CompanyID != nil {
companyID.Set(*row.CompanyID)
}
recipientGroupID := nullable.NewNullNullable[uuid.UUID]()
if row.RecipientGroupID != nil {
recipientGroupID.Set(*row.RecipientGroupID)
}
smtpConfigurationID := nullable.NewNullNullable[uuid.UUID]()
if row.SMTPConfigurationID != nil {
smtpConfigurationID.Set(*row.SMTPConfigurationID)
}
senderEmail := nullable.NewNullNullable[vo.Email]()
if row.SenderEmail != "" {
if email, err := vo.NewEmail(row.SenderEmail); err == nil {
senderEmail.Set(*email)
}
}
emailSubject := nullable.NewNullableWithValue(row.EmailSubject)
emailBody := nullable.NewNullableWithValue(row.EmailBody)
return &model.CompanyReportConfig{
ID: id,
CreatedAt: row.CreatedAt,
UpdatedAt: row.UpdatedAt,
CompanyID: companyID,
Enabled: row.Enabled,
SendOnFinish: row.SendOnFinish,
RecipientGroupID: recipientGroupID,
SMTPConfigurationID: smtpConfigurationID,
SenderEmail: senderEmail,
EmailSubject: emailSubject,
EmailBody: emailBody,
LastSentAt: row.LastSentAt,
}
}