Skip to content
All projects

Mobile-first web app · Field data collection

RAR-AI

A risk-analysis report filled in on a phone during the site visit, with the draft saved on the device, even without signal, and a rules engine that computes the risk level automatically

Private project — no public link

Client
Institutional security · public sector
Role
Full-stack Software Engineer
Year
2026
Technologies
  • Next.js 16
  • React 19
  • TypeScript
  • Tailwind CSS 4
  • Zustand
  • Zod
  • IndexedDB
  • Web Speech API

Context

Mobile-first web app for institutional-security analysts to record site visits and produce the Risk Analysis Report of Areas and Facilities (RAR-AI) in the official template — the “AI” in the name comes from the Portuguese for Areas and Facilities (Áreas e Instalações), not from artificial intelligence. Data is collected on a phone, in the field, in places with an unstable connection. Behind the form sits a substantial body of domain logic, kept confidential: the analysis methodology and business rules are not described here, and the screens show a fictitious report.

Challenge

Turn a long official template — several analysis axes, mandatory checklists and a risk calculation — into a flow that is fast to fill in on a phone, with no data loss when the connection drops and without analysts having to calculate separately or retype what they have already recorded.

Results

steps from header to review, navigable in any order
11
of field data (drafts, photos and audio) kept on the device, with no server
100%
touch targets on the main controls of the custom design system
44 px

Key deliverables

  1. 01Built a mobile-first 11-step form with Next.js 16, React 19 and TypeScript, with free navigation, per-step progress and open-items list, and a report generated in the official template, ready to print or save as PDF.
  2. 02Implemented a deterministic, confidential rules engine in TypeScript: it computes the risk level automatically, builds the mandatory checklist based on the unit's profile and generates the conclusion draft from the recorded vulnerabilities and recommendations.
  3. 03Created a mobile-first design system in Tailwind CSS 4 — semantic color tokens, buttons, selection chips on native radios, a stepper and fields, with 44 px touch targets on the main controls — reused across all analysis axes.
  4. 04Integrated voice notes into every long text field with MediaRecorder and the Web Speech API: the audio is saved and, where the browser supports it, speech is transcribed into the field in Brazilian Portuguese.
  5. 05Implemented local persistence with Zustand (localStorage) and IndexedDB (idb-keyval) for drafts, photos and audio, plus JSON package export/import validated by Zod, so analysts keep working without signal, pick up where they left off and resume the report on another device, with no backend.
  1. Field collection

    Without signal, the indicator switches to offline and filling in continues, with each item rated in a single tap. Each vulnerability gets numbered photos, and the voice note is kept as audio, with partial transcription where the browser supports it.

    • An assessment step without a connection: a Saved · 11:32 · offline indicator at the top, items rated with rating chips, and the observed situation written in the text field, with a Record audio button.
      An assessment step without a connection: a Saved · 11:32 · offline indicator at the top, items rated with rating chips, and the observed situation written in the text field, with a Record audio button.
    • A vulnerability entry: impact chips selected, the Evidence not applicable switch off, two illustrative photos numbered 03 and 04 linked, and Take photo, Gallery and Use existing buttons.
      A vulnerability entry: impact chips selected, the Evidence not applicable switch off, two illustrative photos numbered 03 and 04 linked, and Take photo, Gallery and Use existing buttons.
    • Voice note recording on an item of an assessment step: a rating selected, the observed situation in the text field, a Recording 00:41 indicator, a Stop button and the partial transcription in italics below.
      Voice note recording on an item of an assessment step: a rating selected, the observed situation in the text field, a Recording 00:41 indicator, a Stop button and the partial transcription in italics below.
  2. The same codebase on a computer

    On a computer, the same codebase adds a sidebar with each step's status: complete, in progress or not started.

    The form on a computer, with the report 47% complete: a sidebar with each step's status (complete, in progress or not started), the step's items rated with rating chips, the observed situation in the text field and a 42-second voice note.
    The form on a computer, with the report 47% complete: a sidebar with each step's status (complete, in progress or not started), the step's items rated with rating chips, the observed situation in the text field and a 42-second voice note.
  3. Review and transfer

    The review lists what is missing in each step, with a shortcut to open the step and finish it. With no server, the report travels between devices as a JSON package, with or without photos and audio.

    • Review of a report in progress: a Report status card at 47% with 17 open items, a progress bar and the list of steps with Complete, In progress or Not started status, each step's open items and an Open button.
      Review of a report in progress: a Report status card at 47% with 17 open items, a progress bar and the list of steps with Complete, In progress or Not started status, each step's open items and an Open button.
    • Review step: a Generate RAR-AI card with a View and print (PDF) button, and a Save and transfer card with 4 photos and 4 voice notes, a toggle to include media and Export package (.json), Import package and New report buttons.
      Review step: a Generate RAR-AI card with a View and print (PDF) button, and a Save and transfer card with 4 photos and 4 voice notes, a toggle to include media and Export package (.json), Import package and New report buttons.

