169 lines
4.7 KiB
Go
169 lines
4.7 KiB
Go
package lib
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
)
|
|
|
|
// Broadcast logic — answer published → notify all linked requesters.
|
|
// Uses the broadcasts table for idempotency.
|
|
|
|
// NotifyAnswerPublished broadcasts a published answer to all linked requesters. Stub.
|
|
func NotifyAnswerPublished(db *DB, cfg *Config, answerID string) error {
|
|
// TODO: implementation steps:
|
|
// 1. Query answer_links WHERE answer_id = ? AND status = 'confirmed'
|
|
// 2. For each linked request, find the origin_id (buyer)
|
|
// 3. Check broadcasts table for idempotency
|
|
// 4. Send notification (email, in-app, etc.)
|
|
// 5. Record in broadcasts table
|
|
return nil
|
|
}
|
|
|
|
// NotifyTaskAssigned notifies a user that a task has been assigned to them. Stub.
|
|
func NotifyTaskAssigned(db *DB, cfg *Config, entryID, assigneeID string) error {
|
|
// TODO: implement notification
|
|
return nil
|
|
}
|
|
|
|
// NotifyChainComplete fires when a routing chain completes back to origin. Stub.
|
|
func NotifyChainComplete(db *DB, cfg *Config, entryID string) error {
|
|
// TODO: implement chain completion notification
|
|
return nil
|
|
}
|
|
|
|
// ---- Email Notification Functions ----
|
|
|
|
// NotifyInvite sends an invitation email to a new user.
|
|
func NotifyInvite(m *Mailer, to, inviterName, inviterOrg, projectName, inviteURL string) error {
|
|
if !m.Enabled() {
|
|
return nil
|
|
}
|
|
|
|
subject := fmt.Sprintf("You've been invited to join %s on Dealspace", projectName)
|
|
data := InviteData{
|
|
InviterName: inviterName,
|
|
InviterOrg: inviterOrg,
|
|
ProjectName: projectName,
|
|
InviteURL: inviteURL,
|
|
ExpiresIn: "7 days",
|
|
}
|
|
|
|
return m.SendTemplate(to, subject, "invite.html", data)
|
|
}
|
|
|
|
// NotifyTasksAssigned sends an email when new tasks are assigned to a user.
|
|
func NotifyTasksAssigned(m *Mailer, to, projectName string, tasks []string) error {
|
|
if !m.Enabled() {
|
|
return nil
|
|
}
|
|
|
|
count := len(tasks)
|
|
var subject string
|
|
if count == 1 {
|
|
subject = fmt.Sprintf("You have 1 new task on %s", projectName)
|
|
} else {
|
|
subject = fmt.Sprintf("You have %d new tasks on %s", count, projectName)
|
|
}
|
|
|
|
// Convert task strings to TaskItem (simplified — in real usage, you'd pass full task data)
|
|
taskItems := make([]TaskItem, 0, len(tasks))
|
|
for _, t := range tasks {
|
|
taskItems = append(taskItems, TaskItem{
|
|
Title: t,
|
|
})
|
|
}
|
|
|
|
data := TasksAssignedData{
|
|
ProjectName: projectName,
|
|
Count: count,
|
|
Tasks: taskItems,
|
|
TasksURL: "https://app.muskepo.com/app/tasks",
|
|
}
|
|
|
|
return m.SendTemplate(to, subject, "tasks_assigned.html", data)
|
|
}
|
|
|
|
// NotifyAnswerSubmitted notifies an IB member that a seller submitted an answer.
|
|
func NotifyAnswerSubmitted(m *Mailer, to, answererName, requestTitle, wsName, reviewURL string) error {
|
|
if !m.Enabled() {
|
|
return nil
|
|
}
|
|
|
|
subject := fmt.Sprintf("%s submitted an answer for: %s", answererName, requestTitle)
|
|
data := AnswerSubmittedData{
|
|
AnswererName: answererName,
|
|
RequestTitle: requestTitle,
|
|
WorkstreamName: wsName,
|
|
ReviewURL: reviewURL,
|
|
}
|
|
|
|
return m.SendTemplate(to, subject, "answer_submitted.html", data)
|
|
}
|
|
|
|
// NotifyAnswerApproved notifies a seller that their answer was approved.
|
|
func NotifyAnswerApproved(m *Mailer, to, requestTitle string, published bool) error {
|
|
if !m.Enabled() {
|
|
return nil
|
|
}
|
|
|
|
subject := "Your answer was approved ✓"
|
|
data := AnswerApprovedData{
|
|
RequestTitle: requestTitle,
|
|
Published: published,
|
|
}
|
|
|
|
return m.SendTemplate(to, subject, "answer_approved.html", data)
|
|
}
|
|
|
|
// NotifyAnswerRejected notifies a seller that their answer was rejected.
|
|
func NotifyAnswerRejected(m *Mailer, to, requestTitle, reason, requestURL string) error {
|
|
if !m.Enabled() {
|
|
return nil
|
|
}
|
|
|
|
subject := "Your answer needs revision"
|
|
data := AnswerRejectedData{
|
|
RequestTitle: requestTitle,
|
|
Reason: reason,
|
|
RequestURL: requestURL,
|
|
}
|
|
|
|
return m.SendTemplate(to, subject, "answer_rejected.html", data)
|
|
}
|
|
|
|
// NotifyRequestForwarded notifies a user that a request was forwarded to them.
|
|
func NotifyRequestForwarded(m *Mailer, to, senderName, requestTitle, requestURL string, dueAt *time.Time) error {
|
|
if !m.Enabled() {
|
|
return nil
|
|
}
|
|
|
|
subject := fmt.Sprintf("%s forwarded a request to you: %s", senderName, requestTitle)
|
|
data := RequestForwardedData{
|
|
SenderName: senderName,
|
|
RequestTitle: requestTitle,
|
|
RequestURL: requestURL,
|
|
HasDueDate: dueAt != nil,
|
|
}
|
|
|
|
if dueAt != nil {
|
|
data.DueDate = dueAt.Format("January 2, 2006")
|
|
}
|
|
|
|
return m.SendTemplate(to, subject, "request_forwarded.html", data)
|
|
}
|
|
|
|
// NotifyWelcome sends a welcome email to a new user after accepting an invite.
|
|
func NotifyWelcome(m *Mailer, to, name, tasksURL string) error {
|
|
if !m.Enabled() {
|
|
return nil
|
|
}
|
|
|
|
subject := "Welcome to Dealspace"
|
|
data := WelcomeData{
|
|
RecipientName: name,
|
|
TasksURL: tasksURL,
|
|
}
|
|
|
|
return m.SendTemplate(to, subject, "welcome.html", data)
|
|
}
|