2026-05-21DataMesh Consulting
21 May — iOS v1.1 to the App Store, AfDB detail-page extractor, dashboard site reorder
A heavy ship day across three surfaces. iOS v1.1 went to App Store review — version bump, full AppIcon asset catalog, IAP compliance, plus three behavioural fixes (honest offline banner, rich SwiftData cache, detail-screen refetch after deep-link). The African Development Bank extractor was rewritten as a URL-dispatching Step-0 that handles both listing pages and per-project detail pages, with terminal-status pruning so closed/cancelled tenders don't keep getting re-extracted. And the operator dashboard's Sites tab got drag-and-drop reorder + enable/disable controls, replacing the JSON-edit-and-redeploy workflow.
iOS v1.1 — submitted to App Store review
A bundle of items had accumulated since v1.0:
- Version bump to 1.1, build 17.
- AppIcon asset catalog properly populated. The previous
AppIcon.appiconset.
- IAP compliance — Apple's review notes on v1.0
Product.purchase() with
receipt validation against the backend's /v1/billing
endpoint. The non-IAP web-purchase path still exists
for direct sign-ups via the web portal, but inside the
iOS app it's IAP-only per Apple's guidelines.
Plus three behavioural fixes in the same submission:
- Honest offline banner — the previous version showed
- Rich SwiftData cache — the cache schema was missing
- Detail-screen refetch — opening a tender via a deep
African Development Bank — URL-dispatching extractor
The previous AfDB extractor was listing-only — it scraped the procurement-notices feed and stopped. Description, CPV codes, contact info, and value all stayed null because they live on the per-project detail pages.
The rewrite dispatches on URL pattern at job-time:
https://www.afdb.org/.../procurement-notices?...→ listing
https://www.afdb.org/.../project/...→ detail parser
Terminal-status pruning is the new behaviour:
- If the detail page shows the notice as "Award notice",
- The next listing-poll won't re-fetch the detail page
- This stops a long-running waste pattern where closed
Coverage delta: AfDB went from ~600 tenders with mostly-null fields to ~480 tenders with full enrichment (the drop is explained by terminal-status pruning sweeping out years of old award notices). Average CPV-code coverage on AfDB notices: 78%.
Dashboard Sites tab — drag-and-drop reorder + enable/disable
The Sites tab in the operator dashboard had been read-only.
Reordering or disabling a site meant editing
backend/scripts/seed-sites.js, running the seed against
prod, and redeploying. Slow. Risky on a Saturday.
Three new affordances on the Sites page:
- Drag handle on each row reorders by
priority. Lower
PATCH /v1/admin/sites/:id { priority }.
- Enable/disable toggle flips
isActive. Inactive
- Optimistic UI so the toggle/reorder feels instant; if
Underlying API mutations all run through the standard admin-auth guard. No new privileged endpoints.
Other items
/tenders/searchresponse-shape fix — the backend
[Tender] array
to a { data, totalCount, ... } paginated envelope.
iOS was decoding the bare-array shape and silently
failing on the new envelope, showing "No results" even
when matches existed. iOS now tries both shapes (bare
first for compat, then envelope fallback). Backend will
also accept either query format.
- Saved-but-unmatched tenders in
/tenders/matches—
- SEO: redirects in
generateMetadata— GSC was
generateMetadata makes the
canonical match the destination URL.
What's next
- Wait on App Store review. The 1.1 submission has new IAP
- Tomorrow: the extractor wave continues. ADB and UNGM