- Add digest field to store sha256(method|path|body) separately from key - Enables detection of "same key, different body" in future tasks - Update idempotent.wo insert to compute and store digest value - Typechecker passes: exit 0 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> (cherry picked from commit 3a9bddcd1e3c11f5b371ce54cafc373685ca08b6)
25 lines
No EOL
900 B
Text
25 lines
No EOL
900 B
Text
-- porch/middleware/store.wo — store-backed middleware tables.
|
|
-- Two purpose-shaped @table classes for rate limiting and idempotency.
|
|
-- Iteration 1 of the porch track.
|
|
|
|
-- Rate limiter: fixed-window counter.
|
|
-- Key format: "ip:192.168.1.1" or "principal:alice"
|
|
-- Window = start of current window in time.ticks (µs monotonic)
|
|
@table(name: "rate_limit_counters", index: [key])
|
|
class RateLimitCounter {
|
|
key: Text @unique
|
|
count: Int
|
|
window: Int
|
|
}
|
|
|
|
-- Idempotency: stored response for replay.
|
|
-- Key format: "idem:keyheader" or "idem:keyheader:sha256(method|path|body)"
|
|
-- Response = JSON-encoded Resp {status, headers, body} (allowlist: status, body, content-type)
|
|
-- created_at = time.ticks when stored (µs monotonic) for lazy expiry
|
|
@table(name: "idempotency_keys", index: [key])
|
|
class IdempotencyKey {
|
|
key: Text @unique
|
|
response: Text
|
|
created_at: Int
|
|
digest: Text
|
|
} |