fix: address code review findings across backend and frontend
CI / test (pull_request) Successful in 2m13s

Fix goroutine-unsafe ULID entropy by wrapping in LockedMonotonicReader.
Move PRAGMA foreign_keys outside transaction in v3 migration where
SQLite was silently ignoring it. Escape LIKE wildcards in link
resolution to prevent false matches. Add non-localhost binding warning,
log writeJSON encoder errors, add ?permanent=true for explicit hard
delete, preserve title/description during absorb, use millisecond
backup timestamps, add path.Clean to spaHandler. Frontend gains
checkedJSON() for resp.ok validation, consistent stopPropagation, and
shared renderCardSections() to eliminate duplicate rendering.
This commit is contained in:
2026-05-21 16:01:43 -04:00
parent 8426c2fbc1
commit e9ecc4c1f7
12 changed files with 240 additions and 153 deletions
+4 -2
View File
@@ -8,13 +8,15 @@ import (
)
var (
entropy *ulid.MonotonicEntropy
entropy *ulid.LockedMonotonicReader
entropyOnce sync.Once
)
func New() string {
entropyOnce.Do(func() {
entropy = ulid.Monotonic(rand.Reader, 0)
entropy = &ulid.LockedMonotonicReader{
MonotonicReader: ulid.Monotonic(rand.Reader, 0),
}
})
return ulid.MustNew(ulid.Now(), entropy).String()
}
+23
View File
@@ -1,6 +1,7 @@
package ulid
import (
"sync"
"testing"
)
@@ -26,3 +27,25 @@ func TestNew_Sortable(t *testing.T) {
t.Errorf("expected b >= a for sequential calls: a=%s b=%s", a, b)
}
}
func TestNew_ConcurrentUnique(t *testing.T) {
const n = 100
ids := make([]string, n)
var wg sync.WaitGroup
wg.Add(n)
for i := 0; i < n; i++ {
go func(idx int) {
defer wg.Done()
ids[idx] = New()
}(i)
}
wg.Wait()
seen := make(map[string]struct{}, n)
for _, id := range ids {
if _, dup := seen[id]; dup {
t.Fatalf("duplicate ULID under concurrency: %s", id)
}
seen[id] = struct{}{}
}
}