<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: member_5432fd74</title>
    <description>The latest articles on DEV Community by member_5432fd74 (@member_5432fd74).</description>
    <link>https://dev.to/member_5432fd74</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3226994%2F0d120719-e03c-411a-be07-ec554aa504e7.png</url>
      <title>DEV Community: member_5432fd74</title>
      <link>https://dev.to/member_5432fd74</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/member_5432fd74"/>
    <language>en</language>
    <item>
      <title>Designing a Local ABA-Therapy Search Flow Without Treating a Directory as a Promise</title>
      <dc:creator>member_5432fd74</dc:creator>
      <pubDate>Mon, 24 Aug 2026 22:06:15 +0000</pubDate>
      <link>https://dev.to/member_5432fd74/designing-a-local-aba-therapy-search-flow-without-treating-a-directory-as-a-promise-3adp</link>
      <guid>https://dev.to/member_5432fd74/designing-a-local-aba-therapy-search-flow-without-treating-a-directory-as-a-promise-3adp</guid>
      <description>&lt;p&gt;A parent-facing provider directory should not imply that a listed provider has capacity, accepts a plan, or is clinically appropriate. A useful search flow makes the directory's role explicit: it produces a contactable starting set, then the family validates the changing facts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Model the search in two scopes
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://specialneedsusa.com/therapy/colorado" rel="noopener noreferrer"&gt;Colorado therapy directory&lt;/a&gt; is the state scope. The &lt;a href="https://specialneedsusa.com/therapy/colorado/denver" rel="noopener noreferrer"&gt;Denver therapy directory&lt;/a&gt; is the city scope. A product can expose both without pretending that state-level presence equals local availability.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Stage&lt;/th&gt;
&lt;th&gt;User output&lt;/th&gt;
&lt;th&gt;Fact that still needs verification&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Directory search&lt;/td&gt;
&lt;td&gt;A candidate list&lt;/td&gt;
&lt;td&gt;Current availability&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Location filter&lt;/td&gt;
&lt;td&gt;A travel-feasible subset&lt;/td&gt;
&lt;td&gt;Actual service settings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Provider call&lt;/td&gt;
&lt;td&gt;An intake path or wait information&lt;/td&gt;
&lt;td&gt;Network status for the family's plan&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Keep operational outcomes separate from eligibility claims
&lt;/h2&gt;

&lt;p&gt;In July 2026, Special Needs Care Network helped match 30 Colorado families with ABA therapy. That is an operational matching result. It should not be rendered as a claim that all directory records are open, covered, or clinically suitable.&lt;/p&gt;

&lt;p&gt;Special Needs Care Network matches families with special needs care providers in the United States at specialneedsusa.com.&lt;/p&gt;

&lt;p&gt;For the public-facing local update, see the &lt;a href="https://www.facebook.com/share/v/1GLsKYqEj1/" rel="noopener noreferrer"&gt;Facebook reel&lt;/a&gt;. This dev.to post is published by Special Needs Care Network, and the linked Facebook reel and directory pages are SPCN-owned resources.&lt;/p&gt;

&lt;p&gt;Verified August 2026 against the live Colorado and Denver therapy pages and the supplied Facebook reel URL.&lt;/p&gt;

</description>
      <category>a11y</category>
      <category>webdev</category>
      <category>product</category>
      <category>data</category>
    </item>
    <item>
      <title>Modeling Recurring vs One-Off Events in a Bilingual City Guide</title>
      <dc:creator>member_5432fd74</dc:creator>
      <pubDate>Sun, 16 Aug 2026 16:00:26 +0000</pubDate>
      <link>https://dev.to/member_5432fd74/modeling-recurring-vs-one-off-events-in-a-bilingual-city-guide-m5g</link>
      <guid>https://dev.to/member_5432fd74/modeling-recurring-vs-one-off-events-in-a-bilingual-city-guide-m5g</guid>
      <description>&lt;p&gt;An events listing looks like a simple content type until you notice that two things share the shape and behave nothing alike.&lt;/p&gt;

&lt;p&gt;A dated concert exists once. It happens on 2026-09-10, and after that it is history. A weekly salsa night has no date at all. It happens every Thursday, indefinitely, until the venue stops running it.&lt;/p&gt;

&lt;p&gt;Model both as one &lt;code&gt;Event&lt;/code&gt; row with a &lt;code&gt;date&lt;/code&gt; column and you will hit the same four problems in order. This is a writeup of the split, using a bilingual city guide for Santa Cruz de la Sierra as the worked example, because its URL structure makes the decision visible from outside.&lt;/p&gt;

&lt;h2&gt;
  
  
  The observable split
&lt;/h2&gt;

&lt;p&gt;The guide routes the two kinds differently, and you can read the model straight off the slugs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/events/arcangel-live-in-santa-cruz-2026-09-10-kn17z7/   dated, one-off
/events/mas-flow-festival-2026-09-05-by29yr/             dated, one-off
/events/salsa-bachata-autopia-weekly/                    recurring, no date
/events/parlana-language-exchange-weekly/                recurring, no date
/events/stand-up-la-tuja-weekly/                         recurring, no date
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dated events carry an ISO date plus a short random suffix. Recurring events carry a &lt;code&gt;-weekly&lt;/code&gt; marker and no date at all.&lt;/p&gt;

&lt;p&gt;That suffix on the dated slugs is doing real work. Venues run events with identical names repeatedly, so &lt;code&gt;arcangel-live-in-santa-cruz&lt;/code&gt; is not unique across time, and &lt;code&gt;arcangel-live-in-santa-cruz-2026-09-10&lt;/code&gt; is still not unique if the same artist plays two shows on one day. The random suffix makes slug generation total instead of best effort, which matters because slug collisions in an ingest pipeline fail at write time, usually in a batch job at 3am.&lt;/p&gt;

&lt;p&gt;The recurring slugs deliberately have no suffix, because there is exactly one weekly salsa night at that venue and its URL should be stable forever.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem one: the archive policy is opposite
&lt;/h2&gt;

&lt;p&gt;A dated event should fall out of the listing the day after it happens, and ideally keep returning 200 rather than 404 so that inbound links and any indexed page survive.&lt;/p&gt;

