Major redesign towards a server rendered app#101
Merged
Conversation
- Service plans: named speed/latency/category bundles per technology, one default per technology per filing, assignable per file. Plan values write through to the per-file columns, so the compute and export pipeline is unchanged. - BDC filing windows as pure date math (June/December data dates, weekend-rolled due dates, fabric version numbering), an explicit filed/reopened status, and folder lineage for snapshots. - Fabric intake v2: classifies CostQuest delivery files by role (active / non-BSL / supplemental), checks the delivery's fabric version against the filing's window (overridable), and replaces a prior delivery cleanly. Supplemental addresses feed search only. - An org-scoped jobs stream (SSE) with a plain-language catalog of worker operations, and a sweep that fails tasks orphaned by a dead worker instead of leaving them pending forever. - A per-file coverage buffer override for wired files (100 m default). - Contract tests for the file, fabric, map, export, and organization endpoints, which previously had none.
A site-wide theme picked in the admin panel (three civic variants, light default) and stored as a site setting; admin management of users (disable/enable, password reset, org reassignment) and organizations (create, rename, delete) with audit logging; verification and reset emails carry clickable links instead of bare tokens.
A complete server-rendered workflow beside the existing SPA, served by Flask through nginx and styled by a shared civic design system (Jinja2 + htmx pages; the map is a standalone MapLibre island): - a guided setup funnel: organization, fabric delivery, first coverage files, then into the app; - files & plans: fabric intake with vintage warnings, coverage files with technology/plan pickers and the wired buffer setting, plan management with per-technology defaults; - the map studio: one location layer colored by served state, plan-aware point popups answered from the database, drawn-area edits with per-technology verbs (exclude / set plan), and saved edits that reopen for reshaping (vertex drag, midpoint insertion) or deletion; - submissions: a debt selector listing exactly what stands between the filing and a valid availability CSV, generation as a tracked job with an inline snapshot, explicit filed/reopen status; - a filing switcher: carry-forward into a newly opened BDC window and creation of any past window's filing (copy or from scratch); - auth pages (login, register, reset, verify) on the same shell; - a live job pill and tray over the org-scoped SSE stream. The SPA keeps working unchanged at / until cutover; the new pages live at their final paths (/setup, /files, /map, /submissions, /org). An end-to-end replay drives the new endpoints and asserts the generated export is identical to the legacy pipeline's.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is pretty much a rewrite of the entire BDK application's user experience, while maintaining the core coverage computation more-or-less unchanged. The biggest architectural change is moving away from a next.js/React-based SPA to an htmx-based server-side rendered app. Most of the application is just forms so it's simpler and cleaner to use that approach rather than treating everything as a dynamic component; this will also massively simplify the frontend codebase.
The more substantial change is a significant overhaul of the whole user experience to bring BDK more in line with the original "turbotax for BDC" vision. We introduce an explicit notion of "filings" that are tied to the BDC cadence, add a checklist of remaining tasks to complete before a filing can be submitted (essentially checking what the user has entered so far and directing them to the next task), and make the new filing flow more explicit for return users (including adding checks on fabric version matches). We add a number of more utilitarian UX improvements -- backend async tasks now have a single status endpoint that can update the UI when any org member is making an update, while also explaining what is being updated; the entry for coverages and plans is simplified and restructured; and the entire application doesn't force any specific order of inputting data (e.g., a user can proceed with adding all their coverages and service plans without uploading a fabric.
This is largely additions because we are preserving the old SPA-based version of BDK alongside this and just updating our routes to point to the new server-side rendered app's endpoints. In principle, the entire old version of BDK is still there and accessible.
For testing -- I've ensured that the same coverage files and edits submitted via the new UI produce identical outputs as the current prod version, and I've manually tested all flows through the create/edit/finalize process for a submission.