Silicon Overdrive
Build Scope · Picker App

Baskit Picker App

Standalone build scope: screens, behaviour, APIs, the backend changes it needs, and the database to stand up.
References: Baskit Phase 1 Build Scope
Confidential · V1.0 · 3 July 2026
Scope §06 APIScope §08 ScreensScope §13 PaymentsFrontend PRD

This is a standalone build scope for the Baskit picker app, compiled from the wider Baskit scope so the picker app can be built on its own while staying compatible with the shared backend. It gathers everything picker-facing in one place: the screens and flows, what the app must do, the APIs it uses, the changes the backend needs, and the database to stand up. Where it references sections, those point to the Baskit Phase 1 Build Scope.

The picker app is used by the person who physically collects an order in-store. Baskit routes each order’s per-store leg to a picker, who claims it, picks it against a deadline and a prepaid-card spend target, resolves anything out of stock, bags it, and hands it to the driver.

Feed
Claim a nearby job
Pick
By aisle, to the deadline
Resolve
Substitute or refund
Handoff
Bag & release by code
Earn
Base, tip, bonus
Model to confirm: the business plan describes employed pickers, while these screens describe a gig-style claimable feed. The scope below supports the gig feed; if pickers are employed, dispatch becomes assignment rather than open claiming. Confirm before the dispatch logic is built.
Scope §08 JourneysScope §09 Screen inventory

The picker app runs on six screens. The five core screens are shown below in flow order — earnings is a tab reached from the feed. Each designed screen is annotated with what it must do; the states are summarized in the table beneath.

Job feed
Job feed
Available, active, and todayโ€™s jobs; same-store jobs batch with a bonus.
Job detail
Job detail
Store, items, pack-by deadline, and payout โ€” review before Accept.
Active pick
Active pick
Items grouped by aisle with progress; mark picked, swap, or flag canโ€™t find.
Substitute
Substitute
Out-of-stock item with suggested subs; honour the customer preference or refund.
Ready for handoff
Ready for handoff
Items bagged by type; show the handoff code to release the order to the driver.
ScreenPurposePrimary actions
Job feedSee available, active, and today’s jobs, including same-store batches with any bonus.Go on duty · open a job · refresh
Job detailReview the store, items, pack-by deadline, and payout before committing.Accept · decline
Active pickWork items grouped by aisle against the deadline and the prepaid-card spend target.Mark picked · can’t find · next aisle
SubstituteResolve an out-of-stock item, honouring the customer’s preference.Choose substitute · ask customer · refund-skip
Ready for handoffGroup items into bags (cold, fresh, bakery) and release the order.Show handoff code · mark handed off
EarningsTrack today and the week, with a history of jobs and payouts.View breakdown · history
IDRequirementPriority
PK-01Sign in as a picker and go on or off duty; only approved pickers see jobs.Must
PK-02See a job feed of available, active, and today’s jobs with store, distance, item count, pack-by time, and payout.Must
PK-03See same-store jobs grouped as a batch with any batch bonus.Should
PK-04Accept or decline a job; on accept it moves to the active pick and leaves other pickers’ feeds.Must
PK-05Work an active pick with items grouped by aisle, showing progress and the pack-by countdown.Must
PK-06See the prepaid-card spend target for the store and record the actual amount spent, with a receipt.Must
PK-07Mark each item picked, or flag ‘can’t find’ to substitute or refund.Must
PK-08Substitute from suggested alternatives honouring the customer preference, ask the customer, or refund-skip.Must
PK-09Complete the pick, group items into bags (cold, fresh, bakery), and reach the handoff screen.Must
PK-10Release the order to the driver against the handoff code.Must
PK-11See earnings for today and the week, with a history of jobs and payouts.Should
PK-12Receive push notifications for new nearby jobs and approaching pack-by deadlines.Should
PK-13Keep an active pick usable through brief offline periods and sync on reconnect.Should
Scope §06 API specification

The picker app authenticates as a picker and calls the picker endpoints under /api/v1/picker, plus shared auth and device registration. Two of these go beyond the picker set in the main scope and are new backend work: setting on-duty status with location, and recording actual card spend with a receipt (both marked in the next section).

