mirror of
https://github.com/tiennm99/miti99bot.git
synced 2026-09-15 06:20:28 +00:00
Implements Phases 02 (partial) and 03 of the go-port-cloud-run plan. Introduces module framework with per-module KV prefix isolation, health check endpoint, request timeout protection, and comprehensive test coverage. Cloud Run deployment deferred to Phase 01. Security hardening: constant-time secret comparison, cron auth bridge, and secrets stripped from dependency environment exports. Includes Dockerfile, GitHub CI workflow (vet + race + build), and integration tests for module lifecycle.
56 lines
1.5 KiB
Go
56 lines
1.5 KiB
Go
package storage
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
)
|
|
|
|
// Prefixed returns a KVStore that transparently prepends prefix+":" to every
|
|
// key. List() strips the prefix from returned keys so callers see their own
|
|
// flat namespace. The prefix must be non-empty.
|
|
func Prefixed(inner KVStore, prefix string) KVStore {
|
|
if prefix == "" {
|
|
panic("storage: Prefixed requires non-empty prefix")
|
|
}
|
|
return &prefixedStore{inner: inner, prefix: prefix + ":"}
|
|
}
|
|
|
|
type prefixedStore struct {
|
|
inner KVStore
|
|
prefix string
|
|
}
|
|
|
|
func (p *prefixedStore) k(key string) string { return p.prefix + key }
|
|
|
|
func (p *prefixedStore) Get(ctx context.Context, key string) ([]byte, error) {
|
|
return p.inner.Get(ctx, p.k(key))
|
|
}
|
|
|
|
func (p *prefixedStore) GetJSON(ctx context.Context, key string, dst any) error {
|
|
return p.inner.GetJSON(ctx, p.k(key), dst)
|
|
}
|
|
|
|
func (p *prefixedStore) Put(ctx context.Context, key string, val []byte) error {
|
|
return p.inner.Put(ctx, p.k(key), val)
|
|
}
|
|
|
|
func (p *prefixedStore) PutJSON(ctx context.Context, key string, val any) error {
|
|
return p.inner.PutJSON(ctx, p.k(key), val)
|
|
}
|
|
|
|
func (p *prefixedStore) Delete(ctx context.Context, key string) error {
|
|
return p.inner.Delete(ctx, p.k(key))
|
|
}
|
|
|
|
func (p *prefixedStore) List(ctx context.Context, prefix string) ([]string, error) {
|
|
keys, err := p.inner.List(ctx, p.k(prefix))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
out := make([]string, len(keys))
|
|
for i, k := range keys {
|
|
out[i] = strings.TrimPrefix(k, p.prefix)
|
|
}
|
|
return out, nil
|
|
}
|