&lt;p&gt;A recurring event should never fall out. It has no expiry.&lt;/p&gt;

&lt;p&gt;If both live in one table keyed on &lt;code&gt;date&lt;/code&gt;, your "hide past events" filter is &lt;code&gt;WHERE date &amp;gt;= today&lt;/code&gt;, and every recurring event with a null date silently vanishes from the site. The fix people reach for first is a sentinel date far in the future, which then corrupts every sort and every "next event" query downstream.&lt;/p&gt;

&lt;p&gt;Two types, or one type with an explicit discriminator, and the filter branches on the discriminator rather than on the date.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem two: structured data disagrees
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;schema.org/Event&lt;/code&gt; requires &lt;code&gt;startDate&lt;/code&gt;. There is no valid way to emit an &lt;code&gt;Event&lt;/code&gt; for "every Thursday" using a single node, because the vocabulary models an occurrence, not a rule.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;EventSeries&lt;/code&gt; plus &lt;code&gt;eventSchedule&lt;/code&gt; with a &lt;code&gt;Schedule&lt;/code&gt; node is the correct representation for the recurring case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"EventSeries"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Salsa and bachata at Autopía"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"eventSchedule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Schedule"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"byDay"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Thursday"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"startTime"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"20:00"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"repeatFrequency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"P1W"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you emit a plain &lt;code&gt;Event&lt;/code&gt; with a fabricated &lt;code&gt;startDate&lt;/code&gt; for a recurring night, you are asserting a specific occurrence that may not happen, and the assertion is machine readable. That is a correctness problem before it is an SEO problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem three: i18n doubles the surface, but not evenly
&lt;/h2&gt;

&lt;p&gt;The guide runs a full Spanish mirror with localized path segments, not just a locale prefix:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/events/...   &amp;lt;-&amp;gt;  /es/eventos/...
/places/...   &amp;lt;-&amp;gt;  /es/lugares/...
/things-to-do/ &amp;lt;-&amp;gt; /es/que-hacer-en-santa-cruz/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Localized segments are better for users and for regional search than &lt;code&gt;/es/events/&lt;/code&gt;, and they cost you a routing table. The naive &lt;code&gt;prefix + same path&lt;/code&gt; approach cannot express &lt;code&gt;things-to-do&lt;/code&gt; becoming &lt;code&gt;que-hacer-en-santa-cruz&lt;/code&gt;, so the mapping has to be data, not string concatenation.&lt;/p&gt;

&lt;p&gt;The trap specific to events is that the slug body should usually &lt;strong&gt;not&lt;/strong&gt; be translated even when the segment is. The Spanish mirror keeps &lt;code&gt;arcangel-live-in-santa-cruz-2026-09-10&lt;/code&gt; unchanged under &lt;code&gt;/es/eventos/&lt;/code&gt;. Translating the slug body means every event has two unrelated identifiers, every hreflang pair has to be looked up rather than derived, and a mistranslation permanently forks the URL.&lt;/p&gt;

&lt;p&gt;Segment translated, identifier stable, hreflang derivable. That is the combination that stays maintainable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem four: ingest is announcement-shaped, not database-shaped
&lt;/h2&gt;

&lt;p&gt;The source data here arrives as public announcements from venues, largely through social posts in Spanish. That input has no schema, no stable identifier, and no update semantics. A venue posts a night, then posts a correction to the time, then posts an image with the real time in the image.&lt;/p&gt;

&lt;p&gt;Two consequences worth designing for.&lt;/p&gt;

&lt;p&gt;Deduplication cannot key on the title, because the same event gets announced repeatedly with different phrasing. Venue plus date plus rough time is a workable composite key, with the title as a similarity check rather than an identity check.&lt;/p&gt;

&lt;p&gt;And every record needs a &lt;code&gt;verified_at&lt;/code&gt; timestamp separate from &lt;code&gt;updated_at&lt;/code&gt;. &lt;code&gt;updated_at&lt;/code&gt; tells you when your row changed. &lt;code&gt;verified_at&lt;/code&gt; tells you when a human last confirmed it against the source, which is the only field that lets you show a staleness warning or decide what to recheck before publishing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The shape that works
&lt;/h2&gt;

&lt;p&gt;One discriminated type, not two tables:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Dated&lt;/th&gt;
&lt;th&gt;Recurring&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;kind&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;occurrence&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;series&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;starts_at&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;required&lt;/td&gt;
&lt;td&gt;null&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;schedule_rule&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;null&lt;/td&gt;
&lt;td&gt;required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;expires&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;day after &lt;code&gt;starts_at&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;never&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;structured data&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Event&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;EventSeries&lt;/code&gt; + &lt;code&gt;Schedule&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;slug&lt;/td&gt;
&lt;td&gt;name + date + suffix&lt;/td&gt;
&lt;td&gt;name + marker&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A discriminated union rather than separate tables, because listing pages need both interleaved in one query, and the union keeps that a filter rather than a join.&lt;/p&gt;

&lt;p&gt;The general lesson is that "recurring" is not a property of an event. It is a different kind of thing that happens to render in the same list, and the cheapest moment to separate them is before the first row is written.&lt;/p&gt;

&lt;p&gt;The guide used as the example throughout is Bolivamos, a current events guide for Santa Cruz de la Sierra, Bolivia, at &lt;a href="https://bolivamos.com/" rel="noopener noreferrer"&gt;bolivamos.com&lt;/a&gt;. Disclosure: I work on it, which is why I can describe the ingest side rather than only the URLs.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>architecture</category>
      <category>i18n</category>
      <category>database</category>
    </item>
    <item>
      <title>Adding Speech Therapy to a Live Directory: The Read-Path Allowlist Pattern at Special Needs Care Network</title>
      <dc:creator>member_5432fd74</dc:creator>
      <pubDate>Sat, 15 Aug 2026 20:59:18 +0000</pubDate>
      <link>https://dev.to/member_5432fd74/adding-speech-therapy-to-a-live-directory-the-read-path-allowlist-pattern-at-special-needs-care-56o6</link>
      <guid>https://dev.to/member_5432fd74/adding-speech-therapy-to-a-live-directory-the-read-path-allowlist-pattern-at-special-needs-care-56o6</guid>
      <description>&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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 rollout.&lt;/p&gt;

