Files
Ronni Skansing 23539c10c9 report
Signed-off-by: Ronni Skansing <rskansing@gmail.com>
2026-05-29 17:28:50 +02:00

184 lines
4.5 KiB
Go

package repository
import (
"context"
"errors"
"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"
)
var reportTemplateAllowedColumns = assignTableToColumns(database.REPORT_TEMPLATE_TABLE, []string{
"created_at",
"updated_at",
})
// ReportTemplateOption is for query options
type ReportTemplateOption struct {
*vo.QueryArgs
WithCompany bool
}
// ReportTemplate is a report template repository
type ReportTemplate struct {
DB *gorm.DB
}
func (r *ReportTemplate) load(options *ReportTemplateOption, db *gorm.DB) *gorm.DB {
if options != nil && options.WithCompany {
db = db.Joins("Company")
}
return db
}
// Insert inserts a report template
func (r *ReportTemplate) Insert(
ctx context.Context,
tmpl *model.ReportTemplate,
) (*uuid.UUID, error) {
id := uuid.New()
row := tmpl.ToDBMap()
row["id"] = id
AddTimestamps(row)
res := r.DB.
Model(&database.ReportTemplate{}).
Create(row)
if res.Error != nil {
return nil, res.Error
}
return &id, nil
}
// GetAll gets report templates
func (r *ReportTemplate) GetAll(
ctx context.Context,
companyID *uuid.UUID,
options *ReportTemplateOption,
) (*model.Result[model.ReportTemplate], error) {
result := model.NewEmptyResult[model.ReportTemplate]()
var rows []database.ReportTemplate
db := r.load(options, r.DB)
db = whereCompany(db, database.REPORT_TEMPLATE_TABLE, companyID)
db, err := useQuery(db, database.REPORT_TEMPLATE_TABLE, options.QueryArgs, reportTemplateAllowedColumns...)
if err != nil {
return result, errs.Wrap(err)
}
if res := db.Find(&rows); res.Error != nil {
return result, res.Error
}
hasNextPage, err := useHasNextPage(db, database.REPORT_TEMPLATE_TABLE, options.QueryArgs, reportTemplateAllowedColumns...)
if err != nil {
return result, errs.Wrap(err)
}
result.HasNextPage = hasNextPage
for _, row := range rows {
tmpl, err := ToReportTemplate(&row)
if err != nil {
return result, errs.Wrap(err)
}
result.Rows = append(result.Rows, tmpl)
}
return result, nil
}
// GetByID gets a report template by id
func (r *ReportTemplate) GetByID(
ctx context.Context,
id *uuid.UUID,
options *ReportTemplateOption,
) (*model.ReportTemplate, error) {
db := r.load(options, r.DB)
var row database.ReportTemplate
res := db.
Where(TableColumnID(database.REPORT_TEMPLATE_TABLE)+" = ?", id).
First(&row)
if res.Error != nil {
return nil, res.Error
}
return ToReportTemplate(&row)
}
// GetForCampaign resolves the report template for a given company: company-specific first,
// then global (NULL company_id). Returns gorm.ErrRecordNotFound if neither exists.
func (r *ReportTemplate) GetForCampaign(
ctx context.Context,
companyID *uuid.UUID,
) (*model.ReportTemplate, error) {
var row database.ReportTemplate
if companyID != nil {
res := r.DB.
Where(TableColumn(database.REPORT_TEMPLATE_TABLE, "company_id")+" = ?", companyID).
First(&row)
if res.Error == nil {
return ToReportTemplate(&row)
}
if !errors.Is(res.Error, gorm.ErrRecordNotFound) {
return nil, res.Error
}
}
res := whereCompanyIsNull(r.DB, database.REPORT_TEMPLATE_TABLE).
First(&row)
if res.Error != nil {
return nil, res.Error
}
return ToReportTemplate(&row)
}
// UpdateByID updates a report template
func (r *ReportTemplate) UpdateByID(
ctx context.Context,
id *uuid.UUID,
tmpl *model.ReportTemplate,
) error {
row := tmpl.ToDBMap()
AddUpdatedAt(row)
res := r.DB.
Model(&database.ReportTemplate{}).
Where(TableColumnID(database.REPORT_TEMPLATE_TABLE)+" = ?", id).
Updates(row)
if res.Error != nil {
return res.Error
}
return nil
}
// DeleteByID deletes a report template by id
func (r *ReportTemplate) DeleteByID(
ctx context.Context,
id *uuid.UUID,
) error {
result := r.DB.Delete(&database.ReportTemplate{}, id)
if result.Error != nil {
return result.Error
}
return nil
}
// ToReportTemplate converts a database row to a model
func ToReportTemplate(row *database.ReportTemplate) (*model.ReportTemplate, error) {
id := nullable.NewNullableWithValue(*row.ID)
companyID := nullable.NewNullNullable[uuid.UUID]()
if row.CompanyID != nil {
companyID.Set(*row.CompanyID)
}
c, err := vo.NewOptionalString1MB(row.Content)
if err != nil {
return nil, errs.Wrap(err)
}
content := nullable.NewNullableWithValue(*c)
return &model.ReportTemplate{
ID: id,
CreatedAt: row.CreatedAt,
UpdatedAt: row.UpdatedAt,
CompanyID: companyID,
Content: content,
}, nil
}