Without a JWT the Phoenix TenantSocket refuses the handshake
("REFUSED CONNECTION TO ArcadiaWeb.TenantSocket"), the client retries
forever, and both ends spam logs. Consumers like skyai-ecosystem set
enableRealtime unconditionally at mount, before login completes, which
is the common case for this noise.
Callers should invoke connect() again after login (e.g. on
crema:session-change) — the existing reconnect path covers that.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Document createSocialBindings + useSocial pattern + the three new
TenantEventMap entries (social:notification, social:post,
social:article) so consumers know the channel events exist.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wires three new shapes to the bindings:
- TenantEventMap gains `social:notification`, `social:post`,
`social:article` — typed payloads for the channel pushes the
Phoenix TenantChannel now forwards. Consumers subscribe via the
existing `useArcadiaSubscription` hook.
- SocialBindings.searchUsers(prefix) → `[{user_id, handle,
display_name}]`. Empty prefix returns []. Powers @ autocomplete.
- SocialBindings.search(query, {limit, kinds}) → discriminated
union of post/article hits. Tenant-scoped server-side;
visibility honored. Empty query returns [].
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Typed wrappers for /api/v1/social/* on arcadia-app. Built over the
generic client.GET/POST surface rather than openapi-fetch — the spec
hasn't been regenerated to cover these endpoints, but the shapes
mirror the Phoenix JSON modules exactly and can migrate to the typed
surface later without caller changes.
Factory `createSocialBindings(client)` returns a SocialBindings
object with one method per operation:
Profiles: getMyProfile, updateMyProfile, getProfile, listProfiles
Articles: listArticles, getArticle, createArticle, updateArticle,
deleteArticle
Board: listFeed, getThread, createPost, reply, updatePost,
deletePost
Favourites: listFavourites, addFavourite, removeFavourite
Subs: listSubscriptions, addSubscription, removeSubscription
Notifs: listNotifications, markNotificationRead,
markAllNotificationsRead
addSubscription takes an optional `lastSeenDnaHash` so callers can
record "the version I just vetted" — the platform's
on_dna_change fanout only pings users whose stored hash differs
from the new value, so passing it on subscribe means the user only
hears about *real* changes, not a notification at the value they
were already looking at.
Wire types mirror the Phoenix JSON modules; SocialNotificationKind
is `"mention" | "post_reply" | "dna_change" | (string & ...)` so
the union stays open to future kinds added platform-side.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>