chore(repo): enforce AX review conventions

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Virgil 2026-03-26 11:17:06 +00:00
parent 86f62429cc
commit ec500b86d2
6 changed files with 34 additions and 10 deletions

View file

@ -4,6 +4,7 @@ run:
linters:
enable:
- depguard
- govet
- errcheck
- staticcheck
@ -17,6 +18,17 @@ linters:
- exhaustive
- wrapcheck
linters-settings:
depguard:
rules:
legacy-module-paths:
list-mode: lax
files:
- $all
deny:
- pkg: forge.lthn.ai/
desc: use dappco.re/ module paths instead
issues:
exclude-use-default: false
max-same-issues: 0

7
doc.go Normal file
View file

@ -0,0 +1,7 @@
// Package store provides a SQLite-backed key-value store with group namespaces,
// TTL expiry, quota-enforced scoped views, and reactive change notifications.
//
// Use New to open a store, then Set/Get for CRUD operations. Use
// NewScoped/NewScopedWithQuota when group names need tenant isolation or
// per-namespace quotas.
package store

View file

@ -375,7 +375,7 @@ func TestWatch_Good_ScopedStoreEvents(t *testing.T) {
// EventType.String()
// ---------------------------------------------------------------------------
func TestEventType_String(t *testing.T) {
func TestEventType_Good_String(t *testing.T) {
assert.Equal(t, "set", EventSet.String())
assert.Equal(t, "delete", EventDelete.String())
assert.Equal(t, "delete_group", EventDeleteGroup.String())

2
go.sum
View file

@ -1,3 +1,5 @@
dappco.re/go/core/log v0.1.0 h1:pa71Vq2TD2aoEUQWFKwNcaJ3GBY8HbaNGqtE688Unyc=
dappco.re/go/core/log v0.1.0/go.mod h1:Nkqb8gsXhZAO8VLpx7B8i1iAmohhzqA20b9Zr8VUcJs=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=

View file

@ -14,9 +14,11 @@ import (
)
// ErrNotFound is returned when a key does not exist in the store.
// Use errors.Is(err, ErrNotFound) to test for it.
var ErrNotFound = coreerr.E("store", "not found", nil)
// ErrQuotaExceeded is returned when a namespace quota limit is reached.
// Use errors.Is(err, ErrQuotaExceeded) to test for it.
var ErrQuotaExceeded = coreerr.E("store", "quota exceeded", nil)
// Store is a group-namespaced key-value store backed by SQLite.
@ -343,6 +345,7 @@ func (s *Store) GroupsSeq(prefix string) iter.Seq2[string, error] {
}
}
// escapeLike escapes SQLite LIKE wildcards and the escape character itself.
func escapeLike(s string) string {
s = strings.ReplaceAll(s, "^", "^^")
s = strings.ReplaceAll(s, "%", "^%")

View file

@ -445,7 +445,7 @@ func TestClose_Good_OperationsFailAfterClose(t *testing.T) {
// Edge cases
// ---------------------------------------------------------------------------
func TestEdgeCases(t *testing.T) {
func TestSetGet_Good_EdgeCases(t *testing.T) {
s, _ := New(":memory:")
defer s.Close()
@ -491,7 +491,7 @@ func TestEdgeCases(t *testing.T) {
// Group isolation
// ---------------------------------------------------------------------------
func TestGroupIsolation(t *testing.T) {
func TestStore_Good_GroupIsolation(t *testing.T) {
s, _ := New(":memory:")
defer s.Close()
@ -520,7 +520,7 @@ func TestGroupIsolation(t *testing.T) {
// Concurrent access
// ---------------------------------------------------------------------------
func TestConcurrent_ReadWrite(t *testing.T) {
func TestConcurrent_Good_ReadWrite(t *testing.T) {
dbPath := filepath.Join(t.TempDir(), "concurrent.db")
s, err := New(dbPath)
require.NoError(t, err)
@ -581,7 +581,7 @@ func TestConcurrent_ReadWrite(t *testing.T) {
}
}
func TestConcurrent_GetAll(t *testing.T) {
func TestConcurrent_Good_GetAll(t *testing.T) {
s, err := New(filepath.Join(t.TempDir(), "getall.db"))
require.NoError(t, err)
defer s.Close()
@ -607,7 +607,7 @@ func TestConcurrent_GetAll(t *testing.T) {
wg.Wait()
}
func TestConcurrent_DeleteGroup(t *testing.T) {
func TestConcurrent_Good_DeleteGroup(t *testing.T) {
s, err := New(filepath.Join(t.TempDir(), "delgrp.db"))
require.NoError(t, err)
defer s.Close()
@ -631,7 +631,7 @@ func TestConcurrent_DeleteGroup(t *testing.T) {
// ErrNotFound wrapping verification
// ---------------------------------------------------------------------------
func TestErrNotFound_Is(t *testing.T) {
func TestErrNotFound_Good_Is(t *testing.T) {
s, _ := New(":memory:")
defer s.Close()
@ -900,7 +900,7 @@ func TestPurgeExpired_Good_BackgroundPurge(t *testing.T) {
// Schema migration — reopening an existing database
// ---------------------------------------------------------------------------
func TestSchemaUpgrade_ExistingDB(t *testing.T) {
func TestSchemaUpgrade_Good_ExistingDB(t *testing.T) {
dbPath := filepath.Join(t.TempDir(), "upgrade.db")
// Open, write, close.
@ -925,7 +925,7 @@ func TestSchemaUpgrade_ExistingDB(t *testing.T) {
assert.Equal(t, "ttl-val", val2)
}
func TestSchemaUpgrade_PreTTLDatabase(t *testing.T) {
func TestSchemaUpgrade_Good_PreTTLDatabase(t *testing.T) {
// Simulate a database created before TTL support (no expires_at column).
dbPath := filepath.Join(t.TempDir(), "pre-ttl.db")
db, err := sql.Open("sqlite", dbPath)
@ -965,7 +965,7 @@ func TestSchemaUpgrade_PreTTLDatabase(t *testing.T) {
// Concurrent TTL access
// ---------------------------------------------------------------------------
func TestConcurrent_TTL(t *testing.T) {
func TestConcurrent_Good_TTL(t *testing.T) {
s, err := New(filepath.Join(t.TempDir(), "concurrent-ttl.db"))
require.NoError(t, err)
defer s.Close()