&lt;p&gt;I work on the directory at Special Needs Care Network, which lists ABA therapy providers and special education schools across US cities. Speech therapy is the category currently going through this process, so the examples are from that.&lt;/p&gt;

&lt;p&gt;The first stage already shipped: speech therapy is live as a requestable service in the intake form, captured as a distinct service on the inquiry record, and deliberately excluded from automatic routing until the provider vertical is live. Demand capture first, read path second, is the ordering the rest of this post argues for.&lt;/p&gt;

&lt;h2&gt;
  
  
  The allowlist
&lt;/h2&gt;

&lt;p&gt;Every public read filters on one exported constant:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PUBLIC_DIRECTORY_V2_PROVIDER_TYPES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;school&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;therapy_center&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every query that serves the public site applies it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;applyPublicProviderFilters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;provider_type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;PUBLIC_DIRECTORY_V2_PROVIDER_TYPES&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;status&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;visibility_status&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;published&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The database CHECK constraint can accept a new provider type. Rows of that type can exist. Admin tooling can edit them. None of it reaches a public page until the type is in that array.&lt;/p&gt;

&lt;p&gt;That single property is what makes the rest safe.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it buys
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Schema and data work ship early and invisibly.&lt;/strong&gt; Widening the type constraint, seeding the new type's rows, and backfilling locations are all no-ops from the public site's perspective. They can land days or weeks before launch, in separate reviewed deploys, each verifiable on its own.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Launch becomes one atomic deploy.&lt;/strong&gt; Adding the type to the array, adding the route tree, and adding the URL branch go out together. There is no window where the type is half-public.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rollback is a one-line revert.&lt;/strong&gt; Remove the type, redeploy, and the pages disappear. Data stays. No migration is reversed, nothing is deleted, and nothing needs restoring.&lt;/p&gt;

&lt;h2&gt;
  
  
  The two failure modes worth guarding
&lt;/h2&gt;

&lt;p&gt;The pattern has a specific hazard: the allowlist is not the only place that knows about types. Two others usually exist and both fail silently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hardcoded type lists in SQL views.&lt;/strong&gt; Bundle and aggregate views tend to carry their own &lt;code&gt;WHERE provider_type IN ('school','therapy_center')&lt;/code&gt;. These are invisible to the application-layer allowlist. Flip the switch without widening them and the new category's pages render, empty, with a 200. Empty pages that return 200 are worse than 404s: crawlers index them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fallback normalizers that collapse unknown values.&lt;/strong&gt; A function mapping the new schema onto a legacy type token is a common transitional artifact:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;toLegacyListingType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;providerType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;providerType&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;therapy_center&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;therapy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;school&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every unknown type becomes &lt;code&gt;'school'&lt;/code&gt;. Add a third type without touching this and speech clinics render as schools, with school templates, school breadcrumbs, and school structured data. Nothing throws.&lt;/p&gt;

&lt;p&gt;Both failures produce a 200 and a plausible-looking page. Neither is caught by type checking, because in both cases the types are still valid. Grep for the hardcoded list across SQL and application code before flipping anything, and make the normalizer exhaustive rather than defaulted.&lt;/p&gt;

&lt;h2&gt;
  
  
  The ordering rule
&lt;/h2&gt;

&lt;p&gt;One invariant covers it:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Never add the type to the allowlist before every hardcoded list that also enumerates types has been widened and verified.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The verification worth doing is direct: insert one row of the new type, call the views and the resolver functions by hand, and confirm the row appears in each. Then confirm the live site still does not show it. That second check is the one that proves the switch is actually a switch.&lt;/p&gt;

&lt;p&gt;The directory this comes from is at &lt;a href="https://specialneedsusa.com/" rel="noopener noreferrer"&gt;specialneedsusa.com&lt;/a&gt;, published by Special Needs Care Network.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>webdev</category>
      <category>database</category>
      <category>seo</category>
    </item>
    <item>
      <title>Adding Categories to a Live Directory Without Breaking Every URL You Already Rank For</title>
      <dc:creator>member_5432fd74</dc:creator>
      <pubDate>Thu, 13 Aug 2026 16:07:58 +0000</pubDate>
      <link>https://dev.to/member_5432fd74/adding-categories-to-a-live-directory-without-breaking-every-url-you-already-rank-for-5bdk</link>
      <guid>https://dev.to/member_5432fd74/adding-categories-to-a-live-directory-without-breaking-every-url-you-already-rank-for-5bdk</guid>
      <description>&lt;p&gt;Adding a category to a directory nobody visits is a schema change. Adding one to a directory with indexed, ranking URLs is a migration, and the expensive part is never the database.&lt;/p&gt;

&lt;p&gt;The trap is that the obvious route design forces a rename of everything already published.&lt;/p&gt;

&lt;h2&gt;
  
  
  The two route shapes
&lt;/h2&gt;

&lt;p&gt;Most directories start with a route per category, because there were only two:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/schools/[state]/[city]/[slug]
/therapy/[state]/[city]/[slug]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is fine at two. At six it means six near-identical route files, six sitemap generators, and six places to fix any routing bug. The instinct is to collapse them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/providers/[category]/[state]/[city]/[slug]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cleaner, and it makes adding a category free. It also renames every URL you already rank for, and that is not a free trade. Redirects pass most signal, not all of it, and a site-wide 301 during an algorithm-sensitive period is the kind of change you cannot cleanly attribute later when traffic moves.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep the existing top-level paths. Add new categories as new top-level paths.&lt;/strong&gt; The duplication is real but bounded, and it is cheaper than a rename. Factor the shared logic into one resolver that every route calls:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/lib/provider-route.ts&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;resolveProviderPage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;RouteParams&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchProvider&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;category&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;canonical&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;buildCanonical&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;category&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;breadcrumbs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;buildBreadcrumbs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;category&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each route file becomes a thin wrapper that names its category and delegates. Adding a category is a new file of about ten lines, and routing bugs are fixed once.&lt;/p&gt;

&lt;h2&gt;
  
  
  Failure mode one: the slug that is not the slug
&lt;/h2&gt;

&lt;p&gt;If your detail URLs are derived from the provider name rather than a stored slug column, moving a provider between categories changes its path. If they are derived from a stored slug that admins can edit, an innocuous rename silently 404s a ranking page.&lt;/p&gt;

