Universal Finder
Card: Universal Finder · 6 items · Source: PADI Mobile Scope Alignment v-ceb35f4d
Consumer: the unified PADI app — Expo React Native.
All six items are parked. Almost all of them already exist.
Every item on this card carries
PRK— the client has not given direction, and nothing here is committed. That is the right posture for a product decision.It is the wrong conclusion to draw about feasibility. Five of the six are already built and running in production, three of them proven from a PADI mobile app. The question this card faces is not "can it be built" but "which of the two systems that already do it should the unified app use."
The evidence base: what can actually be verified
These items are parked, so their endpoints may be renamed or restructured before anything is built. What does not move is whether the capability exists — and that is answerable from two durable sources: the source of the apps and front ends that already do it, and our own POCs.
The eleven web repositories checked out under existing-web-apps/ make the first checkable. "Does a PADI web front end call this?" no longer has to be answered from a browser capture — the weakest usable class — because the front-end source is readable.
| Repo | What it is |
|---|---|
padi.com |
padi-frontend — Next.js, the November 2026 rebuild, reads Drupal over JSON:API |
padi-blt |
The current padi.com — Drupal on Acquia BLT |
diviac |
PADI Travel — Django + Elasticsearch. Dive sites, dive centres, destinations, the locator |
scuba-diving |
scubadiving.com — Drupal |
pro-cms |
pro-cms.padi.com — Drupal |
account · club · learning · pro .padi.com |
Vue SPAs |
customer-padi, languages.padi.com |
Shared packages; translation bundles |
A new evidence class, and it is the strongest yet: Web-source. An endpoint cited to file:line in a PADI web repository is better evidence than a browser capture — it shows the route, its parameters, its permissions and its shape, not just that a request happened.
This also answers PADI-20 outright. The Nov 2026 front end reads Drupal at
${BASE_URL}/{locale}/jsonapi/{path}(padi.com/src/shared/services/drupal.ts:19-21), for examplejsonapi/node/page/{uuid}. Published content needs no authentication — the onlyAuthorizationheader is an optional HTTP Basic for Shield-protected non-prod environments (drupal.ts:24-37).So Drupal JSON:API is live, locale-aware and anonymously readable. Any content type the web team builds is exposed to the unified app for free, in every language, the day it ships. That closes PADI-20 and strengthens LEGAL-04.
What "Universal Finder" already is
Three of the six items are Drupal content-modelling tasks, not mobile features. FIND-01, FIND-02 and FIND-03 read, verbatim: "Create a Destination content type in Drupal 11", "Create a Dive Site content type in Drupal 11", "Create a Dive Centre content type in Drupal 11". The deliverable is a CMS schema plus Crowdin translation. Mobile's stake is only whether the result is readable — and by the finding above, it is.
And a complete finder already runs on PADI Travel. diviac is a Django platform with Elasticsearch, and its travel_v2 app tree includes dive-guide/, dsl/, search/, places/, shop/ and marine-life/ (src/diviac/apps/travel_v2/urls.py:25-35).
dsl is the Dive Shop Locator — the same locator the PADI app already sends divers to. So the two are already connected, just not by an API.
The tension worth putting to the client. FIND-01's own scope says "Any travel.padi.com integration is deferred to Phase 2." The artefact therefore proposes building a new destination/dive-site/dive-centre model in Drupal while a production one with Elasticsearch, a place hierarchy, maps and autosuggest sits on travel.padi.com — and while the PADI app already links into it.
That may be the right call: Drupal content is editorial and marketing-owned, Diviac's is operational and commerce-owned. But it is a build-versus-reuse decision nobody has stated as one, and it is the question this parked card is actually waiting on (SCOPE-18).
We have already built this — the POC settles most of the card
poc/mobile-poc contains [PAM-18] — Spike: Dive Center locator (RN): a working rebuild of the web /dive-shops search-with-map view in Expo ~57 / RN 0.86 / React 19, on the existing Travel & Adventures APIs, carried through to booking. There is a video walkthrough at padi-dive-shop-docs.spin.axelerant.tech.
Its own status line:
LOCATOR: WORKING·DIVE-SHOP DETAIL + NATIVE COMMERCE: WORKING·RADIUS SEARCH: OPEN (new API)·SERVER-SIDE COURSE/CERT FILTERS: OPEN (new API)·Q11 CANONICAL BACKEND: OPEN
This is why the parked status and the feasibility answer can be so far apart. The locator is not a question of whether React Native can do it — we have done it, against real hosts, and the locator path is unauthenticated (Accept / Accept-Language only). What is open is narrower and more useful than "is it feasible":
| POC finding | Bearing on this card |
|---|---|
LOCATOR: WORKING |
FIND-03, FIND-05 — proven in the target stack |
DIVE-SHOP DETAIL: WORKING |
FIND-04 — proven, including native commerce on top |
RADIUS SEARCH: OPEN (new API) |
FIND-05 — "distance from a location" needs an endpoint that does not exist |
SERVER-SIDE COURSE/CERT FILTERS: OPEN (new API) |
FIND-05 — course and certification filtering is client-side today |
Q11 CANONICAL BACKEND: OPEN |
This is SCOPE-18. The POC hit the same question and left it open |
One architectural finding worth carrying: the POC needed two API shapes from one backend — api/mobile/v1 for search and scoping, api/v2/travel for list, map pins and detail. "Neither alone can serve the locator" (ADR 0001). Any estimate that assumes a single clean API for the finder is wrong on evidence we already have.
What each app does today
PADI app (kms-ios-padi / kms-android-padi)
- Dive Shop Locator is a webview.
Constant.swift:193—"\(Configuration.EndPoint.dsl.url)/dive-shops/nearby/?lang=%@&browser=in-app", where thedslhost resolves topadi.comin production (Configuration.swift:66). It is a home-screen shortcut (ShortcutType.swift:14,31,56). Android carries a Japan-specific variant,https://www.padi.co.jp/scuba-diving/dive-shop-locator/(build.gradle.kts:95). - Dive-site search is a real API, and it is mobile-proven — the Logbook Hasura GraphQL endpoint:
query DiveSites($searchString: String) { logbook_dive_site(where: {name: {_ilike: $searchString}}) { id name } }(kms-ios-padi/PADI/apollo.graphql:1-6). Name search only; no coordinates, so it cannot drive a map. - No map SDK. Neither KMS app declares MapKit, Google Maps or equivalent. Location permission strings exist and promise "help you find nearby PADI dive shops" (
Info.plist:65-69) — for the webview.
PADI Adventures (travel-rn) — this is the one that matters
A working finder, in a shipped PADI mobile app, with react-native-maps@^0.30.2 (package.json:76):
| Endpoint | Purpose |
|---|---|
/dive-centers/search/map/ · /activities/search/map/ |
Bounding-box map search with a type switch (app/containers/MapView.js:113-123) |
/dive-centers/nearby/ · /dive-centers/autosuggest/ · /dive-centers/populars |
Proximity, typeahead, curated |
/dive-centers/:id/detail/ · /dive-centers/:id/:type |
Detail pages |
/destinations/locator/ · /destinations/nearby/ · /destinations/populars |
Destination finder |
/destinations/continents · /destinations/countries |
Place taxonomy |
/destinations/gmaps/places/autocomplete/ |
Google Places autocomplete for typed locations |
The map call posts activity_type, top_right and bottom_left lat/lng plus an optional date, and re-queries on viewport change — "search this area" (MapView.js:105-124). That is FIND-05 scope lines 1, 3 and 5 already implemented, on a phone.
Diviac (travel_v2) — the API behind it
dive-guide/autosuggest/— cross-place autosuggest,?q=with a 3-character minimum, spanninglocation, area, country, region, continent(views/autosuggest.py:11-29)dive-guide/{continent|region|country|area|location|world}/{id}/dive-sites/and/dive-centers/(dive_guide/urls.py:8-12,45-50)dsl/dive-shops/map/,dsl/dive-shops/{pk}/map/,dsl/dive-shops/{place_type}/{place_id}/dsl/dive-sites/map/,dsl/dive-sites/{pk}/map/,dsl/courses/…/autosuggest/search/shop_autosuggest/{liveaboards|dive-resorts|dive-centers|conservation-shops}/marine-life/— relevant to the monthly marine life calendar in both FIND-01 and FIND-02
Nov 2026 padi.com (padi-frontend) — features built so far are auth, layout, articles, blog, preview (src/features/). No finder, no destinations, no dive sites, no dive centres. The new web front end has not built this either.
FIND-01 — Destinations and Dive guides
Area 06 · Flags PRK parking · Jira E4 · Impact High · Effort Low
API status: Existing — web · Feasibility: buildable from either source; the choice is unmade
What it needs. A Destination content type in Drupal 11 — name, region, hero imagery, climate, dive seasons, water temperature and visibility, a monthly marine life calendar — related to Experiences, Dive Sites, Dive Centres and Trips, CMS-editable, translated via Crowdin.
Available today. Two independent sources:
- Diviac — the place hierarchy (
continent|region|country|area|location|world) with dive sites and dive centres hanging off it, plusmarine-life/for the calendar. Mobile-proven through Adventures'/destinations/*endpoints. - Drupal JSON:API — the moment the content type exists,
/{locale}/jsonapi/node/destinationserves it anonymously, in every Crowdin language.
Gap. None for mobile. The Drupal content type does not exist yet, but building it is web scope (E4), and the API over it is automatic.
Notes for the RN client. The two sources model destinations differently — Diviac's is operational and Elasticsearch-backed; Drupal's would be editorial and translated. Reading both means reconciling two place taxonomies in the client, which is the thing to avoid. Pick one per surface and say so.
POC coverage. Place scoping is proven — the POC's Scope model is "exactly one of: a place (type + id), a point (nearby search around device coords + distance), or bounds" (mobile-poc/CONTEXT.md), and Google Places results resolve to PADI destinations via gmaps/autocomplete → destinations/locator. Destination content (climate, seasons, marine-life calendar) was not in POC scope.
Verdict. Buildable, and the place-scoping half is POC-proven. Parked for a product reason, not a technical one.
Questions: SCOPE-18 (Drupal or Diviac as the source of place data)
FIND-02 — Dive Sites
Area 06 · Flags PRK parking · Jira E5 · Impact High · Effort Low
API status: Existing — mobile · Feasibility: buildable; the current mobile endpoint is too thin for a map
What it needs. A Dive Site content type with coordinates, visibility, temperature, current, entry type, skill level, boat capacity and a monthly marine life calendar; related to Destination, Experiences, Dive Centres and Courses; an interactive map pinning the site and showing nearby sites and centres.
Available today.
| Source | What it gives | Class |
|---|---|---|
Logbook Hasura GraphQL — logbook_dive_site |
{id, name}, _ilike name search |
Mobile-proven (apollo.graphql:1-6) |
Diviac dive-guide/{place}/{id}/dive-sites/ |
Site search within a place | Web-source |
Diviac dsl/dive-sites/map/ · {pk}/map/ |
Map-shaped site data | Web-source |
Diviac marine-life/ |
The monthly calendar | Web-source |
| Drupal JSON:API | The content type, once built | By construction |
Gap. None in availability — but note the shape mismatch. The one dive-site endpoint the PADI app already calls returns only id and name. It backs a logbook autocomplete, not a map. Scope line 4 needs coordinates, and those come from Diviac or from the new Drupal type, not from the Hasura query.
Notes for the RN client. The PADI app has no map SDK; Adventures has react-native-maps. The unified app needs one regardless, and that is a client decision with no API dependency.
POC coverage. Dive sites appear in the POC as "an optional secondary pin overlay on the map", carrying {id, latitude, longitude} (CONTEXT.md). So map-shaped dive-site data is proven reachable; the richer content model was not in scope.
Verdict. Buildable, with the map overlay POC-proven. Do not let the existing logbook_dive_site query be mistaken for sufficient — it is a name lookup.
Questions: SCOPE-18 · SCOPE-19 (is the marine-life calendar in scope, and from which source)
FIND-03 — Dive Shop and Dive Centres
Area 06 · Flags PRK parking · Jira E6 · Impact High · Effort Medium
API status: Existing — web · Feasibility: buildable; one part is not an API question at all
What it needs. A Dive Centre content type — name, location, contact, hours, affiliated instructors, courses, experiences, price range, ratings, gallery — related to Instructors, Courses, Experiences, Dive Sites and Destination, with a contact form routing enquiries into Salesforce as lead records, plus Dive Centre schema markup for local SEO.
Available today. The whole read side. Diviac's dsl/dive-shops/{place_type}/{place_id}/ and dsl/dive-shops/map/ serve exactly this, and Adventures already consumes the equivalent via /dive-centers/:id/detail/.
Two parts that are not reads, and neither is mobile's:
- Salesforce lead capture (scope line 4). No Salesforce write path exists from any client — the same finding as PADI-3 on profile write-back. If this is in mobile scope it needs an endpoint nobody has; if it is web-only, say so.
- SEO structured markup (scope line 4 of the merged shop-detail text) is meaningless in a native app. Carrying it to mobile as parity is the same category error as the Cookie Policy in LEGAL-03.
POC coverage — the strongest on the card. LOCATOR: WORKING and DIVE-SHOP DETAIL: WORKING, in Expo, against the real Travel hosts, unauthenticated for browse.
Verdict. The directory is buildable and POC-proven. The lead-capture and SEO lines should be marked web-only before anyone estimates this for mobile.
Questions: SCOPE-20 (are Salesforce lead capture and SEO markup in mobile scope — recommend no) · PADI-3
FIND-04 — Dive shop & dive site detail pages
Area 06 · Flags PRK parking, Q1 delta (r:feb)
API status: Existing — mobile · Feasibility: buildable now
No detail drawer. The only item on this card in the Q1 2027 delta bucket rather than carried-forward — so if any of the six is nearest to commitment, it is this one.
Available today. /dive-centers/:id/detail/ and /dive-centers/:id/:type are called by a shipped PADI mobile app (travel-rn/app/screens/DiveCenterScreen.js:152-156). Dive-site detail comes from Diviac's dsl/dive-sites/{pk}/map/ and the dive-guide place routes; a Drupal node serves it once the content type exists.
Gap. None.
POC coverage. DIVE-SHOP DETAIL + NATIVE COMMERCE: WORKING — the POC goes past the detail page into booking and native Stripe checkout (ADR 0005). Note the shop popup detail is fetched separately and carries no coordinates; it is anchored to the tapped pin (CONTEXT.md).
Verdict. Buildable, POC-proven, and the least ambiguous item on the card.
Questions: SCOPE-18 (which source)
FIND-05 — Shop Search & Filtering
Area 06 · Flags PRK parking · Jira E20 · Impact High · Effort Medium
API status: Existing — mobile · Feasibility: buildable — most of it is already running on a phone
What it needs. Map and list view of PADI-affiliated shops; filters for course offered, experience type, price range, instructor specialties and distance; search from a typed location or device location; tab switching between Dive Shops, Dive Centres, Pro Activities and Experiences; fast and responsive on mobile.
Available today — line by line:
| Scope line | Status |
|---|---|
| 1. Map + filterable list | Built. MapView.js with MapWithMarkers and a result carousel |
| 3. Typed location | Built. /destinations/gmaps/places/autocomplete/ |
| 3. Device location | Built. /dive-centers/nearby/ |
| 4. Tab switching between search types | Built. selectedActivityType.queryName === 'dive_center' ? '/dive-centers/search/map/' : '/activities/search/map/' (MapView.js:121) |
| 5. Responsive on phones | Built. It is a phone app |
| 2. Filters — course, experience, price, specialty, distance | Partial, and the POC pins it down. RADIUS SEARCH: OPEN (new API) and SERVER-SIDE COURSE/CERT FILTERS: OPEN (new API) — so distance and course/certification filters both need endpoints that do not exist. Instructor specialty is not evidenced anywhere |
| 6. New centres appear automatically | Web/Drupal concern |
Gap — now precise, thanks to the POC. Not "filter breadth" in the abstract. Two named filters need new endpoints: radius/distance search, and server-side course/certification filtering. Instructor specialty has no evidence at all. Everything else in the scope text is built.
POC coverage. Map, list, place scoping, device-location search and viewport re-query all WORKING in Expo. The POC's Scope model already includes a point (device coords + distance) — but the server cannot filter by radius, which is why radius search is listed as a new API.
Verdict. The strongest item on the card, and the one where the POC most changes the conversation: this is not a feasibility question, it is two endpoints and a filter spec.
Questions: SCOPE-21 (confirm the filter set) · PADI-23 (radius search and server-side course/cert filters — both need new endpoints)
FIND-06 — Universal finder — cross-object search & locator
Area 06 · Flags PRK parking
API status: Gap · Feasibility: strong primitives, no cross-object search
No detail drawer. The item the card is named after, and the only genuine gap on it.
What exists is search within object families, not across them:
dive-guide/autosuggest/spans place types — location, area, country, region, continent (views/autosuggest.py:28)search/shop_autosuggest/*spans shop types — liveaboards, dive resorts, dive centres, conservation shopsdsl/courses/autosuggest/covers courses- Drupal JSON:API can serve any single content type, and Drupal search could index across them — but the new front end has no search feature built
Gap. One query returning Destinations and Dive Sites and Dive Centres and Courses and content, ranked together. Nothing does that. Diviac's autosuggests are Elasticsearch-backed and federating them is realistic — but it is a build, and it spans two platforms that do not share an index.
Notes for the RN client. A client-side fan-out across three or four autosuggests with merged ranking is achievable and would look like a universal finder, but ranking across heterogeneous sources without a shared index is exactly where such features disappoint. This is the item most improved by the Axelerant BFF: one endpoint, server-side fan-out, one ranking policy.
POC coverage. None. The POC deliberately scoped to the dive-shop locator; cross-object search was never attempted, and nothing in it suggests the primitives federate on their own.
Verdict. Not buildable as one query today. Correctly parked — and unlike the other five, parking it is a technical judgement as well as a product one.
Questions: SCOPE-22 (what "cross-object" spans) · PADI-22 (is a shared search index planned)
Summary
| Status | Items | Count |
|---|---|---|
| Existing — mobile | FIND-02, FIND-04, FIND-05 | 3 |
| Existing — web | FIND-01, FIND-03 | 2 |
| Gap | FIND-06 | 1 |
Five of six are buildable. Three are POC-proven in Expo. All six are parked.
That gap between feasibility and commitment is the finding to take back to the client. The card is not waiting on engineering discovery; it is waiting on a decision, and the decision is narrower than "do we want a finder":
- Drupal or Diviac? (SCOPE-18) FIND-01/02/03 are scoped as new Drupal 11 content types, while a production, Elasticsearch-backed, map-capable equivalent runs on travel.padi.com — and the PADI app already links into its locator. FIND-01's scope defers that integration to Phase 2 without saying why. This one question governs four of the six items.
- Which lines are web-only? (SCOPE-20) Salesforce lead capture and SEO structured markup are in FIND-03's scope and neither belongs in a native app.
- What does "cross-object" mean? (SCOPE-22) The only real gap, and the one the card is named for.
What is not in doubt: map search, proximity search, typed-location autocomplete, place hierarchy, detail pages and type-switching are all live in production, three of them already running inside a PADI mobile app — and the locator and shop detail have been rebuilt in Expo against the live Travel APIs and reached WORKING.
What the POC says is genuinely missing is two endpoints, not a capability: radius search and server-side course/certification filters (PADI-23).
One thing to fix regardless
The PADI app's Dive Shop Locator is a webview to a URL with a hardcoded Japanese variant on Android. Whatever is decided here, the unified app should reach the locator through an API — Diviac already exposes one — rather than by re-embedding a web page with per-market URL branching.