···652652 hide_others integer default 0
653653 );
654654655655+ create table if not exists newsletter_preferences (
656656+ id integer primary key autoincrement,
657657+ user_did text not null unique,
658658+ status text not null check (status in ('subscribed', 'dismissed')),
659659+ email text,
660660+ updated_at text not null default (strftime('%Y-%m-%dT%H:%M:%SZ', 'now'))
661661+ );
662662+655663 -- indexes for better performance
656664 create index if not exists idx_notifications_recipient_created on notifications(recipient_did, created desc);
657665 create index if not exists idx_notifications_recipient_read on notifications(recipient_did, read);
···660668 create index if not exists idx_webhooks_repo_at on webhooks(repo_at);
661669 create index if not exists idx_webhook_deliveries_webhook_id on webhook_deliveries(webhook_id);
662670 create index if not exists idx_site_deploys_repo_at on site_deploys(repo_at);
671671+ create index if not exists idx_newsletter_prefs_user_did on newsletter_preferences(user_did);
663672 `)
664673 if err != nil {
665674 return nil, err
···14061415 alter table pulls drop column stack_id;
14071416 `)
1408141714091409- return err
14101410- })
14111411-14121412- orm.RunMigration(conn, logger, "add-newsletter-preferences", func(tx *sql.Tx) error {
14131413- _, err := tx.Exec(`
14141414- create table if not exists newsletter_preferences (
14151415- id integer primary key autoincrement,
14161416- user_did text not null unique,
14171417- status text not null check (status in ('subscribed', 'dismissed')),
14181418- email text,
14191419- updated_at text not null default (strftime('%Y-%m-%dT%H:%M:%SZ', 'now'))
14201420- );
14211421- create index if not exists idx_newsletter_prefs_user_did
14221422- on newsletter_preferences(user_did);
14231423- `)
14241418 return err
14251419 })
14261420
+1-4
appview/db/newsletter.go
···4747 if email.Valid {
4848 pref.Email = email.String
4949 }
5050- // Best-effort: the column's default format is ISO-8601, but older rows
5151- // (or manual inserts) might use other layouts. A parse failure is not
5252- // fatal — the zero time is acceptable for a UI gating check.
5353- if t, perr := time.Parse("2006-01-02T15:04:05Z", updatedAt); perr == nil {
5050+ if t, perr := time.Parse(time.RFC3339, updatedAt); perr == nil {
5451 pref.UpdatedAt = t
5552 }
5653
+1-1
appview/db/star.go
···304304 select rsc.subject_at
305305 from repo_star_counts rsc
306306 order by rsc.stars_gained_last_week desc
307307- limit 8
307307+ limit 5
308308 `
309309310310 rows, err := e.Query(query)