Skip to content

Uploading your own stores

LookAlike’s flagship feature lets you upload your own store list and instantly discover neighborhoods that resemble your footprint using the same method the tool applies to the built-in brands. In the authenticated product, the source CSV is stored in a private customer-data bucket, normalized rows are stored under the selected retail client, and the interactive scoring still runs in the browser. The source file is never exposed through the public national-data route.

To start, open the brand picker at the top of the left panel and choose the “Add a brand (CSV or OpenStreetMap)…” row. That opens the upload modal, which has a tab for pasting or dropping a CSV and a tab for fetching a brand from OpenStreetMap.

When you upload a CSV of store locations, the tool:

  • Maps your stores to their nearest census tracts and builds a neighborhood archetype — the average profile of the neighborhoods your stores occupy
  • Ranks every continental-US census tract by how closely it resembles your archetype
  • Surfaces the exact features driving each match on the map and in neighborhood detail panels
  • Optionally applies performance weighting (if you include revenue/sales data) to lean your archetype toward your best-performing locations
  • Optionally flags locations to avoid (closures, failures, underperformers) so the tool shows neighborhoods that look like your winners but NOT like your failures

This is resemblance and discovery, not sales prediction. The labels — revenue, closed, failed — are your ground truth, not a statistical model. Use this to find neighborhoods worth visiting and vetting, not to shortlist sites automatically.

Your upload must include latitude and longitude. Everything else is optional.

Required columns:

  • lat (or latitude, y) — decimal degrees, −90 to 90
  • lon (or lng, long, longitude, x) — decimal degrees, −180 to 180

Optional columns:

  • Performance column — named revenue, sales, value, volume, performance, perf, score, weight, or similar. Numeric values. When present, the Weight by performance toggle becomes available; turning it on leans your archetype toward locations with higher values.
  • Status column — named status, label, group, tier, segment, outcome, result, or class. Values like closed, failed, low, bad (or their variations) mark a location as a failure. Alternatively, a boolean column named failed with values true, 1, yes, or y. When present, the Avoid my failed/low locations toggle becomes available; turning it on downranks neighborhoods that look like your flagged failures. If no status column exists but you have performance data, the bottom third of locations (by performance) are automatically treated as failures.

The upload modal accepts .csv files or plain text pasted directly (tab, comma, or semicolon delimited). It proposes a column mapping, then requires you to confirm latitude, longitude, store identifier, performance, status, and failure columns before saving.

lat,lon,revenue,status
40.7128,-74.0060,2400000,open
34.0522,-118.2437,610000,closed
42.3601,-71.0589,1890000,open
39.7392,-104.9903,540000,failed
41.8781,-87.6298,2100000,open
47.6062,-122.3321,280000,low

In this example:

  • Winners (colored dots on the map): the open and closed stores with higher revenue (New York, Boston, Denver, Chicago, Seattle)
  • Failures (red-ringed dots): the failed location in Denver and the low-revenue location in Seattle

When you enable Avoid my failed/low locations, the scoring penalizes neighborhoods that resemble the failures. The final score for each tract becomes: resemblance-to-winners − (avoidance-strength) × resemblance-to-failures.

Winners show as solid colored dots on the map (the same hue as the uploaded brand). They form the core of your archetype.

Failures show as dots ringed in red. They are excluded from the archetype itself; instead, they define what to penalize.

When you select a neighborhood in the detail panel, you’ll see a winners-vs-failures breakdown — how similarly that neighborhood ranks to each group.

Available only if your CSV includes a numeric performance column (revenue, sales, or similar) with non-empty values in at least some rows.

When enabled, the archetype becomes a weighted average over your store locations. The default transformation uses percentile ranks rather than raw revenue: each valid store is ranked within the uploaded metric, then receives a stable 0–1 weight. This prevents one flagship location, malformed value, or currency scale from dominating the archetype. You must also state whether higher or lower values represent better performance.

When disabled, all non-failed locations are weighted equally, so the archetype is an unweighted mean.

