File size: 86,869 Bytes
3d16fe6
896453f
 
1f7780e
896453f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
fcf298e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
<!doctype html><html lang=en dir=ltr class="docs-wrapper plugin-docs plugin-id-default docs-version-current docs-doc-page docs-doc-id-development/react-refactoring" data-has-hydrated=false><head><meta charset=UTF-8><meta name=generator content="Docusaurus v3.10.0"><title data-rh=true>React + FastAPI Databricks App Refactoring | Open Navigator</title><meta data-rh=true name=viewport content="width=device-width, initial-scale=1.0"/><meta data-rh=true property=og:image content=https://www.communityone.com/img/docusaurus-social-card.jpg /><meta data-rh=true name=twitter:image content=https://www.communityone.com/img/docusaurus-social-card.jpg /><meta data-rh=true property=og:url content=https://www.communityone.com/docs/development/react-refactoring /><meta data-rh=true property=og:locale content=en /><meta data-rh=true name=docusaurus_locale content=en /><meta data-rh=true name=docsearch:language content=en /><meta data-rh=true name=keywords content="civic engagement, policy tracking, meeting minutes, nonprofit tracking, municipal government, advocacy, open data, local government"/><meta data-rh=true property=og:type content=website /><meta data-rh=true property=og:site_name content="Open Navigator"/><meta data-rh=true name=twitter:card content=summary_large_image /><meta data-rh=true name=docusaurus_version content=current /><meta data-rh=true name=docusaurus_tag content=docs-default-current /><meta data-rh=true name=docsearch:version content=current /><meta data-rh=true name=docsearch:docusaurus_tag content=docs-default-current /><meta data-rh=true property=og:title content="React + FastAPI Databricks App Refactoring | Open Navigator"/><meta data-rh=true name=description content="Executive Summary"/><meta data-rh=true property=og:description content="Executive Summary"/><link data-rh=true rel=icon href=/img/favicon.ico /><link data-rh=true rel=canonical href=https://www.communityone.com/docs/development/react-refactoring /><link data-rh=true rel=alternate href=https://www.communityone.com/docs/development/react-refactoring hreflang=en /><link data-rh=true rel=alternate href=https://www.communityone.com/docs/development/react-refactoring hreflang=x-default /><script data-rh=true type=application/ld+json>{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","item":"https://www.communityone.com/docs/for-developers","name":"Developers & Technical Users","position":1},{"@type":"ListItem","item":"https://www.communityone.com/docs/development/react-refactoring","name":"React + FastAPI Databricks App Refactoring","position":2}]}</script><link rel=alternate type=application/rss+xml href=/blog/rss.xml title="Open Navigator RSS Feed"><link rel=alternate type=application/atom+xml href=/blog/atom.xml title="Open Navigator Atom Feed"><link rel=preconnect href=https://www.google-analytics.com><link rel=preconnect href=https://www.googletagmanager.com><script async src="https://www.googletagmanager.com/gtag/js?id=G-5EQV815915"></script><script>function gtag(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],gtag("js",new Date),gtag("config","G-5EQV815915",{anonymize_ip:!0})</script><link rel=stylesheet href=/assets/css/styles.c89d6b2d.css /><script src=/assets/js/runtime~main.c8fa085e.js defer></script><script src=/assets/js/main.6e24e536.js defer></script></head><body><svg style="display: none;"><defs>
<symbol id=theme-svg-external-link viewBox="0 0 24 24"><path fill=currentColor d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"/></symbol>
</defs></svg>
<script>!function(){var t=function(){try{return new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(t){}}()||function(){try{return window.localStorage.getItem("theme-7e9")}catch(t){}}();document.documentElement.setAttribute("data-theme",t||(window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light")),document.documentElement.setAttribute("data-theme-choice",t||"system")}(),function(){try{for(var[t,e]of new URLSearchParams(window.location.search).entries())if(t.startsWith("docusaurus-data-")){var a=t.replace("docusaurus-data-","data-");document.documentElement.setAttribute(a,e)}}catch(t){}}()</script><div id=__docusaurus><link rel=preload as=image href=/img/communityone_logo.svg /><script type=application/ld+json>{"@context":"https://schema.org","@type":"Organization","address":{"@type":"PostalAddress","addressCountry":"US","addressLocality":"Tuscaloosa","addressRegion":"AL","postalCode":"35406","streetAddress":"5617 Lakeridge Court"},"contactPoint":{"@type":"ContactPoint","availableLanguage":["English"],"contactType":"Customer Service","email":"johnbowyer@communityone.com"},"description":"Track 90,000+ jurisdictions, 1.8M nonprofits, and analyze meeting minutes with AI. The open path to everything local.","email":"johnbowyer@communityone.com","legalName":"CommunityOne","logo":"https://www.communityone.com/img/communityone_logo.svg","name":"CommunityOne","sameAs":["https://www.facebook.com/communityone","https://www.instagram.com/communityone","https://twitter.com/communityone","https://www.linkedin.com/company/communityone","https://www.youtube.com/@communityone","https://discord.gg/communityone","https://github.com/getcommunityone/open-navigator"],"url":"https://www.communityone.com"}</script><script type=application/ld+json>{"@context":"https://schema.org","@type":"WebSite","alternateName":"CommunityOne Open Navigator","description":"AI-powered civic engagement platform tracking jurisdictions, nonprofits, and government meetings","name":"Open Navigator","potentialAction":{"@type":"SearchAction","query-input":"required name=search_term_string","target":{"@type":"EntryPoint","urlTemplate":"https://www.communityone.com/search?q={search_term_string}"}},"url":"https://www.communityone.com"}</script><script type=application/ld+json>{"@context":"https://schema.org","@type":"SoftwareApplication","aggregateRating":{"@type":"AggregateRating","ratingCount":"1","ratingValue":"5"},"applicationCategory":"BusinessApplication","description":"Track 90,000+ jurisdictions, 1.8M nonprofits, and analyze meeting minutes with AI","featureList":["Track 90,000+ jurisdictions","Monitor 1.8M nonprofits","Analyze meeting minutes","Legislative bill tracking","Campaign finance data"],"name":"Open Navigator","offers":{"@type":"Offer","price":"0","priceCurrency":"USD"},"operatingSystem":"Web","screenshot":"https://www.communityone.com/img/docusaurus-social-card.jpg","softwareVersion":"1.0.0"}</script><div role=region aria-label="Skip to main content"><a class=skipToContent_fXgn href=#__docusaurus_skipToContent_fallback>Skip to main content</a></div><nav aria-label=Main class="theme-layout-navbar navbar navbar--fixed-top"><div class=navbar__inner><div class="theme-layout-navbar-left navbar__items"><button aria-label="Toggle navigation bar" aria-expanded=false class="navbar__toggle clean-btn" type=button><svg width=30 height=30 viewBox="0 0 30 30" aria-hidden=true><path stroke=currentColor stroke-linecap=round stroke-miterlimit=10 stroke-width=2 d="M4 7h22M4 15h22M4 23h22"/></svg></button><a href=https://www.communityone.com target=_self rel="noopener noreferrer" class=navbar__brand><div class=navbar__logo><img src=/img/communityone_logo.svg alt="CommunityOne Logo" class="themedComponent_mlkZ themedComponent--light_NVdE"/><img src=/img/communityone_logo.svg alt="CommunityOne Logo" class="themedComponent_mlkZ themedComponent--dark_xIcU"/></div><b class="navbar__title text--truncate">Open Navigator Home</b></a><a class="navbar__item navbar__link" href=/docs/intro>Getting Started</a><a class="navbar__item navbar__link" href=/docs/for-families>Families & Individuals</a><a class="navbar__item navbar__link" href=/docs/for-advocates>Policy Makers</a><a class="navbar__item navbar__link" href=/docs/for-developers>Developers</a><a class="navbar__item navbar__link" href=/docs/data-sources/citations>Data and Terms</a><a class="navbar__item navbar__link" href=/blog>Blog</a></div><div class="theme-layout-navbar-right navbar__items navbar__items--right"><a href=https://github.com/getcommunityone/open-navigator-for-engagement target=_blank rel="noopener noreferrer" class="navbar__item navbar__link">GitHub<svg width=13.5 height=13.5 aria-label="(opens in new tab)" class=iconExternalLink_nPIU><use href=#theme-svg-external-link /></svg></a><div class="toggle_vylO colorModeToggle_DEke"><button class="clean-btn toggleButton_gllP toggleButtonDisabled_aARS" type=button disabled title="system mode" aria-label="Switch between dark and light mode (currently system mode)"><svg viewBox="0 0 24 24" width=24 height=24 aria-hidden=true class="toggleIcon_g3eP lightToggleIcon_pyhR"><path fill=currentColor d="M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"/></svg><svg viewBox="0 0 24 24" width=24 height=24 aria-hidden=true class="toggleIcon_g3eP darkToggleIcon_wfgR"><path fill=currentColor d="M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"/></svg><svg viewBox="0 0 24 24" width=24 height=24 aria-hidden=true class="toggleIcon_g3eP systemToggleIcon_QzmC"><path fill=currentColor d="m12 21c4.971 0 9-4.029 9-9s-4.029-9-9-9-9 4.029-9 9 4.029 9 9 9zm4.95-13.95c1.313 1.313 2.05 3.093 2.05 4.95s-0.738 3.637-2.05 4.95c-1.313 1.313-3.093 2.05-4.95 2.05v-14c1.857 0 3.637 0.737 4.95 2.05z"/></svg></button></div><div class=navbarSearchContainer_Bca1></div></div></div><div role=presentation class=navbar-sidebar__backdrop></div></nav><div id=__docusaurus_skipToContent_fallback class="theme-layout-main main-wrapper mainWrapper_z2l0"><div class=docsWrapper_hBAB><button aria-label="Scroll back to top" class="clean-btn theme-back-to-top-button backToTopButton_sjWU" type=button></button><div class=docRoot_UBD9><aside class="theme-doc-sidebar-container docSidebarContainer_YfHR"><div class=sidebarViewport_aRkj><div class=sidebar_njMd><nav aria-label="Docs sidebar" class="menu thin-scrollbar menu_SIkG"><ul class="theme-doc-sidebar-menu menu__list"><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item"><div class=menu__list-item-collapsible><a class="categoryLink_byQd menu__link menu__link--sublist menu__link--sublist-caret" role=button aria-expanded=true href=/docs/intro><span title="Getting Started" class=categoryLinkLabel_W154>Getting Started</span></a></div><ul class=menu__list><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class=menu__link tabindex=0 href=/docs/intro><span title=Introduction class=linkLabel_WmDU>Introduction</span></a><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class=menu__link tabindex=0 href=/docs/open-navigator><span title="Open Navigator" class=linkLabel_WmDU>Open Navigator</span></a></ul><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item"><div class=menu__list-item-collapsible><a class="categoryLink_byQd menu__link menu__link--sublist" href=/docs/for-families><span title="Families & Individuals" class=categoryLinkLabel_W154>Families & Individuals</span></a><button aria-label="Collapse sidebar category 'Families & Individuals'" aria-expanded=true type=button class="clean-btn menu__caret"></button></div><ul class=menu__list><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-2 menu__list-item menu__list-item--collapsed"><div class=menu__list-item-collapsible><a class="categoryLink_byQd menu__link menu__link--sublist menu__link--sublist-caret" role=button aria-expanded=false tabindex=0 href=/docs/families/community-events><span title="Resources for Families" class=categoryLinkLabel_W154>Resources for Families</span></a></div><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class=menu__link tabindex=0 href=/docs/open-navigator><span title="Getting Started with Open Navigator" class=linkLabel_WmDU>Getting Started with Open Navigator</span></a><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class=menu__link tabindex=0 href=/docs/data-sources/citations><span title="Data and Citations" class=linkLabel_WmDU>Data and Citations</span></a></ul><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item"><div class=menu__list-item-collapsible><a class="categoryLink_byQd menu__link menu__link--sublist" href=/docs/for-advocates><span title="Policy Makers & Advocates" class=categoryLinkLabel_W154>Policy Makers & Advocates</span></a><button aria-label="Collapse sidebar category 'Policy Makers & Advocates'" aria-expanded=true type=button class="clean-btn menu__caret"></button></div><ul class=menu__list><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-2 menu__list-item menu__list-item--collapsed"><div class=menu__list-item-collapsible><a class="categoryLink_byQd menu__link menu__link--sublist menu__link--sublist-caret" role=button aria-expanded=false tabindex=0 href=/docs/data-sources/overview><span title="Understanding the Data" class=categoryLinkLabel_W154>Understanding the Data</span></a></div><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-2 menu__list-item menu__list-item--collapsed"><div class=menu__list-item-collapsible><a class="categoryLink_byQd menu__link menu__link--sublist menu__link--sublist-caret" role=button aria-expanded=false tabindex=0 href=/docs/guides/political-economy><span title="Analysis & Strategy" class=categoryLinkLabel_W154>Analysis & Strategy</span></a></div><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-2 menu__list-item menu__list-item--collapsed"><div class=menu__list-item-collapsible><a class="categoryLink_byQd menu__link menu__link--sublist menu__link--sublist-caret" role=button aria-expanded=false tabindex=0 href=/docs/case-studies/tuscaloosa-complete><span title="Real-World Examples" class=categoryLinkLabel_W154>Real-World Examples</span></a></div></ul><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item"><div class=menu__list-item-collapsible><a class="categoryLink_byQd menu__link menu__link--sublist menu__link--active" href=/docs/for-developers><span title="Developers & Technical Users" class=categoryLinkLabel_W154>Developers & Technical Users</span></a><button aria-label="Collapse sidebar category 'Developers & Technical Users'" aria-expanded=true type=button class="clean-btn menu__caret"></button></div><ul class=menu__list><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-2 menu__list-item menu__list-item--collapsed"><div class=menu__list-item-collapsible><a class="categoryLink_byQd menu__link menu__link--sublist menu__link--sublist-caret" role=button aria-expanded=false tabindex=0 href=/docs/quickstart><span title="Setup & Installation" class=categoryLinkLabel_W154>Setup & Installation</span></a></div><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-2 menu__list-item menu__list-item--collapsed"><div class=menu__list-item-collapsible><a class="categoryLink_byQd menu__link menu__link--sublist menu__link--sublist-caret" role=button aria-expanded=false tabindex=0 href=/docs/data-sources/citations><span title="Data Sources (Technical)" class=categoryLinkLabel_W154>Data Sources (Technical)</span></a></div><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-2 menu__list-item menu__list-item--collapsed"><div class=menu__list-item-collapsible><a class="categoryLink_byQd menu__link menu__link--sublist menu__link--sublist-caret" role=button aria-expanded=false tabindex=0 href=/docs/guides/jurisdiction-setup><span title="How-To Guides" class=categoryLinkLabel_W154>How-To Guides</span></a></div><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-2 menu__list-item menu__list-item--collapsed"><div class=menu__list-item-collapsible><a class="categoryLink_byQd menu__link menu__link--sublist menu__link--sublist-caret" role=button aria-expanded=false tabindex=0 href=/docs/integrations/mcp-server><span title=Integrations class=categoryLinkLabel_W154>Integrations</span></a></div><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-2 menu__list-item menu__list-item--collapsed"><div class=menu__list-item-collapsible><a class="categoryLink_byQd menu__link menu__link--sublist menu__link--sublist-caret" role=button aria-expanded=false tabindex=0 href=/docs/deployment/databricks-apps><span title=Deployment class=categoryLinkLabel_W154>Deployment</span></a></div><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-2 menu__list-item"><div class=menu__list-item-collapsible><a class="categoryLink_byQd menu__link menu__link--sublist menu__link--sublist-caret menu__link--active" role=button aria-expanded=true tabindex=0 href=/docs/development/database-setup><span title=Development class=categoryLinkLabel_W154>Development</span></a></div><ul class=menu__list><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class=menu__link tabindex=0 href=/docs/development/database-setup><span title="Database Setup & Stats Verification" class=linkLabel_WmDU>Database Setup & Stats Verification</span></a><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class=menu__link tabindex=0 href=/docs/development/events-naming-migration><span title="File Migration to Events Naming Convention" class=linkLabel_WmDU>File Migration to Events Naming Convention</span></a><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class=menu__link tabindex=0 href=/docs/development/adding-data-sources><span title="Adding New Data Sources" class=linkLabel_WmDU>Adding New Data Sources</span></a><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class=menu__link tabindex=0 href=/docs/development/api-logging-errors><span title="API Logging & Error Handling Implementation" class=linkLabel_WmDU>API Logging & Error Handling Implementation</span></a><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class=menu__link tabindex=0 href=/docs/development/openstates-integration><span title="OpenStates Integration & Contribution Opportunities" class=linkLabel_WmDU>OpenStates Integration & Contribution Opportunities</span></a><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class=menu__link tabindex=0 href=/docs/development/real-time-statistics><span title="Real-Time Statistics with Geographic Filtering" class=linkLabel_WmDU>Real-Time Statistics with Geographic Filtering</span></a><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class=menu__link tabindex=0 href=/docs/development/schema-migration-summary><span title="Schema Migration Summary" class=linkLabel_WmDU>Schema Migration Summary</span></a><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class=menu__link tabindex=0 href=/docs/development/terminal-corruption-prevention><span title="Terminal Corruption Prevention" class=linkLabel_WmDU>Terminal Corruption Prevention</span></a><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class=menu__link tabindex=0 href=/docs/development/county-data-status><span title="County Search and Aggregation - Status Summary" class=linkLabel_WmDU>County Search and Aggregation - Status Summary</span></a><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class=menu__link tabindex=0 href=/docs/development/intel-optimization><span title="DuckDB + Intel Arc Optimization" class=linkLabel_WmDU>DuckDB + Intel Arc Optimization</span></a><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class=menu__link tabindex=0 href=/docs/development/dashboard-redesign><span title="React Dashboard Redesign Summary" class=linkLabel_WmDU>React Dashboard Redesign Summary</span></a><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class=menu__link tabindex=0 href=/docs/development/docs-migration><span title="Documentation Migration Summary" class=linkLabel_WmDU>Documentation Migration Summary</span></a><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class=menu__link tabindex=0 href=/docs/development/port-guide><span title="🚨 CRITICAL: Which Port to Use?" class=linkLabel_WmDU>🚨 CRITICAL: Which Port to Use?</span></a><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class="menu__link menu__link--active" aria-current=page tabindex=0 href=/docs/development/react-refactoring><span title="React + FastAPI Databricks App Refactoring" class=linkLabel_WmDU>React + FastAPI Databricks App Refactoring</span></a><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class=menu__link tabindex=0 href=/docs/development/readme-migration><span title="README Migration Summary" class=linkLabel_WmDU>README Migration Summary</span></a><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class=menu__link tabindex=0 href=/docs/development/refactoring-summary><span title="✨ React + FastAPI Databricks App - Complete Refactoring Summary" class=linkLabel_WmDU>✨ React + FastAPI Databricks App - Complete Refactoring Summary</span></a><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class=menu__link tabindex=0 href=/docs/development/changelog><span title="Changelog - Jurisdiction Discovery System" class=linkLabel_WmDU>Changelog - Jurisdiction Discovery System</span></a><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class=menu__link tabindex=0 href=/docs/development/enhancements><span title="✅ Enhancement Complete: Official Data Sources Integration" class=linkLabel_WmDU>✅ Enhancement Complete: Official Data Sources Integration</span></a><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class=menu__link tabindex=0 href=/docs/development/integration-status><span title="✅ Integration Status Summary" class=linkLabel_WmDU>✅ Integration Status Summary</span></a><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class=menu__link tabindex=0 href=/docs/development/migration-v2><span title="✅ Migration Complete: Pattern-Based Discovery v2.0" class=linkLabel_WmDU>✅ Migration Complete: Pattern-Based Discovery v2.0</span></a><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class=menu__link tabindex=0 href=/docs/development/new-capabilities><span title="🎉 NEW CAPABILITIES SUMMARY" class=linkLabel_WmDU>🎉 NEW CAPABILITIES SUMMARY</span></a></ul></ul></ul></nav></div></div></aside><main class=docMainContainer_TBSr><div class="container padding-top--md padding-bottom--lg"><div class=row><div class="col docItemCol_VOVn"><div class=docItemContainer_Djhp><article><nav class="theme-doc-breadcrumbs breadcrumbsContainer_Z_bl" aria-label=Breadcrumbs><ul class=breadcrumbs><li class=breadcrumbs__item><a aria-label="Home page" class=breadcrumbs__link href=/><svg viewBox="0 0 24 24" class=breadcrumbHomeIcon_YNFT><path d="M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z" fill=currentColor /></svg></a><li class=breadcrumbs__item><a class=breadcrumbs__link href=/docs/for-developers><span>Developers & Technical Users</span></a><li class=breadcrumbs__item><span class=breadcrumbs__link>Development</span><li class="breadcrumbs__item breadcrumbs__item--active"><span class=breadcrumbs__link>React + FastAPI Databricks App Refactoring</span></ul></nav><div class="tocCollapsible_ETCw theme-doc-toc-mobile tocMobile_ITEo"><button type=button class="clean-btn tocCollapsibleButton_TO0P">On this page</button></div><div class="theme-doc-markdown markdown"><header><h1>React + FastAPI Databricks App Refactoring</h1></header>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id=executive-summary>Executive Summary<a href=#executive-summary class=hash-link aria-label="Direct link to Executive Summary" title="Direct link to Executive Summary" translate=no></a></h2>
<p>The Oral Health Policy Pulse has been <strong>completely refactored</strong> from a CLI-based multi-agent system into a <strong>modern full-stack web application</strong> that deploys as a <strong>Databricks App</strong>.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id=what-changed>What Changed<a href=#what-changed class=hash-link aria-label="Direct link to What Changed" title="Direct link to What Changed" translate=no></a></h3>
<table><thead><tr><th>Before (v1.0)<th>After (v2.0)<tbody><tr><td>❌ CLI-only interface<td>✅ Modern React web UI<tr><td>❌ Manual command execution<td>✅ Interactive dashboard<tr><td>❌ Text-based outputs<td>✅ Visual charts & maps<tr><td>❌ Local deployment only<td>✅ Cloud-native Databricks Apps<tr><td>❌ Static HTML heatmap<td>✅ Interactive Leaflet map<tr><td>❌ No user settings<td>✅ Configurable UI settings</table>
<hr/>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id=new-architecture>New Architecture<a href=#new-architecture class=hash-link aria-label="Direct link to New Architecture" title="Direct link to New Architecture" translate=no></a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id=frontend-react--typescript>Frontend (React + TypeScript)<a href=#frontend-react--typescript class=hash-link aria-label="Direct link to Frontend (React + TypeScript)" title="Direct link to Frontend (React + TypeScript)" translate=no></a></h3>
<p><strong>Technology Stack:</strong></p>
<ul>
<li class="">React 18.2 with TypeScript</li>
<li class="">Vite for build tooling</li>
<li class="">Tailwind CSS for styling</li>
<li class="">React Router for navigation</li>
<li class="">TanStack Query for data fetching</li>
<li class="">Recharts for data visualization</li>
<li class="">Leaflet for interactive maps</li>
</ul>
<p><strong>Pages Created:</strong></p>
<ol>
<li class="">
<p><strong>Dashboard</strong> (<code>frontend/src/pages/Dashboard.tsx</code>)</p>
<ul>
<li class="">Real-time statistics cards</li>
<li class="">Topic distribution bar/pie charts</li>
<li class="">Recent opportunities table</li>
</ul>
</li>
<li class="">
<p><strong>Interactive Heatmap</strong> (<code>frontend/src/pages/Heatmap.tsx</code>)</p>
<ul>
<li class="">Geographic visualization using Leaflet</li>
<li class="">State and topic filters</li>
<li class="">Color-coded urgency markers</li>
<li class="">Popup details for each opportunity</li>
</ul>
</li>
<li class="">
<p><strong>Documents Browser</strong> (<code>frontend/src/pages/Documents.tsx</code>)</p>
<ul>
<li class="">Full-text search</li>
<li class="">Pagination</li>
<li class="">Topic tags</li>
<li class="">Direct links to source documents</li>
</ul>
</li>
<li class="">
<p><strong>Opportunities Manager</strong> (<code>frontend/src/pages/Opportunities.tsx</code>)</p>
<ul>
<li class="">Filterable list view</li>
<li class="">Urgency-based sorting</li>
<li class="">One-click email generation</li>
<li class="">Talking points display</li>
<li class="">Confidence score visualization</li>
</ul>
</li>
<li class="">
<p><strong>Settings Panel</strong> (<code>frontend/src/pages/Settings.tsx</code>)</p>
<ul>
<li class="">Target state configuration</li>
<li class="">Policy topic selection</li>
<li class="">Confidence threshold slider</li>
<li class="">Email notification preferences</li>
<li class="">Agent status monitoring</li>
</ul>
</li>
</ol>
<p><strong>Components:</strong></p>
<ul>
<li class=""><strong>Layout</strong> (<code>frontend/src/components/Layout.tsx</code>)<!-- -->
<ul>
<li class="">Sidebar navigation</li>
<li class="">Header with breadcrumbs</li>
<li class="">Responsive design</li>
</ul>
</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id=backend-fastapi-refactored>Backend (FastAPI Refactored)<a href=#backend-fastapi-refactored class=hash-link aria-label="Direct link to Backend (FastAPI Refactored)" title="Direct link to Backend (FastAPI Refactored)" translate=no></a></h3>
<p><strong>New File: <code>api/app.py</code></strong></p>
<p>Completely rewritten FastAPI application optimized for:</p>
<ul>
<li class="">✅ Serving React static files (SPA routing)</li>
<li class="">✅ REST API endpoints for all frontend interactions</li>
<li class="">✅ Databricks Apps compatibility</li>
<li class="">✅ Delta Lake integration</li>
<li class="">✅ Background task processing</li>
<li class="">✅ CORS support for local development</li>
</ul>
<p><strong>Key Endpoints:</strong></p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-text codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token plain">GET  /api/health                    # Health check</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">GET  /api/dashboard                 # Dashboard stats</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">GET  /api/opportunities             # List opportunities</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">GET  /api/documents                 # Browse documents</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">POST /api/workflow/start            # Start analysis</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">POST /api/advocacy/email/{id}       # Generate email</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">GET  /api/settings                  # Get settings</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">PUT  /api/settings                  # Update settings</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">GET  /api/agents/status             # Agent status</span><br/></div></code></pre></div></div>
<p><strong>Static File Serving:</strong></p>
<ul>
<li class="">React build output served from <code>api/static/</code></li>
<li class="">SPA routing with catchall route</li>
<li class="">Automatic index.html fallback</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id=database-layer>Database Layer<a href=#database-layer class=hash-link aria-label="Direct link to Database Layer" title="Direct link to Database Layer" translate=no></a></h3>
<p><strong>New File: <code>pipeline/delta_lake_queries.py</code></strong></p>
<p>Added async query methods to support web app:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-python codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token keyword" style=color:#00009f>async</span><span class="token plain"> </span><span class="token keyword" style=color:#00009f>def</span><span class="token plain"> </span><span class="token function" style=color:#d73a49>get_dashboard_stats</span><span class="token punctuation" style=color:#393A34>(</span><span class="token punctuation" style=color:#393A34>)</span><span class="token plain">       </span><span class="token comment" style=color:#999988;font-style:italic># Dashboard statistics</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token keyword" style=color:#00009f>async</span><span class="token plain"> </span><span class="token keyword" style=color:#00009f>def</span><span class="token plain"> </span><span class="token function" style=color:#d73a49>query_opportunities</span><span class="token punctuation" style=color:#393A34>(</span><span class="token punctuation" style=color:#393A34>)</span><span class="token plain">       </span><span class="token comment" style=color:#999988;font-style:italic># Filtered opportunity queries</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token keyword" style=color:#00009f>async</span><span class="token plain"> </span><span class="token keyword" style=color:#00009f>def</span><span class="token plain"> </span><span class="token function" style=color:#d73a49>query_documents</span><span class="token punctuation" style=color:#393A34>(</span><span class="token punctuation" style=color:#393A34>)</span><span class="token plain">           </span><span class="token comment" style=color:#999988;font-style:italic># Document search/pagination</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token keyword" style=color:#00009f>async</span><span class="token plain"> </span><span class="token keyword" style=color:#00009f>def</span><span class="token plain"> </span><span class="token function" style=color:#d73a49>count_documents</span><span class="token punctuation" style=color:#393A34>(</span><span class="token punctuation" style=color:#393A34>)</span><span class="token plain">           </span><span class="token comment" style=color:#999988;font-style:italic># Total count for pagination</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token keyword" style=color:#00009f>async</span><span class="token plain"> </span><span class="token keyword" style=color:#00009f>def</span><span class="token plain"> </span><span class="token function" style=color:#d73a49>get_opportunity</span><span class="token punctuation" style=color:#393A34>(</span><span class="token punctuation" style=color:#393A34>)</span><span class="token plain">           </span><span class="token comment" style=color:#999988;font-style:italic># Single opportunity details</span><br/></div></code></pre></div></div>
<hr/>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id=databricks-apps-integration>Databricks Apps Integration<a href=#databricks-apps-integration class=hash-link aria-label="Direct link to Databricks Apps Integration" title="Direct link to Databricks Apps Integration" translate=no></a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id=configuration-files>Configuration Files<a href=#configuration-files class=hash-link aria-label="Direct link to Configuration Files" title="Direct link to Configuration Files" translate=no></a></h3>
<p><strong>1. app.yaml</strong> (Databricks Apps manifest)</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token key atrule" style=color:#00a4db>command</span><span class="token punctuation" style=color:#393A34>:</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain">  </span><span class="token punctuation" style=color:#393A34>-</span><span class="token plain"> </span><span class="token string" style=color:#e3116c>"uvicorn"</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain">  </span><span class="token punctuation" style=color:#393A34>-</span><span class="token plain"> </span><span class="token string" style=color:#e3116c>"api.app:app"</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain">  </span><span class="token punctuation" style=color:#393A34>-</span><span class="token plain"> </span><span class="token string" style=color:#e3116c>"--host"</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain">  </span><span class="token punctuation" style=color:#393A34>-</span><span class="token plain"> </span><span class="token string" style=color:#e3116c>"0.0.0.0"</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain">  </span><span class="token punctuation" style=color:#393A34>-</span><span class="token plain"> </span><span class="token string" style=color:#e3116c>"--port"</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain">  </span><span class="token punctuation" style=color:#393A34>-</span><span class="token plain"> </span><span class="token string" style=color:#e3116c>"8000"</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token key atrule" style=color:#00a4db>env</span><span class="token punctuation" style=color:#393A34>:</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain">  </span><span class="token punctuation" style=color:#393A34>-</span><span class="token plain"> </span><span class="token key atrule" style=color:#00a4db>name</span><span class="token punctuation" style=color:#393A34>:</span><span class="token plain"> DATABRICKS_HOST</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">    </span><span class="token key atrule" style=color:#00a4db>valueFrom</span><span class="token punctuation" style=color:#393A34>:</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain">      </span><span class="token key atrule" style=color:#00a4db>databricksSecret</span><span class="token punctuation" style=color:#393A34>:</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain">        </span><span class="token key atrule" style=color:#00a4db>key</span><span class="token punctuation" style=color:#393A34>:</span><span class="token plain"> host</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">        </span><span class="token key atrule" style=color:#00a4db>scope</span><span class="token punctuation" style=color:#393A34>:</span><span class="token plain"> oral</span><span class="token punctuation" style=color:#393A34>-</span><span class="token plain">health</span><span class="token punctuation" style=color:#393A34>-</span><span class="token plain">app</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">  </span><span class="token punctuation" style=color:#393A34>-</span><span class="token plain"> </span><span class="token key atrule" style=color:#00a4db>name</span><span class="token punctuation" style=color:#393A34>:</span><span class="token plain"> OPENAI_API_KEY</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">    </span><span class="token key atrule" style=color:#00a4db>valueFrom</span><span class="token punctuation" style=color:#393A34>:</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain">      </span><span class="token key atrule" style=color:#00a4db>databricksSecret</span><span class="token punctuation" style=color:#393A34>:</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain">        </span><span class="token key atrule" style=color:#00a4db>key</span><span class="token punctuation" style=color:#393A34>:</span><span class="token plain"> openai_key</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">        </span><span class="token key atrule" style=color:#00a4db>scope</span><span class="token punctuation" style=color:#393A34>:</span><span class="token plain"> oral</span><span class="token punctuation" style=color:#393A34>-</span><span class="token plain">health</span><span class="token punctuation" style=color:#393A34>-</span><span class="token plain">app</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token key atrule" style=color:#00a4db>resources</span><span class="token punctuation" style=color:#393A34>:</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain">  </span><span class="token punctuation" style=color:#393A34>-</span><span class="token plain"> </span><span class="token key atrule" style=color:#00a4db>name</span><span class="token punctuation" style=color:#393A34>:</span><span class="token plain"> policy</span><span class="token punctuation" style=color:#393A34>-</span><span class="token plain">classifier</span><span class="token punctuation" style=color:#393A34>-</span><span class="token plain">endpoint</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">    </span><span class="token key atrule" style=color:#00a4db>modelServing</span><span class="token punctuation" style=color:#393A34>:</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain">      </span><span class="token key atrule" style=color:#00a4db>endpoint</span><span class="token punctuation" style=color:#393A34>:</span><span class="token plain"> policy</span><span class="token punctuation" style=color:#393A34>-</span><span class="token plain">classifier</span><span class="token punctuation" style=color:#393A34>-</span><span class="token plain">prod</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token key atrule" style=color:#00a4db>port</span><span class="token punctuation" style=color:#393A34>:</span><span class="token plain"> </span><span class="token number" style=color:#36acaa>8000</span><br/></div></code></pre></div></div>
<p><strong>2. Dockerfile.app</strong> (Container image for Databricks Apps)</p>
<ul>
<li class="">Multi-stage build</li>
<li class="">Node.js for frontend build</li>
<li class="">Python 3.11 for backend</li>
<li class="">Optimized for CPU-only deployment</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id=deployment-scripts>Deployment Scripts<a href=#deployment-scripts class=hash-link aria-label="Direct link to Deployment Scripts" title="Direct link to Deployment Scripts" translate=no></a></h3>
<p><strong>1. scripts/deploy-databricks-app.sh</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token plain"># Automated deployment script:</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"># 1. Build React frontend</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"># 2. Create Databricks secrets</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"># 3. Deploy to Databricks Apps</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"># 4. Provide access URL</span><br/></div></code></pre></div></div>
<p><strong>2. scripts/setup-local.sh</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token plain"># Local development setup:</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"># - Install Python deps</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"># - Install npm packages</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"># - Create .env file</span><br/></div></code></pre></div></div>
<p><strong>3. scripts/test-app.py</strong></p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-python codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token comment" style=color:#999988;font-style:italic># Test production build locally</span><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><span class="token comment" style=color:#999988;font-style:italic># Simulates Databricks Apps environment</span><br/></div></code></pre></div></div>
<hr/>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id=project-structure>Project Structure<a href=#project-structure class=hash-link aria-label="Direct link to Project Structure" title="Direct link to Project Structure" translate=no></a></h2>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-text codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token plain">oral-health-policy-pulse/</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">├── frontend/                      # NEW: React application</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">│   ├── src/</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">│   │   ├── components/</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">│   │   │   └── Layout.tsx        # Main layout component</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">│   │   ├── pages/</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">│   │   │   ├── Dashboard.tsx     # Dashboard page</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">│   │   │   ├── Heatmap.tsx       # Interactive map</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">│   │   │   ├── Documents.tsx     # Document browser</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">│   │   │   ├── Opportunities.tsx # Opportunity manager</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">│   │   │   └── Settings.tsx      # Settings panel</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">│   │   ├── App.tsx               # Root component</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">│   │   ├── main.tsx              # Entry point</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">│   │   └── index.css             # Tailwind styles</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">│   ├── package.json              # npm dependencies</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">│   ├── vite.config.ts            # Vite configuration</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">│   ├── tsconfig.json             # TypeScript config</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">│   ├── tailwind.config.js        # Tailwind config</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">│   └── index.html                # HTML template</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain">├── api/</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">│   ├── app.py                    # NEW: Refactored FastAPI app</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">│   ├── main.py                   # LEGACY: Original API</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">│   └── static/                   # Built React files (generated)</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain">├── pipeline/</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">│   ├── delta_lake.py             # Original Delta Lake pipeline</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">│   └── delta_lake_queries.py     # NEW: Query methods for web app</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain">├── scripts/                       # NEW: Deployment scripts</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">│   ├── deploy-databricks-app.sh  # Deploy to Databricks</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">│   ├── setup-local.sh            # Local development setup</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">│   └── test-app.py               # Test production build</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"></span><br/></div><div class=token-line style=color:#393A34><span class="token plain">├── app.yaml                       # NEW: Databricks Apps config</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">├── Dockerfile.app                 # NEW: Production Docker image</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">├── DATABRICKS_APP_GUIDE.md        # NEW: Deployment documentation</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">└── README.md                      # UPDATED: Added React info</span><br/></div></code></pre></div></div>
<hr/>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id=features-by-page>Features by Page<a href=#features-by-page class=hash-link aria-label="Direct link to Features by Page" title="Direct link to Features by Page" translate=no></a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id=1-dashboard>1. Dashboard<a href=#1-dashboard class=hash-link aria-label="Direct link to 1. Dashboard" title="Direct link to 1. Dashboard" translate=no></a></h3>
<p><strong>Statistics Cards:</strong></p>
<ul>
<li class="">Total documents analyzed</li>
<li class="">Advocacy opportunities found</li>
<li class="">States monitored</li>
</ul>
<p><strong>Charts:</strong></p>
<ul>
<li class="">Topic distribution (bar chart)</li>
<li class="">Topic distribution (pie chart)</li>
</ul>
<p><strong>Recent Activity:</strong></p>
<ul>
<li class="">Latest opportunities table</li>
<li class="">Sortable and filterable</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id=2-interactive-heatmap>2. Interactive Heatmap<a href=#2-interactive-heatmap class=hash-link aria-label="Direct link to 2. Interactive Heatmap" title="Direct link to 2. Interactive Heatmap" translate=no></a></h3>
<p><strong>Map Features:</strong></p>
<ul>
<li class="">OpenStreetMap tiles</li>
<li class="">Circle markers for opportunities</li>
<li class="">Color-coded by urgency:<!-- -->
<ul>
<li class="">🔴 Critical</li>
<li class="">🟠 High</li>
<li class="">🟡 Medium</li>
<li class="">🟢 Low</li>
</ul>
</li>
</ul>
<p><strong>Interactivity:</strong></p>
<ul>
<li class="">Click markers for details</li>
<li class="">Filter by state dropdown</li>
<li class="">Filter by topic dropdown</li>
<li class="">Real-time updates</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id=3-document-browser>3. Document Browser<a href=#3-document-browser class=hash-link aria-label="Direct link to 3. Document Browser" title="Direct link to 3. Document Browser" translate=no></a></h3>
<p><strong>Features:</strong></p>
<ul>
<li class="">Full-text search across all documents</li>
<li class="">Pagination (20 per page)</li>
<li class="">Topic tags for each document</li>
<li class="">Direct links to source</li>
<li class="">Meeting date display</li>
<li class="">State/municipality info</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id=4-opportunities-manager>4. Opportunities Manager<a href=#4-opportunities-manager class=hash-link aria-label="Direct link to 4. Opportunities Manager" title="Direct link to 4. Opportunities Manager" translate=no></a></h3>
<p><strong>Display:</strong></p>
<ul>
<li class="">Card-based layout</li>
<li class="">Urgency badge</li>
<li class="">Key talking points</li>
<li class="">Confidence score bar</li>
</ul>
<p><strong>Actions:</strong></p>
<ul>
<li class="">Generate advocacy email</li>
<li class="">Contact via email</li>
<li class="">Add to calendar</li>
<li class="">Copy talking points</li>
</ul>
<p><strong>Filters:</strong></p>
<ul>
<li class="">Critical only</li>
<li class="">High priority</li>
<li class="">Medium priority</li>
<li class="">Low priority</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id=5-settings-panel>5. Settings Panel<a href=#5-settings-panel class=hash-link aria-label="Direct link to 5. Settings Panel" title="Direct link to 5. Settings Panel" translate=no></a></h3>
<p><strong>Configuration Options:</strong></p>
<ul>
<li class="">Target states (multi-select)</li>
<li class="">Policy topics (checkboxes)</li>
<li class="">Confidence threshold (slider)</li>
<li class="">Email notifications (toggle)</li>
</ul>
<p><strong>System Status:</strong></p>
<ul>
<li class="">Agent health indicators</li>
<li class="">Uptime display</li>
<li class="">Real-time status</li>
</ul>
<hr/>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id=development-workflow>Development Workflow<a href=#development-workflow class=hash-link aria-label="Direct link to Development Workflow" title="Direct link to Development Workflow" translate=no></a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id=local-development>Local Development<a href=#local-development class=hash-link aria-label="Direct link to Local Development" title="Direct link to Local Development" translate=no></a></h3>
<p><strong>1. Backend (Hot Reload)</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token plain">source venv/bin/activate</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">uvicorn api.app:app --reload</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"># Runs on http://localhost:8000</span><br/></div></code></pre></div></div>
<p><strong>2. Frontend (Hot Reload)</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token plain">cd frontend</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">npm run dev</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"># Runs on http://localhost:3000</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"># Proxies API calls to :8000</span><br/></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id=production-build>Production Build<a href=#production-build class=hash-link aria-label="Direct link to Production Build" title="Direct link to Production Build" translate=no></a></h3>
<p><strong>1. Build Frontend</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token plain">cd frontend</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">npm run build</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"># Outputs to api/static/</span><br/></div></code></pre></div></div>
<p><strong>2. Test Locally</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token plain">python scripts/test-app.py</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"># Serves at http://localhost:8000</span><br/></div></code></pre></div></div>
<p><strong>3. Deploy to Databricks</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token plain">./scripts/deploy-databricks-app.sh</span><br/></div><div class=token-line style=color:#393A34><span class="token plain"># One-command deployment</span><br/></div></code></pre></div></div>
<hr/>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id=benefits-of-refactoring>Benefits of Refactoring<a href=#benefits-of-refactoring class=hash-link aria-label="Direct link to Benefits of Refactoring" title="Direct link to Benefits of Refactoring" translate=no></a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id=user-experience>User Experience<a href=#user-experience class=hash-link aria-label="Direct link to User Experience" title="Direct link to User Experience" translate=no></a></h3>
<table><thead><tr><th>Before<th>After<tbody><tr><td>Command-line only<td>Beautiful web interface<tr><td>Manual file management<td>Automatic workflows<tr><td>Static visualizations<td>Interactive maps & charts<tr><td>No configuration UI<td>Full settings panel<tr><td>Email via CLI<td>One-click generation</table>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id=developer-experience>Developer Experience<a href=#developer-experience class=hash-link aria-label="Direct link to Developer Experience" title="Direct link to Developer Experience" translate=no></a></h3>
<table><thead><tr><th>Before<th>After<tbody><tr><td>Python-only<td>Full-stack (Python + TypeScript)<tr><td>Local deployment<td>Cloud-native (Databricks Apps)<tr><td>Manual setup<td>One-command deployment<tr><td>Limited monitoring<td>Built-in observability<tr><td>No UI testing<td>Component testing with Vitest</table>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id=operations>Operations<a href=#operations class=hash-link aria-label="Direct link to Operations" title="Direct link to Operations" translate=no></a></h3>
<table><thead><tr><th>Before<th>After<tbody><tr><td>Single-user CLI<td>Multi-user web app<tr><td>Local storage<td>Cloud Delta Lake<tr><td>Manual scaling<td>Auto-scaling<tr><td>No authentication<td>Databricks SSO<tr><td>Basic logging<td>Enterprise monitoring</table>
<hr/>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id=technology-choices>Technology Choices<a href=#technology-choices class=hash-link aria-label="Direct link to Technology Choices" title="Direct link to Technology Choices" translate=no></a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id=why-react>Why React?<a href=#why-react class=hash-link aria-label="Direct link to Why React?" title="Direct link to Why React?" translate=no></a></h3>
<ul>
<li class="">✅ Industry-standard UI framework</li>
<li class="">✅ Rich ecosystem of libraries</li>
<li class="">✅ TypeScript support for type safety</li>
<li class="">✅ Excellent developer experience</li>
<li class="">✅ Easy to maintain and extend</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id=why-vite>Why Vite?<a href=#why-vite class=hash-link aria-label="Direct link to Why Vite?" title="Direct link to Why Vite?" translate=no></a></h3>
<ul>
<li class="">✅ Lightning-fast dev server</li>
<li class="">✅ Instant hot module replacement</li>
<li class="">✅ Optimized production builds</li>
<li class="">✅ Native ES modules support</li>
<li class="">✅ Built-in TypeScript support</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id=why-tailwind-css>Why Tailwind CSS?<a href=#why-tailwind-css class=hash-link aria-label="Direct link to Why Tailwind CSS?" title="Direct link to Why Tailwind CSS?" translate=no></a></h3>
<ul>
<li class="">✅ Utility-first approach</li>
<li class="">✅ Rapid prototyping</li>
<li class="">✅ Consistent design system</li>
<li class="">✅ Small production bundle</li>
<li class="">✅ Highly customizable</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id=why-databricks-apps>Why Databricks Apps?<a href=#why-databricks-apps class=hash-link aria-label="Direct link to Why Databricks Apps?" title="Direct link to Why Databricks Apps?" translate=no></a></h3>
<ul>
<li class="">✅ Integrated with workspace</li>
<li class="">✅ Automatic authentication</li>
<li class="">✅ Unity Catalog integration</li>
<li class="">✅ Seamless data access</li>
<li class="">✅ Enterprise-ready</li>
</ul>
<hr/>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id=migration-path>Migration Path<a href=#migration-path class=hash-link aria-label="Direct link to Migration Path" title="Direct link to Migration Path" translate=no></a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id=for-existing-users>For Existing Users<a href=#for-existing-users class=hash-link aria-label="Direct link to For Existing Users" title="Direct link to For Existing Users" translate=no></a></h3>
<p><strong>v1.0 (CLI) → v2.0 (Web App)</strong></p>
<ol>
<li class=""><strong>Keep using CLI</strong> - Original functionality preserved in <code>api/main.py</code></li>
<li class=""><strong>Gradually adopt web UI</strong> - Run both simultaneously</li>
<li class=""><strong>Full migration</strong> - Switch to web-only when ready</li>
</ol>
<p><strong>Backward Compatibility:</strong></p>
<ul>
<li class="">All CLI commands still work</li>
<li class="">Original API endpoints unchanged</li>
<li class="">Can run standalone or web mode</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id=for-new-users>For New Users<a href=#for-new-users class=hash-link aria-label="Direct link to For New Users" title="Direct link to For New Users" translate=no></a></h3>
<p><strong>Start with Web UI:</strong></p>
<ol>
<li class="">Deploy to Databricks Apps</li>
<li class="">Access via browser</li>
<li class="">No CLI needed!</li>
</ol>
<hr/>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id=performance-optimizations>Performance Optimizations<a href=#performance-optimizations class=hash-link aria-label="Direct link to Performance Optimizations" title="Direct link to Performance Optimizations" translate=no></a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id=frontend>Frontend<a href=#frontend class=hash-link aria-label="Direct link to Frontend" title="Direct link to Frontend" translate=no></a></h3>
<ul>
<li class="">✅ Code splitting with React lazy loading</li>
<li class="">✅ Query caching with TanStack Query</li>
<li class="">✅ Optimized bundle size (~300KB gzipped)</li>
<li class="">✅ Lazy-loaded charts and maps</li>
<li class="">✅ Debounced search inputs</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id=backend>Backend<a href=#backend class=hash-link aria-label="Direct link to Backend" title="Direct link to Backend" translate=no></a></h3>
<ul>
<li class="">✅ Async endpoints with FastAPI</li>
<li class="">✅ Background task processing</li>
<li class="">✅ Delta Lake query optimization</li>
<li class="">✅ Static file caching</li>
<li class="">✅ CORS preflight caching</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id=deployment>Deployment<a href=#deployment class=hash-link aria-label="Direct link to Deployment" title="Direct link to Deployment" translate=no></a></h3>
<ul>
<li class="">✅ Scale-to-zero when idle</li>
<li class="">✅ Auto-scaling under load</li>
<li class="">✅ CDN for static assets</li>
<li class="">✅ Connection pooling</li>
<li class="">✅ Gzip compression</li>
</ul>
<hr/>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id=next-steps>Next Steps<a href=#next-steps class=hash-link aria-label="Direct link to Next Steps" title="Direct link to Next Steps" translate=no></a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id=planned-features>Planned Features<a href=#planned-features class=hash-link aria-label="Direct link to Planned Features" title="Direct link to Planned Features" translate=no></a></h3>
<p><strong>Phase 1: Enhanced Analytics</strong></p>
<ul class="contains-task-list containsTaskList_mC6p">
<li class=task-list-item><input type=checkbox disabled/> <!-- -->Historical trend charts</li>
<li class=task-list-item><input type=checkbox disabled/> <!-- -->Predictive analytics</li>
<li class=task-list-item><input type=checkbox disabled/> <!-- -->Custom report builder</li>
</ul>
<p><strong>Phase 2: Collaboration</strong></p>
<ul class="contains-task-list containsTaskList_mC6p">
<li class=task-list-item><input type=checkbox disabled/> <!-- -->User comments/notes</li>
<li class=task-list-item><input type=checkbox disabled/> <!-- -->Shared dashboards</li>
<li class=task-list-item><input type=checkbox disabled/> <!-- -->Team workspaces</li>
</ul>
<p><strong>Phase 3: Automation</strong></p>
<ul class="contains-task-list containsTaskList_mC6p">
<li class=task-list-item><input type=checkbox disabled/> <!-- -->Scheduled reports</li>
<li class=task-list-item><input type=checkbox disabled/> <!-- -->Email alerts</li>
<li class=task-list-item><input type=checkbox disabled/> <!-- -->Slack integration</li>
</ul>
<p><strong>Phase 4: Advanced AI</strong></p>
<ul class="contains-task-list containsTaskList_mC6p">
<li class=task-list-item><input type=checkbox disabled/> <!-- -->Document Q&A chatbot</li>
<li class=task-list-item><input type=checkbox disabled/> <!-- -->Meeting video analysis</li>
<li class=task-list-item><input type=checkbox disabled/> <!-- -->Speech-to-text integration</li>
</ul>
<hr/>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id=deployment-examples>Deployment Examples<a href=#deployment-examples class=hash-link aria-label="Direct link to Deployment Examples" title="Direct link to Deployment Examples" translate=no></a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id=example-1-local-testing>Example 1: Local Testing<a href=#example-1-local-testing class=hash-link aria-label="Direct link to Example 1: Local Testing" title="Direct link to Example 1: Local Testing" translate=no></a></h3>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token plain"># Setup</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">./scripts/setup-local.sh</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">source venv/bin/activate</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"># Run backend</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">uvicorn api.app:app --reload &</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"># Run frontend</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">cd frontend && npm run dev</span><br/></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id=example-2-production-deployment>Example 2: Production Deployment<a href=#example-2-production-deployment class=hash-link aria-label="Direct link to Example 2: Production Deployment" title="Direct link to Example 2: Production Deployment" translate=no></a></h3>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token plain"># Configure</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">export DATABRICKS_HOST=https://your-workspace.cloud.databricks.com</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">export DATABRICKS_TOKEN=dapi...</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">export OPENAI_API_KEY=sk-...</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"># Deploy</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">./scripts/deploy-databricks-app.sh</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"># Monitor</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">databricks apps logs oral-health-policy-pulse --follow</span><br/></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id=example-3-docker-deployment>Example 3: Docker Deployment<a href=#example-3-docker-deployment class=hash-link aria-label="Direct link to Example 3: Docker Deployment" title="Direct link to Example 3: Docker Deployment" translate=no></a></h3>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style=--prism-color:#393A34;--prism-background-color:#f6f8fa><div class=codeBlockContent_QJqH><pre tabindex=0 class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style=color:#393A34;background-color:#f6f8fa><code class=codeBlockLines_e6Vv><div class=token-line style=color:#393A34><span class="token plain"># Build</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">docker build -f Dockerfile.app -t oral-health-app .</span><br/></div><div class=token-line style=color:#393A34><span class="token plain" style=display:inline-block></span><br/></div><div class=token-line style=color:#393A34><span class="token plain"># Run</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">docker run -p 8000:8000 \</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">  -e DATABRICKS_HOST=$DATABRICKS_HOST \</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">  -e OPENAI_API_KEY=$OPENAI_API_KEY \</span><br/></div><div class=token-line style=color:#393A34><span class="token plain">  oral-health-app</span><br/></div></code></pre></div></div>
<hr/>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id=conclusion>Conclusion<a href=#conclusion class=hash-link aria-label="Direct link to Conclusion" title="Direct link to Conclusion" translate=no></a></h2>
<p>The <strong>React + FastAPI refactoring</strong> transforms Oral Health Policy Pulse from a developer-focused CLI tool into an <strong>enterprise-ready web application</strong> that can be:</p>
<p><strong>Deployed instantly</strong> to Databricks Apps<br/>
<!-- --><strong>Used by non-technical users</strong> via web browser<br/>
<!-- --><strong>Scaled automatically</strong> for any load<br/>
<!-- --><strong>Monitored comprehensively</strong> with built-in observability<br/>
<!-- --><strong>Secured enterprise-grade</strong> with Databricks SSO</p>
<p><strong>The future of oral health advocacy is here! 🦷✨</strong></div><footer class="theme-doc-footer docusaurus-mt-lg"><div class="row margin-top--sm theme-doc-footer-edit-meta-row"><div class="col noPrint_WFHX"><a href=https://github.com/getcommunityone/open-navigator-for-engagement/tree/main/website/docs/development/react-refactoring.md target=_blank rel="noopener noreferrer" class=theme-edit-this-page><svg fill=currentColor height=20 width=20 viewBox="0 0 40 40" class=iconEdit_Z9Sw aria-hidden=true><g><path d="m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"/></g></svg>Edit this page</a></div><div class="col lastUpdated_JAkA"></div></div></footer></article><nav class="docusaurus-mt-lg pagination-nav" aria-label="Docs pages"><a class="pagination-nav__link pagination-nav__link--prev" href=/docs/development/port-guide><div class=pagination-nav__sublabel>Previous</div><div class=pagination-nav__label>🚨 CRITICAL: Which Port to Use?</div></a><a class="pagination-nav__link pagination-nav__link--next" href=/docs/development/readme-migration><div class=pagination-nav__sublabel>Next</div><div class=pagination-nav__label>README Migration Summary</div></a></nav></div></div><div class="col col--3"><div class="tableOfContents_bqdL thin-scrollbar theme-doc-toc-desktop"><ul class="table-of-contents table-of-contents__left-border"><li><a href=#executive-summary class="table-of-contents__link toc-highlight">Executive Summary</a><ul><li><a href=#what-changed class="table-of-contents__link toc-highlight">What Changed</a></ul><li><a href=#new-architecture class="table-of-contents__link toc-highlight">New Architecture</a><ul><li><a href=#frontend-react--typescript class="table-of-contents__link toc-highlight">Frontend (React + TypeScript)</a><li><a href=#backend-fastapi-refactored class="table-of-contents__link toc-highlight">Backend (FastAPI Refactored)</a><li><a href=#database-layer class="table-of-contents__link toc-highlight">Database Layer</a></ul><li><a href=#databricks-apps-integration class="table-of-contents__link toc-highlight">Databricks Apps Integration</a><ul><li><a href=#configuration-files class="table-of-contents__link toc-highlight">Configuration Files</a><li><a href=#deployment-scripts class="table-of-contents__link toc-highlight">Deployment Scripts</a></ul><li><a href=#project-structure class="table-of-contents__link toc-highlight">Project Structure</a><li><a href=#features-by-page class="table-of-contents__link toc-highlight">Features by Page</a><ul><li><a href=#1-dashboard class="table-of-contents__link toc-highlight">1. Dashboard</a><li><a href=#2-interactive-heatmap class="table-of-contents__link toc-highlight">2. Interactive Heatmap</a><li><a href=#3-document-browser class="table-of-contents__link toc-highlight">3. Document Browser</a><li><a href=#4-opportunities-manager class="table-of-contents__link toc-highlight">4. Opportunities Manager</a><li><a href=#5-settings-panel class="table-of-contents__link toc-highlight">5. Settings Panel</a></ul><li><a href=#development-workflow class="table-of-contents__link toc-highlight">Development Workflow</a><ul><li><a href=#local-development class="table-of-contents__link toc-highlight">Local Development</a><li><a href=#production-build class="table-of-contents__link toc-highlight">Production Build</a></ul><li><a href=#benefits-of-refactoring class="table-of-contents__link toc-highlight">Benefits of Refactoring</a><ul><li><a href=#user-experience class="table-of-contents__link toc-highlight">User Experience</a><li><a href=#developer-experience class="table-of-contents__link toc-highlight">Developer Experience</a><li><a href=#operations class="table-of-contents__link toc-highlight">Operations</a></ul><li><a href=#technology-choices class="table-of-contents__link toc-highlight">Technology Choices</a><ul><li><a href=#why-react class="table-of-contents__link toc-highlight">Why React?</a><li><a href=#why-vite class="table-of-contents__link toc-highlight">Why Vite?</a><li><a href=#why-tailwind-css class="table-of-contents__link toc-highlight">Why Tailwind CSS?</a><li><a href=#why-databricks-apps class="table-of-contents__link toc-highlight">Why Databricks Apps?</a></ul><li><a href=#migration-path class="table-of-contents__link toc-highlight">Migration Path</a><ul><li><a href=#for-existing-users class="table-of-contents__link toc-highlight">For Existing Users</a><li><a href=#for-new-users class="table-of-contents__link toc-highlight">For New Users</a></ul><li><a href=#performance-optimizations class="table-of-contents__link toc-highlight">Performance Optimizations</a><ul><li><a href=#frontend class="table-of-contents__link toc-highlight">Frontend</a><li><a href=#backend class="table-of-contents__link toc-highlight">Backend</a><li><a href=#deployment class="table-of-contents__link toc-highlight">Deployment</a></ul><li><a href=#next-steps class="table-of-contents__link toc-highlight">Next Steps</a><ul><li><a href=#planned-features class="table-of-contents__link toc-highlight">Planned Features</a></ul><li><a href=#deployment-examples class="table-of-contents__link toc-highlight">Deployment Examples</a><ul><li><a href=#example-1-local-testing class="table-of-contents__link toc-highlight">Example 1: Local Testing</a><li><a href=#example-2-production-deployment class="table-of-contents__link toc-highlight">Example 2: Production Deployment</a><li><a href=#example-3-docker-deployment class="table-of-contents__link toc-highlight">Example 3: Docker Deployment</a></ul><li><a href=#conclusion class="table-of-contents__link toc-highlight">Conclusion</a></ul></div></div></div></div></main></div></div></div><footer class="theme-layout-footer footer footer--dark"><div class="container container-fluid"><div class="row footer__links"><div class="theme-layout-footer-column col footer__col"><div class=footer__title>Documentation</div><ul class="footer__items clean-list"><li class=footer__item><a class=footer__link-item href=/docs/intro>Getting Started</a><li class=footer__item><a class=footer__link-item href=/docs/data-sources/citations>Citations & Data Sources</a><li class=footer__item><a class=footer__link-item href=/docs/data-sources/overview>Data Sources</a><li class=footer__item><a class=footer__link-item href=/docs/for-developers>For Developers</a></ul></div><div class="theme-layout-footer-column col footer__col"><div class=footer__title>Resources</div><ul class="footer__items clean-list"><li class=footer__item><a href=https://www.communityone.com target=_blank rel="noopener noreferrer" class=footer__link-item>Launch Open Navigator<svg width=13.5 height=13.5 aria-label="(opens in new tab)" class=iconExternalLink_nPIU><use href=#theme-svg-external-link /></svg></a><li class=footer__item><a href=https://github.com/getcommunityone/open-navigator-for-engagement target=_blank rel="noopener noreferrer" class=footer__link-item>GitHub<svg width=13.5 height=13.5 aria-label="(opens in new tab)" class=iconExternalLink_nPIU><use href=#theme-svg-external-link /></svg></a><li class=footer__item><a href=https://www.groundvue.org/ target=_blank rel="noopener noreferrer" class=footer__link-item>GroundVue (Partner)<svg width=13.5 height=13.5 aria-label="(opens in new tab)" class=iconExternalLink_nPIU><use href=#theme-svg-external-link /></svg></a></ul></div><div class="theme-layout-footer-column col footer__col"><div class=footer__title>Community</div><ul class="footer__items clean-list"><li class=footer__item><a href=https://www.instagram.com/getcommunityone/ target=_blank rel="noopener noreferrer" class=footer__link-item>Instagram<svg width=13.5 height=13.5 aria-label="(opens in new tab)" class=iconExternalLink_nPIU><use href=#theme-svg-external-link /></svg></a><li class=footer__item><a href=https://www.facebook.com/getcommunityone target=_blank rel="noopener noreferrer" class=footer__link-item>Facebook<svg width=13.5 height=13.5 aria-label="(opens in new tab)" class=iconExternalLink_nPIU><use href=#theme-svg-external-link /></svg></a><li class=footer__item><a href=https://x.com/getcommunityone/ target=_blank rel="noopener noreferrer" class=footer__link-item>X (Twitter)<svg width=13.5 height=13.5 aria-label="(opens in new tab)" class=iconExternalLink_nPIU><use href=#theme-svg-external-link /></svg></a><li class=footer__item><a href=https://www.linkedin.com/company/getcommunityone target=_blank rel="noopener noreferrer" class=footer__link-item>LinkedIn<svg width=13.5 height=13.5 aria-label="(opens in new tab)" class=iconExternalLink_nPIU><use href=#theme-svg-external-link /></svg></a><li class=footer__item><a href=https://www.youtube.com/@getcommunityone target=_blank rel="noopener noreferrer" class=footer__link-item>YouTube<svg width=13.5 height=13.5 aria-label="(opens in new tab)" class=iconExternalLink_nPIU><use href=#theme-svg-external-link /></svg></a><li class=footer__item><a href=https://discord.gg/uH6Dytek target=_blank rel="noopener noreferrer" class=footer__link-item>Discord<svg width=13.5 height=13.5 aria-label="(opens in new tab)" class=iconExternalLink_nPIU><use href=#theme-svg-external-link /></svg></a></ul></div><div class="theme-layout-footer-column col footer__col"><div class=footer__title>Legal</div><ul class="footer__items clean-list"><li class=footer__item><a class=footer__link-item href=/docs/legal/privacy-policy>Privacy Policy</a><li class=footer__item><a class=footer__link-item href=/docs/legal/terms-of-service>Terms of Service</a><li class=footer__item><a class=footer__link-item href=/docs/legal/data-provider-terms>Data Provider Terms</a></ul></div><div class="theme-layout-footer-column col footer__col"><div class=footer__title>More</div><ul class="footer__items clean-list"><li class=footer__item><a class=footer__link-item href=/blog>Blog</a><li class=footer__item><a href=https://github.com/getcommunityone/open-navigator-for-engagement/blob/main/LICENSE target=_blank rel="noopener noreferrer" class=footer__link-item>License (MIT)<svg width=13.5 height=13.5 aria-label="(opens in new tab)" class=iconExternalLink_nPIU><use href=#theme-svg-external-link /></svg></a></ul></div></div><div class="footer__bottom text--center"><div class=footer__copyright>Copyright © 2026 Community One. Built with Docusaurus.</div></div></div></footer></div></body>