Skip to contentRyan Katayi
    All work

    Recall / Independent product / iOS

    From a page of notes to a daily review.

    Photograph notes or enter a topic, generate flashcards, and return to them with spaced repetition.

    RolePublished by Ryan Katayi
    StatusOn the App Store

    Built with

    Application
    • TypeScript
    • React Native
    • Expo
    • Expo Router
    Capture & interaction
    • Expo Image Picker
    • Expo Haptics
    AI generation
    • OpenAI API
    • Structured Outputs
    Backend & sessions
    • Supabase
    • PostgreSQL
    • Supabase Auth
    • Supabase Edge Functions
    Review & local state
    • SM-2-style scheduler
    • AsyncStorage
    Checks & release
    • ESLint
    • TypeScript compiler
    • EAS Build
    • EAS Submit

    Structured generation · Pure review scheduling · Anonymous sessions

    Inside the engineering
    Recall App Store screenshot showing decks and due cards
    Inside Recall

    Original App Store screenshots.

    My contribution

    I built the flashcard generation flow, editable decks, review scheduler, and guest session experience, and published the iOS app.

    Under the surface

    The engineering.

    Generating a deck and scheduling a review are different problems. I use a model for the draft material, then ordinary application code to decide exactly when each card returns.

    1. Supply material

      A photo of notes or a text topic.

    2. Draft a deck

      A strict title/cards schema with basic and cloze cards.

    3. Review the draft

      Inspect cards, rename the deck, and remove unwanted cards.

    4. Schedule recall

      A rating updates interval, ease, and the due date.

    Decision / 01

    The model returns data the editor can work with.

    A paragraph of generated study material is not a usable deck. Each card needs a predictable type, question, and answer before the interface can render or edit it.

    How it works

    The generation endpoint requests strict structured output with title and cards fields. Card type is limited to basic or cloze, with required front and back text. Photo requests use a vision model and instructions to stay within the notes; topic requests use a smaller text model. Refusals and empty decks have explicit error responses.

    The tradeoff

    Schema enforcement makes the output usable by the UI, but does not verify factual accuracy. Learners can inspect and remove generated cards before saving, then edit card content in the saved deck. Photo and topic generation also have different grounding expectations.

    Decision / 02

    Make the next review a deterministic calculation.

    A rating needs a consistent consequence. The interval shown on a button should follow the same calculation used when the learner selects it.

    How it works

    The SM-2-style scheduler is a pure TypeScript function over interval, ease, repetitions, lapses, rating, and time. Again resets repetitions, increments lapses, and sets a due date ten minutes out. Successful reviews advance the interval; ease has a floor of 1.3. Button previews call the same scheduler. In the active session, Again also places the card at the back of the queue for another attempt.

    The tradeoff

    The scheduler is small and explainable, with fixed rules rather than individually fitted memory parameters. The active queue can show a failed card again before its stored ten-minute due date, so session behavior and persisted scheduling are distinct.

    Decision / 03

    Guest use still needs a durable identity.

    Asking for an email before a first deck adds friction, but decks and review history still need a user identity behind them.

    How it works

    Session bootstrap restores an existing Supabase session or signs in anonymously. This lets a learner enter the product without an email form while keeping a session that survives app restarts. Account backup is a separate step in the experience.

    The tradeoff

    An anonymous session is tied to credentials on that device. It should not be presented as a replacement for account recovery or as proof of offline availability.

    Edge cases

    What happens when…

    A photo produces no usable cards
    Return an explicit error and ask for clearer material instead of saving an empty deck.
    A new card is rated Easy
    The initial interval is four days; Good starts at one day.
    A card is rated Again
    Reset its repetition count, lower ease within the floor, and requeue it for another attempt.
    Next

    Claro

    A personal finance app for importing statements, categorizing transactions, and asking questions about spending.

    Independent product / iOS