MethodEndpointWhat the client uses it for
POST/api/v1/auth/loginSign in as a picker; receive a JWT with the picker role
PATCH/api/v1/picker/statusGo on or off duty and push current location
GET/api/v1/picker/jobsJob feed: available, active, today
POST/api/v1/picker/jobs/{id}:acceptClaim a job
POST/api/v1/picker/jobs/{id}:declinePass a job
GET/api/v1/picker/jobs/{id}Job detail: items by aisle, spend target, deadline
POST/api/v1/picker/jobs/{id}/items/{itemId}:pickMark an item picked
POST/api/v1/picker/jobs/{id}/items/{itemId}:substituteRecord a substitution
POST/api/v1/picker/jobs/{id}/items/{itemId}:refundRefund and skip an item
POST/api/v1/picker/jobs/{id}:spendRecord actual card spend and upload the receipt
POST/api/v1/picker/jobs/{id}:handoffRelease the order against the handoff code
GET/api/v1/picker/earningsEarnings summary and history
POST/api/v1/devicesRegister the push token

The picker app needs the backend to treat each store leg of an order as a dispatchable job and to carry the picking lifecycle, the prepaid-card spend, the handoff, and earnings. The table lists each change and whether it is new work or an adjustment to something already scoped.

AreaWhat changesType
Roles & authAdd the picker role and an approval plus on-duty state; issue picker-scoped JWTs so only approved, on-duty pickers receive jobs.Adjust
Job dispatchTurn each order’s per-store leg into a claimable job with status, pack-by, payout, and optional same-store batching; claim-lock so two pickers cannot take the same job.New
On-duty & locationEndpoint to set on or off duty and push location, used to rank nearby jobs in the feed.New
Prepaid card & spendAssign a prepaid card to a job with a spend target, and capture the actual spend and receipt at the till.New
Picking statePer-item state machine (pending to picked, substituted, or refunded) driven by events from the app.New
SubstitutionsStore proposed substitutes, the customer-preference flag, and the decision (auto or customer).New
HandoffGenerate and verify handoff codes and record bag grouping and the driver.New
Earnings & payoutRecord base, tip, and batch bonus per job and expose earnings summaries.New
Reconciliation tie-inFeed the captured spend and receipt into the existing reconciliation against the customer charge.Adjust
NotificationsPush new-job and pack-by deadline alerts to picker devices.New
Reconciliation itself already exists in the scope; the picker work feeds it by capturing the actual till spend and receipt against each job, which is then matched to the customer charge.
Scope §05 Data model

The picker slice centres on order_stores — one row per store leg, which is the job. Around it sit the picker, the items and their substitutions, the prepaid card and captured spend, the handoff, and earnings. This is a focused view of the full model in the scope.

P accounts accounts id (pk) role full_name pickers pickers id (pk) account_id (fk) status, on_duty rating accounts->pickers orders orders id (pk) account_id (fk) state accounts->orders order_stores order_stores id (pk) ยท job order_id (fk) store_id (fk) picker_id (fk) status, pack_by handoff_code, spend_target pickers->order_stores prepaid_cards prepaid_cards id (pk) last4 assigned_picker_id (fk) pickers->prepaid_cards picker_earnings picker_earnings id (pk) picker_id (fk) order_store_id (fk) base, tip, bonus pickers->picker_earnings orders->order_stores retailers_stores retailers / stores id (pk) code, name fulfilment retailers_stores->order_stores order_items order_items id (pk) order_store_id (fk) product_id (fk) qty, status substitution_id order_stores->order_items job_cards job_cards id (pk) order_store_id (fk) prepaid_card_id (fk) actual_spend_cents order_stores->job_cards handoffs handoffs id (pk) order_store_id (fk) code status order_stores->handoffs order_stores->picker_earnings substitutions substitutions id (pk) order_item_id (fk) substitute_product_id (fk) customer_pref status order_items->substitutions products products id (pk) name, brand products->order_items products->substitutions prepaid_cards->job_cards

The accompanying file baskit_picker_schema.sql stands the picker database up. It creates 7 enums and 15 tables: the picker-specific tables (pickers, picker_shifts, picker_devices, prepaid_cards, job_batches, order_stores, job_cards, order_items, substitutions, handoffs, picker_earnings) plus a minimal form of the shared tables they depend on (accounts, retailers_stores, products, orders) so it runs on its own.

How to run

Create a fresh database and apply the schema:

createdb baskit_picker
psql baskit_picker -f baskit_picker_schema.sql

Two things to know

  • All money is integer cents; never floating point.
  • Claiming a job is a guarded update: set the picker and status only where the job is still available, so two pickers cannot take the same job.
This is the picker slice. When you merge it into the main backend database, keep the picker-specific tables and reconcile the four shared tables against their full definitions in the scope ERD.