Available if your CSV includes explicit failure flags (a status column with closed/failed/low values, or a boolean failed column) or if you have performance data.

When enabled, tracts are scored as resemblance-to-winners − (avoidance-strength) × resemblance-to-failures.

  • If you flagged failures explicitly (status column), those locations form the failure archetype.
  • If you only provided performance data, the bottom tercile (lowest third) of locations by performance are treated as failures.
  • The avoidance-strength slider controls the penalty weight (0–100%). At 60%, the penalty accounts for 60% of a unit of resemblance-to-failures. Higher values make failure lookalikes rank lower relative to winner lookalikes.

When disabled, all uploaded locations are treated equally.

Authenticated CSV uploads become immutable, versioned datasets under the selected retail client. LookAlike stores the original CSV privately, normalized store rows and quality flags in D1, the selected performance definition, and the national-data release used for tract assignment. A baseline analysis records the scoring-engine version and configuration.

  • It survives reloads. Open the upload dialog and load any published dataset available to your client account.
  • Versions are immutable. Uploading a corrected file creates another version instead of changing the rows behind an existing analysis.
  • Access is client-scoped. Owners and administrators can access all clients; analysts and viewers see only explicitly granted clients, and viewers cannot upload or delete.
  • Deletion is complete. Deleting a dataset removes its normalized records, recorded analyses, and private source object while preserving a non-sensitive audit event.

The unauthenticated pnpm dev workflow remains browser-only for quick interface development. CSV profiles created in that mode use local browser storage and are not customer records.

If you want to analyze a chain that isn’t one of the eleven built-ins and you don’t have a store list of your own, the tool can fetch one from OpenStreetMap for you. Open the brand picker, choose the “Add a brand (CSV or OpenStreetMap)…” row, switch to the OpenStreetMap tab, type the chain’s name (or pick one of the suggested chains, which attaches a Wikidata identifier for a more reliable match), and the browser queries the Overpass API directly for that chain’s United States store points, dedupes them on a 150 m grid, and routes them into the same custom-profile flow described above — labeled with the brand name. The fetched brand is then saved in your browser like any other custom brand.

This mirrors the pipeline’s own store fetch: a union query on brand:wikidata plus the exact name on shops and amenities, within a continental-US bounding box. The query runs from your browser; the two public Overpass endpoints are tried in turn, and very large chains are capped (with the truncation reported) so the request stays manageable.

This is a descriptive neighborhood-resemblance tool, not a predictive sales model. The scoring:

  • Does NOT assume resemblance causes revenue or store success
  • Does NOT adjust for local competition, rent, visibility, traffic patterns, or any other factor beyond census neighborhood characteristics
  • Does NOT validate that your category works in similar neighborhoods
  • Is NOT comparable in prediction strength across different brand categories (a grocery store’s archetype and a coffee chain’s differ profoundly, but both are valid for discovery)

The resemblance percentile (0–100) ranks tracts within your own upload — it is not comparable to the percentile of a built-in brand. Two different custom uploads will have different national ranking scales based on their own archetypes.

The browser computes the entire analysis client-side using the same method as the Python pipeline:

  1. Your lat/lon points are snapped to the nearest tract centroid (approximate at tract borders)
  2. A weighted mean is computed for each of the 21 neighborhood features (income, education, density, age, race/ethnicity, retail context) — using your performance weights if enabled
  3. Each tract is scored as a standardized distance from your archetype, grouped by theme so correlated features don’t over-influence the result
  4. The distance is converted to a 0–100 similarity percentile — higher = more like your winners. The browser also computes the four distance quantiles of your own occupied locations, so each tract gets a Strong / Moderate / Weak absolute-fit band measured against your footprint, exactly as it is for the built-in brands.
  5. If you enable failure avoidance, a second “failure” archetype is built and the final score subtracts a penalty for resemblance to failures

The Worker validates and persists the source file, mapping, normalized locations, metric definition, quality summary, tract assignments, and release lineage. The scoring calculation itself happens in the browser so factor changes remain immediate. Production logs must not contain raw rows, performance values, addresses, session tokens, or source files.