Skip to main content
The Partners Portal is the reference implementation of the Bloom Housing administrative interface. It runs as a Next.js application on port 3001 and provides housing partners — including housing developers, property managers, cities, and counties — with tools to manage listings, review and export applications, run lotteries, and administer users.

Features

Listing management

Create, edit, publish, close, and reopen affordable housing listings. Supports draft and published states.

Application management

View, edit, add, and export applications per listing. Separate views for pending and resolved applications.

Lottery management

Run and publish lotteries for closed listings. Lottery data expires after a configurable number of days.

User management

Invite, confirm, and manage partner users and advocates. Restricted to admin roles.

Admin functions

System-level administrative operations accessible only to admin users.

Settings

Manage jurisdiction preferences, multiselect questions, and property records. Shown when the feature flag is enabled.

User roles

Access to features within the Partners Portal is controlled by role. The following roles are supported:
RoleDescription
adminFull access to all features including user management and admin functions
jurisdictionalAdminAdministrative access scoped to a specific jurisdiction
partnerAccess to listings and applications for their associated properties
leasingAgentAccess to view and manage applications for assigned listings
supportAdminSupport staff with elevated read access for troubleshooting
User management pages (/users) and admin functions (/admin) are restricted to users with the admin or jurisdictionalAdmin role. Accessing these pages without the appropriate role will redirect to /unauthorized.

Page structure

All pages live under sites/partners/src/pages/.
FileRouteDescription
index.tsx/Root redirect to listings dashboard
sign-in.tsx/sign-inPartner sign-in page
forgot-password.tsx/forgot-passwordPassword reset request
reset-password.tsx/reset-passwordPassword reset confirmation
unauthorized.tsx/unauthorizedShown when a user lacks permission for a page
FileRouteDescription
listings/add.tsx/listings/addCreate a new listing
listings/[id]/index.tsx/listings/[id]Listing detail and edit overview
listings/[id]/edit.tsx/listings/[id]/editFull listing edit form
listings/[id]/lottery.tsx/listings/[id]/lotteryLottery management for a listing
FileRouteDescription
listings/[id]/applications/index.tsx/listings/[id]/applicationsAll applications for a listing
listings/[id]/applications/add.tsx/listings/[id]/applications/addAdd a paper/manual application
listings/[id]/applications/pending//listings/[id]/applications/pendingApplications pending review
listings/[id]/applications/resolved//listings/[id]/applications/resolvedResolved/processed applications
application/[id]//application/[id]View or edit an individual application
FileRouteDescription
users/index.tsx/usersList and search all partner users
users/advocates.tsx/users/advocatesManage advocate accounts
users/confirm.tsx/users/confirmConfirm a newly invited user
users/terms.tsx/users/termsTerms of service acceptance
FileRouteDescription
admin/index.tsx/adminSystem administration dashboard
Settings pages are only visible when the settings feature flag is enabled.
FileRouteDescription
settings/index.tsx/settingsJurisdiction settings overview
settings/preferences.tsx/settings/preferencesManage listing preferences
settings/properties.tsx/settings/propertiesManage property records
settings/multiselectquestions/preferences.tsx/settings/multiselectquestions/preferencesManage multiselect question sets

Running locally

1

Install dependencies

From the monorepo root:
yarn install
2

Configure environment variables

Copy the template and set values for your local environment:
cp sites/partners/.env.template sites/partners/.env
Edit sites/partners/.env as needed. See the environment variables section below for details on each variable.
3

Start the backend and partners app

From the monorepo root, this starts the backend on port 3100 and the partners portal on port 3001:
yarn dev:all
Alternatively, start only the partners portal from within sites/partners:
yarn dev
4

Sign in

Navigate to http://localhost:3001 and sign in with the default local development credentials:
The backend must be running on port 3100 before starting the partners portal. Sign-in and all data operations require an active API connection.

Environment variables

Copy .env.template to .env inside sites/partners/. The following variables control the app’s behavior:
VariableDefaultDescription
BACKEND_API_BASEhttp://localhost:3100Base URL for the backend API
BACKEND_PROXY_BASE(empty)If set, routes API calls through this proxy
LISTINGS_QUERY/listingsPath appended to backend base to query listings
API_PASS_KEYsome-key-hereShared passkey; must match the backend’s configured value
VariableDefaultDescription
NEXTJS_PORT3001Port the Next.js app listens on
LOTTERY_DAYS_TILL_EXPIRY45Number of days after which lottery data is considered expired
ALLOW_SEO_INDEXINGFALSESet to TRUE in production only; enables search engine indexing
VariableDefaultDescription
MAPBOX_TOKEN(empty)Mapbox API token for property map views
CLOUDINARY_CLOUD_NAMEexygyCloudinary cloud name for image uploads
CLOUDINARY_KEYabcxyzCloudinary API key for signed uploads
CLOUDINARY_SIGNED_PRESETtest123Cloudinary signed upload preset
RECAPTCHA_KEY(empty)Google reCAPTCHA site key
AXE_DEVELOPER_HUB_API_KEY(empty)Axe DevHub API key for automated accessibility reporting
VariableDefaultDescription
SHOW_LOTTERYFALSEEnables lottery management UI within listing pages
SHOW_SMS_MFATRUEEnables SMS-based multi-factor authentication (on by default)
APPLICATION_EXPORT_AS_SPREADSHEETFALSEExports applications as a spreadsheet (.xlsx) instead of CSV
USE_SECURE_DOWNLOAD_PATHWAYTRUEDownloads exported files through a secure S3 private bucket pathway
LIMIT_CLOSED_LISTING_ACTIONSFALSERestricts edit, republish, and reopen actions on closed listings
RUN_ACCESSIBILITY_E2E_TESTS(empty)Enables accessibility checks in the Cypress E2E suite

Testing

The partners portal has two test suites.
Run the full end-to-end test suite against a running instance of the app:
yarn test
Run from within sites/partners/ with the app already running on port 3001 and the backend running on port 3100.
Set RUN_ACCESSIBILITY_E2E_TESTS=TRUE in .env to also run axe-based accessibility checks during the Cypress suite.

Build docs developers (and LLMs) love