Features and the pains they solve

Every feature was born from a real operational problem.

  1. 01

    Offline saving on the device

    Pain
    Data is collected in places with an unstable connection. Any network dependency mid-inspection risks losing what has already been recorded.
    Solution
    Every change is written immediately: the report goes to localStorage and photos and audio go to IndexedDB, to stay clear of localStorage's ~5 MB limit. An indicator shows “Saved · time” and flags when the device is offline, without interrupting the work, and the report reopens where the analyst left off.

    Impact: Saved on every change, no save button

  2. 02

    Confidential rules engine

    Pain
    The report depends on extensive domain logic — risk level, mandatory checklists and a conclusion consistent with the findings — which, outside the app, required a separate calculation, the analyst's memory and retyping.
    Solution
    A deterministic TypeScript rules engine computes the risk level automatically, builds the mandatory checklist based on the unit's profile and generates the conclusion draft from the recorded vulnerabilities and recommendations. The methodology and rules are confidential and are not detailed here.

    Impact: Risk calculation covered by automated tests

  3. 03

    Steps with status and open items

    Pain
    Analysts walk the unit in the order the site dictates, not the template's, and in a report with dozens of fields it is easy to hand in something incomplete without noticing.
    Solution
    The template became 11 steps that open in any order, with a step bar showing each status and listing specific open items (e.g. “Vulnerability 02: description, impact and evidence”). The review gathers them all with a shortcut to each step and warns before the report is generated.

    Impact: Review is marked complete only when the other 10 steps are

  4. 04

    Voice notes with transcription

    Pain
    There are many long text fields, and typing on a phone during the visit is slow.
    Solution
    Every long text field has a recorder: the audio is kept as a note, with playback and “Insert into text”. Where the browser offers the Web Speech API and there is a connection, speech is transcribed into the field in Brazilian Portuguese.

    Impact: Voice on every long text field, from the assessment to the conclusion

  5. 05

    Numbered photo evidence

    Pain
    The template requires each vulnerability to point to its photo evidence, numbered in the report.
    Solution
    Photos come from the rear camera or the gallery, are compressed and numbered automatically (“Image 01”), and can be reused for another vulnerability. With no photo and no “evidence not applicable”, the vulnerability stays an open item.
  6. 06

    Standardized assessment of the axes

    Pain
    The official template asks for a rating and observed situation for dozens of items; on a phone that means constant scrolling and lookups.
    Solution
    All axes follow the same pattern: observed situation per item and, for control items, a one-tap rating, with the assessment parameters at hand; then vulnerabilities recorded from the rated items themselves and recommendations picked from a predefined list.
  7. 07

    Pre-drafted conclusion

    Pain
    The conclusion repeats vulnerabilities and measures already recorded in the axes, which forced analysts to retype the same content.
    Solution
    The conclusion fields that repeat what was recorded in the axes have a button that inserts an editable draft built by rules from that record. There is no AI involved: the text comes only from what the analyst recorded.
  8. 08

    Official report as PDF

    Pain
    The final report combines tables, results and photo evidence that would otherwise come from separate notes and files.
    Solution
    The report page assembles the document following the official template's structure from what was filled in, with the rules engine's results and the photo evidence, plus a dedicated print style for Print → Save as PDF.
  9. 09

    Transfer package (.json)

    Pain
    Analysts collect on the phone but review and finish on a computer, or hand the visit to a colleague. With no server, the draft would be stuck on the device where it started.
    Solution
    The report is exported as a JSON package, with or without embedded photos and audio, and imported on another device. Import is validated by the same Zod schema as the state and points to the incompatible field when a file doesn't fit.