Patterns
Patterns
The flows members go through again and again, and the rules each one keeps. Every pattern is built in the app today; the screen guide shows each screen in full.
Consent Choice
app/(setup)/consent-read.tsx app/(setup)/consent-choose.tsx app/screens/review.tsx app/screens/recording-detail.tsx app/screens/privacy.tsx
The same four choices appear in four places. Wherever they appear, they look the same, use the same words, and save a record that is never edited.
Who Can Use Your Recordings
Your starting choice. You can change it on every recording.
Setup, step 5 of 6.
The change sheet on Recording Detail, here with sharing paused, so only "Only me" is enabled.
- Always all four choices, in order, with their exact names and one line each with a short pay tag.
- Who can use each recording is visible without opening it: the Library row and the recording's header say it.
- Pause all sharing keeps new recordings with the member; it never changes past choices.
- Withdrawing is never more than two taps away, and its sheet says what cannot be undone.
Invite and Join
app/(join)/* app/invite/[code].tsx packages/core/src/invites.ts apps/mobile/CLAUDE.md §6
- I have an invite collects the invite first, so a new member needs only one sign-in code.
- Codes are forgiving: spaces and dashes are ignored, and I, L and O are read as 1, 1 and 0.
- Invites are sent by the member through the phone's share sheet with the code and a link;
nzinga://invite/CODEopens the invite screen with the code filled in. - The invite screen is open about the inviter's bonus.
Enter the Code
Sent to your number. It expires in 10 minutes.
Sign-In Code. The first three digits are typed; the caret is Volt.
Nzinga Is Invite-Only
Enter the code from the person who invited you. Invite links fill this in automatically.
Each code works once and can't be bought or sold. The member who invited you earns a small bonus when your first recording is accepted.
Invite Code, with the inviter's bonus said openly.
Recording Flow
app/screens/record.tsx recording.tsx review.tsx saved.tsx app/contexts/RecorderContext.tsx
Describe your favourite dish and how it is cooked
Recording: magenta says it is live; Volt marks the one action, Done.
Review: playback, the choice, then one Volt action.
- One recorder for the whole app; a recording still running shows a magenta card that leads back to it.
- Calls and leaving the app pause the recording and say so. Discard always asks first.
- The audio stays on the phone. Only the details and the member's choice are sent.
Review and Rejection
app/screens/recording-detail.tsx lib/recordings.ts apps/api/src/app.ts (review) SPEC.md §5
- A native speaker reviews each recording, usually within about three days. The member is told either way.
- On acceptance, each speaker who chose "Nzinga's models" or wider is paid for their own accepted seconds.
- A rejected recording says why in plain words and offers Record it again. The server does not send a reason yet, so the app names the usual ones honestly rather than inventing a specific one.
- Quality and fraud checks (language identification, duplicates, synthetic or replayed audio) are planned in the spec.
"Not accepted. Usually this means background noise, a very short recording, or speech in a different language from the one chosen."
"Rejected: low quality."
Blames without helping, and offers no way forward.
Payout
app/screens/payout.tsx payout-method.tsx lib/payouts.ts packages/core/src/ledger.ts
- One open request at a time; cancel it any time until it is paid.
- The name on the account must match. Nzinga confirms every payout by SMS before money moves.
- Payout methods and requests are kept on this phone until the server has a payout endpoint, and every payout screen says so.
- A payout never takes the balance below zero.
Empty, Loading and Error States
components/Placeholder.tsx components/SkeletonLoader.tsx app/hooks/useLoad.ts SCREENS.md (design rules)
Every list has all three. Lists reload when the screen comes back into focus, so they are fresh after a save.
Empty: what will be here, and the first step.
Loading: the shape of the content, not a spinner.
Error: what failed, why, and Try again.
| Kind | Title | Subtitle |
|---|---|---|
| Empty | No recording to review | Record a voice note first. |
| Permission | Microphone is off | Nzinga needs the microphone to record. Turn it on for Nzinga in your phone's settings. |
| Error | Could not load your wallet | From errorMessage(): "No connection. Check your internet and try again." |
| Error | Could not load your progress | Your progress is kept on this phone. Try again in a moment. |