Urgent.News

What's breaking now, across thousands of outlets.

Tech

Adding Speech Therapy to a Live Directory: The Read-Path Allowlist Pattern at Special Needs Care Network

Adding a category to a live directory is not one change. It is a schema change, a seeding job, an admin intake change, a routing change, and a sitemap change, and they cannot all ship in the same commit without a bad week. The technique that makes this tractable is boring and worth writing down: put a single allowlist on the public read path and treat it as the feature switch for the entire…

Introducing a new category to a live directory is a complex task. It involves multiple steps such as schema changes, seeding jobs, admin intake changes, routing changes, and sitemap changes. Unfortunately, all these changes cannot be shipped together in a single commit without causing issues. The key to managing this process smoothly is implementing a single allowlist on the public read path, which serves as the feature switch for the entire rollout.

Special Needs Care Network, the organization working on this directory, currently lists ABA therapy providers and special education schools across US cities. The speech therapy category is currently undergoing this process, making it a prime example.

The first step of this process has already been implemented: speech therapy is now a requestable service in the intake form, recorded as a distinct service on the inquiry record. However, it is deliberately excluded from automatic routing until the provider vertical is live. The approach is to first capture demand, then update the read path.

In every public read, there is a single exported constant: export const PUBLIC_DIRECTORY_V2_PROVIDER_TYPES = [ school , therapy_center ] as const ; This constant is applied by every query serving the public site. The database CHECK constraint can accept a new provider type, and rows of that type can exist. Admin tooling can edit these types. None of this affects the public site until the type is included in the allowlist array.

This single property is what ensures the rest of the process is safe. It allows schema and data work to be shipped early and invisibly. Wider type constraints, seeding new type rows, and backfilling locations all function as no-ops from the public site's perspective. They can be deployed days or weeks before the launch, each deploy verifiable on its own. The launch becomes a single atomic deploy.

Adding the new type to the array, adding the route tree, and adding the URL branch are deployed together. There is no period where the type is partially public. Rollback involves a simple one-line revert. The type is removed, and the pages reappear. No data is lost; the migration cannot be reversed, nothing is deleted, nor does anything need restoring.

There are two failure modes to guard against. The first is the allowlist, which is the only place that knows about types. The second is the hardcoded type lists in SQL views, and bundle and aggregate views, which carry their own WHERE provider_type IN (school, therapy_center). These are not visible to the application-layer allowlist.

If the switch is flipped without widening these hardcoded lists, the new category's pages will render, but they will be empty, returning a 200 status code. This is worse than a 404, as crawlers index these pages.

The second failure mode involves fallback normalizers, which map the new schema onto legacy type tokens. Every unknown type becomes a school. Adding a third type without updating this normalizer would cause speech clinics to render as schools, with school templates, breadcrumbs, and structured data. Neither of these failures would be caught by type checking, as they still produce valid 200 responses with plausible-looking pages.

To prevent these issues, it is crucial to verify the addition of the type to the allowlist after every hardcoded list that enumerates types has been widened and verified. This verification involves inserting a row of the new type, calling the views and resolver functions by hand, confirming the row appears in each, and then confirming the live site does not show it. This final check proves that the switch is truly a switch.

Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.

Read the original at dev.to →

More in Tech

More from Saturday 15 August →