Repository navigation
Native iOS app: History, announcements and account tools - #143
Conversation
History mirrors the website's History page: saved cases, chats, attacks, brainstorms, factoids and Sparring rounds for the Current Debate or any other debate, and one-off work with Library sources outside every debate, each with the suggested debate and Add to debate through attach_to_debate. Rows open their documents or the Flowchart, chats reopen in Ask, and cases swipe to delete with the website's confirmation. Sparring rounds stay read-only until Sparring is in the app. The Debate tab's See all and a row in You open it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The app lists the account's active announcements through the announcements Edge Function and shows them one at a time at the top of the Debate tab, with the website's position counter and dismiss. Dismissals are stored on the server, so they are shared with the website. The startsAt/expiresAt filter and the response schema move to packages/core so both clients use one copy; the website's behaviour is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Download my data asks the account function for its export, as the website does, and shares it as debatelab-data-<date>.json. Delete all my data runs clear_current_user_data after the website's email-typed confirmation in a form sheet, then forgets this session's results and drafts, turns one-off mode off and reloads the debates. Both account-wide writes refuse to run once a different account holds the session. Terms and Privacy open the public website's pages in the in-app browser. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each form gets the website's ModelSelector as two native rows, AI model and Reasoning, and Ask gets them as chips beside its options. Pro models show but stay unselectable without Pro access, and reasoning stays at Low for Auto and for students without Pro, as on the website. A change writes the whole feature_configs object in the website's canonical shape through the settings provider's serial queue, filling the defaults when nothing was saved, and a failed write rolls back only its own field. Tools read their model through the same queue, so they run with the model just picked. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A tool reads its model behind pending settings writes so it runs with the model just picked. A write that hangs would have held Generate, Attack, Brainstorm, Factoids and Ask back with it; after five seconds the read now goes ahead on its own. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The screenshot script gains a SCREENS filter to run only some groups, and groups for History (Current Debate, chats, the scope menu, another debate and the unsorted view from made-up rows), the announcement banner from two made-up announcements with a local dismissal, You down to its data rows with Download my data (read-only, iphone-light-en) and the Delete all my data sheet, never confirmed, and the Generate model picker with its menu open, never chosen. The Delete all my data field's email placeholder is masked too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nsorted Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brings in typed Sparring (PR #138). Conflicts in apps/mobile/AGENTS.md and scripts/screenshots.ts keep both sides: the route list names history.tsx, delete-data.tsx and sparring/, and Sparring screenshots become their own SCREENS group next to History, announcements, account and model. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
History's Sparring tab now works as the website's HistoryPage does: a row opens the round's scorecard at sparring/[id] with History as its back label, and swiping deletes it after the website's confirmation through deleteSparringRound, which filters on the user. Deleting the finished round the Sparring screen still holds forgets it there too. The empty tab starts a round in the app. Unsorted rounds keep Add to debate through attachToDebate, which passes the student's side and checks the signed-in account; the screenshot script now shoots the Sparring tab. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configuration
You can disable this status message by setting the Use the checkbox below for a quick retry:
Note 🎁 Summarized by CodeRabbit Free
Comment |
|
Codex review r1 at 0e391e2 (gpt-6.1-sol, high): 3 findings, accepted, fixes in progress.
|
clearAllData checked that the session was still the confirmed account, but supabase-js read the session again when it sent the RPC. An account signed in between the two would have had its data deleted. The request now carries the access token from the session that passed the check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A tool waits up to 5 seconds for earlier settings writes, then reads its config anyway. That read returned the row's previous model while the new pick was still saving. The settings provider now keeps each tool's pending model and reasoning and applies them over the fallback read (leaving out a Pro model the student can't use). Ask also drops its cached config when a save fails, so it never keeps a model that wasn't saved. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
After Delete all my data the sheet only reloaded the debates. When that reload failed, the deleted debates and the Current Debate stayed on screen and new work still targeted them. The debate context now drops the account's debates and Current Debate first (and any load already running can't bring them back), then reloads. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The model picker, settings writes and default model now read Pro access from effective_entitlement through readEntitlement, as feat does, instead of the user_settings tier and Stripe rows. extra.websiteUrl moves from the deleted app.json into app.config.ts. Both history and permissions strings are kept in en, es and hu. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Debate tab imports both the announcements hook and feat's copy holder. The screenshot harness keeps SCREENS= groups and feat's ONLY=offline run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e all History's debate lists and its work outside every debate read through cachedRead, so they answer from a saved copy offline, and the screen holds its copies with useCopyHolder. Every write that already drops a debate's counts and lists now drops that debate's History copy too, and work outside every debate drops the one-off copy. Adding work to a debate from History drops the item's own copy and the lists on both sides, and Delete all my data drops every saved copy before the debates reload. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Round-1 fixes: efe5580 (Delete all my data sends the RPC with the confirmed session's own token; test with a real supabase-js client fails without it), 1c147e7 (after the 5 s wait, tools apply the pending model pick on top of the saved config; Ask drops a config cached with a pick that failed to save; test fails without it), f949f96 (forgetDebates clears the debate list and Current Debate after Delete all even if the reload fails). Then merged feat/native-ios twice (80dbb4f entitlements + app.config.ts; 37b2433 offline reading): Pro gating now goes only through readEntitlement, extra.websiteUrl moved into app.config.ts, and 8f55dcd wires History, Add to debate and Delete all into the offline cache. Local at 8f55dcd: npm run verify green (343 vitest, edge 371, 30 smoke), mobile typecheck, eslint, knip pass. Codex r2 next. |
|
Codex review r2 at 8f55dcd (gpt-6.1-sol, high): r1's three fixes and both merges checked (token pinning across refresh/account switch, all 15 delete-all cache groups, entitlement gating, config only adds extra.websiteUrl). Two new Medium findings, accepted, fix in progress:
|
Keep push notifications on You alongside History, announcements, and account tools. A model read that overlaps a finished save reads the row again, and filing a judged Sparring round drops the one-off History copy. Co-authored-by: Gáborjáni-Szabó Ádám <Programcode@users.noreply.github.com>
|
Deployment failed for project debate-navigator with the following error: Learn More: https://vercel.com/adam-gaborjanis-projects?upgradeToPro=build-rate-limit |
History, announcements and account tools for the iOS app, matching the website.
What's in it
attach_to_debatefunction.accountexport, saved asdebatelab-data-<date>.jsonand shared.feature_configsin the website's shape through the settings write queue.packages/core, and the website imports them back in one line.Out of scope
Checks (local; GitHub Actions is out of minutes)
At this head, each run under the shared memory lock:
npm run verify: exit 0. Vitest 316 tests, collaboration 30/30, Deno edge tests, build, Playwright smoke 30/30.npx eslint apps/mobileandnpx knip: all exit 0.owner-check.test.ts: attach and delete-all refuse to run once a different account holds the session. Confirmed to fail without the guard.feature-config.test.ts: refuses a Pro model without Pro, and changes one tool while keeping the others.Screenshots cover History (all scopes, unsorted), the announcement banner, You, Delete all my data, and the model picker. Shot on iPhone light en, iPhone dark hu and iPad light en.
Staging, seed Pro account:
6a-testcase: created unsorted, added to a debate from History, then deleted. Cases went 2 → 3 → 2.Not proven
Codex review rounds follow as comments.
🤖 Generated with Claude Code
History, announcements and account tools for the Expo (React Native) app, matching the website. This is not an Xcode project.
ios/andandroid/are generated and gitignored, and the checks below were run on Linux.What's in it
attach_to_debatefunction.accountexport, saved asdebatelab-data-<date>.jsonand shared.feature_configsin the website's shape through the settings write queue.packages/core, and the website imports them back in one line.Out of scope
Synced onto feat/native-ios
Merged
origin/feat/native-iosat036b76ba(push notifications, PR #140) into this branch as048a1e11. A rebase would have replayed earlier merge commits already on this branch, so this is a merge commit. Sibling PR #144 (iPad layouts) was still open and conflicting, so it did not land first.Conflicts, all keep-both:
apps/mobile/AGENTS.md: this branch's offline-cache notes, including that filing a judged Sparring round drops the one-off History copy, plus the base's push-notification rules.apps/mobile/src/app/(tabs)/(you)/you.tsx: History, download, delete, and Terms, plus the base's Notifications card.src/locales/{en,es,hu}.json:historyDescanddeleteDataDescplus thenotificationsstrings.apps/mobile/scripts/screenshots.ts: the basewant()filter, with History, announcements, account, and model groups added.History, announcements, account tools, and the model picker sit on parts that are already on
feat/native-ios(Sparring, offline cache, entitlements, push). They do not depend on the iPad layouts in PR #144.Bugs fixed on this sync
readFeatureConfigAfterWritescopiedfeature_configsand then waited on the entitlement. If the save finished in that gap,pendingwas cleared and the tool kept the model the save had just replaced. The fallback now reads the row again when the pending choice disappears during that read. Covered byfeature-config-read.test.ts.attachSparringdropped the debate's History copy but not History's one-off copy, so the round still showed under unsorted work offline. It now dropsdebateListScopes(null, 'sparring')the same way Add to debate does. Covered bysparring-attach.test.ts.Checks on
048a1e11(Linux, Expo, Node 22)Passed:
npm cinpm run -w @debatelab/mobile typecheck(app and scripts)npm run typechecknpm run docs:checknpm run lint(eslint, knip, repo rules)npm test: 50 files, 352 tests. One unrelatedbackend-statushook timed out when git commit signing was on; the same file and the full suite passed withcommit.gpgsign=falsefor that run only. The test was not changed.npx expo export --platform webandnpx expo export --platform iosboth produced bundles. The iOS output was deleted and was not committed./,/sign-in,/history,/you,/delete-data, and/generatereturned 200 with no page errors and no console errors. Signed-out protected routes redirect to sign-in. The sign-in screen shows "Sign in to DebateLab".npm run build(website). Chunk-size warnings only.npx expo-doctor(1.21.5): 18/21 checks passed, exit 1.npx expo install --checkexits 1 for the same patch drift.apps/mobile/package.jsonis unchanged againstorigin/feat/native-ios, so these are already on the base:expo-audiowantsexpo-assetas a direct dependency; it is only present transitively.GitHub Actions jobs on this head failed in about two seconds with no logs (
log not found). That is the account being out of Actions minutes, not a code failure. A local pass is not a CI pass. Vercel production preview failed on the build rate limit; the staging preview succeeded. CodeRabbit succeeded.Not proven
STAGING_DEMO_CODEin this environment, so signed-in History, announcements, download, the delete sheet, and the model picker were not driven. Delete all my data was never run.Codex review rounds follow as comments.