-
-
OISINT app icon — 1024 x 1024, uncropped. Created with AI assistance.
-
Native Android evidence and voting screen from a live restaurant investigation.
-
Native Android home screen. Choose a dining scene and start a restaurant investigation.
-
Native iOS comparison table and group voting from a live Shibuya investigation. 1179 x 2556, no device frame.
-
Native iOS candidate cards with per-condition ratings; unverified conditions shown as ?. 1179 x 2556, no device frame.
The name
OISINT (pronounced oy-shint, オイシント) blends the Japanese word oishii ("delicious") with SIGINT (signals intelligence). It's intelligence work for finding a good meal.
Inspiration
Choosing a restaurant for a group in Japan means jumping between review sites, map apps and a group chat full of opinions. Most of that time goes into checking whether a place actually fits: price, atmosphere, whether you can talk. And nobody can see why someone picked a place. I wanted one flow that goes from "here's what we need" to a choice the group trusts.
What it does
- Plain-language request. Example: "3 people in Shibuya, under ¥4,000 each, quiet enough to talk."
- Candidate discovery from public place data (Geoapify / OpenStreetMap) and web search.
- Per-condition evaluation. Each candidate is checked against every condition. When public information can't answer a condition, it is shown as unknown instead of guessed.
- Evidence links. Every rating links to the public source behind it.
- Group voting. One shared link lets everyone compare and vote on the same shortlist.
- OISINT Plus. An optional monthly (¥580) or annual (¥4,800) subscription through RevenueCat. Research, Evidence and voting stay free.
How I built it
- Native clients: SwiftUI (iOS/iPadOS) and Kotlin + Jetpack Compose (Android). They share the same domain contracts with an Expo web client.
- Backend: Supabase (Postgres with row-level security, Auth, Edge Functions) and a Cloudflare Worker API. Gemini parses requests and evaluates evidence with structured output; contradiction detection and ranking run in code, not in the model.
- Testing: TypeScript, Deno, Swift and Kotlin unit tests, plus Playwright end-to-end tests. A deterministic mock provider lets anyone run the full flow locally without API keys.
RevenueCat integration
- One contract, two stores. iOS (StoreKit) and Android (Google Play Billing) implement one
EntitlementProvideron top of the RevenueCat SDK: offerings, purchase, restore, and log in/out. The account UUID is the App User ID, never an email address. - Server-verified, fail-closed. A Supabase Edge Function receives RevenueCat webhooks (Bearer + HMAC verified) and stores entitlements in Postgres. Out-of-order lifecycle events (cancellation, billing issue, product change, pause) are reconciled. The clients unlock Plus only after the server confirms a signed future expiry or grace period.
- Transparent paywall. Each plan's title, duration and price, Restore Purchases, and links to the Terms, Privacy Policy, cancellation and refunds. Deleting an account starts a RevenueCat customer deletion request and warns that store subscriptions are not cancelled automatically.
Challenges
- Contract drift between clients. The Android build sent a field that the research endpoint didn't accept, so research never started. The build passed; only testing the release build against the live service exposed it. I fixed it with a shared contract and regression tests.
- Honest uncertainty. Getting a language model to say "unknown" instead of inventing an answer took explicit evidence requirements and a separate evaluation step.
- Store billing edge cases. Google Play base-plan identifiers and out-of-order webhook events both broke naive entitlement logic.
Accomplishments
- OISINT 1.0 is live on Google Play (com.oisint.android, first public release October 1, 2026). The iOS build is in App Review.
- A live Android investigation runs end to end: request → three candidates → source-linked Evidence → voting.
- We presented an earlier version at AIAU Craft Day (August 2026) and received the Audience Award.
What I learned
A green build is not a working product. The most valuable tests ran the real user journey against the real service. Treating "no evidence" as a first-class result also made the app more trustworthy than trying to always produce an answer.
What's next
- Finish App Store review and ship the English UI to the store builds
- Verify production purchase and restore end to end, then improve research quality from observed use
- Expand beyond Tokyo
Code and demo
- Public repository (Next Gen, AGPL-3.0): https://github.com/eightman999/OISINT-nextgen
- Demo video: https://youtu.be/gQNt_Z_Md04
AI disclosure
The app icon was created with AI assistance. AI coding assistants were used during development. The design, decisions and review are mine.
Built With
- cloudflare-workers
- expo-router
- expo.io
- gemini
- geoapify
- hono
- jetpack-compose
- kotlin
- openstreetmap
- pgvector
- playwright
- postgresql
- react-native
- react-native-web
- revenuecat
- serper
- supabase
- swift
- swiftui
- tanstack-query
- typescript
- zod
Log in or sign up for Devpost to join the conversation.