Repository navigation
Conversation
|
@Tim4evar Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
|
@Tim4evar is attempting to deploy a commit to the miracle656's projects Team on Vercel. A member of the Team first needs to authorize it. |
Miracle656
left a comment
There was a problem hiding this comment.
The screen itself is largely right — and it calls a backend route that does not exist, while flipping the tile to live. That combination is the blocker.
1. /ngn/bills/data/bundles is not a wraith route
export async function fetchDataBundles(operator: string): Promise<DataBundle[]> {
const { bundles } = await call<{ bundles: DataBundle[] }>(
`/ngn/bills/data/bundles?operator=${encodeURIComponent(operator)}`,
);wraith's NGN router exposes exactly two bill routes:
src/api/ngn.ts:572 router.post("/bills", ...)
src/api/ngn.ts:650 router.get("/bills/:orderId", lookupLimiter, ...)
Grepping the whole of wraith/src for bundles finds nothing. So this call 404s, the bundle list is always empty, and the screen's empty-list state — which you built correctly — becomes the only state anyone ever sees.
And PayForGrid.tsx now reads:
-{ id: 'data', ... status: 'soon' },
+{ id: 'data', ... status: 'live', route: '/data' },So the tile advertises a working feature that cannot work. The last acceptance criterion on #1133 is explicit about this: "The tile goes live only when the flow is complete."
Your tests pass because they mock fetchDataBundles. That is the right way to test a screen, and it is also why the missing route is invisible from inside this PR — mocking a boundary hides whether the boundary exists. Worth keeping in mind generally: a mocked client is a claim about a contract, and the contract needs checking somewhere.
This is not work you can finish alone, and that is not your fault. wraith has to grow the endpoint first. I'm opening an issue on wraith for it so it can be built and paid for; once it exists, this PR becomes small.
2. It copies airtime.tsx, which #1133 asked you not to do
Build on the shared flow from V296; do not copy
airtime.tsx.
app/data.tsx is 914 lines and shares 272 distinct lines with airtime.tsx (844 lines). That is roughly half the file.
I want to be fair about this: V296 is #1132, it is assigned to another contributor, and it has not landed. You were asked to build on something that does not exist yet. That is our sequencing mistake for publishing both issues in the same batch, not a misread on your part.
But the consequence is real — #1132 now has a second 900-line screen to fold in, and whoever takes it inherits your divergences as well as airtime's. So the resolution is ordering, not blame:
- If #1132 lands first, rebase onto the shared flow and this PR should shrink dramatically.
- If it does not land soon, say so and I will decide which goes first rather than leaving you blocked.
Either way #1133 stays yours and stays assigned to you.
What is already right
- Bundles carry
sizeMbandvalidityDays, not just a price. The criterion existed because a column of naira amounts tells someone nothing about what they are buying, and yourDataBundletype and its comment both get that. - An empty list is a state, not a failure —
empty-bundles-notice, tested, and distinct frombundles-error. That distinction is the one most people miss. previewSpendFeeis wired, so the charge is shown before the passkey prompt.- Treating
idas opaque and passing it straight through ascustomerIdis right; inventing structure in an identifier the provider owns is how clients break on a provider change. - 319 lines of tests for a 914-line screen, covering the states rather than the rendering.
One request
Please fill in the PR description. It is the empty template right now, and "Closes #1133" plus two sentences would have told me the bundle endpoint was assumed rather than existing — which is the whole of blocker 1.
|
Follow-up: I've opened Miracle656/wraith#267 for the missing endpoint, at 150 points, so the backend half can be built and paid for rather than sitting as an unowned blocker. It specifies the route shape your client already expects — So the path forward for this PR:
Nothing here needs you to wait idly — if you want to take wraith#267 yourself, it is unassigned and you already know the contract better than anyone, having written the client for it. Say the word and it is yours. |
|
I'll readily take on wraith#267 since I already have the client side wired up and know the expected contract, I'll get started on the backend endpoint so we can clear this blocker. |
cefc2d7 to
6313ae7
Compare
|
wraith#267 is now assigned to @ayo-mide55. #1132/#1145 are still open (and #1145 is currently conflicting). Should I wait for the shared BillFlow, or rebase onto #1145 once it is green? The Data tile stays @ayo-mide55 the client in this PR expects |
The Data tile stays 'soon' until wraith#267 ships the bundle catalogue endpoint, so the app does not advertise a flow whose list can only be empty.
6313ae7 to
3d1c264
Compare
|
Both good questions, and thank you for going and telling @ayo-mide55 the contract directly — that is exactly the right instinct. One answer, one correction, and one thing neither of you could have known. Wait for #1145Build on the shared and the two share But that is precisely what #1145 exists to stop. If I merge this first, the extraction has three call sites to unify instead of two, and the third one is 900 lines that landed after #1145 was branched. We would be creating the duplication in the same week someone is removing it. The cost of waiting is close to zero here, which is what decides it: the tile stays I will get #1145 reviewed and moving rather than leaving you waiting on a conflicting branch indefinitely. Once it is in, rebase onto the shared The
|
|
Filed the purchase-side field as wraith#305, and left a note on wraith#267 so @ayo-mide55 knows the listing id has to match what #305 accepts. All three sides are now working to the same contract. |
Found while answering veil #1144. wraith #267 adds the endpoint that LISTS data bundles; nothing lets a client say which one was bought. POST /ngn/bills accepts nine fields and none identifies a product. The PR author had assumed the bundle id travels in `customerId` -- but that is the subscriber ("a phone number for airtime, a meter number for electricity"), so it would have overwritten the phone number and put a product code into a field that otherwise carries personal data. Two contributors were each building a half and the halves did not meet. Corrected on #1144, noted for the #267 assignee, filed as its own issue rather than widening #267 under someone who had already started. Claude-Session: https://claude.ai/code/session_01USgemLt4Rnz4SGB1Srf3GB
customerId is the phone number the bundle is for. Passing the bundle id there would credit the wrong thing and overwrite the subscriber; the product id now travels in bundleId, matching wraith#305's purchase-side field.
Summary
Adds a data bundle purchase screen at
/datafor the wallet:empty-bundles-noticevsbundles-error);customerIdand the provider's opaque bundleidseparately asbundleId(the purchase-side field tracked in wraith#305).The Data tile in
PayForGrid.tsxintentionally stayssoonfor now. The screen callsGET /ngn/bills/data/bundles?operator=…, which does not exist in wraith yet — it is the subject of Miracle656/wraith#267. Even once it exists,POST /ngn/billsstill has no field for the selected product, so the purchase side depends on wraith#305. Until both land, the flow cannot complete and the tile must staysoon.Shared flow: this screen was written before V296 (#1132) was available and currently duplicates a large part of
airtime.tsx. Once the shared flow lands (#1132 / #1145), the plan is to rebase, remove the duplicated flow, and build on the shared implementation — which should shrink this PR substantially.Related issue
Closes #1133
Depends on: #1145, Miracle656/wraith#267, Miracle656/wraith#305
Type of change
Component
Checklist
cargo testpasses (contracts)npm run typecheckpasses (wallet)npm run buildpasses (wallet / agent)Screenshots / test output
frontend/mobile/__tests__/dataScreen.test.tsx— 8 tests passing, covering the screen's states rather than rendering details. Screenshots to follow.