better rum todo
This commit is contained in:
1 parent
cb3266bf33
commit
e81b8c2fcd
6 files changed
+231
-51
No files matched your search
+22
-18
@@ -31,14 +31,16 @@ func clipTo(s string, n int) string {
|
||||
}
|
||||
|
||||
type todoPayload struct {
|
||||
Project string `json:"project"`
|
||||
Text string `json:"text"`
|
||||
Component string `json:"component"`
|
||||
Path string `json:"path"`
|
||||
Hash string `json:"hash"`
|
||||
URL string `json:"url"`
|
||||
UserAgent string `json:"ua"`
|
||||
Session string `json:"session"`
|
||||
Project string `json:"project"`
|
||||
Text string `json:"text"`
|
||||
Component string `json:"component"`
|
||||
Path string `json:"path"`
|
||||
Hash string `json:"hash"`
|
||||
URL string `json:"url"`
|
||||
UserAgent string `json:"ua"`
|
||||
Session string `json:"session"`
|
||||
ElementSelector string `json:"elementSelector"`
|
||||
ElementLabel string `json:"elementLabel"`
|
||||
}
|
||||
|
||||
// HandleTodoCreate ingests a todo posted by otel-todo.js. It is guarded by
|
||||
@@ -72,16 +74,18 @@ func (c *Collector) HandleTodoCreate(w http.ResponseWriter, r *http.Request) {
|
||||
id := make([]byte, 8)
|
||||
_, _ = rand.Read(id)
|
||||
t := todos.Todo{
|
||||
ID: hex.EncodeToString(id),
|
||||
Project: project,
|
||||
Text: text,
|
||||
Component: clipTo(p.Component, maxTodoMeta),
|
||||
Path: clipTo(p.Path, maxTodoMeta),
|
||||
Hash: clipTo(p.Hash, maxTodoMeta),
|
||||
URL: clipTo(p.URL, maxTodoMeta),
|
||||
UserAgent: clipTo(p.UserAgent, maxTodoMeta),
|
||||
Session: clipTo(p.Session, maxTodoMeta),
|
||||
CreatedAt: time.Now().UTC(),
|
||||
ID: hex.EncodeToString(id),
|
||||
Project: project,
|
||||
Text: text,
|
||||
Component: clipTo(p.Component, maxTodoMeta),
|
||||
Path: clipTo(p.Path, maxTodoMeta),
|
||||
Hash: clipTo(p.Hash, maxTodoMeta),
|
||||
URL: clipTo(p.URL, maxTodoMeta),
|
||||
UserAgent: clipTo(p.UserAgent, maxTodoMeta),
|
||||
Session: clipTo(p.Session, maxTodoMeta),
|
||||
ElementSelector: clipTo(p.ElementSelector, maxTodoMeta),
|
||||
ElementLabel: clipTo(p.ElementLabel, maxTodoMeta),
|
||||
CreatedAt: time.Now().UTC(),
|
||||
}
|
||||
if err := c.todoStore.Add(r.Context(), t); err != nil {
|
||||
log.Printf("failed to store todo: %v", err)
|
||||
|
||||
+19
-17
@@ -17,18 +17,20 @@ import (
|
||||
|
||||
// Todo is one note filed from a page. Project is the RUM service name.
|
||||
type Todo struct {
|
||||
ID string `json:"id"`
|
||||
Project string `json:"project"`
|
||||
Text string `json:"text"`
|
||||
Component string `json:"component,omitempty"`
|
||||
Path string `json:"path,omitempty"`
|
||||
Hash string `json:"hash,omitempty"`
|
||||
URL string `json:"url,omitempty"`
|
||||
UserAgent string `json:"userAgent,omitempty"`
|
||||
Session string `json:"session,omitempty"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
Done bool `json:"done"`
|
||||
DoneAt time.Time `json:"doneAt,omitzero"`
|
||||
ID string `json:"id"`
|
||||
Project string `json:"project"`
|
||||
Text string `json:"text"`
|
||||
Component string `json:"component,omitempty"`
|
||||
Path string `json:"path,omitempty"`
|
||||
Hash string `json:"hash,omitempty"`
|
||||
URL string `json:"url,omitempty"`
|
||||
UserAgent string `json:"userAgent,omitempty"`
|
||||
Session string `json:"session,omitempty"`
|
||||
ElementSelector string `json:"elementSelector,omitempty"` // CSS selector of the referenced element, if picked
|
||||
ElementLabel string `json:"elementLabel,omitempty"` // human-readable tag/text summary of that element
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
Done bool `json:"done"`
|
||||
DoneAt time.Time `json:"doneAt,omitzero"`
|
||||
}
|
||||
|
||||
// Store persists todos. List returns newest first; an empty project means all.
|
||||
@@ -154,7 +156,7 @@ func NewClickHouseStore(ctx context.Context, conn driver.Conn, db string) (*Clic
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, col := range []string{"done UInt8", "done_at DateTime64(3, 'UTC')"} {
|
||||
for _, col := range []string{"done UInt8", "done_at DateTime64(3, 'UTC')", "element_selector String", "element_label String"} {
|
||||
if err := conn.Exec(ctx, fmt.Sprintf(`ALTER TABLE %s.todos ADD COLUMN IF NOT EXISTS %s`, db, col)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -163,12 +165,12 @@ func NewClickHouseStore(ctx context.Context, conn driver.Conn, db string) (*Clic
|
||||
}
|
||||
|
||||
func (s *ClickHouseStore) Add(ctx context.Context, t Todo) error {
|
||||
return s.conn.Exec(ctx, fmt.Sprintf(`INSERT INTO %s.todos (id, project, text, component, path, hash, url, user_agent, session, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, s.db),
|
||||
t.ID, t.Project, t.Text, t.Component, t.Path, t.Hash, t.URL, t.UserAgent, t.Session, t.CreatedAt.UTC())
|
||||
return s.conn.Exec(ctx, fmt.Sprintf(`INSERT INTO %s.todos (id, project, text, component, path, hash, url, user_agent, session, element_selector, element_label, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, s.db),
|
||||
t.ID, t.Project, t.Text, t.Component, t.Path, t.Hash, t.URL, t.UserAgent, t.Session, t.ElementSelector, t.ElementLabel, t.CreatedAt.UTC())
|
||||
}
|
||||
|
||||
func (s *ClickHouseStore) List(ctx context.Context, project string, limit int) ([]Todo, error) {
|
||||
q := fmt.Sprintf(`SELECT id, project, text, component, path, hash, url, user_agent, session, created_at, done, done_at FROM %s.todos`, s.db)
|
||||
q := fmt.Sprintf(`SELECT id, project, text, component, path, hash, url, user_agent, session, element_selector, element_label, created_at, done, done_at FROM %s.todos`, s.db)
|
||||
var args []any
|
||||
if project != "" {
|
||||
q += ` WHERE project = ?`
|
||||
@@ -185,7 +187,7 @@ func (s *ClickHouseStore) List(ctx context.Context, project string, limit int) (
|
||||
for rows.Next() {
|
||||
var t Todo
|
||||
var done uint8
|
||||
if err := rows.Scan(&t.ID, &t.Project, &t.Text, &t.Component, &t.Path, &t.Hash, &t.URL, &t.UserAgent, &t.Session, &t.CreatedAt, &done, &t.DoneAt); err != nil {
|
||||
if err := rows.Scan(&t.ID, &t.Project, &t.Text, &t.Component, &t.Path, &t.Hash, &t.URL, &t.UserAgent, &t.Session, &t.ElementSelector, &t.ElementLabel, &t.CreatedAt, &done, &t.DoneAt); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
t.Done = done != 0
|
||||
|
||||
Reference in new issue
Block a user