Skip to content

feat: add instance onboarding and pairing flow - #2

Merged
meashgrey merged 16 commits into
mainfrom
feat/instance-onboarding
Oct 5, 2026
Merged

meashgrey merged 16 commits into
mainfrom
feat/instance-onboarding

Conversation

@meashgrey

Copy link
Copy Markdown
Member

Summary

This PR introduces the first end-to-end PawMate onboarding and pairing flow, including client-side onboarding screens, pairing/session handling, device management, basic chat integration, server-side pairing APIs and persistence, localization, design-system components, and supporting documentation/tests.

Highlights

  • Add instance onboarding and couple pairing flows in Flutter
  • Add reusable hand-drawn design components and theme primitives
  • Add localization for English and Chinese
  • Add pairing, device, profile, and chat APIs on the Go server
  • Add persistence models and service-layer tests
  • Add client tests for onboarding, login, profile, chat, and server URL handling
  • Update platform targets and app metadata/assets
  • Update project documentation and CI/release workflows

Notes

The branch is 12 commits ahead of main with no divergence at the time of PR preparation.

- Add Flutter inviter setup page for configuring a server URL\n- Generate and display one-time pairing invitation links\n- Add Gin APIs for invite creation, redemption, and status checks\n- Enforce single pending invite and one-time redemption per instance\n- Add pairing service and HTTP integration tests\n- Remove the default server URL from onboarding\n- Add Dart and Go function documentation comments\n- Update the implementation guide and server documentation
- add reusable paper-and-ink UI components for pairing
- accept invitations opened through the pawmate://pair deep link
- store device credentials securely and restore access with rotating recovery codes
- persist pairing state in SQLite and store credential hashes
- document recovery and database backup procedures
- validate saved credentials on app startup and route paired users home
- add authenticated pairing session endpoint
- provide recovery flow for invalid credentials and retry handling for network errors
- navigate invitees and newly paired inviters to the couple home
- document session validation and recovery behavior
- generate launcher icons from the Pawmate SVG for Android, iOS, web, Linux, macOS, and Windows
- add icon generation configuration and source PNG
- add Flutter project scaffolding for the additional platforms
Add persisted text messaging with paginated history, retry-safe sends,
cross-device synchronization, unread reminders, and member-level read receipts.

Open the couple space on the Chat tab and retain drafts and scroll state
between tabs.
…stem

Add invitation-link entry and a login-method chooser, and refine pairing,
device login, recovery, and chat screens. Split the hand-drawn UI into reusable
components, layouts, theme tokens, and icons, with English and Chinese
localizations.

Update the foundation guide with onboarding previews and add tests for the
login methods and onboarding screens.
Collect a nickname and optional avatar during invitation creation and
acceptance, validate and persist profiles with pairing, and show both members'
identities in Home. Localize profile flows and add profile-focused UI and service
coverage.

Replace the implementation guide with reference documentation for onboarding,
pairing, API contracts, and persistence. Remove obsolete draft instructions and
book figures.
Add a scheduled and manually triggered workflow that runs CI, builds
platform-specific Flutter clients and Gin server packages from the same commit,
and publishes checksum-verified draft prereleases.

Document supported artifacts, installation caveats, and release behavior in the
README and project book.
@meashgrey

Copy link
Copy Markdown
Member Author

@codex review

@meashgrey meashgrey self-assigned this Oct 5, 2026
@meashgrey meashgrey added enhancement New feature or request server server-side issues labels Oct 5, 2026
@meashgrey meashgrey linked an issue Oct 5, 2026 that may be closed by this pull request
7 tasks

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cc14f7669e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread lib/features/pairing/pairing_api.dart Outdated
Comment thread android/app/src/main/AndroidManifest.xml Outdated
Comment on lines +132 to +134
return func(c *gin.Context) {
var request recoverPairingRequest
if err := c.ShouldBindJSON(&request); err != nil {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Cap unauthenticated recovery request bodies

When the server is reachable by an untrusted client, /api/v1/pairing/recover passes an unlimited body to ShouldBindJSON, so a caller can force the process to buffer or parse an arbitrarily large payload and exhaust memory. The invite handlers already use http.MaxBytesReader; apply a small bound here as well (and to the similarly unauthenticated device-code redemption handler).

Useful? React with 👍 / 👎.

Comment thread ios/Runner/Info.plist
Comment on lines +19 to +20
<key>CFBundlePackageType</key>
<string>APPL</string>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Register the invitation scheme on iOS

On iOS, tapping a generated pawmate://pair?... invitation cannot launch this app because the new Info.plist contains no CFBundleURLTypes entry for the pawmate scheme; the Android manifest is the only platform registration found in the repository. uriLinkStream only receives links delivered by the OS, so the external invitation flow is unreachable on iOS until the scheme is registered.

Useful? React with 👍 / 👎.

Comment on lines +50 to +52
if (messageBounds.overlaps(bounds) && entry.key > visibleID) {
visibleID = entry.key;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Do not acknowledge off-screen unread messages

When a user opens Chat with enough unread messages to span beyond the viewport, selecting the greatest visible incoming ID advances the server's cumulative cursor past every earlier message, including unread bubbles still off-screen above the viewport. This immediately tells the partner those messages were read and clears their unread count even though the UI promises acknowledgment only after rendering them visibly; the client must avoid advancing across unseen unread IDs.

Useful? React with 👍 / 👎.

Comment on lines +43 to +45
Text(
own ? 'You' : 'Your partner',
style: Theme.of(context).textTheme.labelMedium,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Localize the chat sender labels

When Simplified Chinese is selected, every message bubble still displays the English labels You or Your partner, producing a mixed-language primary chat screen. Add both labels to the English and Chinese localization resources and resolve them through AppLocalizations like the surrounding status text.

AGENTS.md reference: AGENTS.md:L182-L185

Useful? React with 👍 / 👎.

Resolve pairing, device, and chat endpoints relative to the configured
instance URL so deployments hosted under paths such as `/pawmate` keep that
prefix.
Reject HTTP instance URLs in release builds and disable Android cleartext
traffic by default. Allow HTTP only in the debug manifest, and update
localized errors, tests, and server documentation to reflect the policy.
Cap recovery and device login code redemption payloads at 8 KiB to prevent
oversized requests from consuming excessive memory.
@meashgrey
meashgrey merged commit 8174eee into main Oct 5, 2026
4 checks passed
@meashgrey
meashgrey deleted the feat/instance-onboarding branch October 5, 2026 16:24
meashgrey added a commit that referenced this pull request Oct 5, 2026
Allow HTTP instance URLs in all client build modes and enable Android cleartext
traffic. Document that HTTP is unencrypted and best suited to trusted private
networks or tunnels.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request server server-side issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: add secure couple pairing invitations

1 participant