1
0
forked from wrenn/wrenn

Move email types to pkg/email for cloud repo access

Extracts Mailer interface, EmailData, and Button to pkg/email/types.go
so the cloud repo can use them via ServerContext. internal/email re-exports
the types as aliases so existing callers are unchanged. Also fixes
pre-existing lint errors (unchecked rollback and deadline calls).
This commit is contained in:
2026-04-17 16:36:54 +06:00
parent 605ad666a0
commit 5fa3529df9
6 changed files with 38 additions and 25 deletions

View File

@ -533,7 +533,7 @@ func (h *meHandler) DeleteAccount(w http.ResponseWriter, r *http.Request) {
writeError(w, http.StatusInternalServerError, "db_error", "failed to start transaction") writeError(w, http.StatusInternalServerError, "db_error", "failed to start transaction")
return return
} }
defer tx.Rollback(ctx) defer func() { _ = tx.Rollback(ctx) }()
qtx := h.db.WithTx(tx) qtx := h.db.WithTx(tx)

View File

@ -43,14 +43,14 @@ type wsAuthMsg struct {
// authenticated context. The caller must send this as the first message after // authenticated context. The caller must send this as the first message after
// connecting. // connecting.
func wsAuthenticate(ctx context.Context, conn *websocket.Conn, jwtSecret []byte, queries *db.Queries) (auth.AuthContext, error) { func wsAuthenticate(ctx context.Context, conn *websocket.Conn, jwtSecret []byte, queries *db.Queries) (auth.AuthContext, error) {
conn.SetReadDeadline(time.Now().Add(5 * time.Second)) _ = conn.SetReadDeadline(time.Now().Add(5 * time.Second))
var msg wsAuthMsg var msg wsAuthMsg
if err := conn.ReadJSON(&msg); err != nil { if err := conn.ReadJSON(&msg); err != nil {
return auth.AuthContext{}, fmt.Errorf("read auth message: %w", err) return auth.AuthContext{}, fmt.Errorf("read auth message: %w", err)
} }
conn.SetReadDeadline(time.Time{}) // clear deadline _ = conn.SetReadDeadline(time.Time{}) // clear deadline
if msg.Type != "auth" || msg.Token == "" { if msg.Type != "auth" || msg.Token == "" {
return auth.AuthContext{}, fmt.Errorf("first message must be type 'auth' with a token") return auth.AuthContext{}, fmt.Errorf("first message must be type 'auth' with a token")

View File

@ -20,6 +20,8 @@ import (
"net/url" "net/url"
"strconv" "strconv"
"strings" "strings"
emailtypes "git.omukk.dev/wrenn/wrenn/pkg/email"
) )
// Config holds SMTP connection credentials. All fields except Host are // Config holds SMTP connection credentials. All fields except Host are
@ -32,26 +34,10 @@ type Config struct {
FromEmail string // envelope sender address FromEmail string // envelope sender address
} }
// Mailer sends transactional emails. // Re-export public types so existing internal/ callers don't need to change imports.
type Mailer interface { type Mailer = emailtypes.Mailer
Send(ctx context.Context, to string, subject string, data EmailData) error type EmailData = emailtypes.EmailData
} type Button = emailtypes.Button
// EmailData is the generic payload for all transactional emails.
// Templates conditionally render each field based on presence.
type EmailData struct {
RecipientName string // optional — used after "Hello"
Message string // main body (plain text; HTML template wraps it)
Button *Button // optional CTA button
Closing string // optional closing/footer message
}
// Button represents a call-to-action link rendered as a button in HTML
// and as a plain URL in the text variant.
type Button struct {
Text string // button label
URL string // target URL
}
// New constructs a Mailer. If cfg.Host is empty, returns a no-op mailer // New constructs a Mailer. If cfg.Host is empty, returns a no-op mailer
// that logs at debug level and discards. Panics if templates fail to parse // that logs at debug level and discards. Panics if templates fail to parse

View File

@ -10,11 +10,11 @@ import (
"github.com/jackc/pgx/v5/pgxpool" "github.com/jackc/pgx/v5/pgxpool"
"github.com/redis/go-redis/v9" "github.com/redis/go-redis/v9"
"git.omukk.dev/wrenn/wrenn/internal/email"
"git.omukk.dev/wrenn/wrenn/pkg/audit" "git.omukk.dev/wrenn/wrenn/pkg/audit"
"git.omukk.dev/wrenn/wrenn/pkg/auth" "git.omukk.dev/wrenn/wrenn/pkg/auth"
"git.omukk.dev/wrenn/wrenn/pkg/config" "git.omukk.dev/wrenn/wrenn/pkg/config"
"git.omukk.dev/wrenn/wrenn/pkg/db" "git.omukk.dev/wrenn/wrenn/pkg/db"
"git.omukk.dev/wrenn/wrenn/pkg/email"
"git.omukk.dev/wrenn/wrenn/pkg/lifecycle" "git.omukk.dev/wrenn/wrenn/pkg/lifecycle"
"git.omukk.dev/wrenn/wrenn/pkg/scheduler" "git.omukk.dev/wrenn/wrenn/pkg/scheduler"
) )

27
pkg/email/types.go Normal file
View File

@ -0,0 +1,27 @@
// Package email defines the public types for transactional email sending.
// The implementation lives in internal/email — this package only exposes
// the interface and data types so the cloud repo can use them via ServerContext.
package email
import "context"
// Mailer sends transactional emails.
type Mailer interface {
Send(ctx context.Context, to string, subject string, data EmailData) error
}
// EmailData is the generic payload for all transactional emails.
// Templates conditionally render each field based on presence.
type EmailData struct {
RecipientName string // optional — used after "Hello"
Message string // main body (plain text; HTML template wraps it)
Button *Button // optional CTA button
Closing string // optional closing/footer message
}
// Button represents a call-to-action link rendered as a button in HTML
// and as a plain URL in the text variant.
type Button struct {
Text string // button label
URL string // target URL
}