Phase 1 Post-Upgrade Fixes
Completed: 2026-04-02 | PRs: #511, #512, #513, #514, #515, #516 Scope:equa-webrepository | Branch:main
Overview
This release gathers the six PRs that landed onequa-web between 2026-03-30 and 2026-04-02, immediately following the Phase 1 frontend ecosystem upgrade. Each PR was scoped tightly to a single fix or small feature; grouping them here gives a single release-note page for the post-upgrade stabilisation work.
Build and Dependencies
@babel/core Upgrade (PR #511)
Webpack builds on every branch were failing withTypeError: api.assumption is not a function. The hoisted @babel/core was pinned at 7.11.6 (pulled in transitively by @svgr/webpack) while @babel/preset-env sub-dependencies required api.assumption(), introduced in 7.13.
| Package | Before | After |
|---|---|---|
@babel/core | 7.11.6 | 7.29.0 |
@babel/plugin-proposal-class-properties | present | removed (dead dep, not referenced in .babelrc) |
core-js | duplicated entries | deduplicated + alphabetized |
npx webpack --mode production — 0 errors after upgrade (1 error before).
Features
Dashboard Empty State + Gateway Token Sync (PR #512, Spec 001)
PR #512 was split into two independent workstreams targeting the open issues #502 and #503. Workstream A — Gateway Token Sync (#502)equa-web/src/modules/equabot-settings/services/storage.ts now recognizes ?equabotToken=<token> and ?gatewayToken=<token> in the URL query string, persisting the token to localStorage under the gateway-token key. This matches the standard equabot dashboard --no-open handoff pattern and eliminates the client/server token desync class of bug.
Workstream B — Dashboard Empty State (#503)
A new DashboardEmptyState component lives at modules/organization-dashboard/components/empty-state/empty-state.tsx. When every rolling metric on the organization dashboard resolves to zero, the dashboard renders a 3-step onboarding guide (create cap table, invite team, upload documents) instead of a page full of zero values. The sibling RecentActions component replaced its 6-year-old “Coming Soon” placeholder with a “No recent activity” empty state.
See Spec 001 §2.7 for the token contract and Spec 020 § Post-Onboarding Dashboard Empty State for the component.
Lint follow-up (PR #513)
Three ESLint errors instorage.test.ts (added in #512’s review fixes) were cleaned up. 10 storage tests pass.
Bug Fixes
Network Errors No Longer Freeze the Splash Screen (PR #514, issue #482)
baseRequest() in src/service/lib/http-client.ts previously had no try-catch around fetch(). When the backend was unreachable (network error, DNS failure, CORS blocked), fetch() threw a TypeError that propagated as an unhandled rejection. Redux-loop never got a chance to dispatch the failure action, getCurrentUser’s callback never fired, and the app hung on the Equa logo spinner forever.
Fix: Wrap fetch() in try-catch. Network errors now return HttpError(ResponseCode.other, 'networkError', ...) following the same contract as 4xx/5xx responses. The normal error flow proceeds and the app renders the login page instead of hanging.
See Frontend Architecture § Network Error Handling for the caller contract.
E2E Auth Form Locators (PR #515, issue #494)
Five regression tests broke after Phase 0 (PR #465). Root cause: test locators targetedinput[type="email"], but the actual auth forms use <input type="text"> with react-final-form custom field components. The locators never matched, so the tests timed out at 30s.
Fixed files:
e2e/auth-modal-security.spec.ts— registration email locator usesname="email"e2e/regression-fixed-issues.spec.ts— login usesname="usernameOrEmail", registration usesname="email"e2e/visual-regression.spec.ts— replacedtype="email"with placeholder-based selectors
Infrastructure
Railway / CI Cleanup (PR #516)
nginx.conf — dynamic PORT:listen 8080 was changed to listen ${PORT} with envsubst templating at container startup. Railway injects $PORT per service instance; the hard-coded 8080 had worked only because it happened to match the Dockerfile EXPOSE. Local docker run still defaults to 8080 via the Dockerfile ENV PORT=8080.
ci.yml — stale references removed:
stagingremoved frompush/pull_requesttriggers (default branch is nowmain)GH_PATTERNLIB_TOKEN: placeholderenv override removed from the lint-and-build job — the repo-level secret-validation step handles the token properly
production GitHub deployment environment artifact.
See Deployment Infrastructure § Frontend Nginx and CI/CD Pipeline § equa-web CI for the updated configs.
Verification
| Check | Result |
|---|---|
| Webpack production build (PR #511) | Pass (api.assumption error resolved) |
| Jest unit tests (PR #512, #513) | 52 + 10 storage tests passing |
| Playwright E2E with new locators (PR #515) | 5 previously broken tests green |
Network error path returns HttpError (PR #514) | Verified manually — app renders login page instead of splash |
| Railway dynamic PORT (PR #516) | Container boots with Railway-assigned port |