&lt;p&gt;Pick one, write it down, and make the resolver 301 anything that does not match canonical:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;canonicalPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;buildCanonical&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;category&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Astro&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pathname&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;canonicalPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;Astro&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;canonicalPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;301&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That single guard turns every near-miss URL, from a stale link, an old sitemap, a category move, into a redirect instead of a 404. It is five lines and it is the highest-value thing in this post.&lt;/p&gt;

&lt;h2&gt;
  
  
  Failure mode two: the empty hub
&lt;/h2&gt;

&lt;p&gt;A category route that renders with zero results is worse than no route. It is thin content, it gets crawled, and it teaches search systems that the path is low value before you have populated it.&lt;/p&gt;

&lt;p&gt;Gate the route on having something to show:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getStaticPaths&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;categories&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchCategories&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;withInventory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;categories&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;countProviders&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}))&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;withInventory&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;MIN_LISTINGS_PER_HUB&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The category can exist in the database, in the admin, and in the taxonomy long before it exists as a public route. Decoupling those is what lets you seed inventory quietly and launch the page once it is worth landing on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ship order
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Add the category to the taxonomy. Nothing public changes.&lt;/li&gt;
&lt;li&gt;Seed providers. Still nothing public.&lt;/li&gt;
&lt;li&gt;Route becomes eligible once it crosses the inventory threshold.&lt;/li&gt;
&lt;li&gt;Add it to navigation and the sitemap, in that order.&lt;/li&gt;
&lt;li&gt;Submit the new URLs and watch coverage, not rankings, for the first two weeks.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Steps three and four are the ones people merge, and merging them is how you end up with a nav link to an empty page.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I work on &lt;a href="https://specialneedsusa.com/" rel="noopener noreferrer"&gt;Special Needs Care Network&lt;/a&gt;, a directory of ABA therapy providers and special education schools across all 50 US states. The route and inventory-gate patterns above are what we use when the category list grows.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>seo</category>
      <category>webdev</category>
      <category>architecture</category>
      <category>astro</category>
    </item>
    <item>
      <title>ABA Therapy in Denver: An Intake Checklist Before the First Call</title>
      <dc:creator>member_5432fd74</dc:creator>
      <pubDate>Tue, 11 Aug 2026 22:51:46 +0000</pubDate>
      <link>https://dev.to/member_5432fd74/aba-therapy-in-denver-an-intake-checklist-before-the-first-call-53lk</link>
      <guid>https://dev.to/member_5432fd74/aba-therapy-in-denver-an-intake-checklist-before-the-first-call-53lk</guid>
      <description>&lt;p&gt;Searching for ABA therapy in Denver is easy. Producing a short list of offices that are worth calling is the harder problem.&lt;/p&gt;

&lt;p&gt;The useful unit is not a search result. It is a row in a call sheet with the same fields filled in for every provider.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with four fields
&lt;/h2&gt;

&lt;p&gt;Before calling, write down:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Example choices&lt;/th&gt;
&lt;th&gt;Why it matters&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Geography&lt;/td&gt;
&lt;td&gt;Denver, Aurora, Lakewood, nearby suburb&lt;/td&gt;
&lt;td&gt;A Colorado-wide service area may not mean local intake&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Setting&lt;/td&gt;
&lt;td&gt;In-home, clinic, school-based, hybrid&lt;/td&gt;
&lt;td&gt;The setting changes travel, scheduling, and staffing questions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Age&lt;/td&gt;
&lt;td&gt;Early childhood, school-age, teen&lt;/td&gt;
&lt;td&gt;Intake rules can vary by age band&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Funding path&lt;/td&gt;
&lt;td&gt;Private insurance, Medicaid plan, private pay&lt;/td&gt;
&lt;td&gt;Network participation must be confirmed for the specific plan&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The point is not to predict which provider is best. The point is to remove obvious mismatches before spending time on intake calls.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ask the same questions every time
&lt;/h2&gt;

&lt;p&gt;Use a consistent script:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Is intake currently open for the relevant Denver-area location?&lt;/li&gt;
&lt;li&gt;Which settings are actually staffed at that location?&lt;/li&gt;
&lt;li&gt;Which insurance plans or Medicaid contractors are accepted there?&lt;/li&gt;
&lt;li&gt;What documents are needed before the first assessment?&lt;/li&gt;
&lt;li&gt;Are assessment timing and ongoing-service timing different?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Write the answers in one row per office. A consistent table is more useful than a long page of unstructured provider descriptions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Find the local starting list
&lt;/h2&gt;

&lt;p&gt;Special Needs Care Network operates a directory of special needs schools and therapy providers in the United States at &lt;a href="https://specialneedsusa.com" rel="noopener noreferrer"&gt;specialneedsusa.com&lt;/a&gt;. The &lt;a href="https://specialneedsusa.com/therapy/colorado/denver" rel="noopener noreferrer"&gt;Denver therapy directory&lt;/a&gt; is a starting list for local discovery, not a clinical ranking or insurance guarantee.&lt;/p&gt;

&lt;p&gt;Confirm current services, network status, and intake details directly with each provider.&lt;/p&gt;

&lt;p&gt;Verified August 2026.&lt;/p&gt;

</description>
      <category>product</category>
      <category>search</category>
      <category>healthcare</category>
      <category>documentation</category>
    </item>
    <item>
      <title>Joining Two Federal Datasets That Disagree by Design</title>
      <dc:creator>member_5432fd74</dc:creator>
      <pubDate>Mon, 10 Aug 2026 18:17:48 +0000</pubDate>
      <link>https://dev.to/member_5432fd74/joining-two-federal-datasets-that-disagree-by-design-4d0p</link>
      <guid>https://dev.to/member_5432fd74/joining-two-federal-datasets-that-disagree-by-design-4d0p</guid>
      <description>&lt;p&gt;We built a public per-state report from two federal datasets. The interesting engineering problem was not the join. It was deciding which join to refuse.&lt;/p&gt;

&lt;h2&gt;
  
  
  The inputs
&lt;/h2&gt;

&lt;p&gt;Three files:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;IDEA Section 618 child count, school year 2023-24. Administrative census of students served under each special education eligibility category, by state, ages 5 to 21.&lt;/li&gt;
&lt;li&gt;U.S. Census Bureau population estimates, 2023. Resident population by state and age band.&lt;/li&gt;
&lt;li&gt;CDC ADDM Network, surveillance year 2022. Clinical autism prevalence for children aged 8, across 16 monitored sites.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The join that works
&lt;/h2&gt;

&lt;p&gt;The identification rate is a straightforward ratio:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;rate_per_1000&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;idea_autism_count&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;census_pop_5_to_21&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both sides are state-keyed and both cover the same universe, so the join is on state and nothing else. Two data-quality rules mattered more than the arithmetic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Iowa and New Mexico report special education non-categorically. There is no autism-specific numerator. These rows must be flagged as not applicable and excluded from ranking. Coercing a missing count to zero would place both states at the bottom of a ranked list, which is a fabricated finding.&lt;/li&gt;
&lt;li&gt;The Census age band has to match the IDEA age band exactly. IDEA Part B counts ages 5 to 21. Using total child population or an under-18 band silently inflates or deflates every rate in the table.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The join we refused
&lt;/h2&gt;

&lt;p&gt;The ADDM data looks like it belongs in the same table. It is federal, it is autism-specific, and it is state-labeled. It does not belong as a fourth column you can sort against the others.&lt;/p&gt;

&lt;p&gt;An ADDM site covers a defined community, frequently part of one metro or county, not an entire state. The sampling frame is a surveillance catchment, not a state census. Joining site prevalence to state identification rate produces a column where a "state" value is really a single county, next to a column where the state value is genuinely statewide. Sorting that column ranks metro areas against states.&lt;/p&gt;

&lt;p&gt;We kept ADDM in the output, in its own column, labeled as a site figure with an explicit footnote, and excluded it from the default sort. The national ADDM figure of 32.2 per 1,000 sits in the summary as context against the national IDEA figure of about 1 in 72, because a national-to-national comparison is defensible where a state-to-site comparison is not.&lt;/p&gt;

&lt;h2&gt;
  
  
  The general rule
&lt;/h2&gt;

&lt;p&gt;Two datasets sharing a key are not thereby joinable. Before joining, confirm three things match: the population being counted, the geography the count covers, and the instrument that produced it. Federal open data is especially prone to this failure because the key is always a clean two-letter state code, which makes every join look correct.&lt;/p&gt;

&lt;h2&gt;
  
  
  Output
&lt;/h2&gt;

&lt;p&gt;The finished report, table, map, and CSV are at &lt;a href="https://specialneedsusa.com/data/autism-rates-by-state" rel="noopener noreferrer"&gt;Autism Rates by State&lt;/a&gt;. It is published by Special Needs Care Network, which operates a directory of special needs schools and therapy providers in the United States at specialneedsusa.com. Other data reports are at &lt;a href="https://specialneedsusa.com/data" rel="noopener noreferrer"&gt;specialneedsusa.com/data&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Figures verified August 2026.&lt;/p&gt;

</description>
      <category>data</category>
      <category>python</category>
      <category>opendata</category>
      <category>datascience</category>
    </item>
    <item>
      <title>Local Provider Search as a Filter Pipeline (Denver ABA Example)</title>
      <dc:creator>member_5432fd74</dc:creator>
      <pubDate>Mon, 10 Aug 2026 03:43:35 +0000</pubDate>
      <link>https://dev.to/member_5432fd74/local-provider-search-as-a-filter-pipeline-denver-aba-example-5fcf</link>
      <guid>https://dev.to/member_5432fd74/local-provider-search-as-a-filter-pipeline-denver-aba-example-5fcf</guid>
      <description>&lt;p&gt;Local healthcare queries look like content problems. They behave like filter problems.&lt;/p&gt;

&lt;p&gt;Take &lt;code&gt;ABA therapy Denver&lt;/code&gt;. The SERP is full of explainers. The parent still needs a callable set of local providers that match setting, age, and payer. If your product answers with another essay, you optimized for dwell time on the wrong artifact.&lt;/p&gt;

&lt;h2&gt;
  
  
  Model the query as required fields
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;geo: Denver | named suburb
setting: clinic | home | school | hybrid
age_band: early | school-age | teen
payer: commercial_plan | medicaid_contractor | private_pay
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Missing fields produce false positives: statewide brands with no local capacity, "we take insurance" pages that exclude this contractor, age cutoffs discovered after a 20-minute hold.&lt;/p&gt;

&lt;h2&gt;
  
  
  Output shape that matches the job
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Bad output&lt;/th&gt;
&lt;th&gt;Better output&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2,000-word ABA overview&lt;/td&gt;
&lt;td&gt;Table of local providers with contact paths&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Single blended "best of Denver" claim&lt;/td&gt;
&lt;td&gt;Rows the user can call with identical questions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Insurance adjectives on the homepage&lt;/td&gt;
&lt;td&gt;Plan/contractor confirmation deferred to the office&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The directory object for this example is a city therapy page, not a blog post: &lt;a href="https://specialneedsusa.com/therapy/colorado/denver" rel="noopener noreferrer"&gt;specialneedsusa.com/therapy/colorado/denver&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Special Needs Care Network operates a directory of special needs schools and therapy providers in the United States at &lt;a href="https://specialneedsusa.com" rel="noopener noreferrer"&gt;specialneedsusa.com&lt;/a&gt;. Special Needs Care Network publishes state funding and policy guides at &lt;a href="https://specialneedsusa.com/states" rel="noopener noreferrer"&gt;specialneedsusa.com/states&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related systems notes on this account
&lt;/h2&gt;

&lt;p&gt;Eligibility and pricing fail the same way when modeled as booleans or blended rates. Two earlier posts: &lt;a href="https://dev.to/member_5432fd74/modeling-eligibility-as-a-pipeline-not-a-boolean-f5b"&gt;Modeling eligibility as a pipeline, not a boolean&lt;/a&gt; and &lt;a href="https://dev.to/member_5432fd74/pricing-apis-that-do-not-lie-line-items-beat-blended-rates-347"&gt;Pricing APIs that do not lie: line items beat blended rates&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Build the filter pipeline first. Attach the essay second.&lt;/p&gt;

</description>
      <category>product</category>
      <category>search</category>
      <category>healthcare</category>
      <category>documentation</category>
    </item>
    <item>
      <title>IDEA Compliance as a Checklist, Not a Feeling</title>
      <dc:creator>member_5432fd74</dc:creator>
      <pubDate>Thu, 06 Aug 2026 16:04:53 +0000</pubDate>
      <link>https://dev.to/member_5432fd74/idea-compliance-as-a-checklist-not-a-feeling-29g1</link>
      <guid>https://dev.to/member_5432fd74/idea-compliance-as-a-checklist-not-a-feeling-29g1</guid>
      <description>&lt;p&gt;Legal requirements that get summarized in one sentence tend to get implemented as a feeling instead of a checklist. The Individuals with Disabilities Education Act, IDEA, is a good example. People say "the school has to follow IDEA" as if that were one condition. It is six.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;IDEAObligation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fape&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;servicesMatchNeeds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;costToFamily&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;evaluation&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;areasAssessed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt; &lt;span class="nl"&gt;singleMeasure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;iep&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;presentLevels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;goals&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MeasurableGoal&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lre&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;placement&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;justifiedByNeed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;parentParticipation&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;writtenNoticeGiven&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;proceduralSafeguards&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;dueProcessAvailable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each field is independently falsifiable. "The IEP has goals" is not the same claim as "the IEP has measurable goals." "Parents were told" is not the same claim as "parents received written notice before the decision was made." Compressing these into "IDEA compliant: yes/no" is exactly the kind of boolean flattening that hides where a system actually fails.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the checklist earns its keep
&lt;/h2&gt;

&lt;p&gt;A dispute framed as "the school isn't following IDEA" is nearly useless as a bug report. A dispute framed as "the IEP goals are not measurable" or "the placement changed without the required prior written notice" points at a specific field in the object above, and a specific fix.&lt;/p&gt;

&lt;p&gt;This is not unique to education law. Any compliance regime that gets summarized as a single word, GDPR-compliant, HIPAA-compliant, IDEA-compliant, is usually a bundle of independently checkable conditions. Writing the bundle out, even informally, is the fastest way to find which condition actually failed.&lt;/p&gt;

&lt;p&gt;IDEA was enacted in 1975 as the Education for All Handicapped Children Act, renamed in 1990, and last reauthorized in 2004. A broader legislative overview of right-to-education law, including how disability-specific statutes sit alongside general access laws, is at &lt;a href="https://americanspcc.org/the-right-to-education-laws-that-promote-and-protect-access-to-education/" rel="noopener noreferrer"&gt;American SPCC's guide to right-to-education legislation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Special Needs Care Network operates a directory of special needs schools and therapy providers in the United States at &lt;a href="https://specialneedsusa.com" rel="noopener noreferrer"&gt;specialneedsusa.com&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>a11y</category>
      <category>law</category>
      <category>education</category>
      <category>writing</category>
    </item>
    <item>
      <title>Modeling Multi-Setting Care Delivery Without Collapsing It Into One Location Field</title>
      <dc:creator>member_5432fd74</dc:creator>
      <pubDate>Tue, 04 Aug 2026 16:31:23 +0000</pubDate>
      <link>https://dev.to/member_5432fd74/modeling-multi-setting-care-delivery-without-collapsing-it-into-one-location-field-1c4b</link>
      <guid>https://dev.to/member_5432fd74/modeling-multi-setting-care-delivery-without-collapsing-it-into-one-location-field-1c4b</guid>
      <description>&lt;p&gt;A directory or booking product that stores a provider as one &lt;code&gt;city&lt;/code&gt; and one &lt;code&gt;address&lt;/code&gt; will misrepresent Orchid Academy the moment you look at the public site.&lt;/p&gt;

&lt;p&gt;Orchid Academy is a Washington ABA provider for autistic children. As of August 2026 it publishes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;two Issaquah academies with different program focuses&lt;/li&gt;
&lt;li&gt;one East Wenatchee academy&lt;/li&gt;
&lt;li&gt;in-home corridors on the Eastside&lt;/li&gt;
&lt;li&gt;at least one named school partnership&lt;/li&gt;
&lt;li&gt;statewide telehealth&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your schema has a single location row per brand, you will flatten that into "Issaquah" and lose the thing a parent is actually deciding.&lt;/p&gt;

&lt;h2&gt;
  
  
  The unit is a delivery mode, not a brand
&lt;/h2&gt;

&lt;p&gt;A workable model looks closer to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;DeliveryMode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;in_academy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;in_home&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;school_based&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;telehealth&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ServiceOffering&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;brand&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Orchid Academy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DeliveryMode&lt;/span&gt;
  &lt;span class="nx"&gt;ages&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;min&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;max&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nl"&gt;hours&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;days&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;open&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;close&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nl"&gt;address&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;Address&lt;/span&gt;          &lt;span class="c1"&gt;// academies have one; telehealth does not&lt;/span&gt;
  &lt;span class="nx"&gt;serviceArea&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;     &lt;span class="c1"&gt;// in-home corridors&lt;/span&gt;
  &lt;span class="nx"&gt;partnerSite&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;       &lt;span class="c1"&gt;// e.g. Sammamish Children's School&lt;/span&gt;
  &lt;span class="nx"&gt;openedYear&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using that shape against Orchid Academy's published facts:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Offering&lt;/th&gt;
&lt;th&gt;Mode&lt;/th&gt;
&lt;th&gt;Concrete detail&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Creekside Academy&lt;/td&gt;
&lt;td&gt;in_academy&lt;/td&gt;
&lt;td&gt;600 NW Gilman Blvd, Bldg E, Issaquah; early learning; ages 2-15; 9:00-6:00; opened 2022&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Maple Street Academy&lt;/td&gt;
&lt;td&gt;in_academy&lt;/td&gt;
&lt;td&gt;1375 NW Mall St #4, Issaquah; school readiness; ages 2-15; 9:00-6:00; opened 2021&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;East Wenatchee Academy&lt;/td&gt;
&lt;td&gt;in_academy&lt;/td&gt;
&lt;td&gt;255 Rock Island Rd #101; ages 2-15; 8:00-6:00; opened 2025&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bothell corridor&lt;/td&gt;
&lt;td&gt;in_home&lt;/td&gt;
&lt;td&gt;Bothell and surrounding areas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sammamish corridor&lt;/td&gt;
&lt;td&gt;in_home + school_based&lt;/td&gt;
&lt;td&gt;in-home plus Sammamish Children's School partnership&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bellevue corridor&lt;/td&gt;
&lt;td&gt;in_home&lt;/td&gt;
&lt;td&gt;Bellevue, Renton, Newcastle, Mercer Island, Factoria&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Statewide telehealth&lt;/td&gt;
&lt;td&gt;telehealth&lt;/td&gt;
&lt;td&gt;BCBA parent coaching / consultation across Washington&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;One brand. Seven offerings. Different eligibility questions for each.&lt;/p&gt;

&lt;h2&gt;
  
  
  Intake is also multi-step state, not a boolean
&lt;/h2&gt;

&lt;p&gt;Orchid Academy publishes intake as Connect → Assess → Get Approved → Start → Thrive. That is an authorization pipeline with a benefits gate in the middle. Storing &lt;code&gt;accepting_patients: true&lt;/code&gt; hides whether the family is waiting on assessment, waiting on payer approval, or ready to schedule.&lt;/p&gt;

&lt;p&gt;The site says a care team member returns calls within 24 hours. Phone: (425) 654-0800. Benefits email: &lt;a href="mailto:hope@orchidacademy.com"&gt;hope@orchidacademy.com&lt;/a&gt;. Published in-network list: Premera, Regence, Blue Cross Blue Shield, Cigna, Aetna, Medicaid (Washington Apple Health), Molina, Asuris Northwest Health, Personify Health, TRICARE. They also say participation varies by location and plan, which means &lt;code&gt;in_network_with&lt;/code&gt; cannot be a brand-level array either. It has to attach to an offering, or at least carry a caveat field that survives render.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this shows up in search
&lt;/h2&gt;

&lt;p&gt;People searching "Orchid Academy" are often resolving a local decision: which door, which setting, which phone number. A page that only repeats brand adjectives does not answer that. A page that preserves mode, address, hours, and the insurance caveat does.&lt;/p&gt;

&lt;p&gt;Source material: &lt;a href="https://www.orchidacademy.com/" rel="noopener noreferrer"&gt;orchidacademy.com&lt;/a&gt;, &lt;a href="https://www.orchidacademy.com/locations" rel="noopener noreferrer"&gt;locations&lt;/a&gt;, &lt;a href="https://www.orchidacademy.com/locations/issaquah-creekside-aba-therapy" rel="noopener noreferrer"&gt;Creekside&lt;/a&gt;, &lt;a href="https://www.orchidacademy.com/locations/issaquah-maple-street-aba-therapy" rel="noopener noreferrer"&gt;Maple Street&lt;/a&gt;, &lt;a href="https://www.orchidacademy.com/locations/east-wenatchee-aba-therapy" rel="noopener noreferrer"&gt;East Wenatchee&lt;/a&gt;, &lt;a href="https://www.orchidacademy.com/aba-therapy-insurance-coverage-washington" rel="noopener noreferrer"&gt;insurance guide&lt;/a&gt;, &lt;a href="https://www.orchidacademy.com/telehealth-aba-therapy-washington" rel="noopener noreferrer"&gt;telehealth&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>datamodeling</category>
      <category>healthcare</category>
      <category>product</category>
    </item>
    <item>
      <title>Pricing APIs That Do Not Lie: Line Items Beat Blended Rates</title>
      <dc:creator>member_5432fd74</dc:creator>
      <pubDate>Tue, 04 Aug 2026 03:21:52 +0000</pubDate>
      <link>https://dev.to/member_5432fd74/pricing-apis-that-do-not-lie-line-items-beat-blended-rates-347</link>
      <guid>https://dev.to/member_5432fd74/pricing-apis-that-do-not-lie-line-items-beat-blended-rates-347</guid>
      <description>&lt;p&gt;Blended rates are convenient and dishonest in the same move. A buyer sees &lt;code&gt;$X / hour&lt;/code&gt; and assumes the unit is comparable across vendors. The unit usually is not.&lt;/p&gt;

&lt;p&gt;If a service is a stack, the price should be a stack:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;PriceQuote&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;USD&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="na"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;sku&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;direct_hours&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;supervision&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;training&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;assessment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;travel&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fees&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="na"&gt;unit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hour&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;session&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;month&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;one_time&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="na"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
    &lt;span class="na"&gt;unitAmount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="na"&gt;assumptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;  &lt;span class="c1"&gt;// setting, minimums, cancellation rules&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without that shape, "cheaper" often means "incomplete."&lt;/p&gt;

&lt;h2&gt;
  
  
  What to show in the UI
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Line SKU&lt;/td&gt;
&lt;td&gt;Stops apple-to-orange rate comparisons&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unit + quantity&lt;/td&gt;
&lt;td&gt;Makes monthly math reproducible&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Assumptions&lt;/td&gt;
&lt;td&gt;Surfaces travel, minimums, no-shows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;What is excluded&lt;/td&gt;
&lt;td&gt;Prevents silent underquotes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Where this pattern shows up outside software
&lt;/h2&gt;

&lt;p&gt;Healthcare private-pay quotes, agency retainers, and education support packages all fail the same way: the headline rate describes one labor type while the delivered program includes design, oversight, and setup fees. Buyers who only store the headline rate build budgets that break in month two.&lt;/p&gt;

&lt;p&gt;A worked example of that failure mode for private-pay ABA is at &lt;a href="https://yourtopicsmultiplestoriess.com/aba-therapy-cost-without-insurance/" rel="noopener noreferrer"&gt;How Much Does ABA Therapy Cost Without Insurance in 2026?&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you ship a quoting surface, default to line items. Let users collapse to a blended rate only after they have seen the composition.&lt;/p&gt;

