Plan✕ is a platform for creating and publishing digital planning services.
Learn more about how it's currently being used here: https://opendigitalplanning.org/
Explore our component library and design system here: https://storybook.planx.uk/
- Production: https://status.planx.uk
- Staging: https://status.planx.dev
- GIS & other data integrations: https://gis-status.planx.uk (ask for the password in Slack!)
planx-new is a monorepo containing our full application stack. Here's a quick summary of what you'll find here:
api.planx.uk
is a Node/Express server and REST endpointseditor.planx.uk
is our React frontend, which consists of two main environments: an "editor" for service designers and a "preview" for public applicants. Our components are written with Material UI and broadly follow GOV.UK design patternshasura.planx.uk
is a Hasura GraphQL engine for our PostgreSQL databasesharedb.planx.uk
is our implementation of ShareDB, a library for realtime document collaboration based on JSON Operational Transformation (OT) used in our "editor" environmentinfrastructure
is Pulumi infrastructure-as-code for configuring and managing our AWS environments
- Download and install the following dependencies if you don't have them already:
- Docker
- Docker Compose
- PNPM
npm install -g pnpm@8.6.6
- Node
pnpm env use --global 18.16.1
- AWS CLI
If you're an OSL developer:
-
Clone this repository
-
Setup your AWS CLI client with SSO - detailed guide here
-
Pull down environment secrets for running the application in staging mode by running
./scripts/pull-secrets.sh
. (NOTE: Even when running locally, API requests are routed to relevant staging servers and emails are actually processed and sent to provided addresses). -
Run
pnpm run up
from the project root to set up docker containers for the application's backend (postgres, sharedb, api and hasura server processes) and to pull seed application data from production. -
Move into the hasura directory
cd ../hasura.planx.uk
and install dependenciespnpm i
. -
Open Hasura's web console (
cd hasura.planx.uk
thenpnpm start
) and check that your Google email address is in theusers
table, if not then add it. This will eventually allow you to authenticate into the application as an admin. -
Move into the editor directory
cd ../editor.planx.uk
& install dependenciespnpm i
. -
Start the editor dev server, with
pnpm start
-
Open
http://localhost:3000
and login with your Google email address
If you're not a member of OSL, follow these steps:
-
Fork or clone this repository
-
Copy all
.example
env files into their respective directories and replace 👻 with a string like "SECRET" or longer where noted -
Setup free OAuth Client ID credentials in the Google Cloud APIs console
- Application type = "Web application"
- Authorised JavaScript origins = "http://localhost:3000"
- Authorised redirect URIs = "http://localhost:7002/auth/google/callback"
- Update the
GOOGLE_CLIENT_ID
&GOOGLE_CLIENT_SECRET
env vars with your new credentials
-
Run
pnpm start
from the project root to set up docker containers for the application's backend (postgres, sharedb, api and hasura server processes). Please note you will not be able to run commands that sync seed data from production. -
Move into the hasura directory
cd ../hasura.planx.uk
and install dependenciespnpm i
. -
Open Hasura's web console (
cd hasura.planx.uk
thenpnpm start
) and add your Google email address to theusers
table. You'll also likely want to create an initialteam
. This will eventually allow you to authenticate into the application as an admin. -
Follow steps 7-9 above to start the editor and login !
At this point you'll be running the full Planx application locally in a docker container. See our Github Actions pull request workflow as an example of how to deploy via docker to a virtual linux server, or explore the infrastructure
directory for how to deploy via Pulumi infrastructure-as-code to AWS.
We'd love to hear what you're building on Planx, don't hesitate to get in touch with questions.
The root of the project has several scripts set up to help you manage your docker containers:
pnpm run up
alias forpnpm recreate && pnpm sync-data
pnpm run down
alias forpnpm destroy
pnpm run restart
alias forpnpm stop && pnpm start
pnpm start
will (re)create docker containers without rebuilding thempnpm stop
will stop your docker containers without destroying thempnpm recreate
will build and (re)start your docker containers from scratch.pnpm destroy
will remove volumes (i.e. database data) and can be a useful hard reset when necessary.pnpm sync-data
will sync production records with modified data in your databasepnpm clean-data
will sync production records and reset any modified datapnpm tests
will recreate your docker containers and include test servicespnpm analytics
will recreate your docker containers and include Metabasepnpm logs
will print docker log entries (this can be filtered by appending-- [service name]
, for examplepnpm logs -- api
)
This project uses Architecture Decision Records (ADRs) to record significant changes and decisions. Further details of this can be found here.
For maximum visibility and discoverability, we recommend using the GitHub discussions board where possible.
Our main
branch is deployed to AWS staging (editor.planx.dev) and production
is deployed to our AWS production environment (i.e. editor.planx.uk and the custom subdomain like planningservices.{council}.gov.uk) using Github Actions.
We work in feature branches and open pull requests against main
. Pull requests will spin up a Vultr server running Docker to test the whole stack (eg database migrations, API changes, frontend changes, Storybook, etc) and generate unique links that can be shared for user-acceptance testing. Pull request environments use the domain pattern <service>.<PR#>.planx.pizza
and are often simply referred to as "pizzas". The only changes which cannot be fully tested on a pizza are changes related to Pulumi infrastructure-as-code because this is only deployed in AWS environments, not via Docker.
Pull requests will automatically deploy to a new pizza. To skip pizza deployments, include [skip pizza]
anywhere in your commit message.
We aim to keep a linear commit history between main
and production
branches in Github. We "Squash & merge" pull request commits into main
.
You can manually trigger a production deployments by going to the Deploy to Production action and clicking Run workflow
.
Once a deployment is completed, a Slack notification will be sent to the #planx-deployments channel, and the production
branch should read "This branch is up to date with main."
Diverging branches
If the commit history of main
and production
diverge and production
contains commit hashes that are NOT on main, try running this command from production
to reset and then follow the original deploy steps above:
git reset --hard <most recent commit hash **matching** main> && git push --force
You'll have to temporarily turn off branch protection rules to make this change, so run it by another dev to confirm.
Unmet peer dependencies
Make sure pnpm
is installed globally at version 8.6.6 pnpm add -g pnpm@8.6.6
, otherwise you may hit some unmet peer dependencies issues.
Our public-facing live services were last audited by the Digital Accessibility Centre (DAC) on 30th March 2022. At that time we were found to comply with all the requirements of the Web Content Accessibility Guidelines (WCAG) version 2.1 AA. You can review our report here.
Our whole stack was last assessed by Jumpsec between the 21st and 30th November 2023. JUMPSEC then performed a retest of the issues identified in the initial test on the 8th of February 2024. This included verifying that fixes had been successfully applied and that no further risks were introduced as a result of the remediation work carried out. Their penetration test concluded that - "the security posture of PlanX was strong, and following industry best practices. JUMPSEC commend the PlanX team on their dedication to security and ability to both maintain and mitigate issues in a responsible and timely manner". You can review our report here.
There are a few dependent packages that are closely related to this project: