feat: resource caps, Saved Messages, author walls, docs for node bring-up

Node flags (cmd/node/main.go):
  --max-cpu / --max-ram-mb — Go runtime caps (GOMAXPROCS / GOMEMLIMIT)
  --feed-disk-limit-mb — hard 507 refusal for new post bodies over quota
  --chain-disk-limit-mb — advisory watcher (can't reject blocks without
  breaking consensus; logs WARN every minute)

Client — Saved Messages (self-chat):
  - Auto-created on sign-in, pinned top of chat list, blue bookmark avatar
  - Send short-circuits the relay (no encrypt, no fee, no mailbox hop)
  - Empty state rendered outside inverted FlatList — fixes the mirrored
    "say hi…" on Android RTL-aware layout builds
  - PostCard shows "You" for own posts instead of the self-contact alias

Client — user walls:
  - New route /(app)/feed/author/[pub] with infinite-scroll via
    `created_at` cursor and pull-to-refresh
  - Profile screen gains "View posts" button (universal) next to
    "Open chat" (contact-only)

Feed pipeline:
  - Bump client JPEG quality 0.5 → 0.75 to match server scrubber (Q=75),
    so a 60 KiB compose doesn't balloon past 256 KiB after server re-encode
  - ErrPostTooLarge now wraps with the actual size vs cap, errors.Is
    preserved in the HTTP layer
  - FeedMailbox quota + DiskUsage surface — supports new CLI flag

README:
  - Step-by-step "first node / joiner" section on the landing page,
    full flag tables incl. the new resource-cap group, minimal
    checklists for open/private/low-end deployments
This commit is contained in:
vsecoder
2026-04-19 13:14:47 +03:00
parent e6f3d2bcf8
commit a75cbcd224
18 changed files with 870 additions and 102 deletions

View File

@@ -1,6 +1,7 @@
package relay
import (
"errors"
"os"
"testing"
"time"
@@ -12,7 +13,7 @@ func newTestFeedMailbox(t *testing.T) *FeedMailbox {
if err != nil {
t.Fatalf("MkdirTemp: %v", err)
}
fm, err := OpenFeedMailbox(dir, 24*time.Hour)
fm, err := OpenFeedMailbox(dir, 24*time.Hour, 0)
if err != nil {
_ = os.RemoveAll(dir)
t.Fatalf("OpenFeedMailbox: %v", err)
@@ -75,7 +76,7 @@ func TestFeedMailboxTooLarge(t *testing.T) {
Author: "a",
Attachment: big,
}
if _, err := fm.Store(post, 0); err != ErrPostTooLarge {
if _, err := fm.Store(post, 0); !errors.Is(err, ErrPostTooLarge) {
t.Fatalf("Store huge post: got %v, want ErrPostTooLarge", err)
}
}