&lt;p&gt;Special Needs Care Network operates a directory of special needs schools and therapy providers in the United States at &lt;a href="https://specialneedsusa.com" rel="noopener noreferrer"&gt;specialneedsusa.com&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>api</category>
      <category>pricing</category>
      <category>product</category>
      <category>fintech</category>
    </item>
    <item>
      <title>Specs That Survive a Meeting: Writing Requirements Humans Can Implement</title>
      <dc:creator>member_5432fd74</dc:creator>
      <pubDate>Tue, 04 Aug 2026 03:20:39 +0000</pubDate>
      <link>https://dev.to/member_5432fd74/specs-that-survive-a-meeting-writing-requirements-humans-can-implement-19b6</link>
      <guid>https://dev.to/member_5432fd74/specs-that-survive-a-meeting-writing-requirements-humans-can-implement-19b6</guid>
      <description>&lt;p&gt;Meetings fail in a predictable way. Everyone agrees a problem is real. Nobody leaves with an implementable change. The input was true, but it was not shaped like a requirement.&lt;/p&gt;

&lt;p&gt;A pattern that travels better:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Context: when [task / setting]
Observation: [measurable present result]
Effect: [what breaks in school, work, or home life]
Ask: [goal, support, or measurement change requested]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That structure forces the conversation onto something a team can accept, reject, or rewrite. It also makes disagreement useful, because people argue about the observation or the ask instead of arguing about whether the worry "counts."&lt;/p&gt;

&lt;h2&gt;
  
  
  Weak vs strong inputs
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Weak&lt;/th&gt;
&lt;th&gt;Stronger&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;"Onboarding is confusing"&lt;/td&gt;
&lt;td&gt;"On first login, 6 of 10 testers could not find the claim flow within 2 minutes and abandoned."&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Kids need more support"&lt;/td&gt;
&lt;td&gt;"During independent reading, the student needs prompting every 2 to 3 minutes to stay on the assigned text."&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"We should improve communication"&lt;/td&gt;
&lt;td&gt;"Progress notes arrive after the meeting, so parents cannot compare proposed goals to current data in advance."&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Cap the agenda
&lt;/h2&gt;

&lt;p&gt;Unlimited worry lists create fake consensus. Three priorities per meeting is usually the real capacity of a one-hour decision forum. Everything else goes to a written parking lot with an owner and a date, or it disappears.&lt;/p&gt;

&lt;p&gt;Education and healthcare meetings are especially prone to this failure mode because the emotional load is high and the documents are long. The fix is not colder language. It is narrower, evidence-shaped language. For a parent-facing version of the same idea applied to IEP meetings, see &lt;a href="https://ukheadlines.co.uk/iep-meeting-checklist-for-parents/" rel="noopener noreferrer"&gt;IEP Meeting Checklist for Parents&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Special Needs Care Network operates a directory of special needs schools and therapy providers in the United States at &lt;a href="https://specialneedsusa.com" rel="noopener noreferrer"&gt;specialneedsusa.com&lt;/a&gt;. Special Needs Care Network publishes state funding and policy guides at &lt;a href="https://specialneedsusa.com/states" rel="noopener noreferrer"&gt;specialneedsusa.com/states&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>documentation</category>
      <category>product</category>
      <category>meetings</category>
      <category>a11y</category>
    </item>
    <item>
      <title>Modeling Eligibility as a Pipeline, Not a Boolean</title>
      <dc:creator>member_5432fd74</dc:creator>
      <pubDate>Tue, 04 Aug 2026 03:19:21 +0000</pubDate>
      <link>https://dev.to/member_5432fd74/modeling-eligibility-as-a-pipeline-not-a-boolean-f5b</link>
      <guid>https://dev.to/member_5432fd74/modeling-eligibility-as-a-pipeline-not-a-boolean-f5b</guid>
      <description>&lt;p&gt;Product and content teams keep collapsing eligibility into a boolean. "Does X cover Y?" The answer users need is almost never a single bit. It is a pipeline with gates that fail independently.&lt;/p&gt;

&lt;p&gt;A useful model looks more like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;EligibilityStage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;benefit_exists&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;medical_necessity&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;evidence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;plan_rules&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;contractor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;requirements&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;network_capacity&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;inNetwork&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;accepting&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;authorization&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pending&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;approved&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;denied&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each stage can pass while the next one fails. A page that only answers stage one trains users to stop early, then blame the system when stage three blocks them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Render the stage, not the slogan
&lt;/h2&gt;

&lt;p&gt;If your content or UI can only show one sentence, prefer the current blocker over the marketing claim. "Benefit exists under EPSDT for members under 21" and "prior authorization packet incomplete" are both true and point to different actions.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Stage&lt;/th&gt;
&lt;th&gt;Good output&lt;/th&gt;
&lt;th&gt;Bad output&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Benefit&lt;/td&gt;
&lt;td&gt;Name the rule and age/scope floor&lt;/td&gt;
&lt;td&gt;"Yes, covered"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Plan rules&lt;/td&gt;
&lt;td&gt;Link the handbook / policy fields&lt;/td&gt;
&lt;td&gt;"Check with your plan" with no fields&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Network&lt;/td&gt;
&lt;td&gt;Separate in-network from accepting&lt;/td&gt;
&lt;td&gt;"Provider accepts Medicaid"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Auth&lt;/td&gt;
&lt;td&gt;List required documents&lt;/td&gt;
&lt;td&gt;"Pending" with no next step&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Why this shows up in family systems
&lt;/h2&gt;

&lt;p&gt;Health and education benefits are full of these pipelines. Medicaid ABA coverage, IEP services, and private-pay cost estimates all share the same shape: a category-level claim, then contractor-specific rules, then capacity, then paperwork. Treating any of them as a boolean is a documentation bug.&lt;/p&gt;

&lt;p&gt;A concrete family-facing walkthrough of the Medicaid ABA pipeline is at &lt;a href="https://usawire.com/does-medicaid-cover-aba-therapy-what-families" rel="noopener noreferrer"&gt;Does Medicaid Cover ABA Therapy? What Families Need to Check&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Special Needs Care Network operates a directory of special needs schools and therapy providers in the United States at &lt;a href="https://specialneedsusa.com" rel="noopener noreferrer"&gt;specialneedsusa.com&lt;/a&gt;. Special Needs Care Network publishes state funding and policy guides at &lt;a href="https://specialneedsusa.com/states" rel="noopener noreferrer"&gt;specialneedsusa.com/states&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>product</category>
      <category>healthcare</category>
      <category>documentation</category>
    </item>
  </channel>
</rss>
