Purpose and status
Adding a first order is High IQ’s primary activation moment. This page is the canonical product and engineering map for the Gmail and text-input paths, from the first saved shop through order review, durable save, strain research, and post-save management. Photo and image receipt input are intentionally outside this document’s scope.This page describes the implemented text and Gmail paths. Photo and image
receipt input remains intentionally out of scope. The post-sign-in onboarding
action now opens the same Historical Import flow used elsewhere in the app.
Current implementation at a glance
End-to-end activation map
Activation contract
The intended first-use contract is:- Ask where the user shops and save a real dispensary with at least one usable receipt email domain.
- Offer a targeted Gmail scan for that shop before offering a broad search.
- Parse candidates into editable orders; do not commit Gmail-derived dates, names, prices, or quantities until the user has reviewed them.
- Preserve every line the user chooses to save.
- Ask the user whether an unresolved name is actually a cannabis strain.
- Persist the user’s explicit answer and admit only “yes” lines to the strain research pipeline.
- Commit the order once, then let durable workers finish replay-safe side effects without making navigation or animation part of save success.
- Historical Import requests one notebook per confirmed receipt and exposes every committed order in the searchable Stash → Orders archive.
Gmail: connection and targeted discovery
Current connection states
Gmail access is read-only. OAuth tokens stay server-side; raw email bodies are processed in background task memory and are not persisted. Candidate metadata such as subject, sender, date, and snippet is temporary, owner-scoped review data stored in a paged child ledger rather than on one growing job document.Targeted discovery contract
Historical import and Quick Sync default to selected shops with confirmedemailDomains. A user without a Gmail-ready shop can create or update one
inline. “Advanced Options” can start a broader historical scan only after the
user explicitly chooses it.
Current Gmail background sequence
Gmail selection and import rules
- A candidate is not an imported order.
- Users can select dispensary groups and individual candidate emails.
- Gmail message ID is the durable duplicate key.
totalImportedincrements only after a staged receipt is actually confirmed and committed.- Historical and Quick Sync imports do not add to the active stash.
- Every committed historical order requests its own notebook. Quick Sync uses the notebook preference selected before import.
- Safe bulk confirmation is limited to fully resolved, high-confidence historical drafts and commits at most one configured chunk per action.
- Candidate review is paged and each message has a separate durable outcome, so a large archive never depends on one unbounded job payload.
- Closing a staged Gmail review offers Skip Receipt and returns to the remaining receipts; it never silently creates an order.
- Failed orders can be retried without replaying successful message IDs.
- Reopening the flow restores the active job automatically. A recoverable error exposes Resume Import, which reuses the stored scan/import fingerprint and durable child outcomes rather than replaying successful work.
- Historical completion is recorded only after receipt parsing has finished and every staged draft is committed or explicitly discarded.
- Disconnect closes local write boundaries, cancels known background work when possible, and revokes the delegated Gmail token while preserving imported orders.
Text input: parse, recover, and review
Raw pasted text is kept only in the active in-memory review. The persisted recovery projection is versioned and allowlisted; it intentionally excludes the raw receipt text. Drafts expire after 24 hours, and the screen waits for native draft-store hydration before declaring a cold-start draft missing.Review and edit contract
Current Review & Confirm state machine
What users can edit before a text order is saved
Gmail-derived and text-derived orders use this same editable review surface.
Unknown strain confirmation and verification
Implemented user and backend gate
Changing a name or selecting a different match resets the answer. Save remains disabled while any selected unresolved name is pending confirmation or being re-matched. A No answer keeps the line in purchase history with research canceled; it is never sent to the paid pipeline. Identity and research readiness remain separate:Durable commit and post-save outbox
The save sheet currently offers:- Save for Stats Only: no stash merge.
- Save & Add to Stash: resolved lines enter active inventory; unresolved lines keep their stash intent and may enter after successful research.
- Save, Stash & Report: available only when the code-owned notebook policy enables order notebook generation.
Dispensary lifecycle and Gmail readiness
Shop-management rules
- Shop name is the only required field.
- Contact email and receipt sender domains are separate: entering an email or website may suggest a domain, but it does not become Gmail search scope until the user confirms it.
- Domains are normalized, validated, deduplicated, removable, and capped at ten per shop.
- Gmail defaults to strict selected-shop domain scope. Broad search is a clearly labeled secondary opt-in.
- Finalizing a reviewed Gmail order attaches its validated sender domain to the linked shop, making future Quick Sync targeted.
- Empty optional fields can be cleared, malformed email/URL/phone/ZIP/domain values are rejected, double submission is blocked, and dirty cancellation requires confirmation.
- Deleting a shop removes the shop record. Existing orders retain their saved dispensary name, but the detail link may no longer resolve.
Recovery and error states
Error-state truth rules
- “Found” never means “imported.”
- A failed or abandoned Gmail review must not increment imported totals.
- The Gmail History cursor advances only after a bounded discovery window is accepted; bounded failures leave the cursor unchanged.
- A committed order must never be reported as “Save failed” because local cleanup, refresh, or navigation failed afterward.
- Match failure is different from “no match.” A failed matcher keeps a visible retry action and preserves all order lines.
- Research queue acceptance is not research completion.
- A parser batch finishing means ready for review, not “historical import complete.” Completion requires every staged draft to be committed or discarded.
- A cancel result may report provider cancellation as incomplete, but the local terminal state and connection-generation checks still reject late writes.
Post-save order management
Order detail supports editing mutable purchase facts with native date input, inline validation, unsaved-change confirmation, and double-submit protection. Strain identity is intentionally locked because changing it requires the full matching, user confirmation, research, and Stash reconciliation contract; users are directed to add a corrected order for that case. Deleting an order preserves generated notebooks and Stash history while clearing their stale order links. The Orders archive paginates older purchases and filters by status, source, review state, notebook state, date window, and shop. Native header search finds shop names, and an active Gmail-import banner returns directly to the correct Historical Import or Quick Sync flow.Static acceptance matrix
Hard ceilings are intentional service-safety boundaries, not silent truncation:
100 items per order, 50,000 text characters, ten sender domains and five menu
URLs per shop, up to 2,000 historical Gmail candidates globally, and bounded
Gmail import chunks. Invalid overflow is rejected with recoverable input still
intact.
Source-of-truth implementation map
Related guides
Gmail Sync
User-facing connection, scan, review, and privacy guidance.
Managing Shops
What shop fields do today and how they affect Gmail discovery.
Order Import Troubleshooting
Recovery guidance without overstating unsupported editing features.
Gmail Architecture
The current Convex, Trigger.dev, Gmail, and Hono boundaries.
