9f7c9099bc
Synchronous translation on read (Stage D) blocks the HTTP handler on translator I/O. Stage E switches to "send moments-fast, deliver when translated": recipients whose preferred_language differs from the detected body_lang are inserted with available_at=NULL, and an async worker turns them on once a LibreTranslate call materialises the cache row (or fails terminally after 5 retries). Schema delta on diplomail_recipients: available_at, translation_attempts, next_translation_attempt_at, plus a snapshot recipient_preferred_language so the worker queries do not need a join. Read paths (ListInbox, GetMessage, UnreadCount) filter on available_at IS NOT NULL. Push fan-out is moved from Service to the worker so the recipient only sees the toast when the inbox row is actually visible. Translator backend is now a configurable choice: empty BACKEND_DIPLOMAIL_TRANSLATOR_URL → noop (deliver original); populated → LibreTranslate HTTP client. Per-attempt timeout, max attempts, and worker interval all live in DiplomailConfig. The HTTP client itself is unit-tested via httptest (happy path, BCP47 normalisation, unsupported pair, 5xx, identical src/dst, missing URL); worker delivery + fallback paths are covered by the testcontainers-backed e2e tests in diplomail_e2e_test.go. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
118 lines
5.4 KiB
Go
118 lines
5.4 KiB
Go
//
|
|
// Code generated by go-jet DO NOT EDIT.
|
|
//
|
|
// WARNING: Changes to this file may cause incorrect behavior
|
|
// and will be lost if the code is regenerated
|
|
//
|
|
|
|
package table
|
|
|
|
import (
|
|
"github.com/go-jet/jet/v2/postgres"
|
|
)
|
|
|
|
var DiplomailRecipients = newDiplomailRecipientsTable("backend", "diplomail_recipients", "")
|
|
|
|
type diplomailRecipientsTable struct {
|
|
postgres.Table
|
|
|
|
// Columns
|
|
RecipientID postgres.ColumnString
|
|
MessageID postgres.ColumnString
|
|
GameID postgres.ColumnString
|
|
UserID postgres.ColumnString
|
|
RecipientUserName postgres.ColumnString
|
|
RecipientRaceName postgres.ColumnString
|
|
RecipientPreferredLanguage postgres.ColumnString
|
|
AvailableAt postgres.ColumnTimestampz
|
|
TranslationAttempts postgres.ColumnInteger
|
|
NextTranslationAttemptAt postgres.ColumnTimestampz
|
|
DeliveredAt postgres.ColumnTimestampz
|
|
ReadAt postgres.ColumnTimestampz
|
|
DeletedAt postgres.ColumnTimestampz
|
|
NotifiedAt postgres.ColumnTimestampz
|
|
|
|
AllColumns postgres.ColumnList
|
|
MutableColumns postgres.ColumnList
|
|
DefaultColumns postgres.ColumnList
|
|
}
|
|
|
|
type DiplomailRecipientsTable struct {
|
|
diplomailRecipientsTable
|
|
|
|
EXCLUDED diplomailRecipientsTable
|
|
}
|
|
|
|
// AS creates new DiplomailRecipientsTable with assigned alias
|
|
func (a DiplomailRecipientsTable) AS(alias string) *DiplomailRecipientsTable {
|
|
return newDiplomailRecipientsTable(a.SchemaName(), a.TableName(), alias)
|
|
}
|
|
|
|
// Schema creates new DiplomailRecipientsTable with assigned schema name
|
|
func (a DiplomailRecipientsTable) FromSchema(schemaName string) *DiplomailRecipientsTable {
|
|
return newDiplomailRecipientsTable(schemaName, a.TableName(), a.Alias())
|
|
}
|
|
|
|
// WithPrefix creates new DiplomailRecipientsTable with assigned table prefix
|
|
func (a DiplomailRecipientsTable) WithPrefix(prefix string) *DiplomailRecipientsTable {
|
|
return newDiplomailRecipientsTable(a.SchemaName(), prefix+a.TableName(), a.TableName())
|
|
}
|
|
|
|
// WithSuffix creates new DiplomailRecipientsTable with assigned table suffix
|
|
func (a DiplomailRecipientsTable) WithSuffix(suffix string) *DiplomailRecipientsTable {
|
|
return newDiplomailRecipientsTable(a.SchemaName(), a.TableName()+suffix, a.TableName())
|
|
}
|
|
|
|
func newDiplomailRecipientsTable(schemaName, tableName, alias string) *DiplomailRecipientsTable {
|
|
return &DiplomailRecipientsTable{
|
|
diplomailRecipientsTable: newDiplomailRecipientsTableImpl(schemaName, tableName, alias),
|
|
EXCLUDED: newDiplomailRecipientsTableImpl("", "excluded", ""),
|
|
}
|
|
}
|
|
|
|
func newDiplomailRecipientsTableImpl(schemaName, tableName, alias string) diplomailRecipientsTable {
|
|
var (
|
|
RecipientIDColumn = postgres.StringColumn("recipient_id")
|
|
MessageIDColumn = postgres.StringColumn("message_id")
|
|
GameIDColumn = postgres.StringColumn("game_id")
|
|
UserIDColumn = postgres.StringColumn("user_id")
|
|
RecipientUserNameColumn = postgres.StringColumn("recipient_user_name")
|
|
RecipientRaceNameColumn = postgres.StringColumn("recipient_race_name")
|
|
RecipientPreferredLanguageColumn = postgres.StringColumn("recipient_preferred_language")
|
|
AvailableAtColumn = postgres.TimestampzColumn("available_at")
|
|
TranslationAttemptsColumn = postgres.IntegerColumn("translation_attempts")
|
|
NextTranslationAttemptAtColumn = postgres.TimestampzColumn("next_translation_attempt_at")
|
|
DeliveredAtColumn = postgres.TimestampzColumn("delivered_at")
|
|
ReadAtColumn = postgres.TimestampzColumn("read_at")
|
|
DeletedAtColumn = postgres.TimestampzColumn("deleted_at")
|
|
NotifiedAtColumn = postgres.TimestampzColumn("notified_at")
|
|
allColumns = postgres.ColumnList{RecipientIDColumn, MessageIDColumn, GameIDColumn, UserIDColumn, RecipientUserNameColumn, RecipientRaceNameColumn, RecipientPreferredLanguageColumn, AvailableAtColumn, TranslationAttemptsColumn, NextTranslationAttemptAtColumn, DeliveredAtColumn, ReadAtColumn, DeletedAtColumn, NotifiedAtColumn}
|
|
mutableColumns = postgres.ColumnList{MessageIDColumn, GameIDColumn, UserIDColumn, RecipientUserNameColumn, RecipientRaceNameColumn, RecipientPreferredLanguageColumn, AvailableAtColumn, TranslationAttemptsColumn, NextTranslationAttemptAtColumn, DeliveredAtColumn, ReadAtColumn, DeletedAtColumn, NotifiedAtColumn}
|
|
defaultColumns = postgres.ColumnList{RecipientPreferredLanguageColumn, TranslationAttemptsColumn}
|
|
)
|
|
|
|
return diplomailRecipientsTable{
|
|
Table: postgres.NewTable(schemaName, tableName, alias, allColumns...),
|
|
|
|
//Columns
|
|
RecipientID: RecipientIDColumn,
|
|
MessageID: MessageIDColumn,
|
|
GameID: GameIDColumn,
|
|
UserID: UserIDColumn,
|
|
RecipientUserName: RecipientUserNameColumn,
|
|
RecipientRaceName: RecipientRaceNameColumn,
|
|
RecipientPreferredLanguage: RecipientPreferredLanguageColumn,
|
|
AvailableAt: AvailableAtColumn,
|
|
TranslationAttempts: TranslationAttemptsColumn,
|
|
NextTranslationAttemptAt: NextTranslationAttemptAtColumn,
|
|
DeliveredAt: DeliveredAtColumn,
|
|
ReadAt: ReadAtColumn,
|
|
DeletedAt: DeletedAtColumn,
|
|
NotifiedAt: NotifiedAtColumn,
|
|
|
|
AllColumns: allColumns,
|
|
MutableColumns: mutableColumns,
|
|
DefaultColumns: defaultColumns,
|
|
}
|
|
}
|