From e9bb22327c21a054d7921ca06911c9435d7be28f Mon Sep 17 00:00:00 2001 From: Seongmin Lee Date: Sun, 13 Jul 2025 15:30:51 +0900 Subject: [PATCH] appview: db/issues: add `ID` field to `Issue` Change-Id: ukwupvsrvxtvppwwlsrvppsrynwolqos This will help indexing Issues faster when we introduce external search indexer Signed-off-by: Seongmin Lee --- appview/db/issues.go | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/appview/db/issues.go b/appview/db/issues.go index fe5b441b..a5a80bba 100644 --- a/appview/db/issues.go +++ b/appview/db/issues.go @@ -9,6 +9,7 @@ import ( ) type Issue struct { + ID int64 RepoAt syntax.ATURI OwnerDid string IssueId int @@ -65,7 +66,7 @@ func NewIssue(tx *sql.Tx, issue *Issue) error { issue.IssueId = nextId - _, err = tx.Exec(` + res, err := tx.Exec(` insert into issues (repo_at, owner_did, issue_id, title, body) values (?, ?, ?, ?, ?) `, issue.RepoAt, issue.OwnerDid, issue.IssueId, issue.Title, issue.Body) @@ -73,6 +74,12 @@ func NewIssue(tx *sql.Tx, issue *Issue) error { return err } + lastID, err := res.LastInsertId() + if err != nil { + return err + } + issue.ID = lastID + if err := tx.Commit(); err != nil { return err } @@ -114,6 +121,7 @@ func GetIssues(e Execer, repoAt syntax.ATURI, isOpen bool, page pagination.Page) ` with numbered_issue as ( select + i.id, i.owner_did, i.issue_id, i.created, @@ -132,6 +140,7 @@ func GetIssues(e Execer, repoAt syntax.ATURI, isOpen bool, page pagination.Page) i.id, i.owner_did, i.issue_id, i.created, i.title, i.body, i.open ) select + id, owner_did, issue_id, created, @@ -153,7 +162,7 @@ func GetIssues(e Execer, repoAt syntax.ATURI, isOpen bool, page pagination.Page) var issue Issue var createdAt string var metadata IssueMetadata - err := rows.Scan(&issue.OwnerDid, &issue.IssueId, &createdAt, &issue.Title, &issue.Body, &issue.Open, &metadata.CommentCount) + err := rows.Scan(&issue.ID, &issue.OwnerDid, &issue.IssueId, &createdAt, &issue.Title, &issue.Body, &issue.Open, &metadata.CommentCount) if err != nil { return nil, err } @@ -182,6 +191,7 @@ func GetIssuesByOwnerDid(e Execer, ownerDid string, timeframe string) ([]Issue, rows, err := e.Query( `select + i.id, i.owner_did, i.repo_at, i.issue_id, @@ -213,6 +223,7 @@ func GetIssuesByOwnerDid(e Execer, ownerDid string, timeframe string) ([]Issue, var issueCreatedAt, repoCreatedAt string var repo Repo err := rows.Scan( + &issue.ID, &issue.OwnerDid, &issue.RepoAt, &issue.IssueId, @@ -257,12 +268,12 @@ func GetIssuesByOwnerDid(e Execer, ownerDid string, timeframe string) ([]Issue, } func GetIssue(e Execer, repoAt syntax.ATURI, issueId int) (*Issue, error) { - query := `select owner_did, created, title, body, open from issues where repo_at = ? and issue_id = ?` + query := `select id, owner_did, created, title, body, open from issues where repo_at = ? and issue_id = ?` row := e.QueryRow(query, repoAt, issueId) var issue Issue var createdAt string - err := row.Scan(&issue.OwnerDid, &createdAt, &issue.Title, &issue.Body, &issue.Open) + err := row.Scan(&issue.ID, &issue.OwnerDid, &createdAt, &issue.Title, &issue.Body, &issue.Open) if err != nil { return nil, err } @@ -277,12 +288,12 @@ func GetIssue(e Execer, repoAt syntax.ATURI, issueId int) (*Issue, error) { } func GetIssueWithComments(e Execer, repoAt syntax.ATURI, issueId int) (*Issue, []Comment, error) { - query := `select owner_did, issue_id, created, title, body, open from issues where repo_at = ? and issue_id = ?` + query := `select id, owner_did, issue_id, created, title, body, open from issues where repo_at = ? and issue_id = ?` row := e.QueryRow(query, repoAt, issueId) var issue Issue var createdAt string - err := row.Scan(&issue.OwnerDid, &issue.IssueId, &createdAt, &issue.Title, &issue.Body, &issue.Open) + err := row.Scan(&issue.ID, &issue.OwnerDid, &issue.IssueId, &createdAt, &issue.Title, &issue.Body, &issue.Open) if err != nil { return nil, nil, err } -- 2.43.0 From fd6b1f92f45c1ca7cb54af14374d24540c9c09cf Mon Sep 17 00:00:00 2001 From: Seongmin Lee Date: Sun, 13 Jul 2025 15:33:51 +0900 Subject: [PATCH] appview: {db,issues}: remove unnecessary `GetIssueId` method Change-Id: ppqppuxrnlkqqkksyqylnmmxwnyptsqn As `issue.IssueId` is already retrieved from `NewIssue`, We don't need `GetIssueId` to get last issue-id. Using same, last inserted issue-id would be better. Signed-off-by: Seongmin Lee --- appview/db/issues.go | 6 ------ appview/issues/issues.go | 20 +++++++------------- 2 files changed, 7 insertions(+), 19 deletions(-) diff --git a/appview/db/issues.go b/appview/db/issues.go index a5a80bba..7f68d1b1 100644 --- a/appview/db/issues.go +++ b/appview/db/issues.go @@ -98,12 +98,6 @@ func GetIssueAt(e Execer, repoAt syntax.ATURI, issueId int) (string, error) { return issueAt, err } -func GetIssueId(e Execer, repoAt syntax.ATURI) (int, error) { - var issueId int - err := e.QueryRow(`select next_issue_id from repo_issue_seqs where repo_at = ?`, repoAt).Scan(&issueId) - return issueId - 1, err -} - func GetIssueOwnerDid(e Execer, repoAt syntax.ATURI, issueId int) (string, error) { var ownerDid string err := e.QueryRow(`select owner_did from issues where repo_at = ? and issue_id = ?`, repoAt, issueId).Scan(&ownerDid) diff --git a/appview/issues/issues.go b/appview/issues/issues.go index fb227d3d..647bd71b 100644 --- a/appview/issues/issues.go +++ b/appview/issues/issues.go @@ -687,21 +687,15 @@ func (rp *Issues) NewIssue(w http.ResponseWriter, r *http.Request) { return } - err = db.NewIssue(tx, &db.Issue{ + issue := &db.Issue{ RepoAt: f.RepoAt, Title: title, Body: body, OwnerDid: user.Did, - }) - if err != nil { - log.Println("failed to create issue", err) - rp.pages.Notice(w, "issues", "Failed to create issue.") - return } - - issueId, err := db.GetIssueId(rp.db, f.RepoAt) + err = db.NewIssue(tx, issue) if err != nil { - log.Println("failed to get issue id", err) + log.Println("failed to create issue", err) rp.pages.Notice(w, "issues", "Failed to create issue.") return } @@ -723,7 +717,7 @@ func (rp *Issues) NewIssue(w http.ResponseWriter, r *http.Request) { Title: title, Body: &body, Owner: user.Did, - IssueId: int64(issueId), + IssueId: int64(issue.IssueId), }, }, }) @@ -733,7 +727,7 @@ func (rp *Issues) NewIssue(w http.ResponseWriter, r *http.Request) { return } - err = db.SetIssueAt(rp.db, f.RepoAt, issueId, resp.Uri) + err = db.SetIssueAt(rp.db, f.RepoAt, issue.IssueId, resp.Uri) if err != nil { log.Println("failed to set issue at", err) rp.pages.Notice(w, "issues", "Failed to create issue.") @@ -744,14 +738,14 @@ func (rp *Issues) NewIssue(w http.ResponseWriter, r *http.Request) { err = rp.posthog.Enqueue(posthog.Capture{ DistinctId: user.Did, Event: "new_issue", - Properties: posthog.Properties{"repo_at": f.RepoAt.String(), "issue_id": issueId}, + Properties: posthog.Properties{"repo_at": f.RepoAt.String(), "issue_id": issue.IssueId}, }) if err != nil { log.Println("failed to enqueue posthog event:", err) } } - rp.pages.HxLocation(w, fmt.Sprintf("/%s/issues/%d", f.OwnerSlashRepo(), issueId)) + rp.pages.HxLocation(w, fmt.Sprintf("/%s/issues/%d", f.OwnerSlashRepo(), issue.IssueId)) return } } -- 2.43.0 From ea1b2936755e5f67fd6cb253441ad2fbdfee4b78 Mon Sep 17 00:00:00 2001 From: Seongmin Lee Date: Sat, 12 Jul 2025 20:28:10 +0900 Subject: [PATCH] appview: add internal notification system Change-Id: quxnxquxmqrzpwkqzryqlxvwsptomlzs Signed-off-by: Seongmin Lee --- appview/notify/merged_notifier.go | 37 +++++++++++++++++++++++++++++++ appview/notify/notifier.go | 14 ++++++++++++ appview/state/router.go | 2 +- appview/state/state.go | 6 +++++ 4 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 appview/notify/merged_notifier.go create mode 100644 appview/notify/notifier.go diff --git a/appview/notify/merged_notifier.go b/appview/notify/merged_notifier.go new file mode 100644 index 00000000..2c78fcb3 --- /dev/null +++ b/appview/notify/merged_notifier.go @@ -0,0 +1,37 @@ +package notify + +import ( + "context" + + "tangled.sh/tangled.sh/core/appview/db" +) + +type mergedNotifier struct { + notifiers []Notifier +} + +func NewMergedNotifier(notifiers ...Notifier) Notifier { + return &mergedNotifier{ + notifiers, + } +} + +var _ Notifier = &mergedNotifier{} + +func (m *mergedNotifier) NewIssue(ctx context.Context, issue db.Issue) { + for _, notifier := range m.notifiers { + notifier.NewIssue(ctx, issue) + } +} + +func (m *mergedNotifier) NewIssueComment(ctx context.Context, comment db.Comment) { + for _, notifier := range m.notifiers { + notifier.NewIssueComment(ctx, comment) + } +} + +func (m *mergedNotifier) NewPullComment(ctx context.Context, comment db.PullComment) { + for _, notifier := range m.notifiers { + notifier.NewPullComment(ctx, comment) + } +} diff --git a/appview/notify/notifier.go b/appview/notify/notifier.go new file mode 100644 index 00000000..44151df6 --- /dev/null +++ b/appview/notify/notifier.go @@ -0,0 +1,14 @@ +package notify + +import ( + "context" + + "tangled.sh/tangled.sh/core/appview/db" +) + +type Notifier interface { + NewIssue(ctx context.Context, issue db.Issue) + NewIssueComment(ctx context.Context, comment db.Comment) + + NewPullComment(ctx context.Context, comment db.PullComment) +} diff --git a/appview/state/router.go b/appview/state/router.go index da986e31..1c9aa1cd 100644 --- a/appview/state/router.go +++ b/appview/state/router.go @@ -191,7 +191,7 @@ func (s *State) SpindlesRouter() http.Handler { } func (s *State) IssuesRouter(mw *middleware.Middleware) http.Handler { - issues := issues.New(s.oauth, s.repoResolver, s.pages, s.idResolver, s.db, s.config, s.posthog) + issues := issues.New(s.oauth, s.repoResolver, s.pages, s.idResolver, s.db, s.config, s.posthog, s.notifier) return issues.Router(mw) } diff --git a/appview/state/state.go b/appview/state/state.go index 7e4709b1..f97d41a5 100644 --- a/appview/state/state.go +++ b/appview/state/state.go @@ -25,6 +25,7 @@ import ( "tangled.sh/tangled.sh/core/appview/config" "tangled.sh/tangled.sh/core/appview/db" "tangled.sh/tangled.sh/core/appview/idresolver" + "tangled.sh/tangled.sh/core/appview/notify" "tangled.sh/tangled.sh/core/appview/oauth" "tangled.sh/tangled.sh/core/appview/pages" "tangled.sh/tangled.sh/core/appview/reporesolver" @@ -37,6 +38,7 @@ import ( type State struct { db *db.DB + notifier notify.Notifier oauth *oauth.OAuth enforcer *rbac.Enforcer tidClock syntax.TIDClock @@ -134,8 +136,12 @@ func Make(ctx context.Context, config *config.Config) (*State, error) { } spindlestream.Start(ctx) + notifier := notify.NewMergedNotifier( + ) + state := &State{ d, + notifier, oauth, enforcer, clock, -- 2.43.0