CREATE TABLE IF NOT EXISTS email_templates ( id BIGSERIAL PRIMARY KEY, slug VARCHAR(100) NOT NULL UNIQUE, name VARCHAR(200) NOT NULL, subject TEXT NOT NULL, body_text TEXT NOT NULL, body_html TEXT NOT NULL, variables JSONB NOT NULL DEFAULT '[]'::jsonb, is_system BOOLEAN NOT NULL DEFAULT FALSE, status VARCHAR(20) NOT NULL DEFAULT 'ACTIVE' CHECK (status IN ('ACTIVE', 'INACTIVE')), created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ ); CREATE INDEX IF NOT EXISTS idx_email_templates_status ON email_templates(status); CREATE INDEX IF NOT EXISTS idx_email_templates_slug ON email_templates(slug); INSERT INTO email_templates (slug, name, subject, body_text, body_html, variables, is_system, status) VALUES ( 'otp', 'One-Time Password', 'Yimaru Academy — Your verification code', 'Yimaru Academy{{if .FirstName}}, {{.FirstName}}{{end}} Your verification code is {{.OTP}}. It expires in {{.ExpiresMinutes}} minutes. Please do not share this code with anyone.', $otp_html$ Yimaru Academy

Yimaru Academy

Online Learning Platform

Your verification code

{{if .FirstName}}Hi {{.FirstName}}, {{end}}use the code below to continue signing in to Yimaru Academy.

One-time password

{{.OTP}}

Expires in {{.ExpiresMinutes}} minutes

If you did not request this code, you can safely ignore this email.

© 2026 Yimaru Academy · All rights reserved

$otp_html$, '["OTP", "FirstName", "ExpiresMinutes"]'::jsonb, TRUE, 'ACTIVE' ), ( 'invitation', 'User Invitation', 'You are invited to Yimaru Academy', 'Hi{{if .FirstName}} {{.FirstName}}{{end}}, You have been invited{{if .InviterName}} by {{.InviterName}}{{end}} to join Yimaru Academy. Accept your invitation: {{.InviteLink}}', $invite_html$ Yimaru Academy

Yimaru Academy

Online Learning Platform

You’re invited

{{if .FirstName}}Hi {{.FirstName}}, {{end}}you have been invited{{if .InviterName}} by {{.InviterName}}{{end}} to join Yimaru Academy.

Accept invitation

Or copy this link: {{.InviteLink}}

© 2026 Yimaru Academy · All rights reserved

$invite_html$, '["FirstName", "InviterName", "InviteLink"]'::jsonb, TRUE, 'ACTIVE' ), ( 'password_reset', 'Password Reset', 'Reset your Yimaru Academy password', 'Hi{{if .FirstName}} {{.FirstName}}{{end}}, Reset your password: {{.ResetLink}} This link expires in {{.ExpiresMinutes}} minutes.', $reset_html$ Yimaru Academy

Yimaru Academy

Online Learning Platform

Reset your password

{{if .FirstName}}Hi {{.FirstName}}, {{end}}we received a request to reset your Yimaru Academy password. The link below expires in {{.ExpiresMinutes}} minutes.

Reset password

If you did not request a reset, ignore this email.

© 2026 Yimaru Academy · All rights reserved

$reset_html$, '["FirstName", "ResetLink", "ExpiresMinutes"]'::jsonb, TRUE, 'ACTIVE' ), ( 'welcome', 'Welcome Email', 'Welcome to Yimaru Academy', 'Hi{{if .FirstName}} {{.FirstName}}{{end}}, Welcome to Yimaru Academy! Sign in to get started: {{.LoginURL}}', $welcome_html$ Yimaru Academy

Yimaru Academy

Online Learning Platform

Welcome aboard

{{if .FirstName}}Hi {{.FirstName}}, {{end}}your Yimaru Academy account is ready. Start learning at your own pace.

Sign in to Yimaru Academy

© 2026 Yimaru Academy · All rights reserved

$welcome_html$, '["FirstName", "LoginURL"]'::jsonb, TRUE, 'ACTIVE' ), ( 'custom_message', 'Custom Message', '{{.Subject}}', '{{.Message}}', $custom_html$ Yimaru Academy

Yimaru Academy

Online Learning Platform

{{.Subject}}

{{.Message}}

© 2026 Yimaru Academy · All rights reserved

$custom_html$, '["Subject", "Message"]'::jsonb, TRUE, 'ACTIVE' ) ON CONFLICT (slug) DO NOTHING;