Build Log

CityScout Build Thread / Part 4 of 4

CityScout Release Readiness: Turning a Prototype Into a Product

July 12, 20269 min read

The recent CityScout work has been less about adding flashy surface area and more about removing the reasons the product couldn't be trusted yet: tightening web auth, backend limits, failure behavior, release configuration, Android structure, and the documentation that keeps all of it honest.

Reading note

A clearer write-up of the product thinking, system choices, and tradeoffs behind the build.

Release readiness is less about one big launch moment and more about removing the reasons the product cannot be trusted yet.

Why This Push Matters

The early energy around CityScout was about proving the shape of the product: a local-first iOS app, a shared AI backend, structured city content, and a future web planning surface. That made the prototype easy to follow. It didn't, by itself, make the product ready to trust.

This push is different — it's about release discipline: fewer loose assumptions, clearer environment boundaries, safer failure behavior, and enough tests that the product can change without quietly breaking its contract. Less visible than a new screen, but it's the work that decides whether the product can leave the demo stage.

Security Before Surface Area

The browser layer raises the security bar because it cannot be trusted with the same assumptions as a native build or a server process. CityScout now treats that boundary more explicitly: web requests need a session before they can proxy AI work, OpenAI credentials stay server-side, and the backend keeps its shared-secret boundary for trusted clients.

  • Keep OpenAI credentials out of browser and native clients.
  • Require a Supabase web session before web routes can call protected AI endpoints.
  • Use shared-secret backend auth for trusted app-to-server calls instead of exposing model credentials.
  • Treat rate limiting, request caps, and structured non-2xx failures as product infrastructure rather than deployment polish.

This isn't the whole security story, but it's the right direction. The product should only add surface area once the trust boundary around it is clear enough to defend.

Making Mobile Release Real

The iOS app now has a more concrete release configuration path, including backend URL and shared-secret settings that can be supplied without hardcoding production values. That matters because a mobile release isn't just a binary — it's signing, configuration, store metadata, privacy details, support URLs, and a repeatable way to build the same thing twice.

Android is now real enough to have its own release questions too. The current Android work adds backend configuration, optional signing guidance, unit coverage, and a first destination-and-trip shell. That shell is intentionally modest. It gives the platform a release-shaped structure without pretending the Android feature set has caught up with iOS.

Tests As Product Infrastructure

The test work is doing more than checking syntax. Backend route tests now cover auth, request limits, invalid model responses, blank guide content, and failure paths that need to stay predictable in production. Web checks cover linting, unit behavior, and build output. Android has unit coverage around the first UI state logic and Gradle release/debug configuration checks.

  • Backend route tests protect the API contract and security boundary.
  • Regression tests catch OpenAI malformed JSON and blank guide-response behavior before it reaches users.
  • CI checks keep web, backend, iOS-adjacent documentation, and Android work from drifting independently.
  • Android unit tests make the new trip shell safer to extend without turning the first implementation into a dead-end prototype.

That's the value of testing here — it makes the boring parts observable enough that the visible parts can change with less risk.

What Is Still Not Done

This push isn't a launch announcement. It's a release-readiness pass, and several important pieces are still unfinished. The Android app still needs real destination content, tab content, and instrumented UI coverage. Store release work still needs account-side setup, screenshots, signing material, tester groups, privacy details, and support links.

  • Android feature content needs to move beyond the shell into useful trip and destination flows.
  • Store assets and account-side setup still need to be completed for iOS and Android distribution.
  • Web proxy behavior needs stronger observability so production failures are easier to diagnose.
  • A canonical itinerary V1 still needs to settle around stops, timing, validation, and contract tests.
  • Backend dependency locking can be tightened further if the project needs a full transitive production lock.

That remaining list is the point of writing this down. CityScout isn't just asking whether the idea works anymore — it's asking whether the system around the idea is disciplined enough to make the product safe to release.