feat(inbox): inbox messaging + UI polish, client form a11y, integration rate-limit fix#267
Merged
Conversation
Introduce a full inbox feature allowing messages to be sent, scheduled, and managed for both organizations and users. Includes client and management API endpoints, pubsub consumers for async delivery across push (APNS, FCM, WebPush), email, and SMS channels, a scheduler for timed messages, RBAC permissions, database migrations, and a console UI for viewing inbox messages.
Add dedicated channel preview frames (email, phone, push, inbox) and an inbox channel preview, message expanded row, and inbox channel metadata. Extract reusable events layouts for organizations and users, and shared date-time helpers. Refine inbox detail/scheduled tables, datetime editing, broadcast scheduling, and campaign template setup. Tidy inbox scheduler and pubsub consumers for organization/user delivery.
Bring the inbox branch up to date with main, which had already integrated the inbox feature (PR #238) plus subsequent fixes, the client-API auth/RBAC overhaul, access-policies, new providers, and a codebase-wide react-hook-form + zod form-validation refactor. Conflict resolution: - Backend inbox pipeline (consumers, scheduler, store, client controllers, OAPI specs + generated code, migrations, tests): took main's version. Main's design is the tested, integrated baseline (JetStream Msg-Id dedup, sent_at guard, empty-recipient guard). The local refinement commit's parallel backend changes (enriched lifecycle payload, transactional publish-before- commit, email-subject guard) are superseded by main's equivalents. - Frontend inbox UI (preview.tsx, inbox-detail-table.tsx): kept the local refined versions (dedicated Frame preview components incl. the inbox channel preview, message expanded row). Added an inbox template branch to preview.tsx so the generic Preview renders main's new inbox campaign channel via InboxNotificationCenter. - Org/User detail nav: kept both the inbox tab (local) and the scheduled tab (main); added missing CalendarClock import. - scheduled-detail-table.tsx and CreateBroadcastDialog.tsx: took main's version to adopt its react-hook-form + zod validation architecture. The local split date/time picker UX for these two forms is set aside in favor of main's validated forms. - apikeys removed on main (replaced by auth_methods); en.json took main's superset of i18n keys. Verified: go build ./..., go vet on inbox packages, and console tsc --noEmit all pass.
… rate-limit validation
Inbox:
- Preview renders the notification-center card (matching the campaign
preview) instead of the standalone InboxFrame; pass through the sent
time and apply the violet accent styling.
- Add a `time` prop to InboxNotificationCenter so previews can show the
actual sent time rather than always "now".
- Wrap the expand chevron in inbox-detail-table in a real Button with an
accessible label and stop row-click propagation.
- Map SentAt into the inbox message OAPI response.
Settings → Clients / Access (a11y + fixes):
- Associate form labels with controls via htmlFor/id; group selectable
card sets with role="group" + aria-label; label the row actions menu.
- Fix integration setup validation: rate_limit is an override object
({ limit, interval }) matching the registered form fields, not a
scalar. The scalar schema rejected every submit, silently no-op'ing
the create button.
- Re-export GrantConstraints; cap client search at 100 results.
Router: un-nest org events/scheduled from the removed
OrganizationDetailEventsLayout wrapper; drop unused imports.
The lists_test.go referenced oapi.Draft / oapi.Ready, which don't exist in the generated oapi package. The correct constants are oapi.ListStateDraft and oapi.ListStateReady, fixing the test build failure that broke both the lint and tests CI jobs.
EmailPreviewContent referenced emailLabels, which is declared in the
sibling Preview component, causing a ReferenceError at runtime (TS2304).
Pass the labels in as a prop instead.
The SMS template branch read data.text, but TextTemplateData exposes
{ body }, so the preview rendered empty. Read data.body.
Also narrow each template branch to its concrete *TemplateData type so
the union-member property accesses (code/subject/from/title/body) type-
check instead of relying on the untyped union.
InboxFrame was exported from the preview barrel but never consumed; the inbox preview path uses InboxNotificationCenter. Remove the dead module and its barrel re-exports.
The client list has no pagination, so lowering the fetch limit to 100 silently dropped clients for projects with 100-200 of them. Restore the limit to 200 and note pagination as the proper follow-up.
Add timezone-robust unit tests for the pure date/time helpers (parse/split/combine and ISO conversions), asserting round-trip and structural properties so they pass regardless of the host timezone.
Replace the magic literal int16(3) default priority with a named DefaultInboxPriority constant that documents its tie to the OpenAPI schema default. Add pure (non-DB) unit tests for InboxMessage.OAPI()/InboxMessages.OAPI() and normalizeInboxMessageParams, covering the newly-mapped sent_at field and the default priority.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Brings the inbox messaging system to
mainalong with a batch of UI polish and small fixes. Builds on the inbox feature work (originally PR #238) plus follow-up refinements, and a final polish commit.Inbox
InboxFrame, passing through the sent time with violet accent styling.InboxNotificationCentergains atimeprop so previews show the actual sent time rather than always "now".inbox-detail-tableis now a realButtonwith an accessible label; row-click propagation stopped.SentAtmapped into the inbox message OAPI response.Settings → Clients / Access (a11y + fixes)
htmlFor/id); group selectable card sets withrole="group"+aria-label; label the row-actions menu.rate_limitis an override object ({ limit, interval }) matching the registered form fields, not a scalar. The scalar schema rejected every submit, silently no-op'ing the create button.GrantConstraints; cap client search at 100 results.Router
OrganizationDetailEventsLayoutwrapper; drop unused imports.Test plan